1 /* 2 * Copyright (c) 2017-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 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 18 #include "hal_hw_headers.h" 19 #include "dp_types.h" 20 #include "dp_rx.h" 21 #include "dp_peer.h" 22 #include "hal_rx.h" 23 #include "hal_api.h" 24 #include "qdf_trace.h" 25 #include "qdf_nbuf.h" 26 #include "hal_api_mon.h" 27 #include "dp_htt.h" 28 #include "dp_mon.h" 29 #include "dp_rx_mon.h" 30 #include "wlan_cfg.h" 31 #include "dp_internal.h" 32 #include "dp_rx_buffer_pool.h" 33 #include <dp_mon_1.0.h> 34 #include <dp_rx_mon_1.0.h> 35 36 #ifdef WLAN_TX_PKT_CAPTURE_ENH 37 #include "dp_rx_mon_feature.h" 38 #endif 39 40 /* 41 * PPDU id is from 0 to 64k-1. PPDU id read from status ring and PPDU id 42 * read from destination ring shall track each other. If the distance of 43 * two ppdu id is less than 20000. It is assume no wrap around. Otherwise, 44 * It is assume wrap around. 45 */ 46 #define NOT_PPDU_ID_WRAP_AROUND 20000 47 /* 48 * The destination ring processing is stuck if the destrination is not 49 * moving while status ring moves 16 ppdu. the destination ring processing 50 * skips this destination ring ppdu as walkaround 51 */ 52 #define MON_DEST_RING_STUCK_MAX_CNT 16 53 54 #ifdef WLAN_TX_PKT_CAPTURE_ENH 55 void 56 dp_handle_tx_capture(struct dp_soc *soc, struct dp_pdev *pdev, 57 qdf_nbuf_t mon_mpdu) 58 { 59 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 60 struct hal_rx_ppdu_info *ppdu_info = &mon_pdev->ppdu_info; 61 62 if (mon_pdev->tx_capture_enabled 63 == CDP_TX_ENH_CAPTURE_DISABLED) 64 return; 65 66 if ((ppdu_info->sw_frame_group_id == 67 HAL_MPDU_SW_FRAME_GROUP_CTRL_NDPA) || 68 (ppdu_info->sw_frame_group_id == 69 HAL_MPDU_SW_FRAME_GROUP_CTRL_BAR)) 70 dp_handle_tx_capture_from_dest(soc, pdev, mon_mpdu); 71 } 72 73 #ifdef QCA_MONITOR_PKT_SUPPORT 74 static void 75 dp_tx_capture_get_user_id(struct dp_pdev *dp_pdev, void *rx_desc_tlv) 76 { 77 struct dp_mon_pdev *mon_pdev = dp_pdev->monitor_pdev; 78 79 if (mon_pdev->tx_capture_enabled 80 != CDP_TX_ENH_CAPTURE_DISABLED) 81 mon_pdev->ppdu_info.rx_info.user_id = 82 hal_rx_hw_desc_mpdu_user_id(dp_pdev->soc->hal_soc, 83 rx_desc_tlv); 84 } 85 #endif 86 #else 87 static void 88 dp_tx_capture_get_user_id(struct dp_pdev *dp_pdev, void *rx_desc_tlv) 89 { 90 } 91 #endif 92 93 #ifdef QCA_MONITOR_PKT_SUPPORT 94 /** 95 * dp_rx_mon_link_desc_return() - Return a MPDU link descriptor to HW 96 * (WBM), following error handling 97 * 98 * @dp_pdev: core txrx pdev context 99 * @buf_addr_info: void pointer to monitor link descriptor buf addr info 100 * @mac_id: mac_id for which the link desc is released. 101 * 102 * Return: QDF_STATUS 103 */ 104 QDF_STATUS 105 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, 106 hal_buff_addrinfo_t buf_addr_info, int mac_id) 107 { 108 hal_ring_handle_t hal_ring_hdl; 109 hal_soc_handle_t hal_soc; 110 QDF_STATUS status = QDF_STATUS_E_FAILURE; 111 void *src_srng_desc; 112 113 hal_soc = dp_pdev->soc->hal_soc; 114 115 hal_ring_hdl = dp_monitor_get_link_desc_ring(dp_pdev->soc, mac_id); 116 117 qdf_assert(hal_ring_hdl); 118 119 if (qdf_unlikely(hal_srng_access_start(hal_soc, hal_ring_hdl))) { 120 121 /* TODO */ 122 /* 123 * Need API to convert from hal_ring pointer to 124 * Ring Type / Ring Id combo 125 */ 126 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 127 "%s %d : \ 128 HAL RING Access For WBM Release SRNG Failed -- %pK", 129 __func__, __LINE__, hal_ring_hdl); 130 goto done; 131 } 132 133 src_srng_desc = hal_srng_src_get_next(hal_soc, hal_ring_hdl); 134 135 if (qdf_likely(src_srng_desc)) { 136 /* Return link descriptor through WBM ring (SW2WBM)*/ 137 hal_rx_mon_msdu_link_desc_set(hal_soc, 138 src_srng_desc, buf_addr_info); 139 status = QDF_STATUS_SUCCESS; 140 } else { 141 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 142 "%s %d -- Monitor Link Desc WBM Release Ring Full", 143 __func__, __LINE__); 144 } 145 done: 146 hal_srng_access_end(hal_soc, hal_ring_hdl); 147 return status; 148 } 149 150 /** 151 * dp_rx_mon_mpdu_pop() - Return a MPDU link descriptor to HW 152 * (WBM), following error handling 153 * 154 * @soc: core DP main context 155 * @mac_id: mac id which is one of 3 mac_ids 156 * @rxdma_dst_ring_desc: void pointer to monitor link descriptor buf addr info 157 * @head_msdu: head of msdu to be popped 158 * @tail_msdu: tail of msdu to be popped 159 * @npackets: number of packet to be popped 160 * @ppdu_id: ppdu id of processing ppdu 161 * @head: head of descs list to be freed 162 * @tail: tail of decs list to be freed 163 * 164 * Return: number of msdu in MPDU to be popped 165 */ 166 static inline uint32_t 167 dp_rx_mon_mpdu_pop(struct dp_soc *soc, uint32_t mac_id, 168 hal_rxdma_desc_t rxdma_dst_ring_desc, qdf_nbuf_t *head_msdu, 169 qdf_nbuf_t *tail_msdu, uint32_t *npackets, uint32_t *ppdu_id, 170 union dp_rx_desc_list_elem_t **head, 171 union dp_rx_desc_list_elem_t **tail) 172 { 173 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 174 void *rx_desc_tlv, *first_rx_desc_tlv = NULL; 175 void *rx_msdu_link_desc; 176 qdf_nbuf_t msdu; 177 qdf_nbuf_t last; 178 struct hal_rx_msdu_list msdu_list; 179 uint16_t num_msdus; 180 uint32_t rx_buf_size, rx_pkt_offset; 181 struct hal_buf_info buf_info; 182 uint32_t rx_bufs_used = 0; 183 uint32_t msdu_ppdu_id, msdu_cnt; 184 uint8_t *data = NULL; 185 uint32_t i; 186 uint32_t total_frag_len = 0, frag_len = 0; 187 bool is_frag, is_first_msdu; 188 bool drop_mpdu = false, is_frag_non_raw = false; 189 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; 190 qdf_dma_addr_t buf_paddr = 0; 191 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; 192 struct cdp_mon_status *rs; 193 struct dp_mon_pdev *mon_pdev; 194 195 if (qdf_unlikely(!dp_pdev)) { 196 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", soc, mac_id); 197 return rx_bufs_used; 198 } 199 200 mon_pdev = dp_pdev->monitor_pdev; 201 msdu = 0; 202 203 last = NULL; 204 205 hal_rx_reo_ent_buf_paddr_get(soc->hal_soc, rxdma_dst_ring_desc, 206 &buf_info, &msdu_cnt); 207 208 rs = &mon_pdev->rx_mon_recv_status; 209 rs->cdp_rs_rxdma_err = false; 210 if ((hal_rx_reo_ent_rxdma_push_reason_get(rxdma_dst_ring_desc) == 211 HAL_RX_WBM_RXDMA_PSH_RSN_ERROR)) { 212 uint8_t rxdma_err = 213 hal_rx_reo_ent_rxdma_error_code_get( 214 rxdma_dst_ring_desc); 215 if (qdf_unlikely((rxdma_err == HAL_RXDMA_ERR_FLUSH_REQUEST) || 216 (rxdma_err == HAL_RXDMA_ERR_MPDU_LENGTH) || 217 (rxdma_err == HAL_RXDMA_ERR_OVERFLOW) || 218 (rxdma_err == HAL_RXDMA_ERR_FCS && mon_pdev->mcopy_mode) || 219 (rxdma_err == HAL_RXDMA_ERR_FCS && 220 mon_pdev->rx_pktlog_cbf))) { 221 drop_mpdu = true; 222 mon_pdev->rx_mon_stats.dest_mpdu_drop++; 223 } 224 rs->cdp_rs_rxdma_err = true; 225 } 226 227 is_frag = false; 228 is_first_msdu = true; 229 230 do { 231 if (!msdu_cnt) { 232 drop_mpdu = true; 233 DP_STATS_INC(dp_pdev, invalid_msdu_cnt, 1); 234 } 235 236 /* WAR for duplicate link descriptors received from HW */ 237 if (qdf_unlikely(mon_pdev->mon_last_linkdesc_paddr == 238 buf_info.paddr)) { 239 mon_pdev->rx_mon_stats.dup_mon_linkdesc_cnt++; 240 return rx_bufs_used; 241 } 242 243 rx_msdu_link_desc = 244 dp_rx_cookie_2_mon_link_desc(dp_pdev, 245 &buf_info, mac_id); 246 247 qdf_assert_always(rx_msdu_link_desc); 248 249 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, 250 &msdu_list, &num_msdus); 251 252 for (i = 0; i < num_msdus; i++) { 253 uint16_t l2_hdr_offset; 254 struct dp_rx_desc *rx_desc = NULL; 255 struct rx_desc_pool *rx_desc_pool; 256 257 rx_desc = dp_rx_get_mon_desc(soc, 258 msdu_list.sw_cookie[i]); 259 260 qdf_assert_always(rx_desc); 261 262 msdu = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc); 263 buf_paddr = dp_rx_mon_get_paddr_from_desc(rx_desc); 264 265 /* WAR for duplicate buffers received from HW */ 266 if (qdf_unlikely(mon_pdev->mon_last_buf_cookie == 267 msdu_list.sw_cookie[i] || 268 DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) || 269 msdu_list.paddr[i] != buf_paddr || 270 !rx_desc->in_use)) { 271 /* Skip duplicate buffer and drop subsequent 272 * buffers in this MPDU 273 */ 274 drop_mpdu = true; 275 mon_pdev->rx_mon_stats.dup_mon_buf_cnt++; 276 mon_pdev->mon_last_linkdesc_paddr = 277 buf_info.paddr; 278 continue; 279 } 280 281 if (rx_desc->unmapped == 0) { 282 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, 283 mac_id, 284 dp_pdev->pdev_id); 285 dp_rx_mon_buffer_unmap(soc, rx_desc, 286 rx_desc_pool->buf_size); 287 rx_desc->unmapped = 1; 288 } 289 290 if (dp_rx_buffer_pool_refill(soc, msdu, 291 rx_desc->pool_id)) { 292 drop_mpdu = true; 293 msdu = NULL; 294 mon_pdev->mon_last_linkdesc_paddr = 295 buf_info.paddr; 296 goto next_msdu; 297 } 298 299 if (drop_mpdu) { 300 mon_pdev->mon_last_linkdesc_paddr = 301 buf_info.paddr; 302 dp_rx_mon_buffer_free(rx_desc); 303 msdu = NULL; 304 goto next_msdu; 305 } 306 307 data = dp_rx_mon_get_buffer_data(rx_desc); 308 rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); 309 310 dp_rx_mon_dest_debug("%pK: i=%d, ppdu_id=%x, num_msdus = %u", 311 soc, i, *ppdu_id, num_msdus); 312 313 if (is_first_msdu) { 314 if (!hal_rx_mpdu_start_tlv_tag_valid( 315 soc->hal_soc, 316 rx_desc_tlv)) { 317 drop_mpdu = true; 318 dp_rx_mon_buffer_free(rx_desc); 319 msdu = NULL; 320 mon_pdev->mon_last_linkdesc_paddr = 321 buf_info.paddr; 322 goto next_msdu; 323 } 324 325 msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get( 326 soc->hal_soc, 327 rx_desc_tlv, 328 rxdma_dst_ring_desc); 329 is_first_msdu = false; 330 331 dp_rx_mon_dest_debug("%pK: msdu_ppdu_id=%x", 332 soc, msdu_ppdu_id); 333 334 if (*ppdu_id > msdu_ppdu_id) 335 dp_rx_mon_dest_debug("%pK: ppdu_id=%d " 336 "msdu_ppdu_id=%d", soc, 337 *ppdu_id, msdu_ppdu_id); 338 339 if ((*ppdu_id < msdu_ppdu_id) && ( 340 (msdu_ppdu_id - *ppdu_id) < 341 NOT_PPDU_ID_WRAP_AROUND)) { 342 *ppdu_id = msdu_ppdu_id; 343 return rx_bufs_used; 344 } else if ((*ppdu_id > msdu_ppdu_id) && ( 345 (*ppdu_id - msdu_ppdu_id) > 346 NOT_PPDU_ID_WRAP_AROUND)) { 347 *ppdu_id = msdu_ppdu_id; 348 return rx_bufs_used; 349 } 350 351 dp_tx_capture_get_user_id(dp_pdev, 352 rx_desc_tlv); 353 354 if (*ppdu_id == msdu_ppdu_id) 355 mon_pdev->rx_mon_stats.ppdu_id_match++; 356 else 357 mon_pdev->rx_mon_stats.ppdu_id_mismatch 358 ++; 359 360 mon_pdev->mon_last_linkdesc_paddr = 361 buf_info.paddr; 362 363 if (dp_rx_mon_alloc_parent_buffer(head_msdu) 364 != QDF_STATUS_SUCCESS) { 365 DP_STATS_INC(dp_pdev, 366 replenish.nbuf_alloc_fail, 367 1); 368 qdf_frag_free(rx_desc_tlv); 369 dp_rx_mon_dest_debug("failed to allocate parent buffer to hold all frag"); 370 drop_mpdu = true; 371 goto next_msdu; 372 } 373 } 374 375 if (hal_rx_desc_is_first_msdu(soc->hal_soc, 376 rx_desc_tlv)) 377 hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc, 378 rx_desc_tlv, 379 &mon_pdev->ppdu_info.rx_status); 380 381 dp_rx_mon_parse_desc_buffer(soc, 382 &(msdu_list.msdu_info[i]), 383 &is_frag, 384 &total_frag_len, 385 &frag_len, 386 &l2_hdr_offset, 387 rx_desc_tlv, 388 &first_rx_desc_tlv, 389 &is_frag_non_raw, data); 390 if (!is_frag && msdu_cnt) 391 msdu_cnt--; 392 393 dp_rx_mon_dest_debug("total_len %u frag_len %u flags %u", 394 total_frag_len, frag_len, 395 msdu_list.msdu_info[i].msdu_flags); 396 397 rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc); 398 399 rx_buf_size = rx_pkt_offset + l2_hdr_offset 400 + frag_len; 401 402 dp_rx_mon_buffer_set_pktlen(msdu, rx_buf_size); 403 #if 0 404 /* Disable it.see packet on msdu done set to 0 */ 405 /* 406 * Check if DMA completed -- msdu_done is the 407 * last bit to be written 408 */ 409 if (!hal_rx_attn_msdu_done_get(rx_desc_tlv)) { 410 411 QDF_TRACE(QDF_MODULE_ID_DP, 412 QDF_TRACE_LEVEL_ERROR, 413 "%s:%d: Pkt Desc", 414 __func__, __LINE__); 415 416 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, 417 QDF_TRACE_LEVEL_ERROR, 418 rx_desc_tlv, 128); 419 420 qdf_assert_always(0); 421 } 422 #endif 423 dp_rx_mon_dest_debug("%pK: rx_pkt_offset=%d, l2_hdr_offset=%d, msdu_len=%d, frag_len %u", 424 soc, rx_pkt_offset, l2_hdr_offset, 425 msdu_list.msdu_info[i].msdu_len, 426 frag_len); 427 428 if (dp_rx_mon_add_msdu_to_list(soc, head_msdu, msdu, 429 &last, rx_desc_tlv, 430 frag_len, l2_hdr_offset) 431 != QDF_STATUS_SUCCESS) { 432 dp_rx_mon_add_msdu_to_list_failure_handler(rx_desc_tlv, 433 dp_pdev, &last, head_msdu, 434 tail_msdu, __func__); 435 drop_mpdu = true; 436 goto next_msdu; 437 } 438 439 next_msdu: 440 mon_pdev->mon_last_buf_cookie = msdu_list.sw_cookie[i]; 441 rx_bufs_used++; 442 dp_rx_add_to_free_desc_list(head, 443 tail, rx_desc); 444 } 445 446 /* 447 * Store the current link buffer into to the local 448 * structure to be used for release purpose. 449 */ 450 hal_rxdma_buff_addr_info_set(soc->hal_soc, rx_link_buf_info, 451 buf_info.paddr, 452 buf_info.sw_cookie, buf_info.rbm); 453 454 hal_rx_mon_next_link_desc_get(soc->hal_soc, rx_msdu_link_desc, 455 &buf_info); 456 if (dp_rx_monitor_link_desc_return(dp_pdev, 457 (hal_buff_addrinfo_t) 458 rx_link_buf_info, 459 mac_id, 460 bm_action) 461 != QDF_STATUS_SUCCESS) 462 dp_err_rl("monitor link desc return failed"); 463 } while (buf_info.paddr); 464 465 dp_rx_mon_init_tail_msdu(head_msdu, msdu, last, tail_msdu); 466 dp_rx_mon_remove_raw_frame_fcs_len(soc, head_msdu, tail_msdu); 467 468 return rx_bufs_used; 469 } 470 471 #if !defined(DISABLE_MON_CONFIG) && \ 472 (defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC) || \ 473 defined(MON_ENABLE_DROP_FOR_MAC)) 474 /** 475 * dp_rx_mon_drop_one_mpdu() - Drop one mpdu from one rxdma monitor destination 476 * ring. 477 * @pdev: DP pdev handle 478 * @mac_id: MAC id which is being currently processed 479 * @rxdma_dst_ring_desc: RXDMA monitor destination ring entry 480 * @head: HEAD if the rx_desc list to be freed 481 * @tail: TAIL of the rx_desc list to be freed 482 * 483 * Return: Number of msdus which are dropped. 484 */ 485 static int dp_rx_mon_drop_one_mpdu(struct dp_pdev *pdev, 486 uint32_t mac_id, 487 hal_rxdma_desc_t rxdma_dst_ring_desc, 488 union dp_rx_desc_list_elem_t **head, 489 union dp_rx_desc_list_elem_t **tail) 490 { 491 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 492 struct dp_soc *soc = pdev->soc; 493 hal_soc_handle_t hal_soc = soc->hal_soc; 494 struct hal_buf_info buf_info; 495 uint32_t msdu_count = 0; 496 uint32_t rx_bufs_used = 0; 497 void *rx_msdu_link_desc; 498 struct hal_rx_msdu_list msdu_list; 499 uint16_t num_msdus; 500 qdf_nbuf_t nbuf; 501 uint32_t i; 502 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; 503 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; 504 struct rx_desc_pool *rx_desc_pool; 505 506 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id); 507 hal_rx_reo_ent_buf_paddr_get(hal_soc, rxdma_dst_ring_desc, 508 &buf_info, &msdu_count); 509 510 do { 511 rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev, 512 &buf_info, 513 mac_id); 514 if (qdf_unlikely(!rx_msdu_link_desc)) { 515 mon_pdev->rx_mon_stats.mon_link_desc_invalid++; 516 return rx_bufs_used; 517 } 518 519 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, 520 &msdu_list, &num_msdus); 521 522 for (i = 0; i < num_msdus; i++) { 523 struct dp_rx_desc *rx_desc; 524 qdf_dma_addr_t buf_paddr; 525 526 rx_desc = dp_rx_get_mon_desc(soc, 527 msdu_list.sw_cookie[i]); 528 529 if (qdf_unlikely(!rx_desc)) { 530 mon_pdev->rx_mon_stats. 531 mon_rx_desc_invalid++; 532 continue; 533 } 534 535 nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc); 536 buf_paddr = 537 dp_rx_mon_get_paddr_from_desc(rx_desc); 538 539 if (qdf_unlikely(!rx_desc->in_use || !nbuf || 540 msdu_list.paddr[i] != 541 buf_paddr)) { 542 mon_pdev->rx_mon_stats. 543 mon_nbuf_sanity_err++; 544 continue; 545 } 546 rx_bufs_used++; 547 548 if (!rx_desc->unmapped) { 549 dp_rx_mon_buffer_unmap(soc, rx_desc, 550 rx_desc_pool->buf_size); 551 rx_desc->unmapped = 1; 552 } 553 554 qdf_nbuf_free(nbuf); 555 dp_rx_add_to_free_desc_list(head, tail, rx_desc); 556 557 if (!(msdu_list.msdu_info[i].msdu_flags & 558 HAL_MSDU_F_MSDU_CONTINUATION)) 559 msdu_count--; 560 } 561 562 /* 563 * Store the current link buffer into to the local 564 * structure to be used for release purpose. 565 */ 566 hal_rxdma_buff_addr_info_set(soc->hal_soc, 567 rx_link_buf_info, 568 buf_info.paddr, 569 buf_info.sw_cookie, 570 buf_info.rbm); 571 572 hal_rx_mon_next_link_desc_get(soc->hal_soc, 573 rx_msdu_link_desc, 574 &buf_info); 575 if (dp_rx_monitor_link_desc_return(pdev, 576 (hal_buff_addrinfo_t) 577 rx_link_buf_info, 578 mac_id, bm_action) != 579 QDF_STATUS_SUCCESS) 580 dp_info_rl("monitor link desc return failed"); 581 } while (buf_info.paddr && msdu_count); 582 583 return rx_bufs_used; 584 } 585 #endif 586 587 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC) 588 /** 589 * dp_rx_mon_check_n_drop_mpdu() - Check if the current MPDU is not from the 590 * PMAC which is being currently processed, and 591 * if yes, drop the MPDU. 592 * @pdev: DP pdev handle 593 * @mac_id: MAC id which is being currently processed 594 * @rxdma_dst_ring_desc: RXDMA monitor destination ring entry 595 * @head: HEAD if the rx_desc list to be freed 596 * @tail: TAIL of the rx_desc list to be freed 597 * @rx_bufs_dropped: Number of msdus dropped 598 * 599 * Return: QDF_STATUS_SUCCESS, if the mpdu was to be dropped 600 * QDF_STATUS_E_INVAL/QDF_STATUS_E_FAILURE, if the mdpu was not dropped 601 */ 602 static QDF_STATUS 603 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id, 604 hal_rxdma_desc_t rxdma_dst_ring_desc, 605 union dp_rx_desc_list_elem_t **head, 606 union dp_rx_desc_list_elem_t **tail, 607 uint32_t *rx_bufs_dropped) 608 { 609 struct dp_soc *soc = pdev->soc; 610 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 611 uint32_t lmac_id = DP_MON_INVALID_LMAC_ID; 612 uint8_t src_link_id; 613 QDF_STATUS status; 614 615 if (mon_pdev->mon_chan_band == REG_BAND_UNKNOWN) 616 goto drop_mpdu; 617 618 lmac_id = pdev->ch_band_lmac_id_mapping[mon_pdev->mon_chan_band]; 619 620 status = hal_rx_reo_ent_get_src_link_id(soc->hal_soc, 621 rxdma_dst_ring_desc, 622 &src_link_id); 623 if (QDF_IS_STATUS_ERROR(status)) 624 return QDF_STATUS_E_INVAL; 625 626 if (src_link_id == lmac_id) 627 return QDF_STATUS_E_INVAL; 628 629 drop_mpdu: 630 *rx_bufs_dropped = dp_rx_mon_drop_one_mpdu(pdev, mac_id, 631 rxdma_dst_ring_desc, 632 head, tail); 633 634 return QDF_STATUS_SUCCESS; 635 } 636 #else 637 static inline QDF_STATUS 638 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id, 639 hal_rxdma_desc_t rxdma_dst_ring_desc, 640 union dp_rx_desc_list_elem_t **head, 641 union dp_rx_desc_list_elem_t **tail, 642 uint32_t *rx_bufs_dropped) 643 { 644 return QDF_STATUS_E_FAILURE; 645 } 646 #endif 647 648 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, 649 uint32_t mac_id, uint32_t quota) 650 { 651 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 652 uint8_t pdev_id; 653 hal_rxdma_desc_t rxdma_dst_ring_desc; 654 hal_soc_handle_t hal_soc; 655 void *mon_dst_srng; 656 union dp_rx_desc_list_elem_t *head = NULL; 657 union dp_rx_desc_list_elem_t *tail = NULL; 658 uint32_t ppdu_id; 659 uint32_t rx_bufs_used; 660 uint32_t mpdu_rx_bufs_used; 661 int mac_for_pdev = mac_id; 662 struct cdp_pdev_mon_stats *rx_mon_stats; 663 struct dp_mon_pdev *mon_pdev; 664 665 if (!pdev) { 666 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", soc, mac_id); 667 return; 668 } 669 670 mon_pdev = pdev->monitor_pdev; 671 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev); 672 673 if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) { 674 dp_rx_mon_dest_err("%pK: : HAL Monitor Destination Ring Init Failed -- %pK", 675 soc, mon_dst_srng); 676 return; 677 } 678 679 hal_soc = soc->hal_soc; 680 681 qdf_assert((hal_soc && pdev)); 682 683 qdf_spin_lock_bh(&mon_pdev->mon_lock); 684 685 if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) { 686 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 687 "%s %d : HAL Mon Dest Ring access Failed -- %pK", 688 __func__, __LINE__, mon_dst_srng); 689 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 690 return; 691 } 692 693 pdev_id = pdev->pdev_id; 694 ppdu_id = mon_pdev->ppdu_info.com_info.ppdu_id; 695 rx_bufs_used = 0; 696 rx_mon_stats = &mon_pdev->rx_mon_stats; 697 698 while (qdf_likely(rxdma_dst_ring_desc = 699 hal_srng_dst_peek(hal_soc, mon_dst_srng))) { 700 qdf_nbuf_t head_msdu, tail_msdu; 701 uint32_t npackets; 702 uint32_t rx_bufs_dropped; 703 704 rx_bufs_dropped = 0; 705 head_msdu = (qdf_nbuf_t)NULL; 706 tail_msdu = (qdf_nbuf_t)NULL; 707 708 if (QDF_STATUS_SUCCESS == 709 dp_rx_mon_check_n_drop_mpdu(pdev, mac_id, 710 rxdma_dst_ring_desc, 711 &head, &tail, 712 &rx_bufs_dropped)) { 713 /* Increment stats */ 714 rx_bufs_used += rx_bufs_dropped; 715 hal_srng_dst_get_next(hal_soc, mon_dst_srng); 716 continue; 717 } 718 719 mpdu_rx_bufs_used = 720 dp_rx_mon_mpdu_pop(soc, mac_id, 721 rxdma_dst_ring_desc, 722 &head_msdu, &tail_msdu, 723 &npackets, &ppdu_id, 724 &head, &tail); 725 726 rx_bufs_used += mpdu_rx_bufs_used; 727 728 if (mpdu_rx_bufs_used) 729 mon_pdev->mon_dest_ring_stuck_cnt = 0; 730 else 731 mon_pdev->mon_dest_ring_stuck_cnt++; 732 733 if (mon_pdev->mon_dest_ring_stuck_cnt > 734 MON_DEST_RING_STUCK_MAX_CNT) { 735 dp_info("destination ring stuck"); 736 dp_info("ppdu_id status=%d dest=%d", 737 mon_pdev->ppdu_info.com_info.ppdu_id, ppdu_id); 738 rx_mon_stats->mon_rx_dest_stuck++; 739 mon_pdev->ppdu_info.com_info.ppdu_id = ppdu_id; 740 continue; 741 } 742 743 if (ppdu_id != mon_pdev->ppdu_info.com_info.ppdu_id) { 744 rx_mon_stats->stat_ring_ppdu_id_hist[ 745 rx_mon_stats->ppdu_id_hist_idx] = 746 mon_pdev->ppdu_info.com_info.ppdu_id; 747 rx_mon_stats->dest_ring_ppdu_id_hist[ 748 rx_mon_stats->ppdu_id_hist_idx] = ppdu_id; 749 rx_mon_stats->ppdu_id_hist_idx = 750 (rx_mon_stats->ppdu_id_hist_idx + 1) & 751 (MAX_PPDU_ID_HIST - 1); 752 dp_rx_mon_dest_debug("%pK: ppdu_id %x != ppdu_info.com_info.ppdu_id %x", 753 soc, ppdu_id, 754 mon_pdev->ppdu_info.com_info.ppdu_id); 755 break; 756 } 757 758 if (qdf_likely((head_msdu) && (tail_msdu))) { 759 rx_mon_stats->dest_mpdu_done++; 760 dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); 761 } 762 763 rxdma_dst_ring_desc = 764 hal_srng_dst_get_next(hal_soc, 765 mon_dst_srng); 766 } 767 768 dp_srng_access_end(int_ctx, soc, mon_dst_srng); 769 770 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 771 772 if (rx_bufs_used) { 773 rx_mon_stats->dest_ppdu_done++; 774 dp_rx_buffers_replenish(soc, mac_id, 775 dp_rxdma_get_mon_buf_ring(pdev, 776 mac_for_pdev), 777 dp_rx_get_mon_desc_pool(soc, mac_id, 778 pdev_id), 779 rx_bufs_used, &head, &tail, false); 780 } 781 } 782 783 QDF_STATUS 784 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id, 785 bool delayed_replenish) 786 { 787 uint8_t pdev_id = pdev->pdev_id; 788 struct dp_soc *soc = pdev->soc; 789 struct dp_srng *mon_buf_ring; 790 uint32_t num_entries; 791 struct rx_desc_pool *rx_desc_pool; 792 QDF_STATUS status = QDF_STATUS_SUCCESS; 793 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 794 795 mon_buf_ring = dp_rxdma_get_mon_buf_ring(pdev, mac_id); 796 797 num_entries = mon_buf_ring->num_entries; 798 799 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev_id); 800 801 dp_debug("Mon RX Desc Pool[%d] entries=%u", pdev_id, num_entries); 802 803 /* Replenish RXDMA monitor buffer ring with 8 buffers only 804 * delayed_replenish_entries is actually 8 but when we call 805 * dp_pdev_rx_buffers_attach() we pass 1 less than 8, hence 806 * added 1 to delayed_replenish_entries to ensure we have 8 807 * entries. Once the monitor VAP is configured we replenish 808 * the complete RXDMA monitor buffer ring. 809 */ 810 if (delayed_replenish) { 811 num_entries = soc_cfg_ctx->delayed_replenish_entries + 1; 812 status = dp_pdev_rx_buffers_attach(soc, mac_id, mon_buf_ring, 813 rx_desc_pool, 814 num_entries - 1); 815 } else { 816 union dp_rx_desc_list_elem_t *tail = NULL; 817 union dp_rx_desc_list_elem_t *desc_list = NULL; 818 819 status = dp_rx_buffers_replenish(soc, mac_id, 820 mon_buf_ring, 821 rx_desc_pool, 822 num_entries, 823 &desc_list, 824 &tail, false); 825 } 826 827 return status; 828 } 829 830 void 831 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id) 832 { 833 uint8_t pdev_id = pdev->pdev_id; 834 struct dp_soc *soc = pdev->soc; 835 struct dp_srng *mon_buf_ring; 836 uint32_t num_entries; 837 struct rx_desc_pool *rx_desc_pool; 838 uint32_t rx_desc_pool_size; 839 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 840 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 841 842 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id]; 843 844 num_entries = mon_buf_ring->num_entries; 845 846 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 847 848 /* If descriptor pool is already initialized, do not initialize it */ 849 if (rx_desc_pool->freelist) 850 return; 851 852 dp_debug("Mon RX Desc buf Pool[%d] init entries=%u", 853 pdev_id, num_entries); 854 855 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) * 856 num_entries; 857 858 rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id); 859 rx_desc_pool->buf_size = RX_MONITOR_BUFFER_SIZE; 860 rx_desc_pool->buf_alignment = RX_MONITOR_BUFFER_ALIGNMENT; 861 /* Enable frag processing if feature is enabled */ 862 dp_rx_enable_mon_dest_frag(rx_desc_pool, true); 863 864 dp_rx_desc_pool_init(soc, mac_id, rx_desc_pool_size, rx_desc_pool); 865 866 mon_pdev->mon_last_linkdesc_paddr = 0; 867 868 mon_pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1; 869 870 /* Attach full monitor mode resources */ 871 dp_full_mon_attach(pdev); 872 } 873 874 static void 875 dp_rx_pdev_mon_buf_desc_pool_deinit(struct dp_pdev *pdev, uint32_t mac_id) 876 { 877 uint8_t pdev_id = pdev->pdev_id; 878 struct dp_soc *soc = pdev->soc; 879 struct rx_desc_pool *rx_desc_pool; 880 881 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 882 883 dp_debug("Mon RX Desc buf Pool[%d] deinit", pdev_id); 884 885 dp_rx_desc_pool_deinit(soc, rx_desc_pool, mac_id); 886 887 /* Detach full monitor mode resources */ 888 dp_full_mon_detach(pdev); 889 } 890 891 static void 892 dp_rx_pdev_mon_buf_desc_pool_free(struct dp_pdev *pdev, uint32_t mac_id) 893 { 894 uint8_t pdev_id = pdev->pdev_id; 895 struct dp_soc *soc = pdev->soc; 896 struct rx_desc_pool *rx_desc_pool; 897 898 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 899 900 dp_debug("Mon RX Buf Desc Pool Free pdev[%d]", pdev_id); 901 902 dp_rx_desc_pool_free(soc, rx_desc_pool); 903 } 904 905 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) 906 { 907 uint8_t pdev_id = pdev->pdev_id; 908 struct dp_soc *soc = pdev->soc; 909 struct rx_desc_pool *rx_desc_pool; 910 911 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 912 913 dp_debug("Mon RX Buf buffers Free pdev[%d]", pdev_id); 914 915 if (rx_desc_pool->rx_mon_dest_frag_enable) 916 dp_rx_desc_frag_free(soc, rx_desc_pool); 917 else 918 dp_rx_desc_nbuf_free(soc, rx_desc_pool, true); 919 } 920 921 QDF_STATUS 922 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id) 923 { 924 uint8_t pdev_id = pdev->pdev_id; 925 struct dp_soc *soc = pdev->soc; 926 struct dp_srng *mon_buf_ring; 927 uint32_t num_entries; 928 struct rx_desc_pool *rx_desc_pool; 929 uint32_t rx_desc_pool_size; 930 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 931 932 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id]; 933 934 num_entries = mon_buf_ring->num_entries; 935 936 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 937 938 dp_debug("Mon RX Desc Pool[%d] entries=%u", 939 pdev_id, num_entries); 940 941 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) * 942 num_entries; 943 944 if (dp_rx_desc_pool_is_allocated(rx_desc_pool) == QDF_STATUS_SUCCESS) 945 return QDF_STATUS_SUCCESS; 946 947 return dp_rx_desc_pool_alloc(soc, rx_desc_pool_size, rx_desc_pool); 948 } 949 950 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 951 uint32_t 952 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id, 953 bool force_flush) 954 { 955 struct dp_soc *soc = pdev->soc; 956 hal_rxdma_desc_t rxdma_dst_ring_desc; 957 hal_soc_handle_t hal_soc; 958 void *mon_dst_srng; 959 union dp_rx_desc_list_elem_t *head = NULL; 960 union dp_rx_desc_list_elem_t *tail = NULL; 961 uint32_t rx_bufs_used = 0; 962 struct rx_desc_pool *rx_desc_pool; 963 uint32_t reap_cnt = 0; 964 uint32_t rx_bufs_dropped; 965 struct dp_mon_pdev *mon_pdev; 966 bool is_rxdma_dst_ring_common; 967 968 if (qdf_unlikely(!soc || !soc->hal_soc)) 969 return reap_cnt; 970 971 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id); 972 973 if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng))) 974 return reap_cnt; 975 976 hal_soc = soc->hal_soc; 977 mon_pdev = pdev->monitor_pdev; 978 979 qdf_spin_lock_bh(&mon_pdev->mon_lock); 980 981 if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dst_srng))) { 982 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 983 return reap_cnt; 984 } 985 986 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id); 987 is_rxdma_dst_ring_common = dp_is_rxdma_dst_ring_common(pdev); 988 989 while ((rxdma_dst_ring_desc = 990 hal_srng_dst_peek(hal_soc, mon_dst_srng)) && 991 (reap_cnt < MON_DROP_REAP_LIMIT || force_flush)) { 992 if (is_rxdma_dst_ring_common && !force_flush) { 993 if (QDF_STATUS_SUCCESS == 994 dp_rx_mon_check_n_drop_mpdu(pdev, mac_id, 995 rxdma_dst_ring_desc, 996 &head, &tail, 997 &rx_bufs_dropped)) { 998 /* Increment stats */ 999 rx_bufs_used += rx_bufs_dropped; 1000 } else { 1001 /* 1002 * If the mpdu was not dropped, we need to 1003 * wait for the entry to be processed, along 1004 * with the status ring entry for the other 1005 * mac. Hence we bail out here. 1006 */ 1007 break; 1008 } 1009 } else { 1010 rx_bufs_used += dp_rx_mon_drop_one_mpdu(pdev, mac_id, 1011 rxdma_dst_ring_desc, 1012 &head, &tail); 1013 } 1014 reap_cnt++; 1015 rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, 1016 mon_dst_srng); 1017 } 1018 1019 hal_srng_access_end(hal_soc, mon_dst_srng); 1020 1021 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1022 1023 if (rx_bufs_used) { 1024 dp_rx_buffers_replenish(soc, mac_id, 1025 dp_rxdma_get_mon_buf_ring(pdev, mac_id), 1026 rx_desc_pool, 1027 rx_bufs_used, &head, &tail, false); 1028 } 1029 1030 return reap_cnt; 1031 } 1032 #else 1033 #if defined(QCA_SUPPORT_FULL_MON) && defined(WIFI_MONITOR_SUPPORT) 1034 uint32_t 1035 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id) 1036 { 1037 struct dp_soc *soc = pdev->soc; 1038 hal_rxdma_desc_t rxdma_dst_ring_desc; 1039 hal_soc_handle_t hal_soc; 1040 void *mon_dst_srng; 1041 union dp_rx_desc_list_elem_t *head = NULL; 1042 union dp_rx_desc_list_elem_t *tail = NULL; 1043 uint32_t rx_bufs_used = 0; 1044 void *rx_msdu_link_desc; 1045 uint16_t num_msdus; 1046 struct hal_rx_msdu_list msdu_list; 1047 qdf_nbuf_t nbuf = NULL; 1048 uint32_t i; 1049 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; 1050 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; 1051 struct rx_desc_pool *rx_desc_pool = NULL; 1052 uint32_t reap_cnt = 0; 1053 struct dp_mon_pdev *mon_pdev; 1054 struct hal_rx_mon_desc_info *desc_info; 1055 1056 if (qdf_unlikely(!soc || !soc->hal_soc)) 1057 return reap_cnt; 1058 1059 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id); 1060 1061 if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng))) 1062 return reap_cnt; 1063 1064 hal_soc = soc->hal_soc; 1065 mon_pdev = pdev->monitor_pdev; 1066 desc_info = mon_pdev->mon_desc; 1067 1068 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id); 1069 1070 while ((rxdma_dst_ring_desc = 1071 hal_srng_dst_peek(hal_soc, mon_dst_srng))) { 1072 qdf_mem_zero(desc_info, sizeof(struct hal_rx_mon_desc_info)); 1073 hal_rx_sw_mon_desc_info_get((struct hal_soc *)soc->hal_soc, 1074 (void *)rxdma_dst_ring_desc, 1075 (void *)desc_info); 1076 1077 if (desc_info->end_of_ppdu) { 1078 rxdma_dst_ring_desc = 1079 hal_srng_dst_get_next(hal_soc, mon_dst_srng); 1080 continue; 1081 } 1082 1083 do { 1084 rx_msdu_link_desc = 1085 dp_rx_cookie_2_mon_link_desc(pdev, 1086 &desc_info-> 1087 link_desc, 1088 mac_id); 1089 1090 if (qdf_unlikely(!rx_msdu_link_desc)) { 1091 mon_pdev->rx_mon_stats.mon_link_desc_invalid++; 1092 goto next_entry; 1093 } 1094 1095 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, 1096 &msdu_list, &num_msdus); 1097 1098 for (i = 0; i < num_msdus; i++) { 1099 struct dp_rx_desc *rx_desc; 1100 qdf_dma_addr_t buf_paddr; 1101 1102 rx_desc = 1103 dp_rx_get_mon_desc(soc, msdu_list. 1104 sw_cookie[i]); 1105 1106 if (qdf_unlikely(!rx_desc)) { 1107 mon_pdev->rx_mon_stats. 1108 mon_rx_desc_invalid++; 1109 continue; 1110 } 1111 1112 nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc); 1113 buf_paddr = 1114 dp_rx_mon_get_paddr_from_desc(rx_desc); 1115 1116 if (qdf_unlikely(!rx_desc->in_use || !nbuf || 1117 msdu_list.paddr[i] != 1118 buf_paddr)) { 1119 mon_pdev->rx_mon_stats. 1120 mon_nbuf_sanity_err++; 1121 continue; 1122 } 1123 rx_bufs_used++; 1124 1125 if (!rx_desc->unmapped) { 1126 dp_rx_mon_buffer_unmap(soc, rx_desc, 1127 rx_desc_pool-> 1128 buf_size); 1129 rx_desc->unmapped = 1; 1130 } 1131 1132 dp_rx_mon_buffer_free(rx_desc); 1133 dp_rx_add_to_free_desc_list(&head, &tail, 1134 rx_desc); 1135 1136 if (!(msdu_list.msdu_info[i].msdu_flags & 1137 HAL_MSDU_F_MSDU_CONTINUATION)) 1138 desc_info->msdu_count--; 1139 } 1140 1141 /* 1142 * Store the current link buffer into to the local 1143 * structure to be used for release purpose. 1144 */ 1145 hal_rxdma_buff_addr_info_set(soc->hal_soc, 1146 rx_link_buf_info, 1147 desc_info->link_desc.paddr, 1148 desc_info->link_desc. 1149 sw_cookie, 1150 desc_info->link_desc.rbm); 1151 1152 hal_rx_mon_next_link_desc_get(soc->hal_soc, 1153 rx_msdu_link_desc, 1154 &desc_info->link_desc); 1155 if (dp_rx_monitor_link_desc_return(pdev, 1156 (hal_buff_addrinfo_t) 1157 rx_link_buf_info, 1158 mac_id, bm_action) != 1159 QDF_STATUS_SUCCESS) 1160 dp_info_rl("monitor link desc return failed"); 1161 } while (desc_info->link_desc.paddr); 1162 1163 next_entry: 1164 reap_cnt++; 1165 rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, 1166 mon_dst_srng); 1167 } 1168 1169 if (rx_bufs_used) { 1170 dp_rx_buffers_replenish(soc, mac_id, 1171 dp_rxdma_get_mon_buf_ring(pdev, mac_id), 1172 rx_desc_pool, 1173 rx_bufs_used, &head, &tail, false); 1174 } 1175 1176 return reap_cnt; 1177 } 1178 #else 1179 uint32_t 1180 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id) 1181 { 1182 return 0; 1183 } 1184 #endif 1185 #endif 1186 1187 static void 1188 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev) 1189 { 1190 struct dp_soc *soc = pdev->soc; 1191 1192 dp_rx_pdev_mon_buf_desc_pool_free(pdev, mac_for_pdev); 1193 dp_hw_link_desc_pool_banks_free(soc, mac_for_pdev); 1194 } 1195 1196 static void 1197 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev) 1198 { 1199 struct dp_soc *soc = pdev->soc; 1200 1201 if (!soc->wlan_cfg_ctx->rxdma1_enable) 1202 return; 1203 1204 dp_rx_pdev_mon_buf_desc_pool_deinit(pdev, mac_for_pdev); 1205 } 1206 1207 static void 1208 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1209 { 1210 struct dp_soc *soc = pdev->soc; 1211 1212 if (!soc->wlan_cfg_ctx->rxdma1_enable || 1213 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 1214 return; 1215 1216 dp_rx_pdev_mon_buf_desc_pool_init(pdev, mac_for_pdev); 1217 dp_link_desc_ring_replenish(soc, mac_for_pdev); 1218 } 1219 1220 static void 1221 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev) 1222 { 1223 struct dp_soc *soc = pdev->soc; 1224 1225 if (!soc->wlan_cfg_ctx->rxdma1_enable) 1226 return; 1227 1228 dp_rx_pdev_mon_buf_buffers_free(pdev, mac_for_pdev); 1229 } 1230 1231 static QDF_STATUS 1232 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev) 1233 { 1234 struct dp_soc *soc = pdev->soc; 1235 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 1236 bool delayed_replenish; 1237 QDF_STATUS status = QDF_STATUS_SUCCESS; 1238 1239 delayed_replenish = soc_cfg_ctx->delayed_replenish_entries ? 1 : 0; 1240 if (!soc->wlan_cfg_ctx->rxdma1_enable || 1241 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 1242 return status; 1243 1244 status = dp_rx_pdev_mon_buf_buffers_alloc(pdev, mac_for_pdev, 1245 delayed_replenish); 1246 if (!QDF_IS_STATUS_SUCCESS(status)) 1247 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed"); 1248 1249 return status; 1250 } 1251 1252 static QDF_STATUS 1253 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1254 { 1255 struct dp_soc *soc = pdev->soc; 1256 QDF_STATUS status = QDF_STATUS_SUCCESS; 1257 1258 if (!soc->wlan_cfg_ctx->rxdma1_enable || 1259 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 1260 return status; 1261 1262 /* Allocate sw rx descriptor pool for monitor RxDMA buffer ring */ 1263 status = dp_rx_pdev_mon_buf_desc_pool_alloc(pdev, mac_for_pdev); 1264 if (!QDF_IS_STATUS_SUCCESS(status)) { 1265 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed"); 1266 goto fail; 1267 } 1268 1269 /* Allocate link descriptors for the monitor link descriptor ring */ 1270 status = dp_hw_link_desc_pool_banks_alloc(soc, mac_for_pdev); 1271 if (!QDF_IS_STATUS_SUCCESS(status)) { 1272 dp_err("dp_hw_link_desc_pool_banks_alloc() failed"); 1273 goto mon_buf_dealloc; 1274 } 1275 1276 return status; 1277 1278 mon_buf_dealloc: 1279 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 1280 fail: 1281 return status; 1282 } 1283 #else 1284 static void 1285 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev) 1286 { 1287 } 1288 1289 static void 1290 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev) 1291 { 1292 } 1293 1294 static void 1295 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1296 { 1297 } 1298 1299 static void 1300 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev) 1301 { 1302 } 1303 1304 static QDF_STATUS 1305 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev) 1306 { 1307 return QDF_STATUS_SUCCESS; 1308 } 1309 1310 static QDF_STATUS 1311 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1312 { 1313 return QDF_STATUS_SUCCESS; 1314 } 1315 1316 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 1317 uint32_t 1318 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id) 1319 { 1320 return 0; 1321 } 1322 #endif 1323 1324 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_NON_MON_PMAC) 1325 static QDF_STATUS 1326 dp_rx_mon_check_n_drop_mpdu(struct dp_pdev *pdev, uint32_t mac_id, 1327 hal_rxdma_desc_t rxdma_dst_ring_desc, 1328 union dp_rx_desc_list_elem_t **head, 1329 union dp_rx_desc_list_elem_t **tail, 1330 uint32_t *rx_bufs_dropped) 1331 { 1332 return QDF_STATUS_E_FAILURE; 1333 } 1334 #endif 1335 #endif 1336 1337 #ifdef WLAN_SOFTUMAC_SUPPORT 1338 static void dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id) 1339 { 1340 struct qdf_mem_multi_page_t *pages; 1341 1342 pages = dp_monitor_get_link_desc_pages(soc, mac_id); 1343 if (!pages) { 1344 dp_err("can not get mon link desc pages"); 1345 QDF_ASSERT(0); 1346 return; 1347 } 1348 1349 if (pages->dma_pages) { 1350 wlan_minidump_remove((void *) 1351 pages->dma_pages->page_v_addr_start, 1352 pages->num_pages * pages->page_size, 1353 soc->ctrl_psoc, 1354 WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING, 1355 "mon hw_link_desc_bank"); 1356 dp_desc_multi_pages_mem_free(soc, QDF_DP_HW_LINK_DESC_TYPE, 1357 pages, 0, false); 1358 } 1359 } 1360 1361 static QDF_STATUS 1362 dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id) 1363 { 1364 struct qdf_mem_multi_page_t *pages; 1365 uint32_t *total_link_descs, total_mem_size; 1366 uint32_t num_entries; 1367 uint32_t max_alloc_size = wlan_cfg_max_alloc_size(soc->wlan_cfg_ctx); 1368 int link_desc_size = hal_get_link_desc_size(soc->hal_soc); 1369 int link_desc_align = hal_get_link_desc_align(soc->hal_soc); 1370 uint8_t minidump_str[MINIDUMP_STR_SIZE]; 1371 1372 pages = dp_monitor_get_link_desc_pages(soc, mac_id); 1373 if (!pages) { 1374 dp_err("can not get mon link desc pages"); 1375 QDF_ASSERT(0); 1376 return QDF_STATUS_E_FAULT; 1377 } 1378 1379 /* If link descriptor banks are allocated, return from here */ 1380 if (pages->num_pages) 1381 return QDF_STATUS_SUCCESS; 1382 1383 num_entries = dp_monitor_get_num_link_desc_ring_entries(soc, mac_id); 1384 total_link_descs = dp_monitor_get_total_link_descs(soc, mac_id); 1385 qdf_str_lcopy(minidump_str, "mon_link_desc_bank", 1386 MINIDUMP_STR_SIZE); 1387 1388 /* Round up to power of 2 */ 1389 *total_link_descs = 1; 1390 while (*total_link_descs < num_entries) 1391 *total_link_descs <<= 1; 1392 1393 dp_init_info("%pK: total_link_descs: %u, link_desc_size: %d", 1394 soc, *total_link_descs, link_desc_size); 1395 1396 total_mem_size = *total_link_descs * link_desc_size; 1397 total_mem_size += link_desc_align; 1398 1399 dp_init_info("%pK: total_mem_size: %d", soc, total_mem_size); 1400 1401 dp_set_max_page_size(pages, max_alloc_size); 1402 dp_desc_multi_pages_mem_alloc(soc, QDF_DP_HW_LINK_DESC_TYPE, 1403 pages, link_desc_size, 1404 *total_link_descs, 0, false); 1405 1406 if (!pages->num_pages) { 1407 dp_err("Multi page alloc fail for mon hw link desc pool"); 1408 return QDF_STATUS_E_FAULT; 1409 } 1410 1411 wlan_minidump_log(pages->dma_pages->page_v_addr_start, 1412 pages->num_pages * pages->page_size, 1413 soc->ctrl_psoc, 1414 WLAN_MD_DP_SRNG_SW2RXDMA_LINK_RING, 1415 "mon hw_link_desc_bank"); 1416 1417 return QDF_STATUS_SUCCESS; 1418 } 1419 1420 static void 1421 dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id) 1422 { 1423 dp_link_desc_ring_replenish(soc, mac_id); 1424 } 1425 #else 1426 static QDF_STATUS 1427 dp_mon_hw_link_desc_bank_alloc(struct dp_soc *soc, uint32_t mac_id) 1428 { 1429 return QDF_STATUS_SUCCESS; 1430 } 1431 1432 static void 1433 dp_mon_hw_link_desc_bank_free(struct dp_soc *soc, uint32_t mac_id) {} 1434 1435 static void 1436 dp_mon_link_desc_ring_replenish(struct dp_soc *soc, int mac_id) {} 1437 #endif 1438 1439 static void 1440 dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev *pdev, int mac_id) 1441 { 1442 struct dp_soc *soc = pdev->soc; 1443 uint8_t pdev_id = pdev->pdev_id; 1444 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1445 1446 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 1447 dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev); 1448 dp_rx_pdev_mon_dest_desc_pool_free(pdev, mac_for_pdev); 1449 } 1450 1451 void dp_rx_pdev_mon_desc_pool_free(struct dp_pdev *pdev) 1452 { 1453 int mac_id; 1454 1455 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++) 1456 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, mac_id); 1457 } 1458 1459 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 1460 static inline void 1461 dp_rx_lpc_lock_create(struct dp_mon_pdev *mon_pdev) 1462 { 1463 qdf_spinlock_create(&mon_pdev->lpc_lock); 1464 } 1465 1466 static inline void 1467 dp_rx_lpc_lock_destroy(struct dp_mon_pdev *mon_pdev) 1468 { 1469 qdf_spinlock_destroy(&mon_pdev->lpc_lock); 1470 } 1471 #else 1472 static inline void 1473 dp_rx_lpc_lock_create(struct dp_mon_pdev *mon_pdev) 1474 { 1475 } 1476 1477 static inline void 1478 dp_rx_lpc_lock_destroy(struct dp_mon_pdev *mon_pdev) 1479 { 1480 } 1481 #endif 1482 1483 static void 1484 dp_rx_pdev_mon_cmn_desc_pool_deinit(struct dp_pdev *pdev, int mac_id) 1485 { 1486 struct dp_soc *soc = pdev->soc; 1487 uint8_t pdev_id = pdev->pdev_id; 1488 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1489 1490 dp_rx_pdev_mon_status_desc_pool_deinit(pdev, mac_for_pdev); 1491 1492 dp_rx_pdev_mon_dest_desc_pool_deinit(pdev, mac_for_pdev); 1493 } 1494 1495 void 1496 dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev *pdev) 1497 { 1498 int mac_id; 1499 1500 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++) 1501 dp_rx_pdev_mon_cmn_desc_pool_deinit(pdev, mac_id); 1502 qdf_spinlock_destroy(&pdev->monitor_pdev->mon_lock); 1503 dp_rx_lpc_lock_destroy(pdev->monitor_pdev); 1504 } 1505 1506 static void 1507 dp_rx_pdev_mon_cmn_desc_pool_init(struct dp_pdev *pdev, int mac_id) 1508 { 1509 struct dp_soc *soc = pdev->soc; 1510 uint32_t mac_for_pdev; 1511 1512 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); 1513 dp_rx_pdev_mon_status_desc_pool_init(pdev, mac_for_pdev); 1514 dp_mon_link_desc_ring_replenish(soc, mac_for_pdev); 1515 1516 dp_rx_pdev_mon_dest_desc_pool_init(pdev, mac_for_pdev); 1517 } 1518 1519 void 1520 dp_rx_pdev_mon_desc_pool_init(struct dp_pdev *pdev) 1521 { 1522 int mac_id; 1523 1524 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++) 1525 dp_rx_pdev_mon_cmn_desc_pool_init(pdev, mac_id); 1526 qdf_spinlock_create(&pdev->monitor_pdev->mon_lock); 1527 dp_rx_lpc_lock_create(pdev->monitor_pdev); 1528 } 1529 1530 void 1531 dp_rx_pdev_mon_buffers_free(struct dp_pdev *pdev) 1532 { 1533 int mac_id; 1534 int mac_for_pdev; 1535 uint8_t pdev_id = pdev->pdev_id; 1536 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = pdev->soc->wlan_cfg_ctx; 1537 1538 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_status_rings_per_pdev; 1539 mac_id++) { 1540 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1541 pdev_id); 1542 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev); 1543 } 1544 1545 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_dst_rings_per_pdev; 1546 mac_id++) { 1547 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1548 pdev_id); 1549 dp_rx_pdev_mon_dest_buffers_free(pdev, mac_for_pdev); 1550 } 1551 pdev->monitor_pdev->pdev_mon_init = 0; 1552 } 1553 1554 QDF_STATUS 1555 dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev) 1556 { 1557 int mac_id; 1558 int mac_for_pdev; 1559 QDF_STATUS status = QDF_STATUS_SUCCESS; 1560 uint8_t pdev_id = pdev->pdev_id; 1561 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = pdev->soc->wlan_cfg_ctx; 1562 1563 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_status_rings_per_pdev; 1564 mac_id++) { 1565 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1566 pdev_id); 1567 status = dp_rx_pdev_mon_status_buffers_alloc(pdev, 1568 mac_for_pdev); 1569 if (!QDF_IS_STATUS_SUCCESS(status)) { 1570 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed"); 1571 goto mon_status_buf_fail; 1572 } 1573 } 1574 1575 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_dst_rings_per_pdev; 1576 mac_id++) { 1577 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1578 pdev_id); 1579 status = dp_rx_pdev_mon_dest_buffers_alloc(pdev, mac_for_pdev); 1580 if (!QDF_IS_STATUS_SUCCESS(status)) 1581 goto mon_stat_buf_dealloc; 1582 } 1583 1584 return status; 1585 1586 mon_stat_buf_dealloc: 1587 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev); 1588 mon_status_buf_fail: 1589 return status; 1590 } 1591 1592 static QDF_STATUS 1593 dp_rx_pdev_mon_cmn_desc_pool_alloc(struct dp_pdev *pdev, int mac_id) 1594 { 1595 struct dp_soc *soc = pdev->soc; 1596 uint8_t pdev_id = pdev->pdev_id; 1597 uint32_t mac_for_pdev; 1598 QDF_STATUS status; 1599 1600 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1601 1602 /* Allocate sw rx descriptor pool for monitor status ring */ 1603 status = dp_rx_pdev_mon_status_desc_pool_alloc(pdev, mac_for_pdev); 1604 if (!QDF_IS_STATUS_SUCCESS(status)) { 1605 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed"); 1606 goto fail; 1607 } 1608 1609 /* Allocate hw link desc bank for monitor mode for 1610 * SOFTUMAC architecture. 1611 */ 1612 status = dp_mon_hw_link_desc_bank_alloc(soc, mac_for_pdev); 1613 if (!QDF_IS_STATUS_SUCCESS(status)) { 1614 dp_err("dp_mon_hw_link_desc_bank_alloc() failed"); 1615 goto mon_status_dealloc; 1616 } 1617 1618 status = dp_rx_pdev_mon_dest_desc_pool_alloc(pdev, mac_for_pdev); 1619 if (!QDF_IS_STATUS_SUCCESS(status)) 1620 goto link_desc_bank_free; 1621 1622 return status; 1623 1624 link_desc_bank_free: 1625 dp_mon_hw_link_desc_bank_free(soc, mac_for_pdev); 1626 mon_status_dealloc: 1627 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 1628 fail: 1629 return status; 1630 } 1631 1632 QDF_STATUS 1633 dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev) 1634 { 1635 QDF_STATUS status; 1636 int mac_id, count; 1637 1638 for (mac_id = 0; mac_id < NUM_RXDMA_STATUS_RINGS_PER_PDEV; mac_id++) { 1639 status = dp_rx_pdev_mon_cmn_desc_pool_alloc(pdev, mac_id); 1640 if (!QDF_IS_STATUS_SUCCESS(status)) { 1641 dp_rx_mon_dest_err("%pK: %d failed", 1642 pdev->soc, mac_id); 1643 1644 for (count = 0; count < mac_id; count++) 1645 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, count); 1646 1647 return status; 1648 } 1649 } 1650 return status; 1651 } 1652 1653 #ifdef QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT 1654 static inline void 1655 hal_rx_populate_buf_info(struct dp_soc *soc, 1656 struct hal_rx_mon_dest_buf_info *buf_info, 1657 void *rx_desc) 1658 { 1659 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc, 1660 (uint8_t *)buf_info, 1661 sizeof(*buf_info)); 1662 } 1663 1664 static inline uint8_t 1665 hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc *soc, 1666 struct hal_rx_mon_dest_buf_info *buf_info, 1667 void *rx_desc, bool is_first_frag) 1668 { 1669 if (is_first_frag) 1670 return buf_info->l2_hdr_pad; 1671 else 1672 return DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 1673 } 1674 #else 1675 static inline void 1676 hal_rx_populate_buf_info(struct dp_soc *soc, 1677 struct hal_rx_mon_dest_buf_info *buf_info, 1678 void *rx_desc) 1679 { 1680 if (hal_rx_tlv_decap_format_get(soc->hal_soc, rx_desc) == 1681 HAL_HW_RX_DECAP_FORMAT_RAW) 1682 buf_info->is_decap_raw = 1; 1683 1684 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc)) 1685 buf_info->mpdu_len_err = 1; 1686 } 1687 1688 static inline uint8_t 1689 hal_rx_frag_msdu_get_l2_hdr_offset(struct dp_soc *soc, 1690 struct hal_rx_mon_dest_buf_info *buf_info, 1691 void *rx_desc, bool is_first_frag) 1692 { 1693 return hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, rx_desc); 1694 } 1695 #endif 1696 1697 static inline 1698 void dp_rx_msdus_set_payload(struct dp_soc *soc, qdf_nbuf_t msdu, 1699 uint8_t l2_hdr_offset) 1700 { 1701 uint8_t *data; 1702 uint32_t rx_pkt_offset; 1703 1704 data = qdf_nbuf_data(msdu); 1705 rx_pkt_offset = dp_rx_mon_get_rx_pkt_tlv_size(soc); 1706 qdf_nbuf_pull_head(msdu, rx_pkt_offset + l2_hdr_offset); 1707 } 1708 1709 static inline qdf_nbuf_t 1710 dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, 1711 uint32_t mac_id, 1712 qdf_nbuf_t head_msdu, 1713 qdf_nbuf_t last_msdu, 1714 struct cdp_mon_status *rx_status) 1715 { 1716 qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list; 1717 uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len, 1718 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir, 1719 is_amsdu, is_first_frag, amsdu_pad; 1720 void *rx_desc; 1721 char *hdr_desc; 1722 unsigned char *dest; 1723 struct ieee80211_frame *wh; 1724 struct ieee80211_qoscntl *qos; 1725 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1726 struct dp_mon_pdev *mon_pdev; 1727 struct hal_rx_mon_dest_buf_info buf_info; 1728 uint8_t l2_hdr_offset; 1729 1730 head_frag_list = NULL; 1731 mpdu_buf = NULL; 1732 1733 if (qdf_unlikely(!dp_pdev)) { 1734 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", 1735 soc, mac_id); 1736 return NULL; 1737 } 1738 1739 mon_pdev = dp_pdev->monitor_pdev; 1740 1741 /* The nbuf has been pulled just beyond the status and points to the 1742 * payload 1743 */ 1744 if (!head_msdu) 1745 goto mpdu_stitch_fail; 1746 1747 msdu_orig = head_msdu; 1748 1749 rx_desc = qdf_nbuf_data(msdu_orig); 1750 qdf_mem_zero(&buf_info, sizeof(buf_info)); 1751 hal_rx_populate_buf_info(soc, &buf_info, rx_desc); 1752 1753 if (buf_info.mpdu_len_err) { 1754 /* It looks like there is some issue on MPDU len err */ 1755 /* Need further investigate if drop the packet */ 1756 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 1757 return NULL; 1758 } 1759 1760 rx_desc = qdf_nbuf_data(last_msdu); 1761 1762 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc, 1763 rx_desc); 1764 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err; 1765 1766 /* Fill out the rx_status from the PPDU start and end fields */ 1767 /* HAL_RX_GET_PPDU_STATUS(soc, mac_id, rx_status); */ 1768 1769 rx_desc = qdf_nbuf_data(head_msdu); 1770 1771 /* Easy case - The MSDU status indicates that this is a non-decapped 1772 * packet in RAW mode. 1773 */ 1774 if (buf_info.is_decap_raw) { 1775 /* Note that this path might suffer from headroom unavailabilty 1776 * - but the RX status is usually enough 1777 */ 1778 1779 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset(soc, 1780 &buf_info, 1781 rx_desc, 1782 true); 1783 dp_rx_msdus_set_payload(soc, head_msdu, l2_hdr_offset); 1784 1785 dp_rx_mon_dest_debug("%pK: decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK", 1786 soc, head_msdu, head_msdu->next, 1787 last_msdu, last_msdu->next); 1788 1789 mpdu_buf = head_msdu; 1790 1791 prev_buf = mpdu_buf; 1792 1793 frag_list_sum_len = 0; 1794 msdu = qdf_nbuf_next(head_msdu); 1795 is_first_frag = 1; 1796 1797 while (msdu) { 1798 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset( 1799 soc, &buf_info, 1800 rx_desc, false); 1801 dp_rx_msdus_set_payload(soc, msdu, l2_hdr_offset); 1802 1803 if (is_first_frag) { 1804 is_first_frag = 0; 1805 head_frag_list = msdu; 1806 } 1807 1808 frag_list_sum_len += qdf_nbuf_len(msdu); 1809 1810 /* Maintain the linking of the cloned MSDUS */ 1811 qdf_nbuf_set_next_ext(prev_buf, msdu); 1812 1813 /* Move to the next */ 1814 prev_buf = msdu; 1815 msdu = qdf_nbuf_next(msdu); 1816 } 1817 1818 qdf_nbuf_trim_tail(prev_buf, HAL_RX_FCS_LEN); 1819 1820 /* If there were more fragments to this RAW frame */ 1821 if (head_frag_list) { 1822 if (frag_list_sum_len < 1823 sizeof(struct ieee80211_frame_min_one)) { 1824 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 1825 return NULL; 1826 } 1827 frag_list_sum_len -= HAL_RX_FCS_LEN; 1828 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, 1829 frag_list_sum_len); 1830 qdf_nbuf_set_next(mpdu_buf, NULL); 1831 } 1832 1833 goto mpdu_stitch_done; 1834 } 1835 1836 /* Decap mode: 1837 * Calculate the amount of header in decapped packet to knock off based 1838 * on the decap type and the corresponding number of raw bytes to copy 1839 * status header 1840 */ 1841 rx_desc = qdf_nbuf_data(head_msdu); 1842 1843 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc); 1844 1845 dp_rx_mon_dest_debug("%pK: decap format not raw", soc); 1846 1847 /* Base size */ 1848 wifi_hdr_len = sizeof(struct ieee80211_frame); 1849 wh = (struct ieee80211_frame *)hdr_desc; 1850 1851 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 1852 1853 if (dir == IEEE80211_FC1_DIR_DSTODS) 1854 wifi_hdr_len += 6; 1855 1856 is_amsdu = 0; 1857 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) { 1858 qos = (struct ieee80211_qoscntl *) 1859 (hdr_desc + wifi_hdr_len); 1860 wifi_hdr_len += 2; 1861 1862 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU); 1863 } 1864 1865 /* Calculate security header length based on 'Protected' 1866 * and 'EXT_IV' flag 1867 */ 1868 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1869 char *iv = (char *)wh + wifi_hdr_len; 1870 1871 if (iv[3] & KEY_EXTIV) 1872 sec_hdr_len = 8; 1873 else 1874 sec_hdr_len = 4; 1875 } else { 1876 sec_hdr_len = 0; 1877 } 1878 wifi_hdr_len += sec_hdr_len; 1879 1880 /* MSDU related stuff LLC - AMSDU subframe header etc */ 1881 msdu_llc_len = is_amsdu ? (14 + 8) : 8; 1882 1883 mpdu_buf_len = wifi_hdr_len + msdu_llc_len; 1884 1885 /* "Decap" header to remove from MSDU buffer */ 1886 decap_hdr_pull_bytes = 14; 1887 1888 /* Allocate a new nbuf for holding the 802.11 header retrieved from the 1889 * status of the now decapped first msdu. Leave enough headroom for 1890 * accommodating any radio-tap /prism like PHY header 1891 */ 1892 mpdu_buf = qdf_nbuf_alloc(soc->osdev, 1893 MAX_MONITOR_HEADER + mpdu_buf_len, 1894 MAX_MONITOR_HEADER, 4, FALSE); 1895 1896 if (!mpdu_buf) 1897 goto mpdu_stitch_done; 1898 1899 /* Copy the MPDU related header and enc headers into the first buffer 1900 * - Note that there can be a 2 byte pad between heaader and enc header 1901 */ 1902 1903 prev_buf = mpdu_buf; 1904 dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len); 1905 if (!dest) 1906 goto mpdu_stitch_fail; 1907 1908 qdf_mem_copy(dest, hdr_desc, wifi_hdr_len); 1909 hdr_desc += wifi_hdr_len; 1910 1911 #if 0 1912 dest = qdf_nbuf_put_tail(prev_buf, sec_hdr_len); 1913 adf_os_mem_copy(dest, hdr_desc, sec_hdr_len); 1914 hdr_desc += sec_hdr_len; 1915 #endif 1916 1917 /* The first LLC len is copied into the MPDU buffer */ 1918 frag_list_sum_len = 0; 1919 1920 msdu_orig = head_msdu; 1921 is_first_frag = 1; 1922 amsdu_pad = 0; 1923 1924 while (msdu_orig) { 1925 1926 /* TODO: intra AMSDU padding - do we need it ??? */ 1927 1928 msdu = msdu_orig; 1929 1930 if (is_first_frag) { 1931 head_frag_list = msdu; 1932 } else { 1933 /* Reload the hdr ptr only on non-first MSDUs */ 1934 rx_desc = qdf_nbuf_data(msdu_orig); 1935 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, 1936 rx_desc); 1937 } 1938 1939 /* Copy this buffers MSDU related status into the prev buffer */ 1940 1941 if (is_first_frag) 1942 is_first_frag = 0; 1943 1944 /* Update protocol and flow tag for MSDU */ 1945 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, 1946 msdu_orig, rx_desc); 1947 1948 dest = qdf_nbuf_put_tail(prev_buf, 1949 msdu_llc_len + amsdu_pad); 1950 1951 if (!dest) 1952 goto mpdu_stitch_fail; 1953 1954 dest += amsdu_pad; 1955 qdf_mem_copy(dest, hdr_desc, msdu_llc_len); 1956 1957 l2_hdr_offset = hal_rx_frag_msdu_get_l2_hdr_offset(soc, 1958 &buf_info, 1959 rx_desc, 1960 true); 1961 dp_rx_msdus_set_payload(soc, msdu, l2_hdr_offset); 1962 1963 /* Push the MSDU buffer beyond the decap header */ 1964 qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes); 1965 frag_list_sum_len += msdu_llc_len + qdf_nbuf_len(msdu) 1966 + amsdu_pad; 1967 1968 /* Set up intra-AMSDU pad to be added to start of next buffer - 1969 * AMSDU pad is 4 byte pad on AMSDU subframe 1970 */ 1971 amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3; 1972 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 1973 1974 /* TODO FIXME How do we handle MSDUs that have fraglist - Should 1975 * probably iterate all the frags cloning them along the way and 1976 * and also updating the prev_buf pointer 1977 */ 1978 1979 /* Move to the next */ 1980 prev_buf = msdu; 1981 msdu_orig = qdf_nbuf_next(msdu_orig); 1982 } 1983 1984 #if 0 1985 /* Add in the trailer section - encryption trailer + FCS */ 1986 qdf_nbuf_put_tail(prev_buf, HAL_RX_FCS_LEN); 1987 frag_list_sum_len += HAL_RX_FCS_LEN; 1988 #endif 1989 1990 frag_list_sum_len -= msdu_llc_len; 1991 1992 /* TODO: Convert this to suitable adf routines */ 1993 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, 1994 frag_list_sum_len); 1995 1996 dp_rx_mon_dest_debug("%pK: mpdu_buf %pK mpdu_buf->len %u", 1997 soc, mpdu_buf, mpdu_buf->len); 1998 1999 mpdu_stitch_done: 2000 /* Check if this buffer contains the PPDU end status for TSF */ 2001 /* Need revist this code to see where we can get tsf timestamp */ 2002 #if 0 2003 /* PPDU end TLV will be retrieved from monitor status ring */ 2004 last_mpdu = 2005 (*(((u_int32_t *)&rx_desc->attention)) & 2006 RX_ATTENTION_0_LAST_MPDU_MASK) >> 2007 RX_ATTENTION_0_LAST_MPDU_LSB; 2008 2009 if (last_mpdu) 2010 rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp; 2011 2012 #endif 2013 return mpdu_buf; 2014 2015 mpdu_stitch_fail: 2016 if ((mpdu_buf) && !buf_info.is_decap_raw) { 2017 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail mpdu_buf %pK", 2018 soc, mpdu_buf); 2019 /* Free the head buffer */ 2020 qdf_nbuf_free(mpdu_buf); 2021 } 2022 return NULL; 2023 } 2024 2025 #ifdef DP_RX_MON_MEM_FRAG 2026 /** 2027 * dp_rx_mon_fraglist_prepare() - Prepare nbuf fraglist from chained skb 2028 * 2029 * @head_msdu: Parent SKB 2030 * @tail_msdu: Last skb in the chained list 2031 * 2032 * Return: Void 2033 */ 2034 void dp_rx_mon_fraglist_prepare(qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu) 2035 { 2036 qdf_nbuf_t msdu, mpdu_buf, head_frag_list; 2037 uint32_t frag_list_sum_len; 2038 2039 dp_err("[%s][%d] decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK", 2040 __func__, __LINE__, head_msdu, head_msdu->next, 2041 tail_msdu, tail_msdu->next); 2042 2043 /* Single skb accommodating MPDU worth Data */ 2044 if (tail_msdu == head_msdu) 2045 return; 2046 2047 mpdu_buf = head_msdu; 2048 frag_list_sum_len = 0; 2049 2050 msdu = qdf_nbuf_next(head_msdu); 2051 /* msdu can't be NULL here as it is multiple skb case here */ 2052 2053 /* Head frag list to point to second skb */ 2054 head_frag_list = msdu; 2055 2056 while (msdu) { 2057 frag_list_sum_len += qdf_nbuf_len(msdu); 2058 msdu = qdf_nbuf_next(msdu); 2059 } 2060 2061 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, frag_list_sum_len); 2062 2063 /* Make Parent skb next to NULL */ 2064 qdf_nbuf_set_next(mpdu_buf, NULL); 2065 } 2066 2067 /** 2068 * dp_rx_mon_frag_restitch_mpdu_from_msdus() - Restitch logic to 2069 * convert to 802.3 header and adjust frag memory pointing to 2070 * dot3 header and payload in case of Non-Raw frame. 2071 * 2072 * @soc: struct dp_soc * 2073 * @mac_id: MAC id 2074 * @head_msdu: MPDU containing all MSDU as a frag 2075 * @tail_msdu: last skb which accommodate MPDU info 2076 * @rx_status: struct cdp_mon_status * 2077 * 2078 * Return: Adjusted nbuf containing MPDU worth info. 2079 */ 2080 static inline qdf_nbuf_t 2081 dp_rx_mon_frag_restitch_mpdu_from_msdus(struct dp_soc *soc, 2082 uint32_t mac_id, 2083 qdf_nbuf_t head_msdu, 2084 qdf_nbuf_t tail_msdu, 2085 struct cdp_mon_status *rx_status) 2086 { 2087 uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len, 2088 mpdu_buf_len, decap_hdr_pull_bytes, dir, 2089 is_amsdu, amsdu_pad, frag_size, tot_msdu_len; 2090 qdf_frag_t rx_desc, rx_src_desc, rx_dest_desc, frag_addr; 2091 char *hdr_desc; 2092 uint8_t num_frags, frags_iter, l2_hdr_offset; 2093 struct ieee80211_frame *wh; 2094 struct ieee80211_qoscntl *qos; 2095 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 2096 int16_t frag_page_offset = 0; 2097 struct hal_rx_mon_dest_buf_info buf_info; 2098 uint32_t pad_byte_pholder = 0; 2099 qdf_nbuf_t msdu_curr; 2100 uint16_t rx_mon_tlv_size = soc->rx_mon_pkt_tlv_size; 2101 struct dp_mon_pdev *mon_pdev; 2102 2103 if (qdf_unlikely(!dp_pdev)) { 2104 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", 2105 soc, mac_id); 2106 return NULL; 2107 } 2108 2109 mon_pdev = dp_pdev->monitor_pdev; 2110 qdf_mem_zero(&buf_info, sizeof(struct hal_rx_mon_dest_buf_info)); 2111 2112 if (!head_msdu || !tail_msdu) 2113 goto mpdu_stitch_fail; 2114 2115 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size; 2116 2117 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc)) { 2118 /* It looks like there is some issue on MPDU len err */ 2119 /* Need further investigate if drop the packet */ 2120 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 2121 return NULL; 2122 } 2123 2124 /* Look for FCS error */ 2125 num_frags = qdf_nbuf_get_nr_frags(tail_msdu); 2126 rx_desc = qdf_nbuf_get_frag_addr(tail_msdu, num_frags - 1) - 2127 rx_mon_tlv_size; 2128 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc, 2129 rx_desc); 2130 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err; 2131 2132 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size; 2133 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc, 2134 (uint8_t *)&buf_info, 2135 sizeof(buf_info)); 2136 2137 /* Easy case - The MSDU status indicates that this is a non-decapped 2138 * packet in RAW mode. 2139 */ 2140 if (buf_info.is_decap_raw == 1) { 2141 if (qdf_unlikely(mon_pdev->ppdu_info.rx_status.rs_fcs_err)) { 2142 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc); 2143 wh = (struct ieee80211_frame *)hdr_desc; 2144 if ((wh->i_fc[0] & QDF_IEEE80211_FC0_VERSION_MASK) != 2145 QDF_IEEE80211_FC0_VERSION_0) { 2146 DP_STATS_INC(dp_pdev, dropped.mon_ver_err, 1); 2147 return NULL; 2148 } 2149 } 2150 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu); 2151 goto mpdu_stitch_done; 2152 } 2153 2154 l2_hdr_offset = DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 2155 2156 /* Decap mode: 2157 * Calculate the amount of header in decapped packet to knock off based 2158 * on the decap type and the corresponding number of raw bytes to copy 2159 * status header 2160 */ 2161 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc); 2162 2163 dp_rx_mon_dest_debug("%pK: decap format not raw", soc); 2164 2165 /* Base size */ 2166 wifi_hdr_len = sizeof(struct ieee80211_frame); 2167 wh = (struct ieee80211_frame *)hdr_desc; 2168 2169 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 2170 2171 if (dir == IEEE80211_FC1_DIR_DSTODS) 2172 wifi_hdr_len += 6; 2173 2174 is_amsdu = 0; 2175 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) { 2176 qos = (struct ieee80211_qoscntl *) 2177 (hdr_desc + wifi_hdr_len); 2178 wifi_hdr_len += 2; 2179 2180 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU); 2181 } 2182 2183 /*Calculate security header length based on 'Protected' 2184 * and 'EXT_IV' flag 2185 */ 2186 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 2187 char *iv = (char *)wh + wifi_hdr_len; 2188 2189 if (iv[3] & KEY_EXTIV) 2190 sec_hdr_len = 8; 2191 else 2192 sec_hdr_len = 4; 2193 } else { 2194 sec_hdr_len = 0; 2195 } 2196 wifi_hdr_len += sec_hdr_len; 2197 2198 /* MSDU related stuff LLC - AMSDU subframe header etc */ 2199 msdu_llc_len = is_amsdu ? (14 + 8) : 8; 2200 2201 mpdu_buf_len = wifi_hdr_len + msdu_llc_len; 2202 2203 /* "Decap" header to remove from MSDU buffer */ 2204 decap_hdr_pull_bytes = 14; 2205 2206 amsdu_pad = 0; 2207 tot_msdu_len = 0; 2208 2209 /* 2210 * keeping first MSDU ops outside of loop to avoid multiple 2211 * check handling 2212 */ 2213 2214 /* Construct src header */ 2215 rx_src_desc = hdr_desc; 2216 2217 /* 2218 * Update protocol and flow tag for MSDU 2219 * update frag index in ctx_idx field. 2220 * Reset head pointer data of nbuf before updating. 2221 */ 2222 QDF_NBUF_CB_RX_CTX_ID(head_msdu) = 0; 2223 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, head_msdu, rx_desc); 2224 2225 /* Construct destination address */ 2226 frag_addr = qdf_nbuf_get_frag_addr(head_msdu, 0); 2227 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0); 2228 /* We will come here in 2 scenario: 2229 * 1. First MSDU of MPDU with single buffer 2230 * 2. First buffer of First MSDU of MPDU with continuation 2231 * 2232 * ------------------------------------------------------------ 2233 * | SINGLE BUFFER (<= RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN)| 2234 * ------------------------------------------------------------ 2235 * 2236 * ------------------------------------------------------------ 2237 * | First BUFFER with Continuation | ... | 2238 * | (RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN) | | 2239 * ------------------------------------------------------------ 2240 */ 2241 pad_byte_pholder = 2242 (RX_MONITOR_BUFFER_SIZE - soc->rx_mon_pkt_tlv_size) - frag_size; 2243 /* Construct destination address 2244 * -------------------------------------------------------------- 2245 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload | 2246 * | | / | 2247 * | >Frag address points here / | 2248 * | \ / | 2249 * | \ This bytes needs to / | 2250 * | \ removed to frame pkt / | 2251 * | ----------------------- | 2252 * | | | 2253 * | | | 2254 * | WIFI +LLC HDR will be added here <-| | 2255 * | | | | 2256 * | >Dest addr will point | | 2257 * | somewhere in this area | | 2258 * -------------------------------------------------------------- 2259 */ 2260 rx_dest_desc = 2261 (frag_addr + decap_hdr_pull_bytes + l2_hdr_offset) - 2262 mpdu_buf_len; 2263 /* Add WIFI and LLC header for 1st MSDU of MPDU */ 2264 qdf_mem_copy(rx_dest_desc, rx_src_desc, mpdu_buf_len); 2265 2266 frag_page_offset = 2267 (decap_hdr_pull_bytes + l2_hdr_offset) - mpdu_buf_len; 2268 2269 qdf_nbuf_move_frag_page_offset(head_msdu, 0, frag_page_offset); 2270 2271 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0); 2272 2273 if (buf_info.first_buffer && buf_info.last_buffer) { 2274 /* MSDU with single buffer */ 2275 amsdu_pad = frag_size & 0x3; 2276 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 2277 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) { 2278 char *frag_addr_temp; 2279 2280 qdf_nbuf_trim_add_frag_size(head_msdu, 0, amsdu_pad, 2281 0); 2282 frag_addr_temp = 2283 (char *)qdf_nbuf_get_frag_addr(head_msdu, 0); 2284 frag_addr_temp = (frag_addr_temp + 2285 qdf_nbuf_get_frag_size_by_idx(head_msdu, 0)) - 2286 amsdu_pad; 2287 qdf_mem_zero(frag_addr_temp, amsdu_pad); 2288 amsdu_pad = 0; 2289 } 2290 } else { 2291 /* 2292 * First buffer of Continuation frame and hence 2293 * amsdu_padding doesn't need to be added 2294 * Increase tot_msdu_len so that amsdu_pad byte 2295 * will be calculated for last frame of MSDU 2296 */ 2297 tot_msdu_len = frag_size; 2298 amsdu_pad = 0; 2299 } 2300 2301 /* Here amsdu_pad byte will have some value if 1sf buffer was 2302 * Single buffer MSDU and dint had pholder to adjust amsdu padding 2303 * byte in the end 2304 * So dont initialize to ZERO here 2305 */ 2306 pad_byte_pholder = 0; 2307 for (msdu_curr = head_msdu; msdu_curr;) { 2308 /* frag_iter will start from 0 for second skb onwards */ 2309 if (msdu_curr == head_msdu) 2310 frags_iter = 1; 2311 else 2312 frags_iter = 0; 2313 2314 num_frags = qdf_nbuf_get_nr_frags(msdu_curr); 2315 2316 for (; frags_iter < num_frags; frags_iter++) { 2317 /* Construct destination address 2318 * ---------------------------------------------------------- 2319 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload | Pad | 2320 * | | (First buffer) | | | 2321 * | | / / | 2322 * | >Frag address points here / / | 2323 * | \ / / | 2324 * | \ This bytes needs to / / | 2325 * | \ removed to frame pkt/ / | 2326 * | ---------------------- / | 2327 * | | / Add | 2328 * | | / amsdu pad | 2329 * | LLC HDR will be added here <-| | Byte for | 2330 * | | | | last frame | 2331 * | >Dest addr will point | | if space | 2332 * | somewhere in this area | | available | 2333 * | And amsdu_pad will be created if | | | 2334 * | dint get added in last buffer | | | 2335 * | (First Buffer) | | | 2336 * ---------------------------------------------------------- 2337 */ 2338 frag_addr = 2339 qdf_nbuf_get_frag_addr(msdu_curr, frags_iter); 2340 rx_desc = frag_addr - rx_mon_tlv_size; 2341 2342 /* 2343 * Update protocol and flow tag for MSDU 2344 * update frag index in ctx_idx field 2345 */ 2346 QDF_NBUF_CB_RX_CTX_ID(msdu_curr) = frags_iter; 2347 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, 2348 msdu_curr, rx_desc); 2349 2350 /* Read buffer info from stored data in tlvs */ 2351 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc, 2352 (uint8_t *)&buf_info, 2353 sizeof(buf_info)); 2354 2355 frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_curr, 2356 frags_iter); 2357 2358 /* If Middle buffer, dont add any header */ 2359 if ((!buf_info.first_buffer) && 2360 (!buf_info.last_buffer)) { 2361 tot_msdu_len += frag_size; 2362 amsdu_pad = 0; 2363 pad_byte_pholder = 0; 2364 continue; 2365 } 2366 2367 /* Calculate if current buffer has placeholder 2368 * to accommodate amsdu pad byte 2369 */ 2370 pad_byte_pholder = 2371 (RX_MONITOR_BUFFER_SIZE - soc->rx_mon_pkt_tlv_size) 2372 - frag_size; 2373 /* 2374 * We will come here only only three condition: 2375 * 1. Msdu with single Buffer 2376 * 2. First buffer in case MSDU is spread in multiple 2377 * buffer 2378 * 3. Last buffer in case MSDU is spread in multiple 2379 * buffer 2380 * 2381 * First buffER | Last buffer 2382 * Case 1: 1 | 1 2383 * Case 2: 1 | 0 2384 * Case 3: 0 | 1 2385 * 2386 * In 3rd case only l2_hdr_padding byte will be Zero and 2387 * in other case, It will be 2 Bytes. 2388 */ 2389 if (buf_info.first_buffer) 2390 l2_hdr_offset = 2391 DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 2392 else 2393 l2_hdr_offset = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 2394 2395 if (buf_info.first_buffer) { 2396 /* Src addr from where llc header needs to be copied */ 2397 rx_src_desc = 2398 hal_rx_desc_get_80211_hdr(soc->hal_soc, 2399 rx_desc); 2400 2401 /* Size of buffer with llc header */ 2402 frag_size = frag_size - 2403 (l2_hdr_offset + decap_hdr_pull_bytes); 2404 frag_size += msdu_llc_len; 2405 2406 /* Construct destination address */ 2407 rx_dest_desc = frag_addr + 2408 decap_hdr_pull_bytes + l2_hdr_offset; 2409 rx_dest_desc = rx_dest_desc - (msdu_llc_len); 2410 2411 qdf_mem_copy(rx_dest_desc, rx_src_desc, 2412 msdu_llc_len); 2413 2414 /* 2415 * Calculate new page offset and create hole 2416 * if amsdu_pad required. 2417 */ 2418 frag_page_offset = l2_hdr_offset + 2419 decap_hdr_pull_bytes; 2420 frag_page_offset = frag_page_offset - 2421 (msdu_llc_len + amsdu_pad); 2422 2423 qdf_nbuf_move_frag_page_offset(msdu_curr, 2424 frags_iter, 2425 frag_page_offset); 2426 2427 tot_msdu_len = frag_size; 2428 /* 2429 * No amsdu padding required for first frame of 2430 * continuation buffer 2431 */ 2432 if (!buf_info.last_buffer) { 2433 amsdu_pad = 0; 2434 continue; 2435 } 2436 } else { 2437 tot_msdu_len += frag_size; 2438 } 2439 2440 /* Will reach to this place in only two case: 2441 * 1. Single buffer MSDU 2442 * 2. Last buffer of MSDU in case of multiple buf MSDU 2443 */ 2444 2445 /* Check size of buffer if amsdu padding required */ 2446 amsdu_pad = tot_msdu_len & 0x3; 2447 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 2448 2449 /* Create placeholder if current buffer can 2450 * accommodate padding. 2451 */ 2452 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) { 2453 char *frag_addr_temp; 2454 2455 qdf_nbuf_trim_add_frag_size(msdu_curr, 2456 frags_iter, 2457 amsdu_pad, 0); 2458 frag_addr_temp = (char *)qdf_nbuf_get_frag_addr(msdu_curr, 2459 frags_iter); 2460 frag_addr_temp = (frag_addr_temp + 2461 qdf_nbuf_get_frag_size_by_idx(msdu_curr, frags_iter)) - 2462 amsdu_pad; 2463 qdf_mem_zero(frag_addr_temp, amsdu_pad); 2464 amsdu_pad = 0; 2465 } 2466 2467 /* reset tot_msdu_len */ 2468 tot_msdu_len = 0; 2469 } 2470 msdu_curr = qdf_nbuf_next(msdu_curr); 2471 } 2472 2473 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu); 2474 2475 dp_rx_mon_dest_debug("%pK: head_msdu %pK head_msdu->len %u", 2476 soc, head_msdu, head_msdu->len); 2477 2478 mpdu_stitch_done: 2479 return head_msdu; 2480 2481 mpdu_stitch_fail: 2482 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail head_msdu %pK", 2483 soc, head_msdu); 2484 return NULL; 2485 } 2486 #endif 2487 2488 #ifdef DP_RX_MON_MEM_FRAG 2489 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id, 2490 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu, 2491 struct cdp_mon_status *rs) 2492 { 2493 if (qdf_nbuf_get_nr_frags(head_msdu)) 2494 return dp_rx_mon_frag_restitch_mpdu_from_msdus(soc, mac_id, 2495 head_msdu, 2496 tail_msdu, rs); 2497 else 2498 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id, 2499 head_msdu, 2500 tail_msdu, rs); 2501 } 2502 #else 2503 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id, 2504 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu, 2505 struct cdp_mon_status *rs) 2506 { 2507 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id, head_msdu, 2508 tail_msdu, rs); 2509 } 2510 #endif 2511 2512 #ifdef DP_RX_MON_MEM_FRAG 2513 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\ 2514 defined(WLAN_SUPPORT_RX_FLOW_TAG) 2515 void dp_rx_mon_update_pf_tag_to_buf_headroom(struct dp_soc *soc, 2516 qdf_nbuf_t nbuf) 2517 { 2518 qdf_nbuf_t ext_list; 2519 2520 if (qdf_unlikely(!soc)) { 2521 dp_err("Soc[%pK] Null. Can't update pftag to nbuf headroom", 2522 soc); 2523 qdf_assert_always(0); 2524 } 2525 2526 if (!wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx)) 2527 return; 2528 2529 if (qdf_unlikely(!nbuf)) 2530 return; 2531 2532 /* Return if it dint came from mon Path */ 2533 if (!qdf_nbuf_get_nr_frags(nbuf)) 2534 return; 2535 2536 /* Headroom must be double of PF_TAG_SIZE as we copy it 1stly to head */ 2537 if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) { 2538 dp_err("Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]", 2539 qdf_nbuf_headroom(nbuf), DP_RX_MON_TOT_PF_TAG_LEN); 2540 return; 2541 } 2542 2543 qdf_nbuf_push_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN); 2544 qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_head(nbuf), 2545 DP_RX_MON_TOT_PF_TAG_LEN); 2546 qdf_nbuf_pull_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN); 2547 2548 ext_list = qdf_nbuf_get_ext_list(nbuf); 2549 while (ext_list) { 2550 /* Headroom must be double of PF_TAG_SIZE 2551 * as we copy it 1stly to head 2552 */ 2553 if (qdf_unlikely(qdf_nbuf_headroom(ext_list) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) { 2554 dp_err("Fraglist Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]", 2555 qdf_nbuf_headroom(ext_list), 2556 DP_RX_MON_TOT_PF_TAG_LEN); 2557 ext_list = qdf_nbuf_queue_next(ext_list); 2558 continue; 2559 } 2560 qdf_nbuf_push_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN); 2561 qdf_mem_copy(qdf_nbuf_data(ext_list), qdf_nbuf_head(ext_list), 2562 DP_RX_MON_TOT_PF_TAG_LEN); 2563 qdf_nbuf_pull_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN); 2564 ext_list = qdf_nbuf_queue_next(ext_list); 2565 } 2566 } 2567 #endif 2568 #endif 2569 2570 #ifdef QCA_MONITOR_PKT_SUPPORT 2571 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc, 2572 struct dp_pdev *pdev, 2573 int mac_id, 2574 int mac_for_pdev) 2575 { 2576 QDF_STATUS status = QDF_STATUS_SUCCESS; 2577 2578 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2579 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2580 soc->rxdma_mon_buf_ring[mac_id] 2581 .hal_srng, 2582 RXDMA_MONITOR_BUF); 2583 2584 if (status != QDF_STATUS_SUCCESS) { 2585 dp_mon_err("Failed to send htt srng setup message for Rxdma mon buf ring"); 2586 return status; 2587 } 2588 2589 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2590 soc->rxdma_mon_dst_ring[mac_id] 2591 .hal_srng, 2592 RXDMA_MONITOR_DST); 2593 2594 if (status != QDF_STATUS_SUCCESS) { 2595 dp_mon_err("Failed to send htt srng setup message for Rxdma mon dst ring"); 2596 return status; 2597 } 2598 2599 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2600 soc->rxdma_mon_desc_ring[mac_id] 2601 .hal_srng, 2602 RXDMA_MONITOR_DESC); 2603 2604 if (status != QDF_STATUS_SUCCESS) { 2605 dp_mon_err("Failed to send htt srng message for Rxdma mon desc ring"); 2606 return status; 2607 } 2608 } 2609 2610 return status; 2611 } 2612 #endif /* QCA_MONITOR_PKT_SUPPORT */ 2613 2614 #ifdef QCA_MONITOR_PKT_SUPPORT 2615 void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id) 2616 { 2617 struct dp_soc *soc = pdev->soc; 2618 2619 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2620 dp_srng_deinit(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2621 RXDMA_MONITOR_BUF, 0); 2622 dp_srng_deinit(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2623 RXDMA_MONITOR_DST, 0); 2624 dp_srng_deinit(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2625 RXDMA_MONITOR_DESC, 0); 2626 } 2627 } 2628 2629 void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id) 2630 { 2631 struct dp_soc *soc = pdev->soc; 2632 2633 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2634 dp_srng_free(soc, &soc->rxdma_mon_buf_ring[lmac_id]); 2635 dp_srng_free(soc, &soc->rxdma_mon_dst_ring[lmac_id]); 2636 dp_srng_free(soc, &soc->rxdma_mon_desc_ring[lmac_id]); 2637 } 2638 } 2639 2640 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id) 2641 { 2642 struct dp_soc *soc = pdev->soc; 2643 2644 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2645 if (dp_srng_init(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2646 RXDMA_MONITOR_BUF, 0, lmac_id)) { 2647 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc); 2648 goto fail1; 2649 } 2650 2651 if (dp_srng_init(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2652 RXDMA_MONITOR_DST, 0, lmac_id)) { 2653 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc); 2654 goto fail1; 2655 } 2656 2657 if (dp_srng_init(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2658 RXDMA_MONITOR_DESC, 0, lmac_id)) { 2659 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc); 2660 goto fail1; 2661 } 2662 } 2663 return QDF_STATUS_SUCCESS; 2664 2665 fail1: 2666 return QDF_STATUS_E_NOMEM; 2667 } 2668 2669 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id) 2670 { 2671 int entries; 2672 struct dp_soc *soc = pdev->soc; 2673 struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx = pdev->wlan_cfg_ctx; 2674 2675 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2676 entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev_cfg_ctx); 2677 if (dp_srng_alloc(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2678 RXDMA_MONITOR_BUF, entries, 0)) { 2679 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc); 2680 goto fail1; 2681 } 2682 entries = wlan_cfg_get_dma_rx_mon_dest_ring_size(pdev_cfg_ctx); 2683 if (dp_srng_alloc(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2684 RXDMA_MONITOR_DST, entries, 0)) { 2685 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc); 2686 goto fail1; 2687 } 2688 entries = wlan_cfg_get_dma_mon_desc_ring_size(pdev_cfg_ctx); 2689 if (dp_srng_alloc(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2690 RXDMA_MONITOR_DESC, entries, 0)) { 2691 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc); 2692 goto fail1; 2693 } 2694 } 2695 return QDF_STATUS_SUCCESS; 2696 2697 fail1: 2698 return QDF_STATUS_E_NOMEM; 2699 } 2700 #endif 2701