Path: blob/main/sys/contrib/dev/athk/ath12k/hal.c
105220 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.4*/5#include <linux/dma-mapping.h>6#include "hal_tx.h"7#include "hal_rx.h"8#include "debug.h"9#include "hal_desc.h"10#include "hif.h"1112static const struct hal_srng_config hw_srng_config_template[] = {13/* TODO: max_rings can populated by querying HW capabilities */14[HAL_REO_DST] = {15.start_ring_id = HAL_SRNG_RING_ID_REO2SW1,16.max_rings = 8,17.entry_size = sizeof(struct hal_reo_dest_ring) >> 2,18.mac_type = ATH12K_HAL_SRNG_UMAC,19.ring_dir = HAL_SRNG_DIR_DST,20.max_size = HAL_REO_REO2SW1_RING_BASE_MSB_RING_SIZE,21},22[HAL_REO_EXCEPTION] = {23/* Designating REO2SW0 ring as exception ring.24* Any of theREO2SW rings can be used as exception ring.25*/26.start_ring_id = HAL_SRNG_RING_ID_REO2SW0,27.max_rings = 1,28.entry_size = sizeof(struct hal_reo_dest_ring) >> 2,29.mac_type = ATH12K_HAL_SRNG_UMAC,30.ring_dir = HAL_SRNG_DIR_DST,31.max_size = HAL_REO_REO2SW0_RING_BASE_MSB_RING_SIZE,32},33[HAL_REO_REINJECT] = {34.start_ring_id = HAL_SRNG_RING_ID_SW2REO,35.max_rings = 4,36.entry_size = sizeof(struct hal_reo_entrance_ring) >> 2,37.mac_type = ATH12K_HAL_SRNG_UMAC,38.ring_dir = HAL_SRNG_DIR_SRC,39.max_size = HAL_REO_SW2REO_RING_BASE_MSB_RING_SIZE,40},41[HAL_REO_CMD] = {42.start_ring_id = HAL_SRNG_RING_ID_REO_CMD,43.max_rings = 1,44.entry_size = (sizeof(struct hal_tlv_64_hdr) +45sizeof(struct hal_reo_get_queue_stats)) >> 2,46.mac_type = ATH12K_HAL_SRNG_UMAC,47.ring_dir = HAL_SRNG_DIR_SRC,48.max_size = HAL_REO_CMD_RING_BASE_MSB_RING_SIZE,49},50[HAL_REO_STATUS] = {51.start_ring_id = HAL_SRNG_RING_ID_REO_STATUS,52.max_rings = 1,53.entry_size = (sizeof(struct hal_tlv_64_hdr) +54sizeof(struct hal_reo_get_queue_stats_status)) >> 2,55.mac_type = ATH12K_HAL_SRNG_UMAC,56.ring_dir = HAL_SRNG_DIR_DST,57.max_size = HAL_REO_STATUS_RING_BASE_MSB_RING_SIZE,58},59[HAL_TCL_DATA] = {60.start_ring_id = HAL_SRNG_RING_ID_SW2TCL1,61.max_rings = 6,62.entry_size = sizeof(struct hal_tcl_data_cmd) >> 2,63.mac_type = ATH12K_HAL_SRNG_UMAC,64.ring_dir = HAL_SRNG_DIR_SRC,65.max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE,66},67[HAL_TCL_CMD] = {68.start_ring_id = HAL_SRNG_RING_ID_SW2TCL_CMD,69.max_rings = 1,70.entry_size = sizeof(struct hal_tcl_gse_cmd) >> 2,71.mac_type = ATH12K_HAL_SRNG_UMAC,72.ring_dir = HAL_SRNG_DIR_SRC,73.max_size = HAL_SW2TCL1_CMD_RING_BASE_MSB_RING_SIZE,74},75[HAL_TCL_STATUS] = {76.start_ring_id = HAL_SRNG_RING_ID_TCL_STATUS,77.max_rings = 1,78.entry_size = (sizeof(struct hal_tlv_hdr) +79sizeof(struct hal_tcl_status_ring)) >> 2,80.mac_type = ATH12K_HAL_SRNG_UMAC,81.ring_dir = HAL_SRNG_DIR_DST,82.max_size = HAL_TCL_STATUS_RING_BASE_MSB_RING_SIZE,83},84[HAL_CE_SRC] = {85.start_ring_id = HAL_SRNG_RING_ID_CE0_SRC,86.max_rings = 16,87.entry_size = sizeof(struct hal_ce_srng_src_desc) >> 2,88.mac_type = ATH12K_HAL_SRNG_UMAC,89.ring_dir = HAL_SRNG_DIR_SRC,90.max_size = HAL_CE_SRC_RING_BASE_MSB_RING_SIZE,91},92[HAL_CE_DST] = {93.start_ring_id = HAL_SRNG_RING_ID_CE0_DST,94.max_rings = 16,95.entry_size = sizeof(struct hal_ce_srng_dest_desc) >> 2,96.mac_type = ATH12K_HAL_SRNG_UMAC,97.ring_dir = HAL_SRNG_DIR_SRC,98.max_size = HAL_CE_DST_RING_BASE_MSB_RING_SIZE,99},100[HAL_CE_DST_STATUS] = {101.start_ring_id = HAL_SRNG_RING_ID_CE0_DST_STATUS,102.max_rings = 16,103.entry_size = sizeof(struct hal_ce_srng_dst_status_desc) >> 2,104.mac_type = ATH12K_HAL_SRNG_UMAC,105.ring_dir = HAL_SRNG_DIR_DST,106.max_size = HAL_CE_DST_STATUS_RING_BASE_MSB_RING_SIZE,107},108[HAL_WBM_IDLE_LINK] = {109.start_ring_id = HAL_SRNG_RING_ID_WBM_IDLE_LINK,110.max_rings = 1,111.entry_size = sizeof(struct hal_wbm_link_desc) >> 2,112.mac_type = ATH12K_HAL_SRNG_UMAC,113.ring_dir = HAL_SRNG_DIR_SRC,114.max_size = HAL_WBM_IDLE_LINK_RING_BASE_MSB_RING_SIZE,115},116[HAL_SW2WBM_RELEASE] = {117.start_ring_id = HAL_SRNG_RING_ID_WBM_SW0_RELEASE,118.max_rings = 2,119.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,120.mac_type = ATH12K_HAL_SRNG_UMAC,121.ring_dir = HAL_SRNG_DIR_SRC,122.max_size = HAL_SW2WBM_RELEASE_RING_BASE_MSB_RING_SIZE,123},124[HAL_WBM2SW_RELEASE] = {125.start_ring_id = HAL_SRNG_RING_ID_WBM2SW0_RELEASE,126.max_rings = 8,127.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,128.mac_type = ATH12K_HAL_SRNG_UMAC,129.ring_dir = HAL_SRNG_DIR_DST,130.max_size = HAL_WBM2SW_RELEASE_RING_BASE_MSB_RING_SIZE,131},132[HAL_RXDMA_BUF] = {133.start_ring_id = HAL_SRNG_SW2RXDMA_BUF0,134.max_rings = 1,135.entry_size = sizeof(struct hal_wbm_buffer_ring) >> 2,136.mac_type = ATH12K_HAL_SRNG_DMAC,137.ring_dir = HAL_SRNG_DIR_SRC,138.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,139},140[HAL_RXDMA_DST] = {141.start_ring_id = HAL_SRNG_RING_ID_WMAC1_RXDMA2SW0,142.max_rings = 0,143.entry_size = 0,144.mac_type = ATH12K_HAL_SRNG_PMAC,145.ring_dir = HAL_SRNG_DIR_DST,146.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,147},148[HAL_RXDMA_MONITOR_BUF] = {149.start_ring_id = HAL_SRNG_SW2RXMON_BUF0,150.max_rings = 1,151.entry_size = sizeof(struct hal_mon_buf_ring) >> 2,152.mac_type = ATH12K_HAL_SRNG_PMAC,153.ring_dir = HAL_SRNG_DIR_SRC,154.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,155},156[HAL_RXDMA_MONITOR_STATUS] = { 0, },157[HAL_RXDMA_MONITOR_DESC] = { 0, },158[HAL_RXDMA_DIR_BUF] = {159.start_ring_id = HAL_SRNG_RING_ID_RXDMA_DIR_BUF,160.max_rings = 2,161.entry_size = 8 >> 2, /* TODO: Define the struct */162.mac_type = ATH12K_HAL_SRNG_PMAC,163.ring_dir = HAL_SRNG_DIR_SRC,164.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,165},166[HAL_PPE2TCL] = {167.start_ring_id = HAL_SRNG_RING_ID_PPE2TCL1,168.max_rings = 1,169.entry_size = sizeof(struct hal_tcl_entrance_from_ppe_ring) >> 2,170.mac_type = ATH12K_HAL_SRNG_PMAC,171.ring_dir = HAL_SRNG_DIR_SRC,172.max_size = HAL_SW2TCL1_RING_BASE_MSB_RING_SIZE,173},174[HAL_PPE_RELEASE] = {175.start_ring_id = HAL_SRNG_RING_ID_WBM_PPE_RELEASE,176.max_rings = 1,177.entry_size = sizeof(struct hal_wbm_release_ring) >> 2,178.mac_type = ATH12K_HAL_SRNG_PMAC,179.ring_dir = HAL_SRNG_DIR_SRC,180.max_size = HAL_WBM2PPE_RELEASE_RING_BASE_MSB_RING_SIZE,181},182[HAL_TX_MONITOR_BUF] = {183.start_ring_id = HAL_SRNG_SW2TXMON_BUF0,184.max_rings = 1,185.entry_size = sizeof(struct hal_mon_buf_ring) >> 2,186.mac_type = ATH12K_HAL_SRNG_PMAC,187.ring_dir = HAL_SRNG_DIR_SRC,188.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,189},190[HAL_RXDMA_MONITOR_DST] = {191.start_ring_id = HAL_SRNG_RING_ID_WMAC1_SW2RXMON_BUF0,192.max_rings = 1,193.entry_size = sizeof(struct hal_mon_dest_desc) >> 2,194.mac_type = ATH12K_HAL_SRNG_PMAC,195.ring_dir = HAL_SRNG_DIR_DST,196.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,197},198[HAL_TX_MONITOR_DST] = {199.start_ring_id = HAL_SRNG_RING_ID_WMAC1_TXMON2SW0_BUF0,200.max_rings = 1,201.entry_size = sizeof(struct hal_mon_dest_desc) >> 2,202.mac_type = ATH12K_HAL_SRNG_PMAC,203.ring_dir = HAL_SRNG_DIR_DST,204.max_size = HAL_RXDMA_RING_MAX_SIZE_BE,205}206};207208static const struct ath12k_hal_tcl_to_wbm_rbm_map209ath12k_hal_qcn9274_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = {210{211.wbm_ring_num = 0,212.rbm_id = HAL_RX_BUF_RBM_SW0_BM,213},214{215.wbm_ring_num = 1,216.rbm_id = HAL_RX_BUF_RBM_SW1_BM,217},218{219.wbm_ring_num = 2,220.rbm_id = HAL_RX_BUF_RBM_SW2_BM,221},222{223.wbm_ring_num = 4,224.rbm_id = HAL_RX_BUF_RBM_SW4_BM,225}226};227228static const struct ath12k_hal_tcl_to_wbm_rbm_map229ath12k_hal_wcn7850_tcl_to_wbm_rbm_map[DP_TCL_NUM_RING_MAX] = {230{231.wbm_ring_num = 0,232.rbm_id = HAL_RX_BUF_RBM_SW0_BM,233},234{235.wbm_ring_num = 2,236.rbm_id = HAL_RX_BUF_RBM_SW2_BM,237},238{239.wbm_ring_num = 4,240.rbm_id = HAL_RX_BUF_RBM_SW4_BM,241},242};243244static unsigned int ath12k_hal_reo1_ring_id_offset(struct ath12k_base *ab)245{246return HAL_REO1_RING_ID(ab) - HAL_REO1_RING_BASE_LSB(ab);247}248249static unsigned int ath12k_hal_reo1_ring_msi1_base_lsb_offset(struct ath12k_base *ab)250{251return HAL_REO1_RING_MSI1_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);252}253254static unsigned int ath12k_hal_reo1_ring_msi1_base_msb_offset(struct ath12k_base *ab)255{256return HAL_REO1_RING_MSI1_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);257}258259static unsigned int ath12k_hal_reo1_ring_msi1_data_offset(struct ath12k_base *ab)260{261return HAL_REO1_RING_MSI1_DATA(ab) - HAL_REO1_RING_BASE_LSB(ab);262}263264static unsigned int ath12k_hal_reo1_ring_base_msb_offset(struct ath12k_base *ab)265{266return HAL_REO1_RING_BASE_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);267}268269static unsigned int ath12k_hal_reo1_ring_producer_int_setup_offset(struct ath12k_base *ab)270{271return HAL_REO1_RING_PRODUCER_INT_SETUP(ab) - HAL_REO1_RING_BASE_LSB(ab);272}273274static unsigned int ath12k_hal_reo1_ring_hp_addr_lsb_offset(struct ath12k_base *ab)275{276return HAL_REO1_RING_HP_ADDR_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);277}278279static unsigned int ath12k_hal_reo1_ring_hp_addr_msb_offset(struct ath12k_base *ab)280{281return HAL_REO1_RING_HP_ADDR_MSB(ab) - HAL_REO1_RING_BASE_LSB(ab);282}283284static unsigned int ath12k_hal_reo1_ring_misc_offset(struct ath12k_base *ab)285{286return HAL_REO1_RING_MISC(ab) - HAL_REO1_RING_BASE_LSB(ab);287}288289static bool ath12k_hw_qcn9274_rx_desc_get_first_msdu(struct hal_rx_desc *desc)290{291return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5,292RX_MSDU_END_INFO5_FIRST_MSDU);293}294295static bool ath12k_hw_qcn9274_rx_desc_get_last_msdu(struct hal_rx_desc *desc)296{297return !!le16_get_bits(desc->u.qcn9274.msdu_end.info5,298RX_MSDU_END_INFO5_LAST_MSDU);299}300301static u8 ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)302{303return le16_get_bits(desc->u.qcn9274.msdu_end.info5,304RX_MSDU_END_INFO5_L3_HDR_PADDING);305}306307static bool ath12k_hw_qcn9274_rx_desc_encrypt_valid(struct hal_rx_desc *desc)308{309return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,310RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID);311}312313static u32 ath12k_hw_qcn9274_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)314{315return le32_get_bits(desc->u.qcn9274.mpdu_start.info2,316RX_MPDU_START_INFO2_ENC_TYPE);317}318319static u8 ath12k_hw_qcn9274_rx_desc_get_decap_type(struct hal_rx_desc *desc)320{321return le32_get_bits(desc->u.qcn9274.msdu_end.info11,322RX_MSDU_END_INFO11_DECAP_FORMAT);323}324325static u8 ath12k_hw_qcn9274_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)326{327return le32_get_bits(desc->u.qcn9274.msdu_end.info11,328RX_MSDU_END_INFO11_MESH_CTRL_PRESENT);329}330331static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)332{333return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,334RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID);335}336337static bool ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)338{339return !!le32_get_bits(desc->u.qcn9274.mpdu_start.info4,340RX_MPDU_START_INFO4_MPDU_FCTRL_VALID);341}342343static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)344{345return le32_get_bits(desc->u.qcn9274.mpdu_start.info4,346RX_MPDU_START_INFO4_MPDU_SEQ_NUM);347}348349static u16 ath12k_hw_qcn9274_rx_desc_get_msdu_len(struct hal_rx_desc *desc)350{351return le32_get_bits(desc->u.qcn9274.msdu_end.info10,352RX_MSDU_END_INFO10_MSDU_LENGTH);353}354355static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)356{357return le32_get_bits(desc->u.qcn9274.msdu_end.info12,358RX_MSDU_END_INFO12_SGI);359}360361static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)362{363return le32_get_bits(desc->u.qcn9274.msdu_end.info12,364RX_MSDU_END_INFO12_RATE_MCS);365}366367static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)368{369return le32_get_bits(desc->u.qcn9274.msdu_end.info12,370RX_MSDU_END_INFO12_RECV_BW);371}372373static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)374{375return __le32_to_cpu(desc->u.qcn9274.msdu_end.phy_meta_data);376}377378static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)379{380return le32_get_bits(desc->u.qcn9274.msdu_end.info12,381RX_MSDU_END_INFO12_PKT_TYPE);382}383384static u8 ath12k_hw_qcn9274_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)385{386return le32_get_bits(desc->u.qcn9274.msdu_end.info12,387RX_MSDU_END_INFO12_MIMO_SS_BITMAP);388}389390static u8 ath12k_hw_qcn9274_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)391{392return le16_get_bits(desc->u.qcn9274.msdu_end.info5,393RX_MSDU_END_INFO5_TID);394}395396static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)397{398return __le16_to_cpu(desc->u.qcn9274.mpdu_start.sw_peer_id);399}400401static void ath12k_hw_qcn9274_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,402struct hal_rx_desc *ldesc)403{404memcpy(&fdesc->u.qcn9274.msdu_end, &ldesc->u.qcn9274.msdu_end,405sizeof(struct rx_msdu_end_qcn9274));406}407408static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)409{410return __le16_to_cpu(desc->u.qcn9274.mpdu_start.phy_ppdu_id);411}412413static void ath12k_hw_qcn9274_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)414{415u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info10);416417info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH;418info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH);419420desc->u.qcn9274.msdu_end.info10 = __cpu_to_le32(info);421}422423static u8 *ath12k_hw_qcn9274_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)424{425return &desc->u.qcn9274.msdu_payload[0];426}427428static u32 ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset(void)429{430return offsetof(struct hal_rx_desc_qcn9274, mpdu_start);431}432433static u32 ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset(void)434{435return offsetof(struct hal_rx_desc_qcn9274, msdu_end);436}437438static bool ath12k_hw_qcn9274_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)439{440return __le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) &441RX_MPDU_START_INFO4_MAC_ADDR2_VALID;442}443444static u8 *ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)445{446return desc->u.qcn9274.mpdu_start.addr2;447}448449static bool ath12k_hw_qcn9274_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)450{451return __le16_to_cpu(desc->u.qcn9274.msdu_end.info5) &452RX_MSDU_END_INFO5_DA_IS_MCBC;453}454455static void ath12k_hw_qcn9274_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,456struct ieee80211_hdr *hdr)457{458hdr->frame_control = desc->u.qcn9274.mpdu_start.frame_ctrl;459hdr->duration_id = desc->u.qcn9274.mpdu_start.duration;460ether_addr_copy(hdr->addr1, desc->u.qcn9274.mpdu_start.addr1);461ether_addr_copy(hdr->addr2, desc->u.qcn9274.mpdu_start.addr2);462ether_addr_copy(hdr->addr3, desc->u.qcn9274.mpdu_start.addr3);463if (__le32_to_cpu(desc->u.qcn9274.mpdu_start.info4) &464RX_MPDU_START_INFO4_MAC_ADDR4_VALID) {465ether_addr_copy(hdr->addr4, desc->u.qcn9274.mpdu_start.addr4);466}467hdr->seq_ctrl = desc->u.qcn9274.mpdu_start.seq_ctrl;468}469470static void ath12k_hw_qcn9274_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,471u8 *crypto_hdr,472enum hal_encrypt_type enctype)473{474unsigned int key_id;475476switch (enctype) {477case HAL_ENCRYPT_TYPE_OPEN:478return;479case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:480case HAL_ENCRYPT_TYPE_TKIP_MIC:481crypto_hdr[0] =482HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]);483crypto_hdr[1] = 0;484crypto_hdr[2] =485HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]);486break;487case HAL_ENCRYPT_TYPE_CCMP_128:488case HAL_ENCRYPT_TYPE_CCMP_256:489case HAL_ENCRYPT_TYPE_GCMP_128:490case HAL_ENCRYPT_TYPE_AES_GCMP_256:491crypto_hdr[0] =492HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[0]);493crypto_hdr[1] =494HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[0]);495crypto_hdr[2] = 0;496break;497case HAL_ENCRYPT_TYPE_WEP_40:498case HAL_ENCRYPT_TYPE_WEP_104:499case HAL_ENCRYPT_TYPE_WEP_128:500case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:501case HAL_ENCRYPT_TYPE_WAPI:502return;503}504key_id = le32_get_bits(desc->u.qcn9274.mpdu_start.info5,505RX_MPDU_START_INFO5_KEY_ID);506crypto_hdr[3] = 0x20 | (key_id << 6);507crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.qcn9274.mpdu_start.pn[0]);508crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.qcn9274.mpdu_start.pn[0]);509crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.qcn9274.mpdu_start.pn[1]);510crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.qcn9274.mpdu_start.pn[1]);511}512513static u16 ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)514{515return __le16_to_cpu(desc->u.qcn9274.mpdu_start.frame_ctrl);516}517518static int ath12k_hal_srng_create_config_qcn9274(struct ath12k_base *ab)519{520struct ath12k_hal *hal = &ab->hal;521struct hal_srng_config *s;522523hal->srng_config = kmemdup(hw_srng_config_template,524sizeof(hw_srng_config_template),525GFP_KERNEL);526if (!hal->srng_config)527return -ENOMEM;528529s = &hal->srng_config[HAL_REO_DST];530s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab);531s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP;532s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);533s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP;534535s = &hal->srng_config[HAL_REO_EXCEPTION];536s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab);537s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP;538539s = &hal->srng_config[HAL_REO_REINJECT];540s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab);541s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP;542s->reg_size[0] = HAL_SW2REO1_RING_BASE_LSB(ab) - HAL_SW2REO_RING_BASE_LSB(ab);543s->reg_size[1] = HAL_SW2REO1_RING_HP - HAL_SW2REO_RING_HP;544545s = &hal->srng_config[HAL_REO_CMD];546s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab);547s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP;548549s = &hal->srng_config[HAL_REO_STATUS];550s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab);551s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP;552553s = &hal->srng_config[HAL_TCL_DATA];554s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB;555s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;556s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB;557s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP;558559s = &hal->srng_config[HAL_TCL_CMD];560s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab);561s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP;562563s = &hal->srng_config[HAL_TCL_STATUS];564s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);565s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;566567s = &hal->srng_config[HAL_CE_SRC];568s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB;569s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP;570s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -571HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;572s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -573HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;574575s = &hal->srng_config[HAL_CE_DST];576s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB;577s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP;578s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -579HAL_SEQ_WCSS_UMAC_CE0_DST_REG;580s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -581HAL_SEQ_WCSS_UMAC_CE0_DST_REG;582583s = &hal->srng_config[HAL_CE_DST_STATUS];584s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG +585HAL_CE_DST_STATUS_RING_BASE_LSB;586s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP;587s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -588HAL_SEQ_WCSS_UMAC_CE0_DST_REG;589s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -590HAL_SEQ_WCSS_UMAC_CE0_DST_REG;591592s = &hal->srng_config[HAL_WBM_IDLE_LINK];593s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);594s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;595596s = &hal->srng_config[HAL_SW2WBM_RELEASE];597s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +598HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);599s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP;600s->reg_size[0] = HAL_WBM_SW1_RELEASE_RING_BASE_LSB(ab) -601HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);602s->reg_size[1] = HAL_WBM_SW1_RELEASE_RING_HP - HAL_WBM_SW_RELEASE_RING_HP;603604s = &hal->srng_config[HAL_WBM2SW_RELEASE];605s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);606s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;607s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -608HAL_WBM0_RELEASE_RING_BASE_LSB(ab);609s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;610611/* Some LMAC rings are not accessed from the host:612* RXDMA_BUG, RXDMA_DST, RXDMA_MONITOR_BUF, RXDMA_MONITOR_STATUS,613* RXDMA_MONITOR_DST, RXDMA_MONITOR_DESC, RXDMA_DIR_BUF_SRC,614* RXDMA_RX_MONITOR_BUF, TX_MONITOR_BUF, TX_MONITOR_DST, SW2RXDMA615*/616s = &hal->srng_config[HAL_PPE2TCL];617s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_BASE_LSB;618s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_PPE2TCL1_RING_HP;619620s = &hal->srng_config[HAL_PPE_RELEASE];621s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +622HAL_WBM_PPE_RELEASE_RING_BASE_LSB(ab);623s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_PPE_RELEASE_RING_HP;624625return 0;626}627628static bool ath12k_hw_qcn9274_dp_rx_h_msdu_done(struct hal_rx_desc *desc)629{630return !!le32_get_bits(desc->u.qcn9274.msdu_end.info14,631RX_MSDU_END_INFO14_MSDU_DONE);632}633634static bool ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc)635{636return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13,637RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL);638}639640static bool ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc)641{642return !!le32_get_bits(desc->u.qcn9274.msdu_end.info13,643RX_MSDU_END_INFO13_IP_CKSUM_FAIL);644}645646static bool ath12k_hw_qcn9274_dp_rx_h_is_decrypted(struct hal_rx_desc *desc)647{648return (le32_get_bits(desc->u.qcn9274.msdu_end.info14,649RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==650RX_DESC_DECRYPT_STATUS_CODE_OK);651}652653static u32 ath12k_hw_qcn9274_dp_rx_h_mpdu_err(struct hal_rx_desc *desc)654{655u32 info = __le32_to_cpu(desc->u.qcn9274.msdu_end.info13);656u32 errmap = 0;657658if (info & RX_MSDU_END_INFO13_FCS_ERR)659errmap |= HAL_RX_MPDU_ERR_FCS;660661if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)662errmap |= HAL_RX_MPDU_ERR_DECRYPT;663664if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)665errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;666667if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)668errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;669670if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)671errmap |= HAL_RX_MPDU_ERR_OVERFLOW;672673if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)674errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;675676if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)677errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;678679return errmap;680}681682const struct hal_ops hal_qcn9274_ops = {683.rx_desc_get_first_msdu = ath12k_hw_qcn9274_rx_desc_get_first_msdu,684.rx_desc_get_last_msdu = ath12k_hw_qcn9274_rx_desc_get_last_msdu,685.rx_desc_get_l3_pad_bytes = ath12k_hw_qcn9274_rx_desc_get_l3_pad_bytes,686.rx_desc_encrypt_valid = ath12k_hw_qcn9274_rx_desc_encrypt_valid,687.rx_desc_get_encrypt_type = ath12k_hw_qcn9274_rx_desc_get_encrypt_type,688.rx_desc_get_decap_type = ath12k_hw_qcn9274_rx_desc_get_decap_type,689.rx_desc_get_mesh_ctl = ath12k_hw_qcn9274_rx_desc_get_mesh_ctl,690.rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_qcn9274_rx_desc_get_mpdu_seq_ctl_vld,691.rx_desc_get_mpdu_fc_valid = ath12k_hw_qcn9274_rx_desc_get_mpdu_fc_valid,692.rx_desc_get_mpdu_start_seq_no = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_seq_no,693.rx_desc_get_msdu_len = ath12k_hw_qcn9274_rx_desc_get_msdu_len,694.rx_desc_get_msdu_sgi = ath12k_hw_qcn9274_rx_desc_get_msdu_sgi,695.rx_desc_get_msdu_rate_mcs = ath12k_hw_qcn9274_rx_desc_get_msdu_rate_mcs,696.rx_desc_get_msdu_rx_bw = ath12k_hw_qcn9274_rx_desc_get_msdu_rx_bw,697.rx_desc_get_msdu_freq = ath12k_hw_qcn9274_rx_desc_get_msdu_freq,698.rx_desc_get_msdu_pkt_type = ath12k_hw_qcn9274_rx_desc_get_msdu_pkt_type,699.rx_desc_get_msdu_nss = ath12k_hw_qcn9274_rx_desc_get_msdu_nss,700.rx_desc_get_mpdu_tid = ath12k_hw_qcn9274_rx_desc_get_mpdu_tid,701.rx_desc_get_mpdu_peer_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_peer_id,702.rx_desc_copy_end_tlv = ath12k_hw_qcn9274_rx_desc_copy_end_tlv,703.rx_desc_get_mpdu_ppdu_id = ath12k_hw_qcn9274_rx_desc_get_mpdu_ppdu_id,704.rx_desc_set_msdu_len = ath12k_hw_qcn9274_rx_desc_set_msdu_len,705.rx_desc_get_msdu_payload = ath12k_hw_qcn9274_rx_desc_get_msdu_payload,706.rx_desc_get_mpdu_start_offset = ath12k_hw_qcn9274_rx_desc_get_mpdu_start_offset,707.rx_desc_get_msdu_end_offset = ath12k_hw_qcn9274_rx_desc_get_msdu_end_offset,708.rx_desc_mac_addr2_valid = ath12k_hw_qcn9274_rx_desc_mac_addr2_valid,709.rx_desc_mpdu_start_addr2 = ath12k_hw_qcn9274_rx_desc_mpdu_start_addr2,710.rx_desc_is_da_mcbc = ath12k_hw_qcn9274_rx_desc_is_da_mcbc,711.rx_desc_get_dot11_hdr = ath12k_hw_qcn9274_rx_desc_get_dot11_hdr,712.rx_desc_get_crypto_header = ath12k_hw_qcn9274_rx_desc_get_crypto_hdr,713.rx_desc_get_mpdu_frame_ctl = ath12k_hw_qcn9274_rx_desc_get_mpdu_frame_ctl,714.create_srng_config = ath12k_hal_srng_create_config_qcn9274,715.tcl_to_wbm_rbm_map = ath12k_hal_qcn9274_tcl_to_wbm_rbm_map,716.dp_rx_h_msdu_done = ath12k_hw_qcn9274_dp_rx_h_msdu_done,717.dp_rx_h_l4_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_l4_cksum_fail,718.dp_rx_h_ip_cksum_fail = ath12k_hw_qcn9274_dp_rx_h_ip_cksum_fail,719.dp_rx_h_is_decrypted = ath12k_hw_qcn9274_dp_rx_h_is_decrypted,720.dp_rx_h_mpdu_err = ath12k_hw_qcn9274_dp_rx_h_mpdu_err,721};722723static bool ath12k_hw_wcn7850_rx_desc_get_first_msdu(struct hal_rx_desc *desc)724{725return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5,726RX_MSDU_END_INFO5_FIRST_MSDU);727}728729static bool ath12k_hw_wcn7850_rx_desc_get_last_msdu(struct hal_rx_desc *desc)730{731return !!le16_get_bits(desc->u.wcn7850.msdu_end.info5,732RX_MSDU_END_INFO5_LAST_MSDU);733}734735static u8 ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes(struct hal_rx_desc *desc)736{737return le16_get_bits(desc->u.wcn7850.msdu_end.info5,738RX_MSDU_END_INFO5_L3_HDR_PADDING);739}740741static bool ath12k_hw_wcn7850_rx_desc_encrypt_valid(struct hal_rx_desc *desc)742{743return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,744RX_MPDU_START_INFO4_ENCRYPT_INFO_VALID);745}746747static u32 ath12k_hw_wcn7850_rx_desc_get_encrypt_type(struct hal_rx_desc *desc)748{749return le32_get_bits(desc->u.wcn7850.mpdu_start.info2,750RX_MPDU_START_INFO2_ENC_TYPE);751}752753static u8 ath12k_hw_wcn7850_rx_desc_get_decap_type(struct hal_rx_desc *desc)754{755return le32_get_bits(desc->u.wcn7850.msdu_end.info11,756RX_MSDU_END_INFO11_DECAP_FORMAT);757}758759static u8 ath12k_hw_wcn7850_rx_desc_get_mesh_ctl(struct hal_rx_desc *desc)760{761return le32_get_bits(desc->u.wcn7850.msdu_end.info11,762RX_MSDU_END_INFO11_MESH_CTRL_PRESENT);763}764765static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld(struct hal_rx_desc *desc)766{767return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,768RX_MPDU_START_INFO4_MPDU_SEQ_CTRL_VALID);769}770771static bool ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid(struct hal_rx_desc *desc)772{773return !!le32_get_bits(desc->u.wcn7850.mpdu_start.info4,774RX_MPDU_START_INFO4_MPDU_FCTRL_VALID);775}776777static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no(struct hal_rx_desc *desc)778{779return le32_get_bits(desc->u.wcn7850.mpdu_start.info4,780RX_MPDU_START_INFO4_MPDU_SEQ_NUM);781}782783static u16 ath12k_hw_wcn7850_rx_desc_get_msdu_len(struct hal_rx_desc *desc)784{785return le32_get_bits(desc->u.wcn7850.msdu_end.info10,786RX_MSDU_END_INFO10_MSDU_LENGTH);787}788789static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_sgi(struct hal_rx_desc *desc)790{791return le32_get_bits(desc->u.wcn7850.msdu_end.info12,792RX_MSDU_END_INFO12_SGI);793}794795static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs(struct hal_rx_desc *desc)796{797return le32_get_bits(desc->u.wcn7850.msdu_end.info12,798RX_MSDU_END_INFO12_RATE_MCS);799}800801static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw(struct hal_rx_desc *desc)802{803return le32_get_bits(desc->u.wcn7850.msdu_end.info12,804RX_MSDU_END_INFO12_RECV_BW);805}806807static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_freq(struct hal_rx_desc *desc)808{809return __le32_to_cpu(desc->u.wcn7850.msdu_end.phy_meta_data);810}811812static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type(struct hal_rx_desc *desc)813{814return le32_get_bits(desc->u.wcn7850.msdu_end.info12,815RX_MSDU_END_INFO12_PKT_TYPE);816}817818static u8 ath12k_hw_wcn7850_rx_desc_get_msdu_nss(struct hal_rx_desc *desc)819{820return le32_get_bits(desc->u.wcn7850.msdu_end.info12,821RX_MSDU_END_INFO12_MIMO_SS_BITMAP);822}823824static u8 ath12k_hw_wcn7850_rx_desc_get_mpdu_tid(struct hal_rx_desc *desc)825{826return le16_get_bits(desc->u.wcn7850.msdu_end.info5,827RX_MSDU_END_INFO5_TID);828}829830static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id(struct hal_rx_desc *desc)831{832return __le16_to_cpu(desc->u.wcn7850.mpdu_start.sw_peer_id);833}834835static void ath12k_hw_wcn7850_rx_desc_copy_end_tlv(struct hal_rx_desc *fdesc,836struct hal_rx_desc *ldesc)837{838memcpy(&fdesc->u.wcn7850.msdu_end, &ldesc->u.wcn7850.msdu_end,839sizeof(struct rx_msdu_end_qcn9274));840}841842static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag(struct hal_rx_desc *desc)843{844return le64_get_bits(desc->u.wcn7850.mpdu_start_tag,845HAL_TLV_HDR_TAG);846}847848static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id(struct hal_rx_desc *desc)849{850return __le16_to_cpu(desc->u.wcn7850.mpdu_start.phy_ppdu_id);851}852853static void ath12k_hw_wcn7850_rx_desc_set_msdu_len(struct hal_rx_desc *desc, u16 len)854{855u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info10);856857info &= ~RX_MSDU_END_INFO10_MSDU_LENGTH;858info |= u32_encode_bits(len, RX_MSDU_END_INFO10_MSDU_LENGTH);859860desc->u.wcn7850.msdu_end.info10 = __cpu_to_le32(info);861}862863static u8 *ath12k_hw_wcn7850_rx_desc_get_msdu_payload(struct hal_rx_desc *desc)864{865return &desc->u.wcn7850.msdu_payload[0];866}867868static u32 ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset(void)869{870return offsetof(struct hal_rx_desc_wcn7850, mpdu_start_tag);871}872873static u32 ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset(void)874{875return offsetof(struct hal_rx_desc_wcn7850, msdu_end_tag);876}877878static bool ath12k_hw_wcn7850_rx_desc_mac_addr2_valid(struct hal_rx_desc *desc)879{880return __le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) &881RX_MPDU_START_INFO4_MAC_ADDR2_VALID;882}883884static u8 *ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2(struct hal_rx_desc *desc)885{886return desc->u.wcn7850.mpdu_start.addr2;887}888889static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc)890{891return __le16_to_cpu(desc->u.wcn7850.msdu_end.info5) &892RX_MSDU_END_INFO5_DA_IS_MCBC;893}894895static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc,896struct ieee80211_hdr *hdr)897{898hdr->frame_control = desc->u.wcn7850.mpdu_start.frame_ctrl;899hdr->duration_id = desc->u.wcn7850.mpdu_start.duration;900ether_addr_copy(hdr->addr1, desc->u.wcn7850.mpdu_start.addr1);901ether_addr_copy(hdr->addr2, desc->u.wcn7850.mpdu_start.addr2);902ether_addr_copy(hdr->addr3, desc->u.wcn7850.mpdu_start.addr3);903if (__le32_to_cpu(desc->u.wcn7850.mpdu_start.info4) &904RX_MPDU_START_INFO4_MAC_ADDR4_VALID) {905ether_addr_copy(hdr->addr4, desc->u.wcn7850.mpdu_start.addr4);906}907hdr->seq_ctrl = desc->u.wcn7850.mpdu_start.seq_ctrl;908}909910static void ath12k_hw_wcn7850_rx_desc_get_crypto_hdr(struct hal_rx_desc *desc,911u8 *crypto_hdr,912enum hal_encrypt_type enctype)913{914unsigned int key_id;915916switch (enctype) {917case HAL_ENCRYPT_TYPE_OPEN:918return;919case HAL_ENCRYPT_TYPE_TKIP_NO_MIC:920case HAL_ENCRYPT_TYPE_TKIP_MIC:921crypto_hdr[0] =922HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]);923crypto_hdr[1] = 0;924crypto_hdr[2] =925HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]);926break;927case HAL_ENCRYPT_TYPE_CCMP_128:928case HAL_ENCRYPT_TYPE_CCMP_256:929case HAL_ENCRYPT_TYPE_GCMP_128:930case HAL_ENCRYPT_TYPE_AES_GCMP_256:931crypto_hdr[0] =932HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[0]);933crypto_hdr[1] =934HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[0]);935crypto_hdr[2] = 0;936break;937case HAL_ENCRYPT_TYPE_WEP_40:938case HAL_ENCRYPT_TYPE_WEP_104:939case HAL_ENCRYPT_TYPE_WEP_128:940case HAL_ENCRYPT_TYPE_WAPI_GCM_SM4:941case HAL_ENCRYPT_TYPE_WAPI:942return;943}944key_id = u32_get_bits(__le32_to_cpu(desc->u.wcn7850.mpdu_start.info5),945RX_MPDU_START_INFO5_KEY_ID);946crypto_hdr[3] = 0x20 | (key_id << 6);947crypto_hdr[4] = HAL_RX_MPDU_INFO_PN_GET_BYTE3(desc->u.wcn7850.mpdu_start.pn[0]);948crypto_hdr[5] = HAL_RX_MPDU_INFO_PN_GET_BYTE4(desc->u.wcn7850.mpdu_start.pn[0]);949crypto_hdr[6] = HAL_RX_MPDU_INFO_PN_GET_BYTE1(desc->u.wcn7850.mpdu_start.pn[1]);950crypto_hdr[7] = HAL_RX_MPDU_INFO_PN_GET_BYTE2(desc->u.wcn7850.mpdu_start.pn[1]);951}952953static u16 ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl(struct hal_rx_desc *desc)954{955return __le16_to_cpu(desc->u.wcn7850.mpdu_start.frame_ctrl);956}957958static int ath12k_hal_srng_create_config_wcn7850(struct ath12k_base *ab)959{960struct ath12k_hal *hal = &ab->hal;961struct hal_srng_config *s;962963hal->srng_config = kmemdup(hw_srng_config_template,964sizeof(hw_srng_config_template),965GFP_KERNEL);966if (!hal->srng_config)967return -ENOMEM;968969s = &hal->srng_config[HAL_REO_DST];970s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_BASE_LSB(ab);971s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO1_RING_HP;972s->reg_size[0] = HAL_REO2_RING_BASE_LSB(ab) - HAL_REO1_RING_BASE_LSB(ab);973s->reg_size[1] = HAL_REO2_RING_HP - HAL_REO1_RING_HP;974975s = &hal->srng_config[HAL_REO_EXCEPTION];976s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_BASE_LSB(ab);977s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_SW0_RING_HP;978979s = &hal->srng_config[HAL_REO_REINJECT];980s->max_rings = 1;981s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_BASE_LSB(ab);982s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_SW2REO_RING_HP;983984s = &hal->srng_config[HAL_REO_CMD];985s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_RING_BASE_LSB(ab);986s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_CMD_HP;987988s = &hal->srng_config[HAL_REO_STATUS];989s->reg_start[0] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_RING_BASE_LSB(ab);990s->reg_start[1] = HAL_SEQ_WCSS_UMAC_REO_REG + HAL_REO_STATUS_HP;991992s = &hal->srng_config[HAL_TCL_DATA];993s->max_rings = 5;994s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_BASE_LSB;995s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL1_RING_HP;996s->reg_size[0] = HAL_TCL2_RING_BASE_LSB - HAL_TCL1_RING_BASE_LSB;997s->reg_size[1] = HAL_TCL2_RING_HP - HAL_TCL1_RING_HP;998999s = &hal->srng_config[HAL_TCL_CMD];1000s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_BASE_LSB(ab);1001s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_RING_HP;10021003s = &hal->srng_config[HAL_TCL_STATUS];1004s->reg_start[0] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_BASE_LSB(ab);1005s->reg_start[1] = HAL_SEQ_WCSS_UMAC_TCL_REG + HAL_TCL_STATUS_RING_HP;10061007s = &hal->srng_config[HAL_CE_SRC];1008s->max_rings = 12;1009s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_BASE_LSB;1010s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_SRC_REG + HAL_CE_DST_RING_HP;1011s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -1012HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;1013s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_SRC_REG -1014HAL_SEQ_WCSS_UMAC_CE0_SRC_REG;10151016s = &hal->srng_config[HAL_CE_DST];1017s->max_rings = 12;1018s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_BASE_LSB;1019s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_RING_HP;1020s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -1021HAL_SEQ_WCSS_UMAC_CE0_DST_REG;1022s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -1023HAL_SEQ_WCSS_UMAC_CE0_DST_REG;10241025s = &hal->srng_config[HAL_CE_DST_STATUS];1026s->max_rings = 12;1027s->reg_start[0] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG +1028HAL_CE_DST_STATUS_RING_BASE_LSB;1029s->reg_start[1] = HAL_SEQ_WCSS_UMAC_CE0_DST_REG + HAL_CE_DST_STATUS_RING_HP;1030s->reg_size[0] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -1031HAL_SEQ_WCSS_UMAC_CE0_DST_REG;1032s->reg_size[1] = HAL_SEQ_WCSS_UMAC_CE1_DST_REG -1033HAL_SEQ_WCSS_UMAC_CE0_DST_REG;10341035s = &hal->srng_config[HAL_WBM_IDLE_LINK];1036s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_BASE_LSB(ab);1037s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_IDLE_LINK_RING_HP;10381039s = &hal->srng_config[HAL_SW2WBM_RELEASE];1040s->max_rings = 1;1041s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG +1042HAL_WBM_SW_RELEASE_RING_BASE_LSB(ab);1043s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_SW_RELEASE_RING_HP;10441045s = &hal->srng_config[HAL_WBM2SW_RELEASE];1046s->reg_start[0] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_BASE_LSB(ab);1047s->reg_start[1] = HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM0_RELEASE_RING_HP;1048s->reg_size[0] = HAL_WBM1_RELEASE_RING_BASE_LSB(ab) -1049HAL_WBM0_RELEASE_RING_BASE_LSB(ab);1050s->reg_size[1] = HAL_WBM1_RELEASE_RING_HP - HAL_WBM0_RELEASE_RING_HP;10511052s = &hal->srng_config[HAL_RXDMA_BUF];1053s->max_rings = 2;1054s->mac_type = ATH12K_HAL_SRNG_PMAC;10551056s = &hal->srng_config[HAL_RXDMA_DST];1057s->max_rings = 1;1058s->entry_size = sizeof(struct hal_reo_entrance_ring) >> 2;10591060/* below rings are not used */1061s = &hal->srng_config[HAL_RXDMA_DIR_BUF];1062s->max_rings = 0;10631064s = &hal->srng_config[HAL_PPE2TCL];1065s->max_rings = 0;10661067s = &hal->srng_config[HAL_PPE_RELEASE];1068s->max_rings = 0;10691070s = &hal->srng_config[HAL_TX_MONITOR_BUF];1071s->max_rings = 0;10721073s = &hal->srng_config[HAL_TX_MONITOR_DST];1074s->max_rings = 0;10751076s = &hal->srng_config[HAL_PPE2TCL];1077s->max_rings = 0;10781079return 0;1080}10811082static bool ath12k_hw_wcn7850_dp_rx_h_msdu_done(struct hal_rx_desc *desc)1083{1084return !!le32_get_bits(desc->u.wcn7850.msdu_end.info14,1085RX_MSDU_END_INFO14_MSDU_DONE);1086}10871088static bool ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail(struct hal_rx_desc *desc)1089{1090return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13,1091RX_MSDU_END_INFO13_TCP_UDP_CKSUM_FAIL);1092}10931094static bool ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail(struct hal_rx_desc *desc)1095{1096return !!le32_get_bits(desc->u.wcn7850.msdu_end.info13,1097RX_MSDU_END_INFO13_IP_CKSUM_FAIL);1098}10991100static bool ath12k_hw_wcn7850_dp_rx_h_is_decrypted(struct hal_rx_desc *desc)1101{1102return (le32_get_bits(desc->u.wcn7850.msdu_end.info14,1103RX_MSDU_END_INFO14_DECRYPT_STATUS_CODE) ==1104RX_DESC_DECRYPT_STATUS_CODE_OK);1105}11061107static u32 ath12k_hw_wcn7850_dp_rx_h_mpdu_err(struct hal_rx_desc *desc)1108{1109u32 info = __le32_to_cpu(desc->u.wcn7850.msdu_end.info13);1110u32 errmap = 0;11111112if (info & RX_MSDU_END_INFO13_FCS_ERR)1113errmap |= HAL_RX_MPDU_ERR_FCS;11141115if (info & RX_MSDU_END_INFO13_DECRYPT_ERR)1116errmap |= HAL_RX_MPDU_ERR_DECRYPT;11171118if (info & RX_MSDU_END_INFO13_TKIP_MIC_ERR)1119errmap |= HAL_RX_MPDU_ERR_TKIP_MIC;11201121if (info & RX_MSDU_END_INFO13_A_MSDU_ERROR)1122errmap |= HAL_RX_MPDU_ERR_AMSDU_ERR;11231124if (info & RX_MSDU_END_INFO13_OVERFLOW_ERR)1125errmap |= HAL_RX_MPDU_ERR_OVERFLOW;11261127if (info & RX_MSDU_END_INFO13_MSDU_LEN_ERR)1128errmap |= HAL_RX_MPDU_ERR_MSDU_LEN;11291130if (info & RX_MSDU_END_INFO13_MPDU_LEN_ERR)1131errmap |= HAL_RX_MPDU_ERR_MPDU_LEN;11321133return errmap;1134}11351136const struct hal_ops hal_wcn7850_ops = {1137.rx_desc_get_first_msdu = ath12k_hw_wcn7850_rx_desc_get_first_msdu,1138.rx_desc_get_last_msdu = ath12k_hw_wcn7850_rx_desc_get_last_msdu,1139.rx_desc_get_l3_pad_bytes = ath12k_hw_wcn7850_rx_desc_get_l3_pad_bytes,1140.rx_desc_encrypt_valid = ath12k_hw_wcn7850_rx_desc_encrypt_valid,1141.rx_desc_get_encrypt_type = ath12k_hw_wcn7850_rx_desc_get_encrypt_type,1142.rx_desc_get_decap_type = ath12k_hw_wcn7850_rx_desc_get_decap_type,1143.rx_desc_get_mesh_ctl = ath12k_hw_wcn7850_rx_desc_get_mesh_ctl,1144.rx_desc_get_mpdu_seq_ctl_vld = ath12k_hw_wcn7850_rx_desc_get_mpdu_seq_ctl_vld,1145.rx_desc_get_mpdu_fc_valid = ath12k_hw_wcn7850_rx_desc_get_mpdu_fc_valid,1146.rx_desc_get_mpdu_start_seq_no = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_seq_no,1147.rx_desc_get_msdu_len = ath12k_hw_wcn7850_rx_desc_get_msdu_len,1148.rx_desc_get_msdu_sgi = ath12k_hw_wcn7850_rx_desc_get_msdu_sgi,1149.rx_desc_get_msdu_rate_mcs = ath12k_hw_wcn7850_rx_desc_get_msdu_rate_mcs,1150.rx_desc_get_msdu_rx_bw = ath12k_hw_wcn7850_rx_desc_get_msdu_rx_bw,1151.rx_desc_get_msdu_freq = ath12k_hw_wcn7850_rx_desc_get_msdu_freq,1152.rx_desc_get_msdu_pkt_type = ath12k_hw_wcn7850_rx_desc_get_msdu_pkt_type,1153.rx_desc_get_msdu_nss = ath12k_hw_wcn7850_rx_desc_get_msdu_nss,1154.rx_desc_get_mpdu_tid = ath12k_hw_wcn7850_rx_desc_get_mpdu_tid,1155.rx_desc_get_mpdu_peer_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_peer_id,1156.rx_desc_copy_end_tlv = ath12k_hw_wcn7850_rx_desc_copy_end_tlv,1157.rx_desc_get_mpdu_start_tag = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_tag,1158.rx_desc_get_mpdu_ppdu_id = ath12k_hw_wcn7850_rx_desc_get_mpdu_ppdu_id,1159.rx_desc_set_msdu_len = ath12k_hw_wcn7850_rx_desc_set_msdu_len,1160.rx_desc_get_msdu_payload = ath12k_hw_wcn7850_rx_desc_get_msdu_payload,1161.rx_desc_get_mpdu_start_offset = ath12k_hw_wcn7850_rx_desc_get_mpdu_start_offset,1162.rx_desc_get_msdu_end_offset = ath12k_hw_wcn7850_rx_desc_get_msdu_end_offset,1163.rx_desc_mac_addr2_valid = ath12k_hw_wcn7850_rx_desc_mac_addr2_valid,1164.rx_desc_mpdu_start_addr2 = ath12k_hw_wcn7850_rx_desc_mpdu_start_addr2,1165.rx_desc_is_da_mcbc = ath12k_hw_wcn7850_rx_desc_is_da_mcbc,1166.rx_desc_get_dot11_hdr = ath12k_hw_wcn7850_rx_desc_get_dot11_hdr,1167.rx_desc_get_crypto_header = ath12k_hw_wcn7850_rx_desc_get_crypto_hdr,1168.rx_desc_get_mpdu_frame_ctl = ath12k_hw_wcn7850_rx_desc_get_mpdu_frame_ctl,1169.create_srng_config = ath12k_hal_srng_create_config_wcn7850,1170.tcl_to_wbm_rbm_map = ath12k_hal_wcn7850_tcl_to_wbm_rbm_map,1171.dp_rx_h_msdu_done = ath12k_hw_wcn7850_dp_rx_h_msdu_done,1172.dp_rx_h_l4_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_l4_cksum_fail,1173.dp_rx_h_ip_cksum_fail = ath12k_hw_wcn7850_dp_rx_h_ip_cksum_fail,1174.dp_rx_h_is_decrypted = ath12k_hw_wcn7850_dp_rx_h_is_decrypted,1175.dp_rx_h_mpdu_err = ath12k_hw_wcn7850_dp_rx_h_mpdu_err,1176};11771178static int ath12k_hal_alloc_cont_rdp(struct ath12k_base *ab)1179{1180struct ath12k_hal *hal = &ab->hal;1181size_t size;11821183size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;1184hal->rdp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->rdp.paddr,1185GFP_KERNEL);1186if (!hal->rdp.vaddr)1187return -ENOMEM;11881189return 0;1190}11911192static void ath12k_hal_free_cont_rdp(struct ath12k_base *ab)1193{1194struct ath12k_hal *hal = &ab->hal;1195size_t size;11961197if (!hal->rdp.vaddr)1198return;11991200size = sizeof(u32) * HAL_SRNG_RING_ID_MAX;1201dma_free_coherent(ab->dev, size,1202hal->rdp.vaddr, hal->rdp.paddr);1203hal->rdp.vaddr = NULL;1204}12051206static int ath12k_hal_alloc_cont_wrp(struct ath12k_base *ab)1207{1208struct ath12k_hal *hal = &ab->hal;1209size_t size;12101211size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS);1212hal->wrp.vaddr = dma_alloc_coherent(ab->dev, size, &hal->wrp.paddr,1213GFP_KERNEL);1214if (!hal->wrp.vaddr)1215return -ENOMEM;12161217return 0;1218}12191220static void ath12k_hal_free_cont_wrp(struct ath12k_base *ab)1221{1222struct ath12k_hal *hal = &ab->hal;1223size_t size;12241225if (!hal->wrp.vaddr)1226return;12271228size = sizeof(u32) * (HAL_SRNG_NUM_PMAC_RINGS + HAL_SRNG_NUM_DMAC_RINGS);1229dma_free_coherent(ab->dev, size,1230hal->wrp.vaddr, hal->wrp.paddr);1231hal->wrp.vaddr = NULL;1232}12331234static void ath12k_hal_ce_dst_setup(struct ath12k_base *ab,1235struct hal_srng *srng, int ring_num)1236{1237struct hal_srng_config *srng_config = &ab->hal.srng_config[HAL_CE_DST];1238u32 addr;1239u32 val;12401241addr = HAL_CE_DST_RING_CTRL +1242srng_config->reg_start[HAL_SRNG_REG_GRP_R0] +1243ring_num * srng_config->reg_size[HAL_SRNG_REG_GRP_R0];12441245val = ath12k_hif_read32(ab, addr);1246val &= ~HAL_CE_DST_R0_DEST_CTRL_MAX_LEN;1247val |= u32_encode_bits(srng->u.dst_ring.max_buffer_length,1248HAL_CE_DST_R0_DEST_CTRL_MAX_LEN);1249ath12k_hif_write32(ab, addr, val);1250}12511252static void ath12k_hal_srng_dst_hw_init(struct ath12k_base *ab,1253struct hal_srng *srng)1254{1255struct ath12k_hal *hal = &ab->hal;1256u32 val;1257u64 hp_addr;1258u32 reg_base;12591260reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];12611262if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {1263ath12k_hif_write32(ab, reg_base +1264ath12k_hal_reo1_ring_msi1_base_lsb_offset(ab),1265srng->msi_addr);12661267val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT),1268HAL_REO1_RING_MSI1_BASE_MSB_ADDR) |1269HAL_REO1_RING_MSI1_BASE_MSB_MSI1_ENABLE;1270ath12k_hif_write32(ab, reg_base +1271ath12k_hal_reo1_ring_msi1_base_msb_offset(ab), val);12721273ath12k_hif_write32(ab,1274reg_base + ath12k_hal_reo1_ring_msi1_data_offset(ab),1275srng->msi_data);1276}12771278ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr);12791280val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT),1281HAL_REO1_RING_BASE_MSB_RING_BASE_ADDR_MSB) |1282u32_encode_bits((srng->entry_size * srng->num_entries),1283HAL_REO1_RING_BASE_MSB_RING_SIZE);1284ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_base_msb_offset(ab), val);12851286val = u32_encode_bits(srng->ring_id, HAL_REO1_RING_ID_RING_ID) |1287u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE);1288ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_id_offset(ab), val);12891290/* interrupt setup */1291val = u32_encode_bits((srng->intr_timer_thres_us >> 3),1292HAL_REO1_RING_PRDR_INT_SETUP_INTR_TMR_THOLD);12931294val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size),1295HAL_REO1_RING_PRDR_INT_SETUP_BATCH_COUNTER_THOLD);12961297ath12k_hif_write32(ab,1298reg_base + ath12k_hal_reo1_ring_producer_int_setup_offset(ab),1299val);13001301hp_addr = hal->rdp.paddr +1302((unsigned long)srng->u.dst_ring.hp_addr -1303(unsigned long)hal->rdp.vaddr);1304ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_lsb_offset(ab),1305hp_addr & HAL_ADDR_LSB_REG_MASK);1306ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_hp_addr_msb_offset(ab),1307hp_addr >> HAL_ADDR_MSB_REG_SHIFT);13081309/* Initialize head and tail pointers to indicate ring is empty */1310reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];1311ath12k_hif_write32(ab, reg_base, 0);1312ath12k_hif_write32(ab, reg_base + HAL_REO1_RING_TP_OFFSET, 0);1313*srng->u.dst_ring.hp_addr = 0;13141315reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];1316val = 0;1317if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)1318val |= HAL_REO1_RING_MISC_DATA_TLV_SWAP;1319if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)1320val |= HAL_REO1_RING_MISC_HOST_FW_SWAP;1321if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)1322val |= HAL_REO1_RING_MISC_MSI_SWAP;1323val |= HAL_REO1_RING_MISC_SRNG_ENABLE;13241325ath12k_hif_write32(ab, reg_base + ath12k_hal_reo1_ring_misc_offset(ab), val);1326}13271328static void ath12k_hal_srng_src_hw_init(struct ath12k_base *ab,1329struct hal_srng *srng)1330{1331struct ath12k_hal *hal = &ab->hal;1332u32 val;1333u64 tp_addr;1334u32 reg_base;13351336reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];13371338if (srng->flags & HAL_SRNG_FLAGS_MSI_INTR) {1339ath12k_hif_write32(ab, reg_base +1340HAL_TCL1_RING_MSI1_BASE_LSB_OFFSET(ab),1341srng->msi_addr);13421343val = u32_encode_bits(((u64)srng->msi_addr >> HAL_ADDR_MSB_REG_SHIFT),1344HAL_TCL1_RING_MSI1_BASE_MSB_ADDR) |1345HAL_TCL1_RING_MSI1_BASE_MSB_MSI1_ENABLE;1346ath12k_hif_write32(ab, reg_base +1347HAL_TCL1_RING_MSI1_BASE_MSB_OFFSET(ab),1348val);13491350ath12k_hif_write32(ab, reg_base +1351HAL_TCL1_RING_MSI1_DATA_OFFSET(ab),1352srng->msi_data);1353}13541355ath12k_hif_write32(ab, reg_base, srng->ring_base_paddr);13561357val = u32_encode_bits(((u64)srng->ring_base_paddr >> HAL_ADDR_MSB_REG_SHIFT),1358HAL_TCL1_RING_BASE_MSB_RING_BASE_ADDR_MSB) |1359u32_encode_bits((srng->entry_size * srng->num_entries),1360HAL_TCL1_RING_BASE_MSB_RING_SIZE);1361ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_BASE_MSB_OFFSET, val);13621363val = u32_encode_bits(srng->entry_size, HAL_REO1_RING_ID_ENTRY_SIZE);1364ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_ID_OFFSET(ab), val);13651366val = u32_encode_bits(srng->intr_timer_thres_us,1367HAL_TCL1_RING_CONSR_INT_SETUP_IX0_INTR_TMR_THOLD);13681369val |= u32_encode_bits((srng->intr_batch_cntr_thres_entries * srng->entry_size),1370HAL_TCL1_RING_CONSR_INT_SETUP_IX0_BATCH_COUNTER_THOLD);13711372ath12k_hif_write32(ab,1373reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX0_OFFSET(ab),1374val);13751376val = 0;1377if (srng->flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {1378val |= u32_encode_bits(srng->u.src_ring.low_threshold,1379HAL_TCL1_RING_CONSR_INT_SETUP_IX1_LOW_THOLD);1380}1381ath12k_hif_write32(ab,1382reg_base + HAL_TCL1_RING_CONSR_INT_SETUP_IX1_OFFSET(ab),1383val);13841385if (srng->ring_id != HAL_SRNG_RING_ID_WBM_IDLE_LINK) {1386tp_addr = hal->rdp.paddr +1387((unsigned long)srng->u.src_ring.tp_addr -1388(unsigned long)hal->rdp.vaddr);1389ath12k_hif_write32(ab,1390reg_base + HAL_TCL1_RING_TP_ADDR_LSB_OFFSET(ab),1391tp_addr & HAL_ADDR_LSB_REG_MASK);1392ath12k_hif_write32(ab,1393reg_base + HAL_TCL1_RING_TP_ADDR_MSB_OFFSET(ab),1394tp_addr >> HAL_ADDR_MSB_REG_SHIFT);1395}13961397/* Initialize head and tail pointers to indicate ring is empty */1398reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];1399ath12k_hif_write32(ab, reg_base, 0);1400ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_TP_OFFSET, 0);1401*srng->u.src_ring.tp_addr = 0;14021403reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R0];1404val = 0;1405if (srng->flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP)1406val |= HAL_TCL1_RING_MISC_DATA_TLV_SWAP;1407if (srng->flags & HAL_SRNG_FLAGS_RING_PTR_SWAP)1408val |= HAL_TCL1_RING_MISC_HOST_FW_SWAP;1409if (srng->flags & HAL_SRNG_FLAGS_MSI_SWAP)1410val |= HAL_TCL1_RING_MISC_MSI_SWAP;14111412/* Loop count is not used for SRC rings */1413val |= HAL_TCL1_RING_MISC_MSI_LOOPCNT_DISABLE;14141415val |= HAL_TCL1_RING_MISC_SRNG_ENABLE;14161417if (srng->ring_id == HAL_SRNG_RING_ID_WBM_IDLE_LINK)1418val |= HAL_TCL1_RING_MISC_MSI_RING_ID_DISABLE;14191420ath12k_hif_write32(ab, reg_base + HAL_TCL1_RING_MISC_OFFSET(ab), val);1421}14221423static void ath12k_hal_srng_hw_init(struct ath12k_base *ab,1424struct hal_srng *srng)1425{1426if (srng->ring_dir == HAL_SRNG_DIR_SRC)1427ath12k_hal_srng_src_hw_init(ab, srng);1428else1429ath12k_hal_srng_dst_hw_init(ab, srng);1430}14311432static int ath12k_hal_srng_get_ring_id(struct ath12k_base *ab,1433enum hal_ring_type type,1434int ring_num, int mac_id)1435{1436struct hal_srng_config *srng_config = &ab->hal.srng_config[type];1437int ring_id;14381439if (ring_num >= srng_config->max_rings) {1440ath12k_warn(ab, "invalid ring number :%d\n", ring_num);1441return -EINVAL;1442}14431444ring_id = srng_config->start_ring_id + ring_num;1445if (srng_config->mac_type == ATH12K_HAL_SRNG_PMAC)1446ring_id += mac_id * HAL_SRNG_RINGS_PER_PMAC;14471448if (WARN_ON(ring_id >= HAL_SRNG_RING_ID_MAX))1449return -EINVAL;14501451return ring_id;1452}14531454int ath12k_hal_srng_get_entrysize(struct ath12k_base *ab, u32 ring_type)1455{1456struct hal_srng_config *srng_config;14571458if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))1459return -EINVAL;14601461srng_config = &ab->hal.srng_config[ring_type];14621463return (srng_config->entry_size << 2);1464}14651466int ath12k_hal_srng_get_max_entries(struct ath12k_base *ab, u32 ring_type)1467{1468struct hal_srng_config *srng_config;14691470if (WARN_ON(ring_type >= HAL_MAX_RING_TYPES))1471return -EINVAL;14721473srng_config = &ab->hal.srng_config[ring_type];14741475return (srng_config->max_size / srng_config->entry_size);1476}14771478void ath12k_hal_srng_get_params(struct ath12k_base *ab, struct hal_srng *srng,1479struct hal_srng_params *params)1480{1481params->ring_base_paddr = srng->ring_base_paddr;1482params->ring_base_vaddr = srng->ring_base_vaddr;1483params->num_entries = srng->num_entries;1484params->intr_timer_thres_us = srng->intr_timer_thres_us;1485params->intr_batch_cntr_thres_entries =1486srng->intr_batch_cntr_thres_entries;1487params->low_threshold = srng->u.src_ring.low_threshold;1488params->msi_addr = srng->msi_addr;1489params->msi2_addr = srng->msi2_addr;1490params->msi_data = srng->msi_data;1491params->msi2_data = srng->msi2_data;1492params->flags = srng->flags;1493}14941495dma_addr_t ath12k_hal_srng_get_hp_addr(struct ath12k_base *ab,1496struct hal_srng *srng)1497{1498if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))1499return 0;15001501if (srng->ring_dir == HAL_SRNG_DIR_SRC)1502return ab->hal.wrp.paddr +1503((unsigned long)srng->u.src_ring.hp_addr -1504(unsigned long)ab->hal.wrp.vaddr);1505else1506return ab->hal.rdp.paddr +1507((unsigned long)srng->u.dst_ring.hp_addr -1508(unsigned long)ab->hal.rdp.vaddr);1509}15101511dma_addr_t ath12k_hal_srng_get_tp_addr(struct ath12k_base *ab,1512struct hal_srng *srng)1513{1514if (!(srng->flags & HAL_SRNG_FLAGS_LMAC_RING))1515return 0;15161517if (srng->ring_dir == HAL_SRNG_DIR_SRC)1518return ab->hal.rdp.paddr +1519((unsigned long)srng->u.src_ring.tp_addr -1520(unsigned long)ab->hal.rdp.vaddr);1521else1522return ab->hal.wrp.paddr +1523((unsigned long)srng->u.dst_ring.tp_addr -1524(unsigned long)ab->hal.wrp.vaddr);1525}15261527u32 ath12k_hal_ce_get_desc_size(enum hal_ce_desc type)1528{1529switch (type) {1530case HAL_CE_DESC_SRC:1531return sizeof(struct hal_ce_srng_src_desc);1532case HAL_CE_DESC_DST:1533return sizeof(struct hal_ce_srng_dest_desc);1534case HAL_CE_DESC_DST_STATUS:1535return sizeof(struct hal_ce_srng_dst_status_desc);1536}15371538return 0;1539}15401541void ath12k_hal_ce_src_set_desc(struct hal_ce_srng_src_desc *desc, dma_addr_t paddr,1542u32 len, u32 id, u8 byte_swap_data)1543{1544desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK);1545desc->buffer_addr_info =1546le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),1547HAL_CE_SRC_DESC_ADDR_INFO_ADDR_HI) |1548le32_encode_bits(byte_swap_data,1549HAL_CE_SRC_DESC_ADDR_INFO_BYTE_SWAP) |1550le32_encode_bits(0, HAL_CE_SRC_DESC_ADDR_INFO_GATHER) |1551le32_encode_bits(len, HAL_CE_SRC_DESC_ADDR_INFO_LEN);1552desc->meta_info = le32_encode_bits(id, HAL_CE_SRC_DESC_META_INFO_DATA);1553}15541555void ath12k_hal_ce_dst_set_desc(struct hal_ce_srng_dest_desc *desc, dma_addr_t paddr)1556{1557desc->buffer_addr_low = cpu_to_le32(paddr & HAL_ADDR_LSB_REG_MASK);1558desc->buffer_addr_info =1559le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),1560HAL_CE_DEST_DESC_ADDR_INFO_ADDR_HI);1561}15621563u32 ath12k_hal_ce_dst_status_get_length(struct hal_ce_srng_dst_status_desc *desc)1564{1565u32 len;15661567len = le32_get_bits(desc->flags, HAL_CE_DST_STATUS_DESC_FLAGS_LEN);1568desc->flags &= ~cpu_to_le32(HAL_CE_DST_STATUS_DESC_FLAGS_LEN);15691570return len;1571}15721573void ath12k_hal_set_link_desc_addr(struct hal_wbm_link_desc *desc, u32 cookie,1574dma_addr_t paddr)1575{1576desc->buf_addr_info.info0 = le32_encode_bits((paddr & HAL_ADDR_LSB_REG_MASK),1577BUFFER_ADDR_INFO0_ADDR);1578desc->buf_addr_info.info1 =1579le32_encode_bits(((u64)paddr >> HAL_ADDR_MSB_REG_SHIFT),1580BUFFER_ADDR_INFO1_ADDR) |1581le32_encode_bits(1, BUFFER_ADDR_INFO1_RET_BUF_MGR) |1582le32_encode_bits(cookie, BUFFER_ADDR_INFO1_SW_COOKIE);1583}15841585void *ath12k_hal_srng_dst_peek(struct ath12k_base *ab, struct hal_srng *srng)1586{1587lockdep_assert_held(&srng->lock);15881589if (srng->u.dst_ring.tp != srng->u.dst_ring.cached_hp)1590return (srng->ring_base_vaddr + srng->u.dst_ring.tp);15911592return NULL;1593}15941595void *ath12k_hal_srng_dst_get_next_entry(struct ath12k_base *ab,1596struct hal_srng *srng)1597{1598void *desc;15991600lockdep_assert_held(&srng->lock);16011602if (srng->u.dst_ring.tp == srng->u.dst_ring.cached_hp)1603return NULL;16041605desc = srng->ring_base_vaddr + srng->u.dst_ring.tp;16061607srng->u.dst_ring.tp = (srng->u.dst_ring.tp + srng->entry_size) %1608srng->ring_size;16091610return desc;1611}16121613int ath12k_hal_srng_dst_num_free(struct ath12k_base *ab, struct hal_srng *srng,1614bool sync_hw_ptr)1615{1616u32 tp, hp;16171618lockdep_assert_held(&srng->lock);16191620tp = srng->u.dst_ring.tp;16211622if (sync_hw_ptr) {1623hp = *srng->u.dst_ring.hp_addr;1624srng->u.dst_ring.cached_hp = hp;1625} else {1626hp = srng->u.dst_ring.cached_hp;1627}16281629if (hp >= tp)1630return (hp - tp) / srng->entry_size;1631else1632return (srng->ring_size - tp + hp) / srng->entry_size;1633}16341635/* Returns number of available entries in src ring */1636int ath12k_hal_srng_src_num_free(struct ath12k_base *ab, struct hal_srng *srng,1637bool sync_hw_ptr)1638{1639u32 tp, hp;16401641lockdep_assert_held(&srng->lock);16421643hp = srng->u.src_ring.hp;16441645if (sync_hw_ptr) {1646tp = *srng->u.src_ring.tp_addr;1647srng->u.src_ring.cached_tp = tp;1648} else {1649tp = srng->u.src_ring.cached_tp;1650}16511652if (tp > hp)1653return ((tp - hp) / srng->entry_size) - 1;1654else1655return ((srng->ring_size - hp + tp) / srng->entry_size) - 1;1656}16571658void *ath12k_hal_srng_src_get_next_entry(struct ath12k_base *ab,1659struct hal_srng *srng)1660{1661void *desc;1662u32 next_hp;16631664lockdep_assert_held(&srng->lock);16651666/* TODO: Using % is expensive, but we have to do this since size of some1667* SRNG rings is not power of 2 (due to descriptor sizes). Need to see1668* if separate function is defined for rings having power of 2 ring size1669* (TCL2SW, REO2SW, SW2RXDMA and CE rings) so that we can avoid the1670* overhead of % by using mask (with &).1671*/1672next_hp = (srng->u.src_ring.hp + srng->entry_size) % srng->ring_size;16731674if (next_hp == srng->u.src_ring.cached_tp)1675return NULL;16761677desc = srng->ring_base_vaddr + srng->u.src_ring.hp;1678srng->u.src_ring.hp = next_hp;16791680/* TODO: Reap functionality is not used by all rings. If particular1681* ring does not use reap functionality, we need not update reap_hp1682* with next_hp pointer. Need to make sure a separate function is used1683* before doing any optimization by removing below code updating1684* reap_hp.1685*/1686srng->u.src_ring.reap_hp = next_hp;16871688return desc;1689}16901691void *ath12k_hal_srng_src_reap_next(struct ath12k_base *ab,1692struct hal_srng *srng)1693{1694void *desc;1695u32 next_reap_hp;16961697lockdep_assert_held(&srng->lock);16981699next_reap_hp = (srng->u.src_ring.reap_hp + srng->entry_size) %1700srng->ring_size;17011702if (next_reap_hp == srng->u.src_ring.cached_tp)1703return NULL;17041705desc = srng->ring_base_vaddr + next_reap_hp;1706srng->u.src_ring.reap_hp = next_reap_hp;17071708return desc;1709}17101711void *ath12k_hal_srng_src_get_next_reaped(struct ath12k_base *ab,1712struct hal_srng *srng)1713{1714void *desc;17151716lockdep_assert_held(&srng->lock);17171718if (srng->u.src_ring.hp == srng->u.src_ring.reap_hp)1719return NULL;17201721desc = srng->ring_base_vaddr + srng->u.src_ring.hp;1722srng->u.src_ring.hp = (srng->u.src_ring.hp + srng->entry_size) %1723srng->ring_size;17241725return desc;1726}17271728void ath12k_hal_srng_access_begin(struct ath12k_base *ab, struct hal_srng *srng)1729{1730lockdep_assert_held(&srng->lock);17311732if (srng->ring_dir == HAL_SRNG_DIR_SRC)1733srng->u.src_ring.cached_tp =1734*(volatile u32 *)srng->u.src_ring.tp_addr;1735else1736srng->u.dst_ring.cached_hp = *srng->u.dst_ring.hp_addr;1737}17381739/* Update cached ring head/tail pointers to HW. ath12k_hal_srng_access_begin()1740* should have been called before this.1741*/1742void ath12k_hal_srng_access_end(struct ath12k_base *ab, struct hal_srng *srng)1743{1744lockdep_assert_held(&srng->lock);17451746/* TODO: See if we need a write memory barrier here */1747if (srng->flags & HAL_SRNG_FLAGS_LMAC_RING) {1748/* For LMAC rings, ring pointer updates are done through FW and1749* hence written to a shared memory location that is read by FW1750*/1751if (srng->ring_dir == HAL_SRNG_DIR_SRC) {1752srng->u.src_ring.last_tp =1753*(volatile u32 *)srng->u.src_ring.tp_addr;1754*srng->u.src_ring.hp_addr = srng->u.src_ring.hp;1755} else {1756srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;1757*srng->u.dst_ring.tp_addr = srng->u.dst_ring.tp;1758}1759} else {1760if (srng->ring_dir == HAL_SRNG_DIR_SRC) {1761srng->u.src_ring.last_tp =1762*(volatile u32 *)srng->u.src_ring.tp_addr;1763ath12k_hif_write32(ab,1764(unsigned long)srng->u.src_ring.hp_addr -1765(unsigned long)ab->mem,1766srng->u.src_ring.hp);1767} else {1768srng->u.dst_ring.last_hp = *srng->u.dst_ring.hp_addr;1769ath12k_hif_write32(ab,1770(unsigned long)srng->u.dst_ring.tp_addr -1771(unsigned long)ab->mem,1772srng->u.dst_ring.tp);1773}1774}17751776srng->timestamp = jiffies;1777}17781779void ath12k_hal_setup_link_idle_list(struct ath12k_base *ab,1780struct hal_wbm_idle_scatter_list *sbuf,1781u32 nsbufs, u32 tot_link_desc,1782u32 end_offset)1783{1784struct ath12k_buffer_addr *link_addr;1785int i;1786u32 reg_scatter_buf_sz = HAL_WBM_IDLE_SCATTER_BUF_SIZE / 64;1787u32 val;17881789#if defined(__linux__)1790link_addr = (void *)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE;1791#elif defined(__FreeBSD__)1792link_addr = (void *)((uintptr_t)sbuf[0].vaddr + HAL_WBM_IDLE_SCATTER_BUF_SIZE);1793#endif17941795for (i = 1; i < nsbufs; i++) {1796link_addr->info0 = cpu_to_le32(sbuf[i].paddr & HAL_ADDR_LSB_REG_MASK);17971798link_addr->info1 =1799le32_encode_bits((u64)sbuf[i].paddr >> HAL_ADDR_MSB_REG_SHIFT,1800HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |1801le32_encode_bits(BASE_ADDR_MATCH_TAG_VAL,1802HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG);18031804#if defined(__linux__)1805link_addr = (void *)sbuf[i].vaddr +1806HAL_WBM_IDLE_SCATTER_BUF_SIZE;1807#elif defined(__FreeBSD__)1808link_addr = (void *)((uintptr_t)sbuf[i].vaddr +1809HAL_WBM_IDLE_SCATTER_BUF_SIZE);1810#endif1811}18121813val = u32_encode_bits(reg_scatter_buf_sz, HAL_WBM_SCATTER_BUFFER_SIZE) |1814u32_encode_bits(0x1, HAL_WBM_LINK_DESC_IDLE_LIST_MODE);18151816ath12k_hif_write32(ab,1817HAL_SEQ_WCSS_UMAC_WBM_REG +1818HAL_WBM_R0_IDLE_LIST_CONTROL_ADDR(ab),1819val);18201821val = u32_encode_bits(reg_scatter_buf_sz * nsbufs,1822HAL_WBM_SCATTER_RING_SIZE_OF_IDLE_LINK_DESC_LIST);1823ath12k_hif_write32(ab,1824HAL_SEQ_WCSS_UMAC_WBM_REG + HAL_WBM_R0_IDLE_LIST_SIZE_ADDR(ab),1825val);18261827val = u32_encode_bits(sbuf[0].paddr & HAL_ADDR_LSB_REG_MASK,1828BUFFER_ADDR_INFO0_ADDR);1829ath12k_hif_write32(ab,1830HAL_SEQ_WCSS_UMAC_WBM_REG +1831HAL_WBM_SCATTERED_RING_BASE_LSB(ab),1832val);18331834val = u32_encode_bits(BASE_ADDR_MATCH_TAG_VAL,1835HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_MATCH_TAG) |1836u32_encode_bits((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT,1837HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32);1838ath12k_hif_write32(ab,1839HAL_SEQ_WCSS_UMAC_WBM_REG +1840HAL_WBM_SCATTERED_RING_BASE_MSB(ab),1841val);18421843/* Setup head and tail pointers for the idle list */1844val = u32_encode_bits(sbuf[nsbufs - 1].paddr, BUFFER_ADDR_INFO0_ADDR);1845ath12k_hif_write32(ab,1846HAL_SEQ_WCSS_UMAC_WBM_REG +1847HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab),1848val);18491850val = u32_encode_bits(((u64)sbuf[nsbufs - 1].paddr >> HAL_ADDR_MSB_REG_SHIFT),1851HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |1852u32_encode_bits((end_offset >> 2),1853HAL_WBM_SCATTERED_DESC_HEAD_P_OFFSET_IX1);1854ath12k_hif_write32(ab,1855HAL_SEQ_WCSS_UMAC_WBM_REG +1856HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX1(ab),1857val);18581859val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR);1860ath12k_hif_write32(ab,1861HAL_SEQ_WCSS_UMAC_WBM_REG +1862HAL_WBM_SCATTERED_DESC_PTR_HEAD_INFO_IX0(ab),1863val);18641865val = u32_encode_bits(sbuf[0].paddr, BUFFER_ADDR_INFO0_ADDR);1866ath12k_hif_write32(ab,1867HAL_SEQ_WCSS_UMAC_WBM_REG +1868HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX0(ab),1869val);18701871val = u32_encode_bits(((u64)sbuf[0].paddr >> HAL_ADDR_MSB_REG_SHIFT),1872HAL_WBM_SCATTERED_DESC_MSB_BASE_ADDR_39_32) |1873u32_encode_bits(0, HAL_WBM_SCATTERED_DESC_TAIL_P_OFFSET_IX1);1874ath12k_hif_write32(ab,1875HAL_SEQ_WCSS_UMAC_WBM_REG +1876HAL_WBM_SCATTERED_DESC_PTR_TAIL_INFO_IX1(ab),1877val);18781879val = 2 * tot_link_desc;1880ath12k_hif_write32(ab,1881HAL_SEQ_WCSS_UMAC_WBM_REG +1882HAL_WBM_SCATTERED_DESC_PTR_HP_ADDR(ab),1883val);18841885/* Enable the SRNG */1886val = u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_SRNG_ENABLE) |1887u32_encode_bits(1, HAL_WBM_IDLE_LINK_RING_MISC_RIND_ID_DISABLE);1888ath12k_hif_write32(ab,1889HAL_SEQ_WCSS_UMAC_WBM_REG +1890HAL_WBM_IDLE_LINK_RING_MISC_ADDR(ab),1891val);1892}18931894int ath12k_hal_srng_setup(struct ath12k_base *ab, enum hal_ring_type type,1895int ring_num, int mac_id,1896struct hal_srng_params *params)1897{1898struct ath12k_hal *hal = &ab->hal;1899struct hal_srng_config *srng_config = &ab->hal.srng_config[type];1900struct hal_srng *srng;1901int ring_id;1902u32 idx;1903int i;1904u32 reg_base;19051906ring_id = ath12k_hal_srng_get_ring_id(ab, type, ring_num, mac_id);1907if (ring_id < 0)1908return ring_id;19091910srng = &hal->srng_list[ring_id];19111912srng->ring_id = ring_id;1913srng->ring_dir = srng_config->ring_dir;1914srng->ring_base_paddr = params->ring_base_paddr;1915srng->ring_base_vaddr = params->ring_base_vaddr;1916srng->entry_size = srng_config->entry_size;1917srng->num_entries = params->num_entries;1918srng->ring_size = srng->entry_size * srng->num_entries;1919srng->intr_batch_cntr_thres_entries =1920params->intr_batch_cntr_thres_entries;1921srng->intr_timer_thres_us = params->intr_timer_thres_us;1922srng->flags = params->flags;1923srng->msi_addr = params->msi_addr;1924srng->msi2_addr = params->msi2_addr;1925srng->msi_data = params->msi_data;1926srng->msi2_data = params->msi2_data;1927srng->initialized = 1;1928spin_lock_init(&srng->lock);1929lockdep_set_class(&srng->lock, &srng->lock_key);19301931for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) {1932srng->hwreg_base[i] = srng_config->reg_start[i] +1933(ring_num * srng_config->reg_size[i]);1934}19351936memset(srng->ring_base_vaddr, 0,1937(srng->entry_size * srng->num_entries) << 2);19381939reg_base = srng->hwreg_base[HAL_SRNG_REG_GRP_R2];19401941if (srng->ring_dir == HAL_SRNG_DIR_SRC) {1942srng->u.src_ring.hp = 0;1943srng->u.src_ring.cached_tp = 0;1944srng->u.src_ring.reap_hp = srng->ring_size - srng->entry_size;1945srng->u.src_ring.tp_addr = (void *)(hal->rdp.vaddr + ring_id);1946srng->u.src_ring.low_threshold = params->low_threshold *1947srng->entry_size;1948if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) {1949if (!ab->hw_params->supports_shadow_regs)1950srng->u.src_ring.hp_addr =1951(u32 *)((unsigned long)ab->mem + reg_base);1952else1953ath12k_dbg(ab, ATH12K_DBG_HAL,1954"hal type %d ring_num %d reg_base 0x%x shadow 0x%lx\n",1955type, ring_num,1956reg_base,1957(unsigned long)srng->u.src_ring.hp_addr -1958(unsigned long)ab->mem);1959} else {1960idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START;1961srng->u.src_ring.hp_addr = (void *)(hal->wrp.vaddr +1962idx);1963srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;1964}1965} else {1966/* During initialization loop count in all the descriptors1967* will be set to zero, and HW will set it to 1 on completing1968* descriptor update in first loop, and increments it by 1 on1969* subsequent loops (loop count wraps around after reaching1970* 0xffff). The 'loop_cnt' in SW ring state is the expected1971* loop count in descriptors updated by HW (to be processed1972* by SW).1973*/1974srng->u.dst_ring.loop_cnt = 1;1975srng->u.dst_ring.tp = 0;1976srng->u.dst_ring.cached_hp = 0;1977srng->u.dst_ring.hp_addr = (void *)(hal->rdp.vaddr + ring_id);1978if (srng_config->mac_type == ATH12K_HAL_SRNG_UMAC) {1979if (!ab->hw_params->supports_shadow_regs)1980srng->u.dst_ring.tp_addr =1981(u32 *)((unsigned long)ab->mem + reg_base +1982(HAL_REO1_RING_TP - HAL_REO1_RING_HP));1983else1984ath12k_dbg(ab, ATH12K_DBG_HAL,1985"type %d ring_num %d target_reg 0x%x shadow 0x%lx\n",1986type, ring_num,1987reg_base + HAL_REO1_RING_TP - HAL_REO1_RING_HP,1988(unsigned long)srng->u.dst_ring.tp_addr -1989(unsigned long)ab->mem);1990} else {1991/* For PMAC & DMAC rings, tail pointer updates will be done1992* through FW by writing to a shared memory location1993*/1994idx = ring_id - HAL_SRNG_RING_ID_DMAC_CMN_ID_START;1995srng->u.dst_ring.tp_addr = (void *)(hal->wrp.vaddr +1996idx);1997srng->flags |= HAL_SRNG_FLAGS_LMAC_RING;1998}1999}20002001if (srng_config->mac_type != ATH12K_HAL_SRNG_UMAC)2002return ring_id;20032004ath12k_hal_srng_hw_init(ab, srng);20052006if (type == HAL_CE_DST) {2007srng->u.dst_ring.max_buffer_length = params->max_buffer_len;2008ath12k_hal_ce_dst_setup(ab, srng, ring_num);2009}20102011return ring_id;2012}20132014static void ath12k_hal_srng_update_hp_tp_addr(struct ath12k_base *ab,2015int shadow_cfg_idx,2016enum hal_ring_type ring_type,2017int ring_num)2018{2019struct hal_srng *srng;2020struct ath12k_hal *hal = &ab->hal;2021int ring_id;2022struct hal_srng_config *srng_config = &hal->srng_config[ring_type];20232024ring_id = ath12k_hal_srng_get_ring_id(ab, ring_type, ring_num, 0);2025if (ring_id < 0)2026return;20272028srng = &hal->srng_list[ring_id];20292030if (srng_config->ring_dir == HAL_SRNG_DIR_DST)2031srng->u.dst_ring.tp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) +2032(unsigned long)ab->mem);2033else2034srng->u.src_ring.hp_addr = (u32 *)(HAL_SHADOW_REG(shadow_cfg_idx) +2035(unsigned long)ab->mem);2036}20372038int ath12k_hal_srng_update_shadow_config(struct ath12k_base *ab,2039enum hal_ring_type ring_type,2040int ring_num)2041{2042struct ath12k_hal *hal = &ab->hal;2043struct hal_srng_config *srng_config = &hal->srng_config[ring_type];2044int shadow_cfg_idx = hal->num_shadow_reg_configured;2045u32 target_reg;20462047if (shadow_cfg_idx >= HAL_SHADOW_NUM_REGS)2048return -EINVAL;20492050hal->num_shadow_reg_configured++;20512052target_reg = srng_config->reg_start[HAL_HP_OFFSET_IN_REG_START];2053target_reg += srng_config->reg_size[HAL_HP_OFFSET_IN_REG_START] *2054ring_num;20552056/* For destination ring, shadow the TP */2057if (srng_config->ring_dir == HAL_SRNG_DIR_DST)2058target_reg += HAL_OFFSET_FROM_HP_TO_TP;20592060hal->shadow_reg_addr[shadow_cfg_idx] = target_reg;20612062/* update hp/tp addr to hal structure*/2063ath12k_hal_srng_update_hp_tp_addr(ab, shadow_cfg_idx, ring_type,2064ring_num);20652066ath12k_dbg(ab, ATH12K_DBG_HAL,2067"target_reg %x, shadow reg 0x%x shadow_idx 0x%x, ring_type %d, ring num %d",2068target_reg,2069HAL_SHADOW_REG(shadow_cfg_idx),2070shadow_cfg_idx,2071ring_type, ring_num);20722073return 0;2074}20752076void ath12k_hal_srng_shadow_config(struct ath12k_base *ab)2077{2078struct ath12k_hal *hal = &ab->hal;2079int ring_type, ring_num;20802081/* update all the non-CE srngs. */2082for (ring_type = 0; ring_type < HAL_MAX_RING_TYPES; ring_type++) {2083struct hal_srng_config *srng_config = &hal->srng_config[ring_type];20842085if (ring_type == HAL_CE_SRC ||2086ring_type == HAL_CE_DST ||2087ring_type == HAL_CE_DST_STATUS)2088continue;20892090if (srng_config->mac_type == ATH12K_HAL_SRNG_DMAC ||2091srng_config->mac_type == ATH12K_HAL_SRNG_PMAC)2092continue;20932094for (ring_num = 0; ring_num < srng_config->max_rings; ring_num++)2095ath12k_hal_srng_update_shadow_config(ab, ring_type, ring_num);2096}2097}20982099void ath12k_hal_srng_get_shadow_config(struct ath12k_base *ab,2100u32 **cfg, u32 *len)2101{2102struct ath12k_hal *hal = &ab->hal;21032104*len = hal->num_shadow_reg_configured;2105*cfg = hal->shadow_reg_addr;2106}21072108void ath12k_hal_srng_shadow_update_hp_tp(struct ath12k_base *ab,2109struct hal_srng *srng)2110{2111lockdep_assert_held(&srng->lock);21122113/* check whether the ring is empty. Update the shadow2114* HP only when then ring isn't' empty.2115*/2116if (srng->ring_dir == HAL_SRNG_DIR_SRC &&2117*srng->u.src_ring.tp_addr != srng->u.src_ring.hp)2118ath12k_hal_srng_access_end(ab, srng);2119}21202121static void ath12k_hal_register_srng_lock_keys(struct ath12k_base *ab)2122{2123#if defined(__linux__)2124struct ath12k_hal *hal = &ab->hal;2125#endif2126u32 ring_id;21272128for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)2129lockdep_register_key(&hal->srng_list[ring_id].lock_key);2130}21312132static void ath12k_hal_unregister_srng_lock_keys(struct ath12k_base *ab)2133{2134#if defined(__linux__)2135struct ath12k_hal *hal = &ab->hal;2136#endif2137u32 ring_id;21382139for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++)2140lockdep_unregister_key(&hal->srng_list[ring_id].lock_key);2141}21422143int ath12k_hal_srng_init(struct ath12k_base *ab)2144{2145struct ath12k_hal *hal = &ab->hal;2146int ret;21472148memset(hal, 0, sizeof(*hal));21492150ret = ab->hw_params->hal_ops->create_srng_config(ab);2151if (ret)2152goto err_hal;21532154ret = ath12k_hal_alloc_cont_rdp(ab);2155if (ret)2156goto err_hal;21572158ret = ath12k_hal_alloc_cont_wrp(ab);2159if (ret)2160goto err_free_cont_rdp;21612162ath12k_hal_register_srng_lock_keys(ab);21632164return 0;21652166err_free_cont_rdp:2167ath12k_hal_free_cont_rdp(ab);21682169err_hal:2170return ret;2171}21722173void ath12k_hal_srng_deinit(struct ath12k_base *ab)2174{2175struct ath12k_hal *hal = &ab->hal;21762177ath12k_hal_unregister_srng_lock_keys(ab);2178ath12k_hal_free_cont_rdp(ab);2179ath12k_hal_free_cont_wrp(ab);2180kfree(hal->srng_config);2181hal->srng_config = NULL;2182}21832184void ath12k_hal_dump_srng_stats(struct ath12k_base *ab)2185{2186struct hal_srng *srng;2187struct ath12k_ext_irq_grp *irq_grp;2188struct ath12k_ce_pipe *ce_pipe;2189int i;21902191ath12k_err(ab, "Last interrupt received for each CE:\n");2192for (i = 0; i < ab->hw_params->ce_count; i++) {2193ce_pipe = &ab->ce.ce_pipe[i];21942195if (ath12k_ce_get_attr_flags(ab, i) & CE_ATTR_DIS_INTR)2196continue;21972198ath12k_err(ab, "CE_id %d pipe_num %d %ums before\n",2199i, ce_pipe->pipe_num,2200jiffies_to_msecs(jiffies - ce_pipe->timestamp));2201}22022203ath12k_err(ab, "\nLast interrupt received for each group:\n");2204for (i = 0; i < ATH12K_EXT_IRQ_GRP_NUM_MAX; i++) {2205irq_grp = &ab->ext_irq_grp[i];2206ath12k_err(ab, "group_id %d %ums before\n",2207irq_grp->grp_id,2208jiffies_to_msecs(jiffies - irq_grp->timestamp));2209}22102211for (i = 0; i < HAL_SRNG_RING_ID_MAX; i++) {2212srng = &ab->hal.srng_list[i];22132214if (!srng->initialized)2215continue;22162217if (srng->ring_dir == HAL_SRNG_DIR_SRC)2218ath12k_err(ab,2219"src srng id %u hp %u, reap_hp %u, cur tp %u, cached tp %u last tp %u napi processed before %ums\n",2220srng->ring_id, srng->u.src_ring.hp,2221srng->u.src_ring.reap_hp,2222*srng->u.src_ring.tp_addr, srng->u.src_ring.cached_tp,2223srng->u.src_ring.last_tp,2224jiffies_to_msecs(jiffies - srng->timestamp));2225else if (srng->ring_dir == HAL_SRNG_DIR_DST)2226ath12k_err(ab,2227"dst srng id %u tp %u, cur hp %u, cached hp %u last hp %u napi processed before %ums\n",2228srng->ring_id, srng->u.dst_ring.tp,2229*srng->u.dst_ring.hp_addr,2230srng->u.dst_ring.cached_hp,2231srng->u.dst_ring.last_hp,2232jiffies_to_msecs(jiffies - srng->timestamp));2233}2234}223522362237