1 /* 2 * Copyright (c) 2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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 rx_user_status = &ppdu_info->rx_user_status[user_id]; 64 rx_stats_peruser = &cdp_rx_ppdu->user[user_id]; 65 sw_peer_id = rx_user_status->sw_peer_id; 66 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 67 DP_MOD_ID_RX_PPDU_STATS); 68 if (!peer) { 69 rx_stats_peruser->peer_id = HTT_INVALID_PEER; 70 continue; 71 } 72 73 qdf_mem_copy(rx_stats_peruser->mac_addr, 74 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 75 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 76 } 77 } 78 79 void 80 dp_rx_mon_populate_cfr_ppdu_info(struct dp_pdev *pdev, 81 struct hal_rx_ppdu_info *ppdu_info, 82 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 83 { 84 struct dp_peer *peer; 85 struct dp_soc *soc = pdev->soc; 86 int chain; 87 uint16_t sw_peer_id; 88 struct mon_rx_user_status *rx_user_status; 89 uint32_t num_users = ppdu_info->com_info.num_users; 90 91 cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; 92 cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; 93 cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; 94 95 for (chain = 0; chain < MAX_CHAIN; chain++) 96 cdp_rx_ppdu->per_chain_rssi[chain] = 97 ppdu_info->rx_status.rssi[chain]; 98 99 cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; 100 cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; 101 cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; 102 103 if ((ppdu_info->rx_status.sgi == VHT_SGI_NYSM) && 104 (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC)) 105 cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; 106 else 107 cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; 108 109 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { 110 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; 111 } else if (ppdu_info->rx_status.preamble_type == 112 HAL_RX_PKT_TYPE_11AX) { 113 cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> 114 QDF_MON_STATUS_STBC_SHIFT) & 0x1; 115 cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> 116 QDF_MON_STATUS_DCM_SHIFT) & 0x1; 117 } 118 119 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 120 dp_rx_mon_handle_cfr_mu_info(pdev, ppdu_info, cdp_rx_ppdu); 121 rx_user_status = &ppdu_info->rx_user_status[num_users - 1]; 122 sw_peer_id = rx_user_status->sw_peer_id; 123 cdp_rx_ppdu->num_users = num_users; 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 return; 128 } 129 130 cdp_rx_ppdu->peer_id = peer->peer_id; 131 cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; 132 133 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 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 * @pdev: pdev ctx 254 * @ppdu_info: structure for rx ppdu ring 255 * 256 * Return: Success/ Failure 257 */ 258 static inline QDF_STATUS 259 dp_bb_captured_chan_status(struct dp_pdev *pdev, 260 struct hal_rx_ppdu_info *ppdu_info) 261 { 262 QDF_STATUS status = QDF_STATUS_E_FAILURE; 263 struct hal_rx_ppdu_cfr_info *cfr = &ppdu_info->cfr_info; 264 265 if (dp_cfr_rcc_mode_status(pdev)) { 266 if (cfr->bb_captured_channel) 267 status = QDF_STATUS_SUCCESS; 268 } 269 270 return status; 271 } 272 #else 273 static inline QDF_STATUS 274 dp_bb_captured_chan_status(struct dp_pdev *pdev, 275 struct hal_rx_ppdu_info *ppdu_info) 276 { 277 return QDF_STATUS_E_NOSUPPORT; 278 } 279 #endif /* WLAN_CFR_ENABLE */ 280 281 #ifdef QCA_ENHANCED_STATS_SUPPORT 282 #ifdef QCA_RSSI_DB2DBM 283 /** 284 * dp_rx_mon_rf_index_conv() - this function will convert BB index to RF 285 * index in the rssi_chain[chain][bw] array 286 * 287 * @chain: BB chain index 288 * @mon_pdev: pdev structure 289 * 290 * Return: return RF chain index 291 * 292 * Computation: 293 * 3 Bytes of xbar_config are used for RF to BB mapping 294 * Samples of xbar_config, 295 * 296 * If xbar_config is 0x688FAC(hex): 297 * RF chains 0-3 are connected to BB chains 4-7 298 * RF chains 4-7 are connected to BB chains 0-3 299 * here, 300 * bits 0 to 2 = 4, maps BB chain 4 for RF chain 0 301 * bits 3 to 5 = 5, maps BB chain 5 for RF chain 1 302 * bits 6 to 8 = 6, maps BB chain 6 for RF chain 2 303 * bits 9 to 11 = 7, maps BB chain 7 for RF chain 3 304 * bits 12 to 14 = 0, maps BB chain 0 for RF chain 4 305 * bits 15 to 17 = 1, maps BB chain 1 for RF chain 5 306 * bits 18 to 20 = 2, maps BB chain 2 for RF chain 6 307 * bits 21 to 23 = 3, maps BB chain 3 for RF chain 7 308 */ 309 static uint8_t dp_rx_mon_rf_index_conv(uint8_t chain, 310 struct dp_mon_pdev *mon_pdev) 311 { 312 uint32_t xbar_config = mon_pdev->rssi_offsets.xbar_config; 313 314 if (mon_pdev->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 dp_mon_pdev *mon_pdev) 321 { 322 return chain; 323 } 324 #endif 325 void 326 dp_rx_populate_rx_rssi_chain(struct hal_rx_ppdu_info *ppdu_info, 327 struct cdp_rx_indication_ppdu *cdp_rx_ppdu, 328 struct dp_pdev *pdev) 329 { 330 uint8_t chain, bw; 331 uint8_t rssi; 332 uint8_t chain_rf; 333 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 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, mon_pdev); 338 rssi = ppdu_info->rx_status.rssi_chain[chain_rf][bw]; 339 if (rssi != DP_RSSI_INVAL) 340 cdp_rx_ppdu->rssi_chain[chain_rf][bw] = rssi; 341 else 342 cdp_rx_ppdu->rssi_chain[chain_rf][bw] = 0; 343 } 344 } 345 } 346 347 void 348 dp_rx_populate_su_evm_details(struct hal_rx_ppdu_info *ppdu_info, 349 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 350 { 351 uint16_t pilot_evm; 352 uint16_t nss_count; 353 uint16_t pilot_count; 354 355 nss_count = ppdu_info->evm_info.nss_count; 356 pilot_count = ppdu_info->evm_info.pilot_count; 357 358 if ((nss_count * pilot_count) > DP_RX_MAX_SU_EVM_COUNT) { 359 qdf_debug("pilot evm count is more than expected"); 360 return; 361 } 362 cdp_rx_ppdu->evm_info.pilot_count = pilot_count; 363 cdp_rx_ppdu->evm_info.nss_count = nss_count; 364 365 /* Populate evm for pilot_evm = nss_count*pilot_count */ 366 for (pilot_evm = 0; pilot_evm < nss_count * pilot_count; pilot_evm++) { 367 cdp_rx_ppdu->evm_info.pilot_evm[pilot_evm] = 368 ppdu_info->evm_info.pilot_evm[pilot_evm]; 369 } 370 } 371 372 /** 373 * dp_rx_inc_rusize_cnt() - increment pdev stats based on RU size 374 * @pdev: pdev ctx 375 * @rx_user_status: mon rx user status 376 * 377 * Return: bool 378 */ 379 static inline bool 380 dp_rx_inc_rusize_cnt(struct dp_pdev *pdev, 381 struct mon_rx_user_status *rx_user_status) 382 { 383 uint32_t ru_size; 384 bool is_data; 385 386 ru_size = rx_user_status->ofdma_ru_size; 387 388 if (dp_is_subtype_data(rx_user_status->frame_control)) { 389 DP_STATS_INC(pdev, 390 ul_ofdma.data_rx_ru_size[ru_size], 1); 391 is_data = true; 392 } else { 393 DP_STATS_INC(pdev, 394 ul_ofdma.nondata_rx_ru_size[ru_size], 1); 395 is_data = false; 396 } 397 398 return is_data; 399 } 400 401 /** 402 * dp_rx_populate_cdp_indication_ppdu_user() - Populate per user cdp indication 403 * @pdev: pdev ctx 404 * @ppdu_info: ppdu info structure from ppdu ring 405 * @cdp_rx_ppdu: Rx PPDU indication structure 406 * 407 * Return: none 408 */ 409 static void 410 dp_rx_populate_cdp_indication_ppdu_user(struct dp_pdev *pdev, 411 struct hal_rx_ppdu_info *ppdu_info, 412 struct cdp_rx_indication_ppdu 413 *cdp_rx_ppdu) 414 { 415 struct dp_peer *peer; 416 struct dp_soc *soc = pdev->soc; 417 int i; 418 struct mon_rx_user_status *rx_user_status; 419 struct mon_rx_user_info *rx_user_info; 420 struct cdp_rx_stats_ppdu_user *rx_stats_peruser; 421 int ru_size; 422 bool is_data = false; 423 uint32_t num_users; 424 struct dp_mon_ops *mon_ops; 425 uint16_t sw_peer_id; 426 427 num_users = ppdu_info->com_info.num_users; 428 for (i = 0; i < num_users; i++) { 429 if (i >= OFDMA_NUM_USERS) 430 return; 431 432 rx_user_status = &ppdu_info->rx_user_status[i]; 433 rx_user_info = &ppdu_info->rx_user_info[i]; 434 rx_stats_peruser = &cdp_rx_ppdu->user[i]; 435 436 sw_peer_id = rx_user_status->sw_peer_id; 437 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 438 DP_MOD_ID_RX_PPDU_STATS); 439 if (qdf_unlikely(!peer)) { 440 rx_stats_peruser->peer_id = HTT_INVALID_PEER; 441 continue; 442 } 443 rx_stats_peruser->is_bss_peer = peer->bss_peer; 444 445 rx_stats_peruser->first_data_seq_ctrl = 446 rx_user_status->first_data_seq_ctrl; 447 448 rx_stats_peruser->frame_control_info_valid = 449 rx_user_status->frame_control_info_valid; 450 rx_stats_peruser->frame_control = 451 rx_user_status->frame_control; 452 453 rx_stats_peruser->qos_control_info_valid = 454 rx_user_info->qos_control_info_valid; 455 rx_stats_peruser->qos_control = 456 rx_user_info->qos_control; 457 rx_stats_peruser->tcp_msdu_count = 458 rx_user_status->tcp_msdu_count; 459 rx_stats_peruser->udp_msdu_count = 460 rx_user_status->udp_msdu_count; 461 rx_stats_peruser->other_msdu_count = 462 rx_user_status->other_msdu_count; 463 464 rx_stats_peruser->num_msdu = 465 rx_stats_peruser->tcp_msdu_count + 466 rx_stats_peruser->udp_msdu_count + 467 rx_stats_peruser->other_msdu_count; 468 469 rx_stats_peruser->preamble_type = 470 cdp_rx_ppdu->u.preamble; 471 rx_stats_peruser->mpdu_cnt_fcs_ok = 472 rx_user_status->mpdu_cnt_fcs_ok; 473 rx_stats_peruser->mpdu_cnt_fcs_err = 474 rx_user_status->mpdu_cnt_fcs_err; 475 qdf_mem_copy(&rx_stats_peruser->mpdu_fcs_ok_bitmap, 476 &rx_user_status->mpdu_fcs_ok_bitmap, 477 HAL_RX_NUM_WORDS_PER_PPDU_BITMAP * 478 sizeof(rx_user_status->mpdu_fcs_ok_bitmap[0])); 479 rx_stats_peruser->mpdu_ok_byte_count = 480 rx_user_status->mpdu_ok_byte_count; 481 rx_stats_peruser->mpdu_err_byte_count = 482 rx_user_status->mpdu_err_byte_count; 483 484 cdp_rx_ppdu->num_mpdu += rx_user_status->mpdu_cnt_fcs_ok; 485 cdp_rx_ppdu->num_msdu += rx_stats_peruser->num_msdu; 486 rx_stats_peruser->retries = 487 CDP_FC_IS_RETRY_SET(rx_stats_peruser->frame_control) ? 488 rx_stats_peruser->mpdu_cnt_fcs_ok : 0; 489 cdp_rx_ppdu->retries += rx_stats_peruser->retries; 490 491 if (rx_stats_peruser->mpdu_cnt_fcs_ok > 1) 492 rx_stats_peruser->is_ampdu = 1; 493 else 494 rx_stats_peruser->is_ampdu = 0; 495 496 rx_stats_peruser->tid = ppdu_info->rx_status.tid; 497 498 qdf_mem_copy(rx_stats_peruser->mac_addr, 499 peer->mac_addr.raw, QDF_MAC_ADDR_SIZE); 500 rx_stats_peruser->peer_id = peer->peer_id; 501 cdp_rx_ppdu->vdev_id = peer->vdev->vdev_id; 502 rx_stats_peruser->vdev_id = peer->vdev->vdev_id; 503 rx_stats_peruser->mu_ul_info_valid = 0; 504 505 mon_ops = dp_mon_ops_get(soc); 506 if (mon_ops && mon_ops->mon_rx_populate_ppdu_usr_info) 507 mon_ops->mon_rx_populate_ppdu_usr_info(rx_user_status, 508 rx_stats_peruser); 509 510 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 511 if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || 512 cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { 513 if (rx_user_status->mu_ul_info_valid) { 514 rx_stats_peruser->nss = rx_user_status->nss; 515 cdp_rx_ppdu->usr_nss_sum += rx_stats_peruser->nss; 516 rx_stats_peruser->mcs = rx_user_status->mcs; 517 rx_stats_peruser->mu_ul_info_valid = 518 rx_user_status->mu_ul_info_valid; 519 rx_stats_peruser->ofdma_ru_start_index = 520 rx_user_status->ofdma_ru_start_index; 521 rx_stats_peruser->ofdma_ru_width = 522 rx_user_status->ofdma_ru_width; 523 cdp_rx_ppdu->usr_ru_tones_sum += 524 rx_stats_peruser->ofdma_ru_width; 525 rx_stats_peruser->user_index = i; 526 ru_size = rx_user_status->ofdma_ru_size; 527 /* 528 * max RU size will be equal to 529 * HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2 530 */ 531 if (qdf_unlikely(ru_size >= OFDMA_NUM_RU_SIZE)) { 532 dp_err("invalid ru_size %d", 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_mon_eval_avg_rate_filter() - Evaluates rate value against filter 666 * @peer: dp peer 667 * @ratekbps: last packet rate in kbps 668 * @avg_rate: average rate for which new rate is to be evaluated 669 * 670 * Return: true when average need to be evaluated else false 671 */ 672 static inline bool 673 dp_mon_eval_avg_rate_filter(struct dp_peer *peer, uint32_t ratekbps, 674 uint32_t avg_rate) { 675 uint16_t filter_val = 0; 676 677 if (qdf_unlikely(!peer || !peer->vdev || 678 !peer->vdev->pdev->soc->wlan_cfg_ctx)) { 679 return true; 680 } 681 682 filter_val = 683 peer->vdev->pdev->soc->wlan_cfg_ctx->avg_rate_stats_filter_val; 684 685 if (!filter_val || avg_rate < filter_val || ratekbps > filter_val) { 686 return true; 687 } 688 return false; 689 } 690 691 /** 692 * dp_rx_rate_stats_update() - Update per-peer rate statistics 693 * @peer: Datapath peer handle 694 * @ppdu: PPDU Descriptor 695 * @user: user index 696 * 697 * Return: None 698 */ 699 static inline void dp_rx_rate_stats_update(struct dp_peer *peer, 700 struct cdp_rx_indication_ppdu *ppdu, 701 uint32_t user) 702 { 703 uint32_t ratekbps = 0; 704 uint32_t ppdu_rx_rate = 0; 705 uint32_t nss = 0; 706 uint8_t mcs = 0; 707 uint32_t rix; 708 uint16_t ratecode = 0; 709 struct cdp_rx_stats_ppdu_user *ppdu_user = NULL; 710 struct dp_mon_peer *mon_peer = NULL; 711 712 if (!peer || !ppdu) 713 return; 714 715 mon_peer = peer->monitor_peer; 716 ppdu_user = &ppdu->user[user]; 717 718 if (!mon_peer) 719 return; 720 721 if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU) { 722 if (ppdu_user->nss == 0) 723 nss = 0; 724 else 725 nss = ppdu_user->nss - 1; 726 mcs = ppdu_user->mcs; 727 728 mon_peer->stats.rx.nss_info = ppdu_user->nss; 729 mon_peer->stats.rx.mcs_info = ppdu_user->mcs; 730 } else { 731 if (ppdu->u.nss == 0) 732 nss = 0; 733 else 734 nss = ppdu->u.nss - 1; 735 mcs = ppdu->u.mcs; 736 737 mon_peer->stats.rx.nss_info = ppdu->u.nss; 738 mon_peer->stats.rx.mcs_info = ppdu->u.mcs; 739 } 740 741 ratekbps = dp_getrateindex(ppdu->u.gi, 742 mcs, 743 nss, 744 ppdu->u.preamble, 745 ppdu->u.bw, 746 ppdu->punc_bw, 747 &rix, 748 &ratecode); 749 750 if (!ratekbps) { 751 ppdu->rix = 0; 752 ppdu_user->rix = 0; 753 ppdu->rx_ratekbps = 0; 754 ppdu->rx_ratecode = 0; 755 ppdu_user->rx_ratekbps = 0; 756 return; 757 } 758 759 mon_peer->stats.rx.bw_info = ppdu->u.bw; 760 mon_peer->stats.rx.gi_info = ppdu->u.gi; 761 mon_peer->stats.rx.preamble_info = ppdu->u.preamble; 762 763 ppdu->rix = rix; 764 ppdu_user->rix = rix; 765 DP_STATS_UPD(mon_peer, rx.last_rx_rate, ratekbps); 766 if (qdf_likely(dp_mon_eval_avg_rate_filter(peer, ratekbps, 767 mon_peer->stats.rx.avg_rx_rate))) { 768 mon_peer->stats.rx.avg_rx_rate = 769 dp_ath_rate_lpf(mon_peer->stats.rx.avg_rx_rate, 770 ratekbps); 771 } 772 ppdu_rx_rate = dp_ath_rate_out(mon_peer->stats.rx.avg_rx_rate); 773 DP_STATS_UPD(mon_peer, rx.rnd_avg_rx_rate, ppdu_rx_rate); 774 ppdu->rx_ratekbps = ratekbps; 775 ppdu->rx_ratecode = ratecode; 776 ppdu_user->rx_ratekbps = ratekbps; 777 778 if (peer->vdev) 779 peer->vdev->stats.rx.last_rx_rate = ratekbps; 780 } 781 782 #ifdef WLAN_CONFIG_TELEMETRY_AGENT 783 static void 784 dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev, 785 struct dp_peer *peer, 786 struct cdp_rx_indication_ppdu *ppdu_desc, 787 struct cdp_rx_stats_ppdu_user *user) 788 { 789 uint32_t nss_ru_width_sum = 0; 790 struct dp_mon_peer *mon_peer = NULL; 791 uint8_t ac = 0; 792 793 if (!pdev || !ppdu_desc || !user || !peer) 794 return; 795 796 nss_ru_width_sum = ppdu_desc->usr_nss_sum * ppdu_desc->usr_ru_tones_sum; 797 if (!nss_ru_width_sum) 798 nss_ru_width_sum = 1; 799 800 if (ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_OFDMA || 801 ppdu_desc->u.ppdu_type == HAL_RX_TYPE_MU_MIMO) { 802 user->rx_time_us = (ppdu_desc->duration * 803 user->nss * user->ofdma_ru_width) / 804 nss_ru_width_sum; 805 } else { 806 user->rx_time_us = ppdu_desc->duration; 807 } 808 809 mon_peer = peer->monitor_peer; 810 if (qdf_unlikely(!mon_peer)) 811 return; 812 813 ac = TID_TO_WME_AC(user->tid); 814 DP_STATS_INC(mon_peer, airtime_stats.rx_airtime_consumption[ac].consumption, 815 user->rx_time_us); 816 } 817 818 /** 819 * dp_rx_mon_update_user_deter_stats() - Update per-peer deterministic stats 820 * @pdev: Datapath pdev handle 821 * @peer: Datapath peer handle 822 * @ppdu: PPDU Descriptor 823 * @user: Per user RX stats 824 * 825 * Return: None 826 */ 827 static inline 828 void dp_rx_mon_update_user_deter_stats(struct dp_pdev *pdev, 829 struct dp_peer *peer, 830 struct cdp_rx_indication_ppdu *ppdu, 831 struct cdp_rx_stats_ppdu_user *user) 832 { 833 struct dp_mon_peer *mon_peer; 834 uint8_t tid; 835 836 if (!pdev || !ppdu || !user || !peer) 837 return; 838 839 if (!dp_is_subtype_data(ppdu->frame_ctrl)) 840 return; 841 842 if (ppdu->u.ppdu_type != HAL_RX_TYPE_SU) 843 return; 844 845 mon_peer = peer->monitor_peer; 846 if (!mon_peer) 847 return; 848 849 tid = user->tid; 850 if (tid >= CDP_DATA_TID_MAX) 851 return; 852 853 DP_STATS_INC(mon_peer, 854 deter_stats.deter[tid].rx_det.mode_cnt, 855 1); 856 DP_STATS_UPD(mon_peer, 857 deter_stats.deter[tid].rx_det.avg_rate, 858 mon_peer->stats.rx.avg_rx_rate); 859 } 860 861 /** 862 * dp_rx_mon_update_pdev_deter_stats() - Update pdev deterministic stats 863 * @pdev: Datapath pdev handle 864 * @ppdu: PPDU Descriptor 865 * 866 * Return: None 867 */ 868 static inline 869 void dp_rx_mon_update_pdev_deter_stats(struct dp_pdev *pdev, 870 struct cdp_rx_indication_ppdu *ppdu) 871 { 872 if (!dp_is_subtype_data(ppdu->frame_ctrl)) 873 return; 874 875 DP_STATS_INC(pdev, 876 deter_stats.rx_su_cnt, 877 1); 878 } 879 #else 880 static inline void 881 dp_ppdu_desc_user_rx_time_update(struct dp_pdev *pdev, 882 struct dp_peer *peer, 883 struct cdp_rx_indication_ppdu *ppdu_desc, 884 struct cdp_rx_stats_ppdu_user *user) 885 { } 886 887 static inline 888 void dp_rx_mon_update_user_deter_stats(struct dp_pdev *pdev, 889 struct dp_peer *peer, 890 struct cdp_rx_indication_ppdu *ppdu, 891 struct cdp_rx_stats_ppdu_user *user) 892 { } 893 894 static inline 895 void dp_rx_mon_update_pdev_deter_stats(struct dp_pdev *pdev, 896 struct cdp_rx_indication_ppdu *ppdu) 897 { } 898 #endif 899 900 static void dp_rx_stats_update(struct dp_pdev *pdev, 901 struct cdp_rx_indication_ppdu *ppdu) 902 { 903 struct dp_soc *soc = NULL; 904 uint8_t mcs, preamble, ac = 0, nss, ppdu_type, res_mcs = 0; 905 uint32_t num_msdu; 906 struct dp_peer *peer; 907 struct dp_mon_peer *mon_peer; 908 struct cdp_rx_stats_ppdu_user *ppdu_user; 909 uint32_t i; 910 enum cdp_mu_packet_type mu_pkt_type; 911 struct dp_mon_ops *mon_ops; 912 struct dp_mon_pdev *mon_pdev = NULL; 913 uint64_t byte_count; 914 bool is_preamble_valid = true; 915 916 if (qdf_likely(pdev)) 917 soc = pdev->soc; 918 else 919 return; 920 921 if (qdf_likely(!soc) || soc->process_rx_status) 922 return; 923 924 mon_pdev = pdev->monitor_pdev; 925 926 preamble = ppdu->u.preamble; 927 ppdu_type = ppdu->u.ppdu_type; 928 929 for (i = 0; i < ppdu->num_users && i < CDP_MU_MAX_USERS; i++) { 930 peer = NULL; 931 ppdu_user = &ppdu->user[i]; 932 peer = dp_peer_get_ref_by_id(soc, ppdu_user->peer_id, 933 DP_MOD_ID_RX_PPDU_STATS); 934 935 if (qdf_unlikely(!peer)) 936 mon_peer = mon_pdev->invalid_mon_peer; 937 else 938 mon_peer = peer->monitor_peer; 939 940 if (qdf_unlikely(!mon_peer)) { 941 if (peer) 942 dp_peer_unref_delete(peer, 943 DP_MOD_ID_RX_PPDU_STATS); 944 945 continue; 946 } 947 948 if ((preamble == DOT11_A) || (preamble == DOT11_B)) 949 ppdu->u.nss = 1; 950 951 if (ppdu_type == HAL_RX_TYPE_SU) { 952 mcs = ppdu->u.mcs; 953 nss = ppdu->u.nss; 954 } else { 955 mcs = ppdu_user->mcs; 956 nss = ppdu_user->nss; 957 } 958 959 num_msdu = ppdu_user->num_msdu; 960 byte_count = ppdu_user->mpdu_ok_byte_count + 961 ppdu_user->mpdu_err_byte_count; 962 963 DP_STATS_UPD(mon_peer, rx.snr, ppdu->rssi); 964 965 if (qdf_unlikely(mon_peer->stats.rx.avg_snr == CDP_INVALID_SNR)) 966 mon_peer->stats.rx.avg_snr = 967 CDP_SNR_IN(mon_peer->stats.rx.snr); 968 else 969 CDP_SNR_UPDATE_AVG(mon_peer->stats.rx.avg_snr, 970 mon_peer->stats.rx.snr); 971 972 if (ppdu_type == HAL_RX_TYPE_SU) { 973 if (nss) { 974 DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu); 975 DP_STATS_INC(mon_peer, rx.ppdu_nss[nss - 1], 1); 976 } 977 978 DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_ok, 979 ppdu_user->mpdu_cnt_fcs_ok); 980 DP_STATS_INC(mon_peer, rx.mpdu_cnt_fcs_err, 981 ppdu_user->mpdu_cnt_fcs_err); 982 } 983 984 if (ppdu_type >= HAL_RX_TYPE_MU_MIMO && 985 ppdu_type <= HAL_RX_TYPE_MU_OFDMA) { 986 if (ppdu_type == HAL_RX_TYPE_MU_MIMO) 987 mu_pkt_type = TXRX_TYPE_MU_MIMO; 988 else 989 mu_pkt_type = TXRX_TYPE_MU_OFDMA; 990 991 if (qdf_likely(nss)) { 992 DP_STATS_INC(mon_peer, rx.nss[nss - 1], num_msdu); 993 DP_STATS_INC(mon_peer, 994 rx.rx_mu[mu_pkt_type].ppdu_nss[nss - 1], 995 1); 996 } 997 998 DP_STATS_INC(mon_peer, 999 rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_ok, 1000 ppdu_user->mpdu_cnt_fcs_ok); 1001 DP_STATS_INC(mon_peer, 1002 rx.rx_mu[mu_pkt_type].mpdu_cnt_fcs_err, 1003 ppdu_user->mpdu_cnt_fcs_err); 1004 } 1005 1006 DP_STATS_INC(mon_peer, rx.sgi_count[ppdu->u.gi], num_msdu); 1007 DP_STATS_INC(mon_peer, rx.bw[ppdu->u.bw], num_msdu); 1008 DP_STATS_INC(mon_peer, rx.reception_type[ppdu->u.ppdu_type], 1009 num_msdu); 1010 DP_STATS_INC(mon_peer, rx.ppdu_cnt[ppdu->u.ppdu_type], 1); 1011 DP_STATS_INCC(mon_peer, rx.ampdu_cnt, num_msdu, 1012 ppdu_user->is_ampdu); 1013 DP_STATS_INCC(mon_peer, rx.non_ampdu_cnt, num_msdu, 1014 !(ppdu_user->is_ampdu)); 1015 DP_STATS_UPD(mon_peer, rx.rx_rate, mcs); 1016 1017 switch (preamble) { 1018 case DOT11_A: 1019 res_mcs = (mcs < MAX_MCS_11A) ? mcs : (MAX_MCS - 1); 1020 break; 1021 case DOT11_B: 1022 res_mcs = (mcs < MAX_MCS_11B) ? mcs : (MAX_MCS - 1); 1023 break; 1024 case DOT11_N: 1025 res_mcs = (mcs < MAX_MCS_11N) ? mcs : (MAX_MCS - 1); 1026 break; 1027 case DOT11_AC: 1028 res_mcs = (mcs < MAX_MCS_11AC) ? mcs : (MAX_MCS - 1); 1029 break; 1030 case DOT11_AX: 1031 res_mcs = (mcs < MAX_MCS_11AX) ? mcs : (MAX_MCS - 1); 1032 break; 1033 default: 1034 is_preamble_valid = false; 1035 } 1036 1037 DP_STATS_INCC(mon_peer, 1038 rx.pkt_type[preamble].mcs_count[res_mcs], num_msdu, 1039 is_preamble_valid); 1040 1041 if (preamble == DOT11_AX) { 1042 DP_STATS_INCC(mon_peer, 1043 rx.su_ax_ppdu_cnt.mcs_count[res_mcs], 1, 1044 (ppdu_type == HAL_RX_TYPE_SU)); 1045 DP_STATS_INCC(mon_peer, 1046 rx.rx_mu[TXRX_TYPE_MU_OFDMA].ppdu.mcs_count[res_mcs], 1047 1, (ppdu_type == HAL_RX_TYPE_MU_OFDMA)); 1048 DP_STATS_INCC(mon_peer, 1049 rx.rx_mu[TXRX_TYPE_MU_MIMO].ppdu.mcs_count[res_mcs], 1050 1, (ppdu_type == HAL_RX_TYPE_MU_MIMO)); 1051 } 1052 1053 /* 1054 * If invalid TID, it could be a non-qos frame, hence do not 1055 * update any AC counters 1056 */ 1057 ac = TID_TO_WME_AC(ppdu_user->tid); 1058 1059 if (qdf_likely(ppdu->tid != HAL_TID_INVALID)) { 1060 DP_STATS_INC(mon_peer, rx.wme_ac_type[ac], num_msdu); 1061 DP_STATS_INC(mon_peer, rx.wme_ac_type_bytes[ac], 1062 byte_count); 1063 } 1064 1065 DP_STATS_INC(mon_peer, rx.rx_ppdus, 1); 1066 DP_STATS_INC(mon_peer, rx.rx_mpdus, 1067 (ppdu_user->mpdu_cnt_fcs_ok + ppdu_user->mpdu_cnt_fcs_err)); 1068 1069 mon_ops = dp_mon_ops_get(soc); 1070 if (qdf_likely(mon_ops && mon_ops->mon_rx_stats_update)) 1071 mon_ops->mon_rx_stats_update(mon_peer, ppdu, ppdu_user); 1072 1073 if (qdf_unlikely(!peer)) 1074 continue; 1075 1076 dp_peer_stats_notify(pdev, peer); 1077 DP_STATS_UPD(mon_peer, rx.last_snr, ppdu->rssi); 1078 1079 dp_peer_qos_stats_notify(pdev, ppdu_user); 1080 1081 if (dp_is_subtype_data(ppdu->frame_ctrl)) 1082 dp_rx_rate_stats_update(peer, ppdu, i); 1083 1084 dp_send_stats_event(pdev, peer, ppdu_user->peer_id); 1085 1086 dp_ppdu_desc_user_rx_time_update(pdev, peer, ppdu, ppdu_user); 1087 1088 if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) 1089 dp_rx_mon_update_user_deter_stats(pdev, peer, 1090 ppdu, ppdu_user); 1091 1092 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 1093 } 1094 } 1095 1096 void 1097 dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev, 1098 struct hal_rx_ppdu_info *ppdu_info) 1099 { 1100 qdf_nbuf_t ppdu_nbuf; 1101 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 1102 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1103 uint64_t size = 0; 1104 uint8_t num_users = 0; 1105 1106 /* 1107 * Do not allocate if fcs error, 1108 * ast idx invalid / fctl invalid 1109 * 1110 * In CFR RCC mode - PPDU status TLVs of error pkts are also needed 1111 */ 1112 if (qdf_unlikely(ppdu_info->com_info.mpdu_cnt_fcs_ok == 0)) 1113 return; 1114 1115 if (qdf_unlikely(mon_pdev->neighbour_peers_added)) { 1116 if (ppdu_info->nac_info.fc_valid && 1117 ppdu_info->nac_info.to_ds_flag && 1118 ppdu_info->nac_info.mac_addr2_valid) { 1119 struct dp_neighbour_peer *peer = NULL; 1120 uint8_t rssi = ppdu_info->rx_status.rssi_comb; 1121 1122 qdf_spin_lock_bh(&mon_pdev->neighbour_peer_mutex); 1123 if (mon_pdev->neighbour_peers_added) { 1124 TAILQ_FOREACH(peer, &mon_pdev->neighbour_peers_list, 1125 neighbour_peer_list_elem) { 1126 if (!qdf_mem_cmp(&peer->neighbour_peers_macaddr, 1127 &ppdu_info->nac_info.mac_addr2, 1128 QDF_MAC_ADDR_SIZE)) { 1129 peer->rssi = rssi; 1130 break; 1131 } 1132 } 1133 } 1134 qdf_spin_unlock_bh(&mon_pdev->neighbour_peer_mutex); 1135 } else { 1136 dp_info("Neighbour peers RSSI update failed! fc_valid = %d, to_ds_flag = %d and mac_addr2_valid = %d", 1137 ppdu_info->nac_info.fc_valid, 1138 ppdu_info->nac_info.to_ds_flag, 1139 ppdu_info->nac_info.mac_addr2_valid); 1140 } 1141 } 1142 1143 /* need not generate wdi event when mcopy, cfr rcc mode and 1144 * enhanced stats are not enabled 1145 */ 1146 if (qdf_unlikely(!mon_pdev->mcopy_mode && 1147 !mon_pdev->enhanced_stats_en && 1148 !dp_cfr_rcc_mode_status(pdev))) 1149 return; 1150 1151 if (qdf_unlikely(dp_cfr_rcc_mode_status(pdev))) 1152 dp_update_cfr_dbg_stats(pdev, ppdu_info); 1153 1154 if (qdf_unlikely(!ppdu_info->rx_status.frame_control_info_valid || 1155 ppdu_info->rx_status.ast_index == HAL_AST_IDX_INVALID)) { 1156 if (!(mon_pdev->mcopy_mode || 1157 (dp_bb_captured_chan_status(pdev, ppdu_info) == 1158 QDF_STATUS_SUCCESS))) 1159 return; 1160 } 1161 num_users = ppdu_info->com_info.num_users; 1162 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 1163 size = sizeof(struct cdp_rx_indication_ppdu) + 1164 num_users * sizeof(struct cdp_rx_stats_ppdu_user); 1165 ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, 1166 size, 1167 0, 0, FALSE); 1168 if (qdf_likely(ppdu_nbuf)) { 1169 cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)qdf_nbuf_data(ppdu_nbuf); 1170 1171 qdf_mem_zero(cdp_rx_ppdu, size); 1172 dp_rx_mon_populate_cfr_info(pdev, ppdu_info, cdp_rx_ppdu); 1173 dp_rx_populate_cdp_indication_ppdu(pdev, 1174 ppdu_info, cdp_rx_ppdu); 1175 if (!qdf_unlikely(qdf_nbuf_put_tail(ppdu_nbuf, 1176 sizeof(struct cdp_rx_indication_ppdu)))) 1177 return; 1178 1179 if (wlan_cfg_get_sawf_stats_config(pdev->soc->wlan_cfg_ctx)) { 1180 if (cdp_rx_ppdu->u.ppdu_type == HAL_RX_TYPE_SU) 1181 dp_rx_mon_update_pdev_deter_stats(pdev, 1182 cdp_rx_ppdu); 1183 } 1184 1185 dp_rx_stats_update(pdev, cdp_rx_ppdu); 1186 1187 if (qdf_unlikely(cdp_rx_ppdu->peer_id != HTT_INVALID_PEER)) { 1188 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, 1189 soc, ppdu_nbuf, 1190 cdp_rx_ppdu->peer_id, 1191 WDI_NO_VAL, pdev->pdev_id); 1192 } else if (qdf_unlikely(mon_pdev->mcopy_mode || dp_cfr_rcc_mode_status(pdev))) { 1193 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc, 1194 ppdu_nbuf, HTT_INVALID_PEER, 1195 WDI_NO_VAL, pdev->pdev_id); 1196 } else { 1197 qdf_nbuf_free(ppdu_nbuf); 1198 } 1199 } 1200 } 1201 #endif/* QCA_ENHANCED_STATS_SUPPORT */ 1202 1203 #ifdef QCA_UNDECODED_METADATA_SUPPORT 1204 #define RX_PHYERR_MASK_GET64(_val1, _val2) (((uint64_t)(_val2) << 32) | (_val1)) 1205 /** 1206 * dp_rx_populate_cdp_indication_ppdu_undecoded_metadata() - Populate cdp 1207 * rx indication structure 1208 * @pdev: pdev ctx 1209 * @ppdu_info: ppdu info structure from ppdu ring 1210 * @cdp_rx_ppdu: Rx PPDU indication structure 1211 * 1212 * Return: none 1213 */ 1214 static void 1215 dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(struct dp_pdev *pdev, 1216 struct hal_rx_ppdu_info *ppdu_info, 1217 struct cdp_rx_indication_ppdu *cdp_rx_ppdu) 1218 { 1219 uint32_t chain; 1220 1221 cdp_rx_ppdu->phyrx_abort = ppdu_info->rx_status.phyrx_abort; 1222 cdp_rx_ppdu->phyrx_abort_reason = 1223 ppdu_info->rx_status.phyrx_abort_reason; 1224 1225 cdp_rx_ppdu->first_data_seq_ctrl = 1226 ppdu_info->rx_status.first_data_seq_ctrl; 1227 cdp_rx_ppdu->frame_ctrl = 1228 ppdu_info->rx_status.frame_control; 1229 cdp_rx_ppdu->tcp_msdu_count = ppdu_info->rx_status.tcp_msdu_count; 1230 cdp_rx_ppdu->udp_msdu_count = ppdu_info->rx_status.udp_msdu_count; 1231 cdp_rx_ppdu->other_msdu_count = ppdu_info->rx_status.other_msdu_count; 1232 cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type; 1233 cdp_rx_ppdu->num_mpdu = ppdu_info->com_info.mpdu_cnt_fcs_ok; 1234 cdp_rx_ppdu->num_msdu = (cdp_rx_ppdu->tcp_msdu_count + 1235 cdp_rx_ppdu->udp_msdu_count + 1236 cdp_rx_ppdu->other_msdu_count); 1237 1238 cdp_rx_ppdu->retries = CDP_FC_IS_RETRY_SET(cdp_rx_ppdu->frame_ctrl) ? 1239 ppdu_info->com_info.mpdu_cnt_fcs_ok : 0; 1240 1241 if (ppdu_info->com_info.mpdu_cnt_fcs_ok > 1) 1242 cdp_rx_ppdu->is_ampdu = 1; 1243 else 1244 cdp_rx_ppdu->is_ampdu = 0; 1245 cdp_rx_ppdu->tid = ppdu_info->rx_status.tid; 1246 1247 cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id; 1248 cdp_rx_ppdu->length = ppdu_info->rx_status.ppdu_len; 1249 cdp_rx_ppdu->duration = ppdu_info->rx_status.duration; 1250 cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw; 1251 cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss; 1252 cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs; 1253 if (ppdu_info->rx_status.sgi == VHT_SGI_NYSM && 1254 ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) 1255 cdp_rx_ppdu->u.gi = CDP_SGI_0_4_US; 1256 else 1257 cdp_rx_ppdu->u.gi = ppdu_info->rx_status.sgi; 1258 1259 cdp_rx_ppdu->u.ldpc = ppdu_info->rx_status.ldpc; 1260 cdp_rx_ppdu->u.ppdu_type = ppdu_info->rx_status.reception_type; 1261 cdp_rx_ppdu->u.ltf_size = (ppdu_info->rx_status.he_data5 >> 1262 QDF_MON_STATUS_HE_LTF_SIZE_SHIFT) & 0x3; 1263 1264 cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb; 1265 cdp_rx_ppdu->timestamp = ppdu_info->rx_status.tsft; 1266 cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_num; 1267 cdp_rx_ppdu->beamformed = ppdu_info->rx_status.beamformed; 1268 cdp_rx_ppdu->num_bytes = ppdu_info->rx_status.ppdu_len; 1269 cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; 1270 cdp_rx_ppdu->u.ltf_size = ppdu_info->rx_status.ltf_size; 1271 1272 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AC) { 1273 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.is_stbc; 1274 cdp_rx_ppdu->vht_no_txop_ps = 1275 ppdu_info->rx_status.vht_no_txop_ps; 1276 cdp_rx_ppdu->vht_crc = ppdu_info->rx_status.vht_crc; 1277 cdp_rx_ppdu->group_id = ppdu_info->rx_status.vht_flag_values5; 1278 } else if (ppdu_info->rx_status.preamble_type == 1279 HAL_RX_PKT_TYPE_11AX) { 1280 cdp_rx_ppdu->u.stbc = (ppdu_info->rx_status.he_data3 >> 1281 QDF_MON_STATUS_STBC_SHIFT) & 0x1; 1282 cdp_rx_ppdu->u.dcm = (ppdu_info->rx_status.he_data3 >> 1283 QDF_MON_STATUS_DCM_SHIFT) & 0x1; 1284 } else { 1285 cdp_rx_ppdu->u.stbc = ppdu_info->rx_status.ht_stbc; 1286 cdp_rx_ppdu->ht_length = ppdu_info->rx_status.ht_length; 1287 cdp_rx_ppdu->ht_smoothing = ppdu_info->rx_status.smoothing; 1288 cdp_rx_ppdu->ht_not_sounding = 1289 ppdu_info->rx_status.not_sounding; 1290 cdp_rx_ppdu->ht_aggregation = ppdu_info->rx_status.aggregation; 1291 cdp_rx_ppdu->ht_stbc = ppdu_info->rx_status.ht_stbc; 1292 cdp_rx_ppdu->ht_crc = ppdu_info->rx_status.ht_crc; 1293 } 1294 1295 cdp_rx_ppdu->l_sig_length = ppdu_info->rx_status.l_sig_length; 1296 cdp_rx_ppdu->l_sig_a_parity = ppdu_info->rx_status.l_sig_a_parity; 1297 cdp_rx_ppdu->l_sig_a_pkt_type = ppdu_info->rx_status.l_sig_a_pkt_type; 1298 1299 if (ppdu_info->rx_status.preamble_type == HAL_RX_PKT_TYPE_11AX) { 1300 cdp_rx_ppdu->he_crc = ppdu_info->rx_status.he_crc; 1301 cdp_rx_ppdu->bss_color_id = 1302 ppdu_info->rx_status.he_data3 & 0x3F; 1303 cdp_rx_ppdu->beam_change = (ppdu_info->rx_status.he_data3 >> 1304 QDF_MON_STATUS_BEAM_CHANGE_SHIFT) & 0x1; 1305 cdp_rx_ppdu->dl_ul_flag = (ppdu_info->rx_status.he_data3 >> 1306 QDF_MON_STATUS_DL_UL_SHIFT) & 0x1; 1307 cdp_rx_ppdu->ldpc_extra_sym = (ppdu_info->rx_status.he_data3 >> 1308 QDF_MON_STATUS_LDPC_EXTRA_SYMBOL_SHIFT) & 0x1; 1309 cdp_rx_ppdu->special_reuse = 1310 ppdu_info->rx_status.he_data4 & 0xF; 1311 cdp_rx_ppdu->ltf_sym = (ppdu_info->rx_status.he_data5 >> 1312 QDF_MON_STATUS_HE_LTF_SYM_SHIFT) & 0x7; 1313 cdp_rx_ppdu->txbf = (ppdu_info->rx_status.he_data5 >> 1314 QDF_MON_STATUS_TXBF_SHIFT) & 0x1; 1315 cdp_rx_ppdu->pe_disambiguity = (ppdu_info->rx_status.he_data5 >> 1316 QDF_MON_STATUS_PE_DISAMBIGUITY_SHIFT) & 0x1; 1317 cdp_rx_ppdu->pre_fec_pad = (ppdu_info->rx_status.he_data5 >> 1318 QDF_MON_STATUS_PRE_FEC_PAD_SHIFT) & 0x3; 1319 cdp_rx_ppdu->dopplar = (ppdu_info->rx_status.he_data6 >> 1320 QDF_MON_STATUS_DOPPLER_SHIFT) & 0x1; 1321 cdp_rx_ppdu->txop_duration = (ppdu_info->rx_status.he_data6 >> 1322 QDF_MON_STATUS_TXOP_SHIFT) & 0x7F; 1323 cdp_rx_ppdu->sig_b_mcs = ppdu_info->rx_status.he_flags1 & 0x7; 1324 cdp_rx_ppdu->sig_b_dcm = (ppdu_info->rx_status.he_flags1 >> 1325 QDF_MON_STATUS_DCM_FLAG_1_SHIFT) & 0x1; 1326 cdp_rx_ppdu->sig_b_sym = (ppdu_info->rx_status.he_flags2 >> 1327 QDF_MON_STATUS_NUM_SIG_B_SYMBOLS_SHIFT) & 0xF; 1328 cdp_rx_ppdu->sig_b_comp = (ppdu_info->rx_status.he_flags2 >> 1329 QDF_MON_STATUS_SIG_B_COMPRESSION_FLAG_2_SHIFT) & 0x1; 1330 } 1331 dp_rx_populate_rx_rssi_chain(ppdu_info, cdp_rx_ppdu, pdev); 1332 dp_rx_populate_su_evm_details(ppdu_info, cdp_rx_ppdu); 1333 cdp_rx_ppdu->rx_antenna = ppdu_info->rx_status.rx_antenna; 1334 1335 cdp_rx_ppdu->nf = ppdu_info->rx_status.chan_noise_floor; 1336 for (chain = 0; chain < MAX_CHAIN; chain++) 1337 cdp_rx_ppdu->per_chain_rssi[chain] = 1338 ppdu_info->rx_status.rssi[chain]; 1339 1340 cdp_rx_ppdu->is_mcast_bcast = ppdu_info->nac_info.mcast_bcast; 1341 1342 cdp_rx_ppdu->num_users = ppdu_info->com_info.num_users; 1343 1344 dp_rx_populate_cdp_indication_ppdu_user(pdev, ppdu_info, cdp_rx_ppdu); 1345 } 1346 1347 /** 1348 * dp_rx_is_valid_undecoded_frame() - Check unencoded frame received valid 1349 * or not against configured error mask 1350 * @err_mask: configured err mask 1351 * @err_code: Received error reason code for phy abort 1352 * 1353 * Return: true / false 1354 */ 1355 static inline bool 1356 dp_rx_is_valid_undecoded_frame(uint64_t err_mask, uint8_t err_code) 1357 { 1358 if (err_code < CDP_PHYRX_ERR_MAX && 1359 (err_mask & (1ULL << err_code))) 1360 return true; 1361 1362 return false; 1363 } 1364 1365 void 1366 dp_rx_handle_ppdu_undecoded_metadata(struct dp_soc *soc, struct dp_pdev *pdev, 1367 struct hal_rx_ppdu_info *ppdu_info) 1368 { 1369 qdf_nbuf_t ppdu_nbuf; 1370 struct cdp_rx_indication_ppdu *cdp_rx_ppdu; 1371 uint8_t abort_reason = 0; 1372 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1373 uint64_t mask64; 1374 1375 /* Return if RX_ABORT not set */ 1376 if (ppdu_info->rx_status.phyrx_abort == 0) 1377 return; 1378 1379 mask64 = RX_PHYERR_MASK_GET64(mon_pdev->phyrx_error_mask, 1380 mon_pdev->phyrx_error_mask_cont); 1381 abort_reason = ppdu_info->rx_status.phyrx_abort_reason; 1382 1383 if (!dp_rx_is_valid_undecoded_frame(mask64, abort_reason)) 1384 return; 1385 1386 ppdu_nbuf = qdf_nbuf_alloc(soc->osdev, 1387 sizeof(struct cdp_rx_indication_ppdu), 1388 0, 0, FALSE); 1389 if (ppdu_nbuf) { 1390 cdp_rx_ppdu = ((struct cdp_rx_indication_ppdu *) 1391 qdf_nbuf_data(ppdu_nbuf)); 1392 1393 qdf_mem_zero(cdp_rx_ppdu, 1394 sizeof(struct cdp_rx_indication_ppdu)); 1395 dp_rx_populate_cdp_indication_ppdu_undecoded_metadata(pdev, 1396 ppdu_info, cdp_rx_ppdu); 1397 1398 if (!qdf_nbuf_put_tail(ppdu_nbuf, 1399 sizeof(struct cdp_rx_indication_ppdu))) { 1400 return; 1401 } 1402 1403 mon_pdev->rx_mon_stats.rx_undecoded_count++; 1404 mon_pdev->rx_mon_stats.rx_undecoded_error[abort_reason] += 1; 1405 1406 dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC_UNDECODED_METADATA, 1407 soc, ppdu_nbuf, HTT_INVALID_PEER, 1408 WDI_NO_VAL, pdev->pdev_id); 1409 } 1410 } 1411 #endif/* QCA_UNDECODED_METADATA_SUPPORT */ 1412 1413 #ifdef QCA_MCOPY_SUPPORT 1414 QDF_STATUS 1415 dp_rx_handle_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1416 struct hal_rx_ppdu_info *ppdu_info, qdf_nbuf_t nbuf, 1417 uint8_t fcs_ok_mpdu_cnt, bool deliver_frame) 1418 { 1419 uint16_t size = 0; 1420 struct ieee80211_frame *wh; 1421 uint32_t *nbuf_data; 1422 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1423 1424 if (!ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload) 1425 return QDF_STATUS_SUCCESS; 1426 1427 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1428 if (mon_pdev->mcopy_mode == M_COPY) { 1429 if (mon_pdev->m_copy_id.rx_ppdu_id == ppdu_info->com_info.ppdu_id) 1430 return QDF_STATUS_SUCCESS; 1431 } 1432 1433 wh = (struct ieee80211_frame *)(ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload + 4); 1434 1435 size = (ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].first_msdu_payload - 1436 qdf_nbuf_data(nbuf)); 1437 1438 if (qdf_nbuf_pull_head(nbuf, size) == NULL) 1439 return QDF_STATUS_SUCCESS; 1440 1441 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1442 IEEE80211_FC0_TYPE_MGT) || 1443 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == 1444 IEEE80211_FC0_TYPE_CTL)) { 1445 return QDF_STATUS_SUCCESS; 1446 } 1447 1448 nbuf_data = (uint32_t *)qdf_nbuf_data(nbuf); 1449 *nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id; 1450 /* only retain RX MSDU payload in the skb */ 1451 qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - ppdu_info->ppdu_msdu_info[fcs_ok_mpdu_cnt].payload_len); 1452 if (deliver_frame) { 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, HTT_INVALID_PEER, 1456 WDI_NO_VAL, pdev->pdev_id); 1457 } 1458 return QDF_STATUS_E_ALREADY; 1459 } 1460 1461 void 1462 dp_rx_mcopy_handle_last_mpdu(struct dp_soc *soc, struct dp_pdev *pdev, 1463 struct hal_rx_ppdu_info *ppdu_info, 1464 qdf_nbuf_t status_nbuf) 1465 { 1466 QDF_STATUS mcopy_status; 1467 qdf_nbuf_t nbuf_clone = NULL; 1468 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1469 1470 /* If the MPDU end tlv and RX header are received in different buffers, 1471 * process the RX header based on fcs status. 1472 */ 1473 if (mon_pdev->mcopy_status_nbuf) { 1474 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1475 if (mon_pdev->mcopy_mode == M_COPY) { 1476 if (mon_pdev->m_copy_id.rx_ppdu_id == 1477 ppdu_info->com_info.ppdu_id) 1478 goto end1; 1479 } 1480 1481 if (ppdu_info->is_fcs_passed) { 1482 nbuf_clone = qdf_nbuf_clone(mon_pdev->mcopy_status_nbuf); 1483 if (!nbuf_clone) { 1484 QDF_TRACE(QDF_MODULE_ID_TXRX, 1485 QDF_TRACE_LEVEL_ERROR, 1486 "Failed to clone nbuf"); 1487 goto end1; 1488 } 1489 1490 mon_pdev->m_copy_id.rx_ppdu_id = ppdu_info->com_info.ppdu_id; 1491 dp_wdi_event_handler(WDI_EVENT_RX_DATA, soc, 1492 nbuf_clone, 1493 HTT_INVALID_PEER, 1494 WDI_NO_VAL, pdev->pdev_id); 1495 ppdu_info->is_fcs_passed = false; 1496 } 1497 end1: 1498 qdf_nbuf_free(mon_pdev->mcopy_status_nbuf); 1499 mon_pdev->mcopy_status_nbuf = NULL; 1500 } 1501 1502 /* If the MPDU end tlv and RX header are received in different buffers, 1503 * preserve the RX header as the fcs status will be received in MPDU 1504 * end tlv in next buffer. So, cache the buffer to be processd in next 1505 * iteration 1506 */ 1507 if ((ppdu_info->fcs_ok_cnt + ppdu_info->fcs_err_cnt) != 1508 ppdu_info->com_info.mpdu_cnt) { 1509 mon_pdev->mcopy_status_nbuf = qdf_nbuf_clone(status_nbuf); 1510 if (mon_pdev->mcopy_status_nbuf) { 1511 mcopy_status = dp_rx_handle_mcopy_mode( 1512 soc, pdev, 1513 ppdu_info, 1514 mon_pdev->mcopy_status_nbuf, 1515 ppdu_info->fcs_ok_cnt, 1516 false); 1517 if (mcopy_status == QDF_STATUS_SUCCESS) { 1518 qdf_nbuf_free(mon_pdev->mcopy_status_nbuf); 1519 mon_pdev->mcopy_status_nbuf = NULL; 1520 } 1521 } 1522 } 1523 } 1524 1525 void 1526 dp_rx_mcopy_process_ppdu_info(struct dp_pdev *pdev, 1527 struct hal_rx_ppdu_info *ppdu_info, 1528 uint32_t tlv_status) 1529 { 1530 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1531 1532 if (qdf_unlikely(!mon_pdev->mcopy_mode)) 1533 return; 1534 1535 /* The fcs status is received in MPDU end tlv. If the RX header 1536 * and its MPDU end tlv are received in different status buffer then 1537 * to process that header ppdu_info->is_fcs_passed is used. 1538 * If end tlv is received in next status buffer then com_info.mpdu_cnt 1539 * will be 0 at the time of receiving MPDU end tlv and we update the 1540 * is_fcs_passed flag based on ppdu_info->fcs_err. 1541 */ 1542 if (tlv_status != HAL_TLV_STATUS_MPDU_END) 1543 return; 1544 1545 if (!ppdu_info->fcs_err) { 1546 if (ppdu_info->fcs_ok_cnt > 1547 HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER) { 1548 dp_err("No. of MPDUs(%d) per status buff exceeded", 1549 ppdu_info->fcs_ok_cnt); 1550 return; 1551 } 1552 if (ppdu_info->com_info.mpdu_cnt) 1553 ppdu_info->fcs_ok_cnt++; 1554 else 1555 ppdu_info->is_fcs_passed = true; 1556 } else { 1557 if (ppdu_info->com_info.mpdu_cnt) 1558 ppdu_info->fcs_err_cnt++; 1559 else 1560 ppdu_info->is_fcs_passed = false; 1561 } 1562 } 1563 1564 void 1565 dp_rx_process_mcopy_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1566 struct hal_rx_ppdu_info *ppdu_info, 1567 uint32_t tlv_status, 1568 qdf_nbuf_t status_nbuf) 1569 { 1570 QDF_STATUS mcopy_status; 1571 qdf_nbuf_t nbuf_clone = NULL; 1572 uint8_t fcs_ok_mpdu_cnt = 0; 1573 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1574 1575 dp_rx_mcopy_handle_last_mpdu(soc, pdev, ppdu_info, status_nbuf); 1576 1577 if (qdf_unlikely(!ppdu_info->com_info.mpdu_cnt)) 1578 goto end; 1579 1580 if (qdf_unlikely(!ppdu_info->fcs_ok_cnt)) 1581 goto end; 1582 1583 /* For M_COPY mode only one msdu per ppdu is sent to upper layer*/ 1584 if (mon_pdev->mcopy_mode == M_COPY) 1585 ppdu_info->fcs_ok_cnt = 1; 1586 1587 while (fcs_ok_mpdu_cnt < ppdu_info->fcs_ok_cnt) { 1588 nbuf_clone = qdf_nbuf_clone(status_nbuf); 1589 if (!nbuf_clone) { 1590 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1591 "Failed to clone nbuf"); 1592 goto end; 1593 } 1594 1595 mcopy_status = dp_rx_handle_mcopy_mode(soc, pdev, 1596 ppdu_info, 1597 nbuf_clone, 1598 fcs_ok_mpdu_cnt, 1599 true); 1600 1601 if (mcopy_status == QDF_STATUS_SUCCESS) 1602 qdf_nbuf_free(nbuf_clone); 1603 1604 fcs_ok_mpdu_cnt++; 1605 } 1606 end: 1607 qdf_nbuf_free(status_nbuf); 1608 ppdu_info->fcs_ok_cnt = 0; 1609 ppdu_info->fcs_err_cnt = 0; 1610 ppdu_info->com_info.mpdu_cnt = 0; 1611 qdf_mem_zero(&ppdu_info->ppdu_msdu_info, 1612 HAL_RX_MAX_MPDU_H_PER_STATUS_BUFFER 1613 * sizeof(struct hal_rx_msdu_payload_info)); 1614 } 1615 #endif /* QCA_MCOPY_SUPPORT */ 1616 1617 int 1618 dp_rx_handle_smart_mesh_mode(struct dp_soc *soc, struct dp_pdev *pdev, 1619 struct hal_rx_ppdu_info *ppdu_info, 1620 qdf_nbuf_t nbuf) 1621 { 1622 uint8_t size = 0; 1623 struct dp_mon_vdev *mon_vdev; 1624 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1625 1626 if (!mon_pdev->mvdev) { 1627 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1628 "[%s]:[%d] Monitor vdev is NULL !!", 1629 __func__, __LINE__); 1630 return 1; 1631 } 1632 1633 mon_vdev = mon_pdev->mvdev->monitor_vdev; 1634 1635 if (!ppdu_info->msdu_info.first_msdu_payload) { 1636 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1637 "[%s]:[%d] First msdu payload not present", 1638 __func__, __LINE__); 1639 return 1; 1640 } 1641 1642 /* Adding 4 bytes to get to start of 802.11 frame after phy_ppdu_id */ 1643 size = (ppdu_info->msdu_info.first_msdu_payload - 1644 qdf_nbuf_data(nbuf)) + 4; 1645 ppdu_info->msdu_info.first_msdu_payload = NULL; 1646 1647 if (!qdf_nbuf_pull_head(nbuf, size)) { 1648 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 1649 "[%s]:[%d] No header present", 1650 __func__, __LINE__); 1651 return 1; 1652 } 1653 1654 /* Only retain RX MSDU payload in the skb */ 1655 qdf_nbuf_trim_tail(nbuf, qdf_nbuf_len(nbuf) - 1656 ppdu_info->msdu_info.payload_len); 1657 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, nbuf, 1658 qdf_nbuf_headroom(nbuf))) { 1659 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 1660 return 1; 1661 } 1662 1663 mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, 1664 nbuf, NULL); 1665 mon_pdev->ppdu_info.rx_status.monitor_direct_used = 0; 1666 return 0; 1667 } 1668 1669 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 1670 /** 1671 * dp_rx_mon_stitch_mpdu() - Stich MPDU from MSDU 1672 * @mon_pdev: mon_pdev handle 1673 * @tail: 1st MSDU of next MPDU 1674 * 1675 * Return: mpdu buf 1676 */ 1677 static qdf_nbuf_t 1678 dp_rx_mon_stitch_mpdu(struct dp_mon_pdev *mon_pdev, qdf_nbuf_t tail) 1679 { 1680 qdf_nbuf_t head, nbuf, next; 1681 qdf_nbuf_t mpdu_buf = NULL, head_frag_list = NULL; 1682 uint32_t is_first_frag, frag_list_sum_len = 0; 1683 1684 if (!(qdf_nbuf_is_queue_empty(&mon_pdev->msdu_queue))) { 1685 head = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue); 1686 nbuf = head; 1687 mpdu_buf = qdf_nbuf_copy(head); 1688 if (qdf_unlikely(!mpdu_buf)) 1689 goto fail; 1690 1691 is_first_frag = 1; 1692 1693 while (nbuf) { 1694 /* Find the 1st msdu to append in mpdu_buf->frag_list */ 1695 if (nbuf != head && is_first_frag) { 1696 is_first_frag = 0; 1697 head_frag_list = nbuf; 1698 } 1699 1700 /* calculate frag_list length */ 1701 if (!is_first_frag) 1702 frag_list_sum_len += qdf_nbuf_len(nbuf); 1703 1704 if (qdf_nbuf_queue_first(&mon_pdev->msdu_queue) == tail) 1705 break; 1706 1707 next = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue); 1708 qdf_nbuf_set_next(nbuf, next); 1709 nbuf = next; 1710 } 1711 1712 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, 1713 frag_list_sum_len); 1714 qdf_nbuf_free(head); 1715 } 1716 1717 return mpdu_buf; 1718 1719 fail: 1720 dp_err_rl("nbuf copy failed len: %d Q1: %d Q2: %d", qdf_nbuf_len(nbuf), 1721 qdf_nbuf_queue_len(&mon_pdev->msdu_queue), 1722 qdf_nbuf_queue_len(&mon_pdev->mpdu_queue)); 1723 1724 /* Drop all MSDU of MPDU */ 1725 while (nbuf) { 1726 qdf_nbuf_free(nbuf); 1727 if (qdf_nbuf_queue_first(&mon_pdev->msdu_queue) == tail) 1728 break; 1729 nbuf = qdf_nbuf_queue_remove(&mon_pdev->msdu_queue); 1730 } 1731 1732 return NULL; 1733 } 1734 1735 /** 1736 * dp_rx_mon_send_mpdu() - Send MPDU to stack 1737 * @pdev: DP pdev handle 1738 * @mon_pdev: mon_pdev handle 1739 * @mpdu_buf: buffer to submit 1740 * 1741 * Return: None 1742 */ 1743 static inline void 1744 dp_rx_mon_send_mpdu(struct dp_pdev *pdev, struct dp_mon_pdev *mon_pdev, 1745 qdf_nbuf_t mpdu_buf) 1746 { 1747 struct dp_mon_vdev *mon_vdev; 1748 1749 if (qdf_unlikely(!mon_pdev->mvdev)) { 1750 dp_info_rl("Monitor vdev is NULL !!"); 1751 qdf_nbuf_free(mpdu_buf); 1752 return; 1753 } 1754 1755 mon_pdev->ppdu_info.rx_status.ppdu_id = 1756 mon_pdev->ppdu_info.com_info.ppdu_id; 1757 mon_pdev->ppdu_info.rx_status.device_id = pdev->soc->device_id; 1758 mon_pdev->ppdu_info.rx_status.chan_noise_floor = 1759 pdev->chan_noise_floor; 1760 1761 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, mpdu_buf, 1762 qdf_nbuf_headroom(mpdu_buf))) { 1763 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 1764 qdf_nbuf_free(mpdu_buf); 1765 dp_err("radiotap_update_err"); 1766 return; 1767 } 1768 1769 mon_vdev = mon_pdev->mvdev->monitor_vdev; 1770 if (qdf_likely(mon_vdev && mon_vdev->osif_rx_mon)) 1771 mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, 1772 mpdu_buf, NULL); 1773 else 1774 qdf_nbuf_free(mpdu_buf); 1775 } 1776 1777 int dp_rx_handle_local_pkt_capture(struct dp_pdev *pdev, 1778 struct hal_rx_ppdu_info *ppdu_info, 1779 qdf_nbuf_t nbuf, uint32_t tlv_status) 1780 { 1781 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1782 qdf_nbuf_t buf, last; 1783 uint16_t size; 1784 1785 qdf_spin_lock_bh(&mon_pdev->lpc_lock); 1786 switch (tlv_status) { 1787 case HAL_TLV_STATUS_MPDU_START: 1788 { 1789 /* Only Add MPDU to queue if multiple MPDUs present in PPDU */ 1790 if (qdf_unlikely(mon_pdev->first_mpdu)) { 1791 mon_pdev->first_mpdu = false; 1792 break; 1793 } 1794 1795 /* last nbuf of queue points to 1st MSDU of next MPDU */ 1796 last = qdf_nbuf_queue_last(&mon_pdev->msdu_queue); 1797 buf = dp_rx_mon_stitch_mpdu(mon_pdev, last); 1798 /* Add MPDU to queue */ 1799 if (qdf_likely(buf)) 1800 qdf_nbuf_queue_add(&mon_pdev->mpdu_queue, buf); 1801 break; 1802 } 1803 1804 case HAL_TLV_STATUS_HEADER: 1805 { 1806 buf = qdf_nbuf_clone(nbuf); 1807 if (qdf_unlikely(!buf)) 1808 break; 1809 1810 /* Adding 8 bytes to get to start of 802.11 frame 1811 * after phy_ppdu_id 1812 */ 1813 size = (ppdu_info->msdu_info.first_msdu_payload - 1814 qdf_nbuf_data(buf)) + mon_pdev->phy_ppdu_id_size; 1815 1816 if (qdf_unlikely(!qdf_nbuf_pull_head(buf, size))) { 1817 qdf_nbuf_free(buf); 1818 dp_info("No header present"); 1819 break; 1820 } 1821 1822 /* Only retain RX MSDU payload in the skb */ 1823 qdf_nbuf_trim_tail(buf, qdf_nbuf_len(buf) - 1824 ppdu_info->msdu_info.payload_len + 1825 mon_pdev->phy_ppdu_id_size); 1826 1827 /* Add MSDU to Queue */ 1828 qdf_nbuf_queue_add(&mon_pdev->msdu_queue, buf); 1829 break; 1830 } 1831 1832 case HAL_TLV_STATUS_PPDU_DONE: 1833 { 1834 while ((buf = qdf_nbuf_queue_remove(&mon_pdev->mpdu_queue))) 1835 dp_rx_mon_send_mpdu(pdev, mon_pdev, buf); 1836 1837 /* Stich and send Last MPDU of PPDU */ 1838 buf = dp_rx_mon_stitch_mpdu(mon_pdev, NULL); 1839 if (buf) 1840 dp_rx_mon_send_mpdu(pdev, mon_pdev, buf); 1841 1842 mon_pdev->first_mpdu = true; 1843 break; 1844 } 1845 1846 default: 1847 break; 1848 } 1849 1850 qdf_spin_unlock_bh(&mon_pdev->lpc_lock); 1851 1852 return 0; 1853 } 1854 #endif 1855 1856 qdf_nbuf_t 1857 dp_rx_nbuf_prepare(struct dp_soc *soc, struct dp_pdev *pdev) 1858 { 1859 uint8_t *buf; 1860 int32_t nbuf_retry_count; 1861 QDF_STATUS ret; 1862 qdf_nbuf_t nbuf = NULL; 1863 1864 for (nbuf_retry_count = 0; nbuf_retry_count < 1865 QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD; 1866 nbuf_retry_count++) { 1867 /* Allocate a new skb using alloc_skb */ 1868 nbuf = qdf_nbuf_alloc_no_recycler(RX_MON_STATUS_BUF_SIZE, 1869 RX_MON_STATUS_BUF_RESERVATION, 1870 RX_DATA_BUFFER_ALIGNMENT); 1871 1872 if (!nbuf) { 1873 DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1); 1874 continue; 1875 } 1876 1877 buf = qdf_nbuf_data(nbuf); 1878 1879 memset(buf, 0, RX_MON_STATUS_BUF_SIZE); 1880 1881 ret = qdf_nbuf_map_nbytes_single(soc->osdev, nbuf, 1882 QDF_DMA_FROM_DEVICE, 1883 RX_MON_STATUS_BUF_SIZE); 1884 1885 /* nbuf map failed */ 1886 if (qdf_unlikely(QDF_IS_STATUS_ERROR(ret))) { 1887 qdf_nbuf_free(nbuf); 1888 DP_STATS_INC(pdev, replenish.map_err, 1); 1889 continue; 1890 } 1891 /* qdf_nbuf alloc and map succeeded */ 1892 break; 1893 } 1894 1895 /* qdf_nbuf still alloc or map failed */ 1896 if (qdf_unlikely(nbuf_retry_count >= 1897 QDF_NBUF_ALLOC_MAP_RETRY_THRESHOLD)) 1898 return NULL; 1899 1900 return nbuf; 1901 } 1902 1903 #ifndef DISABLE_MON_CONFIG 1904 uint32_t 1905 dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, 1906 uint32_t mac_id, uint32_t quota) 1907 { 1908 struct dp_mon_soc *mon_soc = soc->monitor_soc; 1909 1910 if (mon_soc && mon_soc->mon_rx_process) 1911 return mon_soc->mon_rx_process(soc, int_ctx, 1912 mac_id, quota); 1913 return 0; 1914 } 1915 #else 1916 uint32_t 1917 dp_mon_process(struct dp_soc *soc, struct dp_intr *int_ctx, 1918 uint32_t mac_id, uint32_t quota) 1919 { 1920 return 0; 1921 } 1922 #endif 1923 1924 /** 1925 * dp_send_mgmt_packet_to_stack(): send indicataion to upper layers 1926 * 1927 * @soc: soc handle 1928 * @nbuf: Mgmt packet 1929 * @pdev: pdev handle 1930 * 1931 * Return: QDF_STATUS_SUCCESS on success 1932 * QDF_STATUS_E_INVAL in error 1933 */ 1934 #ifdef QCA_MCOPY_SUPPORT 1935 static inline QDF_STATUS 1936 dp_send_mgmt_packet_to_stack(struct dp_soc *soc, 1937 qdf_nbuf_t nbuf, 1938 struct dp_pdev *pdev) 1939 { 1940 uint32_t *nbuf_data; 1941 struct ieee80211_frame *wh; 1942 qdf_frag_t addr; 1943 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1944 1945 if (!nbuf) 1946 return QDF_STATUS_E_INVAL; 1947 1948 /* Get addr pointing to80211 header */ 1949 addr = dp_rx_mon_get_nbuf_80211_hdr(nbuf); 1950 if (qdf_unlikely(!addr)) { 1951 qdf_nbuf_free(nbuf); 1952 return QDF_STATUS_E_INVAL; 1953 } 1954 1955 /*check if this is not a mgmt packet*/ 1956 wh = (struct ieee80211_frame *)addr; 1957 if (((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != 1958 IEEE80211_FC0_TYPE_MGT) && 1959 ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) != 1960 IEEE80211_FC0_TYPE_CTL)) { 1961 qdf_nbuf_free(nbuf); 1962 return QDF_STATUS_E_INVAL; 1963 } 1964 nbuf_data = (uint32_t *)qdf_nbuf_push_head(nbuf, 4); 1965 if (!nbuf_data) { 1966 QDF_TRACE(QDF_MODULE_ID_DP, 1967 QDF_TRACE_LEVEL_ERROR, 1968 FL("No headroom")); 1969 qdf_nbuf_free(nbuf); 1970 return QDF_STATUS_E_INVAL; 1971 } 1972 *nbuf_data = mon_pdev->ppdu_info.com_info.ppdu_id; 1973 1974 dp_wdi_event_handler(WDI_EVENT_RX_MGMT_CTRL, soc, nbuf, 1975 HTT_INVALID_PEER, 1976 WDI_NO_VAL, pdev->pdev_id); 1977 return QDF_STATUS_SUCCESS; 1978 } 1979 #else 1980 static inline QDF_STATUS 1981 dp_send_mgmt_packet_to_stack(struct dp_soc *soc, 1982 qdf_nbuf_t nbuf, 1983 struct dp_pdev *pdev) 1984 { 1985 return QDF_STATUS_SUCCESS; 1986 } 1987 #endif /* QCA_MCOPY_SUPPORT */ 1988 1989 QDF_STATUS dp_rx_mon_process_dest_pktlog(struct dp_soc *soc, 1990 uint32_t mac_id, 1991 qdf_nbuf_t mpdu) 1992 { 1993 uint32_t event, msdu_timestamp = 0; 1994 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1995 void *data; 1996 struct ieee80211_frame *wh; 1997 uint8_t type, subtype; 1998 struct dp_mon_pdev *mon_pdev; 1999 2000 if (!pdev) 2001 return QDF_STATUS_E_INVAL; 2002 2003 mon_pdev = pdev->monitor_pdev; 2004 2005 if (mon_pdev->rx_pktlog_cbf) { 2006 if (qdf_nbuf_get_nr_frags(mpdu)) 2007 data = qdf_nbuf_get_frag_addr(mpdu, 0); 2008 else 2009 data = qdf_nbuf_data(mpdu); 2010 2011 /* CBF logging required, doesn't matter if it is a full mode 2012 * or lite mode. 2013 * Need to look for mpdu with: 2014 * TYPE = ACTION, SUBTYPE = NO ACK in the header 2015 */ 2016 event = WDI_EVENT_RX_CBF; 2017 2018 wh = (struct ieee80211_frame *)data; 2019 type = (wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK; 2020 subtype = (wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; 2021 if (type == IEEE80211_FC0_TYPE_MGT && 2022 subtype == IEEE80211_FCO_SUBTYPE_ACTION_NO_ACK) { 2023 msdu_timestamp = mon_pdev->ppdu_info.rx_status.tsft; 2024 dp_rx_populate_cbf_hdr(soc, 2025 mac_id, event, 2026 mpdu, 2027 msdu_timestamp); 2028 } 2029 } 2030 return QDF_STATUS_SUCCESS; 2031 } 2032 2033 QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id, 2034 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu) 2035 { 2036 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 2037 struct cdp_mon_status *rs; 2038 qdf_nbuf_t mon_skb, skb_next; 2039 qdf_nbuf_t mon_mpdu = NULL; 2040 struct dp_mon_vdev *mon_vdev; 2041 struct dp_mon_pdev *mon_pdev; 2042 2043 if (!pdev) 2044 goto mon_deliver_fail; 2045 2046 mon_pdev = pdev->monitor_pdev; 2047 rs = &mon_pdev->rx_mon_recv_status; 2048 2049 if (!mon_pdev->mvdev && !mon_pdev->mcopy_mode && 2050 !mon_pdev->rx_pktlog_cbf) 2051 goto mon_deliver_fail; 2052 2053 /* restitch mon MPDU for delivery via monitor interface */ 2054 mon_mpdu = dp_rx_mon_restitch_mpdu(soc, mac_id, head_msdu, 2055 tail_msdu, rs); 2056 2057 /* If MPDU restitch fails, free buffers*/ 2058 if (!mon_mpdu) { 2059 dp_info("MPDU restitch failed, free buffers"); 2060 goto mon_deliver_fail; 2061 } 2062 2063 dp_rx_mon_process_dest_pktlog(soc, mac_id, mon_mpdu); 2064 2065 /* monitor vap cannot be present when mcopy is enabled 2066 * hence same skb can be consumed 2067 */ 2068 if (mon_pdev->mcopy_mode) 2069 return dp_send_mgmt_packet_to_stack(soc, mon_mpdu, pdev); 2070 2071 if (mon_pdev->mvdev && 2072 mon_pdev->mvdev->osif_vdev && 2073 mon_pdev->mvdev->monitor_vdev && 2074 mon_pdev->mvdev->monitor_vdev->osif_rx_mon) { 2075 mon_vdev = mon_pdev->mvdev->monitor_vdev; 2076 2077 mon_pdev->ppdu_info.rx_status.ppdu_id = 2078 mon_pdev->ppdu_info.com_info.ppdu_id; 2079 mon_pdev->ppdu_info.rx_status.device_id = soc->device_id; 2080 mon_pdev->ppdu_info.rx_status.chan_noise_floor = 2081 pdev->chan_noise_floor; 2082 dp_handle_tx_capture(soc, pdev, mon_mpdu); 2083 2084 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, 2085 mon_mpdu, 2086 qdf_nbuf_headroom(mon_mpdu))) { 2087 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 2088 qdf_nbuf_free(mon_mpdu); 2089 return QDF_STATUS_E_INVAL; 2090 } 2091 2092 dp_rx_mon_update_pf_tag_to_buf_headroom(soc, mon_mpdu); 2093 mon_vdev->osif_rx_mon(mon_pdev->mvdev->osif_vdev, 2094 mon_mpdu, 2095 &mon_pdev->ppdu_info.rx_status); 2096 } else { 2097 dp_rx_mon_dest_debug("%pK: mon_mpdu=%pK monitor_vdev %pK osif_vdev %pK" 2098 , soc, mon_mpdu, mon_pdev->mvdev, 2099 (mon_pdev->mvdev ? mon_pdev->mvdev->osif_vdev 2100 : NULL)); 2101 qdf_nbuf_free(mon_mpdu); 2102 return QDF_STATUS_E_INVAL; 2103 } 2104 2105 return QDF_STATUS_SUCCESS; 2106 2107 mon_deliver_fail: 2108 mon_skb = head_msdu; 2109 while (mon_skb) { 2110 skb_next = qdf_nbuf_next(mon_skb); 2111 2112 dp_rx_mon_dest_debug("%pK: [%s][%d] mon_skb=%pK len %u", 2113 soc, __func__, __LINE__, mon_skb, mon_skb->len); 2114 2115 qdf_nbuf_free(mon_skb); 2116 mon_skb = skb_next; 2117 } 2118 return QDF_STATUS_E_INVAL; 2119 } 2120 2121 QDF_STATUS dp_rx_mon_deliver_non_std(struct dp_soc *soc, 2122 uint32_t mac_id) 2123 { 2124 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 2125 ol_txrx_rx_mon_fp osif_rx_mon; 2126 qdf_nbuf_t dummy_msdu; 2127 struct dp_mon_pdev *mon_pdev; 2128 struct dp_mon_vdev *mon_vdev; 2129 2130 /* Sanity checking */ 2131 if (!pdev || !pdev->monitor_pdev) 2132 goto mon_deliver_non_std_fail; 2133 2134 mon_pdev = pdev->monitor_pdev; 2135 2136 if (!mon_pdev->mvdev || !mon_pdev->mvdev || 2137 !mon_pdev->mvdev->monitor_vdev || 2138 !mon_pdev->mvdev->monitor_vdev->osif_rx_mon) 2139 goto mon_deliver_non_std_fail; 2140 2141 mon_vdev = mon_pdev->mvdev->monitor_vdev; 2142 /* Generate a dummy skb_buff */ 2143 osif_rx_mon = mon_vdev->osif_rx_mon; 2144 dummy_msdu = qdf_nbuf_alloc(soc->osdev, MAX_MONITOR_HEADER, 2145 MAX_MONITOR_HEADER, 4, FALSE); 2146 if (!dummy_msdu) 2147 goto allocate_dummy_msdu_fail; 2148 2149 qdf_nbuf_set_pktlen(dummy_msdu, 0); 2150 qdf_nbuf_set_next(dummy_msdu, NULL); 2151 2152 mon_pdev->ppdu_info.rx_status.ppdu_id = 2153 mon_pdev->ppdu_info.com_info.ppdu_id; 2154 2155 /* Apply the radio header to this dummy skb */ 2156 if (!qdf_nbuf_update_radiotap(&mon_pdev->ppdu_info.rx_status, dummy_msdu, 2157 qdf_nbuf_headroom(dummy_msdu))) { 2158 DP_STATS_INC(pdev, dropped.mon_radiotap_update_err, 1); 2159 qdf_nbuf_free(dummy_msdu); 2160 goto mon_deliver_non_std_fail; 2161 } 2162 2163 /* deliver to the user layer application */ 2164 osif_rx_mon(mon_pdev->mvdev->osif_vdev, 2165 dummy_msdu, NULL); 2166 2167 return QDF_STATUS_SUCCESS; 2168 2169 allocate_dummy_msdu_fail: 2170 dp_rx_mon_dest_debug("%pK: mon_skb=%pK ", 2171 soc, dummy_msdu); 2172 2173 mon_deliver_non_std_fail: 2174 return QDF_STATUS_E_INVAL; 2175 } 2176 2177 /** 2178 * dp_rx_process_peer_based_pktlog() - Process Rx pktlog if peer based 2179 * filtering enabled 2180 * @soc: core txrx main context 2181 * @ppdu_info: Structure for rx ppdu info 2182 * @status_nbuf: Qdf nbuf abstraction for linux skb 2183 * @pdev_id: mac_id/pdev_id correspondinggly for MCL and WIN 2184 * 2185 * Return: none 2186 */ 2187 void 2188 dp_rx_process_peer_based_pktlog(struct dp_soc *soc, 2189 struct hal_rx_ppdu_info *ppdu_info, 2190 qdf_nbuf_t status_nbuf, uint32_t pdev_id) 2191 { 2192 struct dp_peer *peer; 2193 struct mon_rx_user_status *rx_user_status; 2194 uint32_t num_users = ppdu_info->com_info.num_users; 2195 uint16_t sw_peer_id; 2196 2197 /* Sanity check for num_users */ 2198 if (!num_users) 2199 return; 2200 2201 qdf_assert_always(num_users <= CDP_MU_MAX_USERS); 2202 rx_user_status = &ppdu_info->rx_user_status[num_users - 1]; 2203 2204 sw_peer_id = rx_user_status->sw_peer_id; 2205 2206 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 2207 DP_MOD_ID_RX_PPDU_STATS); 2208 2209 if (!peer) 2210 return; 2211 2212 if ((peer->peer_id != HTT_INVALID_PEER) && (peer->monitor_peer) && 2213 (peer->monitor_peer->peer_based_pktlog_filter)) { 2214 dp_wdi_event_handler( 2215 WDI_EVENT_RX_DESC, soc, 2216 status_nbuf, 2217 peer->peer_id, 2218 WDI_NO_VAL, pdev_id); 2219 } 2220 dp_peer_unref_delete(peer, 2221 DP_MOD_ID_RX_PPDU_STATS); 2222 } 2223 2224 uint32_t 2225 dp_mon_rx_add_tlv(uint8_t id, uint16_t len, void *value, qdf_nbuf_t mpdu_nbuf) 2226 { 2227 uint8_t *dest = NULL; 2228 uint32_t num_bytes_pushed = 0; 2229 2230 /* Add tlv id field */ 2231 dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint8_t)); 2232 if (qdf_likely(dest)) { 2233 *((uint8_t *)dest) = id; 2234 num_bytes_pushed += sizeof(uint8_t); 2235 } 2236 2237 /* Add tlv len field */ 2238 dest = qdf_nbuf_push_head(mpdu_nbuf, sizeof(uint16_t)); 2239 if (qdf_likely(dest)) { 2240 *((uint16_t *)dest) = len; 2241 num_bytes_pushed += sizeof(uint16_t); 2242 } 2243 2244 /* Add tlv value field */ 2245 dest = qdf_nbuf_push_head(mpdu_nbuf, len); 2246 if (qdf_likely(dest)) { 2247 qdf_mem_copy(dest, value, len); 2248 num_bytes_pushed += len; 2249 } 2250 2251 return num_bytes_pushed; 2252 } 2253 2254 void 2255 dp_mon_rx_stats_update_rssi_dbm_params(struct dp_mon_pdev *mon_pdev, 2256 struct hal_rx_ppdu_info *ppdu_info) 2257 { 2258 ppdu_info->rx_status.rssi_offset = mon_pdev->rssi_offsets.rssi_offset; 2259 ppdu_info->rx_status.rssi_dbm_conv_support = 2260 mon_pdev->rssi_dbm_conv_support; 2261 ppdu_info->rx_status.chan_noise_floor = 2262 mon_pdev->rssi_offsets.rssi_offset; 2263 } 2264 2265 #ifdef WLAN_SUPPORT_CTRL_FRAME_STATS 2266 void dp_rx_mon_update_user_ctrl_frame_stats(struct dp_pdev *pdev, 2267 struct hal_rx_ppdu_info *ppdu_info) 2268 { 2269 struct dp_peer *peer; 2270 struct dp_mon_peer *mon_peer; 2271 struct dp_soc *soc = pdev->soc; 2272 uint16_t fc, sw_peer_id; 2273 uint8_t i; 2274 2275 if (qdf_unlikely(!ppdu_info)) 2276 return; 2277 2278 fc = ppdu_info->nac_info.frame_control; 2279 if (qdf_likely((qdf_cpu_to_le16(fc) & QDF_IEEE80211_FC0_TYPE_MASK) != 2280 QDF_IEEE80211_FC0_TYPE_CTL)) 2281 return; 2282 2283 for (i = 0; i < ppdu_info->com_info.num_users; i++) { 2284 sw_peer_id = ppdu_info->rx_user_status[i].sw_peer_id; 2285 peer = dp_peer_get_ref_by_id(soc, sw_peer_id, 2286 DP_MOD_ID_RX_PPDU_STATS); 2287 if (qdf_unlikely(!peer)) 2288 continue; 2289 mon_peer = peer->monitor_peer; 2290 if (qdf_unlikely(!mon_peer)) { 2291 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 2292 continue; 2293 } 2294 DP_STATS_INCC(mon_peer, rx.ndpa_cnt, 1, 2295 ppdu_info->ctrl_frm_info[i].ndpa); 2296 DP_STATS_INCC(mon_peer, rx.bar_cnt, 1, 2297 ppdu_info->ctrl_frm_info[i].bar); 2298 2299 dp_peer_unref_delete(peer, DP_MOD_ID_RX_PPDU_STATS); 2300 } 2301 } 2302 #endif /* WLAN_SUPPORT_CTRL_FRAME_STATS */ 2303