1 /* 2 * Copyright (c) 2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include "hal_hw_headers.h" 21 #include "dp_types.h" 22 #include "dp_rx.h" 23 #include "dp_peer.h" 24 #include "hal_rx.h" 25 #include "hal_api.h" 26 #include "qdf_trace.h" 27 #include "qdf_nbuf.h" 28 #include "hal_api_mon.h" 29 #include "dp_internal.h" 30 #include "qdf_mem.h" /* qdf_mem_malloc,free */ 31 #include "dp_htt.h" 32 #include "dp_mon.h" 33 #include "dp_rx_mon.h" 34 35 #include "htt.h" 36 #ifdef FEATURE_PERPKT_INFO 37 #include "dp_ratetable.h" 38 #endif 39 40 #ifndef IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK 41 #define IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK 0xe0 42 #endif 43 44 #if defined(WLAN_CFR_ENABLE) && defined(WLAN_ENH_CFR_ENABLE) 45 void 46 dp_rx_mon_handle_cfr_mu_info(struct dp_pdev *pdev, 47 struct hal_rx_ppdu_info *ppdu_info, 48 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 49 { 50 struct dp_peer *peer; 51 struct dp_soc *soc = pdev->soc; 52 struct mon_rx_user_status *rx_user_status; 53 struct cdp_rx_stats_ppdu_user *rx_stats_peruser; 54 uint32_t num_users; 55 int user_id; 56 uint16_t sw_peer_id; 57 58 num_users = ppdu_info->com_info.num_users; 59 for (user_id = 0; user_id < num_users; user_id++) { 60 if (user_id > OFDMA_NUM_USERS) { 61 return; 62 } 63 64 rx_user_status = &ppdu_info->rx_user_status[user_id]; 65 rx_stats_peruser = &cdp_rx_ppdu->user[user_id]; 66 sw_peer_id = rx_user_status->sw_peer_id; 67 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 68 DP_MOD_ID_RX_PPDU_STATS); 69 if (!peer) { 70 rx_stats_peruser->peer_id = HTT_INVALID_PEER; 71 continue; 72 } 73 74 qdf_mem_copy(rx_stats_peruser->mac_addr, 75 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 76 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 77 } 78 } 79 80 void 81 dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, 82 struct hal_rx_ppdu_info *ppdu_info, 83 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 84 { 85 struct dp_peer *peer; 86 struct dp_soc *soc = pdev->soc; 87 int chain; 88 uint16_t sw_peer_id; 89 struct mon_rx_user_status *rx_user_status; 90 uint32_t num_users = ppdu_info->com_info.num_users; 91 92 cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; 93 cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; 94 cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; 95 96 for (chain = 0; chain < MAX_CHAIN; chain++) 97 cdp_rx_ppdu->per_chain_rssi[chain] = 98 ppdu_info->rx_status.rssi[chain]; 99 100 cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; 101 cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; 102 cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; 103 104 if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && 105 (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) 106 cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; 107 else 108 cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; 109 110 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { 111 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; 112 } else if (ppdu_info->rx_status.preamble_type == 113 HAL_RX_PKT_TYPE_11AX) { 114 cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> 115 QDF_MON_STATUS_STBC_SHIFT) & 0x1; 116 cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> 117 QDF_MON_STATUS_DCM_SHIFT) & 0x1; 118 } 119 120 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 121 dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu); 122 rx_user_status = &ppdu_info->rx_user_status[num_users - 1]; 123 sw_peer_id = rx_user_status->sw_peer_id; 124 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, DP_MOD_ID_RX_PPDU_STATS); 125 if (!peer) { 126 cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; 127 cdp_rx_ppdu->num_users = 0; 128 return; 129 } 130 131 cdp_rx_ppdu->peer_id = peer->peer_id; 132 cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; 133 cdp_rx_ppdu->num_users = num_users; 134 } 135 136 bool 137 dp_cfr_rcc_mode_status(struct dp_pdev *pdev) 138 { 139 return pdev->cfr_rcc_mode; 140 } 141 142 void 143 dp_rx_mon_populate_cfr_info(struct dp_pdev *pdev, 144 struct hal_rx_ppdu_info *ppdu_info, 145 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 146 { 147 struct cdp_rx_ppdu_cfr_info *cfr_info; 148 149 if (!qdf_unlikely(dp_cfr_rcc_mode_status(pdev))) 150 return; 151 152 cfr_info = &cdp_rx_ppdu->cfr_info; 153 154 cfr_info->bb_captured_channel 155 = ppdu_info->cfr_info.bb_captured_channel; 156 cfr_info->bb_captured_timeout 157 = ppdu_info->cfr_info.bb_captured_timeout; 158 cfr_info->bb_captured_reason 159 = ppdu_info->cfr_info.bb_captured_reason; 160 cfr_info->rx_location_info_valid 161 = ppdu_info->cfr_info.rx_location_info_valid; 162 cfr_info->chan_capture_status 163 = ppdu_info->cfr_info.chan_capture_status; 164 cfr_info->rtt_che_buffer_pointer_high8 165 = ppdu_info->cfr_info.rtt_che_buffer_pointer_high8; 166 cfr_info->rtt_che_buffer_pointer_low32 167 = ppdu_info->cfr_info.rtt_che_buffer_pointer_low32; 168 cfr_info->rtt_cfo_measurement 169 = (int16_t)ppdu_info->cfr_info.rtt_cfo_measurement; 170 cfr_info->agc_gain_info0 171 = ppdu_info->cfr_info.agc_gain_info0; 172 cfr_info->agc_gain_info1 173 = ppdu_info->cfr_info.agc_gain_info1; 174 cfr_info->agc_gain_info2 175 = ppdu_info->cfr_info.agc_gain_info2; 176 cfr_info->agc_gain_info3 177 = ppdu_info->cfr_info.agc_gain_info3; 178 cfr_info->rx_start_ts 179 = ppdu_info->cfr_info.rx_start_ts; 180 cfr_info->mcs_rate 181 = ppdu_info->cfr_info.mcs_rate; 182 cfr_info->gi_type 183 = ppdu_info->cfr_info.gi_type; 184 } 185 186 void 187 dp_update_cfr_dbg_stats(struct dp_pdev *pdev, 188 struct hal_rx_ppdu_info *ppdu_info) 189 { 190 struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info; 191 192 DP_STATS_INC(pdev, 193 rcc.chan_capture_status[cfr->chan_capture_status], 1); 194 if (cfr->rx_location_info_valid) { 195 DP_STATS_INC(pdev, rcc.rx_loc_info_valid_cnt, 1); 196 if (cfr->bb_captured_channel) { 197 DP_STATS_INC(pdev, rcc.bb_captured_channel_cnt, 1); 198 DP_STATS_INC(pdev, 199 rcc.reason_cnt[cfr->bb_captured_reason], 200 1); 201 } else if (cfr->bb_captured_timeout) { 202 DP_STATS_INC(pdev, rcc.bb_captured_timeout_cnt, 1); 203 DP_STATS_INC(pdev, 204 rcc.reason_cnt[cfr->bb_captured_reason], 205 1); 206 } 207 } 208 } 209 210 void 211 dp_rx_handle_cfr(struct dp_soc *soc, struct dp_pdev *pdev, 212 struct hal_rx_ppdu_info *ppdu_info) 213 { 214 qdf_nbuf_t ppdu_nbuf; 215 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 216 217 dp_update_cfr_dbg_stats(pdev, ppdu_info); 218 if (!ppdu_info->cfr_info.bb_captured_channel) 219 return; 220 221 ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, 222 sizeof(struct cdp_rx_indication_ppdu), 223 0, 224 0, 225 FALSE); 226 if (ppdu_nbuf) { 227 cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data; 228 229 dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu); 230 dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu); 231 qdf_nbuf_put_tail(ppdu_nbuf, 232 sizeof(struct cdp_rx_indication_ppdu)); 233 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, 234 ppdu_nbuf, HTT_INVALID_PEER, 235 WDI_NO_VAL, pdev->pdev_id); 236 } 237 } 238 239 void 240 dp_rx_populate_cfr_non_assoc_sta(struct dp_pdev *pdev, 241 struct hal_rx_ppdu_info *ppdu_info, 242 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 243 { 244 if (!dp_cfr_rcc_mode_status(pdev)) 245 return; 246 247 if (ppdu_info->cfr_info.bb_captured_channel) 248 dp_rx_mon_populate_cfr_ppdu_info(pdev, ppdu_info, cdp_rx_ppdu); 249 } 250 251 /** 252 * dp_bb_captured_chan_status() - Get the bb_captured_channel status 253 * @ppdu_info: structure for rx ppdu ring 254 * 255 * Return: Success/ Failure 256 */ 257 static inline QDF_STATUS 258 dp_bb_captured_chan_status(struct dp_pdev *pdev, 259 struct hal_rx_ppdu_info *ppdu_info) 260 { 261 QDF_STATUS status = QDF_STATUS_E_FAILURE; 262 struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info; 263 264 if (dp_cfr_rcc_mode_status(pdev)) { 265 if (cfr->bb_captured_channel) 266 status = QDF_STATUS_SUCCESS; 267 } 268 269 return status; 270 } 271 #else 272 static inline QDF_STATUS 273 dp_bb_captured_chan_status(struct dp_pdev *pdev, 274 struct hal_rx_ppdu_info *ppdu_info) 275 { 276 return QDF_STATUS_E_NOSUPPORT; 277 } 278 #endif /* WLAN_CFR_ENABLE */ 279 280 #ifdef QCA_ENHANCED_STATS_SUPPORT 281 #ifdef QCA_RSSI_DB2DBM 282 /** 283 * dp_rx_mon_rf_index_conv() - this function will convert BB index to RF 284 * index in the rssi_chain[chain][bw] array 285 * 286 * @chain: BB chain index 287 * @pdev: pdev structure 288 * 289 * Return: return RF chain index 290 * 291 * Computation: 292 * 3 Bytes of xbar_config are used for RF to BB mapping 293 * Samples of xbar_config, 294 * 295 * If xbar_config is 0x688FAC(hex): 296 * RF chains 0-3 are connected to BB chains 4-7 297 * RF chains 4-7 are connected to BB chains 0-3 298 * here, 299 * bits 0 to 2 = 4, maps BB chain 4 for RF chain 0 300 * bits 3 to 5 = 5, maps BB chain 5 for RF chain 1 301 * bits 6 to 8 = 6, maps BB chain 6 for RF chain 2 302 * bits 9 to 11 = 7, maps BB chain 7 for RF chain 3 303 * bits 12 to 14 = 0, maps BB chain 0 for RF chain 4 304 * bits 15 to 17 = 1, maps BB chain 1 for RF chain 5 305 * bits 18 to 20 = 2, maps BB chain 2 for RF chain 6 306 * bits 21 to 23 = 3, maps BB chain 3 for RF chain 7 307 */ 308 static uint8_t dp_rx_mon_rf_index_conv(uint8_t chain, 309 struct hal_rx_ppdu_info *ppdu_info, 310 struct dp_pdev *pdev) 311 { 312 uint32_t xbar_config = ppdu_info->rx_status.xbar_config; 313 314 if (pdev->soc->features.rssi_dbm_conv_support && xbar_config) 315 return ((xbar_config >> (3 * chain)) & 0x07); 316 return chain; 317 } 318 #else 319 static uint8_t dp_rx_mon_rf_index_conv(uint8_t chain, 320 struct hal_rx_ppdu_info *ppdu_info, 321 struct dp_pdev *pdev) 322 { 323 return chain; 324 } 325 #endif 326 void 327 dp_rx_populate_rx_rssi_chain(struct hal_rx_ppdu_info *ppdu_info, 328 struct cdp_rx_indication_ppdu *cdp_rx_ppdu, 329 struct dp_pdev *pdev) 330 { 331 uint8_t chain, bw; 332 uint8_t rssi; 333 uint8_t chain_rf; 334 335 for (chain = 0; chain < SS_COUNT; chain++) { 336 for (bw = 0; bw < MAX_BW; bw++) { 337 chain_rf = dp_rx_mon_rf_index_conv(chain, 338 ppdu_info, pdev); 339 rssi = ppdu_info->rx_status.rssi_chain[chain_rf][bw]; 340 if (rssi != DP_RSSI_INVAL) 341 cdp_rx_ppdu->rssi_chain[chain_rf][bw] = rssi; 342 else 343 cdp_rx_ppdu->rssi_chain[chain_rf][bw] = 0; 344 } 345 } 346 } 347 348 void 349 dp_rx_populate_su_evm_details(struct hal_rx_ppdu_info *ppdu_info, 350 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 351 { 352 uint8_t pilot_evm; 353 uint8_t nss_count; 354 uint8_t pilot_count; 355 356 nss_count = ppdu_info->evm_info.nss_count; 357 pilot_count = ppdu_info->evm_info.pilot_count; 358 359 if ((nss_count * pilot_count) > DP_RX_MAX_SU_EVM_COUNT) { 360 qdf_err("pilot evm count is more than expected"); 361 return; 362 } 363 cdp_rx_ppdu->evm_info.pilot_count = pilot_count; 364 cdp_rx_ppdu->evm_info.nss_count = nss_count; 365 366 /* Populate evm for pilot_evm = nss_count*pilot_count */ 367 for (pilot_evm = 0; pilot_evm < nss_count * pilot_count; pilot_evm++) { 368 cdp_rx_ppdu->evm_info.pilot_evm[pilot_evm] = 369 ppdu_info->evm_info.pilot_evm[pilot_evm]; 370 } 371 } 372 373 /** 374 * dp_rx_inc_rusize_cnt() - increment pdev stats based on RU size 375 * @pdev: pdev ctx 376 * @rx_user_status: mon rx user status 377 * 378 * Return: bool 379 */ 380 static inline bool 381 dp_rx_inc_rusize_cnt(struct dp_pdev *pdev, 382 struct mon_rx_user_status *rx_user_status) 383 { 384 uint32_t ru_size; 385 bool is_data; 386 387 ru_size = rx_user_status->ofdma_ru_size; 388 389 if (dp_is_subtype_data(rx_user_status->frame_control)) { 390 DP_STATS_INC(pdev, 391 ul_ofdma.data_rx_ru_size[ru_size], 1); 392 is_data = true; 393 } else { 394 DP_STATS_INC(pdev, 395 ul_ofdma.nondata_rx_ru_size[ru_size], 1); 396 is_data = false; 397 } 398 399 return is_data; 400 } 401 402 /** 403 * dp_rx_populate_cdp_indication_ppdu_user() - Populate per user cdp indication 404 * @pdev: pdev ctx 405 * @ppdu_info: ppdu info structure from ppdu ring 406 * @cdp_rx_ppdu: Rx PPDU indication structure 407 * 408 * Return: none 409 */ 410 static void 411 dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, 412 struct hal_rx_ppdu_info *ppdu_info, 413 struct cdp_rx_indication_ppdu 414 *cdp_rx_ppdu) 415 { 416 struct dp_peer *peer; 417 struct dp_soc *soc = pdev->soc; 418 int i; 419 struct mon_rx_user_status *rx_user_status; 420 struct mon_rx_user_info *rx_user_info; 421 struct cdp_rx_stats_ppdu_user *rx_stats_peruser; 422 int ru_size; 423 bool is_data = false; 424 uint32_t num_users; 425 struct dp_mon_ops *mon_ops; 426 uint16_t sw_peer_id; 427 428 num_users = ppdu_info->com_info.num_users; 429 for (i = 0; i < num_users; i++) { 430 if (i > OFDMA_NUM_USERS) 431 return; 432 433 rx_user_status = &ppdu_info->rx_user_status[i]; 434 rx_user_info = &ppdu_info->rx_user_info[i]; 435 rx_stats_peruser = &cdp_rx_ppdu->user[i]; 436 437 sw_peer_id = rx_user_status->sw_peer_id; 438 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 439 DP_MOD_ID_RX_PPDU_STATS); 440 if (qdf_unlikely(!peer)) { 441 rx_stats_peruser->peer_id = HTT_INVALID_PEER; 442 continue; 443 } 444 rx_stats_peruser->is_bss_peer = peer->bss_peer; 445 446 rx_stats_peruser->first_data_seq_ctrl = 447 rx_user_status->first_data_seq_ctrl; 448 449 rx_stats_peruser->frame_control_info_valid = 450 rx_user_status->frame_control_info_valid; 451 rx_stats_peruser->frame_control = 452 rx_user_status->frame_control; 453 454 rx_stats_peruser->qos_control_info_valid = 455 rx_user_info->qos_control_info_valid; 456 rx_stats_peruser->qos_control = 457 rx_user_info->qos_control; 458 rx_stats_peruser->tcp_msdu_count = 459 rx_user_status->tcp_msdu_count; 460 rx_stats_peruser->udp_msdu_count = 461 rx_user_status->udp_msdu_count; 462 rx_stats_peruser->other_msdu_count = 463 rx_user_status->other_msdu_count; 464 465 rx_stats_peruser->num_msdu = 466 rx_stats_peruser->tcp_msdu_count + 467 rx_stats_peruser->udp_msdu_count + 468 rx_stats_peruser->other_msdu_count; 469 470 rx_stats_peruser->preamble_type = 471 cdp_rx_ppdu->u.preamble; 472 rx_stats_peruser->mpdu_cnt_fcs_ok = 473 rx_user_status->mpdu_cnt_fcs_ok; 474 rx_stats_peruser->mpdu_cnt_fcs_err = 475 rx_user_status->mpdu_cnt_fcs_err; 476 qdf_mem_copy(&rx_stats_peruser->mpdu_fcs_ok_bitmap, 477 &rx_user_status->mpdu_fcs_ok_bitmap, 478 HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * 479 sizeof(rx_user_status->mpdu_fcs_ok_bitmap[0])); 480 rx_stats_peruser->mpdu_ok_byte_count = 481 rx_user_status->mpdu_ok_byte_count; 482 rx_stats_peruser->mpdu_err_byte_count = 483 rx_user_status->mpdu_err_byte_count; 484 485 cdp_rx_ppdu->num_mpdu += rx_user_status->mpdu_cnt_fcs_ok; 486 cdp_rx_ppdu->num_msdu += rx_stats_peruser->num_msdu; 487 rx_stats_peruser->retries = 488 CDP_FC_IS_RETRY_SET(rx_stats_peruser->frame_control) ? 489 rx_stats_peruser->mpdu_cnt_fcs_ok : 0; 490 cdp_rx_ppdu->retries += rx_stats_peruser->retries; 491 492 if (rx_stats_peruser->mpdu_cnt_fcs_ok > 1) 493 rx_stats_peruser->is_ampdu = 1; 494 else 495 rx_stats_peruser->is_ampdu = 0; 496 497 rx_stats_peruser->tid = ppdu_info->rx_status.tid; 498 499 qdf_mem_copy(rx_stats_peruser->mac_addr, 500 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 501 rx_stats_peruser->peer_id = peer->peer_id; 502 cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; 503 rx_stats_peruser->vdev_id = peer->vdev->vdev_id; 504 rx_stats_peruser->mu_ul_info_valid = 0; 505 506 mon_ops = dp_mon_ops_get(soc); 507 if (mon_ops && mon_ops->mon_rx_populate_ppdu_usr_info) 508 mon_ops->mon_rx_populate_ppdu_usr_info(rx_user_status, 509 rx_stats_peruser); 510 511 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 512 if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || 513 cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { 514 if (rx_user_status->mu_ul_info_valid) { 515 rx_stats_peruser->nss = rx_user_status->nss; 516 cdp_rx_ppdu->usr_nss_sum += rx_stats_peruser->nss; 517 rx_stats_peruser->mcs = rx_user_status->mcs; 518 rx_stats_peruser->mu_ul_info_valid = 519 rx_user_status->mu_ul_info_valid; 520 rx_stats_peruser->ofdma_ru_start_index = 521 rx_user_status->ofdma_ru_start_index; 522 rx_stats_peruser->ofdma_ru_width = 523 rx_user_status->ofdma_ru_width; 524 cdp_rx_ppdu->usr_ru_tones_sum += 525 rx_stats_peruser->ofdma_ru_width; 526 rx_stats_peruser->user_index = i; 527 ru_size = rx_user_status->ofdma_ru_size; 528 /* 529 * max RU size will be equal to 530 * HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2 531 */ 532 if (qdf_unlikely(ru_size >= OFDMA_NUM_RU_SIZE)) { 533 dp_err("invalid ru_size %d\n", 534 ru_size); 535 return; 536 } 537 is_data = dp_rx_inc_rusize_cnt(pdev, 538 rx_user_status); 539 } 540 if (is_data) { 541 /* counter to get number of MU OFDMA */ 542 pdev->stats.ul_ofdma.data_rx_ppdu++; 543 pdev->stats.ul_ofdma.data_users[num_users]++; 544 } 545 } 546 } 547 } 548 549 /** 550 * dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure 551 * @pdev: pdev ctx 552 * @ppdu_info: ppdu info structure from ppdu ring 553 * @cdp_rx_ppdu: Rx PPDU indication structure 554 * 555 * Return: none 556 */ 557 static void 558 dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, 559 struct hal_rx_ppdu_info *ppdu_info, 560 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 561 { 562 struct dp_peer *peer; 563 struct dp_soc *soc = pdev->soc; 564 uint32_t i; 565 struct dp_mon_ops *mon_ops; 566 uint16_t sw_peer_id; 567 struct mon_rx_user_status *rx_user_status; 568 uint32_t num_users = ppdu_info->com_info.num_users; 569 570 cdp_rx_ppdu->first_data_seq_ctrl = 571 ppdu_info->rx_status.first_data_seq_ctrl; 572 cdp_rx_ppdu->frame_ctrl = 573 ppdu_info->rx_status.frame_control; 574 cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count; 575 cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count; 576 cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count; 577 /* num mpdu is consolidated and added together in num user loop */ 578 cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok; 579 /* num msdu is consolidated and added together in num user loop */ 580 cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count + 581 cdp_rx_ppdu->udp_msdu_count + 582 cdp_rx_ppdu->other_msdu_count); 583 584 cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ? 585 ppdu_info->com_info.mpdu_cnt_fcs_ok : 0; 586 587 if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1) 588 cdp_rx_ppdu->is_ampdu = 1; 589 else 590 cdp_rx_ppdu->is_ampdu = 0; 591 cdp_rx_ppdu->tid = ppdu_info->rx_status.tid; 592 593 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 594 rx_user_status = &ppdu_info->rx_user_status[num_users - 1]; 595 sw_peer_id = rx_user_status->sw_peer_id; 596 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 597 DP_MOD_ID_RX_PPDU_STATS); 598 if (qdf_unlikely(!peer)) { 599 cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; 600 cdp_rx_ppdu->num_users = 0; 601 goto end; 602 } 603 604 qdf_mem_copy(cdp_rx_ppdu->mac_addr, 605 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 606 cdp_rx_ppdu->peer_id = peer->peer_id; 607 cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; 608 609 cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; 610 cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len; 611 cdp_rx_ppdu->duration = ppdu_info->rx_status.duration; 612 cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss; 613 cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs; 614 if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && 615 (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) 616 cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; 617 else 618 cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; 619 cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; 620 cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; 621 cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >> 622 QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3; 623 cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb; 624 cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; 625 cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num; 626 cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; 627 cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; 628 cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; 629 cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; 630 631 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { 632 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; 633 } else if (ppdu_info->rx_status.preamble_type == 634 HAL_RX_PKT_TYPE_11AX) { 635 cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> 636 QDF_MON_STATUS_STBC_SHIFT) & 0x1; 637 cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> 638 QDF_MON_STATUS_DCM_SHIFT) & 0x1; 639 } 640 dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu, pdev); 641 dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); 642 cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; 643 644 mon_ops = dp_mon_ops_get(pdev->soc); 645 if (mon_ops && mon_ops->mon_rx_populate_ppdu_info) 646 mon_ops->mon_rx_populate_ppdu_info(ppdu_info, 647 cdp_rx_ppdu); 648 649 cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor; 650 for (i = 0; i < MAX_CHAIN; i++) 651 cdp_rx_ppdu->per_chain_rssi[i] = ppdu_info->rx_status.rssi[i]; 652 653 cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast; 654 655 cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; 656 657 dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu); 658 659 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 660 661 return; 662 end: 663 dp_rx_populate_cfr_non_assoc_sta(pdev, ppdu_info, cdp_rx_ppdu); 664 } 665 666 /** 667 * dp_rx_stats_update() - Update per-peer statistics 668 * @soc: Datapath SOC handle 669 * @peer: Datapath peer handle 670 * @ppdu: PPDU Descriptor 671 * 672 * Return: None 673 */ 674 static inline void dp_rx_rate_stats_update(struct dp_peer *peer, 675 struct cdp_rx_indication_ppdu *ppdu, 676 uint32_t user) 677 { 678 uint32_t ratekbps = 0; 679 uint32_t ppdu_rx_rate = 0; 680 uint32_t nss = 0; 681 uint8_t mcs = 0; 682 uint32_t rix; 683 uint16_t ratecode = 0; 684 struct cdp_rx_stats_ppdu_user *ppdu_user = NULL; 685 struct dp_mon_peer *mon_peer = NULL; 686 687 if (!peer || !ppdu) 688 return; 689 690 mon_peer = peer->monitor_peer; 691 ppdu_user = &ppdu->user[user]; 692 693 if (!mon_peer) 694 return; 695 696 if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU) { 697 if (ppdu_user->nss == 0) 698 nss = 0; 699 else 700 nss = ppdu_user->nss - 1; 701 mcs = ppdu_user->mcs; 702 703 mon_peer->stats.rx.nss_info = ppdu_user->nss; 704 mon_peer->stats.rx.mcs_info = ppdu_user->mcs; 705 } else { 706 if (ppdu->u.nss == 0) 707 nss = 0; 708 else 709 nss = ppdu->u.nss - 1; 710 mcs = ppdu->u.mcs; 711 712 mon_peer->stats.rx.nss_info = ppdu->u.nss; 713 mon_peer->stats.rx.mcs_info = ppdu->u.mcs; 714 } 715 716 ratekbps = dp_getrateindex(ppdu->u.gi, 717 mcs, 718 nss, 719 ppdu->u.preamble, 720 ppdu->u.bw, 721 ppdu->punc_bw, 722 &rix, 723 &ratecode); 724 725 if (!ratekbps) { 726 ppdu->rix = 0; 727 ppdu_user->rix = 0; 728 ppdu->rx_ratekbps = 0; 729 ppdu->rx_ratecode = 0; 730 ppdu_user->rx_ratekbps = 0; 731 return; 732 } 733 734 mon_peer->stats.rx.bw_info = ppdu->u.bw; 735 mon_peer->stats.rx.gi_info = ppdu->u.gi; 736 mon_peer->stats.rx.preamble_info = ppdu->u.preamble; 737 738 ppdu->rix = rix; 739 ppdu_user->rix = rix; 740 DP_STATS_UPD(mon_peer, rx.last_rx_rate, ratekbps); 741 mon_peer->stats.rx.avg_rx_rate = 742 dp_ath_rate_lpf(mon_peer->stats.rx.avg_rx_rate, ratekbps); 743 ppdu_rx_rate = dp_ath_rate_out(mon_peer->stats.rx.avg_rx_rate); 744 DP_STATS_UPD(mon_peer, rx.rnd_avg_rx_rate, ppdu_rx_rate); 745 ppdu->rx_ratekbps = ratekbps; 746 ppdu->rx_ratecode = ratecode; 747 ppdu_user->rx_ratekbps = ratekbps; 748 749 if (peer->vdev) 750 peer->vdev->stats.rx.last_rx_rate = ratekbps; 751 } 752 753 #ifdef WLAN_FEATURE_11BE 754 static inline uint8_t dp_get_bw_offset_frm_bw(struct dp_soc *soc, 755 enum CMN_BW_TYPES bw) 756 { 757 uint8_t pkt_bw_offset; 758 759 switch (bw) { 760 case CMN_BW_20MHZ: 761 pkt_bw_offset = PKT_BW_GAIN_20MHZ; 762 break; 763 case CMN_BW_40MHZ: 764 pkt_bw_offset = PKT_BW_GAIN_40MHZ; 765 break; 766 case CMN_BW_80MHZ: 767 pkt_bw_offset = PKT_BW_GAIN_80MHZ; 768 break; 769 case CMN_BW_160MHZ: 770 pkt_bw_offset = PKT_BW_GAIN_160MHZ; 771 break; 772 case CMN_BW_320MHZ: 773 pkt_bw_offset = PKT_BW_GAIN_320MHZ; 774 break; 775 default: 776 pkt_bw_offset = 0; 777 dp_rx_mon_status_debug("%pK: Invalid BW index = %d", 778 soc, bw); 779 } 780 781 return pkt_bw_offset; 782 } 783 #else 784 static inline uint8_t dp_get_bw_offset_frm_bw(struct dp_soc *soc, 785 enum CMN_BW_TYPES bw) 786 { 787 uint8_t pkt_bw_offset; 788 789 switch (bw) { 790 case CMN_BW_20MHZ: 791 pkt_bw_offset = PKT_BW_GAIN_20MHZ; 792 break; 793 case CMN_BW_40MHZ: 794 pkt_bw_offset = PKT_BW_GAIN_40MHZ; 795 break; 796 case CMN_BW_80MHZ: 797 pkt_bw_offset = PKT_BW_GAIN_80MHZ; 798 break; 799 case CMN_BW_160MHZ: 800 pkt_bw_offset = PKT_BW_GAIN_160MHZ; 801 break; 802 default: 803 pkt_bw_offset = 0; 804 dp_rx_mon_status_debug("%pK: Invalid BW index = %d", 805 soc, bw); 806 } 807 808 return pkt_bw_offset; 809 } 810 #endif 811 812 #ifdef WLAN_TELEMETRY_STATS_SUPPORT 813 static void 814 dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev, 815 struct dp_peer *peer, 816 struct cdp_rx_indication_ppdu *ppdu_desc, 817 struct cdp_rx_stats_ppdu_user *user) 818 { 819 uint32_t nss_ru_width_sum = 0; 820 struct dp_mon_peer *mon_peer = NULL; 821 uint8_t ac = 0; 822 823 if (!pdev || !ppdu_desc || !user || !peer) 824 return; 825 826 nss_ru_width_sum = ppdu_desc->usr_nss_sum * ppdu_desc->usr_ru_tones_sum; 827 if (!nss_ru_width_sum) 828 nss_ru_width_sum = 1; 829 830 if (ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || 831 ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { 832 user->rx_time_us = (ppdu_desc->duration * 833 user->nss * user->ofdma_ru_width) / 834 nss_ru_width_sum; 835 } else { 836 user->rx_time_us = ppdu_desc->duration; 837 } 838 839 mon_peer = peer->monitor_peer; 840 if (qdf_unlikely(!mon_peer)) 841 return; 842 843 ac = TID_TO_WME_AC(user->tid); 844 DP_STATS_INC(mon_peer, airtime_consumption[ac].consumption, 845 user->rx_time_us); 846 } 847 #else 848 static inline void 849 dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev, 850 struct dp_peer *peer, 851 struct cdp_rx_indication_ppdu *ppdu_desc, 852 struct cdp_rx_stats_ppdu_user *user) 853 { } 854 #endif 855 856 static void dp_rx_stats_update(struct dp_pdev *pdev, 857 struct cdp_rx_indication_ppdu *ppdu) 858 { 859 struct dp_soc *soc = NULL; 860 uint8_t mcs, preamble, ac = 0, nss, ppdu_type; 861 uint32_t num_msdu; 862 uint8_t pkt_bw_offset; 863 struct dp_peer *peer; 864 struct dp_mon_peer *mon_peer; 865 struct cdp_rx_stats_ppdu_user *ppdu_user; 866 uint32_t i; 867 enum cdp_mu_packet_type mu_pkt_type; 868 struct dp_mon_ops *mon_ops; 869 struct dp_mon_pdev *mon_pdev = NULL; 870 871 if (qdf_likely(pdev)) 872 soc = pdev->soc; 873 else 874 return; 875 876 if (qdf_likely(!soc) || soc->process_rx_status) 877 return; 878 879 mon_pdev = pdev->monitor_pdev; 880 881 preamble = ppdu->u.preamble; 882 ppdu_type = ppdu->u.ppdu_type; 883 884 for (i = 0; i < ppdu->num_users && i < CDP_MU_MAX_USERS; i++) { 885 peer = NULL; 886 ppdu_user = &ppdu->user[i]; 887 peer = dp_peer_get_ref_by_id(soc, ppdu_user->peer_id, 888 DP_MOD_ID_RX_PPDU_STATS); 889 890 if (qdf_unlikely(!peer)) 891 mon_peer = mon_pdev->invalid_mon_peer; 892 else 893 mon_peer = peer->monitor_peer; 894 895 if (qdf_unlikely(!mon_peer)) { 896 if (peer) 897 dp_peer_unref_delete(peer, 898 DP_MOD_ID_RX_PPDU_STATS); 899 900 continue; 901 } 902 903 if ((preamble == DOT11_A) || (preamble == DOT11_B)) 904 ppdu->u.nss = 1; 905 906 if (ppdu_type == HAL_RX_TYPE_SU) { 907 mcs = ppdu->u.mcs; 908 nss = ppdu->u.nss; 909 } else { 910 mcs = ppdu_user->mcs; 911 nss = ppdu_user->nss; 912 } 913 914 num_msdu = ppdu_user->num_msdu; 915 916 pkt_bw_offset = dp_get_bw_offset_frm_bw(soc, ppdu->u.bw); 917 DP_STATS_UPD(mon_peer, rx.snr, (ppdu->rssi + pkt_bw_offset)); 918 919 if (qdf_unlikely(mon_peer->stats.rx.avg_snr == CDP_INVALID_SNR)) 920 mon_peer->stats.rx.avg_snr = 921 CDP_SNR_IN(mon_peer->stats.rx.snr); 922 else 923 CDP_SNR_UPDATE_AVG(mon_peer->stats.rx.avg_snr, 924 mon_peer->stats.rx.snr); 925 926 if (ppdu_type == HAL_RX_TYPE_SU) { 927 if (nss) { 928 DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu); 929 DP_STATS_INC(mon_peer, rx.ppdu_nss[nss - 1], 1); 930 } 931 932 DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_ok, 933 ppdu_user->mpdu_cnt_fcs_ok); 934 DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_err, 935 ppdu_user->mpdu_cnt_fcs_err); 936 } 937 938 if (ppdu_type >= HAL_RX_TYPE_MU_MIMO && 939 ppdu_type <= HAL_RX_TYPE_MU_OFDMA) { 940 if (ppdu_type == HAL_RX_TYPE_MU_MIMO) 941 mu_pkt_type = TXRX_TYPE_MU_MIMO; 942 else 943 mu_pkt_type = TXRX_TYPE_MU_OFDMA; 944 945 if (qdf_likely(nss)) { 946 DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu); 947 DP_STATS_INC(mon_peer, 948 rx.rx_mu[mu_pkt_type].ppdu_nss[nss - 1], 949 1); 950 } 951 952 DP_STATS_INC(mon_peer, 953 rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_ok, 954 ppdu_user->mpdu_cnt_fcs_ok); 955 DP_STATS_INC(mon_peer, 956 rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_err, 957 ppdu_user->mpdu_cnt_fcs_err); 958 } 959 960 DP_STATS_INC(mon_peer, rx.sgi_count[ppdu->u.gi], num_msdu); 961 DP_STATS_INC(mon_peer, rx.bw[ppdu->u.bw], num_msdu); 962 DP_STATS_INC(mon_peer, rx.reception_type[ppdu->u.ppdu_type], 963 num_msdu); 964 DP_STATS_INC(mon_peer, rx.ppdu_cnt[ppdu->u.ppdu_type], 1); 965 DP_STATS_INCC(mon_peer, rx.ampdu_cnt, num_msdu, 966 ppdu_user->is_ampdu); 967 DP_STATS_INCC(mon_peer, rx.non_ampdu_cnt, num_msdu, 968 !(ppdu_user->is_ampdu)); 969 DP_STATS_UPD(mon_peer, rx.rx_rate, mcs); 970 DP_STATS_INCC(mon_peer, 971 rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, 972 ((mcs >= MAX_MCS_11A) && (preamble == DOT11_A))); 973 DP_STATS_INCC(mon_peer, 974 rx.pkt_type[preamble].mcs_count[mcs], num_msdu, 975 ((mcs < MAX_MCS_11A) && (preamble == DOT11_A))); 976 DP_STATS_INCC(mon_peer, 977 rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, 978 ((mcs >= MAX_MCS_11B) && (preamble == DOT11_B))); 979 DP_STATS_INCC(mon_peer, 980 rx.pkt_type[preamble].mcs_count[mcs], num_msdu, 981 ((mcs < MAX_MCS_11B) && (preamble == DOT11_B))); 982 DP_STATS_INCC(mon_peer, 983 rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, 984 ((mcs >= MAX_MCS_11A) && (preamble == DOT11_N))); 985 DP_STATS_INCC(mon_peer, 986 rx.pkt_type[preamble].mcs_count[mcs], num_msdu, 987 ((mcs < MAX_MCS_11A) && (preamble == DOT11_N))); 988 DP_STATS_INCC(mon_peer, 989 rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, 990 ((mcs >= MAX_MCS_11AC) && (preamble == DOT11_AC))); 991 DP_STATS_INCC(mon_peer, 992 rx.pkt_type[preamble].mcs_count[mcs], num_msdu, 993 ((mcs < MAX_MCS_11AC) && (preamble == DOT11_AC))); 994 DP_STATS_INCC(mon_peer, 995 rx.pkt_type[preamble].mcs_count[MAX_MCS - 1], num_msdu, 996 ((mcs >= (MAX_MCS_11AX)) && (preamble == DOT11_AX))); 997 DP_STATS_INCC(mon_peer, 998 rx.pkt_type[preamble].mcs_count[mcs], num_msdu, 999 ((mcs < (MAX_MCS_11AX)) && (preamble == DOT11_AX))); 1000 DP_STATS_INCC(mon_peer, 1001 rx.su_ax_ppdu_cnt.mcs_count[MAX_MCS - 1], 1, 1002 ((mcs >= (MAX_MCS_11AX)) && (preamble == DOT11_AX) && 1003 (ppdu_type == HAL_RX_TYPE_SU))); 1004 DP_STATS_INCC(mon_peer, 1005 rx.su_ax_ppdu_cnt.mcs_count[mcs], 1, 1006 ((mcs < (MAX_MCS_11AX)) && (preamble == DOT11_AX) && 1007 (ppdu_type == HAL_RX_TYPE_SU))); 1008 DP_STATS_INCC(mon_peer, 1009 rx.rx_mu[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[MAX_MCS - 1], 1010 1, ((mcs >= (MAX_MCS_11AX)) && 1011 (preamble == DOT11_AX) && 1012 (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); 1013 DP_STATS_INCC(mon_peer, 1014 rx.rx_mu[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[mcs], 1015 1, ((mcs < (MAX_MCS_11AX)) && 1016 (preamble == DOT11_AX) && 1017 (ppdu_type == HAL_RX_TYPE_MU_OFDMA))); 1018 DP_STATS_INCC(mon_peer, 1019 rx.rx_mu[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[MAX_MCS - 1], 1020 1, ((mcs >= (MAX_MCS_11AX)) && 1021 (preamble == DOT11_AX) && 1022 (ppdu_type == HAL_RX_TYPE_MU_MIMO))); 1023 DP_STATS_INCC(mon_peer, 1024 rx.rx_mu[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[mcs], 1025 1, ((mcs < (MAX_MCS_11AX)) && 1026 (preamble == DOT11_AX) && 1027 (ppdu_type == HAL_RX_TYPE_MU_MIMO))); 1028 1029 /* 1030 * If invalid TID, it could be a non-qos frame, hence do not 1031 * update any AC counters 1032 */ 1033 ac = TID_TO_WME_AC(ppdu_user->tid); 1034 1035 if (qdf_likely(ppdu->tid != HAL_TID_INVALID)) 1036 DP_STATS_INC(mon_peer, rx.wme_ac_type[ac], num_msdu); 1037 1038 DP_STATS_INC(mon_peer, rx.rx_ppdus, 1); 1039 DP_STATS_INC(mon_peer, rx.rx_mpdus, 1040 (ppdu_user->mpdu_cnt_fcs_ok + ppdu_user->mpdu_cnt_fcs_err)); 1041 1042 mon_ops = dp_mon_ops_get(soc); 1043 if (qdf_likely(mon_ops && mon_ops->mon_rx_stats_update)) 1044 mon_ops->mon_rx_stats_update(mon_peer, ppdu, ppdu_user); 1045 1046 if (qdf_unlikely(!peer)) 1047 continue; 1048 1049 dp_peer_stats_notify(pdev, peer); 1050 DP_STATS_UPD(mon_peer, rx.last_snr, 1051 (ppdu->rssi + pkt_bw_offset)); 1052 1053 dp_peer_qos_stats_notify(pdev, ppdu_user); 1054 1055 if (dp_is_subtype_data(ppdu->frame_ctrl)) 1056 dp_rx_rate_stats_update(peer, ppdu, i); 1057 1058 dp_send_stats_event(pdev, peer, ppdu_user->peer_id); 1059 1060 dp_ppdu_desc_user_rx_time_update(pdev, peer, ppdu, ppdu_user); 1061 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 1062 } 1063 } 1064 1065 void 1066 dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, 1067 struct hal_rx_ppdu_info *ppdu_info) 1068 { 1069 qdf_nbuf_t ppdu_nbuf; 1070 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 1071 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1072 uint64_t size = 0; 1073 uint8_t num_users = 0; 1074 1075 /* 1076 * Do not allocate if fcs error, 1077 * ast idx invalid / fctl invalid 1078 * 1079 * In CFR RCC mode - PPDU status TLVs of error pkts are also needed 1080 */ 1081 if (qdf_unlikely(ppdu_info->com_info.mpdu_cnt_fcs_ok == 0)) 1082 return; 1083 1084 if (qdf_unlikely(mon_pdev->neighbour_peers_added)) { 1085 if (ppdu_info->nac_info.fc_valid && 1086 ppdu_info->nac_info.to_ds_flag && 1087 ppdu_info->nac_info.mac_addr2_valid) { 1088 struct dp_neighbour_peer *peer = NULL; 1089 uint8_t rssi = ppdu_info->rx_status.rssi_comb; 1090 1091 qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex); 1092 if (mon_pdev->neighbour_peers_added) { 1093 TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list, 1094 neighbour_peer_list_elem) { 1095 if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr, 1096 &ppdu_info->nac_info.mac_addr2, 1097 QDF_MAC_ADDR_SIZE)) { 1098 peer->rssi = rssi; 1099 break; 1100 } 1101 } 1102 } 1103 qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex); 1104 } else { 1105 dp_info("Neighbour peers RSSI update failed! fc_valid = %d, to_ds_flag = %d and mac_addr2_valid = %d", 1106 ppdu_info->nac_info.fc_valid, 1107 ppdu_info->nac_info.to_ds_flag, 1108 ppdu_info->nac_info.mac_addr2_valid); 1109 } 1110 } 1111 1112 /* need not generate wdi event when mcopy, cfr rcc mode and 1113 * enhanced stats are not enabled 1114 */ 1115 if (qdf_unlikely(!mon_pdev->mcopy_mode && 1116 !mon_pdev->enhanced_stats_en && 1117 !dp_cfr_rcc_mode_status(pdev))) 1118 return; 1119 1120 if (qdf_unlikely(dp_cfr_rcc_mode_status(pdev))) 1121 dp_update_cfr_dbg_stats(pdev, ppdu_info); 1122 1123 if (qdf_unlikely(!ppdu_info->rx_status.frame_control_info_valid || 1124 ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)) { 1125 if (!(mon_pdev->mcopy_mode || 1126 (dp_bb_captured_chan_status(pdev, ppdu_info) == 1127 QDF_STATUS_SUCCESS))) 1128 return; 1129 } 1130 num_users = ppdu_info->com_info.num_users; 1131 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 1132 size = sizeof(struct cdp_rx_indication_ppdu) + 1133 num_users * sizeof(struct cdp_rx_stats_ppdu_user); 1134 ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, 1135 size, 1136 0, 0, FALSE); 1137 if (qdf_likely(ppdu_nbuf)) { 1138 cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(ppdu_nbuf); 1139 1140 qdf_mem_zero(cdp_rx_ppdu, size); 1141 dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu); 1142 dp_rx_populate_cdp_indication_ppdu(pdev, 1143 ppdu_info, cdp_rx_ppdu); 1144 if (!qdf_unlikely(qdf_nbuf_put_tail(ppdu_nbuf, 1145 sizeof(struct cdp_rx_indication_ppdu)))) 1146 return; 1147 1148 dp_rx_stats_update(pdev, cdp_rx_ppdu); 1149 1150 if (qdf_unlikely(cdp_rx_ppdu->peer_id != HTT_INVALID_PEER)) { 1151 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, 1152 soc, ppdu_nbuf, 1153 cdp_rx_ppdu->peer_id, 1154 WDI_NO_VAL, pdev->pdev_id); 1155 } else if (qdf_unlikely(mon_pdev->mcopy_mode || dp_cfr_rcc_mode_status(pdev))) { 1156 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, 1157 ppdu_nbuf, HTT_INVALID_PEER, 1158 WDI_NO_VAL, pdev->pdev_id); 1159 } else { 1160 qdf_nbuf_free(ppdu_nbuf); 1161 } 1162 } 1163 } 1164 #endif/* QCA_ENHANCED_STATS_SUPPORT */ 1165 1166 #ifdef QCA_UNDECODED_METADATA_SUPPORT 1167 #define RX_PHYERR_MASK_GET64(_val1, _val2) (((uint64_t)(_val2) << 32) | (_val1)) 1168 /** 1169 * dp_rx_populate_cdp_indication_ppdu_undecoded_metadata() - Populate cdp 1170 * rx indication structure 1171 * @pdev: pdev ctx 1172 * @ppdu_info: ppdu info structure from ppdu ring 1173 * @cdp_rx_ppdu: Rx PPDU indication structure 1174 * 1175 * Return: none 1176 */ 1177 static void 1178 dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(struct dp_pdev *pdev, 1179 struct hal_rx_ppdu_info *ppdu_info, 1180 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 1181 { 1182 uint32_t chain; 1183 1184 cdp_rx_ppdu->phyrx_abort = ppdu_info->rx_status.phyrx_abort; 1185 cdp_rx_ppdu->phyrx_abort_reason = 1186 ppdu_info->rx_status.phyrx_abort_reason; 1187 1188 cdp_rx_ppdu->first_data_seq_ctrl = 1189 ppdu_info->rx_status.first_data_seq_ctrl; 1190 cdp_rx_ppdu->frame_ctrl = 1191 ppdu_info->rx_status.frame_control; 1192 cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count; 1193 cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count; 1194 cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count; 1195 cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type; 1196 cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok; 1197 cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count + 1198 cdp_rx_ppdu->udp_msdu_count + 1199 cdp_rx_ppdu->other_msdu_count); 1200 1201 cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ? 1202 ppdu_info->com_info.mpdu_cnt_fcs_ok : 0; 1203 1204 if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1) 1205 cdp_rx_ppdu->is_ampdu = 1; 1206 else 1207 cdp_rx_ppdu->is_ampdu = 0; 1208 cdp_rx_ppdu->tid = ppdu_info->rx_status.tid; 1209 1210 cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; 1211 cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len; 1212 cdp_rx_ppdu->duration = ppdu_info->rx_status.duration; 1213 cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw; 1214 cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss; 1215 cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs; 1216 if (ppdu_info->rx_status.sgi == VHT_SGI_NYSM && 1217 ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) 1218 cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; 1219 else 1220 cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; 1221 1222 cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; 1223 cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; 1224 cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >> 1225 QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3; 1226 1227 cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb; 1228 cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; 1229 cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num; 1230 cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; 1231 cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; 1232 cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; 1233 cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; 1234 1235 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { 1236 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; 1237 cdp_rx_ppdu->vht_no_txop_ps = 1238 ppdu_info->rx_status.vht_no_txop_ps; 1239 cdp_rx_ppdu->vht_crc = ppdu_info->rx_status.vht_crc; 1240 cdp_rx_ppdu->group_id = ppdu_info->rx_status.vht_flag_values5; 1241 } else if (ppdu_info->rx_status.preamble_type == 1242 HAL_RX_PKT_TYPE_11AX) { 1243 cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> 1244 QDF_MON_STATUS_STBC_SHIFT) & 0x1; 1245 cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> 1246 QDF_MON_STATUS_DCM_SHIFT) & 0x1; 1247 } else { 1248 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.ht_stbc; 1249 cdp_rx_ppdu->ht_length = ppdu_info->rx_status.ht_length; 1250 cdp_rx_ppdu->ht_smoothing = ppdu_info->rx_status.smoothing; 1251 cdp_rx_ppdu->ht_not_sounding = 1252 ppdu_info->rx_status.not_sounding; 1253 cdp_rx_ppdu->ht_aggregation = ppdu_info->rx_status.aggregation; 1254 cdp_rx_ppdu->ht_stbc = ppdu_info->rx_status.ht_stbc; 1255 cdp_rx_ppdu->ht_crc = ppdu_info->rx_status.ht_crc; 1256 } 1257 1258 cdp_rx_ppdu->l_sig_length = ppdu_info->rx_status.l_sig_length; 1259 cdp_rx_ppdu->l_sig_a_parity = ppdu_info->rx_status.l_sig_a_parity; 1260 cdp_rx_ppdu->l_sig_a_pkt_type = ppdu_info->rx_status.l_sig_a_pkt_type; 1261 1262 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { 1263 cdp_rx_ppdu->he_crc = ppdu_info->rx_status.he_crc; 1264 cdp_rx_ppdu->bss_color_id = 1265 ppdu_info->rx_status.he_data3 & 0x3F; 1266 cdp_rx_ppdu->beam_change = (ppdu_info->rx_status.he_data3 >> 1267 QDF_MON_STATUS_BEAM_CHANGE_SHIFT) & 0x1; 1268 cdp_rx_ppdu->dl_ul_flag = (ppdu_info->rx_status.he_data3 >> 1269 QDF_MON_STATUS_DL_UL_SHIFT) & 0x1; 1270 cdp_rx_ppdu->ldpc_extra_sym = (ppdu_info->rx_status.he_data3 >> 1271 QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT) & 0x1; 1272 cdp_rx_ppdu->special_reuse = 1273 ppdu_info->rx_status.he_data4 & 0xF; 1274 cdp_rx_ppdu->ltf_sym = (ppdu_info->rx_status.he_data5 >> 1275 QDF_MON_STATUS_HE_LTF_SYM_SHIFT) & 0x7; 1276 cdp_rx_ppdu->txbf = (ppdu_info->rx_status.he_data5 >> 1277 QDF_MON_STATUS_TXBF_SHIFT) & 0x1; 1278 cdp_rx_ppdu->pe_disambiguity = (ppdu_info->rx_status.he_data5 >> 1279 QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT) & 0x1; 1280 cdp_rx_ppdu->pre_fec_pad = (ppdu_info->rx_status.he_data5 >> 1281 QDF_MON_STATUS_PRE_FEC_PAD_SHIFT) & 0x3; 1282 cdp_rx_ppdu->dopplar = (ppdu_info->rx_status.he_data6 >> 1283 QDF_MON_STATUS_DOPPLER_SHIFT) & 0x1; 1284 cdp_rx_ppdu->txop_duration = (ppdu_info->rx_status.he_data6 >> 1285 QDF_MON_STATUS_TXOP_SHIFT) & 0x7F; 1286 cdp_rx_ppdu->sig_b_mcs = ppdu_info->rx_status.he_flags1 & 0x7; 1287 cdp_rx_ppdu->sig_b_dcm = (ppdu_info->rx_status.he_flags1 >> 1288 QDF_MON_STATUS_DCM_FLAG_1_SHIFT) & 0x1; 1289 cdp_rx_ppdu->sig_b_sym = (ppdu_info->rx_status.he_flags2 >> 1290 QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT) & 0xF; 1291 cdp_rx_ppdu->sig_b_comp = (ppdu_info->rx_status.he_flags2 >> 1292 QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT) & 0x1; 1293 } 1294 dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu, pdev); 1295 dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); 1296 cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; 1297 1298 cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor; 1299 for (chain = 0; chain < MAX_CHAIN; chain++) 1300 cdp_rx_ppdu->per_chain_rssi[chain] = 1301 ppdu_info->rx_status.rssi[chain]; 1302 1303 cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast; 1304 1305 cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; 1306 1307 dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu); 1308 } 1309 1310 /** 1311 * dp_rx_is_valid_undecoded_frame() - Check unencoded frame received valid 1312 * or not against configured error mask 1313 * @err_mask: configured err mask 1314 * @err_code: Received error reason code for phy abort 1315 * 1316 * Return: true / false 1317 */ 1318 static inline bool 1319 dp_rx_is_valid_undecoded_frame(uint64_t err_mask, uint8_t err_code) 1320 { 1321 if (err_code < CDP_PHYRX_ERR_MAX && 1322 (err_mask & (1L << err_code))) 1323 return true; 1324 1325 return false; 1326 } 1327 1328 void 1329 dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev, 1330 struct hal_rx_ppdu_info *ppdu_info) 1331 { 1332 qdf_nbuf_t ppdu_nbuf; 1333 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 1334 uint8_t abort_reason = 0; 1335 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1336 uint64_t mask64; 1337 1338 /* Return if RX_ABORT not set */ 1339 if (ppdu_info->rx_status.phyrx_abort == 0) 1340 return; 1341 1342 mask64 = RX_PHYERR_MASK_GET64(mon_pdev->phyrx_error_mask, 1343 mon_pdev->phyrx_error_mask_cont); 1344 abort_reason = ppdu_info->rx_status.phyrx_abort_reason; 1345 1346 if (!dp_rx_is_valid_undecoded_frame(mask64, abort_reason)) 1347 return; 1348 1349 ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, 1350 sizeof(struct cdp_rx_indication_ppdu), 1351 0, 0, FALSE); 1352 if (ppdu_nbuf) { 1353 cdp_rx_ppdu = ((struct cdp_rx_indication_ppdu *) 1354 qdf_nbuf_data(ppdu_nbuf)); 1355 1356 qdf_mem_zero(cdp_rx_ppdu, 1357 sizeof(struct cdp_rx_indication_ppdu)); 1358 dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(pdev, 1359 ppdu_info, cdp_rx_ppdu); 1360 1361 if (!qdf_nbuf_put_tail(ppdu_nbuf, 1362 sizeof(struct cdp_rx_indication_ppdu))) { 1363 return; 1364 } 1365 1366 mon_pdev->rx_mon_stats.rx_undecoded_count++; 1367 mon_pdev->rx_mon_stats.rx_undecoded_error[abort_reason] += 1; 1368 1369 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA, 1370 soc, ppdu_nbuf, HTT_INVALID_PEER, 1371 WDI_NO_VAL, pdev->pdev_id); 1372 } 1373 } 1374 #endif/* QCA_UNDECODED_METADATA_SUPPORT */ 1375 1376 #ifdef QCA_MCOPY_SUPPORT 1377 QDF_STATUS 1378 dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1379 struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf, 1380 uint8_t fcs_ok_mpdu_cnt, bool deliver_frame) 1381 { 1382 uint16_t size = 0; 1383 struct ieee80211_frame *wh; 1384 uint32_t *nbuf_data; 1385 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1386 1387 if (!ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload) 1388 return QDF_STATUS_SUCCESS; 1389 1390 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1391 if (mon_pdev->mcopy_mode == M_COPY) { 1392 if (mon_pdev->m_copy_id.rx_ppdu_id == ppdu_info->com_info.ppdu_id) 1393 return QDF_STATUS_SUCCESS; 1394 } 1395 1396 wh = (struct ieee80211_frame *)(ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload + 4); 1397 1398 size = (ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload - 1399 qdf_nbuf_data(nbuf)); 1400 1401 if (qdf_nbuf_pull_head(nbuf, size) == NULL) 1402 return QDF_STATUS_SUCCESS; 1403 1404 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1405 IEEE80211_FC0_TYPE_MGT) || 1406 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1407 IEEE80211_FC0_TYPE_CTL)) { 1408 return QDF_STATUS_SUCCESS; 1409 } 1410 1411 nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf); 1412 *nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id; 1413 /* only retain RX MSDU payload in the skb */ 1414 qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].payload_len); 1415 if (deliver_frame) { 1416 mon_pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id; 1417 dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc, 1418 nbuf, HTT_INVALID_PEER, 1419 WDI_NO_VAL, pdev->pdev_id); 1420 } 1421 return QDF_STATUS_E_ALREADY; 1422 } 1423 1424 void 1425 dp_rx_mcopy_handle_last_mpdu(struct dp_soc *soc, struct dp_pdev *pdev, 1426 struct hal_rx_ppdu_info *ppdu_info, 1427 qdf_nbuf_t status_nbuf) 1428 { 1429 QDF_STATUS mcopy_status; 1430 qdf_nbuf_t nbuf_clone = NULL; 1431 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1432 1433 /* If the MPDU end tlv and RX header are received in different buffers, 1434 * process the RX header based on fcs status. 1435 */ 1436 if (mon_pdev->mcopy_status_nbuf) { 1437 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1438 if (mon_pdev->mcopy_mode == M_COPY) { 1439 if (mon_pdev->m_copy_id.rx_ppdu_id == 1440 ppdu_info->com_info.ppdu_id) 1441 goto end1; 1442 } 1443 1444 if (ppdu_info->is_fcs_passed) { 1445 nbuf_clone = qdf_nbuf_clone(mon_pdev->mcopy_status_nbuf); 1446 if (!nbuf_clone) { 1447 QDF_TRACE(QDF_MODULE_ID_TXRX, 1448 QDF_TRACE_LEVEL_ERROR, 1449 "Failed to clone nbuf"); 1450 goto end1; 1451 } 1452 1453 mon_pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id; 1454 dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc, 1455 nbuf_clone, 1456 HTT_INVALID_PEER, 1457 WDI_NO_VAL, pdev->pdev_id); 1458 ppdu_info->is_fcs_passed = false; 1459 } 1460 end1: 1461 qdf_nbuf_free(mon_pdev->mcopy_status_nbuf); 1462 mon_pdev->mcopy_status_nbuf = NULL; 1463 } 1464 1465 /* If the MPDU end tlv and RX header are received in different buffers, 1466 * preserve the RX header as the fcs status will be received in MPDU 1467 * end tlv in next buffer. So, cache the buffer to be processd in next 1468 * iteration 1469 */ 1470 if ((ppdu_info->fcs_ok_cnt + ppdu_info->fcs_err_cnt) != 1471 ppdu_info->com_info.mpdu_cnt) { 1472 mon_pdev->mcopy_status_nbuf = qdf_nbuf_clone(status_nbuf); 1473 if (mon_pdev->mcopy_status_nbuf) { 1474 mcopy_status = dp_rx_handle_mcopy_mode( 1475 soc, pdev, 1476 ppdu_info, 1477 mon_pdev->mcopy_status_nbuf, 1478 ppdu_info->fcs_ok_cnt, 1479 false); 1480 if (mcopy_status == QDF_STATUS_SUCCESS) { 1481 qdf_nbuf_free(mon_pdev->mcopy_status_nbuf); 1482 mon_pdev->mcopy_status_nbuf = NULL; 1483 } 1484 } 1485 } 1486 } 1487 1488 void 1489 dp_rx_mcopy_process_ppdu_info(struct dp_pdev *pdev, 1490 struct hal_rx_ppdu_info *ppdu_info, 1491 uint32_t tlv_status) 1492 { 1493 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1494 1495 if (qdf_unlikely(!mon_pdev->mcopy_mode)) 1496 return; 1497 1498 /* The fcs status is received in MPDU end tlv. If the RX header 1499 * and its MPDU end tlv are received in different status buffer then 1500 * to process that header ppdu_info->is_fcs_passed is used. 1501 * If end tlv is received in next status buffer then com_info.mpdu_cnt 1502 * will be 0 at the time of receiving MPDU end tlv and we update the 1503 * is_fcs_passed flag based on ppdu_info->fcs_err. 1504 */ 1505 if (tlv_status != HAL_TLV_STATUS_MPDU_END) 1506 return; 1507 1508 if (!ppdu_info->fcs_err) { 1509 if (ppdu_info->fcs_ok_cnt > 1510 HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER) { 1511 dp_err("No. of MPDUs(%d) per status buff exceeded", 1512 ppdu_info->fcs_ok_cnt); 1513 return; 1514 } 1515 if (ppdu_info->com_info.mpdu_cnt) 1516 ppdu_info->fcs_ok_cnt++; 1517 else 1518 ppdu_info->is_fcs_passed = true; 1519 } else { 1520 if (ppdu_info->com_info.mpdu_cnt) 1521 ppdu_info->fcs_err_cnt++; 1522 else 1523 ppdu_info->is_fcs_passed = false; 1524 } 1525 } 1526 1527 void 1528 dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1529 struct hal_rx_ppdu_info *ppdu_info, 1530 uint32_t tlv_status, 1531 qdf_nbuf_t status_nbuf) 1532 { 1533 QDF_STATUS mcopy_status; 1534 qdf_nbuf_t nbuf_clone = NULL; 1535 uint8_t fcs_ok_mpdu_cnt = 0; 1536 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1537 1538 dp_rx_mcopy_handle_last_mpdu(soc, pdev, ppdu_info, status_nbuf); 1539 1540 if (qdf_unlikely(!ppdu_info->com_info.mpdu_cnt)) 1541 goto end; 1542 1543 if (qdf_unlikely(!ppdu_info->fcs_ok_cnt)) 1544 goto end; 1545 1546 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1547 if (mon_pdev->mcopy_mode == M_COPY) 1548 ppdu_info->fcs_ok_cnt = 1; 1549 1550 while (fcs_ok_mpdu_cnt < ppdu_info->fcs_ok_cnt) { 1551 nbuf_clone = qdf_nbuf_clone(status_nbuf); 1552 if (!nbuf_clone) { 1553 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1554 "Failed to clone nbuf"); 1555 goto end; 1556 } 1557 1558 mcopy_status = dp_rx_handle_mcopy_mode(soc, pdev, 1559 ppdu_info, 1560 nbuf_clone, 1561 fcs_ok_mpdu_cnt, 1562 true); 1563 1564 if (mcopy_status == QDF_STATUS_SUCCESS) 1565 qdf_nbuf_free(nbuf_clone); 1566 1567 fcs_ok_mpdu_cnt++; 1568 } 1569 end: 1570 qdf_nbuf_free(status_nbuf); 1571 ppdu_info->fcs_ok_cnt = 0; 1572 ppdu_info->fcs_err_cnt = 0; 1573 ppdu_info->com_info.mpdu_cnt = 0; 1574 qdf_mem_zero(&ppdu_info->ppdu_msdu_info, 1575 HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER 1576 * sizeof(struct hal_rx_msdu_payload_info)); 1577 } 1578 #endif /* QCA_MCOPY_SUPPORT */ 1579 1580 int 1581 dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1582 struct hal_rx_ppdu_info *ppdu_info, 1583 qdf_nbuf_t nbuf) 1584 { 1585 uint8_t size = 0; 1586 struct dp_mon_vdev *mon_vdev; 1587 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1588 1589 if (!mon_pdev->mvdev) { 1590 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1591 "[%s]:[%d] Monitor vdev is NULL !!", 1592 __func__, __LINE__); 1593 return 1; 1594 } 1595 1596 mon_vdev = mon_pdev->mvdev->monitor_vdev; 1597 1598 if (!ppdu_info->msdu_info.first_msdu_payload) { 1599 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1600 "[%s]:[%d] First msdu payload not present", 1601 __func__, __LINE__); 1602 return 1; 1603 } 1604 1605 /* Adding 4 bytes to get to start of 802.11 frame after phy_ppdu_id */ 1606 size = (ppdu_info->msdu_info.first_msdu_payload - 1607 qdf_nbuf_data(nbuf)) + 4; 1608 ppdu_info->msdu_info.first_msdu_payload = NULL; 1609 1610 if (!qdf_nbuf_pull_head(nbuf, size)) { 1611 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1612 "[%s]:[%d] No header present", 1613 __func__, __LINE__); 1614 return 1; 1615 } 1616 1617 /* Only retain RX MSDU payload in the skb */ 1618 qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - 1619 ppdu_info->msdu_info.payload_len); 1620 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, nbuf, 1621 qdf_nbuf_headroom(nbuf))) { 1622 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 1623 return 1; 1624 } 1625 1626 mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, 1627 nbuf, NULL); 1628 mon_pdev->ppdu_info.rx_status.monitor_direct_used = 0; 1629 return 0; 1630 } 1631 1632 qdf_nbuf_t 1633 dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev) 1634 { 1635 uint8_t *buf; 1636 int32_t nbuf_retry_count; 1637 QDF_STATUS ret; 1638 qdf_nbuf_t nbuf = NULL; 1639 1640 for (nbuf_retry_count = 0; nbuf_retry_count < 1641 QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD; 1642 nbuf_retry_count++) { 1643 /* Allocate a new skb using alloc_skb */ 1644 nbuf = qdf_nbuf_alloc_no_recycler(RX_MON_STATUS_BUF_SIZE, 1645 RX_MON_STATUS_BUF_RESERVATION, 1646 RX_DATA_BUFFER_ALIGNMENT); 1647 1648 if (!nbuf) { 1649 DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1); 1650 continue; 1651 } 1652 1653 buf = qdf_nbuf_data(nbuf); 1654 1655 memset(buf, 0, RX_MON_STATUS_BUF_SIZE); 1656 1657 ret = qdf_nbuf_map_nbytes_single(soc->osdev, nbuf, 1658 QDF_DMA_FROM_DEVICE, 1659 RX_MON_STATUS_BUF_SIZE); 1660 1661 /* nbuf map failed */ 1662 if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) { 1663 qdf_nbuf_free(nbuf); 1664 DP_STATS_INC(pdev, replenish.map_err, 1); 1665 continue; 1666 } 1667 /* qdf_nbuf alloc and map succeeded */ 1668 break; 1669 } 1670 1671 /* qdf_nbuf still alloc or map failed */ 1672 if (qdf_unlikely(nbuf_retry_count >= 1673 QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD)) 1674 return NULL; 1675 1676 return nbuf; 1677 } 1678 1679 #ifndef DISABLE_MON_CONFIG 1680 uint32_t 1681 dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, 1682 uint32_t mac_id, uint32_t quota) 1683 { 1684 struct dp_mon_soc *mon_soc = soc->monitor_soc; 1685 1686 if (mon_soc && mon_soc->mon_rx_process) 1687 return mon_soc->mon_rx_process(soc, int_ctx, 1688 mac_id, quota); 1689 return 0; 1690 } 1691 #else 1692 uint32_t 1693 dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, 1694 uint32_t mac_id, uint32_t quota) 1695 { 1696 return 0; 1697 } 1698 #endif 1699 1700 /** 1701 * dp_send_mgmt_packet_to_stack(): send indicataion to upper layers 1702 * 1703 * @soc: soc handle 1704 * @nbuf: Mgmt packet 1705 * @pdev: pdev handle 1706 * 1707 * Return: QDF_STATUS_SUCCESS on success 1708 * QDF_STATUS_E_INVAL in error 1709 */ 1710 #ifdef QCA_MCOPY_SUPPORT 1711 static inline QDF_STATUS 1712 dp_send_mgmt_packet_to_stack(struct dp_soc *soc, 1713 qdf_nbuf_t nbuf, 1714 struct dp_pdev *pdev) 1715 { 1716 uint32_t *nbuf_data; 1717 struct ieee80211_frame *wh; 1718 qdf_frag_t addr; 1719 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1720 1721 if (!nbuf) 1722 return QDF_STATUS_E_INVAL; 1723 1724 /* Get addr pointing to80211 header */ 1725 addr = dp_rx_mon_get_nbuf_80211_hdr(nbuf); 1726 if (qdf_unlikely(!addr)) { 1727 qdf_nbuf_free(nbuf); 1728 return QDF_STATUS_E_INVAL; 1729 } 1730 1731 /*check if this is not a mgmt packet*/ 1732 wh = (struct ieee80211_frame *)addr; 1733 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != 1734 IEEE80211_FC0_TYPE_MGT) && 1735 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != 1736 IEEE80211_FC0_TYPE_CTL)) { 1737 qdf_nbuf_free(nbuf); 1738 return QDF_STATUS_E_INVAL; 1739 } 1740 nbuf_data = (uint32_t *)qdf_nbuf_push_head(nbuf, 4); 1741 if (!nbuf_data) { 1742 QDF_TRACE(QDF_MODULE_ID_DP, 1743 QDF_TRACE_LEVEL_ERROR, 1744 FL("No headroom")); 1745 qdf_nbuf_free(nbuf); 1746 return QDF_STATUS_E_INVAL; 1747 } 1748 *nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id; 1749 1750 dp_wdi_event_handler(WDI_EVENT_RX_MGMT_CTRL, soc, nbuf, 1751 HTT_INVALID_PEER, 1752 WDI_NO_VAL, pdev->pdev_id); 1753 return QDF_STATUS_SUCCESS; 1754 } 1755 #else 1756 static inline QDF_STATUS 1757 dp_send_mgmt_packet_to_stack(struct dp_soc *soc, 1758 qdf_nbuf_t nbuf, 1759 struct dp_pdev *pdev) 1760 { 1761 return QDF_STATUS_SUCCESS; 1762 } 1763 #endif /* QCA_MCOPY_SUPPORT */ 1764 1765 QDF_STATUS dp_rx_mon_process_dest_pktlog(struct dp_soc *soc, 1766 uint32_t mac_id, 1767 qdf_nbuf_t mpdu) 1768 { 1769 uint32_t event, msdu_timestamp = 0; 1770 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1771 void *data; 1772 struct ieee80211_frame *wh; 1773 uint8_t type, subtype; 1774 struct dp_mon_pdev *mon_pdev; 1775 1776 if (!pdev) 1777 return QDF_STATUS_E_INVAL; 1778 1779 mon_pdev = pdev->monitor_pdev; 1780 1781 if (mon_pdev->rx_pktlog_cbf) { 1782 if (qdf_nbuf_get_nr_frags(mpdu)) 1783 data = qdf_nbuf_get_frag_addr(mpdu, 0); 1784 else 1785 data = qdf_nbuf_data(mpdu); 1786 1787 /* CBF logging required, doesn't matter if it is a full mode 1788 * or lite mode. 1789 * Need to look for mpdu with: 1790 * TYPE = ACTION, SUBTYPE = NO ACK in the header 1791 */ 1792 event = WDI_EVENT_RX_CBF; 1793 1794 wh = (struct ieee80211_frame *)data; 1795 type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 1796 subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 1797 if (type == IEEE80211_FC0_TYPE_MGT && 1798 subtype == IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK) { 1799 msdu_timestamp = mon_pdev->ppdu_info.rx_status.tsft; 1800 dp_rx_populate_cbf_hdr(soc, 1801 mac_id, event, 1802 mpdu, 1803 msdu_timestamp); 1804 } 1805 } 1806 return QDF_STATUS_SUCCESS; 1807 } 1808 1809 QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, 1810 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu) 1811 { 1812 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1813 struct cdp_mon_status *rs; 1814 qdf_nbuf_t mon_skb, skb_next; 1815 qdf_nbuf_t mon_mpdu = NULL; 1816 struct dp_mon_vdev *mon_vdev; 1817 struct dp_mon_pdev *mon_pdev; 1818 1819 if (!pdev) 1820 goto mon_deliver_fail; 1821 1822 mon_pdev = pdev->monitor_pdev; 1823 rs = &mon_pdev->rx_mon_recv_status; 1824 1825 if (!mon_pdev->mvdev && !mon_pdev->mcopy_mode && 1826 !mon_pdev->rx_pktlog_cbf) 1827 goto mon_deliver_fail; 1828 1829 /* restitch mon MPDU for delivery via monitor interface */ 1830 mon_mpdu = dp_rx_mon_restitch_mpdu(soc, mac_id, head_msdu, 1831 tail_msdu, rs); 1832 1833 /* If MPDU restitch fails, free buffers*/ 1834 if (!mon_mpdu) { 1835 dp_info("MPDU restitch failed, free buffers"); 1836 goto mon_deliver_fail; 1837 } 1838 1839 dp_rx_mon_process_dest_pktlog(soc, mac_id, mon_mpdu); 1840 1841 /* monitor vap cannot be present when mcopy is enabled 1842 * hence same skb can be consumed 1843 */ 1844 if (mon_pdev->mcopy_mode) 1845 return dp_send_mgmt_packet_to_stack(soc, mon_mpdu, pdev); 1846 1847 if (mon_mpdu && mon_pdev->mvdev && 1848 mon_pdev->mvdev->osif_vdev && 1849 mon_pdev->mvdev->monitor_vdev && 1850 mon_pdev->mvdev->monitor_vdev->osif_rx_mon) { 1851 mon_vdev = mon_pdev->mvdev->monitor_vdev; 1852 1853 mon_pdev->ppdu_info.rx_status.ppdu_id = 1854 mon_pdev->ppdu_info.com_info.ppdu_id; 1855 mon_pdev->ppdu_info.rx_status.device_id = soc->device_id; 1856 mon_pdev->ppdu_info.rx_status.chan_noise_floor = 1857 pdev->chan_noise_floor; 1858 dp_handle_tx_capture(soc, pdev, mon_mpdu); 1859 1860 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, 1861 mon_mpdu, 1862 qdf_nbuf_headroom(mon_mpdu))) { 1863 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 1864 goto mon_deliver_fail; 1865 } 1866 1867 dp_rx_mon_update_pf_tag_to_buf_headroom(soc, mon_mpdu); 1868 mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, 1869 mon_mpdu, 1870 &mon_pdev->ppdu_info.rx_status); 1871 } else { 1872 dp_rx_mon_dest_debug("%pK: mon_mpdu=%pK monitor_vdev %pK osif_vdev %pK" 1873 , soc, mon_mpdu, mon_pdev->mvdev, 1874 (mon_pdev->mvdev ? mon_pdev->mvdev->osif_vdev 1875 : NULL)); 1876 goto mon_deliver_fail; 1877 } 1878 1879 return QDF_STATUS_SUCCESS; 1880 1881 mon_deliver_fail: 1882 mon_skb = head_msdu; 1883 while (mon_skb) { 1884 skb_next = qdf_nbuf_next(mon_skb); 1885 1886 dp_rx_mon_dest_debug("%pK: [%s][%d] mon_skb=%pK len %u", 1887 soc, __func__, __LINE__, mon_skb, mon_skb->len); 1888 1889 qdf_nbuf_free(mon_skb); 1890 mon_skb = skb_next; 1891 } 1892 return QDF_STATUS_E_INVAL; 1893 } 1894 1895 QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, 1896 uint32_t mac_id) 1897 { 1898 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1899 ol_txrx_rx_mon_fp osif_rx_mon; 1900 qdf_nbuf_t dummy_msdu; 1901 struct dp_mon_pdev *mon_pdev; 1902 struct dp_mon_vdev *mon_vdev; 1903 1904 /* Sanity checking */ 1905 if (!pdev || !pdev->monitor_pdev) 1906 goto mon_deliver_non_std_fail; 1907 1908 mon_pdev = pdev->monitor_pdev; 1909 1910 if (!mon_pdev->mvdev || !mon_pdev->mvdev || 1911 !mon_pdev->mvdev->monitor_vdev || 1912 !mon_pdev->mvdev->monitor_vdev->osif_rx_mon) 1913 goto mon_deliver_non_std_fail; 1914 1915 mon_vdev = mon_pdev->mvdev->monitor_vdev; 1916 /* Generate a dummy skb_buff */ 1917 osif_rx_mon = mon_vdev->osif_rx_mon; 1918 dummy_msdu = qdf_nbuf_alloc(soc->osdev, MAX_MONITOR_HEADER, 1919 MAX_MONITOR_HEADER, 4, FALSE); 1920 if (!dummy_msdu) 1921 goto allocate_dummy_msdu_fail; 1922 1923 qdf_nbuf_set_pktlen(dummy_msdu, 0); 1924 qdf_nbuf_set_next(dummy_msdu, NULL); 1925 1926 mon_pdev->ppdu_info.rx_status.ppdu_id = 1927 mon_pdev->ppdu_info.com_info.ppdu_id; 1928 1929 /* Apply the radio header to this dummy skb */ 1930 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, dummy_msdu, 1931 qdf_nbuf_headroom(dummy_msdu))) { 1932 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 1933 qdf_nbuf_free(dummy_msdu); 1934 goto mon_deliver_non_std_fail; 1935 } 1936 1937 /* deliver to the user layer application */ 1938 osif_rx_mon(mon_pdev->mvdev->osif_vdev, 1939 dummy_msdu, NULL); 1940 1941 /* Clear rx_status*/ 1942 qdf_mem_zero(&mon_pdev->ppdu_info.rx_status, 1943 sizeof(mon_pdev->ppdu_info.rx_status)); 1944 mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_START; 1945 1946 return QDF_STATUS_SUCCESS; 1947 1948 allocate_dummy_msdu_fail: 1949 dp_rx_mon_dest_debug("%pK: mon_skb=%pK ", 1950 soc, dummy_msdu); 1951 1952 mon_deliver_non_std_fail: 1953 return QDF_STATUS_E_INVAL; 1954 } 1955 1956 /** 1957 * dp_rx_process_peer_based_pktlog() - Process Rx pktlog if peer based 1958 * filtering enabled 1959 * @soc: core txrx main context 1960 * @ppdu_info: Structure for rx ppdu info 1961 * @status_nbuf: Qdf nbuf abstraction for linux skb 1962 * @pdev_id: mac_id/pdev_id correspondinggly for MCL and WIN 1963 * 1964 * Return: none 1965 */ 1966 void 1967 dp_rx_process_peer_based_pktlog(struct dp_soc *soc, 1968 struct hal_rx_ppdu_info *ppdu_info, 1969 qdf_nbuf_t status_nbuf, uint32_t pdev_id) 1970 { 1971 struct dp_peer *peer; 1972 struct mon_rx_user_status *rx_user_status; 1973 uint32_t num_users = ppdu_info->com_info.num_users; 1974 uint16_t sw_peer_id; 1975 1976 /* Sanity check for num_users */ 1977 if (!num_users) 1978 return; 1979 1980 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 1981 rx_user_status = &ppdu_info->rx_user_status[num_users - 1]; 1982 1983 sw_peer_id = rx_user_status->sw_peer_id; 1984 1985 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 1986 DP_MOD_ID_RX_PPDU_STATS); 1987 1988 if (!peer) 1989 return; 1990 1991 if ((peer->peer_id != HTT_INVALID_PEER) && (peer->monitor_peer) && 1992 (peer->monitor_peer->peer_based_pktlog_filter)) { 1993 dp_wdi_event_handler( 1994 WDI_EVENT_RX_DESC, soc, 1995 status_nbuf, 1996 peer->peer_id, 1997 WDI_NO_VAL, pdev_id); 1998 } 1999 dp_peer_unref_delete(peer, 2000 DP_MOD_ID_RX_PPDU_STATS); 2001 } 2002 2003 uint32_t 2004 dp_mon_rx_add_tlv(uint8_t id, uint16_t len, void *value, qdf_nbuf_t mpdu_nbuf) 2005 { 2006 uint8_t *dest = NULL; 2007 uint32_t num_bytes_pushed = 0; 2008 2009 /* Add tlv id field */ 2010 dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint8_t)); 2011 if (qdf_likely(dest)) { 2012 *((uint8_t *)dest) = id; 2013 num_bytes_pushed += sizeof(uint8_t); 2014 } 2015 2016 /* Add tlv len field */ 2017 dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint16_t)); 2018 if (qdf_likely(dest)) { 2019 *((uint16_t *)dest) = len; 2020 num_bytes_pushed += sizeof(uint16_t); 2021 } 2022 2023 /* Add tlv value field */ 2024 dest = qdf_nbuf_push_head(mpdu_nbuf, len); 2025 if (qdf_likely(dest)) { 2026 qdf_mem_copy(dest, value, len); 2027 num_bytes_pushed += len; 2028 } 2029 2030 return num_bytes_pushed; 2031 } 2032