2560 lines · c
1// SPDX-License-Identifier: BSD-3-Clause-Clear2/*3 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.5 */6 7#include "dp_mon.h"8#include "debug.h"9#include "dp_rx.h"10#include "dp_tx.h"11#include "peer.h"12 13static void ath12k_dp_mon_rx_handle_ofdma_info(void *rx_tlv,14 struct hal_rx_user_status *rx_user_status)15{16 struct hal_rx_ppdu_end_user_stats *ppdu_end_user = rx_tlv;17 18 rx_user_status->ul_ofdma_user_v0_word0 =19 __le32_to_cpu(ppdu_end_user->usr_resp_ref);20 rx_user_status->ul_ofdma_user_v0_word1 =21 __le32_to_cpu(ppdu_end_user->usr_resp_ref_ext);22}23 24static void25ath12k_dp_mon_rx_populate_byte_count(const struct hal_rx_ppdu_end_user_stats *stats,26 void *ppduinfo,27 struct hal_rx_user_status *rx_user_status)28{29 u32 mpdu_ok_byte_count = __le32_to_cpu(stats->mpdu_ok_cnt);30 u32 mpdu_err_byte_count = __le32_to_cpu(stats->mpdu_err_cnt);31 32 rx_user_status->mpdu_ok_byte_count =33 u32_get_bits(mpdu_ok_byte_count,34 HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_OK_BYTE_COUNT);35 rx_user_status->mpdu_err_byte_count =36 u32_get_bits(mpdu_err_byte_count,37 HAL_RX_PPDU_END_USER_STATS_MPDU_DELIM_ERR_BYTE_COUNT);38}39 40static void41ath12k_dp_mon_rx_populate_mu_user_info(void *rx_tlv,42 struct hal_rx_mon_ppdu_info *ppdu_info,43 struct hal_rx_user_status *rx_user_status)44{45 rx_user_status->ast_index = ppdu_info->ast_index;46 rx_user_status->tid = ppdu_info->tid;47 rx_user_status->tcp_ack_msdu_count =48 ppdu_info->tcp_ack_msdu_count;49 rx_user_status->tcp_msdu_count =50 ppdu_info->tcp_msdu_count;51 rx_user_status->udp_msdu_count =52 ppdu_info->udp_msdu_count;53 rx_user_status->other_msdu_count =54 ppdu_info->other_msdu_count;55 rx_user_status->frame_control = ppdu_info->frame_control;56 rx_user_status->frame_control_info_valid =57 ppdu_info->frame_control_info_valid;58 rx_user_status->data_sequence_control_info_valid =59 ppdu_info->data_sequence_control_info_valid;60 rx_user_status->first_data_seq_ctrl =61 ppdu_info->first_data_seq_ctrl;62 rx_user_status->preamble_type = ppdu_info->preamble_type;63 rx_user_status->ht_flags = ppdu_info->ht_flags;64 rx_user_status->vht_flags = ppdu_info->vht_flags;65 rx_user_status->he_flags = ppdu_info->he_flags;66 rx_user_status->rs_flags = ppdu_info->rs_flags;67 68 rx_user_status->mpdu_cnt_fcs_ok =69 ppdu_info->num_mpdu_fcs_ok;70 rx_user_status->mpdu_cnt_fcs_err =71 ppdu_info->num_mpdu_fcs_err;72 memcpy(&rx_user_status->mpdu_fcs_ok_bitmap[0], &ppdu_info->mpdu_fcs_ok_bitmap[0],73 HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *74 sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));75 76 ath12k_dp_mon_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);77}78 79static void ath12k_dp_mon_parse_vht_sig_a(u8 *tlv_data,80 struct hal_rx_mon_ppdu_info *ppdu_info)81{82 struct hal_rx_vht_sig_a_info *vht_sig =83 (struct hal_rx_vht_sig_a_info *)tlv_data;84 u32 nsts, group_id, info0, info1;85 u8 gi_setting;86 87 info0 = __le32_to_cpu(vht_sig->info0);88 info1 = __le32_to_cpu(vht_sig->info1);89 90 ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);91 ppdu_info->mcs = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_MCS);92 gi_setting = u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_GI_SETTING);93 switch (gi_setting) {94 case HAL_RX_VHT_SIG_A_NORMAL_GI:95 ppdu_info->gi = HAL_RX_GI_0_8_US;96 break;97 case HAL_RX_VHT_SIG_A_SHORT_GI:98 case HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY:99 ppdu_info->gi = HAL_RX_GI_0_4_US;100 break;101 }102 103 ppdu_info->is_stbc = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_STBC);104 nsts = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_NSTS);105 if (ppdu_info->is_stbc && nsts > 0)106 nsts = ((nsts + 1) >> 1) - 1;107 108 ppdu_info->nss = u32_get_bits(nsts, VHT_SIG_SU_NSS_MASK);109 ppdu_info->bw = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_BW);110 ppdu_info->beamformed = u32_get_bits(info1,111 HAL_RX_VHT_SIG_A_INFO_INFO1_BEAMFORMED);112 group_id = u32_get_bits(info0, HAL_RX_VHT_SIG_A_INFO_INFO0_GROUP_ID);113 if (group_id == 0 || group_id == 63)114 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;115 else116 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;117 ppdu_info->vht_flag_values5 = group_id;118 ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) |119 ppdu_info->nss);120 ppdu_info->vht_flag_values2 = ppdu_info->bw;121 ppdu_info->vht_flag_values4 =122 u32_get_bits(info1, HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING);123}124 125static void ath12k_dp_mon_parse_ht_sig(u8 *tlv_data,126 struct hal_rx_mon_ppdu_info *ppdu_info)127{128 struct hal_rx_ht_sig_info *ht_sig =129 (struct hal_rx_ht_sig_info *)tlv_data;130 u32 info0 = __le32_to_cpu(ht_sig->info0);131 u32 info1 = __le32_to_cpu(ht_sig->info1);132 133 ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_MCS);134 ppdu_info->bw = u32_get_bits(info0, HAL_RX_HT_SIG_INFO_INFO0_BW);135 ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_STBC);136 ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING);137 ppdu_info->gi = u32_get_bits(info1, HAL_RX_HT_SIG_INFO_INFO1_GI);138 ppdu_info->nss = (ppdu_info->mcs >> 3);139 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;140}141 142static void ath12k_dp_mon_parse_l_sig_b(u8 *tlv_data,143 struct hal_rx_mon_ppdu_info *ppdu_info)144{145 struct hal_rx_lsig_b_info *lsigb =146 (struct hal_rx_lsig_b_info *)tlv_data;147 u32 info0 = __le32_to_cpu(lsigb->info0);148 u8 rate;149 150 rate = u32_get_bits(info0, HAL_RX_LSIG_B_INFO_INFO0_RATE);151 switch (rate) {152 case 1:153 rate = HAL_RX_LEGACY_RATE_1_MBPS;154 break;155 case 2:156 case 5:157 rate = HAL_RX_LEGACY_RATE_2_MBPS;158 break;159 case 3:160 case 6:161 rate = HAL_RX_LEGACY_RATE_5_5_MBPS;162 break;163 case 4:164 case 7:165 rate = HAL_RX_LEGACY_RATE_11_MBPS;166 break;167 default:168 rate = HAL_RX_LEGACY_RATE_INVALID;169 }170 171 ppdu_info->rate = rate;172 ppdu_info->cck_flag = 1;173 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;174}175 176static void ath12k_dp_mon_parse_l_sig_a(u8 *tlv_data,177 struct hal_rx_mon_ppdu_info *ppdu_info)178{179 struct hal_rx_lsig_a_info *lsiga =180 (struct hal_rx_lsig_a_info *)tlv_data;181 u32 info0 = __le32_to_cpu(lsiga->info0);182 u8 rate;183 184 rate = u32_get_bits(info0, HAL_RX_LSIG_A_INFO_INFO0_RATE);185 switch (rate) {186 case 8:187 rate = HAL_RX_LEGACY_RATE_48_MBPS;188 break;189 case 9:190 rate = HAL_RX_LEGACY_RATE_24_MBPS;191 break;192 case 10:193 rate = HAL_RX_LEGACY_RATE_12_MBPS;194 break;195 case 11:196 rate = HAL_RX_LEGACY_RATE_6_MBPS;197 break;198 case 12:199 rate = HAL_RX_LEGACY_RATE_54_MBPS;200 break;201 case 13:202 rate = HAL_RX_LEGACY_RATE_36_MBPS;203 break;204 case 14:205 rate = HAL_RX_LEGACY_RATE_18_MBPS;206 break;207 case 15:208 rate = HAL_RX_LEGACY_RATE_9_MBPS;209 break;210 default:211 rate = HAL_RX_LEGACY_RATE_INVALID;212 }213 214 ppdu_info->rate = rate;215 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;216}217 218static void ath12k_dp_mon_parse_he_sig_b2_ofdma(u8 *tlv_data,219 struct hal_rx_mon_ppdu_info *ppdu_info)220{221 struct hal_rx_he_sig_b2_ofdma_info *he_sig_b2_ofdma =222 (struct hal_rx_he_sig_b2_ofdma_info *)tlv_data;223 u32 info0, value;224 225 info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);226 227 ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_DCM_KNOWN | HE_CODING_KNOWN;228 229 /* HE-data2 */230 ppdu_info->he_data2 |= HE_TXBF_KNOWN;231 232 ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS);233 value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;234 ppdu_info->he_data3 |= value;235 236 value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM);237 value = value << HE_DCM_SHIFT;238 ppdu_info->he_data3 |= value;239 240 value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING);241 ppdu_info->ldpc = value;242 value = value << HE_CODING_SHIFT;243 ppdu_info->he_data3 |= value;244 245 /* HE-data4 */246 value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID);247 value = value << HE_STA_ID_SHIFT;248 ppdu_info->he_data4 |= value;249 250 ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS);251 ppdu_info->beamformed = u32_get_bits(info0,252 HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF);253 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;254}255 256static void ath12k_dp_mon_parse_he_sig_b2_mu(u8 *tlv_data,257 struct hal_rx_mon_ppdu_info *ppdu_info)258{259 struct hal_rx_he_sig_b2_mu_info *he_sig_b2_mu =260 (struct hal_rx_he_sig_b2_mu_info *)tlv_data;261 u32 info0, value;262 263 info0 = __le32_to_cpu(he_sig_b2_mu->info0);264 265 ppdu_info->he_data1 |= HE_MCS_KNOWN | HE_CODING_KNOWN;266 267 ppdu_info->mcs = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS);268 value = ppdu_info->mcs << HE_TRANSMIT_MCS_SHIFT;269 ppdu_info->he_data3 |= value;270 271 value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING);272 ppdu_info->ldpc = value;273 value = value << HE_CODING_SHIFT;274 ppdu_info->he_data3 |= value;275 276 value = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID);277 value = value << HE_STA_ID_SHIFT;278 ppdu_info->he_data4 |= value;279 280 ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS);281}282 283static void ath12k_dp_mon_parse_he_sig_b1_mu(u8 *tlv_data,284 struct hal_rx_mon_ppdu_info *ppdu_info)285{286 struct hal_rx_he_sig_b1_mu_info *he_sig_b1_mu =287 (struct hal_rx_he_sig_b1_mu_info *)tlv_data;288 u32 info0 = __le32_to_cpu(he_sig_b1_mu->info0);289 u16 ru_tones;290 291 ru_tones = u32_get_bits(info0,292 HAL_RX_HE_SIG_B1_MU_INFO_INFO0_RU_ALLOCATION);293 ppdu_info->ru_alloc = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(ru_tones);294 ppdu_info->he_RU[0] = ru_tones;295 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;296}297 298static void ath12k_dp_mon_parse_he_sig_mu(u8 *tlv_data,299 struct hal_rx_mon_ppdu_info *ppdu_info)300{301 struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =302 (struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;303 u32 info0, info1, value;304 u16 he_gi = 0, he_ltf = 0;305 306 info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);307 info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);308 309 ppdu_info->he_mu_flags = 1;310 311 ppdu_info->he_data1 = HE_MU_FORMAT_TYPE;312 ppdu_info->he_data1 |=313 HE_BSS_COLOR_KNOWN |314 HE_DL_UL_KNOWN |315 HE_LDPC_EXTRA_SYMBOL_KNOWN |316 HE_STBC_KNOWN |317 HE_DATA_BW_RU_KNOWN |318 HE_DOPPLER_KNOWN;319 320 ppdu_info->he_data2 =321 HE_GI_KNOWN |322 HE_LTF_SYMBOLS_KNOWN |323 HE_PRE_FEC_PADDING_KNOWN |324 HE_PE_DISAMBIGUITY_KNOWN |325 HE_TXOP_KNOWN |326 HE_MIDABLE_PERIODICITY_KNOWN;327 328 /* data3 */329 ppdu_info->he_data3 = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_BSS_COLOR);330 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_UL_FLAG);331 value = value << HE_DL_UL_SHIFT;332 ppdu_info->he_data3 |= value;333 334 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_LDPC_EXTRA);335 value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;336 ppdu_info->he_data3 |= value;337 338 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC);339 value = value << HE_STBC_SHIFT;340 ppdu_info->he_data3 |= value;341 342 /* data4 */343 ppdu_info->he_data4 = u32_get_bits(info0,344 HAL_RX_HE_SIG_A_MU_DL_INFO0_SPATIAL_REUSE);345 ppdu_info->he_data4 = value;346 347 /* data5 */348 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);349 ppdu_info->he_data5 = value;350 ppdu_info->bw = value;351 352 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_CP_LTF_SIZE);353 switch (value) {354 case 0:355 he_gi = HE_GI_0_8;356 he_ltf = HE_LTF_4_X;357 break;358 case 1:359 he_gi = HE_GI_0_8;360 he_ltf = HE_LTF_2_X;361 break;362 case 2:363 he_gi = HE_GI_1_6;364 he_ltf = HE_LTF_2_X;365 break;366 case 3:367 he_gi = HE_GI_3_2;368 he_ltf = HE_LTF_4_X;369 break;370 }371 372 ppdu_info->gi = he_gi;373 value = he_gi << HE_GI_SHIFT;374 ppdu_info->he_data5 |= value;375 376 value = he_ltf << HE_LTF_SIZE_SHIFT;377 ppdu_info->he_data5 |= value;378 379 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_NUM_LTF_SYMB);380 value = (value << HE_LTF_SYM_SHIFT);381 ppdu_info->he_data5 |= value;382 383 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_FACTOR);384 value = value << HE_PRE_FEC_PAD_SHIFT;385 ppdu_info->he_data5 |= value;386 387 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_PKT_EXT_PE_DISAM);388 value = value << HE_PE_DISAMBIGUITY_SHIFT;389 ppdu_info->he_data5 |= value;390 391 /*data6*/392 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DOPPLER_INDICATION);393 value = value << HE_DOPPLER_SHIFT;394 ppdu_info->he_data6 |= value;395 396 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_MU_DL_INFO1_TXOP_DURATION);397 value = value << HE_TXOP_SHIFT;398 ppdu_info->he_data6 |= value;399 400 /* HE-MU Flags */401 /* HE-MU-flags1 */402 ppdu_info->he_flags1 =403 HE_SIG_B_MCS_KNOWN |404 HE_SIG_B_DCM_KNOWN |405 HE_SIG_B_COMPRESSION_FLAG_1_KNOWN |406 HE_SIG_B_SYM_NUM_KNOWN |407 HE_RU_0_KNOWN;408 409 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_MCS_OF_SIGB);410 ppdu_info->he_flags1 |= value;411 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_DCM_OF_SIGB);412 value = value << HE_DCM_FLAG_1_SHIFT;413 ppdu_info->he_flags1 |= value;414 415 /* HE-MU-flags2 */416 ppdu_info->he_flags2 = HE_BW_KNOWN;417 418 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_TRANSMIT_BW);419 ppdu_info->he_flags2 |= value;420 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_COMP_MODE_SIGB);421 value = value << HE_SIG_B_COMPRESSION_FLAG_2_SHIFT;422 ppdu_info->he_flags2 |= value;423 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_MU_DL_INFO0_NUM_SIGB_SYMB);424 value = value - 1;425 value = value << HE_NUM_SIG_B_SYMBOLS_SHIFT;426 ppdu_info->he_flags2 |= value;427 428 ppdu_info->is_stbc = info1 &429 HAL_RX_HE_SIG_A_MU_DL_INFO1_STBC;430 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;431}432 433static void ath12k_dp_mon_parse_he_sig_su(u8 *tlv_data,434 struct hal_rx_mon_ppdu_info *ppdu_info)435{436 struct hal_rx_he_sig_a_su_info *he_sig_a =437 (struct hal_rx_he_sig_a_su_info *)tlv_data;438 u32 info0, info1, value;439 u32 dcm;440 u8 he_dcm = 0, he_stbc = 0;441 u16 he_gi = 0, he_ltf = 0;442 443 ppdu_info->he_flags = 1;444 445 info0 = __le32_to_cpu(he_sig_a->info0);446 info1 = __le32_to_cpu(he_sig_a->info1);447 448 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND);449 if (value == 0)450 ppdu_info->he_data1 = HE_TRIG_FORMAT_TYPE;451 else452 ppdu_info->he_data1 = HE_SU_FORMAT_TYPE;453 454 ppdu_info->he_data1 |=455 HE_BSS_COLOR_KNOWN |456 HE_BEAM_CHANGE_KNOWN |457 HE_DL_UL_KNOWN |458 HE_MCS_KNOWN |459 HE_DCM_KNOWN |460 HE_CODING_KNOWN |461 HE_LDPC_EXTRA_SYMBOL_KNOWN |462 HE_STBC_KNOWN |463 HE_DATA_BW_RU_KNOWN |464 HE_DOPPLER_KNOWN;465 466 ppdu_info->he_data2 |=467 HE_GI_KNOWN |468 HE_TXBF_KNOWN |469 HE_PE_DISAMBIGUITY_KNOWN |470 HE_TXOP_KNOWN |471 HE_LTF_SYMBOLS_KNOWN |472 HE_PRE_FEC_PADDING_KNOWN |473 HE_MIDABLE_PERIODICITY_KNOWN;474 475 ppdu_info->he_data3 = u32_get_bits(info0,476 HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR);477 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE);478 value = value << HE_BEAM_CHANGE_SHIFT;479 ppdu_info->he_data3 |= value;480 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG);481 value = value << HE_DL_UL_SHIFT;482 ppdu_info->he_data3 |= value;483 484 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);485 ppdu_info->mcs = value;486 value = value << HE_TRANSMIT_MCS_SHIFT;487 ppdu_info->he_data3 |= value;488 489 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);490 he_dcm = value;491 value = value << HE_DCM_SHIFT;492 ppdu_info->he_data3 |= value;493 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);494 value = value << HE_CODING_SHIFT;495 ppdu_info->he_data3 |= value;496 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA);497 value = value << HE_LDPC_EXTRA_SYMBOL_SHIFT;498 ppdu_info->he_data3 |= value;499 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);500 he_stbc = value;501 value = value << HE_STBC_SHIFT;502 ppdu_info->he_data3 |= value;503 504 /* data4 */505 ppdu_info->he_data4 = u32_get_bits(info0,506 HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE);507 508 /* data5 */509 value = u32_get_bits(info0,510 HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);511 ppdu_info->he_data5 = value;512 ppdu_info->bw = value;513 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE);514 switch (value) {515 case 0:516 he_gi = HE_GI_0_8;517 he_ltf = HE_LTF_1_X;518 break;519 case 1:520 he_gi = HE_GI_0_8;521 he_ltf = HE_LTF_2_X;522 break;523 case 2:524 he_gi = HE_GI_1_6;525 he_ltf = HE_LTF_2_X;526 break;527 case 3:528 if (he_dcm && he_stbc) {529 he_gi = HE_GI_0_8;530 he_ltf = HE_LTF_4_X;531 } else {532 he_gi = HE_GI_3_2;533 he_ltf = HE_LTF_4_X;534 }535 break;536 }537 ppdu_info->gi = he_gi;538 value = he_gi << HE_GI_SHIFT;539 ppdu_info->he_data5 |= value;540 value = he_ltf << HE_LTF_SIZE_SHIFT;541 ppdu_info->ltf_size = he_ltf;542 ppdu_info->he_data5 |= value;543 544 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);545 value = (value << HE_LTF_SYM_SHIFT);546 ppdu_info->he_data5 |= value;547 548 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR);549 value = value << HE_PRE_FEC_PAD_SHIFT;550 ppdu_info->he_data5 |= value;551 552 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);553 value = value << HE_TXBF_SHIFT;554 ppdu_info->he_data5 |= value;555 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM);556 value = value << HE_PE_DISAMBIGUITY_SHIFT;557 ppdu_info->he_data5 |= value;558 559 /* data6 */560 value = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);561 value++;562 ppdu_info->he_data6 = value;563 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND);564 value = value << HE_DOPPLER_SHIFT;565 ppdu_info->he_data6 |= value;566 value = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION);567 value = value << HE_TXOP_SHIFT;568 ppdu_info->he_data6 |= value;569 570 ppdu_info->mcs =571 u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS);572 ppdu_info->bw =573 u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW);574 ppdu_info->ldpc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING);575 ppdu_info->is_stbc = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC);576 ppdu_info->beamformed = u32_get_bits(info1, HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF);577 dcm = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM);578 ppdu_info->nss = u32_get_bits(info0, HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS);579 ppdu_info->dcm = dcm;580 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;581}582 583static enum hal_rx_mon_status584ath12k_dp_mon_rx_parse_status_tlv(struct ath12k_base *ab,585 struct ath12k_mon_data *pmon,586 u32 tlv_tag, u8 *tlv_data, u32 userid)587{588 struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;589 u32 info[7];590 591 switch (tlv_tag) {592 case HAL_RX_PPDU_START: {593 struct hal_rx_ppdu_start *ppdu_start =594 (struct hal_rx_ppdu_start *)tlv_data;595 596 info[0] = __le32_to_cpu(ppdu_start->info0);597 598 ppdu_info->ppdu_id =599 u32_get_bits(info[0], HAL_RX_PPDU_START_INFO0_PPDU_ID);600 ppdu_info->chan_num = __le32_to_cpu(ppdu_start->chan_num);601 ppdu_info->ppdu_ts = __le32_to_cpu(ppdu_start->ppdu_start_ts);602 603 if (ppdu_info->ppdu_id != ppdu_info->last_ppdu_id) {604 ppdu_info->last_ppdu_id = ppdu_info->ppdu_id;605 ppdu_info->num_users = 0;606 memset(&ppdu_info->mpdu_fcs_ok_bitmap, 0,607 HAL_RX_NUM_WORDS_PER_PPDU_BITMAP *608 sizeof(ppdu_info->mpdu_fcs_ok_bitmap[0]));609 }610 break;611 }612 case HAL_RX_PPDU_END_USER_STATS: {613 struct hal_rx_ppdu_end_user_stats *eu_stats =614 (struct hal_rx_ppdu_end_user_stats *)tlv_data;615 616 info[0] = __le32_to_cpu(eu_stats->info0);617 info[1] = __le32_to_cpu(eu_stats->info1);618 info[2] = __le32_to_cpu(eu_stats->info2);619 info[4] = __le32_to_cpu(eu_stats->info4);620 info[5] = __le32_to_cpu(eu_stats->info5);621 info[6] = __le32_to_cpu(eu_stats->info6);622 623 ppdu_info->ast_index =624 u32_get_bits(info[2], HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX);625 ppdu_info->fc_valid =626 u32_get_bits(info[1], HAL_RX_PPDU_END_USER_STATS_INFO1_FC_VALID);627 ppdu_info->tid =628 ffs(u32_get_bits(info[6],629 HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP)630 - 1);631 ppdu_info->tcp_msdu_count =632 u32_get_bits(info[4],633 HAL_RX_PPDU_END_USER_STATS_INFO4_TCP_MSDU_CNT);634 ppdu_info->udp_msdu_count =635 u32_get_bits(info[4],636 HAL_RX_PPDU_END_USER_STATS_INFO4_UDP_MSDU_CNT);637 ppdu_info->other_msdu_count =638 u32_get_bits(info[5],639 HAL_RX_PPDU_END_USER_STATS_INFO5_OTHER_MSDU_CNT);640 ppdu_info->tcp_ack_msdu_count =641 u32_get_bits(info[5],642 HAL_RX_PPDU_END_USER_STATS_INFO5_TCP_ACK_MSDU_CNT);643 ppdu_info->preamble_type =644 u32_get_bits(info[1],645 HAL_RX_PPDU_END_USER_STATS_INFO1_PKT_TYPE);646 ppdu_info->num_mpdu_fcs_ok =647 u32_get_bits(info[1],648 HAL_RX_PPDU_END_USER_STATS_INFO1_MPDU_CNT_FCS_OK);649 ppdu_info->num_mpdu_fcs_err =650 u32_get_bits(info[0],651 HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR);652 switch (ppdu_info->preamble_type) {653 case HAL_RX_PREAMBLE_11N:654 ppdu_info->ht_flags = 1;655 break;656 case HAL_RX_PREAMBLE_11AC:657 ppdu_info->vht_flags = 1;658 break;659 case HAL_RX_PREAMBLE_11AX:660 ppdu_info->he_flags = 1;661 break;662 default:663 break;664 }665 666 if (userid < HAL_MAX_UL_MU_USERS) {667 struct hal_rx_user_status *rxuser_stats =668 &ppdu_info->userstats[userid];669 ppdu_info->num_users += 1;670 671 ath12k_dp_mon_rx_handle_ofdma_info(tlv_data, rxuser_stats);672 ath12k_dp_mon_rx_populate_mu_user_info(tlv_data, ppdu_info,673 rxuser_stats);674 }675 ppdu_info->mpdu_fcs_ok_bitmap[0] = __le32_to_cpu(eu_stats->rsvd1[0]);676 ppdu_info->mpdu_fcs_ok_bitmap[1] = __le32_to_cpu(eu_stats->rsvd1[1]);677 break;678 }679 case HAL_RX_PPDU_END_USER_STATS_EXT: {680 struct hal_rx_ppdu_end_user_stats_ext *eu_stats =681 (struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;682 ppdu_info->mpdu_fcs_ok_bitmap[2] = __le32_to_cpu(eu_stats->info1);683 ppdu_info->mpdu_fcs_ok_bitmap[3] = __le32_to_cpu(eu_stats->info2);684 ppdu_info->mpdu_fcs_ok_bitmap[4] = __le32_to_cpu(eu_stats->info3);685 ppdu_info->mpdu_fcs_ok_bitmap[5] = __le32_to_cpu(eu_stats->info4);686 ppdu_info->mpdu_fcs_ok_bitmap[6] = __le32_to_cpu(eu_stats->info5);687 ppdu_info->mpdu_fcs_ok_bitmap[7] = __le32_to_cpu(eu_stats->info6);688 break;689 }690 case HAL_PHYRX_HT_SIG:691 ath12k_dp_mon_parse_ht_sig(tlv_data, ppdu_info);692 break;693 694 case HAL_PHYRX_L_SIG_B:695 ath12k_dp_mon_parse_l_sig_b(tlv_data, ppdu_info);696 break;697 698 case HAL_PHYRX_L_SIG_A:699 ath12k_dp_mon_parse_l_sig_a(tlv_data, ppdu_info);700 break;701 702 case HAL_PHYRX_VHT_SIG_A:703 ath12k_dp_mon_parse_vht_sig_a(tlv_data, ppdu_info);704 break;705 706 case HAL_PHYRX_HE_SIG_A_SU:707 ath12k_dp_mon_parse_he_sig_su(tlv_data, ppdu_info);708 break;709 710 case HAL_PHYRX_HE_SIG_A_MU_DL:711 ath12k_dp_mon_parse_he_sig_mu(tlv_data, ppdu_info);712 break;713 714 case HAL_PHYRX_HE_SIG_B1_MU:715 ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, ppdu_info);716 break;717 718 case HAL_PHYRX_HE_SIG_B2_MU:719 ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, ppdu_info);720 break;721 722 case HAL_PHYRX_HE_SIG_B2_OFDMA:723 ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, ppdu_info);724 break;725 726 case HAL_PHYRX_RSSI_LEGACY: {727 struct hal_rx_phyrx_rssi_legacy_info *rssi =728 (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;729 u32 reception_type = 0;730 u32 rssi_legacy_info = __le32_to_cpu(rssi->rsvd[0]);731 732 info[0] = __le32_to_cpu(rssi->info0);733 734 /* TODO: Please note that the combined rssi will not be accurate735 * in MU case. Rssi in MU needs to be retrieved from736 * PHYRX_OTHER_RECEIVE_INFO TLV.737 */738 ppdu_info->rssi_comb =739 u32_get_bits(info[0],740 HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO0_RSSI_COMB);741 reception_type =742 u32_get_bits(rssi_legacy_info,743 HAL_RX_PHYRX_RSSI_LEGACY_INFO_RSVD1_RECEPTION);744 745 switch (reception_type) {746 case HAL_RECEPTION_TYPE_ULOFMDA:747 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;748 break;749 case HAL_RECEPTION_TYPE_ULMIMO:750 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;751 break;752 default:753 ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;754 break;755 }756 break;757 }758 case HAL_RXPCU_PPDU_END_INFO: {759 struct hal_rx_ppdu_end_duration *ppdu_rx_duration =760 (struct hal_rx_ppdu_end_duration *)tlv_data;761 762 info[0] = __le32_to_cpu(ppdu_rx_duration->info0);763 ppdu_info->rx_duration =764 u32_get_bits(info[0], HAL_RX_PPDU_END_DURATION);765 ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);766 ppdu_info->tsft = (ppdu_info->tsft << 32) |767 __le32_to_cpu(ppdu_rx_duration->rsvd0[0]);768 break;769 }770 case HAL_RX_MPDU_START: {771 struct hal_rx_mpdu_start *mpdu_start =772 (struct hal_rx_mpdu_start *)tlv_data;773 struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;774 u16 peer_id;775 776 info[1] = __le32_to_cpu(mpdu_start->info1);777 peer_id = u32_get_bits(info[1], HAL_RX_MPDU_START_INFO1_PEERID);778 if (peer_id)779 ppdu_info->peer_id = peer_id;780 781 ppdu_info->mpdu_len += u32_get_bits(info[1],782 HAL_RX_MPDU_START_INFO2_MPDU_LEN);783 if (userid < HAL_MAX_UL_MU_USERS) {784 info[0] = __le32_to_cpu(mpdu_start->info0);785 ppdu_info->userid = userid;786 ppdu_info->ampdu_id[userid] =787 u32_get_bits(info[0], HAL_RX_MPDU_START_INFO1_PEERID);788 }789 790 mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);791 if (!mon_mpdu)792 return HAL_RX_MON_STATUS_PPDU_NOT_DONE;793 794 break;795 }796 case HAL_RX_MSDU_START:797 /* TODO: add msdu start parsing logic */798 break;799 case HAL_MON_BUF_ADDR: {800 struct dp_rxdma_mon_ring *buf_ring = &ab->dp.rxdma_mon_buf_ring;801 struct dp_mon_packet_info *packet_info =802 (struct dp_mon_packet_info *)tlv_data;803 int buf_id = u32_get_bits(packet_info->cookie,804 DP_RXDMA_BUF_COOKIE_BUF_ID);805 struct sk_buff *msdu;806 struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;807 struct ath12k_skb_rxcb *rxcb;808 809 spin_lock_bh(&buf_ring->idr_lock);810 msdu = idr_remove(&buf_ring->bufs_idr, buf_id);811 spin_unlock_bh(&buf_ring->idr_lock);812 813 if (unlikely(!msdu)) {814 ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",815 buf_id);816 return HAL_RX_MON_STATUS_PPDU_NOT_DONE;817 }818 819 rxcb = ATH12K_SKB_RXCB(msdu);820 dma_unmap_single(ab->dev, rxcb->paddr,821 msdu->len + skb_tailroom(msdu),822 DMA_FROM_DEVICE);823 824 if (mon_mpdu->tail)825 mon_mpdu->tail->next = msdu;826 else827 mon_mpdu->tail = msdu;828 829 ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);830 831 break;832 }833 case HAL_RX_MSDU_END: {834 struct rx_msdu_end_qcn9274 *msdu_end =835 (struct rx_msdu_end_qcn9274 *)tlv_data;836 bool is_first_msdu_in_mpdu;837 u16 msdu_end_info;838 839 msdu_end_info = __le16_to_cpu(msdu_end->info5);840 is_first_msdu_in_mpdu = u32_get_bits(msdu_end_info,841 RX_MSDU_END_INFO5_FIRST_MSDU);842 if (is_first_msdu_in_mpdu) {843 pmon->mon_mpdu->head = pmon->mon_mpdu->tail;844 pmon->mon_mpdu->tail = NULL;845 }846 break;847 }848 case HAL_RX_MPDU_END:849 list_add_tail(&pmon->mon_mpdu->list, &pmon->dp_rx_mon_mpdu_list);850 break;851 case HAL_DUMMY:852 return HAL_RX_MON_STATUS_BUF_DONE;853 case HAL_RX_PPDU_END_STATUS_DONE:854 case 0:855 return HAL_RX_MON_STATUS_PPDU_DONE;856 default:857 break;858 }859 860 return HAL_RX_MON_STATUS_PPDU_NOT_DONE;861}862 863static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar, struct sk_buff *msdu)864{865 u32 rx_pkt_offset, l2_hdr_offset;866 867 rx_pkt_offset = ar->ab->hal.hal_desc_sz;868 l2_hdr_offset = ath12k_dp_rx_h_l3pad(ar->ab,869 (struct hal_rx_desc *)msdu->data);870 skb_pull(msdu, rx_pkt_offset + l2_hdr_offset);871}872 873static struct sk_buff *874ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,875 u32 mac_id, struct sk_buff *head_msdu,876 struct ieee80211_rx_status *rxs, bool *fcs_err)877{878 struct ath12k_base *ab = ar->ab;879 struct sk_buff *msdu, *mpdu_buf, *prev_buf;880 struct hal_rx_desc *rx_desc;881 u8 *hdr_desc, *dest, decap_format;882 struct ieee80211_hdr_3addr *wh;883 u32 err_bitmap;884 885 mpdu_buf = NULL;886 887 if (!head_msdu)888 goto err_merge_fail;889 890 rx_desc = (struct hal_rx_desc *)head_msdu->data;891 err_bitmap = ath12k_dp_rx_h_mpdu_err(ab, rx_desc);892 893 if (err_bitmap & HAL_RX_MPDU_ERR_FCS)894 *fcs_err = true;895 896 decap_format = ath12k_dp_rx_h_decap_type(ab, rx_desc);897 898 ath12k_dp_rx_h_ppdu(ar, rx_desc, rxs);899 900 if (decap_format == DP_RX_DECAP_TYPE_RAW) {901 ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu);902 903 prev_buf = head_msdu;904 msdu = head_msdu->next;905 906 while (msdu) {907 ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);908 909 prev_buf = msdu;910 msdu = msdu->next;911 }912 913 prev_buf->next = NULL;914 915 skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN);916 } else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) {917 u8 qos_pkt = 0;918 919 rx_desc = (struct hal_rx_desc *)head_msdu->data;920 hdr_desc =921 ab->hal_rx_ops->rx_desc_get_msdu_payload(rx_desc);922 923 /* Base size */924 wh = (struct ieee80211_hdr_3addr *)hdr_desc;925 926 if (ieee80211_is_data_qos(wh->frame_control))927 qos_pkt = 1;928 929 msdu = head_msdu;930 931 while (msdu) {932 ath12k_dp_mon_rx_msdus_set_payload(ar, msdu);933 if (qos_pkt) {934 dest = skb_push(msdu, sizeof(__le16));935 if (!dest)936 goto err_merge_fail;937 memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr));938 }939 prev_buf = msdu;940 msdu = msdu->next;941 }942 dest = skb_put(prev_buf, HAL_RX_FCS_LEN);943 if (!dest)944 goto err_merge_fail;945 946 ath12k_dbg(ab, ATH12K_DBG_DATA,947 "mpdu_buf %p mpdu_buf->len %u",948 prev_buf, prev_buf->len);949 } else {950 ath12k_dbg(ab, ATH12K_DBG_DATA,951 "decap format %d is not supported!\n",952 decap_format);953 goto err_merge_fail;954 }955 956 return head_msdu;957 958err_merge_fail:959 if (mpdu_buf && decap_format != DP_RX_DECAP_TYPE_RAW) {960 ath12k_dbg(ab, ATH12K_DBG_DATA,961 "err_merge_fail mpdu_buf %p", mpdu_buf);962 /* Free the head buffer */963 dev_kfree_skb_any(mpdu_buf);964 }965 return NULL;966}967 968static void969ath12k_dp_mon_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status,970 u8 *rtap_buf)971{972 u32 rtap_len = 0;973 974 put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);975 rtap_len += 2;976 977 put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);978 rtap_len += 2;979 980 put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);981 rtap_len += 2;982 983 put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);984 rtap_len += 2;985 986 put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);987 rtap_len += 2;988 989 put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);990}991 992static void993ath12k_dp_mon_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status,994 u8 *rtap_buf)995{996 u32 rtap_len = 0;997 998 put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);999 rtap_len += 2;1000 1001 put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);1002 rtap_len += 2;1003 1004 rtap_buf[rtap_len] = rx_status->he_RU[0];1005 rtap_len += 1;1006 1007 rtap_buf[rtap_len] = rx_status->he_RU[1];1008 rtap_len += 1;1009 1010 rtap_buf[rtap_len] = rx_status->he_RU[2];1011 rtap_len += 1;1012 1013 rtap_buf[rtap_len] = rx_status->he_RU[3];1014}1015 1016static void ath12k_dp_mon_update_radiotap(struct ath12k *ar,1017 struct hal_rx_mon_ppdu_info *ppduinfo,1018 struct sk_buff *mon_skb,1019 struct ieee80211_rx_status *rxs)1020{1021 struct ieee80211_supported_band *sband;1022 u8 *ptr = NULL;1023 u16 ampdu_id = ppduinfo->ampdu_id[ppduinfo->userid];1024 1025 rxs->flag |= RX_FLAG_MACTIME_START;1026 rxs->signal = ppduinfo->rssi_comb + ATH12K_DEFAULT_NOISE_FLOOR;1027 rxs->nss = ppduinfo->nss + 1;1028 1029 if (ampdu_id) {1030 rxs->flag |= RX_FLAG_AMPDU_DETAILS;1031 rxs->ampdu_reference = ampdu_id;1032 }1033 1034 if (ppduinfo->he_mu_flags) {1035 rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;1036 rxs->encoding = RX_ENC_HE;1037 ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));1038 ath12k_dp_mon_rx_update_radiotap_he_mu(ppduinfo, ptr);1039 } else if (ppduinfo->he_flags) {1040 rxs->flag |= RX_FLAG_RADIOTAP_HE;1041 rxs->encoding = RX_ENC_HE;1042 ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));1043 ath12k_dp_mon_rx_update_radiotap_he(ppduinfo, ptr);1044 rxs->rate_idx = ppduinfo->rate;1045 } else if (ppduinfo->vht_flags) {1046 rxs->encoding = RX_ENC_VHT;1047 rxs->rate_idx = ppduinfo->rate;1048 } else if (ppduinfo->ht_flags) {1049 rxs->encoding = RX_ENC_HT;1050 rxs->rate_idx = ppduinfo->rate;1051 } else {1052 rxs->encoding = RX_ENC_LEGACY;1053 sband = &ar->mac.sbands[rxs->band];1054 rxs->rate_idx = ath12k_mac_hw_rate_to_idx(sband, ppduinfo->rate,1055 ppduinfo->cck_flag);1056 }1057 1058 rxs->mactime = ppduinfo->tsft;1059}1060 1061static void ath12k_dp_mon_rx_deliver_msdu(struct ath12k *ar, struct napi_struct *napi,1062 struct sk_buff *msdu,1063 struct ieee80211_rx_status *status)1064{1065 static const struct ieee80211_radiotap_he known = {1066 .data1 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |1067 IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN),1068 .data2 = cpu_to_le16(IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN),1069 };1070 struct ieee80211_rx_status *rx_status;1071 struct ieee80211_radiotap_he *he = NULL;1072 struct ieee80211_sta *pubsta = NULL;1073 struct ath12k_peer *peer;1074 struct ath12k_skb_rxcb *rxcb = ATH12K_SKB_RXCB(msdu);1075 u8 decap = DP_RX_DECAP_TYPE_RAW;1076 bool is_mcbc = rxcb->is_mcbc;1077 bool is_eapol_tkip = rxcb->is_eapol;1078 1079 if ((status->encoding == RX_ENC_HE) && !(status->flag & RX_FLAG_RADIOTAP_HE) &&1080 !(status->flag & RX_FLAG_SKIP_MONITOR)) {1081 he = skb_push(msdu, sizeof(known));1082 memcpy(he, &known, sizeof(known));1083 status->flag |= RX_FLAG_RADIOTAP_HE;1084 }1085 1086 if (!(status->flag & RX_FLAG_ONLY_MONITOR))1087 decap = ath12k_dp_rx_h_decap_type(ar->ab, rxcb->rx_desc);1088 spin_lock_bh(&ar->ab->base_lock);1089 peer = ath12k_dp_rx_h_find_peer(ar->ab, msdu);1090 if (peer && peer->sta)1091 pubsta = peer->sta;1092 spin_unlock_bh(&ar->ab->base_lock);1093 1094 ath12k_dbg(ar->ab, ATH12K_DBG_DATA,1095 "rx skb %p len %u peer %pM %u %s %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",1096 msdu,1097 msdu->len,1098 peer ? peer->addr : NULL,1099 rxcb->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" : "",1108 (status->bw == RATE_INFO_BW_320) ? "320" : "",1109 status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",1110 status->rate_idx,1111 status->nss,1112 status->freq,1113 status->band, status->flag,1114 !!(status->flag & RX_FLAG_FAILED_FCS_CRC),1115 !!(status->flag & RX_FLAG_MMIC_ERROR),1116 !!(status->flag & RX_FLAG_AMSDU_MORE));1117 1118 ath12k_dbg_dump(ar->ab, ATH12K_DBG_DP_RX, NULL, "dp rx msdu: ",1119 msdu->data, msdu->len);1120 rx_status = IEEE80211_SKB_RXCB(msdu);1121 *rx_status = *status;1122 1123 /* TODO: trace rx packet */1124 1125 /* PN for multicast packets are not validate in HW,1126 * so skip 802.3 rx path1127 * Also, fast_rx expects the STA to be authorized, hence1128 * eapol packets are sent in slow path.1129 */1130 if (decap == DP_RX_DECAP_TYPE_ETHERNET2_DIX && !is_eapol_tkip &&1131 !(is_mcbc && rx_status->flag & RX_FLAG_DECRYPTED))1132 rx_status->flag |= RX_FLAG_8023;1133 1134 ieee80211_rx_napi(ath12k_ar_to_hw(ar), pubsta, msdu, napi);1135}1136 1137static int ath12k_dp_mon_rx_deliver(struct ath12k *ar, u32 mac_id,1138 struct sk_buff *head_msdu,1139 struct hal_rx_mon_ppdu_info *ppduinfo,1140 struct napi_struct *napi)1141{1142 struct ath12k_pdev_dp *dp = &ar->dp;1143 struct sk_buff *mon_skb, *skb_next, *header;1144 struct ieee80211_rx_status *rxs = &dp->rx_status;1145 bool fcs_err = false;1146 1147 mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mac_id, head_msdu,1148 rxs, &fcs_err);1149 if (!mon_skb)1150 goto mon_deliver_fail;1151 1152 header = mon_skb;1153 rxs->flag = 0;1154 1155 if (fcs_err)1156 rxs->flag = RX_FLAG_FAILED_FCS_CRC;1157 1158 do {1159 skb_next = mon_skb->next;1160 if (!skb_next)1161 rxs->flag &= ~RX_FLAG_AMSDU_MORE;1162 else1163 rxs->flag |= RX_FLAG_AMSDU_MORE;1164 1165 if (mon_skb == header) {1166 header = NULL;1167 rxs->flag &= ~RX_FLAG_ALLOW_SAME_PN;1168 } else {1169 rxs->flag |= RX_FLAG_ALLOW_SAME_PN;1170 }1171 rxs->flag |= RX_FLAG_ONLY_MONITOR;1172 ath12k_dp_mon_update_radiotap(ar, ppduinfo, mon_skb, rxs);1173 ath12k_dp_mon_rx_deliver_msdu(ar, napi, mon_skb, rxs);1174 mon_skb = skb_next;1175 } while (mon_skb);1176 rxs->flag = 0;1177 1178 return 0;1179 1180mon_deliver_fail:1181 mon_skb = head_msdu;1182 while (mon_skb) {1183 skb_next = mon_skb->next;1184 dev_kfree_skb_any(mon_skb);1185 mon_skb = skb_next;1186 }1187 return -EINVAL;1188}1189 1190static enum hal_rx_mon_status1191ath12k_dp_mon_parse_rx_dest(struct ath12k_base *ab, struct ath12k_mon_data *pmon,1192 struct sk_buff *skb)1193{1194 struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;1195 struct hal_tlv_hdr *tlv;1196 enum hal_rx_mon_status hal_status;1197 u32 tlv_userid = 0;1198 u16 tlv_tag, tlv_len;1199 u8 *ptr = skb->data;1200 1201 memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));1202 1203 do {1204 tlv = (struct hal_tlv_hdr *)ptr;1205 tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);1206 tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);1207 tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);1208 ptr += sizeof(*tlv);1209 1210 /* The actual length of PPDU_END is the combined length of many PHY1211 * TLVs that follow. Skip the TLV header and1212 * rx_rxpcu_classification_overview that follows the header to get to1213 * next TLV.1214 */1215 1216 if (tlv_tag == HAL_RX_PPDU_END)1217 tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);1218 1219 hal_status = ath12k_dp_mon_rx_parse_status_tlv(ab, pmon,1220 tlv_tag, ptr, tlv_userid);1221 ptr += tlv_len;1222 ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);1223 1224 if ((ptr - skb->data) >= DP_RX_BUFFER_SIZE)1225 break;1226 1227 } while (hal_status == HAL_RX_MON_STATUS_PPDU_NOT_DONE);1228 1229 return hal_status;1230}1231 1232enum hal_rx_mon_status1233ath12k_dp_mon_rx_parse_mon_status(struct ath12k *ar,1234 struct ath12k_mon_data *pmon,1235 int mac_id,1236 struct sk_buff *skb,1237 struct napi_struct *napi)1238{1239 struct ath12k_base *ab = ar->ab;1240 struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;1241 struct dp_mon_mpdu *tmp;1242 struct dp_mon_mpdu *mon_mpdu = pmon->mon_mpdu;1243 struct sk_buff *head_msdu, *tail_msdu;1244 enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;1245 1246 ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);1247 1248 list_for_each_entry_safe(mon_mpdu, tmp, &pmon->dp_rx_mon_mpdu_list, list) {1249 list_del(&mon_mpdu->list);1250 head_msdu = mon_mpdu->head;1251 tail_msdu = mon_mpdu->tail;1252 1253 if (head_msdu && tail_msdu) {1254 ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,1255 ppdu_info, napi);1256 }1257 1258 kfree(mon_mpdu);1259 }1260 return hal_status;1261}1262 1263int ath12k_dp_mon_buf_replenish(struct ath12k_base *ab,1264 struct dp_rxdma_mon_ring *buf_ring,1265 int req_entries)1266{1267 struct hal_mon_buf_ring *mon_buf;1268 struct sk_buff *skb;1269 struct hal_srng *srng;1270 dma_addr_t paddr;1271 u32 cookie;1272 int buf_id;1273 1274 srng = &ab->hal.srng_list[buf_ring->refill_buf_ring.ring_id];1275 spin_lock_bh(&srng->lock);1276 ath12k_hal_srng_access_begin(ab, srng);1277 1278 while (req_entries > 0) {1279 skb = dev_alloc_skb(DP_RX_BUFFER_SIZE + DP_RX_BUFFER_ALIGN_SIZE);1280 if (unlikely(!skb))1281 goto fail_alloc_skb;1282 1283 if (!IS_ALIGNED((unsigned long)skb->data, DP_RX_BUFFER_ALIGN_SIZE)) {1284 skb_pull(skb,1285 PTR_ALIGN(skb->data, DP_RX_BUFFER_ALIGN_SIZE) -1286 skb->data);1287 }1288 1289 paddr = dma_map_single(ab->dev, skb->data,1290 skb->len + skb_tailroom(skb),1291 DMA_FROM_DEVICE);1292 1293 if (unlikely(dma_mapping_error(ab->dev, paddr)))1294 goto fail_free_skb;1295 1296 spin_lock_bh(&buf_ring->idr_lock);1297 buf_id = idr_alloc(&buf_ring->bufs_idr, skb, 0,1298 buf_ring->bufs_max * 3, GFP_ATOMIC);1299 spin_unlock_bh(&buf_ring->idr_lock);1300 1301 if (unlikely(buf_id < 0))1302 goto fail_dma_unmap;1303 1304 mon_buf = ath12k_hal_srng_src_get_next_entry(ab, srng);1305 if (unlikely(!mon_buf))1306 goto fail_idr_remove;1307 1308 ATH12K_SKB_RXCB(skb)->paddr = paddr;1309 1310 cookie = u32_encode_bits(buf_id, DP_RXDMA_BUF_COOKIE_BUF_ID);1311 1312 mon_buf->paddr_lo = cpu_to_le32(lower_32_bits(paddr));1313 mon_buf->paddr_hi = cpu_to_le32(upper_32_bits(paddr));1314 mon_buf->cookie = cpu_to_le64(cookie);1315 1316 req_entries--;1317 }1318 1319 ath12k_hal_srng_access_end(ab, srng);1320 spin_unlock_bh(&srng->lock);1321 return 0;1322 1323fail_idr_remove:1324 spin_lock_bh(&buf_ring->idr_lock);1325 idr_remove(&buf_ring->bufs_idr, buf_id);1326 spin_unlock_bh(&buf_ring->idr_lock);1327fail_dma_unmap:1328 dma_unmap_single(ab->dev, paddr, skb->len + skb_tailroom(skb),1329 DMA_FROM_DEVICE);1330fail_free_skb:1331 dev_kfree_skb_any(skb);1332fail_alloc_skb:1333 ath12k_hal_srng_access_end(ab, srng);1334 spin_unlock_bh(&srng->lock);1335 return -ENOMEM;1336}1337 1338static struct dp_mon_tx_ppdu_info *1339ath12k_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon,1340 unsigned int ppdu_id,1341 enum dp_mon_tx_ppdu_info_type type)1342{1343 struct dp_mon_tx_ppdu_info *tx_ppdu_info;1344 1345 if (type == DP_MON_TX_PROT_PPDU_INFO) {1346 tx_ppdu_info = pmon->tx_prot_ppdu_info;1347 1348 if (tx_ppdu_info && !tx_ppdu_info->is_used)1349 return tx_ppdu_info;1350 kfree(tx_ppdu_info);1351 } else {1352 tx_ppdu_info = pmon->tx_data_ppdu_info;1353 1354 if (tx_ppdu_info && !tx_ppdu_info->is_used)1355 return tx_ppdu_info;1356 kfree(tx_ppdu_info);1357 }1358 1359 /* allocate new tx_ppdu_info */1360 tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC);1361 if (!tx_ppdu_info)1362 return NULL;1363 1364 tx_ppdu_info->is_used = 0;1365 tx_ppdu_info->ppdu_id = ppdu_id;1366 1367 if (type == DP_MON_TX_PROT_PPDU_INFO)1368 pmon->tx_prot_ppdu_info = tx_ppdu_info;1369 else1370 pmon->tx_data_ppdu_info = tx_ppdu_info;1371 1372 return tx_ppdu_info;1373}1374 1375static struct dp_mon_tx_ppdu_info *1376ath12k_dp_mon_hal_tx_ppdu_info(struct ath12k_mon_data *pmon,1377 u16 tlv_tag)1378{1379 switch (tlv_tag) {1380 case HAL_TX_FES_SETUP:1381 case HAL_TX_FLUSH:1382 case HAL_PCU_PPDU_SETUP_INIT:1383 case HAL_TX_PEER_ENTRY:1384 case HAL_TX_QUEUE_EXTENSION:1385 case HAL_TX_MPDU_START:1386 case HAL_TX_MSDU_START:1387 case HAL_TX_DATA:1388 case HAL_MON_BUF_ADDR:1389 case HAL_TX_MPDU_END:1390 case HAL_TX_LAST_MPDU_FETCHED:1391 case HAL_TX_LAST_MPDU_END:1392 case HAL_COEX_TX_REQ:1393 case HAL_TX_RAW_OR_NATIVE_FRAME_SETUP:1394 case HAL_SCH_CRITICAL_TLV_REFERENCE:1395 case HAL_TX_FES_SETUP_COMPLETE:1396 case HAL_TQM_MPDU_GLOBAL_START:1397 case HAL_SCHEDULER_END:1398 case HAL_TX_FES_STATUS_USER_PPDU:1399 break;1400 case HAL_TX_FES_STATUS_PROT: {1401 if (!pmon->tx_prot_ppdu_info->is_used)1402 pmon->tx_prot_ppdu_info->is_used = true;1403 1404 return pmon->tx_prot_ppdu_info;1405 }1406 }1407 1408 if (!pmon->tx_data_ppdu_info->is_used)1409 pmon->tx_data_ppdu_info->is_used = true;1410 1411 return pmon->tx_data_ppdu_info;1412}1413 1414#define MAX_MONITOR_HEADER 5121415#define MAX_DUMMY_FRM_BODY 1281416 1417struct sk_buff *ath12k_dp_mon_tx_alloc_skb(void)1418{1419 struct sk_buff *skb;1420 1421 skb = dev_alloc_skb(MAX_MONITOR_HEADER + MAX_DUMMY_FRM_BODY);1422 if (!skb)1423 return NULL;1424 1425 skb_reserve(skb, MAX_MONITOR_HEADER);1426 1427 if (!IS_ALIGNED((unsigned long)skb->data, 4))1428 skb_pull(skb, PTR_ALIGN(skb->data, 4) - skb->data);1429 1430 return skb;1431}1432 1433static int1434ath12k_dp_mon_tx_gen_cts2self_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1435{1436 struct sk_buff *skb;1437 struct ieee80211_cts *cts;1438 1439 skb = ath12k_dp_mon_tx_alloc_skb();1440 if (!skb)1441 return -ENOMEM;1442 1443 cts = (struct ieee80211_cts *)skb->data;1444 memset(cts, 0, MAX_DUMMY_FRM_BODY);1445 cts->frame_control =1446 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);1447 cts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1448 memcpy(cts->ra, tx_ppdu_info->rx_status.addr1, sizeof(cts->ra));1449 1450 skb_put(skb, sizeof(*cts));1451 tx_ppdu_info->tx_mon_mpdu->head = skb;1452 tx_ppdu_info->tx_mon_mpdu->tail = NULL;1453 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1454 &tx_ppdu_info->dp_tx_mon_mpdu_list);1455 1456 return 0;1457}1458 1459static int1460ath12k_dp_mon_tx_gen_rts_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1461{1462 struct sk_buff *skb;1463 struct ieee80211_rts *rts;1464 1465 skb = ath12k_dp_mon_tx_alloc_skb();1466 if (!skb)1467 return -ENOMEM;1468 1469 rts = (struct ieee80211_rts *)skb->data;1470 memset(rts, 0, MAX_DUMMY_FRM_BODY);1471 rts->frame_control =1472 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);1473 rts->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1474 memcpy(rts->ra, tx_ppdu_info->rx_status.addr1, sizeof(rts->ra));1475 memcpy(rts->ta, tx_ppdu_info->rx_status.addr2, sizeof(rts->ta));1476 1477 skb_put(skb, sizeof(*rts));1478 tx_ppdu_info->tx_mon_mpdu->head = skb;1479 tx_ppdu_info->tx_mon_mpdu->tail = NULL;1480 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1481 &tx_ppdu_info->dp_tx_mon_mpdu_list);1482 1483 return 0;1484}1485 1486static int1487ath12k_dp_mon_tx_gen_3addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1488{1489 struct sk_buff *skb;1490 struct ieee80211_qos_hdr *qhdr;1491 1492 skb = ath12k_dp_mon_tx_alloc_skb();1493 if (!skb)1494 return -ENOMEM;1495 1496 qhdr = (struct ieee80211_qos_hdr *)skb->data;1497 memset(qhdr, 0, MAX_DUMMY_FRM_BODY);1498 qhdr->frame_control =1499 cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);1500 qhdr->duration_id = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1501 memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);1502 memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);1503 memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);1504 1505 skb_put(skb, sizeof(*qhdr));1506 tx_ppdu_info->tx_mon_mpdu->head = skb;1507 tx_ppdu_info->tx_mon_mpdu->tail = NULL;1508 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1509 &tx_ppdu_info->dp_tx_mon_mpdu_list);1510 1511 return 0;1512}1513 1514static int1515ath12k_dp_mon_tx_gen_4addr_qos_null_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1516{1517 struct sk_buff *skb;1518 struct dp_mon_qosframe_addr4 *qhdr;1519 1520 skb = ath12k_dp_mon_tx_alloc_skb();1521 if (!skb)1522 return -ENOMEM;1523 1524 qhdr = (struct dp_mon_qosframe_addr4 *)skb->data;1525 memset(qhdr, 0, MAX_DUMMY_FRM_BODY);1526 qhdr->frame_control =1527 cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_NULLFUNC);1528 qhdr->duration = cpu_to_le16(tx_ppdu_info->rx_status.rx_duration);1529 memcpy(qhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);1530 memcpy(qhdr->addr2, tx_ppdu_info->rx_status.addr2, ETH_ALEN);1531 memcpy(qhdr->addr3, tx_ppdu_info->rx_status.addr3, ETH_ALEN);1532 memcpy(qhdr->addr4, tx_ppdu_info->rx_status.addr4, ETH_ALEN);1533 1534 skb_put(skb, sizeof(*qhdr));1535 tx_ppdu_info->tx_mon_mpdu->head = skb;1536 tx_ppdu_info->tx_mon_mpdu->tail = NULL;1537 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1538 &tx_ppdu_info->dp_tx_mon_mpdu_list);1539 1540 return 0;1541}1542 1543static int1544ath12k_dp_mon_tx_gen_ack_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1545{1546 struct sk_buff *skb;1547 struct dp_mon_frame_min_one *fbmhdr;1548 1549 skb = ath12k_dp_mon_tx_alloc_skb();1550 if (!skb)1551 return -ENOMEM;1552 1553 fbmhdr = (struct dp_mon_frame_min_one *)skb->data;1554 memset(fbmhdr, 0, MAX_DUMMY_FRM_BODY);1555 fbmhdr->frame_control =1556 cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_CFACK);1557 memcpy(fbmhdr->addr1, tx_ppdu_info->rx_status.addr1, ETH_ALEN);1558 1559 /* set duration zero for ack frame */1560 fbmhdr->duration = 0;1561 1562 skb_put(skb, sizeof(*fbmhdr));1563 tx_ppdu_info->tx_mon_mpdu->head = skb;1564 tx_ppdu_info->tx_mon_mpdu->tail = NULL;1565 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1566 &tx_ppdu_info->dp_tx_mon_mpdu_list);1567 1568 return 0;1569}1570 1571static int1572ath12k_dp_mon_tx_gen_prot_frame(struct dp_mon_tx_ppdu_info *tx_ppdu_info)1573{1574 int ret = 0;1575 1576 switch (tx_ppdu_info->rx_status.medium_prot_type) {1577 case DP_MON_TX_MEDIUM_RTS_LEGACY:1578 case DP_MON_TX_MEDIUM_RTS_11AC_STATIC_BW:1579 case DP_MON_TX_MEDIUM_RTS_11AC_DYNAMIC_BW:1580 ret = ath12k_dp_mon_tx_gen_rts_frame(tx_ppdu_info);1581 break;1582 case DP_MON_TX_MEDIUM_CTS2SELF:1583 ret = ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);1584 break;1585 case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_3ADDR:1586 ret = ath12k_dp_mon_tx_gen_3addr_qos_null_frame(tx_ppdu_info);1587 break;1588 case DP_MON_TX_MEDIUM_QOS_NULL_NO_ACK_4ADDR:1589 ret = ath12k_dp_mon_tx_gen_4addr_qos_null_frame(tx_ppdu_info);1590 break;1591 }1592 1593 return ret;1594}1595 1596static enum dp_mon_tx_tlv_status1597ath12k_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab,1598 struct ath12k_mon_data *pmon,1599 u16 tlv_tag, u8 *tlv_data, u32 userid)1600{1601 struct dp_mon_tx_ppdu_info *tx_ppdu_info;1602 enum dp_mon_tx_tlv_status status = DP_MON_TX_STATUS_PPDU_NOT_DONE;1603 u32 info[7];1604 1605 tx_ppdu_info = ath12k_dp_mon_hal_tx_ppdu_info(pmon, tlv_tag);1606 1607 switch (tlv_tag) {1608 case HAL_TX_FES_SETUP: {1609 struct hal_tx_fes_setup *tx_fes_setup =1610 (struct hal_tx_fes_setup *)tlv_data;1611 1612 info[0] = __le32_to_cpu(tx_fes_setup->info0);1613 tx_ppdu_info->ppdu_id = __le32_to_cpu(tx_fes_setup->schedule_id);1614 tx_ppdu_info->num_users =1615 u32_get_bits(info[0], HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);1616 status = DP_MON_TX_FES_SETUP;1617 break;1618 }1619 1620 case HAL_TX_FES_STATUS_END: {1621 struct hal_tx_fes_status_end *tx_fes_status_end =1622 (struct hal_tx_fes_status_end *)tlv_data;1623 u32 tst_15_0, tst_31_16;1624 1625 info[0] = __le32_to_cpu(tx_fes_status_end->info0);1626 tst_15_0 =1627 u32_get_bits(info[0],1628 HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_15_0);1629 tst_31_16 =1630 u32_get_bits(info[0],1631 HAL_TX_FES_STATUS_END_INFO0_START_TIMESTAMP_31_16);1632 1633 tx_ppdu_info->rx_status.ppdu_ts = (tst_15_0 | (tst_31_16 << 16));1634 status = DP_MON_TX_FES_STATUS_END;1635 break;1636 }1637 1638 case HAL_RX_RESPONSE_REQUIRED_INFO: {1639 struct hal_rx_resp_req_info *rx_resp_req_info =1640 (struct hal_rx_resp_req_info *)tlv_data;1641 u32 addr_32;1642 u16 addr_16;1643 1644 info[0] = __le32_to_cpu(rx_resp_req_info->info0);1645 info[1] = __le32_to_cpu(rx_resp_req_info->info1);1646 info[2] = __le32_to_cpu(rx_resp_req_info->info2);1647 info[3] = __le32_to_cpu(rx_resp_req_info->info3);1648 info[4] = __le32_to_cpu(rx_resp_req_info->info4);1649 info[5] = __le32_to_cpu(rx_resp_req_info->info5);1650 1651 tx_ppdu_info->rx_status.ppdu_id =1652 u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_PPDU_ID);1653 tx_ppdu_info->rx_status.reception_type =1654 u32_get_bits(info[0], HAL_RX_RESP_REQ_INFO0_RECEPTION_TYPE);1655 tx_ppdu_info->rx_status.rx_duration =1656 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_DURATION);1657 tx_ppdu_info->rx_status.mcs =1658 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_RATE_MCS);1659 tx_ppdu_info->rx_status.sgi =1660 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_SGI);1661 tx_ppdu_info->rx_status.is_stbc =1662 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_STBC);1663 tx_ppdu_info->rx_status.ldpc =1664 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_LDPC);1665 tx_ppdu_info->rx_status.is_ampdu =1666 u32_get_bits(info[1], HAL_RX_RESP_REQ_INFO1_IS_AMPDU);1667 tx_ppdu_info->rx_status.num_users =1668 u32_get_bits(info[2], HAL_RX_RESP_REQ_INFO2_NUM_USER);1669 1670 addr_32 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO3_ADDR1_31_0);1671 addr_16 = u32_get_bits(info[3], HAL_RX_RESP_REQ_INFO4_ADDR1_47_32);1672 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);1673 1674 addr_16 = u32_get_bits(info[4], HAL_RX_RESP_REQ_INFO4_ADDR1_15_0);1675 addr_32 = u32_get_bits(info[5], HAL_RX_RESP_REQ_INFO5_ADDR1_47_16);1676 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);1677 1678 if (tx_ppdu_info->rx_status.reception_type == 0)1679 ath12k_dp_mon_tx_gen_cts2self_frame(tx_ppdu_info);1680 status = DP_MON_RX_RESPONSE_REQUIRED_INFO;1681 break;1682 }1683 1684 case HAL_PCU_PPDU_SETUP_INIT: {1685 struct hal_tx_pcu_ppdu_setup_init *ppdu_setup =1686 (struct hal_tx_pcu_ppdu_setup_init *)tlv_data;1687 u32 addr_32;1688 u16 addr_16;1689 1690 info[0] = __le32_to_cpu(ppdu_setup->info0);1691 info[1] = __le32_to_cpu(ppdu_setup->info1);1692 info[2] = __le32_to_cpu(ppdu_setup->info2);1693 info[3] = __le32_to_cpu(ppdu_setup->info3);1694 info[4] = __le32_to_cpu(ppdu_setup->info4);1695 info[5] = __le32_to_cpu(ppdu_setup->info5);1696 info[6] = __le32_to_cpu(ppdu_setup->info6);1697 1698 /* protection frame address 1 */1699 addr_32 = u32_get_bits(info[1],1700 HAL_TX_PPDU_SETUP_INFO1_PROT_FRAME_ADDR1_31_0);1701 addr_16 = u32_get_bits(info[2],1702 HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR1_47_32);1703 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);1704 1705 /* protection frame address 2 */1706 addr_16 = u32_get_bits(info[2],1707 HAL_TX_PPDU_SETUP_INFO2_PROT_FRAME_ADDR2_15_0);1708 addr_32 = u32_get_bits(info[3],1709 HAL_TX_PPDU_SETUP_INFO3_PROT_FRAME_ADDR2_47_16);1710 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr2);1711 1712 /* protection frame address 3 */1713 addr_32 = u32_get_bits(info[4],1714 HAL_TX_PPDU_SETUP_INFO4_PROT_FRAME_ADDR3_31_0);1715 addr_16 = u32_get_bits(info[5],1716 HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR3_47_32);1717 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr3);1718 1719 /* protection frame address 4 */1720 addr_16 = u32_get_bits(info[5],1721 HAL_TX_PPDU_SETUP_INFO5_PROT_FRAME_ADDR4_15_0);1722 addr_32 = u32_get_bits(info[6],1723 HAL_TX_PPDU_SETUP_INFO6_PROT_FRAME_ADDR4_47_16);1724 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr4);1725 1726 status = u32_get_bits(info[0],1727 HAL_TX_PPDU_SETUP_INFO0_MEDIUM_PROT_TYPE);1728 break;1729 }1730 1731 case HAL_TX_QUEUE_EXTENSION: {1732 struct hal_tx_queue_exten *tx_q_exten =1733 (struct hal_tx_queue_exten *)tlv_data;1734 1735 info[0] = __le32_to_cpu(tx_q_exten->info0);1736 1737 tx_ppdu_info->rx_status.frame_control =1738 u32_get_bits(info[0],1739 HAL_TX_Q_EXT_INFO0_FRAME_CTRL);1740 tx_ppdu_info->rx_status.fc_valid = true;1741 break;1742 }1743 1744 case HAL_TX_FES_STATUS_START: {1745 struct hal_tx_fes_status_start *tx_fes_start =1746 (struct hal_tx_fes_status_start *)tlv_data;1747 1748 info[0] = __le32_to_cpu(tx_fes_start->info0);1749 1750 tx_ppdu_info->rx_status.medium_prot_type =1751 u32_get_bits(info[0],1752 HAL_TX_FES_STATUS_START_INFO0_MEDIUM_PROT_TYPE);1753 break;1754 }1755 1756 case HAL_TX_FES_STATUS_PROT: {1757 struct hal_tx_fes_status_prot *tx_fes_status =1758 (struct hal_tx_fes_status_prot *)tlv_data;1759 u32 start_timestamp;1760 u32 end_timestamp;1761 1762 info[0] = __le32_to_cpu(tx_fes_status->info0);1763 info[1] = __le32_to_cpu(tx_fes_status->info1);1764 1765 start_timestamp =1766 u32_get_bits(info[0],1767 HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_15_0);1768 start_timestamp |=1769 u32_get_bits(info[0],1770 HAL_TX_FES_STAT_PROT_INFO0_STRT_FRM_TS_31_16) << 15;1771 end_timestamp =1772 u32_get_bits(info[1],1773 HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_15_0);1774 end_timestamp |=1775 u32_get_bits(info[1],1776 HAL_TX_FES_STAT_PROT_INFO1_END_FRM_TS_31_16) << 15;1777 tx_ppdu_info->rx_status.rx_duration = end_timestamp - start_timestamp;1778 1779 ath12k_dp_mon_tx_gen_prot_frame(tx_ppdu_info);1780 break;1781 }1782 1783 case HAL_TX_FES_STATUS_START_PPDU:1784 case HAL_TX_FES_STATUS_START_PROT: {1785 struct hal_tx_fes_status_start_prot *tx_fes_stat_start =1786 (struct hal_tx_fes_status_start_prot *)tlv_data;1787 u64 ppdu_ts;1788 1789 info[0] = __le32_to_cpu(tx_fes_stat_start->info0);1790 1791 tx_ppdu_info->rx_status.ppdu_ts =1792 u32_get_bits(info[0],1793 HAL_TX_FES_STAT_STRT_INFO0_PROT_TS_LOWER_32);1794 ppdu_ts = (u32_get_bits(info[1],1795 HAL_TX_FES_STAT_STRT_INFO1_PROT_TS_UPPER_32));1796 tx_ppdu_info->rx_status.ppdu_ts |= ppdu_ts << 32;1797 break;1798 }1799 1800 case HAL_TX_FES_STATUS_USER_PPDU: {1801 struct hal_tx_fes_status_user_ppdu *tx_fes_usr_ppdu =1802 (struct hal_tx_fes_status_user_ppdu *)tlv_data;1803 1804 info[0] = __le32_to_cpu(tx_fes_usr_ppdu->info0);1805 1806 tx_ppdu_info->rx_status.rx_duration =1807 u32_get_bits(info[0],1808 HAL_TX_FES_STAT_USR_PPDU_INFO0_DURATION);1809 break;1810 }1811 1812 case HAL_MACTX_HE_SIG_A_SU:1813 ath12k_dp_mon_parse_he_sig_su(tlv_data, &tx_ppdu_info->rx_status);1814 break;1815 1816 case HAL_MACTX_HE_SIG_A_MU_DL:1817 ath12k_dp_mon_parse_he_sig_mu(tlv_data, &tx_ppdu_info->rx_status);1818 break;1819 1820 case HAL_MACTX_HE_SIG_B1_MU:1821 ath12k_dp_mon_parse_he_sig_b1_mu(tlv_data, &tx_ppdu_info->rx_status);1822 break;1823 1824 case HAL_MACTX_HE_SIG_B2_MU:1825 ath12k_dp_mon_parse_he_sig_b2_mu(tlv_data, &tx_ppdu_info->rx_status);1826 break;1827 1828 case HAL_MACTX_HE_SIG_B2_OFDMA:1829 ath12k_dp_mon_parse_he_sig_b2_ofdma(tlv_data, &tx_ppdu_info->rx_status);1830 break;1831 1832 case HAL_MACTX_VHT_SIG_A:1833 ath12k_dp_mon_parse_vht_sig_a(tlv_data, &tx_ppdu_info->rx_status);1834 break;1835 1836 case HAL_MACTX_L_SIG_A:1837 ath12k_dp_mon_parse_l_sig_a(tlv_data, &tx_ppdu_info->rx_status);1838 break;1839 1840 case HAL_MACTX_L_SIG_B:1841 ath12k_dp_mon_parse_l_sig_b(tlv_data, &tx_ppdu_info->rx_status);1842 break;1843 1844 case HAL_RX_FRAME_BITMAP_ACK: {1845 struct hal_rx_frame_bitmap_ack *fbm_ack =1846 (struct hal_rx_frame_bitmap_ack *)tlv_data;1847 u32 addr_32;1848 u16 addr_16;1849 1850 info[0] = __le32_to_cpu(fbm_ack->info0);1851 info[1] = __le32_to_cpu(fbm_ack->info1);1852 1853 addr_32 = u32_get_bits(info[0],1854 HAL_RX_FBM_ACK_INFO0_ADDR1_31_0);1855 addr_16 = u32_get_bits(info[1],1856 HAL_RX_FBM_ACK_INFO1_ADDR1_47_32);1857 ath12k_dp_get_mac_addr(addr_32, addr_16, tx_ppdu_info->rx_status.addr1);1858 1859 ath12k_dp_mon_tx_gen_ack_frame(tx_ppdu_info);1860 break;1861 }1862 1863 case HAL_MACTX_PHY_DESC: {1864 struct hal_tx_phy_desc *tx_phy_desc =1865 (struct hal_tx_phy_desc *)tlv_data;1866 1867 info[0] = __le32_to_cpu(tx_phy_desc->info0);1868 info[1] = __le32_to_cpu(tx_phy_desc->info1);1869 info[2] = __le32_to_cpu(tx_phy_desc->info2);1870 info[3] = __le32_to_cpu(tx_phy_desc->info3);1871 1872 tx_ppdu_info->rx_status.beamformed =1873 u32_get_bits(info[0],1874 HAL_TX_PHY_DESC_INFO0_BF_TYPE);1875 tx_ppdu_info->rx_status.preamble_type =1876 u32_get_bits(info[0],1877 HAL_TX_PHY_DESC_INFO0_PREAMBLE_11B);1878 tx_ppdu_info->rx_status.mcs =1879 u32_get_bits(info[1],1880 HAL_TX_PHY_DESC_INFO1_MCS);1881 tx_ppdu_info->rx_status.ltf_size =1882 u32_get_bits(info[3],1883 HAL_TX_PHY_DESC_INFO3_LTF_SIZE);1884 tx_ppdu_info->rx_status.nss =1885 u32_get_bits(info[2],1886 HAL_TX_PHY_DESC_INFO2_NSS);1887 tx_ppdu_info->rx_status.chan_num =1888 u32_get_bits(info[3],1889 HAL_TX_PHY_DESC_INFO3_ACTIVE_CHANNEL);1890 tx_ppdu_info->rx_status.bw =1891 u32_get_bits(info[0],1892 HAL_TX_PHY_DESC_INFO0_BANDWIDTH);1893 break;1894 }1895 1896 case HAL_TX_MPDU_START: {1897 struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu;1898 1899 mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC);1900 if (!mon_mpdu)1901 return DP_MON_TX_STATUS_PPDU_NOT_DONE;1902 status = DP_MON_TX_MPDU_START;1903 break;1904 }1905 1906 case HAL_TX_MPDU_END:1907 list_add_tail(&tx_ppdu_info->tx_mon_mpdu->list,1908 &tx_ppdu_info->dp_tx_mon_mpdu_list);1909 break;1910 }1911 1912 return status;1913}1914 1915enum dp_mon_tx_tlv_status1916ath12k_dp_mon_tx_status_get_num_user(u16 tlv_tag,1917 struct hal_tlv_hdr *tx_tlv,1918 u8 *num_users)1919{1920 u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;1921 u32 info0;1922 1923 switch (tlv_tag) {1924 case HAL_TX_FES_SETUP: {1925 struct hal_tx_fes_setup *tx_fes_setup =1926 (struct hal_tx_fes_setup *)tx_tlv;1927 1928 info0 = __le32_to_cpu(tx_fes_setup->info0);1929 1930 *num_users = u32_get_bits(info0, HAL_TX_FES_SETUP_INFO0_NUM_OF_USERS);1931 tlv_status = DP_MON_TX_FES_SETUP;1932 break;1933 }1934 1935 case HAL_RX_RESPONSE_REQUIRED_INFO: {1936 /* TODO: need to update *num_users */1937 tlv_status = DP_MON_RX_RESPONSE_REQUIRED_INFO;1938 break;1939 }1940 }1941 1942 return tlv_status;1943}1944 1945static void1946ath12k_dp_mon_tx_process_ppdu_info(struct ath12k *ar, int mac_id,1947 struct napi_struct *napi,1948 struct dp_mon_tx_ppdu_info *tx_ppdu_info)1949{1950 struct dp_mon_mpdu *tmp, *mon_mpdu;1951 struct sk_buff *head_msdu;1952 1953 list_for_each_entry_safe(mon_mpdu, tmp,1954 &tx_ppdu_info->dp_tx_mon_mpdu_list, list) {1955 list_del(&mon_mpdu->list);1956 head_msdu = mon_mpdu->head;1957 1958 if (head_msdu)1959 ath12k_dp_mon_rx_deliver(ar, mac_id, head_msdu,1960 &tx_ppdu_info->rx_status, napi);1961 1962 kfree(mon_mpdu);1963 }1964}1965 1966enum hal_rx_mon_status1967ath12k_dp_mon_tx_parse_mon_status(struct ath12k *ar,1968 struct ath12k_mon_data *pmon,1969 int mac_id,1970 struct sk_buff *skb,1971 struct napi_struct *napi,1972 u32 ppdu_id)1973{1974 struct ath12k_base *ab = ar->ab;1975 struct dp_mon_tx_ppdu_info *tx_prot_ppdu_info, *tx_data_ppdu_info;1976 struct hal_tlv_hdr *tlv;1977 u8 *ptr = skb->data;1978 u16 tlv_tag;1979 u16 tlv_len;1980 u32 tlv_userid = 0;1981 u8 num_user;1982 u32 tlv_status = DP_MON_TX_STATUS_PPDU_NOT_DONE;1983 1984 tx_prot_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,1985 DP_MON_TX_PROT_PPDU_INFO);1986 if (!tx_prot_ppdu_info)1987 return -ENOMEM;1988 1989 tlv = (struct hal_tlv_hdr *)ptr;1990 tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);1991 1992 tlv_status = ath12k_dp_mon_tx_status_get_num_user(tlv_tag, tlv, &num_user);1993 if (tlv_status == DP_MON_TX_STATUS_PPDU_NOT_DONE || !num_user)1994 return -EINVAL;1995 1996 tx_data_ppdu_info = ath12k_dp_mon_tx_get_ppdu_info(pmon, ppdu_id,1997 DP_MON_TX_DATA_PPDU_INFO);1998 if (!tx_data_ppdu_info)1999 return -ENOMEM;2000 2001 do {2002 tlv = (struct hal_tlv_hdr *)ptr;2003 tlv_tag = le32_get_bits(tlv->tl, HAL_TLV_HDR_TAG);2004 tlv_len = le32_get_bits(tlv->tl, HAL_TLV_HDR_LEN);2005 tlv_userid = le32_get_bits(tlv->tl, HAL_TLV_USR_ID);2006 2007 tlv_status = ath12k_dp_mon_tx_parse_status_tlv(ab, pmon,2008 tlv_tag, ptr,2009 tlv_userid);2010 ptr += tlv_len;2011 ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);2012 if ((ptr - skb->data) >= DP_TX_MONITOR_BUF_SIZE)2013 break;2014 } while (tlv_status != DP_MON_TX_FES_STATUS_END);2015 2016 ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_data_ppdu_info);2017 ath12k_dp_mon_tx_process_ppdu_info(ar, mac_id, napi, tx_prot_ppdu_info);2018 2019 return tlv_status;2020}2021 2022int ath12k_dp_mon_srng_process(struct ath12k *ar, int mac_id, int *budget,2023 enum dp_monitor_mode monitor_mode,2024 struct napi_struct *napi)2025{2026 struct hal_mon_dest_desc *mon_dst_desc;2027 struct ath12k_pdev_dp *pdev_dp = &ar->dp;2028 struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;2029 struct ath12k_base *ab = ar->ab;2030 struct ath12k_dp *dp = &ab->dp;2031 struct sk_buff *skb;2032 struct ath12k_skb_rxcb *rxcb;2033 struct dp_srng *mon_dst_ring;2034 struct hal_srng *srng;2035 struct dp_rxdma_mon_ring *buf_ring;2036 u64 cookie;2037 u32 ppdu_id;2038 int num_buffs_reaped = 0, srng_id, buf_id;2039 u8 dest_idx = 0, i;2040 bool end_of_ppdu;2041 struct hal_rx_mon_ppdu_info *ppdu_info;2042 struct ath12k_peer *peer = NULL;2043 2044 ppdu_info = &pmon->mon_ppdu_info;2045 memset(ppdu_info, 0, sizeof(*ppdu_info));2046 ppdu_info->peer_id = HAL_INVALID_PEERID;2047 2048 srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);2049 2050 if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE) {2051 mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];2052 buf_ring = &dp->rxdma_mon_buf_ring;2053 } else {2054 return 0;2055 }2056 2057 srng = &ab->hal.srng_list[mon_dst_ring->ring_id];2058 2059 spin_lock_bh(&srng->lock);2060 ath12k_hal_srng_access_begin(ab, srng);2061 2062 while (likely(*budget)) {2063 *budget -= 1;2064 mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);2065 if (unlikely(!mon_dst_desc))2066 break;2067 2068 cookie = le32_to_cpu(mon_dst_desc->cookie);2069 buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);2070 2071 spin_lock_bh(&buf_ring->idr_lock);2072 skb = idr_remove(&buf_ring->bufs_idr, buf_id);2073 spin_unlock_bh(&buf_ring->idr_lock);2074 2075 if (unlikely(!skb)) {2076 ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",2077 buf_id);2078 goto move_next;2079 }2080 2081 rxcb = ATH12K_SKB_RXCB(skb);2082 dma_unmap_single(ab->dev, rxcb->paddr,2083 skb->len + skb_tailroom(skb),2084 DMA_FROM_DEVICE);2085 2086 pmon->dest_skb_q[dest_idx] = skb;2087 dest_idx++;2088 ppdu_id = le32_to_cpu(mon_dst_desc->ppdu_id);2089 end_of_ppdu = le32_get_bits(mon_dst_desc->info0,2090 HAL_MON_DEST_INFO0_END_OF_PPDU);2091 if (!end_of_ppdu)2092 continue;2093 2094 for (i = 0; i < dest_idx; i++) {2095 skb = pmon->dest_skb_q[i];2096 2097 if (monitor_mode == ATH12K_DP_RX_MONITOR_MODE)2098 ath12k_dp_mon_rx_parse_mon_status(ar, pmon, mac_id,2099 skb, napi);2100 else2101 ath12k_dp_mon_tx_parse_mon_status(ar, pmon, mac_id,2102 skb, napi, ppdu_id);2103 2104 peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);2105 2106 if (!peer || !peer->sta) {2107 ath12k_dbg(ab, ATH12K_DBG_DATA,2108 "failed to find the peer with peer_id %d\n",2109 ppdu_info->peer_id);2110 dev_kfree_skb_any(skb);2111 continue;2112 }2113 2114 dev_kfree_skb_any(skb);2115 pmon->dest_skb_q[i] = NULL;2116 }2117 2118 dest_idx = 0;2119move_next:2120 ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);2121 ath12k_hal_srng_src_get_next_entry(ab, srng);2122 num_buffs_reaped++;2123 }2124 2125 ath12k_hal_srng_access_end(ab, srng);2126 spin_unlock_bh(&srng->lock);2127 2128 return num_buffs_reaped;2129}2130 2131static void2132ath12k_dp_mon_rx_update_peer_rate_table_stats(struct ath12k_rx_peer_stats *rx_stats,2133 struct hal_rx_mon_ppdu_info *ppdu_info,2134 struct hal_rx_user_status *user_stats,2135 u32 num_msdu)2136{2137 u32 rate_idx = 0;2138 u32 mcs_idx = (user_stats) ? user_stats->mcs : ppdu_info->mcs;2139 u32 nss_idx = (user_stats) ? user_stats->nss - 1 : ppdu_info->nss - 1;2140 u32 bw_idx = ppdu_info->bw;2141 u32 gi_idx = ppdu_info->gi;2142 2143 if ((mcs_idx > HAL_RX_MAX_MCS_HE) || (nss_idx >= HAL_RX_MAX_NSS) ||2144 (bw_idx >= HAL_RX_BW_MAX) || (gi_idx >= HAL_RX_GI_MAX)) {2145 return;2146 }2147 2148 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N ||2149 ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC) {2150 rate_idx = mcs_idx * 8 + 8 * 10 * nss_idx;2151 rate_idx += bw_idx * 2 + gi_idx;2152 } else if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX) {2153 gi_idx = ath12k_he_gi_to_nl80211_he_gi(ppdu_info->gi);2154 rate_idx = mcs_idx * 12 + 12 * 12 * nss_idx;2155 rate_idx += bw_idx * 3 + gi_idx;2156 } else {2157 return;2158 }2159 2160 rx_stats->pkt_stats.rx_rate[rate_idx] += num_msdu;2161 if (user_stats)2162 rx_stats->byte_stats.rx_rate[rate_idx] += user_stats->mpdu_ok_byte_count;2163 else2164 rx_stats->byte_stats.rx_rate[rate_idx] += ppdu_info->mpdu_len;2165}2166 2167static void ath12k_dp_mon_rx_update_peer_su_stats(struct ath12k *ar,2168 struct ath12k_sta *arsta,2169 struct hal_rx_mon_ppdu_info *ppdu_info)2170{2171 struct ath12k_rx_peer_stats *rx_stats = arsta->rx_stats;2172 u32 num_msdu;2173 2174 if (!rx_stats)2175 return;2176 2177 arsta->rssi_comb = ppdu_info->rssi_comb;2178 2179 num_msdu = ppdu_info->tcp_msdu_count + ppdu_info->tcp_ack_msdu_count +2180 ppdu_info->udp_msdu_count + ppdu_info->other_msdu_count;2181 2182 rx_stats->num_msdu += num_msdu;2183 rx_stats->tcp_msdu_count += ppdu_info->tcp_msdu_count +2184 ppdu_info->tcp_ack_msdu_count;2185 rx_stats->udp_msdu_count += ppdu_info->udp_msdu_count;2186 rx_stats->other_msdu_count += ppdu_info->other_msdu_count;2187 2188 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||2189 ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) {2190 ppdu_info->nss = 1;2191 ppdu_info->mcs = HAL_RX_MAX_MCS;2192 ppdu_info->tid = IEEE80211_NUM_TIDS;2193 }2194 2195 if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)2196 rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;2197 2198 if (ppdu_info->tid <= IEEE80211_NUM_TIDS)2199 rx_stats->tid_count[ppdu_info->tid] += num_msdu;2200 2201 if (ppdu_info->preamble_type < HAL_RX_PREAMBLE_MAX)2202 rx_stats->pream_cnt[ppdu_info->preamble_type] += num_msdu;2203 2204 if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)2205 rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;2206 2207 if (ppdu_info->is_stbc)2208 rx_stats->stbc_count += num_msdu;2209 2210 if (ppdu_info->beamformed)2211 rx_stats->beamformed_count += num_msdu;2212 2213 if (ppdu_info->num_mpdu_fcs_ok > 1)2214 rx_stats->ampdu_msdu_count += num_msdu;2215 else2216 rx_stats->non_ampdu_msdu_count += num_msdu;2217 2218 rx_stats->num_mpdu_fcs_ok += ppdu_info->num_mpdu_fcs_ok;2219 rx_stats->num_mpdu_fcs_err += ppdu_info->num_mpdu_fcs_err;2220 rx_stats->dcm_count += ppdu_info->dcm;2221 2222 rx_stats->rx_duration += ppdu_info->rx_duration;2223 arsta->rx_duration = rx_stats->rx_duration;2224 2225 if (ppdu_info->nss > 0 && ppdu_info->nss <= HAL_RX_MAX_NSS) {2226 rx_stats->pkt_stats.nss_count[ppdu_info->nss - 1] += num_msdu;2227 rx_stats->byte_stats.nss_count[ppdu_info->nss - 1] += ppdu_info->mpdu_len;2228 }2229 2230 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11N &&2231 ppdu_info->mcs <= HAL_RX_MAX_MCS_HT) {2232 rx_stats->pkt_stats.ht_mcs_count[ppdu_info->mcs] += num_msdu;2233 rx_stats->byte_stats.ht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2234 /* To fit into rate table for HT packets */2235 ppdu_info->mcs = ppdu_info->mcs % 8;2236 }2237 2238 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AC &&2239 ppdu_info->mcs <= HAL_RX_MAX_MCS_VHT) {2240 rx_stats->pkt_stats.vht_mcs_count[ppdu_info->mcs] += num_msdu;2241 rx_stats->byte_stats.vht_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2242 }2243 2244 if (ppdu_info->preamble_type == HAL_RX_PREAMBLE_11AX &&2245 ppdu_info->mcs <= HAL_RX_MAX_MCS_HE) {2246 rx_stats->pkt_stats.he_mcs_count[ppdu_info->mcs] += num_msdu;2247 rx_stats->byte_stats.he_mcs_count[ppdu_info->mcs] += ppdu_info->mpdu_len;2248 }2249 2250 if ((ppdu_info->preamble_type == HAL_RX_PREAMBLE_11A ||2251 ppdu_info->preamble_type == HAL_RX_PREAMBLE_11B) &&2252 ppdu_info->rate < HAL_RX_LEGACY_RATE_INVALID) {2253 rx_stats->pkt_stats.legacy_count[ppdu_info->rate] += num_msdu;2254 rx_stats->byte_stats.legacy_count[ppdu_info->rate] += ppdu_info->mpdu_len;2255 }2256 2257 if (ppdu_info->gi < HAL_RX_GI_MAX) {2258 rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;2259 rx_stats->byte_stats.gi_count[ppdu_info->gi] += ppdu_info->mpdu_len;2260 }2261 2262 if (ppdu_info->bw < HAL_RX_BW_MAX) {2263 rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;2264 rx_stats->byte_stats.bw_count[ppdu_info->bw] += ppdu_info->mpdu_len;2265 }2266 2267 ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,2268 NULL, num_msdu);2269}2270 2271void ath12k_dp_mon_rx_process_ulofdma(struct hal_rx_mon_ppdu_info *ppdu_info)2272{2273 struct hal_rx_user_status *rx_user_status;2274 u32 num_users, i, mu_ul_user_v0_word0, mu_ul_user_v0_word1, ru_size;2275 2276 if (!(ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_MIMO ||2277 ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||2278 ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO))2279 return;2280 2281 num_users = ppdu_info->num_users;2282 if (num_users > HAL_MAX_UL_MU_USERS)2283 num_users = HAL_MAX_UL_MU_USERS;2284 2285 for (i = 0; i < num_users; i++) {2286 rx_user_status = &ppdu_info->userstats[i];2287 mu_ul_user_v0_word0 =2288 rx_user_status->ul_ofdma_user_v0_word0;2289 mu_ul_user_v0_word1 =2290 rx_user_status->ul_ofdma_user_v0_word1;2291 2292 if (u32_get_bits(mu_ul_user_v0_word0,2293 HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VALID) &&2294 !u32_get_bits(mu_ul_user_v0_word0,2295 HAL_RX_UL_OFDMA_USER_INFO_V0_W0_VER)) {2296 rx_user_status->mcs =2297 u32_get_bits(mu_ul_user_v0_word1,2298 HAL_RX_UL_OFDMA_USER_INFO_V0_W1_MCS);2299 rx_user_status->nss =2300 u32_get_bits(mu_ul_user_v0_word1,2301 HAL_RX_UL_OFDMA_USER_INFO_V0_W1_NSS) + 1;2302 2303 rx_user_status->ofdma_info_valid = 1;2304 rx_user_status->ul_ofdma_ru_start_index =2305 u32_get_bits(mu_ul_user_v0_word1,2306 HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_START);2307 2308 ru_size = u32_get_bits(mu_ul_user_v0_word1,2309 HAL_RX_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE);2310 rx_user_status->ul_ofdma_ru_width = ru_size;2311 rx_user_status->ul_ofdma_ru_size = ru_size;2312 }2313 rx_user_status->ldpc = u32_get_bits(mu_ul_user_v0_word1,2314 HAL_RX_UL_OFDMA_USER_INFO_V0_W1_LDPC);2315 }2316 ppdu_info->ldpc = 1;2317}2318 2319static void2320ath12k_dp_mon_rx_update_user_stats(struct ath12k *ar,2321 struct hal_rx_mon_ppdu_info *ppdu_info,2322 u32 uid)2323{2324 struct ath12k_sta *arsta = NULL;2325 struct ath12k_rx_peer_stats *rx_stats = NULL;2326 struct hal_rx_user_status *user_stats = &ppdu_info->userstats[uid];2327 struct ath12k_peer *peer;2328 u32 num_msdu;2329 2330 if (user_stats->ast_index == 0 || user_stats->ast_index == 0xFFFF)2331 return;2332 2333 peer = ath12k_peer_find_by_ast(ar->ab, user_stats->ast_index);2334 2335 if (!peer) {2336 ath12k_warn(ar->ab, "peer ast idx %d can't be found\n",2337 user_stats->ast_index);2338 return;2339 }2340 2341 arsta = ath12k_sta_to_arsta(peer->sta);2342 rx_stats = arsta->rx_stats;2343 2344 if (!rx_stats)2345 return;2346 2347 arsta->rssi_comb = ppdu_info->rssi_comb;2348 2349 num_msdu = user_stats->tcp_msdu_count + user_stats->tcp_ack_msdu_count +2350 user_stats->udp_msdu_count + user_stats->other_msdu_count;2351 2352 rx_stats->num_msdu += num_msdu;2353 rx_stats->tcp_msdu_count += user_stats->tcp_msdu_count +2354 user_stats->tcp_ack_msdu_count;2355 rx_stats->udp_msdu_count += user_stats->udp_msdu_count;2356 rx_stats->other_msdu_count += user_stats->other_msdu_count;2357 2358 if (ppdu_info->ldpc < HAL_RX_SU_MU_CODING_MAX)2359 rx_stats->coding_count[ppdu_info->ldpc] += num_msdu;2360 2361 if (user_stats->tid <= IEEE80211_NUM_TIDS)2362 rx_stats->tid_count[user_stats->tid] += num_msdu;2363 2364 if (user_stats->preamble_type < HAL_RX_PREAMBLE_MAX)2365 rx_stats->pream_cnt[user_stats->preamble_type] += num_msdu;2366 2367 if (ppdu_info->reception_type < HAL_RX_RECEPTION_TYPE_MAX)2368 rx_stats->reception_type[ppdu_info->reception_type] += num_msdu;2369 2370 if (ppdu_info->is_stbc)2371 rx_stats->stbc_count += num_msdu;2372 2373 if (ppdu_info->beamformed)2374 rx_stats->beamformed_count += num_msdu;2375 2376 if (user_stats->mpdu_cnt_fcs_ok > 1)2377 rx_stats->ampdu_msdu_count += num_msdu;2378 else2379 rx_stats->non_ampdu_msdu_count += num_msdu;2380 2381 rx_stats->num_mpdu_fcs_ok += user_stats->mpdu_cnt_fcs_ok;2382 rx_stats->num_mpdu_fcs_err += user_stats->mpdu_cnt_fcs_err;2383 rx_stats->dcm_count += ppdu_info->dcm;2384 if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA ||2385 ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_MU_OFDMA_MIMO)2386 rx_stats->ru_alloc_cnt[user_stats->ul_ofdma_ru_size] += num_msdu;2387 2388 rx_stats->rx_duration += ppdu_info->rx_duration;2389 arsta->rx_duration = rx_stats->rx_duration;2390 2391 if (user_stats->nss > 0 && user_stats->nss <= HAL_RX_MAX_NSS) {2392 rx_stats->pkt_stats.nss_count[user_stats->nss - 1] += num_msdu;2393 rx_stats->byte_stats.nss_count[user_stats->nss - 1] +=2394 user_stats->mpdu_ok_byte_count;2395 }2396 2397 if (user_stats->preamble_type == HAL_RX_PREAMBLE_11AX &&2398 user_stats->mcs <= HAL_RX_MAX_MCS_HE) {2399 rx_stats->pkt_stats.he_mcs_count[user_stats->mcs] += num_msdu;2400 rx_stats->byte_stats.he_mcs_count[user_stats->mcs] +=2401 user_stats->mpdu_ok_byte_count;2402 }2403 2404 if (ppdu_info->gi < HAL_RX_GI_MAX) {2405 rx_stats->pkt_stats.gi_count[ppdu_info->gi] += num_msdu;2406 rx_stats->byte_stats.gi_count[ppdu_info->gi] +=2407 user_stats->mpdu_ok_byte_count;2408 }2409 2410 if (ppdu_info->bw < HAL_RX_BW_MAX) {2411 rx_stats->pkt_stats.bw_count[ppdu_info->bw] += num_msdu;2412 rx_stats->byte_stats.bw_count[ppdu_info->bw] +=2413 user_stats->mpdu_ok_byte_count;2414 }2415 2416 ath12k_dp_mon_rx_update_peer_rate_table_stats(rx_stats, ppdu_info,2417 user_stats, num_msdu);2418}2419 2420static void2421ath12k_dp_mon_rx_update_peer_mu_stats(struct ath12k *ar,2422 struct hal_rx_mon_ppdu_info *ppdu_info)2423{2424 u32 num_users, i;2425 2426 num_users = ppdu_info->num_users;2427 if (num_users > HAL_MAX_UL_MU_USERS)2428 num_users = HAL_MAX_UL_MU_USERS;2429 2430 for (i = 0; i < num_users; i++)2431 ath12k_dp_mon_rx_update_user_stats(ar, ppdu_info, i);2432}2433 2434int ath12k_dp_mon_rx_process_stats(struct ath12k *ar, int mac_id,2435 struct napi_struct *napi, int *budget)2436{2437 struct ath12k_base *ab = ar->ab;2438 struct ath12k_pdev_dp *pdev_dp = &ar->dp;2439 struct ath12k_mon_data *pmon = (struct ath12k_mon_data *)&pdev_dp->mon_data;2440 struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;2441 struct ath12k_dp *dp = &ab->dp;2442 struct hal_mon_dest_desc *mon_dst_desc;2443 struct sk_buff *skb;2444 struct ath12k_skb_rxcb *rxcb;2445 struct dp_srng *mon_dst_ring;2446 struct hal_srng *srng;2447 struct dp_rxdma_mon_ring *buf_ring;2448 struct ath12k_sta *arsta = NULL;2449 struct ath12k_peer *peer;2450 u64 cookie;2451 int num_buffs_reaped = 0, srng_id, buf_id;2452 u8 dest_idx = 0, i;2453 bool end_of_ppdu;2454 u32 hal_status;2455 2456 srng_id = ath12k_hw_mac_id_to_srng_id(ab->hw_params, mac_id);2457 mon_dst_ring = &pdev_dp->rxdma_mon_dst_ring[srng_id];2458 buf_ring = &dp->rxdma_mon_buf_ring;2459 2460 srng = &ab->hal.srng_list[mon_dst_ring->ring_id];2461 spin_lock_bh(&srng->lock);2462 ath12k_hal_srng_access_begin(ab, srng);2463 2464 while (likely(*budget)) {2465 *budget -= 1;2466 mon_dst_desc = ath12k_hal_srng_dst_peek(ab, srng);2467 if (unlikely(!mon_dst_desc))2468 break;2469 cookie = le32_to_cpu(mon_dst_desc->cookie);2470 buf_id = u32_get_bits(cookie, DP_RXDMA_BUF_COOKIE_BUF_ID);2471 2472 spin_lock_bh(&buf_ring->idr_lock);2473 skb = idr_remove(&buf_ring->bufs_idr, buf_id);2474 spin_unlock_bh(&buf_ring->idr_lock);2475 2476 if (unlikely(!skb)) {2477 ath12k_warn(ab, "monitor destination with invalid buf_id %d\n",2478 buf_id);2479 goto move_next;2480 }2481 2482 rxcb = ATH12K_SKB_RXCB(skb);2483 dma_unmap_single(ab->dev, rxcb->paddr,2484 skb->len + skb_tailroom(skb),2485 DMA_FROM_DEVICE);2486 pmon->dest_skb_q[dest_idx] = skb;2487 dest_idx++;2488 end_of_ppdu = le32_get_bits(mon_dst_desc->info0,2489 HAL_MON_DEST_INFO0_END_OF_PPDU);2490 if (!end_of_ppdu)2491 continue;2492 2493 for (i = 0; i < dest_idx; i++) {2494 skb = pmon->dest_skb_q[i];2495 hal_status = ath12k_dp_mon_parse_rx_dest(ab, pmon, skb);2496 2497 if (ppdu_info->peer_id == HAL_INVALID_PEERID ||2498 hal_status != HAL_RX_MON_STATUS_PPDU_DONE) {2499 dev_kfree_skb_any(skb);2500 continue;2501 }2502 2503 rcu_read_lock();2504 spin_lock_bh(&ab->base_lock);2505 peer = ath12k_peer_find_by_id(ab, ppdu_info->peer_id);2506 if (!peer || !peer->sta) {2507 ath12k_dbg(ab, ATH12K_DBG_DATA,2508 "failed to find the peer with peer_id %d\n",2509 ppdu_info->peer_id);2510 spin_unlock_bh(&ab->base_lock);2511 rcu_read_unlock();2512 dev_kfree_skb_any(skb);2513 continue;2514 }2515 2516 if (ppdu_info->reception_type == HAL_RX_RECEPTION_TYPE_SU) {2517 arsta = ath12k_sta_to_arsta(peer->sta);2518 ath12k_dp_mon_rx_update_peer_su_stats(ar, arsta,2519 ppdu_info);2520 } else if ((ppdu_info->fc_valid) &&2521 (ppdu_info->ast_index != HAL_AST_IDX_INVALID)) {2522 ath12k_dp_mon_rx_process_ulofdma(ppdu_info);2523 ath12k_dp_mon_rx_update_peer_mu_stats(ar, ppdu_info);2524 }2525 2526 spin_unlock_bh(&ab->base_lock);2527 rcu_read_unlock();2528 dev_kfree_skb_any(skb);2529 memset(ppdu_info, 0, sizeof(*ppdu_info));2530 ppdu_info->peer_id = HAL_INVALID_PEERID;2531 }2532 2533 dest_idx = 0;2534move_next:2535 ath12k_dp_mon_buf_replenish(ab, buf_ring, 1);2536 ath12k_hal_srng_src_get_next_entry(ab, srng);2537 num_buffs_reaped++;2538 }2539 2540 ath12k_hal_srng_access_end(ab, srng);2541 spin_unlock_bh(&srng->lock);2542 return num_buffs_reaped;2543}2544 2545int ath12k_dp_mon_process_ring(struct ath12k_base *ab, int mac_id,2546 struct napi_struct *napi, int budget,2547 enum dp_monitor_mode monitor_mode)2548{2549 struct ath12k *ar = ath12k_ab_to_ar(ab, mac_id);2550 int num_buffs_reaped = 0;2551 2552 if (!ar->monitor_started)2553 ath12k_dp_mon_rx_process_stats(ar, mac_id, napi, &budget);2554 else2555 num_buffs_reaped = ath12k_dp_mon_srng_process(ar, mac_id, &budget,2556 monitor_mode, napi);2557 2558 return num_buffs_reaped;2559}2560