1 /* 2 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include "hal_hw_headers.h" 18 #include "dp_types.h" 19 #include "dp_rx.h" 20 #include "dp_peer.h" 21 #include "hal_rx.h" 22 #include "hal_api.h" 23 #include "qdf_trace.h" 24 #include "qdf_nbuf.h" 25 #include "hal_api_mon.h" 26 #include "dp_internal.h" 27 #include "qdf_mem.h" /* qdf_mem_malloc,free */ 28 #include "dp_htt.h" 29 #include "dp_mon.h" 30 #include "dp_rx_mon.h" 31 #include "htt.h" 32 #include <dp_mon_1.0.h> 33 #include <dp_rx_mon_1.0.h> 34 35 #ifdef FEATURE_PERPKT_INFO 36 #include "dp_ratetable.h" 37 #endif 38 39 static inline 40 QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, 41 uint32_t mac_id, 42 struct dp_srng *dp_rxdma_srng, 43 struct rx_desc_pool *rx_desc_pool, 44 uint32_t num_req_buffers, 45 union dp_rx_desc_list_elem_t **desc_list, 46 union dp_rx_desc_list_elem_t **tail, 47 uint8_t owner); 48 49 /** 50 * dp_rx_mon_handle_status_buf_done() - Handle status buf DMA not done 51 * 52 * @pdev: DP pdev handle 53 * @mon_status_srng: Monitor status SRNG 54 * 55 * As per MAC team's suggestion, If HP + 2 entry's DMA done is set, 56 * skip HP + 1 entry and start processing in next interrupt. 57 * If HP + 2 entry's DMA done is not set, poll onto HP + 1 entry 58 * for it's DMA done TLV to be set. 59 * 60 * Return: enum dp_mon_reap_status 61 */ 62 enum dp_mon_reap_status 63 dp_rx_mon_handle_status_buf_done(struct dp_pdev *pdev, 64 void *mon_status_srng) 65 { 66 struct dp_soc *soc = pdev->soc; 67 hal_soc_handle_t hal_soc; 68 void *ring_entry; 69 struct hal_buf_info hbi; 70 qdf_nbuf_t status_nbuf; 71 struct dp_rx_desc *rx_desc; 72 void *rx_tlv; 73 QDF_STATUS buf_status; 74 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 75 76 hal_soc = soc->hal_soc; 77 78 ring_entry = hal_srng_src_peek_n_get_next_next(hal_soc, 79 mon_status_srng); 80 if (!ring_entry) { 81 dp_rx_mon_status_debug("%pK: Monitor status ring entry is NULL for SRNG: %pK", 82 soc, mon_status_srng); 83 return DP_MON_STATUS_NO_DMA; 84 } 85 86 hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)ring_entry, 87 &hbi); 88 rx_desc = dp_rx_cookie_2_va_mon_status(soc, hbi.sw_cookie); 89 90 qdf_assert_always(rx_desc); 91 92 status_nbuf = rx_desc->nbuf; 93 94 qdf_nbuf_sync_for_cpu(soc->osdev, status_nbuf, 95 QDF_DMA_FROM_DEVICE); 96 97 rx_tlv = qdf_nbuf_data(status_nbuf); 98 buf_status = hal_get_rx_status_done(rx_tlv); 99 100 /* If status buffer DMA is not done, 101 * 1. As per MAC team's suggestion, If HP + 2 entry's DMA done is set, 102 * replenish HP + 1 entry and start processing in next interrupt. 103 * 2. If HP + 2 entry's DMA done is not set 104 * hold on to mon destination ring. 105 */ 106 if (buf_status != QDF_STATUS_SUCCESS) { 107 dp_err_rl("Monitor status ring: DMA is not done " 108 "for nbuf: %pK", status_nbuf); 109 mon_pdev->rx_mon_stats.tlv_tag_status_err++; 110 return DP_MON_STATUS_REPLENISH; 111 } 112 113 mon_pdev->rx_mon_stats.status_buf_done_war++; 114 115 return DP_MON_STATUS_REPLENISH; 116 } 117 118 #ifdef WLAN_RX_PKT_CAPTURE_ENH 119 #include "dp_rx_mon_feature.h" 120 #else 121 static QDF_STATUS 122 dp_rx_handle_enh_capture(struct dp_soc *soc, struct dp_pdev *pdev, 123 struct hal_rx_ppdu_info *ppdu_info) 124 { 125 return QDF_STATUS_SUCCESS; 126 } 127 128 static void 129 dp_rx_mon_enh_capture_process(struct dp_pdev *pdev, uint32_t tlv_status, 130 qdf_nbuf_t status_nbuf, 131 struct hal_rx_ppdu_info *ppdu_info, 132 bool *nbuf_used) 133 { 134 } 135 #endif 136 137 #ifdef WLAN_TX_PKT_CAPTURE_ENH 138 #include "dp_rx_mon_feature.h" 139 #else 140 static QDF_STATUS 141 dp_send_ack_frame_to_stack(struct dp_soc *soc, 142 struct dp_pdev *pdev, 143 struct hal_rx_ppdu_info *ppdu_info) 144 { 145 return QDF_STATUS_SUCCESS; 146 } 147 #endif 148 149 #if defined(HTT_UL_OFDMA_USER_INFO_V0_W0_VALID_M) 150 static inline void 151 dp_rx_ul_ofdma_ru_size_to_width( 152 uint32_t ru_size, 153 uint32_t *ru_width) 154 { 155 uint32_t width; 156 157 width = 0; 158 switch (ru_size) { 159 case HTT_UL_OFDMA_V0_RU_SIZE_RU_26: 160 width = 1; 161 break; 162 case HTT_UL_OFDMA_V0_RU_SIZE_RU_52: 163 width = 2; 164 break; 165 case HTT_UL_OFDMA_V0_RU_SIZE_RU_106: 166 width = 4; 167 break; 168 case HTT_UL_OFDMA_V0_RU_SIZE_RU_242: 169 width = 9; 170 break; 171 case HTT_UL_OFDMA_V0_RU_SIZE_RU_484: 172 width = 18; 173 break; 174 case HTT_UL_OFDMA_V0_RU_SIZE_RU_996: 175 width = 37; 176 break; 177 case HTT_UL_OFDMA_V0_RU_SIZE_RU_996x2: 178 width = 74; 179 break; 180 default: 181 dp_rx_mon_status_err("RU size to width convert err"); 182 break; 183 } 184 *ru_width = width; 185 } 186 187 static inline void 188 dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) 189 { 190 struct mon_rx_user_status *mon_rx_user_status; 191 uint32_t num_users; 192 uint32_t i; 193 uint32_t mu_ul_user_v0_word0; 194 uint32_t mu_ul_user_v0_word1; 195 uint32_t ru_width; 196 uint32_t ru_size; 197 198 if (!(ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_OFDMA || 199 ppdu_info->rx_status.reception_type == HAL_RX_TYPE_MU_MIMO)) 200 return; 201 202 num_users = ppdu_info->com_info.num_users; 203 if (num_users > HAL_MAX_UL_MU_USERS) 204 num_users = HAL_MAX_UL_MU_USERS; 205 for (i = 0; i < num_users; i++) { 206 mon_rx_user_status = &ppdu_info->rx_user_status[i]; 207 mu_ul_user_v0_word0 = 208 mon_rx_user_status->mu_ul_user_v0_word0; 209 mu_ul_user_v0_word1 = 210 mon_rx_user_status->mu_ul_user_v0_word1; 211 212 if (HTT_UL_OFDMA_USER_INFO_V0_W0_VALID_GET( 213 mu_ul_user_v0_word0) && 214 !HTT_UL_OFDMA_USER_INFO_V0_W0_VER_GET( 215 mu_ul_user_v0_word0)) { 216 mon_rx_user_status->mcs = 217 HTT_UL_OFDMA_USER_INFO_V0_W1_MCS_GET( 218 mu_ul_user_v0_word1); 219 mon_rx_user_status->nss = 220 HTT_UL_OFDMA_USER_INFO_V0_W1_NSS_GET( 221 mu_ul_user_v0_word1) + 1; 222 223 mon_rx_user_status->mu_ul_info_valid = 1; 224 mon_rx_user_status->ofdma_ru_start_index = 225 HTT_UL_OFDMA_USER_INFO_V0_W1_RU_START_GET( 226 mu_ul_user_v0_word1); 227 228 ru_size = 229 HTT_UL_OFDMA_USER_INFO_V0_W1_RU_SIZE_GET( 230 mu_ul_user_v0_word1); 231 dp_rx_ul_ofdma_ru_size_to_width(ru_size, &ru_width); 232 mon_rx_user_status->ofdma_ru_width = ru_width; 233 mon_rx_user_status->ofdma_ru_size = ru_size; 234 } 235 } 236 } 237 #else 238 static inline void 239 dp_rx_mon_handle_mu_ul_info(struct hal_rx_ppdu_info *ppdu_info) 240 { 241 } 242 #endif 243 244 #ifdef QCA_UNDECODED_METADATA_SUPPORT 245 static inline bool 246 dp_rx_mon_check_phyrx_abort(struct dp_pdev *pdev, 247 struct hal_rx_ppdu_info *ppdu_info) 248 { 249 return (pdev->monitor_pdev->undecoded_metadata_capture && 250 ppdu_info->rx_status.phyrx_abort); 251 } 252 253 static inline void 254 dp_rx_mon_handle_ppdu_undecoded_metadata(struct dp_soc *soc, 255 struct dp_pdev *pdev, 256 struct hal_rx_ppdu_info *ppdu_info) 257 { 258 if (pdev->monitor_pdev->undecoded_metadata_capture) 259 dp_rx_handle_ppdu_undecoded_metadata(soc, pdev, ppdu_info); 260 261 pdev->monitor_pdev->mon_ppdu_status = DP_PPDU_STATUS_START; 262 } 263 #else 264 static inline bool 265 dp_rx_mon_check_phyrx_abort(struct dp_pdev *pdev, 266 struct hal_rx_ppdu_info *ppdu_info) 267 { 268 return false; 269 } 270 271 static inline void 272 dp_rx_mon_handle_ppdu_undecoded_metadata(struct dp_soc *soc, 273 struct dp_pdev *pdev, 274 struct hal_rx_ppdu_info *ppdu_info) 275 { 276 } 277 #endif 278 279 #ifdef QCA_SUPPORT_SCAN_SPCL_VAP_STATS 280 /** 281 * dp_rx_mon_update_scan_spcl_vap_stats() - Update special vap stats 282 * @pdev: dp pdev context 283 * @ppdu_info: ppdu info structure from ppdu ring 284 * 285 * Return: none 286 */ 287 static inline void 288 dp_rx_mon_update_scan_spcl_vap_stats(struct dp_pdev *pdev, 289 struct hal_rx_ppdu_info *ppdu_info) 290 { 291 struct mon_rx_user_status *rx_user_status = NULL; 292 struct dp_mon_pdev *mon_pdev = NULL; 293 struct dp_mon_vdev *mon_vdev = NULL; 294 uint32_t num_users = 0; 295 uint32_t user = 0; 296 297 mon_pdev = pdev->monitor_pdev; 298 if (!mon_pdev || !mon_pdev->mvdev) 299 return; 300 301 mon_vdev = mon_pdev->mvdev->monitor_vdev; 302 if (!mon_vdev || !mon_vdev->scan_spcl_vap_stats) 303 return; 304 305 num_users = ppdu_info->com_info.num_users; 306 for (user = 0; user < num_users; user++) { 307 rx_user_status = &ppdu_info->rx_user_status[user]; 308 mon_vdev->scan_spcl_vap_stats->rx_ok_pkts += 309 rx_user_status->mpdu_cnt_fcs_ok; 310 mon_vdev->scan_spcl_vap_stats->rx_ok_bytes += 311 rx_user_status->mpdu_ok_byte_count; 312 mon_vdev->scan_spcl_vap_stats->rx_err_pkts += 313 rx_user_status->mpdu_cnt_fcs_err; 314 mon_vdev->scan_spcl_vap_stats->rx_err_bytes += 315 rx_user_status->mpdu_err_byte_count; 316 } 317 mon_vdev->scan_spcl_vap_stats->rx_mgmt_pkts += 318 ppdu_info->frm_type_info.rx_mgmt_cnt; 319 mon_vdev->scan_spcl_vap_stats->rx_ctrl_pkts += 320 ppdu_info->frm_type_info.rx_ctrl_cnt; 321 mon_vdev->scan_spcl_vap_stats->rx_data_pkts += 322 ppdu_info->frm_type_info.rx_data_cnt; 323 } 324 #else 325 static inline void 326 dp_rx_mon_update_scan_spcl_vap_stats(struct dp_pdev *pdev, 327 struct hal_rx_ppdu_info *ppdu_info) 328 { 329 } 330 #endif 331 332 #ifdef WLAN_FEATURE_DP_MON_STATUS_RING_HISTORY 333 /** 334 * dp_rx_mon_status_ring_record_entry() - Record one entry of a particular 335 * event type into the monitor status 336 * buffer tracking history. 337 * @soc: DP soc handle 338 * @event: event type 339 * @ring_desc: Monitor status ring descriptor 340 * @rx_desc: RX descriptor 341 * @nbuf: status buffer. 342 * 343 * Return: None 344 */ 345 static void 346 dp_rx_mon_status_ring_record_entry(struct dp_soc *soc, 347 enum dp_mon_status_process_event event, 348 hal_ring_desc_t ring_desc, 349 struct dp_rx_desc *rx_desc, 350 qdf_nbuf_t nbuf) 351 { 352 struct dp_mon_stat_info_record *record; 353 struct hal_buf_info hbi; 354 uint32_t idx; 355 356 if (qdf_unlikely(!soc->mon_status_ring_history)) 357 return; 358 359 idx = dp_history_get_next_index(&soc->mon_status_ring_history->index, 360 DP_MON_STATUS_HIST_MAX); 361 362 /* No NULL check needed for record since its an array */ 363 record = &soc->mon_status_ring_history->entry[idx]; 364 365 record->timestamp = qdf_get_log_timestamp(); 366 if (event == DP_MON_STATUS_BUF_REAP) { 367 hal_rx_buffer_addr_info_get_paddr(ring_desc, &hbi); 368 369 /* buffer_addr_info is the first element of ring_desc */ 370 hal_rx_buf_cookie_rbm_get(soc->hal_soc, (uint32_t *)ring_desc, 371 &hbi); 372 373 record->hbi.paddr = hbi.paddr; 374 record->hbi.sw_cookie = hbi.sw_cookie; 375 record->hbi.rbm = hbi.rbm; 376 record->rx_desc = rx_desc; 377 if (rx_desc) { 378 record->nbuf = rx_desc->nbuf; 379 record->rx_desc_nbuf_data = qdf_nbuf_data(rx_desc->nbuf); 380 } else { 381 record->nbuf = NULL; 382 record->rx_desc_nbuf_data = NULL; 383 } 384 } 385 386 if (event == DP_MON_STATUS_BUF_ENQUEUE) { 387 record->nbuf = nbuf; 388 record->rx_desc_nbuf_data = qdf_nbuf_data(nbuf); 389 } 390 391 if (event == DP_MON_STATUS_BUF_DEQUEUE) { 392 record->nbuf = nbuf; 393 if (nbuf) 394 record->rx_desc_nbuf_data = qdf_nbuf_data(nbuf); 395 else 396 record->rx_desc_nbuf_data = NULL; 397 } 398 } 399 #else 400 static void 401 dp_rx_mon_status_ring_record_entry(struct dp_soc *soc, 402 enum dp_mon_status_process_event event, 403 hal_ring_desc_t ring_desc, 404 struct dp_rx_desc *rx_desc, 405 qdf_nbuf_t nbuf) 406 { 407 } 408 #endif 409 410 /** 411 * dp_rx_mon_status_process_tlv() - Process status TLV in status 412 * buffer on Rx status Queue posted by status SRNG processing. 413 * @soc: core txrx main context 414 * @int_ctx: interrupt context 415 * @mac_id: mac_id which is one of 3 mac_ids _ring 416 * @quota: amount of work which can be done 417 * 418 * Return: none 419 */ 420 static inline void 421 dp_rx_mon_status_process_tlv(struct dp_soc *soc, struct dp_intr *int_ctx, 422 uint32_t mac_id, uint32_t quota) 423 { 424 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 425 struct hal_rx_ppdu_info *ppdu_info; 426 qdf_nbuf_t status_nbuf; 427 uint8_t *rx_tlv; 428 uint8_t *rx_tlv_start; 429 uint32_t tlv_status = HAL_TLV_STATUS_BUF_DONE; 430 struct cdp_pdev_mon_stats *rx_mon_stats; 431 int smart_mesh_status; 432 enum WDI_EVENT pktlog_mode = WDI_NO_VAL; 433 bool nbuf_used; 434 uint32_t rx_enh_capture_mode; 435 struct dp_mon_soc *mon_soc = soc->monitor_soc; 436 struct dp_mon_pdev *mon_pdev; 437 438 if (qdf_unlikely(!pdev)) { 439 dp_rx_mon_status_debug("%pK: pdev is null for mac_id = %d", soc, 440 mac_id); 441 return; 442 } 443 444 mon_pdev = pdev->monitor_pdev; 445 ppdu_info = &mon_pdev->ppdu_info; 446 rx_mon_stats = &mon_pdev->rx_mon_stats; 447 448 if (qdf_unlikely(mon_pdev->mon_ppdu_status != DP_PPDU_STATUS_START)) 449 return; 450 451 rx_enh_capture_mode = mon_pdev->rx_enh_capture_mode; 452 453 while (!qdf_nbuf_is_queue_empty(&mon_pdev->rx_status_q)) { 454 455 status_nbuf = qdf_nbuf_queue_remove(&mon_pdev->rx_status_q); 456 dp_rx_mon_status_ring_record_entry(soc, 457 DP_MON_STATUS_BUF_DEQUEUE, 458 NULL, NULL, status_nbuf); 459 460 if (qdf_unlikely(!status_nbuf)) 461 return; 462 463 rx_tlv = qdf_nbuf_data(status_nbuf); 464 rx_tlv_start = rx_tlv; 465 nbuf_used = false; 466 467 if ((mon_pdev->mvdev) || (mon_pdev->enhanced_stats_en) || 468 (mon_pdev->mcopy_mode) || (dp_cfr_rcc_mode_status(pdev)) || 469 (mon_pdev->undecoded_metadata_capture) || 470 (rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) { 471 do { 472 tlv_status = hal_rx_status_get_tlv_info(rx_tlv, 473 ppdu_info, pdev->soc->hal_soc, 474 status_nbuf); 475 476 dp_rx_mon_update_dbg_ppdu_stats(ppdu_info, 477 rx_mon_stats); 478 479 dp_rx_mon_enh_capture_process(pdev, tlv_status, 480 status_nbuf, ppdu_info, 481 &nbuf_used); 482 483 dp_rx_mcopy_process_ppdu_info(pdev, 484 ppdu_info, 485 tlv_status); 486 487 rx_tlv = hal_rx_status_get_next_tlv(rx_tlv, 488 mon_pdev->is_tlv_hdr_64_bit); 489 490 if (qdf_unlikely((rx_tlv - rx_tlv_start)) >= 491 RX_MON_STATUS_BUF_SIZE) 492 break; 493 494 } while ((tlv_status == HAL_TLV_STATUS_PPDU_NOT_DONE) || 495 (tlv_status == HAL_TLV_STATUS_HEADER) || 496 (tlv_status == HAL_TLV_STATUS_MPDU_END) || 497 (tlv_status == HAL_TLV_STATUS_MPDU_START) || 498 (tlv_status == HAL_TLV_STATUS_MSDU_END)); 499 } 500 dp_mon_rx_stats_update_rssi_dbm_params(mon_pdev, ppdu_info); 501 if (qdf_unlikely(mon_pdev->dp_peer_based_pktlog)) { 502 dp_rx_process_peer_based_pktlog(soc, ppdu_info, 503 status_nbuf, 504 pdev->pdev_id); 505 } else { 506 if (qdf_unlikely(mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_FULL)) 507 pktlog_mode = WDI_EVENT_RX_DESC; 508 else if (qdf_unlikely(mon_pdev->rx_pktlog_mode == DP_RX_PKTLOG_LITE)) 509 pktlog_mode = WDI_EVENT_LITE_RX; 510 511 if (qdf_unlikely(pktlog_mode != WDI_NO_VAL)) 512 dp_wdi_event_handler(pktlog_mode, soc, 513 status_nbuf, 514 HTT_INVALID_PEER, 515 WDI_NO_VAL, pdev->pdev_id); 516 } 517 518 /* smart monitor vap and m_copy cannot co-exist */ 519 if (qdf_unlikely(ppdu_info->rx_status.monitor_direct_used && 520 mon_pdev->neighbour_peers_added && 521 mon_pdev->mvdev)) { 522 smart_mesh_status = dp_rx_handle_smart_mesh_mode(soc, 523 pdev, ppdu_info, status_nbuf); 524 if (smart_mesh_status) 525 qdf_nbuf_free(status_nbuf); 526 } else if (qdf_unlikely(mon_pdev->mcopy_mode)) { 527 dp_rx_process_mcopy_mode(soc, pdev, 528 ppdu_info, tlv_status, 529 status_nbuf); 530 } else if (qdf_unlikely(rx_enh_capture_mode != CDP_RX_ENH_CAPTURE_DISABLED)) { 531 if (!nbuf_used) 532 qdf_nbuf_free(status_nbuf); 533 534 if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) 535 dp_rx_handle_enh_capture(soc, 536 pdev, ppdu_info); 537 } else { 538 qdf_nbuf_free(status_nbuf); 539 } 540 541 if (qdf_unlikely(tlv_status == HAL_TLV_STATUS_PPDU_NON_STD_DONE)) { 542 dp_rx_mon_deliver_non_std(soc, mac_id); 543 } else if ((qdf_likely(tlv_status == HAL_TLV_STATUS_PPDU_DONE)) && 544 (qdf_likely(!dp_rx_mon_check_phyrx_abort(pdev, ppdu_info)))) { 545 rx_mon_stats->status_ppdu_done++; 546 dp_rx_mon_handle_mu_ul_info(ppdu_info); 547 548 if (qdf_unlikely(mon_pdev->tx_capture_enabled 549 != CDP_TX_ENH_CAPTURE_DISABLED)) 550 dp_send_ack_frame_to_stack(soc, pdev, 551 ppdu_info); 552 553 if (qdf_likely(mon_pdev->enhanced_stats_en || 554 mon_pdev->mcopy_mode || 555 mon_pdev->neighbour_peers_added)) 556 dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info); 557 else if (dp_cfr_rcc_mode_status(pdev)) 558 dp_rx_handle_cfr(soc, pdev, ppdu_info); 559 560 mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE; 561 562 /* Collect spcl vap stats if configured */ 563 if (qdf_unlikely(mon_pdev->scan_spcl_vap_configured)) 564 dp_rx_mon_update_scan_spcl_vap_stats(pdev, 565 ppdu_info); 566 567 dp_rx_mon_update_user_ctrl_frame_stats(pdev, ppdu_info); 568 569 /* 570 * if chan_num is not fetched correctly from ppdu RX TLV, 571 * get it from pdev saved. 572 */ 573 if (qdf_unlikely(mon_pdev->ppdu_info.rx_status.chan_num == 0)) 574 mon_pdev->ppdu_info.rx_status.chan_num = 575 mon_pdev->mon_chan_num; 576 /* 577 * if chan_freq is not fetched correctly from ppdu RX TLV, 578 * get it from pdev saved. 579 */ 580 if (qdf_unlikely(mon_pdev->ppdu_info.rx_status.chan_freq == 0)) { 581 mon_pdev->ppdu_info.rx_status.chan_freq = 582 mon_pdev->mon_chan_freq; 583 } 584 585 if (!mon_soc->full_mon_mode) 586 dp_rx_mon_dest_process(soc, int_ctx, mac_id, 587 quota); 588 589 mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_START; 590 } else { 591 dp_rx_mon_handle_ppdu_undecoded_metadata(soc, pdev, 592 ppdu_info); 593 } 594 } 595 return; 596 } 597 598 /* 599 * dp_rx_mon_status_srng_process() - Process monitor status ring 600 * post the status ring buffer to Rx status Queue for later 601 * processing when status ring is filled with status TLV. 602 * Allocate a new buffer to status ring if the filled buffer 603 * is posted. 604 * @soc: core txrx main context 605 * @int_ctx: interrupt context 606 * @mac_id: mac_id which is one of 3 mac_ids 607 * @quota: No. of ring entry that can be serviced in one shot. 608 609 * Return: uint32_t: No. of ring entry that is processed. 610 */ 611 static inline uint32_t 612 dp_rx_mon_status_srng_process(struct dp_soc *soc, struct dp_intr *int_ctx, 613 uint32_t mac_id, uint32_t quota) 614 { 615 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 616 hal_soc_handle_t hal_soc; 617 void *mon_status_srng; 618 void *rxdma_mon_status_ring_entry; 619 QDF_STATUS status; 620 enum dp_mon_reap_status reap_status; 621 uint32_t work_done = 0; 622 struct dp_mon_pdev *mon_pdev; 623 624 if (qdf_unlikely(!pdev)) { 625 dp_rx_mon_status_debug("%pK: pdev is null for mac_id = %d", 626 soc, mac_id); 627 return work_done; 628 } 629 630 mon_pdev = pdev->monitor_pdev; 631 632 mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng; 633 634 qdf_assert(mon_status_srng); 635 if (qdf_unlikely(!mon_status_srng || 636 !hal_srng_initialized(mon_status_srng))) { 637 638 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 639 "%s %d : HAL Monitor Status Ring Init Failed -- %pK", 640 __func__, __LINE__, mon_status_srng); 641 return work_done; 642 } 643 644 hal_soc = soc->hal_soc; 645 646 qdf_assert(hal_soc); 647 648 if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_status_srng))) 649 goto done; 650 651 /* mon_status_ring_desc => WBM_BUFFER_RING STRUCT => 652 * BUFFER_ADDR_INFO STRUCT 653 */ 654 while (qdf_likely((rxdma_mon_status_ring_entry = 655 hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng)) 656 && quota--)) { 657 struct hal_buf_info hbi; 658 qdf_nbuf_t status_nbuf; 659 struct dp_rx_desc *rx_desc; 660 uint8_t *status_buf; 661 qdf_dma_addr_t paddr; 662 uint64_t buf_addr; 663 struct rx_desc_pool *rx_desc_pool; 664 665 rx_desc_pool = &soc->rx_desc_status[mac_id]; 666 buf_addr = 667 (HAL_RX_BUFFER_ADDR_31_0_GET( 668 rxdma_mon_status_ring_entry) | 669 ((uint64_t)(HAL_RX_BUFFER_ADDR_39_32_GET( 670 rxdma_mon_status_ring_entry)) << 32)); 671 672 if (qdf_likely(buf_addr)) { 673 674 hal_rx_buf_cookie_rbm_get(soc->hal_soc, 675 (uint32_t *)rxdma_mon_status_ring_entry, 676 &hbi); 677 rx_desc = dp_rx_cookie_2_va_mon_status(soc, 678 hbi.sw_cookie); 679 dp_rx_mon_status_ring_record_entry(soc, DP_MON_STATUS_BUF_REAP, 680 rxdma_mon_status_ring_entry, 681 rx_desc, NULL); 682 683 qdf_assert_always(rx_desc); 684 685 if (qdf_unlikely(!dp_rx_desc_paddr_sanity_check(rx_desc, 686 buf_addr))) { 687 DP_STATS_INC(soc, rx.err.nbuf_sanity_fail, 1); 688 hal_srng_src_get_next(hal_soc, mon_status_srng); 689 continue; 690 } 691 692 status_nbuf = rx_desc->nbuf; 693 694 qdf_nbuf_sync_for_cpu(soc->osdev, status_nbuf, 695 QDF_DMA_FROM_DEVICE); 696 697 status_buf = qdf_nbuf_data(status_nbuf); 698 699 status = hal_get_rx_status_done(status_buf); 700 701 if (qdf_unlikely(status != QDF_STATUS_SUCCESS)) { 702 uint32_t hp, tp; 703 hal_get_sw_hptp(hal_soc, mon_status_srng, 704 &tp, &hp); 705 dp_info_rl("tlv tag status error hp:%u, tp:%u", 706 hp, tp); 707 708 /* RxDMA status done bit might not be set even 709 * though tp is moved by HW. 710 */ 711 712 /* If done status is missing: 713 * 1. As per MAC team's suggestion, 714 * when HP + 1 entry is peeked and if DMA 715 * is not done and if HP + 2 entry's DMA done 716 * is set. skip HP + 1 entry and 717 * start processing in next interrupt. 718 * 2. If HP + 2 entry's DMA done is not set, 719 * poll onto HP + 1 entry DMA done to be set. 720 * Check status for same buffer for next time 721 * dp_rx_mon_status_srng_process 722 */ 723 reap_status = dp_rx_mon_handle_status_buf_done(pdev, 724 mon_status_srng); 725 if (qdf_unlikely(reap_status == DP_MON_STATUS_NO_DMA)) 726 continue; 727 else if (qdf_unlikely(reap_status == DP_MON_STATUS_REPLENISH)) { 728 if (!rx_desc->unmapped) { 729 qdf_nbuf_unmap_nbytes_single( 730 soc->osdev, status_nbuf, 731 QDF_DMA_FROM_DEVICE, 732 rx_desc_pool->buf_size); 733 rx_desc->unmapped = 1; 734 } 735 qdf_nbuf_free(status_nbuf); 736 goto buf_replenish; 737 } 738 } 739 qdf_nbuf_set_pktlen(status_nbuf, 740 RX_MON_STATUS_BUF_SIZE); 741 742 if (qdf_likely(!rx_desc->unmapped)) { 743 qdf_nbuf_unmap_nbytes_single(soc->osdev, status_nbuf, 744 QDF_DMA_FROM_DEVICE, 745 rx_desc_pool->buf_size); 746 rx_desc->unmapped = 1; 747 } 748 749 /* Put the status_nbuf to queue */ 750 qdf_nbuf_queue_add(&mon_pdev->rx_status_q, status_nbuf); 751 dp_rx_mon_status_ring_record_entry(soc, DP_MON_STATUS_BUF_ENQUEUE, 752 rxdma_mon_status_ring_entry, 753 rx_desc, status_nbuf); 754 755 } else { 756 union dp_rx_desc_list_elem_t *desc_list = NULL; 757 union dp_rx_desc_list_elem_t *tail = NULL; 758 uint32_t num_alloc_desc; 759 760 num_alloc_desc = dp_rx_get_free_desc_list(soc, mac_id, 761 rx_desc_pool, 762 1, 763 &desc_list, 764 &tail); 765 /* 766 * No free descriptors available 767 */ 768 if (qdf_unlikely(num_alloc_desc == 0)) { 769 work_done++; 770 break; 771 } 772 773 rx_desc = &desc_list->rx_desc; 774 } 775 776 buf_replenish: 777 status_nbuf = dp_rx_nbuf_prepare(soc, pdev); 778 779 /* 780 * qdf_nbuf alloc or map failed, 781 * free the dp rx desc to free list, 782 * fill in NULL dma address at current HP entry, 783 * keep HP in mon_status_ring unchanged, 784 * wait next time dp_rx_mon_status_srng_process 785 * to fill in buffer at current HP. 786 */ 787 if (qdf_unlikely(!status_nbuf)) { 788 union dp_rx_desc_list_elem_t *desc_list = NULL; 789 union dp_rx_desc_list_elem_t *tail = NULL; 790 struct rx_desc_pool *rx_desc_pool; 791 792 rx_desc_pool = &soc->rx_desc_status[mac_id]; 793 794 dp_info_rl("fail to allocate or map qdf_nbuf"); 795 dp_rx_add_to_free_desc_list(&desc_list, 796 &tail, rx_desc); 797 dp_rx_add_desc_list_to_free_list(soc, &desc_list, 798 &tail, mac_id, rx_desc_pool); 799 800 hal_rxdma_buff_addr_info_set( 801 hal_soc, rxdma_mon_status_ring_entry, 802 0, 0, 803 HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id)); 804 work_done++; 805 break; 806 } 807 808 paddr = qdf_nbuf_get_frag_paddr(status_nbuf, 0); 809 810 rx_desc->nbuf = status_nbuf; 811 rx_desc->in_use = 1; 812 rx_desc->unmapped = 0; 813 814 hal_rxdma_buff_addr_info_set(hal_soc, 815 rxdma_mon_status_ring_entry, 816 paddr, rx_desc->cookie, 817 HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id)); 818 819 hal_srng_src_get_next(hal_soc, mon_status_srng); 820 work_done++; 821 } 822 done: 823 824 dp_srng_access_end(int_ctx, soc, mon_status_srng); 825 826 return work_done; 827 828 } 829 830 uint32_t 831 dp_rx_mon_status_process(struct dp_soc *soc, struct dp_intr *int_ctx, 832 uint32_t mac_id, uint32_t quota) 833 { 834 uint32_t work_done; 835 836 work_done = dp_rx_mon_status_srng_process(soc, int_ctx, mac_id, quota); 837 quota -= work_done; 838 dp_rx_mon_status_process_tlv(soc, int_ctx, mac_id, quota); 839 840 return work_done; 841 } 842 843 QDF_STATUS 844 dp_rx_pdev_mon_status_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id) 845 { 846 uint8_t pdev_id = pdev->pdev_id; 847 struct dp_soc *soc = pdev->soc; 848 struct dp_srng *mon_status_ring; 849 uint32_t num_entries; 850 struct rx_desc_pool *rx_desc_pool; 851 union dp_rx_desc_list_elem_t *desc_list = NULL; 852 union dp_rx_desc_list_elem_t *tail = NULL; 853 854 mon_status_ring = &soc->rxdma_mon_status_ring[mac_id]; 855 856 num_entries = mon_status_ring->num_entries; 857 858 rx_desc_pool = &soc->rx_desc_status[mac_id]; 859 860 dp_debug("Mon RX Desc Pool[%d] entries=%u", 861 pdev_id, num_entries); 862 863 return dp_rx_mon_status_buffers_replenish(soc, mac_id, mon_status_ring, 864 rx_desc_pool, num_entries, 865 &desc_list, &tail, 866 HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id)); 867 } 868 869 QDF_STATUS 870 dp_rx_pdev_mon_status_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id) 871 { 872 uint8_t pdev_id = pdev->pdev_id; 873 struct dp_soc *soc = pdev->soc; 874 struct dp_srng *mon_status_ring; 875 uint32_t num_entries; 876 struct rx_desc_pool *rx_desc_pool; 877 878 mon_status_ring = &soc->rxdma_mon_status_ring[mac_id]; 879 880 num_entries = mon_status_ring->num_entries; 881 882 rx_desc_pool = &soc->rx_desc_status[mac_id]; 883 884 dp_debug("Mon RX Desc Pool[%d] entries=%u", pdev_id, num_entries); 885 886 rx_desc_pool->desc_type = DP_RX_DESC_STATUS_TYPE; 887 return dp_rx_desc_pool_alloc(soc, num_entries + 1, rx_desc_pool); 888 } 889 890 void 891 dp_rx_pdev_mon_status_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id) 892 { 893 uint32_t i; 894 uint8_t pdev_id = pdev->pdev_id; 895 struct dp_soc *soc = pdev->soc; 896 struct dp_srng *mon_status_ring; 897 uint32_t num_entries; 898 struct rx_desc_pool *rx_desc_pool; 899 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 900 901 mon_status_ring = &soc->rxdma_mon_status_ring[mac_id]; 902 903 num_entries = mon_status_ring->num_entries; 904 905 rx_desc_pool = &soc->rx_desc_status[mac_id]; 906 907 dp_debug("Mon RX Desc status Pool[%d] init entries=%u", 908 pdev_id, num_entries); 909 910 rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id); 911 rx_desc_pool->buf_size = RX_MON_STATUS_BUF_SIZE; 912 rx_desc_pool->buf_alignment = RX_DATA_BUFFER_ALIGNMENT; 913 /* Disable frag processing flag */ 914 dp_rx_enable_mon_dest_frag(rx_desc_pool, false); 915 916 dp_rx_desc_pool_init(soc, mac_id, num_entries + 1, rx_desc_pool); 917 918 qdf_nbuf_queue_init(&mon_pdev->rx_status_q); 919 920 mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_START; 921 922 qdf_mem_zero(&mon_pdev->ppdu_info, sizeof(mon_pdev->ppdu_info)); 923 924 /* 925 * Set last_ppdu_id to HAL_INVALID_PPDU_ID in order to avoid ppdu_id 926 * match with '0' ppdu_id from monitor status ring 927 */ 928 mon_pdev->ppdu_info.com_info.last_ppdu_id = HAL_INVALID_PPDU_ID; 929 930 qdf_mem_zero(&mon_pdev->rx_mon_stats, sizeof(mon_pdev->rx_mon_stats)); 931 932 dp_rx_mon_init_dbg_ppdu_stats(&mon_pdev->ppdu_info, 933 &mon_pdev->rx_mon_stats); 934 935 for (i = 0; i < MAX_MU_USERS; i++) { 936 qdf_nbuf_queue_init(&mon_pdev->mpdu_q[i]); 937 mon_pdev->is_mpdu_hdr[i] = true; 938 } 939 940 qdf_mem_zero(mon_pdev->msdu_list, 941 sizeof(mon_pdev->msdu_list[MAX_MU_USERS])); 942 943 mon_pdev->rx_enh_capture_mode = CDP_RX_ENH_CAPTURE_DISABLED; 944 } 945 946 void 947 dp_rx_pdev_mon_status_desc_pool_deinit(struct dp_pdev *pdev, uint32_t mac_id) { 948 uint8_t pdev_id = pdev->pdev_id; 949 struct dp_soc *soc = pdev->soc; 950 struct rx_desc_pool *rx_desc_pool; 951 952 rx_desc_pool = &soc->rx_desc_status[mac_id]; 953 954 dp_debug("Mon RX Desc status Pool[%d] deinit", pdev_id); 955 956 dp_rx_desc_pool_deinit(soc, rx_desc_pool, mac_id); 957 } 958 959 void 960 dp_rx_pdev_mon_status_desc_pool_free(struct dp_pdev *pdev, uint32_t mac_id) { 961 uint8_t pdev_id = pdev->pdev_id; 962 struct dp_soc *soc = pdev->soc; 963 struct rx_desc_pool *rx_desc_pool; 964 965 rx_desc_pool = &soc->rx_desc_status[mac_id]; 966 967 dp_debug("Mon RX Status Desc Pool Free pdev[%d]", pdev_id); 968 969 dp_rx_desc_pool_free(soc, rx_desc_pool); 970 } 971 972 void 973 dp_rx_pdev_mon_status_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) 974 { 975 uint8_t pdev_id = pdev->pdev_id; 976 struct dp_soc *soc = pdev->soc; 977 struct rx_desc_pool *rx_desc_pool; 978 979 rx_desc_pool = &soc->rx_desc_status[mac_id]; 980 981 dp_debug("Mon RX Status Desc Pool Free pdev[%d]", pdev_id); 982 983 dp_rx_desc_nbuf_free(soc, rx_desc_pool, true); 984 } 985 986 /* 987 * dp_rx_buffers_replenish() - replenish monitor status ring with 988 * rx nbufs called during dp rx 989 * monitor status ring initialization 990 * 991 * @soc: core txrx main context 992 * @mac_id: mac_id which is one of 3 mac_ids 993 * @dp_rxdma_srng: dp monitor status circular ring 994 * @rx_desc_pool; Pointer to Rx descriptor pool 995 * @num_req_buffers: number of buffer to be replenished 996 * @desc_list: list of descs if called from dp rx monitor status 997 * process or NULL during dp rx initialization or 998 * out of buffer interrupt 999 * @tail: tail of descs list 1000 * @owner: who owns the nbuf (host, NSS etc...) 1001 * Return: return success or failure 1002 */ 1003 static inline 1004 QDF_STATUS dp_rx_mon_status_buffers_replenish(struct dp_soc *dp_soc, 1005 uint32_t mac_id, 1006 struct dp_srng *dp_rxdma_srng, 1007 struct rx_desc_pool *rx_desc_pool, 1008 uint32_t num_req_buffers, 1009 union dp_rx_desc_list_elem_t **desc_list, 1010 union dp_rx_desc_list_elem_t **tail, 1011 uint8_t owner) 1012 { 1013 uint32_t num_alloc_desc; 1014 uint16_t num_desc_to_free = 0; 1015 uint32_t num_entries_avail; 1016 uint32_t count = 0; 1017 int sync_hw_ptr = 1; 1018 qdf_dma_addr_t paddr; 1019 qdf_nbuf_t rx_netbuf; 1020 void *rxdma_ring_entry; 1021 union dp_rx_desc_list_elem_t *next; 1022 void *rxdma_srng; 1023 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(dp_soc, mac_id); 1024 1025 if (!dp_pdev) { 1026 dp_rx_mon_status_debug("%pK: pdev is null for mac_id = %d", 1027 dp_soc, mac_id); 1028 return QDF_STATUS_E_FAILURE; 1029 } 1030 1031 rxdma_srng = dp_rxdma_srng->hal_srng; 1032 1033 qdf_assert(rxdma_srng); 1034 1035 dp_rx_mon_status_debug("%pK: requested %d buffers for replenish", 1036 dp_soc, num_req_buffers); 1037 1038 /* 1039 * if desc_list is NULL, allocate the descs from freelist 1040 */ 1041 if (!(*desc_list)) { 1042 1043 num_alloc_desc = dp_rx_get_free_desc_list(dp_soc, mac_id, 1044 rx_desc_pool, 1045 num_req_buffers, 1046 desc_list, 1047 tail); 1048 1049 if (!num_alloc_desc) { 1050 dp_rx_mon_status_err("%pK: no free rx_descs in freelist", 1051 dp_soc); 1052 return QDF_STATUS_E_NOMEM; 1053 } 1054 1055 dp_rx_mon_status_debug("%pK: %d rx desc allocated", dp_soc, 1056 num_alloc_desc); 1057 1058 num_req_buffers = num_alloc_desc; 1059 } 1060 1061 hal_srng_access_start(dp_soc->hal_soc, rxdma_srng); 1062 num_entries_avail = hal_srng_src_num_avail(dp_soc->hal_soc, 1063 rxdma_srng, sync_hw_ptr); 1064 1065 dp_rx_mon_status_debug("%pK: no of available entries in rxdma ring: %d", 1066 dp_soc, num_entries_avail); 1067 1068 if (num_entries_avail < num_req_buffers) { 1069 num_desc_to_free = num_req_buffers - num_entries_avail; 1070 num_req_buffers = num_entries_avail; 1071 } 1072 1073 while (count <= num_req_buffers) { 1074 rx_netbuf = dp_rx_nbuf_prepare(dp_soc, dp_pdev); 1075 1076 /* 1077 * qdf_nbuf alloc or map failed, 1078 * keep HP in mon_status_ring unchanged, 1079 * wait dp_rx_mon_status_srng_process 1080 * to fill in buffer at current HP. 1081 */ 1082 if (qdf_unlikely(!rx_netbuf)) { 1083 dp_rx_mon_status_err("%pK: qdf_nbuf allocate or map fail, count %d", 1084 dp_soc, count); 1085 break; 1086 } 1087 1088 paddr = qdf_nbuf_get_frag_paddr(rx_netbuf, 0); 1089 1090 next = (*desc_list)->next; 1091 rxdma_ring_entry = hal_srng_src_get_cur_hp_n_move_next( 1092 dp_soc->hal_soc, 1093 rxdma_srng); 1094 1095 if (qdf_unlikely(!rxdma_ring_entry)) { 1096 dp_rx_mon_status_err("%pK: rxdma_ring_entry is NULL, count - %d", 1097 dp_soc, count); 1098 qdf_nbuf_unmap_nbytes_single(dp_soc->osdev, rx_netbuf, 1099 QDF_DMA_FROM_DEVICE, 1100 rx_desc_pool->buf_size); 1101 qdf_nbuf_free(rx_netbuf); 1102 break; 1103 } 1104 1105 (*desc_list)->rx_desc.nbuf = rx_netbuf; 1106 (*desc_list)->rx_desc.in_use = 1; 1107 (*desc_list)->rx_desc.unmapped = 0; 1108 count++; 1109 1110 hal_rxdma_buff_addr_info_set(dp_soc->hal_soc, 1111 rxdma_ring_entry, paddr, 1112 (*desc_list)->rx_desc.cookie, 1113 owner); 1114 1115 dp_rx_mon_status_debug("%pK: rx_desc=%pK, cookie=%d, nbuf=%pK, paddr=%pK", 1116 dp_soc, &(*desc_list)->rx_desc, 1117 (*desc_list)->rx_desc.cookie, rx_netbuf, 1118 (void *)paddr); 1119 1120 *desc_list = next; 1121 } 1122 1123 hal_srng_access_end(dp_soc->hal_soc, rxdma_srng); 1124 1125 dp_rx_mon_status_debug("%pK: successfully replenished %d buffers", 1126 dp_soc, num_req_buffers); 1127 1128 dp_rx_mon_status_debug("%pK: %d rx desc added back to free list", 1129 dp_soc, num_desc_to_free); 1130 1131 /* 1132 * add any available free desc back to the free list 1133 */ 1134 if (*desc_list) { 1135 dp_rx_add_desc_list_to_free_list(dp_soc, desc_list, tail, 1136 mac_id, rx_desc_pool); 1137 } 1138 1139 return QDF_STATUS_SUCCESS; 1140 } 1141 1142 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 1143 /** 1144 * dp_mon_status_srng_drop_for_mac() - Drop the mon status ring packets for 1145 * a given mac 1146 * @pdev: DP pdev 1147 * @mac_id: mac id 1148 * @quota: maximum number of ring entries that can be processed 1149 * 1150 * Return: Number of ring entries reaped 1151 */ 1152 static uint32_t 1153 dp_mon_status_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id, 1154 uint32_t quota) 1155 { 1156 struct dp_soc *soc = pdev->soc; 1157 void *mon_status_srng; 1158 hal_soc_handle_t hal_soc; 1159 void *ring_desc; 1160 uint32_t reap_cnt = 0; 1161 1162 if (qdf_unlikely(!soc || !soc->hal_soc)) 1163 return reap_cnt; 1164 1165 mon_status_srng = soc->rxdma_mon_status_ring[mac_id].hal_srng; 1166 1167 if (qdf_unlikely(!mon_status_srng || 1168 !hal_srng_initialized(mon_status_srng))) 1169 return reap_cnt; 1170 1171 hal_soc = soc->hal_soc; 1172 1173 if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_status_srng))) 1174 return reap_cnt; 1175 1176 while ((ring_desc = 1177 hal_srng_src_peek_n_get_next(hal_soc, mon_status_srng)) && 1178 reap_cnt < MON_DROP_REAP_LIMIT && quota--) { 1179 uint64_t buf_addr; 1180 struct hal_buf_info hbi; 1181 struct dp_rx_desc *rx_desc; 1182 qdf_nbuf_t status_nbuf; 1183 uint8_t *status_buf; 1184 enum dp_mon_reap_status reap_status; 1185 qdf_dma_addr_t iova; 1186 struct rx_desc_pool *rx_desc_pool; 1187 1188 rx_desc_pool = &soc->rx_desc_status[mac_id]; 1189 1190 buf_addr = (HAL_RX_BUFFER_ADDR_31_0_GET(ring_desc) | 1191 ((uint64_t)(HAL_RX_BUFFER_ADDR_39_32_GET(ring_desc)) << 32)); 1192 1193 if (qdf_likely(buf_addr)) { 1194 hal_rx_buf_cookie_rbm_get(soc->hal_soc, 1195 (uint32_t *)ring_desc, 1196 &hbi); 1197 rx_desc = dp_rx_cookie_2_va_mon_status(soc, 1198 hbi.sw_cookie); 1199 1200 qdf_assert_always(rx_desc); 1201 1202 status_nbuf = rx_desc->nbuf; 1203 1204 qdf_nbuf_sync_for_cpu(soc->osdev, status_nbuf, 1205 QDF_DMA_FROM_DEVICE); 1206 1207 status_buf = qdf_nbuf_data(status_nbuf); 1208 1209 if (hal_get_rx_status_done(status_buf) != 1210 QDF_STATUS_SUCCESS) { 1211 /* If done status is missing: 1212 * 1. As per MAC team's suggestion, 1213 * when HP + 1 entry is peeked and if DMA 1214 * is not done and if HP + 2 entry's DMA done 1215 * is set. skip HP + 1 entry and 1216 * start processing in next interrupt. 1217 * 2. If HP + 2 entry's DMA done is not set, 1218 * poll onto HP + 1 entry DMA done to be set. 1219 * Check status for same buffer for next time 1220 * dp_rx_mon_status_srng_process 1221 */ 1222 reap_status = 1223 dp_rx_mon_handle_status_buf_done(pdev, 1224 mon_status_srng); 1225 if (reap_status == DP_MON_STATUS_NO_DMA) 1226 break; 1227 } 1228 qdf_nbuf_unmap_nbytes_single(soc->osdev, status_nbuf, 1229 QDF_DMA_FROM_DEVICE, 1230 rx_desc_pool->buf_size); 1231 qdf_nbuf_free(status_nbuf); 1232 } else { 1233 union dp_rx_desc_list_elem_t *rx_desc_elem; 1234 1235 qdf_spin_lock_bh(&rx_desc_pool->lock); 1236 1237 if (!rx_desc_pool->freelist) { 1238 qdf_spin_unlock_bh(&rx_desc_pool->lock); 1239 break; 1240 } 1241 rx_desc_elem = rx_desc_pool->freelist; 1242 rx_desc_pool->freelist = rx_desc_pool->freelist->next; 1243 qdf_spin_unlock_bh(&rx_desc_pool->lock); 1244 1245 rx_desc = &rx_desc_elem->rx_desc; 1246 } 1247 1248 status_nbuf = dp_rx_nbuf_prepare(soc, pdev); 1249 1250 if (qdf_unlikely(!status_nbuf)) { 1251 union dp_rx_desc_list_elem_t *desc_list = NULL; 1252 union dp_rx_desc_list_elem_t *tail = NULL; 1253 1254 dp_info_rl("fail to allocate or map nbuf"); 1255 dp_rx_add_to_free_desc_list(&desc_list, &tail, 1256 rx_desc); 1257 dp_rx_add_desc_list_to_free_list(soc, 1258 &desc_list, 1259 &tail, mac_id, 1260 rx_desc_pool); 1261 1262 hal_rxdma_buff_addr_info_set(hal_soc, ring_desc, 0, 0, 1263 HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id)); 1264 break; 1265 } 1266 1267 iova = qdf_nbuf_get_frag_paddr(status_nbuf, 0); 1268 1269 rx_desc->nbuf = status_nbuf; 1270 rx_desc->in_use = 1; 1271 1272 hal_rxdma_buff_addr_info_set(hal_soc, ring_desc, iova, 1273 rx_desc->cookie, 1274 HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id)); 1275 1276 reap_cnt++; 1277 hal_srng_src_get_next(hal_soc, mon_status_srng); 1278 } 1279 1280 hal_srng_access_end(hal_soc, mon_status_srng); 1281 1282 return reap_cnt; 1283 } 1284 1285 uint32_t dp_mon_drop_packets_for_mac(struct dp_pdev *pdev, uint32_t mac_id, 1286 uint32_t quota) 1287 { 1288 uint32_t work_done; 1289 1290 work_done = dp_mon_status_srng_drop_for_mac(pdev, mac_id, quota); 1291 dp_mon_dest_srng_drop_for_mac(pdev, mac_id); 1292 1293 return work_done; 1294 } 1295 #else 1296 uint32_t dp_mon_drop_packets_for_mac(struct dp_pdev *pdev, uint32_t mac_id, 1297 uint32_t quota) 1298 { 1299 return 0; 1300 } 1301 #endif 1302