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