Path: blob/main/sys/contrib/dev/athk/ath12k/dp_mon.c
48378 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.4*/56#include "dp_mon.h"7#include "debug.h"8#include "dp_rx.h"9#include "dp_tx.h"10#include "peer.h"1112static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,13struct hal_rx_user_status *rx_user_status)14{15struct hal_rx_ppdu_end_user_stats *ppdu_end_user =16(struct hal_rx_ppdu_end_user_stats *)rx_tlv;1718rx_user_status->ul_ofdma_user_v0_word0 =19__le32_to_cpu(ppdu_end_user->usr_resp_ref);20rx_user_status->ul_ofdma_user_v0_word1 =21__le32_to_cpu(ppdu_end_user->usr_resp_ref_ext);22}2324static void25ath12k_dp_mon_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,26struct hal_rx_user_status *rx_user_status)27{28struct hal_rx_ppdu_end_user_stats *ppdu_end_user =29(struct hal_rx_ppdu_end_user_stats *)rx_tlv;30u32 mpdu_ok_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_ok_cnt);31u32 mpdu_err_byte_count = __le32_to_cpu(ppdu_end_user->mpdu_err_cnt);3233rx_user_status->mpdu_ok_byte_count =34u32_get_bits(mpdu_ok_byte_count,35HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_OK_BYTE_COUNT);36rx_user_status->mpdu_err_byte_count =37u32_get_bits(mpdu_err_byte_count,38HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_ERR_BYTE_COUNT);39}4041static void42ath12k_dp_mon_rx_populate_mu_user_info(void *rx_tlv,43struct hal_rx_mon_ppdu_info *ppdu_info,44struct hal_rx_user_status *rx_user_status)45{46rx_user_status->ast_index = ppdu_info->ast_index;47rx_user_status->tid = ppdu_info->tid;48rx_user_status->tcp_ack_msdu_count =49ppdu_info->tcp_ack_msdu_count;50rx_user_status->tcp_msdu_count =51ppdu_info->tcp_msdu_count;52rx_user_status->udp_msdu_count =53ppdu_info->udp_msdu_count;54rx_user_status->other_msdu_count =55ppdu_info->other_msdu_count;56rx_user_status->frame_control = ppdu_info->frame_control;57rx_user_status->frame_control_info_valid =58ppdu_info->frame_control_info_valid;59rx_user_status->data_sequence_control_info_valid =60ppdu_info->data_sequence_control_info_valid;61rx_user_status->first_data_seq_ctrl =62ppdu_info->first_data_seq_ctrl;63rx_user_status->preamble_type = ppdu_info->preamble_type;64rx_user_status->ht_flags = ppdu_info->ht_flags;65rx_user_status->vht_flags = ppdu_info->vht_flags;66rx_user_status->he_flags = ppdu_info->he_flags;67rx_user_status->rs_flags = ppdu_info->rs_flags;6869rx_user_status->mpdu_cnt_fcs_ok =70ppdu_info->num_mpdu_fcs_ok;71rx_user_status->mpdu_cnt_fcs_err =72ppdu_info->num_mpdu_fcs_err;73memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0],74HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *75sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));7677ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);78}7980static void ath12k_dp_mon_parse_vht_sig_a(u8 *tlv_data,81struct hal_rx_mon_ppdu_info *ppdu_info)82{83struct hal_rx_vht_sig_a_info *vht_sig =84(struct hal_rx_vht_sig_a_info *)tlv_data;85u32 nsts, group_id, info0, info1;86u8 gi_setting;8788info0 = __le32_to_cpu(vht_sig->info0);89info1 = __le32_to_cpu(vht_sig->info1);9091ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);92ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS);93gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING);94switch (gi_setting) {95case HAL_RX_VHT_SIG_A_NORMAL_GI:96ppdu_info->gi = HAL_RX_GI_0_8_US;97break;98case HAL_RX_VHT_SIG_A_SHORT_GI:99case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY:100ppdu_info->gi = HAL_RX_GI_0_4_US;101break;102}103104ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC);105nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS);106if (ppdu_info->is_stbc && nsts > 0)107nsts = ((nsts + 1) >> 1) - 1;108109ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK);110ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW);111ppdu_info->beamformed = u32_get_bits(info1,112HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED);113group_id = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID);114if (group_id == 0 || group_id == 63)115ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;116else117ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;118ppdu_info->vht_flag_values5 = group_id;119ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) |120ppdu_info->nss);121ppdu_info->vht_flag_values2 = ppdu_info->bw;122ppdu_info->vht_flag_values4 =123u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);124}125126static void ath12k_dp_mon_parse_ht_sig(u8 *tlv_data,127struct hal_rx_mon_ppdu_info *ppdu_info)128{129struct hal_rx_ht_sig_info *ht_sig =130(struct hal_rx_ht_sig_info *)tlv_data;131u32 info0 = __le32_to_cpu(ht_sig->info0);132u32 info1 = __le32_to_cpu(ht_sig->info1);133134ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS);135ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW);136ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC);137ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING);138ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);139ppdu_info->nss = (ppdu_info->mcs >> 3);140ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;141}142143static void ath12k_dp_mon_parse_l_sig_b(u8 *tlv_data,144struct hal_rx_mon_ppdu_info *ppdu_info)145{146struct hal_rx_lsig_b_info *lsigb =147(struct hal_rx_lsig_b_info *)tlv_data;148u32 info0 = __le32_to_cpu(lsigb->info0);149u8 rate;150151rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE);152switch (rate) {153case 1:154rate = HAL_RX_LEGACY_RATE_1_MBPS;155break;156case 2:157case 5:158rate = HAL_RX_LEGACY_RATE_2_MBPS;159break;160case 3:161case 6:162rate = HAL_RX_LEGACY_RATE_5_5_MBPS;163break;164case 4:165case 7:166rate = HAL_RX_LEGACY_RATE_11_MBPS;167break;168default:169rate = HAL_RX_LEGACY_RATE_INVALID;170}171172ppdu_info->rate = rate;173ppdu_info->cck_flag = 1;174ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;175}176177static void ath12k_dp_mon_parse_l_sig_a(u8 *tlv_data,178struct hal_rx_mon_ppdu_info *ppdu_info)179{180struct hal_rx_lsig_a_info *lsiga =181(struct hal_rx_lsig_a_info *)tlv_data;182u32 info0 = __le32_to_cpu(lsiga->info0);183u8 rate;184185rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE);186switch (rate) {187case 8:188rate = HAL_RX_LEGACY_RATE_48_MBPS;189break;190case 9:191rate = HAL_RX_LEGACY_RATE_24_MBPS;192break;193case 10:194rate = HAL_RX_LEGACY_RATE_12_MBPS;195break;196case 11:197rate = HAL_RX_LEGACY_RATE_6_MBPS;198break;199case 12:200rate = HAL_RX_LEGACY_RATE_54_MBPS;201break;202case 13:203rate = HAL_RX_LEGACY_RATE_36_MBPS;204break;205case 14:206rate = HAL_RX_LEGACY_RATE_18_MBPS;207break;208case 15:209rate = HAL_RX_LEGACY_RATE_9_MBPS;210break;211default:212rate = HAL_RX_LEGACY_RATE_INVALID;213}214215ppdu_info->rate = rate;216ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;217}218219static void ath12k_dp_mon_parse_he_sig_b2_ofdma(u8 *tlv_data,220struct hal_rx_mon_ppdu_info *ppdu_info)221{222struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma =223(struct hal_rx_he_sig_b2_ofdma_info *)tlv_data;224u32 info0, value;225226info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);227228ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN;229230/* HE-data2 */231ppdu_info->he_data2 |= HE_TXBF_KNOWN;232233ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS);234value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;235ppdu_info->he_data3 |= value;236237value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM);238value = value << HE_DCM_SHIFT;239ppdu_info->he_data3 |= value;240241value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING);242ppdu_info->ldpc = value;243value = value << HE_CODING_SHIFT;244ppdu_info->he_data3 |= value;245246/* HE-data4 */247value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID);248value = value << HE_STA_ID_SHIFT;249ppdu_info->he_data4 |= value;250251ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS);252ppdu_info->beamformed = u32_get_bits(info0,253HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);254ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;255}256257static void ath12k_dp_mon_parse_he_sig_b2_mu(u8 *tlv_data,258struct hal_rx_mon_ppdu_info *ppdu_info)259{260struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu =261(struct hal_rx_he_sig_b2_mu_info *)tlv_data;262u32 info0, value;263264info0 = __le32_to_cpu(he_sig_b2_mu->info0);265266ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN;267268ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS);269value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;270ppdu_info->he_data3 |= value;271272value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING);273ppdu_info->ldpc = value;274value = value << HE_CODING_SHIFT;275ppdu_info->he_data3 |= value;276277value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID);278value = value << HE_STA_ID_SHIFT;279ppdu_info->he_data4 |= value;280281ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);282}283284static void ath12k_dp_mon_parse_he_sig_b1_mu(u8 *tlv_data,285struct hal_rx_mon_ppdu_info *ppdu_info)286{287struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu =288(struct hal_rx_he_sig_b1_mu_info *)tlv_data;289u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0);290u16 ru_tones;291292ru_tones = u32_get_bits(info0,293HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION);294ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);295ppdu_info->he_RU[0] = ru_tones;296ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;297}298299static void ath12k_dp_mon_parse_he_sig_mu(u8 *tlv_data,300struct hal_rx_mon_ppdu_info *ppdu_info)301{302struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =303(struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;304u32 info0, info1, value;305u16 he_gi = 0, he_ltf = 0;306307info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);308info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);309310ppdu_info->he_mu_flags = 1;311312ppdu_info->he_data1 = HE_MU_FORMAT_TYPE;313ppdu_info->he_data1 |=314HE_BSS_COLOR_KNOWN |315HE_DL_UL_KNOWN |316HE_LDPC_EXTRA_SYMBOL_KNOWN |317HE_STBC_KNOWN |318HE_DATA_BW_RU_KNOWN |319HE_DOPPLER_KNOWN;320321ppdu_info->he_data2 =322HE_GI_KNOWN |323HE_LTF_SYMBOLS_KNOWN |324HE_PRE_FEC_PADDING_KNOWN |325HE_PE_DISAMBIGUITY_KNOWN |326HE_TXOP_KNOWN |327HE_MIDABLE_PERIODICITY_KNOWN;328329/* data3 */330ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR);331value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG);332value = value << HE_DL_UL_SHIFT;333ppdu_info->he_data3 |= value;334335value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA);336value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;337ppdu_info->he_data3 |= value;338339value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC);340value = value << HE_STBC_SHIFT;341ppdu_info->he_data3 |= value;342343/* data4 */344ppdu_info->he_data4 = u32_get_bits(info0,345HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE);346ppdu_info->he_data4 = value;347348/* data5 */349value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);350ppdu_info->he_data5 = value;351ppdu_info->bw = value;352353value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE);354switch (value) {355case 0:356he_gi = HE_GI_0_8;357he_ltf = HE_LTF_4_X;358break;359case 1:360he_gi = HE_GI_0_8;361he_ltf = HE_LTF_2_X;362break;363case 2:364he_gi = HE_GI_1_6;365he_ltf = HE_LTF_2_X;366break;367case 3:368he_gi = HE_GI_3_2;369he_ltf = HE_LTF_4_X;370break;371}372373ppdu_info->gi = he_gi;374value = he_gi << HE_GI_SHIFT;375ppdu_info->he_data5 |= value;376377value = he_ltf << HE_LTF_SIZE_SHIFT;378ppdu_info->he_data5 |= value;379380value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB);381value = (value << HE_LTF_SYM_SHIFT);382ppdu_info->he_data5 |= value;383384value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR);385value = value << HE_PRE_FEC_PAD_SHIFT;386ppdu_info->he_data5 |= value;387388value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM);389value = value << HE_PE_DISAMBIGUITY_SHIFT;390ppdu_info->he_data5 |= value;391392/*data6*/393value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION);394value = value << HE_DOPPLER_SHIFT;395ppdu_info->he_data6 |= value;396397value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION);398value = value << HE_TXOP_SHIFT;399ppdu_info->he_data6 |= value;400401/* HE-MU Flags */402/* HE-MU-flags1 */403ppdu_info->he_flags1 =404HE_SIG_B_MCS_KNOWN |405HE_SIG_B_DCM_KNOWN |406HE_SIG_B_COMPRESSION_FLAG_1_KNOWN |407HE_SIG_B_SYM_NUM_KNOWN |408HE_RU_0_KNOWN;409410value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB);411ppdu_info->he_flags1 |= value;412value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB);413value = value << HE_DCM_FLAG_1_SHIFT;414ppdu_info->he_flags1 |= value;415416/* HE-MU-flags2 */417ppdu_info->he_flags2 = HE_BW_KNOWN;418419value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);420ppdu_info->he_flags2 |= value;421value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB);422value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT;423ppdu_info->he_flags2 |= value;424value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB);425value = value - 1;426value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT;427ppdu_info->he_flags2 |= value;428429ppdu_info->is_stbc = info1 &430HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC;431ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;432}433434static void ath12k_dp_mon_parse_he_sig_su(u8 *tlv_data,435struct hal_rx_mon_ppdu_info *ppdu_info)436{437struct hal_rx_he_sig_a_su_info *he_sig_a =438(struct hal_rx_he_sig_a_su_info *)tlv_data;439u32 info0, info1, value;440u32 dcm;441u8 he_dcm = 0, he_stbc = 0;442u16 he_gi = 0, he_ltf = 0;443444ppdu_info->he_flags = 1;445446info0 = __le32_to_cpu(he_sig_a->info0);447info1 = __le32_to_cpu(he_sig_a->info1);448449value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND);450if (value == 0)451ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE;452else453ppdu_info->he_data1 = HE_SU_FORMAT_TYPE;454455ppdu_info->he_data1 |=456HE_BSS_COLOR_KNOWN |457HE_BEAM_CHANGE_KNOWN |458HE_DL_UL_KNOWN |459HE_MCS_KNOWN |460HE_DCM_KNOWN |461HE_CODING_KNOWN |462HE_LDPC_EXTRA_SYMBOL_KNOWN |463HE_STBC_KNOWN |464HE_DATA_BW_RU_KNOWN |465HE_DOPPLER_KNOWN;466467ppdu_info->he_data2 |=468HE_GI_KNOWN |469HE_TXBF_KNOWN |470HE_PE_DISAMBIGUITY_KNOWN |471HE_TXOP_KNOWN |472HE_LTF_SYMBOLS_KNOWN |473HE_PRE_FEC_PADDING_KNOWN |474HE_MIDABLE_PERIODICITY_KNOWN;475476ppdu_info->he_data3 = u32_get_bits(info0,477HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR);478value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE);479value = value << HE_BEAM_CHANGE_SHIFT;480ppdu_info->he_data3 |= value;481value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG);482value = value << HE_DL_UL_SHIFT;483ppdu_info->he_data3 |= value;484485value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);486ppdu_info->mcs = value;487value = value << HE_TRANSMIT_MCS_SHIFT;488ppdu_info->he_data3 |= value;489490value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);491he_dcm = value;492value = value << HE_DCM_SHIFT;493ppdu_info->he_data3 |= value;494value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);495value = value << HE_CODING_SHIFT;496ppdu_info->he_data3 |= value;497value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA);498value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;499ppdu_info->he_data3 |= value;500value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);501he_stbc = value;502value = value << HE_STBC_SHIFT;503ppdu_info->he_data3 |= value;504505/* data4 */506ppdu_info->he_data4 = u32_get_bits(info0,507HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE);508509/* data5 */510value = u32_get_bits(info0,511HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);512ppdu_info->he_data5 = value;513ppdu_info->bw = value;514value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE);515switch (value) {516case 0:517he_gi = HE_GI_0_8;518he_ltf = HE_LTF_1_X;519break;520case 1:521he_gi = HE_GI_0_8;522he_ltf = HE_LTF_2_X;523break;524case 2:525he_gi = HE_GI_1_6;526he_ltf = HE_LTF_2_X;527break;528case 3:529if (he_dcm && he_stbc) {530he_gi = HE_GI_0_8;531he_ltf = HE_LTF_4_X;532} else {533he_gi = HE_GI_3_2;534he_ltf = HE_LTF_4_X;535}536break;537}538ppdu_info->gi = he_gi;539value = he_gi << HE_GI_SHIFT;540ppdu_info->he_data5 |= value;541value = he_ltf << HE_LTF_SIZE_SHIFT;542ppdu_info->ltf_size = he_ltf;543ppdu_info->he_data5 |= value;544545value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);546value = (value << HE_LTF_SYM_SHIFT);547ppdu_info->he_data5 |= value;548549value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR);550value = value << HE_PRE_FEC_PAD_SHIFT;551ppdu_info->he_data5 |= value;552553value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);554value = value << HE_TXBF_SHIFT;555ppdu_info->he_data5 |= value;556value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM);557value = value << HE_PE_DISAMBIGUITY_SHIFT;558ppdu_info->he_data5 |= value;559560/* data6 */561value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);562value++;563ppdu_info->he_data6 = value;564value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND);565value = value << HE_DOPPLER_SHIFT;566ppdu_info->he_data6 |= value;567value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION);568value = value << HE_TXOP_SHIFT;569ppdu_info->he_data6 |= value;570571ppdu_info->mcs =572u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);573ppdu_info->bw =574u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);575ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);576ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);577ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);578dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);579ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);580ppdu_info->dcm = dcm;581ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;582}583584static enum hal_rx_mon_status585ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base *ab,586struct ath12k_mon_data *pmon,587u32 tlv_tag, u8 *tlv_data, u32 userid)588{589struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;590u32 info[7];591592switch (tlv_tag) {593case HAL_RX_PPDU_START: {594struct hal_rx_ppdu_start *ppdu_start =595(struct hal_rx_ppdu_start *)tlv_data;596597info[0] = __le32_to_cpu(ppdu_start->info0);598599ppdu_info->ppdu_id =600u32_get_bits(info[0], HAL_RX_PPDU_START_INFO0_PPDU_ID);601ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);602ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);603604if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {605ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;606ppdu_info->num_users = 0;607memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,608HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *609sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));610}611break;612}613case HAL_RX_PPDU_END_USER_STATS: {614struct hal_rx_ppdu_end_user_stats *eu_stats =615(struct hal_rx_ppdu_end_user_stats *)tlv_data;616617info[0] = __le32_to_cpu(eu_stats->info0);618info[1] = __le32_to_cpu(eu_stats->info1);619info[2] = __le32_to_cpu(eu_stats->info2);620info[4] = __le32_to_cpu(eu_stats->info4);621info[5] = __le32_to_cpu(eu_stats->info5);622info[6] = __le32_to_cpu(eu_stats->info6);623624ppdu_info->ast_index =625u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX);626ppdu_info->fc_valid =627u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID);628ppdu_info->tid =629ffs(u32_get_bits(info[6],630HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP)631- 1);632ppdu_info->tcp_msdu_count =633u32_get_bits(info[4],634HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT);635ppdu_info->udp_msdu_count =636u32_get_bits(info[4],637HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT);638ppdu_info->other_msdu_count =639u32_get_bits(info[5],640HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT);641ppdu_info->tcp_ack_msdu_count =642u32_get_bits(info[5],643HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT);644ppdu_info->preamble_type =645u32_get_bits(info[1],646HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE);647ppdu_info->num_mpdu_fcs_ok =648u32_get_bits(info[1],649HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK);650ppdu_info->num_mpdu_fcs_err =651u32_get_bits(info[0],652HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR);653switch (ppdu_info->preamble_type) {654case HAL_RX_PREAMBLE_11N:655ppdu_info->ht_flags = 1;656break;657case HAL_RX_PREAMBLE_11AC:658ppdu_info->vht_flags = 1;659break;660case HAL_RX_PREAMBLE_11AX:661ppdu_info->he_flags = 1;662break;663default:664break;665}666667if (userid < HAL_MAX_UL_MU_USERS) {668struct hal_rx_user_status *rxuser_stats =669&ppdu_info->userstats[userid];670ppdu_info->num_users += 1;671672ath12k_dp_mon_rx_handle_ofdma_info(tlv_data, rxuser_stats);673ath12k_dp_mon_rx_populate_mu_user_info(tlv_data, ppdu_info,674rxuser_stats);675}676ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]);677ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]);678break;679}680case HAL_RX_PPDU_END_USER_STATS_EXT: {681struct hal_rx_ppdu_end_user_stats_ext *eu_stats =682(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;683ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1);684ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2);685ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3);686ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4);687ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5);688ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6);689break;690}691case HAL_PHYRX_HT_SIG:692ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info);693break;694695case HAL_PHYRX_L_SIG_B:696ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info);697break;698699case HAL_PHYRX_L_SIG_A:700ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info);701break;702703case HAL_PHYRX_VHT_SIG_A:704ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info);705break;706707case HAL_PHYRX_HE_SIG_A_SU:708ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info);709break;710711case HAL_PHYRX_HE_SIG_A_MU_DL:712ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info);713break;714715case HAL_PHYRX_HE_SIG_B1_MU:716ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info);717break;718719case HAL_PHYRX_HE_SIG_B2_MU:720ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info);721break;722723case HAL_PHYRX_HE_SIG_B2_OFDMA:724ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info);725break;726727case HAL_PHYRX_RSSI_LEGACY: {728struct hal_rx_phyrx_rssi_legacy_info *rssi =729(struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;730u32 reception_type = 0;731u32 rssi_legacy_info = __le32_to_cpu(rssi->rsvd[0]);732733info[0] = __le32_to_cpu(rssi->info0);734735/* TODO: Please note that the combined rssi will not be accurate736* in MU case. Rssi in MU needs to be retrieved from737* PHYRX_OTHER_RECEIVE_INFO TLV.738*/739ppdu_info->rssi_comb =740u32_get_bits(info[0],741HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB);742reception_type =743u32_get_bits(rssi_legacy_info,744HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION);745746switch (reception_type) {747case HAL_RECEPTION_TYPE_ULOFMDA:748ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;749break;750case HAL_RECEPTION_TYPE_ULMIMO:751ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;752break;753default:754ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;755break;756}757break;758}759case HAL_RXPCU_PPDU_END_INFO: {760struct hal_rx_ppdu_end_duration *ppdu_rx_duration =761(struct hal_rx_ppdu_end_duration *)tlv_data;762763info[0] = __le32_to_cpu(ppdu_rx_duration->info0);764ppdu_info->rx_duration =765u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION);766ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);767ppdu_info->tsft = (ppdu_info->tsft << 32) |768__le32_to_cpu(ppdu_rx_duration->rsvd0[0]);769break;770}771case HAL_RX_MPDU_START: {772struct hal_rx_mpdu_start *mpdu_start =773(struct hal_rx_mpdu_start *)tlv_data;774struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;775u16 peer_id;776777info[1] = __le32_to_cpu(mpdu_start->info1);778peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID);779if (peer_id)780ppdu_info->peer_id = peer_id;781782ppdu_info->mpdu_len += u32_get_bits(info[1],783HAL_RX_MPDU_START_INFO2_MPDU_LEN);784if (userid < HAL_MAX_UL_MU_USERS) {785info[0] = __le32_to_cpu(mpdu_start->info0);786ppdu_info->userid = userid;787ppdu_info->ampdu_id[userid] =788u32_get_bits(info[0], HAL_RX_MPDU_START_INFO1_PEERID);789}790791mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);792if (!mon_mpdu)793return HAL_RX_MON_STATUS_PPDU_NOT_DONE;794795break;796}797case HAL_RX_MSDU_START:798/* TODO: add msdu start parsing logic */799break;800case HAL_MON_BUF_ADDR: {801struct dp_rxdma_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;802struct dp_mon_packet_info *packet_info =803(struct dp_mon_packet_info *)tlv_data;804int buf_id = u32_get_bits(packet_info->cookie,805DP_RXDMA_BUF_COOKIE_BUF_ID);806struct sk_buff *msdu;807struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;808struct ath12k_skb_rxcb *rxcb;809810spin_lock_bh(&buf_ring->idr_lock);811msdu = idr_remove(&buf_ring->bufs_idr, buf_id);812spin_unlock_bh(&buf_ring->idr_lock);813814if (unlikely(!msdu)) {815ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",816buf_id);817return HAL_RX_MON_STATUS_PPDU_NOT_DONE;818}819820rxcb = ATH12K_SKB_RXCB(msdu);821dma_unmap_single(ab->dev, rxcb->paddr,822msdu->len + skb_tailroom(msdu),823DMA_FROM_DEVICE);824825if (mon_mpdu->tail)826mon_mpdu->tail->next = msdu;827else828mon_mpdu->tail = msdu;829830ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);831832break;833}834case HAL_RX_MSDU_END: {835struct rx_msdu_end_qcn9274 *msdu_end =836(struct rx_msdu_end_qcn9274 *)tlv_data;837bool is_first_msdu_in_mpdu;838u16 msdu_end_info;839840msdu_end_info = __le16_to_cpu(msdu_end->info5);841is_first_msdu_in_mpdu = u32_get_bits(msdu_end_info,842RX_MSDU_END_INFO5_FIRST_MSDU);843if (is_first_msdu_in_mpdu) {844pmon->mon_mpdu->head = pmon->mon_mpdu->tail;845pmon->mon_mpdu->tail = NULL;846}847break;848}849case HAL_RX_MPDU_END:850list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);851break;852case HAL_DUMMY:853return HAL_RX_MON_STATUS_BUF_DONE;854case HAL_RX_PPDU_END_STATUS_DONE:855case 0:856return HAL_RX_MON_STATUS_PPDU_DONE;857default:858break;859}860861return HAL_RX_MON_STATUS_PPDU_NOT_DONE;862}863864static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, struct sk_buff *msdu)865{866u32 rx_pkt_offset, l2_hdr_offset;867868rx_pkt_offset = ar->ab->hw_params->hal_desc_sz;869l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab,870(struct hal_rx_desc *)msdu->data);871skb_pull(msdu, rx_pkt_offset + l2_hdr_offset);872}873874static struct sk_buff *875ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,876u32 mac_id, struct sk_buff *head_msdu,877struct ieee80211_rx_status *rxs, bool *fcs_err)878{879struct ath12k_base *ab = ar->ab;880struct sk_buff *msdu, *mpdu_buf, *prev_buf;881struct hal_rx_desc *rx_desc;882u8 *hdr_desc, *dest, decap_format;883struct ieee80211_hdr_3addr *wh;884u32 err_bitmap;885886mpdu_buf = NULL;887888if (!head_msdu)889goto err_merge_fail;890891rx_desc = (struct hal_rx_desc *)head_msdu->data;892err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);893894if (err_bitmap & HAL_RX_MPDU_ERR_FCS)895*fcs_err = true;896897decap_format = ath12k_dp_rx_h_decap_type(ab, rx_desc);898899ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);900901if (decap_format == DP_RX_DECAP_TYPE_RAW) {902ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu);903904prev_buf = head_msdu;905msdu = head_msdu->next;906907while (msdu) {908ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);909910prev_buf = msdu;911msdu = msdu->next;912}913914prev_buf->next = NULL;915916skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN);917} else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) {918u8 qos_pkt = 0;919920rx_desc = (struct hal_rx_desc *)head_msdu->data;921hdr_desc = ab->hw_params->hal_ops->rx_desc_get_msdu_payload(rx_desc);922923/* Base size */924wh = (struct ieee80211_hdr_3addr *)hdr_desc;925926if (ieee80211_is_data_qos(wh->frame_control))927qos_pkt = 1;928929msdu = head_msdu;930931while (msdu) {932ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);933if (qos_pkt) {934dest = skb_push(msdu, sizeof(__le16));935if (!dest)936goto err_merge_fail;937memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr));938}939prev_buf = msdu;940msdu = msdu->next;941}942dest = skb_put(prev_buf, HAL_RX_FCS_LEN);943if (!dest)944goto err_merge_fail;945946ath12k_dbg(ab, ATH12K_DBG_DATA,947"mpdu_buf %pK mpdu_buf->len %u",948prev_buf, prev_buf->len);949} else {950ath12k_dbg(ab, ATH12K_DBG_DATA,951"decap format %d is not supported!\n",952decap_format);953goto err_merge_fail;954}955956return head_msdu;957958err_merge_fail:959if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {960ath12k_dbg(ab, ATH12K_DBG_DATA,961"err_merge_fail mpdu_buf %pK", mpdu_buf);962/* Free the head buffer */963dev_kfree_skb_any(mpdu_buf);964}965return NULL;966}967968static void969ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status,970u8 *rtap_buf)971{972u32 rtap_len = 0;973974put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);975rtap_len += 2;976977put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);978rtap_len += 2;979980put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);981rtap_len += 2;982983put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);984rtap_len += 2;985986put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);987rtap_len += 2;988989put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);990}991992static void993ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status,994u8 *rtap_buf)995{996u32 rtap_len = 0;997998put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);999rtap_len += 2;10001001put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);1002rtap_len += 2;10031004rtap_buf[rtap_len] = rx_status->he_RU[0];1005rtap_len += 1;10061007rtap_buf[rtap_len] = rx_status->he_RU[1];1008rtap_len += 1;10091010rtap_buf[rtap_len] = rx_status->he_RU[2];1011rtap_len += 1;10121013rtap_buf[rtap_len] = rx_status->he_RU[3];1014}10151016static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,1017struct hal_rx_mon_ppdu_info *ppduinfo,1018struct sk_buff *mon_skb,1019struct ieee80211_rx_status *rxs)1020{1021struct ieee80211_supported_band *sband;1022u8 *ptr = NULL;1023u16 ampdu_id = ppduinfo->ampdu_id[ppduinfo->userid];10241025rxs->flag |= RX_FLAG_MACTIME_START;1026rxs->signal = ppduinfo->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR;1027rxs->nss = ppduinfo->nss + 1;10281029if (ampdu_id) {1030rxs->flag |= RX_FLAG_AMPDU_DETAILS;1031rxs->ampdu_reference = ampdu_id;1032}10331034if (ppduinfo->he_mu_flags) {1035rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;1036rxs->encoding = RX_ENC_HE;1037ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));1038ath12k_dp_mon_rx_update_radiotap_he_mu(ppduinfo, ptr);1039} else if (ppduinfo->he_flags) {1040rxs->flag |= RX_FLAG_RADIOTAP_HE;1041rxs->encoding = RX_ENC_HE;1042ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));1043ath12k_dp_mon_rx_update_radiotap_he(ppduinfo, ptr);1044rxs->rate_idx = ppduinfo->rate;1045} else if (ppduinfo->vht_flags) {1046rxs->encoding = RX_ENC_VHT;1047rxs->rate_idx = ppduinfo->rate;1048} else if (ppduinfo->ht_flags) {1049rxs->encoding = RX_ENC_HT;1050rxs->rate_idx = ppduinfo->rate;1051} else {1052rxs->encoding = RX_ENC_LEGACY;1053sband = &ar->mac.sbands[rxs->band];1054rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, ppduinfo->rate,1055ppduinfo->cck_flag);1056}10571058rxs->mactime = ppduinfo->tsft;1059}10601061static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,1062struct sk_buff *msdu,1063struct ieee80211_rx_status *status)1064{1065static const struct ieee80211_radiotap_he known = {1066.data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |1067IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),1068.data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),1069};1070struct ieee80211_rx_status *rx_status;1071struct ieee80211_radiotap_he *he = NULL;1072struct ieee80211_sta *pubsta = NULL;1073struct ath12k_peer *peer;1074struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);1075u8 decap = DP_RX_DECAP_TYPE_RAW;1076bool is_mcbc = rxcb->is_mcbc;1077bool is_eapol_tkip = rxcb->is_eapol;10781079if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&1080!(status->flag & RX_FLAG_SKIP_MONITOR)) {1081he = skb_push(msdu, sizeof(known));1082memcpy(he, &known, sizeof(known));1083status->flag |= RX_FLAG_RADIOTAP_HE;1084}10851086if (!(status->flag & RX_FLAG_ONLY_MONITOR))1087decap = ath12k_dp_rx_h_decap_type(ar->ab, rxcb->rx_desc);1088spin_lock_bh(&ar->ab->base_lock);1089peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);1090if (peer && peer->sta)1091pubsta = peer->sta;1092spin_unlock_bh(&ar->ab->base_lock);10931094ath12k_dbg(ar->ab, ATH12K_DBG_DATA,1095"rx skb %pK len %u peer %pM %u %s %s%s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",1096msdu,1097msdu->len,1098peer ? peer->addr : NULL,1099rxcb->tid,1100(is_mcbc) ? "mcast" : "ucast",1101(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",1102(status->encoding == RX_ENC_HT) ? "ht" : "",1103(status->encoding == RX_ENC_VHT) ? "vht" : "",1104(status->encoding == RX_ENC_HE) ? "he" : "",1105(status->bw == RATE_INFO_BW_40) ? "40" : "",1106(status->bw == RATE_INFO_BW_80) ? "80" : "",1107(status->bw == RATE_INFO_BW_160) ? "160" : "",1108status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",1109status->rate_idx,1110status->nss,1111status->freq,1112status->band, status->flag,1113!!(status->flag & RX_FLAG_FAILED_FCS_CRC),1114!!(status->flag & RX_FLAG_MMIC_ERROR),1115!!(status->flag & RX_FLAG_AMSDU_MORE));11161117ath12k_dbg_dump(ar->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ",1118msdu->data, msdu->len);1119rx_status = IEEE80211_SKB_RXCB(msdu);1120*rx_status = *status;11211122/* TODO: trace rx packet */11231124/* PN for multicast packets are not validate in HW,1125* so skip 802.3 rx path1126* Also, fast_rx expects the STA to be authorized, hence1127* eapol packets are sent in slow path.1128*/1129if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol_tkip &&1130!(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))1131rx_status->flag |= RX_FLAG_8023;11321133ieee80211_rx_napi(ar->hw, pubsta, msdu, napi);1134}11351136static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, u32 mac_id,1137struct sk_buff *head_msdu,1138struct hal_rx_mon_ppdu_info *ppduinfo,1139struct napi_struct *napi)1140{1141struct ath12k_pdev_dp *dp = &ar->dp;1142struct sk_buff *mon_skb, *skb_next, *header;1143struct ieee80211_rx_status *rxs = &dp->rx_status;1144bool fcs_err = false;11451146mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mac_id, head_msdu,1147rxs, &fcs_err);1148if (!mon_skb)1149goto mon_deliver_fail;11501151header = mon_skb;1152rxs->flag = 0;11531154if (fcs_err)1155rxs->flag = RX_FLAG_FAILED_FCS_CRC;11561157do {1158skb_next = mon_skb->next;1159if (!skb_next)1160rxs->flag &= ~RX_FLAG_AMSDU_MORE;1161else1162rxs->flag |= RX_FLAG_AMSDU_MORE;11631164if (mon_skb == header) {1165header = NULL;1166rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN;1167} else {1168rxs->flag |= RX_FLAG_ALLOW_SAME_PN;1169}1170rxs->flag |= RX_FLAG_ONLY_MONITOR;1171ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs);1172ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs);1173mon_skb = skb_next;1174} while (mon_skb);1175rxs->flag = 0;11761177return 0;11781179mon_deliver_fail:1180mon_skb = head_msdu;1181while (mon_skb) {1182skb_next = mon_skb->next;1183dev_kfree_skb_any(mon_skb);1184mon_skb = skb_next;1185}1186return -EINVAL;1187}11881189static enum hal_rx_mon_status1190ath12k_dp_mon_parse_rx_dest(struct ath12k_base *ab, struct ath12k_mon_data *pmon,1191struct sk_buff *skb)1192{1193struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;1194struct hal_tlv_hdr *tlv;1195enum hal_rx_mon_status hal_status;1196u32 tlv_userid = 0;1197u16 tlv_tag, tlv_len;1198u8 *ptr = skb->data;11991200memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));12011202do {1203tlv = (struct hal_tlv_hdr *)ptr;1204tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);1205tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);1206tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);1207ptr += sizeof(*tlv);12081209/* The actual length of PPDU_END is the combined length of many PHY1210* TLVs that follow. Skip the TLV header and1211* rx_rxpcu_classification_overview that follows the header to get to1212* next TLV.1213*/12141215if (tlv_tag == HAL_RX_PPDU_END)1216tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);12171218hal_status = ath12k_dp_mon_rx_parse_status_tlv(ab, pmon,1219tlv_tag, ptr, tlv_userid);1220ptr += tlv_len;1221ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);12221223if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)1224break;12251226} while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE);12271228return hal_status;1229}12301231enum hal_rx_mon_status1232ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,1233struct ath12k_mon_data *pmon,1234int mac_id,1235struct sk_buff *skb,1236struct napi_struct *napi)1237{1238struct ath12k_base *ab = ar->ab;1239struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;1240struct dp_mon_mpdu *tmp;1241struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;1242struct sk_buff *head_msdu, *tail_msdu;1243enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;12441245ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);12461247list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {1248list_del(&mon_mpdu->list);1249head_msdu = mon_mpdu->head;1250tail_msdu = mon_mpdu->tail;12511252if (head_msdu && tail_msdu) {1253ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,1254ppdu_info, napi);1255}12561257kfree(mon_mpdu);1258}1259return hal_status;1260}12611262int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,1263struct dp_rxdma_ring *buf_ring,1264int req_entries)1265{1266struct hal_mon_buf_ring *mon_buf;1267struct sk_buff *skb;1268struct hal_srng *srng;1269dma_addr_t paddr;1270u32 cookie;1271int buf_id;12721273srng = &ab->hal.srng_list[buf_ring->refill_buf_ring.ring_id];1274spin_lock_bh(&srng->lock);1275ath12k_hal_srng_access_begin(ab, srng);12761277while (req_entries > 0) {1278skb = dev_alloc_skb(DP_RX_BUFFER_SIZE + DP_RX_BUFFER_ALIGN_SIZE);1279if (unlikely(!skb))1280goto fail_alloc_skb;12811282if (!IS_ALIGNED((unsigned long)skb->data, DP_RX_BUFFER_ALIGN_SIZE)) {1283skb_pull(skb,1284PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) -1285skb->data);1286}12871288paddr = dma_map_single(ab->dev, skb->data,1289skb->len + skb_tailroom(skb),1290DMA_FROM_DEVICE);12911292if (unlikely(dma_mapping_error(ab->dev, paddr)))1293goto fail_free_skb;12941295spin_lock_bh(&buf_ring->idr_lock);1296buf_id = idr_alloc(&buf_ring->bufs_idr, skb, 0,1297buf_ring->bufs_max * 3, GFP_ATOMIC);1298spin_unlock_bh(&buf_ring->idr_lock);12991300if (unlikely(buf_id < 0))1301goto fail_dma_unmap;13021303mon_buf = ath12k_hal_srng_src_get_next_entry(ab, srng);1304if (unlikely(!mon_buf))1305goto fail_idr_remove;13061307ATH12K_SKB_RXCB(skb)->paddr = paddr;13081309cookie = u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID);13101311mon_buf->paddr_lo = cpu_to_le32(lower_32_bits(paddr));1312mon_buf->paddr_hi = cpu_to_le32(upper_32_bits(paddr));1313mon_buf->cookie = cpu_to_le64(cookie);13141315req_entries--;1316}13171318ath12k_hal_srng_access_end(ab, srng);1319spin_unlock_bh(&srng->lock);1320return 0;13211322fail_idr_remove:1323spin_lock_bh(&buf_ring->idr_lock);1324idr_remove(&buf_ring->bufs_idr, buf_id);1325spin_unlock_bh(&buf_ring->idr_lock);1326fail_dma_unmap:1327dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),1328DMA_FROM_DEVICE);1329fail_free_skb:1330dev_kfree_skb_any(skb);1331fail_alloc_skb:1332ath12k_hal_srng_access_end(ab, srng);1333spin_unlock_bh(&srng->lock);1334return -ENOMEM;1335}13361337static struct dp_mon_tx_ppdu_info *1338ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon,1339unsigned int ppdu_id,1340enum dp_mon_tx_ppdu_info_type type)1341{1342struct dp_mon_tx_ppdu_info *tx_ppdu_info;13431344if (type == DP_MON_TX_PROT_PPDU_INFO) {1345tx_ppdu_info = pmon->tx_prot_ppdu_info;13461347if (tx_ppdu_info && !tx_ppdu_info->is_used)1348return tx_ppdu_info;1349kfree(tx_ppdu_info);1350} else {1351tx_ppdu_info = pmon->tx_data_ppdu_info;13521353if (tx_ppdu_info && !tx_ppdu_info->is_used)1354return tx_ppdu_info;1355kfree(tx_ppdu_info);1356}13571358/* allocate new tx_ppdu_info */1359tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC);1360if (!tx_ppdu_info)1361return NULL;13621363tx_ppdu_info->is_used = 0;1364tx_ppdu_info->ppdu_id = ppdu_id;13651366if (type == DP_MON_TX_PROT_PPDU_INFO)1367pmon->tx_prot_ppdu_info = tx_ppdu_info;1368else1369pmon->tx_data_ppdu_info = tx_ppdu_info;13701371return tx_ppdu_info;1372}13731374static struct dp_mon_tx_ppdu_info *1375ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon,1376u16 tlv_tag)1377{1378switch (tlv_tag) {1379case HAL_TX_FES_SETUP:1380case HAL_TX_FLUSH:1381case HAL_PCU_PPDU_SETUP_INIT:1382case HAL_TX_PEER_ENTRY:1383case HAL_TX_QUEUE_EXTENSION:1384case HAL_TX_MPDU_START:1385case HAL_TX_MSDU_START:1386case HAL_TX_DATA:1387case HAL_MON_BUF_ADDR:1388case HAL_TX_MPDU_END:1389case HAL_TX_LAST_MPDU_FETCHED:1390case HAL_TX_LAST_MPDU_END:1391case HAL_COEX_TX_REQ:1392case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP:1393case HAL_SCH_CRITICAL_TLV_REFERENCE:1394case HAL_TX_FES_SETUP_COMPLETE:1395case HAL_TQM_MPDU_GLOBAL_START:1396case HAL_SCHEDULER_END:1397case HAL_TX_FES_STATUS_USER_PPDU:1398break;1399case HAL_TX_FES_STATUS_PROT: {1400if (!pmon->tx_prot_ppdu_info->is_used)1401pmon->tx_prot_ppdu_info->is_used = true;14021403return pmon->tx_prot_ppdu_info;1404}1405}14061407if (!pmon->tx_data_ppdu_info->is_used)1408pmon->tx_data_ppdu_info->is_used = true;14091410return pmon->tx_data_ppdu_info;1411}14121413#define MAX_MONITOR_HEADER 5121414#define MAX_DUMMY_FRM_BODY 12814151416struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void)1417{1418struct sk_buff *skb;14191420skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY);1421if (!skb)1422return NULL;14231424skb_reserve(skb, MAX_MONITOR_HEADER);14251426if (!IS_ALIGNED((unsigned long)skb->data, 4))1427skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data);14281429return skb;1430}14311432static int1433ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1434{1435struct sk_buff *skb;1436struct ieee80211_cts *cts;14371438skb = ath12k_dp_mon_tx_alloc_skb();1439if (!skb)1440return -ENOMEM;14411442cts = (struct ieee80211_cts *)skb->data;1443memset(cts, 0, MAX_DUMMY_FRM_BODY);1444cts->frame_control =1445cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);1446cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1447memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra));14481449skb_put(skb, sizeof(*cts));1450tx_ppdu_info->tx_mon_mpdu->head = skb;1451tx_ppdu_info->tx_mon_mpdu->tail = NULL;1452list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1453&tx_ppdu_info->dp_tx_mon_mpdu_list);14541455return 0;1456}14571458static int1459ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1460{1461struct sk_buff *skb;1462struct ieee80211_rts *rts;14631464skb = ath12k_dp_mon_tx_alloc_skb();1465if (!skb)1466return -ENOMEM;14671468rts = (struct ieee80211_rts *)skb->data;1469memset(rts, 0, MAX_DUMMY_FRM_BODY);1470rts->frame_control =1471cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);1472rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1473memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra));1474memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta));14751476skb_put(skb, sizeof(*rts));1477tx_ppdu_info->tx_mon_mpdu->head = skb;1478tx_ppdu_info->tx_mon_mpdu->tail = NULL;1479list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1480&tx_ppdu_info->dp_tx_mon_mpdu_list);14811482return 0;1483}14841485static int1486ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1487{1488struct sk_buff *skb;1489struct ieee80211_qos_hdr *qhdr;14901491skb = ath12k_dp_mon_tx_alloc_skb();1492if (!skb)1493return -ENOMEM;14941495qhdr = (struct ieee80211_qos_hdr *)skb->data;1496memset(qhdr, 0, MAX_DUMMY_FRM_BODY);1497qhdr->frame_control =1498cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);1499qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1500memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);1501memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);1502memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);15031504skb_put(skb, sizeof(*qhdr));1505tx_ppdu_info->tx_mon_mpdu->head = skb;1506tx_ppdu_info->tx_mon_mpdu->tail = NULL;1507list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1508&tx_ppdu_info->dp_tx_mon_mpdu_list);15091510return 0;1511}15121513static int1514ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1515{1516struct sk_buff *skb;1517struct dp_mon_qosframe_addr4 *qhdr;15181519skb = ath12k_dp_mon_tx_alloc_skb();1520if (!skb)1521return -ENOMEM;15221523qhdr = (struct dp_mon_qosframe_addr4 *)skb->data;1524memset(qhdr, 0, MAX_DUMMY_FRM_BODY);1525qhdr->frame_control =1526cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);1527qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1528memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);1529memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);1530memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);1531memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN);15321533skb_put(skb, sizeof(*qhdr));1534tx_ppdu_info->tx_mon_mpdu->head = skb;1535tx_ppdu_info->tx_mon_mpdu->tail = NULL;1536list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1537&tx_ppdu_info->dp_tx_mon_mpdu_list);15381539return 0;1540}15411542static int1543ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1544{1545struct sk_buff *skb;1546struct dp_mon_frame_min_one *fbmhdr;15471548skb = ath12k_dp_mon_tx_alloc_skb();1549if (!skb)1550return -ENOMEM;15511552fbmhdr = (struct dp_mon_frame_min_one *)skb->data;1553memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY);1554fbmhdr->frame_control =1555cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK);1556memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);15571558/* set duration zero for ack frame */1559fbmhdr->duration = 0;15601561skb_put(skb, sizeof(*fbmhdr));1562tx_ppdu_info->tx_mon_mpdu->head = skb;1563tx_ppdu_info->tx_mon_mpdu->tail = NULL;1564list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1565&tx_ppdu_info->dp_tx_mon_mpdu_list);15661567return 0;1568}15691570static int1571ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1572{1573int ret = 0;15741575switch (tx_ppdu_info->rx_status.medium_prot_type) {1576case DP_MON_TX_MEDIUM_RTS_LEGACY:1577case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW:1578case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW:1579ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info);1580break;1581case DP_MON_TX_MEDIUM_CTS2SELF:1582ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);1583break;1584case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR:1585ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info);1586break;1587case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR:1588ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info);1589break;1590}15911592return ret;1593}15941595static enum dp_mon_tx_tlv_status1596ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab,1597struct ath12k_mon_data *pmon,1598u16 tlv_tag, u8 *tlv_data, u32 userid)1599{1600struct dp_mon_tx_ppdu_info *tx_ppdu_info;1601enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE;1602u32 info[7];16031604tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag);16051606switch (tlv_tag) {1607case HAL_TX_FES_SETUP: {1608struct hal_tx_fes_setup *tx_fes_setup =1609(struct hal_tx_fes_setup *)tlv_data;16101611info[0] = __le32_to_cpu(tx_fes_setup->info0);1612tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id);1613tx_ppdu_info->num_users =1614u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);1615status = DP_MON_TX_FES_SETUP;1616break;1617}16181619case HAL_TX_FES_STATUS_END: {1620struct hal_tx_fes_status_end *tx_fes_status_end =1621(struct hal_tx_fes_status_end *)tlv_data;1622u32 tst_15_0, tst_31_16;16231624info[0] = __le32_to_cpu(tx_fes_status_end->info0);1625tst_15_0 =1626u32_get_bits(info[0],1627HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0);1628tst_31_16 =1629u32_get_bits(info[0],1630HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16);16311632tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16));1633status = DP_MON_TX_FES_STATUS_END;1634break;1635}16361637case HAL_RX_RESPONSE_REQUIRED_INFO: {1638struct hal_rx_resp_req_info *rx_resp_req_info =1639(struct hal_rx_resp_req_info *)tlv_data;1640u32 addr_32;1641u16 addr_16;16421643info[0] = __le32_to_cpu(rx_resp_req_info->info0);1644info[1] = __le32_to_cpu(rx_resp_req_info->info1);1645info[2] = __le32_to_cpu(rx_resp_req_info->info2);1646info[3] = __le32_to_cpu(rx_resp_req_info->info3);1647info[4] = __le32_to_cpu(rx_resp_req_info->info4);1648info[5] = __le32_to_cpu(rx_resp_req_info->info5);16491650tx_ppdu_info->rx_status.ppdu_id =1651u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID);1652tx_ppdu_info->rx_status.reception_type =1653u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE);1654tx_ppdu_info->rx_status.rx_duration =1655u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION);1656tx_ppdu_info->rx_status.mcs =1657u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS);1658tx_ppdu_info->rx_status.sgi =1659u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI);1660tx_ppdu_info->rx_status.is_stbc =1661u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC);1662tx_ppdu_info->rx_status.ldpc =1663u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC);1664tx_ppdu_info->rx_status.is_ampdu =1665u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU);1666tx_ppdu_info->rx_status.num_users =1667u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER);16681669addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0);1670addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32);1671ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);16721673addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0);1674addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16);1675ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);16761677if (tx_ppdu_info->rx_status.reception_type == 0)1678ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);1679status = DP_MON_RX_RESPONSE_REQUIRED_INFO;1680break;1681}16821683case HAL_PCU_PPDU_SETUP_INIT: {1684struct hal_tx_pcu_ppdu_setup_init *ppdu_setup =1685(struct hal_tx_pcu_ppdu_setup_init *)tlv_data;1686u32 addr_32;1687u16 addr_16;16881689info[0] = __le32_to_cpu(ppdu_setup->info0);1690info[1] = __le32_to_cpu(ppdu_setup->info1);1691info[2] = __le32_to_cpu(ppdu_setup->info2);1692info[3] = __le32_to_cpu(ppdu_setup->info3);1693info[4] = __le32_to_cpu(ppdu_setup->info4);1694info[5] = __le32_to_cpu(ppdu_setup->info5);1695info[6] = __le32_to_cpu(ppdu_setup->info6);16961697/* protection frame address 1 */1698addr_32 = u32_get_bits(info[1],1699HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0);1700addr_16 = u32_get_bits(info[2],1701HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32);1702ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);17031704/* protection frame address 2 */1705addr_16 = u32_get_bits(info[2],1706HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0);1707addr_32 = u32_get_bits(info[3],1708HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16);1709ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);17101711/* protection frame address 3 */1712addr_32 = u32_get_bits(info[4],1713HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0);1714addr_16 = u32_get_bits(info[5],1715HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32);1716ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3);17171718/* protection frame address 4 */1719addr_16 = u32_get_bits(info[5],1720HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0);1721addr_32 = u32_get_bits(info[6],1722HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16);1723ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4);17241725status = u32_get_bits(info[0],1726HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE);1727break;1728}17291730case HAL_TX_QUEUE_EXTENSION: {1731struct hal_tx_queue_exten *tx_q_exten =1732(struct hal_tx_queue_exten *)tlv_data;17331734info[0] = __le32_to_cpu(tx_q_exten->info0);17351736tx_ppdu_info->rx_status.frame_control =1737u32_get_bits(info[0],1738HAL_TX_Q_EXT_INFO0_FRAME_CTRL);1739tx_ppdu_info->rx_status.fc_valid = true;1740break;1741}17421743case HAL_TX_FES_STATUS_START: {1744struct hal_tx_fes_status_start *tx_fes_start =1745(struct hal_tx_fes_status_start *)tlv_data;17461747info[0] = __le32_to_cpu(tx_fes_start->info0);17481749tx_ppdu_info->rx_status.medium_prot_type =1750u32_get_bits(info[0],1751HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE);1752break;1753}17541755case HAL_TX_FES_STATUS_PROT: {1756struct hal_tx_fes_status_prot *tx_fes_status =1757(struct hal_tx_fes_status_prot *)tlv_data;1758u32 start_timestamp;1759u32 end_timestamp;17601761info[0] = __le32_to_cpu(tx_fes_status->info0);1762info[1] = __le32_to_cpu(tx_fes_status->info1);17631764start_timestamp =1765u32_get_bits(info[0],1766HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0);1767start_timestamp |=1768u32_get_bits(info[0],1769HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15;1770end_timestamp =1771u32_get_bits(info[1],1772HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0);1773end_timestamp |=1774u32_get_bits(info[1],1775HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15;1776tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp;17771778ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info);1779break;1780}17811782case HAL_TX_FES_STATUS_START_PPDU:1783case HAL_TX_FES_STATUS_START_PROT: {1784struct hal_tx_fes_status_start_prot *tx_fes_stat_start =1785(struct hal_tx_fes_status_start_prot *)tlv_data;1786u64 ppdu_ts;17871788info[0] = __le32_to_cpu(tx_fes_stat_start->info0);17891790tx_ppdu_info->rx_status.ppdu_ts =1791u32_get_bits(info[0],1792HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32);1793ppdu_ts = (u32_get_bits(info[1],1794HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32));1795tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32;1796break;1797}17981799case HAL_TX_FES_STATUS_USER_PPDU: {1800struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu =1801(struct hal_tx_fes_status_user_ppdu *)tlv_data;18021803info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0);18041805tx_ppdu_info->rx_status.rx_duration =1806u32_get_bits(info[0],1807HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION);1808break;1809}18101811case HAL_MACTX_HE_SIG_A_SU:1812ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status);1813break;18141815case HAL_MACTX_HE_SIG_A_MU_DL:1816ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status);1817break;18181819case HAL_MACTX_HE_SIG_B1_MU:1820ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status);1821break;18221823case HAL_MACTX_HE_SIG_B2_MU:1824ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status);1825break;18261827case HAL_MACTX_HE_SIG_B2_OFDMA:1828ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status);1829break;18301831case HAL_MACTX_VHT_SIG_A:1832ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status);1833break;18341835case HAL_MACTX_L_SIG_A:1836ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status);1837break;18381839case HAL_MACTX_L_SIG_B:1840ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status);1841break;18421843case HAL_RX_FRAME_BITMAP_ACK: {1844struct hal_rx_frame_bitmap_ack *fbm_ack =1845(struct hal_rx_frame_bitmap_ack *)tlv_data;1846u32 addr_32;1847u16 addr_16;18481849info[0] = __le32_to_cpu(fbm_ack->info0);1850info[1] = __le32_to_cpu(fbm_ack->info1);18511852addr_32 = u32_get_bits(info[0],1853HAL_RX_FBM_ACK_INFO0_ADDR1_31_0);1854addr_16 = u32_get_bits(info[1],1855HAL_RX_FBM_ACK_INFO1_ADDR1_47_32);1856ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);18571858ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info);1859break;1860}18611862case HAL_MACTX_PHY_DESC: {1863struct hal_tx_phy_desc *tx_phy_desc =1864(struct hal_tx_phy_desc *)tlv_data;18651866info[0] = __le32_to_cpu(tx_phy_desc->info0);1867info[1] = __le32_to_cpu(tx_phy_desc->info1);1868info[2] = __le32_to_cpu(tx_phy_desc->info2);1869info[3] = __le32_to_cpu(tx_phy_desc->info3);18701871tx_ppdu_info->rx_status.beamformed =1872u32_get_bits(info[0],1873HAL_TX_PHY_DESC_INFO0_BF_TYPE);1874tx_ppdu_info->rx_status.preamble_type =1875u32_get_bits(info[0],1876HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B);1877tx_ppdu_info->rx_status.mcs =1878u32_get_bits(info[1],1879HAL_TX_PHY_DESC_INFO1_MCS);1880tx_ppdu_info->rx_status.ltf_size =1881u32_get_bits(info[3],1882HAL_TX_PHY_DESC_INFO3_LTF_SIZE);1883tx_ppdu_info->rx_status.nss =1884u32_get_bits(info[2],1885HAL_TX_PHY_DESC_INFO2_NSS);1886tx_ppdu_info->rx_status.chan_num =1887u32_get_bits(info[3],1888HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL);1889tx_ppdu_info->rx_status.bw =1890u32_get_bits(info[0],1891HAL_TX_PHY_DESC_INFO0_BANDWIDTH);1892break;1893}18941895case HAL_TX_MPDU_START: {1896struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;18971898mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);1899if (!mon_mpdu)1900return DP_MON_TX_STATUS_PPDU_NOT_DONE;1901status = DP_MON_TX_MPDU_START;1902break;1903}19041905case HAL_MON_BUF_ADDR: {1906struct dp_rxdma_ring *buf_ring = &ab->dp.tx_mon_buf_ring;1907struct dp_mon_packet_info *packet_info =1908(struct dp_mon_packet_info *)tlv_data;1909int buf_id = u32_get_bits(packet_info->cookie,1910DP_RXDMA_BUF_COOKIE_BUF_ID);1911struct sk_buff *msdu;1912struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;1913struct ath12k_skb_rxcb *rxcb;19141915spin_lock_bh(&buf_ring->idr_lock);1916msdu = idr_remove(&buf_ring->bufs_idr, buf_id);1917spin_unlock_bh(&buf_ring->idr_lock);19181919if (unlikely(!msdu)) {1920ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",1921buf_id);1922return DP_MON_TX_STATUS_PPDU_NOT_DONE;1923}19241925rxcb = ATH12K_SKB_RXCB(msdu);1926dma_unmap_single(ab->dev, rxcb->paddr,1927msdu->len + skb_tailroom(msdu),1928DMA_FROM_DEVICE);19291930if (!mon_mpdu->head)1931mon_mpdu->head = msdu;1932else if (mon_mpdu->tail)1933mon_mpdu->tail->next = msdu;19341935mon_mpdu->tail = msdu;19361937ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);1938status = DP_MON_TX_BUFFER_ADDR;1939break;1940}19411942case HAL_TX_MPDU_END:1943list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1944&tx_ppdu_info->dp_tx_mon_mpdu_list);1945break;1946}19471948return status;1949}19501951enum dp_mon_tx_tlv_status1952ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag,1953struct hal_tlv_hdr *tx_tlv,1954u8 *num_users)1955{1956u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;1957u32 info0;19581959switch (tlv_tag) {1960case HAL_TX_FES_SETUP: {1961struct hal_tx_fes_setup *tx_fes_setup =1962(struct hal_tx_fes_setup *)tx_tlv;19631964info0 = __le32_to_cpu(tx_fes_setup->info0);19651966*num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);1967tlv_status = DP_MON_TX_FES_SETUP;1968break;1969}19701971case HAL_RX_RESPONSE_REQUIRED_INFO: {1972/* TODO: need to update *num_users */1973tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO;1974break;1975}1976}19771978return tlv_status;1979}19801981static void1982ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, int mac_id,1983struct napi_struct *napi,1984struct dp_mon_tx_ppdu_info *tx_ppdu_info)1985{1986struct dp_mon_mpdu *tmp, *mon_mpdu;1987struct sk_buff *head_msdu;19881989list_for_each_entry_safe(mon_mpdu, tmp,1990&tx_ppdu_info->dp_tx_mon_mpdu_list, list) {1991list_del(&mon_mpdu->list);1992head_msdu = mon_mpdu->head;19931994if (head_msdu)1995ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,1996&tx_ppdu_info->rx_status, napi);19971998kfree(mon_mpdu);1999}2000}20012002enum hal_rx_mon_status2003ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar,2004struct ath12k_mon_data *pmon,2005int mac_id,2006struct sk_buff *skb,2007struct napi_struct *napi,2008u32 ppdu_id)2009{2010struct ath12k_base *ab = ar->ab;2011struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info;2012struct hal_tlv_hdr *tlv;2013u8 *ptr = skb->data;2014u16 tlv_tag;2015u16 tlv_len;2016u32 tlv_userid = 0;2017u8 num_user;2018u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;20192020tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,2021DP_MON_TX_PROT_PPDU_INFO);2022if (!tx_prot_ppdu_info)2023return -ENOMEM;20242025tlv = (struct hal_tlv_hdr *)ptr;2026tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);20272028tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user);2029if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user)2030return -EINVAL;20312032tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,2033DP_MON_TX_DATA_PPDU_INFO);2034if (!tx_data_ppdu_info)2035return -ENOMEM;20362037do {2038tlv = (struct hal_tlv_hdr *)ptr;2039tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);2040tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);2041tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);20422043tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon,2044tlv_tag, ptr,2045tlv_userid);2046ptr += tlv_len;2047ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);2048if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE)2049break;2050} while (tlv_status != DP_MON_TX_FES_STATUS_END);20512052ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_data_ppdu_info);2053ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_prot_ppdu_info);20542055return tlv_status;2056}20572058int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget,2059enum dp_monitor_mode monitor_mode,2060struct napi_struct *napi)2061{2062struct hal_mon_dest_desc *mon_dst_desc;2063struct ath12k_pdev_dp *pdev_dp = &ar->dp;2064struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;2065struct ath12k_base *ab = ar->ab;2066struct ath12k_dp *dp = &ab->dp;2067struct sk_buff *skb;2068struct ath12k_skb_rxcb *rxcb;2069struct dp_srng *mon_dst_ring;2070struct hal_srng *srng;2071struct dp_rxdma_ring *buf_ring;2072u64 cookie;2073u32 ppdu_id;2074int num_buffs_reaped = 0, srng_id, buf_id;2075u8 dest_idx = 0, i;2076bool end_of_ppdu;2077struct hal_rx_mon_ppdu_info *ppdu_info;2078struct ath12k_peer *peer = NULL;20792080ppdu_info = &pmon->mon_ppdu_info;2081memset(ppdu_info, 0, sizeof(*ppdu_info));2082ppdu_info->peer_id = HAL_INVALID_PEERID;20832084srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);20852086if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) {2087mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];2088buf_ring = &dp->rxdma_mon_buf_ring;2089} else {2090mon_dst_ring = &pdev_dp->tx_mon_dst_ring[srng_id];2091buf_ring = &dp->tx_mon_buf_ring;2092}20932094srng = &ab->hal.srng_list[mon_dst_ring->ring_id];20952096spin_lock_bh(&srng->lock);2097ath12k_hal_srng_access_begin(ab, srng);20982099while (likely(*budget)) {2100*budget -= 1;2101mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);2102if (unlikely(!mon_dst_desc))2103break;21042105cookie = le32_to_cpu(mon_dst_desc->cookie);2106buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);21072108spin_lock_bh(&buf_ring->idr_lock);2109skb = idr_remove(&buf_ring->bufs_idr, buf_id);2110spin_unlock_bh(&buf_ring->idr_lock);21112112if (unlikely(!skb)) {2113ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",2114buf_id);2115goto move_next;2116}21172118rxcb = ATH12K_SKB_RXCB(skb);2119dma_unmap_single(ab->dev, rxcb->paddr,2120skb->len + skb_tailroom(skb),2121DMA_FROM_DEVICE);21222123pmon->dest_skb_q[dest_idx] = skb;2124dest_idx++;2125ppdu_id = le32_to_cpu(mon_dst_desc->ppdu_id);2126end_of_ppdu = le32_get_bits(mon_dst_desc->info0,2127HAL_MON_DEST_INFO0_END_OF_PPDU);2128if (!end_of_ppdu)2129continue;21302131for (i = 0; i < dest_idx; i++) {2132skb = pmon->dest_skb_q[i];21332134if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE)2135ath12k_dp_mon_rx_parse_mon_status(ar, pmon, mac_id,2136skb, napi);2137else2138ath12k_dp_mon_tx_parse_mon_status(ar, pmon, mac_id,2139skb, napi, ppdu_id);21402141peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);21422143if (!peer || !peer->sta) {2144ath12k_dbg(ab, ATH12K_DBG_DATA,2145"failed to find the peer with peer_id %d\n",2146ppdu_info->peer_id);2147dev_kfree_skb_any(skb);2148continue;2149}21502151dev_kfree_skb_any(skb);2152pmon->dest_skb_q[i] = NULL;2153}21542155dest_idx = 0;2156move_next:2157ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);2158ath12k_hal_srng_src_get_next_entry(ab, srng);2159num_buffs_reaped++;2160}21612162ath12k_hal_srng_access_end(ab, srng);2163spin_unlock_bh(&srng->lock);21642165return num_buffs_reaped;2166}21672168static void2169ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats,2170struct hal_rx_mon_ppdu_info *ppdu_info,2171struct hal_rx_user_status *user_stats,2172u32 num_msdu)2173{2174u32 rate_idx = 0;2175u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs;2176u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1;2177u32 bw_idx = ppdu_info->bw;2178u32 gi_idx = ppdu_info->gi;21792180if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) ||2181(bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) {2182return;2183}21842185if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N ||2186ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) {2187rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx;2188rate_idx += bw_idx * 2 + gi_idx;2189} else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) {2190gi_idx = ath12k_he_gi_to_nl80211_he_gi(ppdu_info->gi);2191rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx;2192rate_idx += bw_idx * 3 + gi_idx;2193} else {2194return;2195}21962197rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;2198if (user_stats)2199rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count;2200else2201rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;2202}22032204static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar,2205struct ath12k_sta *arsta,2206struct hal_rx_mon_ppdu_info *ppdu_info)2207{2208struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats;2209u32 num_msdu;22102211if (!rx_stats)2212return;22132214arsta->rssi_comb = ppdu_info->rssi_comb;22152216num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count +2217ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count;22182219rx_stats->num_msdu += num_msdu;2220rx_stats->tcp_msdu_count += ppdu_info->tcp_msdu_count +2221ppdu_info->tcp_ack_msdu_count;2222rx_stats->udp_msdu_count += ppdu_info->udp_msdu_count;2223rx_stats->other_msdu_count += ppdu_info->other_msdu_count;22242225if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||2226ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) {2227ppdu_info->nss = 1;2228ppdu_info->mcs = HAL_RX_MAX_MCS;2229ppdu_info->tid = IEEE80211_NUM_TIDS;2230}22312232if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)2233rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;22342235if (ppdu_info->tid <= IEEE80211_NUM_TIDS)2236rx_stats->tid_count[ppdu_info->tid] += num_msdu;22372238if (ppdu_info->preamble_type < HAL_RX_PREAMBLE_MAX)2239rx_stats->pream_cnt[ppdu_info->preamble_type] += num_msdu;22402241if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)2242rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;22432244if (ppdu_info->is_stbc)2245rx_stats->stbc_count += num_msdu;22462247if (ppdu_info->beamformed)2248rx_stats->beamformed_count += num_msdu;22492250if (ppdu_info->num_mpdu_fcs_ok > 1)2251rx_stats->ampdu_msdu_count += num_msdu;2252else2253rx_stats->non_ampdu_msdu_count += num_msdu;22542255rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;2256rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;2257rx_stats->dcm_count += ppdu_info->dcm;22582259rx_stats->rx_duration += ppdu_info->rx_duration;2260arsta->rx_duration = rx_stats->rx_duration;22612262if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) {2263rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu;2264rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len;2265}22662267if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&2268ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {2269rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;2270rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2271/* To fit into rate table for HT packets */2272ppdu_info->mcs = ppdu_info->mcs % 8;2273}22742275if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&2276ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) {2277rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu;2278rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2279}22802281if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX &&2282ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) {2283rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu;2284rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2285}22862287if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||2288ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) &&2289ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) {2290rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu;2291rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len;2292}22932294if (ppdu_info->gi < HAL_RX_GI_MAX) {2295rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;2296rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len;2297}22982299if (ppdu_info->bw < HAL_RX_BW_MAX) {2300rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;2301rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;2302}23032304ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,2305NULL, num_msdu);2306}23072308void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info)2309{2310struct hal_rx_user_status *rx_user_status;2311u32 num_users, i, mu_ul_user_v0_word0, mu_ul_user_v0_word1, ru_size;23122313if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO ||2314ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||2315ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO))2316return;23172318num_users = ppdu_info->num_users;2319if (num_users > HAL_MAX_UL_MU_USERS)2320num_users = HAL_MAX_UL_MU_USERS;23212322for (i = 0; i < num_users; i++) {2323rx_user_status = &ppdu_info->userstats[i];2324mu_ul_user_v0_word0 =2325rx_user_status->ul_ofdma_user_v0_word0;2326mu_ul_user_v0_word1 =2327rx_user_status->ul_ofdma_user_v0_word1;23282329if (u32_get_bits(mu_ul_user_v0_word0,2330HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID) &&2331!u32_get_bits(mu_ul_user_v0_word0,2332HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER)) {2333rx_user_status->mcs =2334u32_get_bits(mu_ul_user_v0_word1,2335HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS);2336rx_user_status->nss =2337u32_get_bits(mu_ul_user_v0_word1,2338HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS) + 1;23392340rx_user_status->ofdma_info_valid = 1;2341rx_user_status->ul_ofdma_ru_start_index =2342u32_get_bits(mu_ul_user_v0_word1,2343HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START);23442345ru_size = u32_get_bits(mu_ul_user_v0_word1,2346HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE);2347rx_user_status->ul_ofdma_ru_width = ru_size;2348rx_user_status->ul_ofdma_ru_size = ru_size;2349}2350rx_user_status->ldpc = u32_get_bits(mu_ul_user_v0_word1,2351HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC);2352}2353ppdu_info->ldpc = 1;2354}23552356static void2357ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar,2358struct hal_rx_mon_ppdu_info *ppdu_info,2359u32 uid)2360{2361struct ath12k_sta *arsta = NULL;2362struct ath12k_rx_peer_stats *rx_stats = NULL;2363struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];2364struct ath12k_peer *peer;2365u32 num_msdu;23662367if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF)2368return;23692370peer = ath12k_peer_find_by_ast(ar->ab, user_stats->ast_index);23712372if (!peer) {2373ath12k_warn(ar->ab, "peer ast idx %d can't be found\n",2374user_stats->ast_index);2375return;2376}23772378arsta = (struct ath12k_sta *)peer->sta->drv_priv;2379rx_stats = arsta->rx_stats;23802381if (!rx_stats)2382return;23832384arsta->rssi_comb = ppdu_info->rssi_comb;23852386num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count +2387user_stats->udp_msdu_count + user_stats->other_msdu_count;23882389rx_stats->num_msdu += num_msdu;2390rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count +2391user_stats->tcp_ack_msdu_count;2392rx_stats->udp_msdu_count += user_stats->udp_msdu_count;2393rx_stats->other_msdu_count += user_stats->other_msdu_count;23942395if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)2396rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;23972398if (user_stats->tid <= IEEE80211_NUM_TIDS)2399rx_stats->tid_count[user_stats->tid] += num_msdu;24002401if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX)2402rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu;24032404if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)2405rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;24062407if (ppdu_info->is_stbc)2408rx_stats->stbc_count += num_msdu;24092410if (ppdu_info->beamformed)2411rx_stats->beamformed_count += num_msdu;24122413if (user_stats->mpdu_cnt_fcs_ok > 1)2414rx_stats->ampdu_msdu_count += num_msdu;2415else2416rx_stats->non_ampdu_msdu_count += num_msdu;24172418rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok;2419rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err;2420rx_stats->dcm_count += ppdu_info->dcm;2421if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||2422ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)2423rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;24242425rx_stats->rx_duration += ppdu_info->rx_duration;2426arsta->rx_duration = rx_stats->rx_duration;24272428if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {2429rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;2430rx_stats->byte_stats.nss_count[user_stats->nss - 1] +=2431user_stats->mpdu_ok_byte_count;2432}24332434if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX &&2435user_stats->mcs <= HAL_RX_MAX_MCS_HE) {2436rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu;2437rx_stats->byte_stats.he_mcs_count[user_stats->mcs] +=2438user_stats->mpdu_ok_byte_count;2439}24402441if (ppdu_info->gi < HAL_RX_GI_MAX) {2442rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;2443rx_stats->byte_stats.gi_count[ppdu_info->gi] +=2444user_stats->mpdu_ok_byte_count;2445}24462447if (ppdu_info->bw < HAL_RX_BW_MAX) {2448rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;2449rx_stats->byte_stats.bw_count[ppdu_info->bw] +=2450user_stats->mpdu_ok_byte_count;2451}24522453ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,2454user_stats, num_msdu);2455}24562457static void2458ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar,2459struct hal_rx_mon_ppdu_info *ppdu_info)2460{2461u32 num_users, i;24622463num_users = ppdu_info->num_users;2464if (num_users > HAL_MAX_UL_MU_USERS)2465num_users = HAL_MAX_UL_MU_USERS;24662467for (i = 0; i < num_users; i++)2468ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, i);2469}24702471int ath12k_dp_mon_rx_process_stats(struct ath12k *ar, int mac_id,2472struct napi_struct *napi, int *budget)2473{2474struct ath12k_base *ab = ar->ab;2475struct ath12k_pdev_dp *pdev_dp = &ar->dp;2476struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;2477struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;2478struct ath12k_dp *dp = &ab->dp;2479struct hal_mon_dest_desc *mon_dst_desc;2480struct sk_buff *skb;2481struct ath12k_skb_rxcb *rxcb;2482struct dp_srng *mon_dst_ring;2483struct hal_srng *srng;2484struct dp_rxdma_ring *buf_ring;2485struct ath12k_sta *arsta = NULL;2486struct ath12k_peer *peer;2487u64 cookie;2488int num_buffs_reaped = 0, srng_id, buf_id;2489u8 dest_idx = 0, i;2490bool end_of_ppdu;2491u32 hal_status;24922493srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);2494mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];2495buf_ring = &dp->rxdma_mon_buf_ring;24962497srng = &ab->hal.srng_list[mon_dst_ring->ring_id];2498spin_lock_bh(&srng->lock);2499ath12k_hal_srng_access_begin(ab, srng);25002501while (likely(*budget)) {2502*budget -= 1;2503mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);2504if (unlikely(!mon_dst_desc))2505break;2506cookie = le32_to_cpu(mon_dst_desc->cookie);2507buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);25082509spin_lock_bh(&buf_ring->idr_lock);2510skb = idr_remove(&buf_ring->bufs_idr, buf_id);2511spin_unlock_bh(&buf_ring->idr_lock);25122513if (unlikely(!skb)) {2514ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",2515buf_id);2516goto move_next;2517}25182519rxcb = ATH12K_SKB_RXCB(skb);2520dma_unmap_single(ab->dev, rxcb->paddr,2521skb->len + skb_tailroom(skb),2522DMA_FROM_DEVICE);2523pmon->dest_skb_q[dest_idx] = skb;2524dest_idx++;2525end_of_ppdu = le32_get_bits(mon_dst_desc->info0,2526HAL_MON_DEST_INFO0_END_OF_PPDU);2527if (!end_of_ppdu)2528continue;25292530for (i = 0; i < dest_idx; i++) {2531skb = pmon->dest_skb_q[i];2532hal_status = ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);25332534if (ppdu_info->peer_id == HAL_INVALID_PEERID ||2535hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {2536dev_kfree_skb_any(skb);2537continue;2538}25392540rcu_read_lock();2541spin_lock_bh(&ab->base_lock);2542peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);2543if (!peer || !peer->sta) {2544ath12k_dbg(ab, ATH12K_DBG_DATA,2545"failed to find the peer with peer_id %d\n",2546ppdu_info->peer_id);2547spin_unlock_bh(&ab->base_lock);2548rcu_read_unlock();2549dev_kfree_skb_any(skb);2550continue;2551}25522553if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {2554arsta = (struct ath12k_sta *)peer->sta->drv_priv;2555ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,2556ppdu_info);2557} else if ((ppdu_info->fc_valid) &&2558(ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {2559ath12k_dp_mon_rx_process_ulofdma(ppdu_info);2560ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info);2561}25622563spin_unlock_bh(&ab->base_lock);2564rcu_read_unlock();2565dev_kfree_skb_any(skb);2566memset(ppdu_info, 0, sizeof(*ppdu_info));2567ppdu_info->peer_id = HAL_INVALID_PEERID;2568}25692570dest_idx = 0;2571move_next:2572ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);2573ath12k_hal_srng_src_get_next_entry(ab, srng);2574num_buffs_reaped++;2575}25762577ath12k_hal_srng_access_end(ab, srng);2578spin_unlock_bh(&srng->lock);2579return num_buffs_reaped;2580}25812582int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,2583struct napi_struct *napi, int budget,2584enum dp_monitor_mode monitor_mode)2585{2586struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id);2587int num_buffs_reaped = 0;25882589if (!ar->monitor_started)2590ath12k_dp_mon_rx_process_stats(ar, mac_id, napi, &budget);2591else2592num_buffs_reaped = ath12k_dp_mon_srng_process(ar, mac_id, &budget,2593monitor_mode, napi);25942595return num_buffs_reaped;2596}259725982599