1 /* 2 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 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 * Return: QDF_STATUS 101 */ 102 QDF_STATUS 103 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, 104 hal_buff_addrinfo_t buf_addr_info, int mac_id) 105 { 106 struct dp_srng *dp_srng; 107 hal_ring_handle_t hal_ring_hdl; 108 hal_soc_handle_t hal_soc; 109 QDF_STATUS status = QDF_STATUS_E_FAILURE; 110 void *src_srng_desc; 111 112 hal_soc = dp_pdev->soc->hal_soc; 113 114 dp_srng = &dp_pdev->soc->rxdma_mon_desc_ring[mac_id]; 115 hal_ring_hdl = dp_srng->hal_srng; 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; 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 /* WAR for duplicate link descriptors received from HW */ 232 if (qdf_unlikely(mon_pdev->mon_last_linkdesc_paddr == 233 buf_info.paddr)) { 234 mon_pdev->rx_mon_stats.dup_mon_linkdesc_cnt++; 235 return rx_bufs_used; 236 } 237 238 rx_msdu_link_desc = 239 dp_rx_cookie_2_mon_link_desc(dp_pdev, 240 buf_info, mac_id); 241 242 qdf_assert_always(rx_msdu_link_desc); 243 244 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, 245 &msdu_list, &num_msdus); 246 247 for (i = 0; i < num_msdus; i++) { 248 uint16_t l2_hdr_offset; 249 struct dp_rx_desc *rx_desc = NULL; 250 struct rx_desc_pool *rx_desc_pool; 251 252 rx_desc = dp_rx_get_mon_desc(soc, 253 msdu_list.sw_cookie[i]); 254 255 qdf_assert_always(rx_desc); 256 257 msdu = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc); 258 buf_paddr = dp_rx_mon_get_paddr_from_desc(rx_desc); 259 260 /* WAR for duplicate buffers received from HW */ 261 if (qdf_unlikely(mon_pdev->mon_last_buf_cookie == 262 msdu_list.sw_cookie[i] || 263 DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) || 264 msdu_list.paddr[i] != buf_paddr || 265 !rx_desc->in_use)) { 266 /* Skip duplicate buffer and drop subsequent 267 * buffers in this MPDU 268 */ 269 drop_mpdu = true; 270 mon_pdev->rx_mon_stats.dup_mon_buf_cnt++; 271 mon_pdev->mon_last_linkdesc_paddr = 272 buf_info.paddr; 273 continue; 274 } 275 276 if (rx_desc->unmapped == 0) { 277 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, 278 mac_id, 279 dp_pdev->pdev_id); 280 dp_rx_mon_buffer_unmap(soc, rx_desc, 281 rx_desc_pool->buf_size); 282 rx_desc->unmapped = 1; 283 } 284 285 if (dp_rx_buffer_pool_refill(soc, msdu, 286 rx_desc->pool_id)) { 287 drop_mpdu = true; 288 msdu = NULL; 289 mon_pdev->mon_last_linkdesc_paddr = 290 buf_info.paddr; 291 goto next_msdu; 292 } 293 294 if (drop_mpdu) { 295 mon_pdev->mon_last_linkdesc_paddr = 296 buf_info.paddr; 297 dp_rx_mon_buffer_free(rx_desc); 298 msdu = NULL; 299 goto next_msdu; 300 } 301 302 data = dp_rx_mon_get_buffer_data(rx_desc); 303 rx_desc_tlv = HAL_RX_MON_DEST_GET_DESC(data); 304 305 dp_rx_mon_dest_debug("%pK: i=%d, ppdu_id=%x, num_msdus = %u", 306 soc, i, *ppdu_id, num_msdus); 307 308 if (is_first_msdu) { 309 if (!hal_rx_mpdu_start_tlv_tag_valid( 310 soc->hal_soc, 311 rx_desc_tlv)) { 312 drop_mpdu = true; 313 dp_rx_mon_buffer_free(rx_desc); 314 msdu = NULL; 315 mon_pdev->mon_last_linkdesc_paddr = 316 buf_info.paddr; 317 goto next_msdu; 318 } 319 320 msdu_ppdu_id = hal_rx_hw_desc_get_ppduid_get( 321 soc->hal_soc, 322 rx_desc_tlv, 323 rxdma_dst_ring_desc); 324 is_first_msdu = false; 325 326 dp_rx_mon_dest_debug("%pK: msdu_ppdu_id=%x", 327 soc, msdu_ppdu_id); 328 329 if (*ppdu_id > msdu_ppdu_id) 330 dp_rx_mon_dest_debug("%pK: ppdu_id=%d " 331 "msdu_ppdu_id=%d", soc, 332 *ppdu_id, msdu_ppdu_id); 333 334 if ((*ppdu_id < msdu_ppdu_id) && ( 335 (msdu_ppdu_id - *ppdu_id) < 336 NOT_PPDU_ID_WRAP_AROUND)) { 337 *ppdu_id = msdu_ppdu_id; 338 return rx_bufs_used; 339 } else if ((*ppdu_id > msdu_ppdu_id) && ( 340 (*ppdu_id - msdu_ppdu_id) > 341 NOT_PPDU_ID_WRAP_AROUND)) { 342 *ppdu_id = msdu_ppdu_id; 343 return rx_bufs_used; 344 } 345 346 dp_tx_capture_get_user_id(dp_pdev, 347 rx_desc_tlv); 348 349 if (*ppdu_id == msdu_ppdu_id) 350 mon_pdev->rx_mon_stats.ppdu_id_match++; 351 else 352 mon_pdev->rx_mon_stats.ppdu_id_mismatch 353 ++; 354 355 mon_pdev->mon_last_linkdesc_paddr = 356 buf_info.paddr; 357 358 if (dp_rx_mon_alloc_parent_buffer(head_msdu) 359 != QDF_STATUS_SUCCESS) { 360 DP_STATS_INC(dp_pdev, 361 replenish.nbuf_alloc_fail, 362 1); 363 qdf_frag_free(rx_desc_tlv); 364 dp_rx_mon_dest_debug("failed to allocate parent buffer to hold all frag"); 365 drop_mpdu = true; 366 goto next_msdu; 367 } 368 } 369 370 if (hal_rx_desc_is_first_msdu(soc->hal_soc, 371 rx_desc_tlv)) 372 hal_rx_mon_hw_desc_get_mpdu_status(soc->hal_soc, 373 rx_desc_tlv, 374 &mon_pdev->ppdu_info.rx_status); 375 376 dp_rx_mon_parse_desc_buffer(soc, 377 &(msdu_list.msdu_info[i]), 378 &is_frag, 379 &total_frag_len, 380 &frag_len, 381 &l2_hdr_offset, 382 rx_desc_tlv, 383 &is_frag_non_raw, data); 384 if (!is_frag) 385 msdu_cnt--; 386 387 dp_rx_mon_dest_debug("total_len %u frag_len %u flags %u", 388 total_frag_len, frag_len, 389 msdu_list.msdu_info[i].msdu_flags); 390 391 rx_pkt_offset = soc->rx_mon_pkt_tlv_size; 392 393 rx_buf_size = rx_pkt_offset + l2_hdr_offset 394 + frag_len; 395 396 dp_rx_mon_buffer_set_pktlen(msdu, rx_buf_size); 397 #if 0 398 /* Disble it.see packet on msdu done set to 0 */ 399 /* 400 * Check if DMA completed -- msdu_done is the 401 * last bit to be written 402 */ 403 if (!hal_rx_attn_msdu_done_get(rx_desc_tlv)) { 404 405 QDF_TRACE(QDF_MODULE_ID_DP, 406 QDF_TRACE_LEVEL_ERROR, 407 "%s:%d: Pkt Desc", 408 __func__, __LINE__); 409 410 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_DP, 411 QDF_TRACE_LEVEL_ERROR, 412 rx_desc_tlv, 128); 413 414 qdf_assert_always(0); 415 } 416 #endif 417 dp_rx_mon_dest_debug("%pK: rx_pkt_offset=%d, l2_hdr_offset=%d, msdu_len=%d, frag_len %u", 418 soc, rx_pkt_offset, l2_hdr_offset, 419 msdu_list.msdu_info[i].msdu_len, 420 frag_len); 421 422 if (dp_rx_mon_add_msdu_to_list(soc, head_msdu, msdu, 423 &last, rx_desc_tlv, 424 frag_len, l2_hdr_offset) 425 != QDF_STATUS_SUCCESS) { 426 dp_rx_mon_add_msdu_to_list_failure_handler(rx_desc_tlv, 427 dp_pdev, &last, head_msdu, 428 tail_msdu, __func__); 429 drop_mpdu = true; 430 goto next_msdu; 431 } 432 433 next_msdu: 434 mon_pdev->mon_last_buf_cookie = msdu_list.sw_cookie[i]; 435 rx_bufs_used++; 436 dp_rx_add_to_free_desc_list(head, 437 tail, rx_desc); 438 } 439 440 /* 441 * Store the current link buffer into to the local 442 * structure to be used for release purpose. 443 */ 444 hal_rxdma_buff_addr_info_set(soc->hal_soc, rx_link_buf_info, 445 buf_info.paddr, 446 buf_info.sw_cookie, buf_info.rbm); 447 448 hal_rx_mon_next_link_desc_get(soc->hal_soc, rx_msdu_link_desc, 449 &buf_info); 450 if (dp_rx_monitor_link_desc_return(dp_pdev, 451 (hal_buff_addrinfo_t) 452 rx_link_buf_info, 453 mac_id, 454 bm_action) 455 != QDF_STATUS_SUCCESS) 456 dp_err_rl("monitor link desc return failed"); 457 } while (buf_info.paddr && msdu_cnt); 458 459 dp_rx_mon_init_tail_msdu(head_msdu, msdu, last, tail_msdu); 460 dp_rx_mon_remove_raw_frame_fcs_len(soc, head_msdu, tail_msdu); 461 462 return rx_bufs_used; 463 } 464 465 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, 466 uint32_t mac_id, uint32_t quota) 467 { 468 struct dp_pdev *pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 469 uint8_t pdev_id; 470 hal_rxdma_desc_t rxdma_dst_ring_desc; 471 hal_soc_handle_t hal_soc; 472 void *mon_dst_srng; 473 union dp_rx_desc_list_elem_t *head = NULL; 474 union dp_rx_desc_list_elem_t *tail = NULL; 475 uint32_t ppdu_id; 476 uint32_t rx_bufs_used; 477 uint32_t mpdu_rx_bufs_used; 478 int mac_for_pdev = mac_id; 479 struct cdp_pdev_mon_stats *rx_mon_stats; 480 struct dp_mon_pdev *mon_pdev; 481 482 if (!pdev) { 483 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", soc, mac_id); 484 return; 485 } 486 487 mon_pdev = pdev->monitor_pdev; 488 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_for_pdev); 489 490 if (!mon_dst_srng || !hal_srng_initialized(mon_dst_srng)) { 491 dp_rx_mon_dest_err("%pK: : HAL Monitor Destination Ring Init Failed -- %pK", 492 soc, mon_dst_srng); 493 return; 494 } 495 496 hal_soc = soc->hal_soc; 497 498 qdf_assert((hal_soc && pdev)); 499 500 qdf_spin_lock_bh(&mon_pdev->mon_lock); 501 502 if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, mon_dst_srng))) { 503 QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR, 504 "%s %d : HAL Mon Dest Ring access Failed -- %pK", 505 __func__, __LINE__, mon_dst_srng); 506 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 507 return; 508 } 509 510 pdev_id = pdev->pdev_id; 511 ppdu_id = mon_pdev->ppdu_info.com_info.ppdu_id; 512 rx_bufs_used = 0; 513 rx_mon_stats = &mon_pdev->rx_mon_stats; 514 515 while (qdf_likely(rxdma_dst_ring_desc = 516 hal_srng_dst_peek(hal_soc, mon_dst_srng))) { 517 qdf_nbuf_t head_msdu, tail_msdu; 518 uint32_t npackets; 519 520 head_msdu = (qdf_nbuf_t)NULL; 521 tail_msdu = (qdf_nbuf_t)NULL; 522 523 mpdu_rx_bufs_used = 524 dp_rx_mon_mpdu_pop(soc, mac_id, 525 rxdma_dst_ring_desc, 526 &head_msdu, &tail_msdu, 527 &npackets, &ppdu_id, 528 &head, &tail); 529 530 rx_bufs_used += mpdu_rx_bufs_used; 531 532 if (mpdu_rx_bufs_used) 533 mon_pdev->mon_dest_ring_stuck_cnt = 0; 534 else 535 mon_pdev->mon_dest_ring_stuck_cnt++; 536 537 if (mon_pdev->mon_dest_ring_stuck_cnt > 538 MON_DEST_RING_STUCK_MAX_CNT) { 539 dp_info("destination ring stuck"); 540 dp_info("ppdu_id status=%d dest=%d", 541 mon_pdev->ppdu_info.com_info.ppdu_id, ppdu_id); 542 rx_mon_stats->mon_rx_dest_stuck++; 543 mon_pdev->ppdu_info.com_info.ppdu_id = ppdu_id; 544 continue; 545 } 546 547 if (ppdu_id != mon_pdev->ppdu_info.com_info.ppdu_id) { 548 rx_mon_stats->stat_ring_ppdu_id_hist[ 549 rx_mon_stats->ppdu_id_hist_idx] = 550 mon_pdev->ppdu_info.com_info.ppdu_id; 551 rx_mon_stats->dest_ring_ppdu_id_hist[ 552 rx_mon_stats->ppdu_id_hist_idx] = ppdu_id; 553 rx_mon_stats->ppdu_id_hist_idx = 554 (rx_mon_stats->ppdu_id_hist_idx + 1) & 555 (MAX_PPDU_ID_HIST - 1); 556 mon_pdev->mon_ppdu_status = DP_PPDU_STATUS_START; 557 qdf_mem_zero(&mon_pdev->ppdu_info.rx_status, 558 sizeof(mon_pdev->ppdu_info.rx_status)); 559 dp_rx_mon_dest_debug("%pK: ppdu_id %x != ppdu_info.com_info.ppdu_id %x", 560 soc, ppdu_id, 561 mon_pdev->ppdu_info.com_info.ppdu_id); 562 break; 563 } 564 565 if (qdf_likely((head_msdu) && (tail_msdu))) { 566 rx_mon_stats->dest_mpdu_done++; 567 dp_rx_mon_deliver(soc, mac_id, head_msdu, tail_msdu); 568 } 569 570 rxdma_dst_ring_desc = 571 hal_srng_dst_get_next(hal_soc, 572 mon_dst_srng); 573 } 574 575 dp_srng_access_end(int_ctx, soc, mon_dst_srng); 576 577 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 578 579 if (rx_bufs_used) { 580 rx_mon_stats->dest_ppdu_done++; 581 dp_rx_buffers_replenish(soc, mac_id, 582 dp_rxdma_get_mon_buf_ring(pdev, 583 mac_for_pdev), 584 dp_rx_get_mon_desc_pool(soc, mac_id, 585 pdev_id), 586 rx_bufs_used, &head, &tail); 587 } 588 } 589 590 QDF_STATUS 591 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id, 592 bool delayed_replenish) 593 { 594 uint8_t pdev_id = pdev->pdev_id; 595 struct dp_soc *soc = pdev->soc; 596 struct dp_srng *mon_buf_ring; 597 uint32_t num_entries; 598 struct rx_desc_pool *rx_desc_pool; 599 QDF_STATUS status = QDF_STATUS_SUCCESS; 600 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 601 602 mon_buf_ring = dp_rxdma_get_mon_buf_ring(pdev, mac_id); 603 604 num_entries = mon_buf_ring->num_entries; 605 606 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev_id); 607 608 dp_debug("Mon RX Desc Pool[%d] entries=%u", pdev_id, num_entries); 609 610 /* Replenish RXDMA monitor buffer ring with 8 buffers only 611 * delayed_replenish_entries is actually 8 but when we call 612 * dp_pdev_rx_buffers_attach() we pass 1 less than 8, hence 613 * added 1 to delayed_replenish_entries to ensure we have 8 614 * entries. Once the monitor VAP is configured we replenish 615 * the complete RXDMA monitor buffer ring. 616 */ 617 if (delayed_replenish) { 618 num_entries = soc_cfg_ctx->delayed_replenish_entries + 1; 619 status = dp_pdev_rx_buffers_attach(soc, mac_id, mon_buf_ring, 620 rx_desc_pool, 621 num_entries - 1); 622 } else { 623 union dp_rx_desc_list_elem_t *tail = NULL; 624 union dp_rx_desc_list_elem_t *desc_list = NULL; 625 626 status = dp_rx_buffers_replenish(soc, mac_id, 627 mon_buf_ring, 628 rx_desc_pool, 629 num_entries, 630 &desc_list, 631 &tail); 632 } 633 634 return status; 635 } 636 637 void 638 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id) 639 { 640 uint8_t pdev_id = pdev->pdev_id; 641 struct dp_soc *soc = pdev->soc; 642 struct dp_srng *mon_buf_ring; 643 uint32_t num_entries; 644 struct rx_desc_pool *rx_desc_pool; 645 uint32_t rx_desc_pool_size; 646 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 647 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 648 649 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id]; 650 651 num_entries = mon_buf_ring->num_entries; 652 653 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 654 655 /* If descriptor pool is already initialized, do not initialize it */ 656 if (rx_desc_pool->freelist) 657 return; 658 659 dp_debug("Mon RX Desc buf Pool[%d] init entries=%u", 660 pdev_id, num_entries); 661 662 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) * 663 num_entries; 664 665 rx_desc_pool->owner = HAL_RX_BUF_RBM_SW3_BM(soc->wbm_sw0_bm_id); 666 rx_desc_pool->buf_size = RX_MONITOR_BUFFER_SIZE; 667 rx_desc_pool->buf_alignment = RX_MONITOR_BUFFER_ALIGNMENT; 668 /* Enable frag processing if feature is enabled */ 669 dp_rx_enable_mon_dest_frag(rx_desc_pool, true); 670 671 dp_rx_desc_pool_init(soc, mac_id, rx_desc_pool_size, rx_desc_pool); 672 673 mon_pdev->mon_last_linkdesc_paddr = 0; 674 675 mon_pdev->mon_last_buf_cookie = DP_RX_DESC_COOKIE_MAX + 1; 676 677 /* Attach full monitor mode resources */ 678 dp_full_mon_attach(pdev); 679 } 680 681 static void 682 dp_rx_pdev_mon_buf_desc_pool_deinit(struct dp_pdev *pdev, uint32_t mac_id) 683 { 684 uint8_t pdev_id = pdev->pdev_id; 685 struct dp_soc *soc = pdev->soc; 686 struct rx_desc_pool *rx_desc_pool; 687 688 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 689 690 dp_debug("Mon RX Desc buf Pool[%d] deinit", pdev_id); 691 692 dp_rx_desc_pool_deinit(soc, rx_desc_pool, mac_id); 693 694 /* Detach full monitor mode resources */ 695 dp_full_mon_detach(pdev); 696 } 697 698 static void 699 dp_rx_pdev_mon_buf_desc_pool_free(struct dp_pdev *pdev, uint32_t mac_id) 700 { 701 uint8_t pdev_id = pdev->pdev_id; 702 struct dp_soc *soc = pdev->soc; 703 struct rx_desc_pool *rx_desc_pool; 704 705 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 706 707 dp_debug("Mon RX Buf Desc Pool Free pdev[%d]", pdev_id); 708 709 dp_rx_desc_pool_free(soc, rx_desc_pool); 710 } 711 712 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) 713 { 714 uint8_t pdev_id = pdev->pdev_id; 715 struct dp_soc *soc = pdev->soc; 716 struct rx_desc_pool *rx_desc_pool; 717 718 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 719 720 dp_debug("Mon RX Buf buffers Free pdev[%d]", pdev_id); 721 722 if (rx_desc_pool->rx_mon_dest_frag_enable) 723 dp_rx_desc_frag_free(soc, rx_desc_pool); 724 else 725 dp_rx_desc_nbuf_free(soc, rx_desc_pool); 726 } 727 728 QDF_STATUS 729 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id) 730 { 731 uint8_t pdev_id = pdev->pdev_id; 732 struct dp_soc *soc = pdev->soc; 733 struct dp_srng *mon_buf_ring; 734 uint32_t num_entries; 735 struct rx_desc_pool *rx_desc_pool; 736 uint32_t rx_desc_pool_size; 737 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 738 739 mon_buf_ring = &soc->rxdma_mon_buf_ring[mac_id]; 740 741 num_entries = mon_buf_ring->num_entries; 742 743 rx_desc_pool = &soc->rx_desc_mon[mac_id]; 744 745 dp_debug("Mon RX Desc Pool[%d] entries=%u", 746 pdev_id, num_entries); 747 748 rx_desc_pool_size = wlan_cfg_get_dp_soc_rx_sw_desc_weight(soc_cfg_ctx) * 749 num_entries; 750 751 if (dp_rx_desc_pool_is_allocated(rx_desc_pool) == QDF_STATUS_SUCCESS) 752 return QDF_STATUS_SUCCESS; 753 754 return dp_rx_desc_pool_alloc(soc, rx_desc_pool_size, rx_desc_pool); 755 } 756 757 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 758 uint32_t 759 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id) 760 { 761 struct dp_soc *soc = pdev->soc; 762 hal_rxdma_desc_t rxdma_dst_ring_desc; 763 hal_soc_handle_t hal_soc; 764 void *mon_dst_srng; 765 union dp_rx_desc_list_elem_t *head = NULL; 766 union dp_rx_desc_list_elem_t *tail = NULL; 767 uint32_t rx_bufs_used = 0; 768 void *rx_msdu_link_desc; 769 uint32_t msdu_count = 0; 770 uint16_t num_msdus; 771 struct hal_buf_info buf_info; 772 struct hal_rx_msdu_list msdu_list; 773 qdf_nbuf_t nbuf; 774 uint32_t i; 775 uint8_t bm_action = HAL_BM_ACTION_PUT_IN_IDLE_LIST; 776 uint32_t rx_link_buf_info[HAL_RX_BUFFINFO_NUM_DWORDS]; 777 struct rx_desc_pool *rx_desc_pool; 778 uint32_t reap_cnt = 0; 779 struct dp_mon_pdev *mon_pdev; 780 781 if (qdf_unlikely(!soc || !soc->hal_soc)) 782 return reap_cnt; 783 784 mon_dst_srng = dp_rxdma_get_mon_dst_ring(pdev, mac_id); 785 786 if (qdf_unlikely(!mon_dst_srng || !hal_srng_initialized(mon_dst_srng))) 787 return reap_cnt; 788 789 hal_soc = soc->hal_soc; 790 mon_pdev = pdev->monitor_pdev; 791 792 qdf_spin_lock_bh(&mon_pdev->mon_lock); 793 794 if (qdf_unlikely(hal_srng_access_start(hal_soc, mon_dst_srng))) { 795 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 796 return reap_cnt; 797 } 798 799 rx_desc_pool = dp_rx_get_mon_desc_pool(soc, mac_id, pdev->pdev_id); 800 801 while ((rxdma_dst_ring_desc = 802 hal_srng_dst_peek(hal_soc, mon_dst_srng)) && 803 reap_cnt < MON_DROP_REAP_LIMIT) { 804 805 hal_rx_reo_ent_buf_paddr_get(hal_soc, rxdma_dst_ring_desc, 806 &buf_info, &msdu_count); 807 808 do { 809 rx_msdu_link_desc = dp_rx_cookie_2_mon_link_desc(pdev, 810 buf_info, mac_id); 811 812 if (qdf_unlikely(!rx_msdu_link_desc)) { 813 mon_pdev->rx_mon_stats.mon_link_desc_invalid++; 814 goto next_entry; 815 } 816 817 hal_rx_msdu_list_get(soc->hal_soc, rx_msdu_link_desc, 818 &msdu_list, &num_msdus); 819 820 for (i = 0; i < num_msdus; i++) { 821 struct dp_rx_desc *rx_desc; 822 qdf_dma_addr_t buf_paddr; 823 824 rx_desc = dp_rx_get_mon_desc(soc, 825 msdu_list.sw_cookie[i]); 826 827 if (qdf_unlikely(!rx_desc)) { 828 mon_pdev->rx_mon_stats. 829 mon_rx_desc_invalid++; 830 continue; 831 } 832 833 nbuf = DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc); 834 buf_paddr = 835 dp_rx_mon_get_paddr_from_desc(rx_desc); 836 837 if (qdf_unlikely(!rx_desc->in_use || !nbuf || 838 msdu_list.paddr[i] != 839 buf_paddr)) { 840 mon_pdev->rx_mon_stats. 841 mon_nbuf_sanity_err++; 842 continue; 843 } 844 rx_bufs_used++; 845 846 if (!rx_desc->unmapped) { 847 dp_rx_mon_buffer_unmap(soc, rx_desc, 848 rx_desc_pool->buf_size); 849 rx_desc->unmapped = 1; 850 } 851 852 qdf_nbuf_free(nbuf); 853 dp_rx_add_to_free_desc_list(&head, &tail, 854 rx_desc); 855 856 if (!(msdu_list.msdu_info[i].msdu_flags & 857 HAL_MSDU_F_MSDU_CONTINUATION)) 858 msdu_count--; 859 } 860 861 /* 862 * Store the current link buffer into to the local 863 * structure to be used for release purpose. 864 */ 865 hal_rxdma_buff_addr_info_set(soc->hal_soc, 866 rx_link_buf_info, 867 buf_info.paddr, 868 buf_info.sw_cookie, 869 buf_info.rbm); 870 871 hal_rx_mon_next_link_desc_get(soc->hal_soc, 872 rx_msdu_link_desc, 873 &buf_info); 874 if (dp_rx_monitor_link_desc_return(pdev, 875 (hal_buff_addrinfo_t) 876 rx_link_buf_info, 877 mac_id, bm_action) != 878 QDF_STATUS_SUCCESS) 879 dp_info_rl("monitor link desc return failed"); 880 } while (buf_info.paddr && msdu_count); 881 882 next_entry: 883 reap_cnt++; 884 rxdma_dst_ring_desc = hal_srng_dst_get_next(hal_soc, 885 mon_dst_srng); 886 } 887 888 hal_srng_access_end(hal_soc, mon_dst_srng); 889 890 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 891 892 if (rx_bufs_used) { 893 dp_rx_buffers_replenish(soc, mac_id, 894 dp_rxdma_get_mon_buf_ring(pdev, mac_id), 895 rx_desc_pool, 896 rx_bufs_used, &head, &tail); 897 } 898 899 return reap_cnt; 900 } 901 #endif 902 903 static void 904 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev) 905 { 906 struct dp_soc *soc = pdev->soc; 907 908 dp_rx_pdev_mon_buf_desc_pool_free(pdev, mac_for_pdev); 909 dp_hw_link_desc_pool_banks_free(soc, mac_for_pdev); 910 } 911 912 static void 913 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev) 914 { 915 struct dp_soc *soc = pdev->soc; 916 917 if (!soc->wlan_cfg_ctx->rxdma1_enable) 918 return; 919 920 dp_rx_pdev_mon_buf_desc_pool_deinit(pdev, mac_for_pdev); 921 } 922 923 static void 924 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev) 925 { 926 struct dp_soc *soc = pdev->soc; 927 928 if (!soc->wlan_cfg_ctx->rxdma1_enable || 929 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 930 return; 931 932 dp_rx_pdev_mon_buf_desc_pool_init(pdev, mac_for_pdev); 933 dp_link_desc_ring_replenish(soc, mac_for_pdev); 934 } 935 936 static void 937 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev) 938 { 939 struct dp_soc *soc = pdev->soc; 940 941 if (!soc->wlan_cfg_ctx->rxdma1_enable) 942 return; 943 944 dp_rx_pdev_mon_buf_buffers_free(pdev, mac_for_pdev); 945 } 946 947 static QDF_STATUS 948 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev) 949 { 950 struct dp_soc *soc = pdev->soc; 951 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = soc->wlan_cfg_ctx; 952 bool delayed_replenish; 953 QDF_STATUS status = QDF_STATUS_SUCCESS; 954 955 delayed_replenish = soc_cfg_ctx->delayed_replenish_entries ? 1 : 0; 956 if (!soc->wlan_cfg_ctx->rxdma1_enable || 957 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 958 return status; 959 960 status = dp_rx_pdev_mon_buf_buffers_alloc(pdev, mac_for_pdev, 961 delayed_replenish); 962 if (!QDF_IS_STATUS_SUCCESS(status)) 963 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed"); 964 965 return status; 966 } 967 968 static QDF_STATUS 969 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev) 970 { 971 struct dp_soc *soc = pdev->soc; 972 QDF_STATUS status = QDF_STATUS_SUCCESS; 973 974 if (!soc->wlan_cfg_ctx->rxdma1_enable || 975 !wlan_cfg_is_delay_mon_replenish(soc->wlan_cfg_ctx)) 976 return status; 977 978 /* Allocate sw rx descriptor pool for monitor RxDMA buffer ring */ 979 status = dp_rx_pdev_mon_buf_desc_pool_alloc(pdev, mac_for_pdev); 980 if (!QDF_IS_STATUS_SUCCESS(status)) { 981 dp_err("dp_rx_pdev_mon_buf_desc_pool_alloc() failed"); 982 goto fail; 983 } 984 985 /* Allocate link descriptors for the monitor link descriptor ring */ 986 status = dp_hw_link_desc_pool_banks_alloc(soc, mac_for_pdev); 987 if (!QDF_IS_STATUS_SUCCESS(status)) { 988 dp_err("dp_hw_link_desc_pool_banks_alloc() failed"); 989 goto mon_buf_dealloc; 990 } 991 992 return status; 993 994 mon_buf_dealloc: 995 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 996 fail: 997 return status; 998 } 999 #else 1000 static void 1001 dp_rx_pdev_mon_dest_desc_pool_free(struct dp_pdev *pdev, int mac_for_pdev) 1002 { 1003 } 1004 1005 static void 1006 dp_rx_pdev_mon_dest_desc_pool_deinit(struct dp_pdev *pdev, int mac_for_pdev) 1007 { 1008 } 1009 1010 static void 1011 dp_rx_pdev_mon_dest_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1012 { 1013 } 1014 1015 static void 1016 dp_rx_pdev_mon_dest_buffers_free(struct dp_pdev *pdev, int mac_for_pdev) 1017 { 1018 } 1019 1020 static QDF_STATUS 1021 dp_rx_pdev_mon_dest_buffers_alloc(struct dp_pdev *pdev, int mac_for_pdev) 1022 { 1023 return QDF_STATUS_SUCCESS; 1024 } 1025 1026 static QDF_STATUS 1027 dp_rx_pdev_mon_dest_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_for_pdev) 1028 { 1029 return QDF_STATUS_SUCCESS; 1030 } 1031 1032 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 1033 uint32_t 1034 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id) 1035 { 1036 return 0; 1037 } 1038 #endif 1039 #endif 1040 1041 static void 1042 dp_rx_pdev_mon_cmn_desc_pool_free(struct dp_pdev *pdev, int mac_id) 1043 { 1044 struct dp_soc *soc = pdev->soc; 1045 uint8_t pdev_id = pdev->pdev_id; 1046 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1047 1048 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 1049 dp_rx_pdev_mon_dest_desc_pool_free(pdev, mac_for_pdev); 1050 } 1051 1052 void dp_rx_pdev_mon_desc_pool_free(struct dp_pdev *pdev) 1053 { 1054 int mac_id; 1055 1056 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) 1057 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, mac_id); 1058 } 1059 1060 static void 1061 dp_rx_pdev_mon_cmn_desc_pool_deinit(struct dp_pdev *pdev, int mac_id) 1062 { 1063 struct dp_soc *soc = pdev->soc; 1064 uint8_t pdev_id = pdev->pdev_id; 1065 int mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1066 1067 dp_rx_pdev_mon_status_desc_pool_deinit(pdev, mac_for_pdev); 1068 1069 dp_rx_pdev_mon_dest_desc_pool_deinit(pdev, mac_for_pdev); 1070 } 1071 1072 void 1073 dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev *pdev) 1074 { 1075 int mac_id; 1076 1077 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) 1078 dp_rx_pdev_mon_cmn_desc_pool_deinit(pdev, mac_id); 1079 qdf_spinlock_destroy(&pdev->monitor_pdev->mon_lock); 1080 } 1081 1082 static void 1083 dp_rx_pdev_mon_cmn_desc_pool_init(struct dp_pdev *pdev, int mac_id) 1084 { 1085 struct dp_soc *soc = pdev->soc; 1086 uint32_t mac_for_pdev; 1087 1088 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); 1089 dp_rx_pdev_mon_status_desc_pool_init(pdev, mac_for_pdev); 1090 1091 dp_rx_pdev_mon_dest_desc_pool_init(pdev, mac_for_pdev); 1092 } 1093 1094 void 1095 dp_rx_pdev_mon_desc_pool_init(struct dp_pdev *pdev) 1096 { 1097 int mac_id; 1098 1099 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) 1100 dp_rx_pdev_mon_cmn_desc_pool_init(pdev, mac_id); 1101 qdf_spinlock_create(&pdev->monitor_pdev->mon_lock); 1102 } 1103 1104 static void 1105 dp_rx_pdev_mon_cmn_buffers_free(struct dp_pdev *pdev, int mac_id) 1106 { 1107 uint8_t pdev_id = pdev->pdev_id; 1108 int mac_for_pdev; 1109 1110 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, pdev_id); 1111 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev); 1112 1113 dp_rx_pdev_mon_dest_buffers_free(pdev, mac_for_pdev); 1114 } 1115 1116 void 1117 dp_rx_pdev_mon_buffers_free(struct dp_pdev *pdev) 1118 { 1119 int mac_id; 1120 1121 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) 1122 dp_rx_pdev_mon_cmn_buffers_free(pdev, mac_id); 1123 pdev->monitor_pdev->pdev_mon_init = 0; 1124 } 1125 1126 QDF_STATUS 1127 dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev) 1128 { 1129 int mac_id; 1130 int mac_for_pdev; 1131 QDF_STATUS status = QDF_STATUS_SUCCESS; 1132 uint8_t pdev_id = pdev->pdev_id; 1133 struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx = pdev->soc->wlan_cfg_ctx; 1134 1135 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_status_rings_per_pdev; 1136 mac_id++) { 1137 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1138 pdev_id); 1139 status = dp_rx_pdev_mon_status_buffers_alloc(pdev, 1140 mac_for_pdev); 1141 if (!QDF_IS_STATUS_SUCCESS(status)) { 1142 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed"); 1143 goto mon_status_buf_fail; 1144 } 1145 } 1146 1147 for (mac_id = 0; mac_id < soc_cfg_ctx->num_rxdma_dst_rings_per_pdev; 1148 mac_id++) { 1149 mac_for_pdev = dp_get_lmac_id_for_pdev_id(pdev->soc, mac_id, 1150 pdev_id); 1151 status = dp_rx_pdev_mon_dest_buffers_alloc(pdev, mac_for_pdev); 1152 if (!QDF_IS_STATUS_SUCCESS(status)) 1153 goto mon_stat_buf_dealloc; 1154 } 1155 1156 return status; 1157 1158 mon_stat_buf_dealloc: 1159 dp_rx_pdev_mon_status_buffers_free(pdev, mac_for_pdev); 1160 mon_status_buf_fail: 1161 return status; 1162 } 1163 1164 static QDF_STATUS 1165 dp_rx_pdev_mon_cmn_desc_pool_alloc(struct dp_pdev *pdev, int mac_id) 1166 { 1167 struct dp_soc *soc = pdev->soc; 1168 uint8_t pdev_id = pdev->pdev_id; 1169 uint32_t mac_for_pdev; 1170 QDF_STATUS status; 1171 1172 mac_for_pdev = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev_id); 1173 1174 /* Allocate sw rx descriptor pool for monitor status ring */ 1175 status = dp_rx_pdev_mon_status_desc_pool_alloc(pdev, mac_for_pdev); 1176 if (!QDF_IS_STATUS_SUCCESS(status)) { 1177 dp_err("dp_rx_pdev_mon_status_desc_pool_alloc() failed"); 1178 goto fail; 1179 } 1180 1181 status = dp_rx_pdev_mon_dest_desc_pool_alloc(pdev, mac_for_pdev); 1182 if (!QDF_IS_STATUS_SUCCESS(status)) 1183 goto mon_status_dealloc; 1184 1185 return status; 1186 1187 mon_status_dealloc: 1188 dp_rx_pdev_mon_status_desc_pool_free(pdev, mac_for_pdev); 1189 fail: 1190 return status; 1191 } 1192 1193 QDF_STATUS 1194 dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev) 1195 { 1196 QDF_STATUS status; 1197 int mac_id, count; 1198 1199 for (mac_id = 0; mac_id < NUM_RXDMA_RINGS_PER_PDEV; mac_id++) { 1200 status = dp_rx_pdev_mon_cmn_desc_pool_alloc(pdev, mac_id); 1201 if (!QDF_IS_STATUS_SUCCESS(status)) { 1202 dp_rx_mon_dest_err("%pK: %d failed\n", 1203 pdev->soc, mac_id); 1204 1205 for (count = 0; count < mac_id; count++) 1206 dp_rx_pdev_mon_cmn_desc_pool_free(pdev, count); 1207 1208 return status; 1209 } 1210 } 1211 return status; 1212 } 1213 1214 static inline 1215 void dp_rx_msdus_set_payload(struct dp_soc *soc, qdf_nbuf_t msdu) 1216 { 1217 uint8_t *data; 1218 uint32_t rx_pkt_offset, l2_hdr_offset; 1219 1220 data = qdf_nbuf_data(msdu); 1221 rx_pkt_offset = soc->rx_mon_pkt_tlv_size; 1222 l2_hdr_offset = hal_rx_msdu_end_l3_hdr_padding_get(soc->hal_soc, data); 1223 qdf_nbuf_pull_head(msdu, rx_pkt_offset + l2_hdr_offset); 1224 } 1225 1226 static inline qdf_nbuf_t 1227 dp_rx_mon_restitch_mpdu_from_msdus(struct dp_soc *soc, 1228 uint32_t mac_id, 1229 qdf_nbuf_t head_msdu, 1230 qdf_nbuf_t last_msdu, 1231 struct cdp_mon_status *rx_status) 1232 { 1233 qdf_nbuf_t msdu, mpdu_buf, prev_buf, msdu_orig, head_frag_list; 1234 uint32_t decap_format, wifi_hdr_len, sec_hdr_len, msdu_llc_len, 1235 mpdu_buf_len, decap_hdr_pull_bytes, frag_list_sum_len, dir, 1236 is_amsdu, is_first_frag, amsdu_pad; 1237 void *rx_desc; 1238 char *hdr_desc; 1239 unsigned char *dest; 1240 struct ieee80211_frame *wh; 1241 struct ieee80211_qoscntl *qos; 1242 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1243 struct dp_mon_pdev *mon_pdev; 1244 1245 head_frag_list = NULL; 1246 mpdu_buf = NULL; 1247 1248 if (qdf_unlikely(!dp_pdev)) { 1249 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", 1250 soc, mac_id); 1251 return NULL; 1252 } 1253 1254 mon_pdev = dp_pdev->monitor_pdev; 1255 1256 /* The nbuf has been pulled just beyond the status and points to the 1257 * payload 1258 */ 1259 if (!head_msdu) 1260 goto mpdu_stitch_fail; 1261 1262 msdu_orig = head_msdu; 1263 1264 rx_desc = qdf_nbuf_data(msdu_orig); 1265 1266 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc)) { 1267 /* It looks like there is some issue on MPDU len err */ 1268 /* Need further investigate if drop the packet */ 1269 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 1270 return NULL; 1271 } 1272 1273 rx_desc = qdf_nbuf_data(last_msdu); 1274 1275 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc, 1276 rx_desc); 1277 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err; 1278 1279 /* Fill out the rx_status from the PPDU start and end fields */ 1280 /* HAL_RX_GET_PPDU_STATUS(soc, mac_id, rx_status); */ 1281 1282 rx_desc = qdf_nbuf_data(head_msdu); 1283 1284 decap_format = hal_rx_tlv_decap_format_get(soc->hal_soc, rx_desc); 1285 1286 /* Easy case - The MSDU status indicates that this is a non-decapped 1287 * packet in RAW mode. 1288 */ 1289 if (decap_format == HAL_HW_RX_DECAP_FORMAT_RAW) { 1290 /* Note that this path might suffer from headroom unavailabilty 1291 * - but the RX status is usually enough 1292 */ 1293 1294 dp_rx_msdus_set_payload(soc, head_msdu); 1295 1296 dp_rx_mon_dest_debug("%pK: decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK", 1297 soc, head_msdu, head_msdu->next, 1298 last_msdu, last_msdu->next); 1299 1300 mpdu_buf = head_msdu; 1301 1302 prev_buf = mpdu_buf; 1303 1304 frag_list_sum_len = 0; 1305 msdu = qdf_nbuf_next(head_msdu); 1306 is_first_frag = 1; 1307 1308 while (msdu) { 1309 1310 dp_rx_msdus_set_payload(soc, msdu); 1311 1312 if (is_first_frag) { 1313 is_first_frag = 0; 1314 head_frag_list = msdu; 1315 } 1316 1317 frag_list_sum_len += qdf_nbuf_len(msdu); 1318 1319 /* Maintain the linking of the cloned MSDUS */ 1320 qdf_nbuf_set_next_ext(prev_buf, msdu); 1321 1322 /* Move to the next */ 1323 prev_buf = msdu; 1324 msdu = qdf_nbuf_next(msdu); 1325 } 1326 1327 qdf_nbuf_trim_tail(prev_buf, HAL_RX_FCS_LEN); 1328 1329 /* If there were more fragments to this RAW frame */ 1330 if (head_frag_list) { 1331 if (frag_list_sum_len < 1332 sizeof(struct ieee80211_frame_min_one)) { 1333 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 1334 return NULL; 1335 } 1336 frag_list_sum_len -= HAL_RX_FCS_LEN; 1337 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, 1338 frag_list_sum_len); 1339 qdf_nbuf_set_next(mpdu_buf, NULL); 1340 } 1341 1342 goto mpdu_stitch_done; 1343 } 1344 1345 /* Decap mode: 1346 * Calculate the amount of header in decapped packet to knock off based 1347 * on the decap type and the corresponding number of raw bytes to copy 1348 * status header 1349 */ 1350 rx_desc = qdf_nbuf_data(head_msdu); 1351 1352 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc); 1353 1354 dp_rx_mon_dest_debug("%pK: decap format not raw", soc); 1355 1356 /* Base size */ 1357 wifi_hdr_len = sizeof(struct ieee80211_frame); 1358 wh = (struct ieee80211_frame *)hdr_desc; 1359 1360 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 1361 1362 if (dir == IEEE80211_FC1_DIR_DSTODS) 1363 wifi_hdr_len += 6; 1364 1365 is_amsdu = 0; 1366 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) { 1367 qos = (struct ieee80211_qoscntl *) 1368 (hdr_desc + wifi_hdr_len); 1369 wifi_hdr_len += 2; 1370 1371 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU); 1372 } 1373 1374 /* Calculate security header length based on 'Protected' 1375 * and 'EXT_IV' flag 1376 */ 1377 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1378 char *iv = (char *)wh + wifi_hdr_len; 1379 1380 if (iv[3] & KEY_EXTIV) 1381 sec_hdr_len = 8; 1382 else 1383 sec_hdr_len = 4; 1384 } else { 1385 sec_hdr_len = 0; 1386 } 1387 wifi_hdr_len += sec_hdr_len; 1388 1389 /* MSDU related stuff LLC - AMSDU subframe header etc */ 1390 msdu_llc_len = is_amsdu ? (14 + 8) : 8; 1391 1392 mpdu_buf_len = wifi_hdr_len + msdu_llc_len; 1393 1394 /* "Decap" header to remove from MSDU buffer */ 1395 decap_hdr_pull_bytes = 14; 1396 1397 /* Allocate a new nbuf for holding the 802.11 header retrieved from the 1398 * status of the now decapped first msdu. Leave enough headroom for 1399 * accomodating any radio-tap /prism like PHY header 1400 */ 1401 mpdu_buf = qdf_nbuf_alloc(soc->osdev, 1402 MAX_MONITOR_HEADER + mpdu_buf_len, 1403 MAX_MONITOR_HEADER, 4, FALSE); 1404 1405 if (!mpdu_buf) 1406 goto mpdu_stitch_done; 1407 1408 /* Copy the MPDU related header and enc headers into the first buffer 1409 * - Note that there can be a 2 byte pad between heaader and enc header 1410 */ 1411 1412 prev_buf = mpdu_buf; 1413 dest = qdf_nbuf_put_tail(prev_buf, wifi_hdr_len); 1414 if (!dest) 1415 goto mpdu_stitch_fail; 1416 1417 qdf_mem_copy(dest, hdr_desc, wifi_hdr_len); 1418 hdr_desc += wifi_hdr_len; 1419 1420 #if 0 1421 dest = qdf_nbuf_put_tail(prev_buf, sec_hdr_len); 1422 adf_os_mem_copy(dest, hdr_desc, sec_hdr_len); 1423 hdr_desc += sec_hdr_len; 1424 #endif 1425 1426 /* The first LLC len is copied into the MPDU buffer */ 1427 frag_list_sum_len = 0; 1428 1429 msdu_orig = head_msdu; 1430 is_first_frag = 1; 1431 amsdu_pad = 0; 1432 1433 while (msdu_orig) { 1434 1435 /* TODO: intra AMSDU padding - do we need it ??? */ 1436 1437 msdu = msdu_orig; 1438 1439 if (is_first_frag) { 1440 head_frag_list = msdu; 1441 } else { 1442 /* Reload the hdr ptr only on non-first MSDUs */ 1443 rx_desc = qdf_nbuf_data(msdu_orig); 1444 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, 1445 rx_desc); 1446 } 1447 1448 /* Copy this buffers MSDU related status into the prev buffer */ 1449 1450 if (is_first_frag) 1451 is_first_frag = 0; 1452 1453 /* Update protocol and flow tag for MSDU */ 1454 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, 1455 msdu_orig, rx_desc); 1456 1457 dest = qdf_nbuf_put_tail(prev_buf, 1458 msdu_llc_len + amsdu_pad); 1459 1460 if (!dest) 1461 goto mpdu_stitch_fail; 1462 1463 dest += amsdu_pad; 1464 qdf_mem_copy(dest, hdr_desc, msdu_llc_len); 1465 1466 dp_rx_msdus_set_payload(soc, msdu); 1467 1468 /* Push the MSDU buffer beyond the decap header */ 1469 qdf_nbuf_pull_head(msdu, decap_hdr_pull_bytes); 1470 frag_list_sum_len += msdu_llc_len + qdf_nbuf_len(msdu) 1471 + amsdu_pad; 1472 1473 /* Set up intra-AMSDU pad to be added to start of next buffer - 1474 * AMSDU pad is 4 byte pad on AMSDU subframe 1475 */ 1476 amsdu_pad = (msdu_llc_len + qdf_nbuf_len(msdu)) & 0x3; 1477 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 1478 1479 /* TODO FIXME How do we handle MSDUs that have fraglist - Should 1480 * probably iterate all the frags cloning them along the way and 1481 * and also updating the prev_buf pointer 1482 */ 1483 1484 /* Move to the next */ 1485 prev_buf = msdu; 1486 msdu_orig = qdf_nbuf_next(msdu_orig); 1487 } 1488 1489 #if 0 1490 /* Add in the trailer section - encryption trailer + FCS */ 1491 qdf_nbuf_put_tail(prev_buf, HAL_RX_FCS_LEN); 1492 frag_list_sum_len += HAL_RX_FCS_LEN; 1493 #endif 1494 1495 frag_list_sum_len -= msdu_llc_len; 1496 1497 /* TODO: Convert this to suitable adf routines */ 1498 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, 1499 frag_list_sum_len); 1500 1501 dp_rx_mon_dest_debug("%pK: mpdu_buf %pK mpdu_buf->len %u", 1502 soc, mpdu_buf, mpdu_buf->len); 1503 1504 mpdu_stitch_done: 1505 /* Check if this buffer contains the PPDU end status for TSF */ 1506 /* Need revist this code to see where we can get tsf timestamp */ 1507 #if 0 1508 /* PPDU end TLV will be retrieved from monitor status ring */ 1509 last_mpdu = 1510 (*(((u_int32_t *)&rx_desc->attention)) & 1511 RX_ATTENTION_0_LAST_MPDU_MASK) >> 1512 RX_ATTENTION_0_LAST_MPDU_LSB; 1513 1514 if (last_mpdu) 1515 rx_status->rs_tstamp.tsf = rx_desc->ppdu_end.tsf_timestamp; 1516 1517 #endif 1518 return mpdu_buf; 1519 1520 mpdu_stitch_fail: 1521 if ((mpdu_buf) && (decap_format != HAL_HW_RX_DECAP_FORMAT_RAW)) { 1522 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail mpdu_buf %pK", 1523 soc, mpdu_buf); 1524 /* Free the head buffer */ 1525 qdf_nbuf_free(mpdu_buf); 1526 } 1527 return NULL; 1528 } 1529 1530 #ifdef DP_RX_MON_MEM_FRAG 1531 /** 1532 * dp_rx_mon_fraglist_prepare() - Prepare nbuf fraglist from chained skb 1533 * 1534 * @head_msdu: Parent SKB 1535 * @tail_msdu: Last skb in the chained list 1536 * 1537 * Return: Void 1538 */ 1539 void dp_rx_mon_fraglist_prepare(qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu) 1540 { 1541 qdf_nbuf_t msdu, mpdu_buf, prev_buf, head_frag_list; 1542 uint32_t frag_list_sum_len; 1543 1544 dp_err("[%s][%d] decap format raw head %pK head->next %pK last_msdu %pK last_msdu->next %pK", 1545 __func__, __LINE__, head_msdu, head_msdu->next, 1546 tail_msdu, tail_msdu->next); 1547 1548 /* Single skb accommodating MPDU worth Data */ 1549 if (tail_msdu == head_msdu) 1550 return; 1551 1552 mpdu_buf = head_msdu; 1553 prev_buf = mpdu_buf; 1554 frag_list_sum_len = 0; 1555 1556 msdu = qdf_nbuf_next(head_msdu); 1557 /* msdu can't be NULL here as it is multiple skb case here */ 1558 1559 /* Head frag list to point to second skb */ 1560 head_frag_list = msdu; 1561 1562 while (msdu) { 1563 frag_list_sum_len += qdf_nbuf_len(msdu); 1564 prev_buf = msdu; 1565 msdu = qdf_nbuf_next(msdu); 1566 } 1567 1568 qdf_nbuf_append_ext_list(mpdu_buf, head_frag_list, frag_list_sum_len); 1569 1570 /* Make Parent skb next to NULL */ 1571 qdf_nbuf_set_next(mpdu_buf, NULL); 1572 } 1573 1574 /** 1575 * dp_rx_mon_frag_restitch_mpdu_from_msdus() - Restitch logic to 1576 * convert to 802.3 header and adjust frag memory pointing to 1577 * dot3 header and payload in case of Non-Raw frame. 1578 * 1579 * @soc: struct dp_soc * 1580 * @mac_id: MAC id 1581 * @head_msdu: MPDU containing all MSDU as a frag 1582 * @tail_msdu: last skb which accommodate MPDU info 1583 * @rx_status: struct cdp_mon_status * 1584 * 1585 * Return: Adjusted nbuf containing MPDU worth info. 1586 */ 1587 static inline qdf_nbuf_t 1588 dp_rx_mon_frag_restitch_mpdu_from_msdus(struct dp_soc *soc, 1589 uint32_t mac_id, 1590 qdf_nbuf_t head_msdu, 1591 qdf_nbuf_t tail_msdu, 1592 struct cdp_mon_status *rx_status) 1593 { 1594 uint32_t wifi_hdr_len, sec_hdr_len, msdu_llc_len, 1595 mpdu_buf_len, decap_hdr_pull_bytes, dir, 1596 is_amsdu, amsdu_pad, frag_size, tot_msdu_len; 1597 qdf_frag_t rx_desc, rx_src_desc, rx_dest_desc, frag_addr; 1598 char *hdr_desc; 1599 uint8_t num_frags, frags_iter, l2_hdr_offset; 1600 struct ieee80211_frame *wh; 1601 struct ieee80211_qoscntl *qos; 1602 struct dp_pdev *dp_pdev = dp_get_pdev_for_lmac_id(soc, mac_id); 1603 int16_t frag_page_offset = 0; 1604 struct hal_rx_mon_dest_buf_info buf_info; 1605 uint32_t pad_byte_pholder = 0; 1606 qdf_nbuf_t msdu_curr; 1607 uint16_t rx_mon_tlv_size = soc->rx_mon_pkt_tlv_size; 1608 struct dp_mon_pdev *mon_pdev; 1609 1610 if (qdf_unlikely(!dp_pdev)) { 1611 dp_rx_mon_dest_debug("%pK: pdev is null for mac_id = %d", 1612 soc, mac_id); 1613 return NULL; 1614 } 1615 1616 mon_pdev = dp_pdev->monitor_pdev; 1617 qdf_mem_zero(&buf_info, sizeof(struct hal_rx_mon_dest_buf_info)); 1618 1619 if (!head_msdu || !tail_msdu) 1620 goto mpdu_stitch_fail; 1621 1622 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size; 1623 1624 if (hal_rx_tlv_mpdu_len_err_get(soc->hal_soc, rx_desc)) { 1625 /* It looks like there is some issue on MPDU len err */ 1626 /* Need further investigate if drop the packet */ 1627 DP_STATS_INC(dp_pdev, dropped.mon_rx_drop, 1); 1628 return NULL; 1629 } 1630 1631 /* Look for FCS error */ 1632 num_frags = qdf_nbuf_get_nr_frags(tail_msdu); 1633 rx_desc = qdf_nbuf_get_frag_addr(tail_msdu, num_frags - 1) - 1634 rx_mon_tlv_size; 1635 rx_status->cdp_rs_fcs_err = hal_rx_tlv_mpdu_fcs_err_get(soc->hal_soc, 1636 rx_desc); 1637 mon_pdev->ppdu_info.rx_status.rs_fcs_err = rx_status->cdp_rs_fcs_err; 1638 1639 rx_desc = qdf_nbuf_get_frag_addr(head_msdu, 0) - rx_mon_tlv_size; 1640 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc, 1641 (uint8_t *)&buf_info, 1642 sizeof(buf_info)); 1643 1644 /* Easy case - The MSDU status indicates that this is a non-decapped 1645 * packet in RAW mode. 1646 */ 1647 if (buf_info.is_decap_raw == 1) { 1648 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu); 1649 goto mpdu_stitch_done; 1650 } 1651 1652 l2_hdr_offset = DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 1653 1654 /* Decap mode: 1655 * Calculate the amount of header in decapped packet to knock off based 1656 * on the decap type and the corresponding number of raw bytes to copy 1657 * status header 1658 */ 1659 hdr_desc = hal_rx_desc_get_80211_hdr(soc->hal_soc, rx_desc); 1660 1661 dp_rx_mon_dest_debug("%pK: decap format not raw", soc); 1662 1663 /* Base size */ 1664 wifi_hdr_len = sizeof(struct ieee80211_frame); 1665 wh = (struct ieee80211_frame *)hdr_desc; 1666 1667 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; 1668 1669 if (dir == IEEE80211_FC1_DIR_DSTODS) 1670 wifi_hdr_len += 6; 1671 1672 is_amsdu = 0; 1673 if (wh->i_fc[0] & QDF_IEEE80211_FC0_SUBTYPE_QOS) { 1674 qos = (struct ieee80211_qoscntl *) 1675 (hdr_desc + wifi_hdr_len); 1676 wifi_hdr_len += 2; 1677 1678 is_amsdu = (qos->i_qos[0] & IEEE80211_QOS_AMSDU); 1679 } 1680 1681 /*Calculate security header length based on 'Protected' 1682 * and 'EXT_IV' flag 1683 */ 1684 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1685 char *iv = (char *)wh + wifi_hdr_len; 1686 1687 if (iv[3] & KEY_EXTIV) 1688 sec_hdr_len = 8; 1689 else 1690 sec_hdr_len = 4; 1691 } else { 1692 sec_hdr_len = 0; 1693 } 1694 wifi_hdr_len += sec_hdr_len; 1695 1696 /* MSDU related stuff LLC - AMSDU subframe header etc */ 1697 msdu_llc_len = is_amsdu ? (14 + 8) : 8; 1698 1699 mpdu_buf_len = wifi_hdr_len + msdu_llc_len; 1700 1701 /* "Decap" header to remove from MSDU buffer */ 1702 decap_hdr_pull_bytes = 14; 1703 1704 amsdu_pad = 0; 1705 tot_msdu_len = 0; 1706 1707 /* 1708 * keeping first MSDU ops outside of loop to avoid multiple 1709 * check handling 1710 */ 1711 1712 /* Construct src header */ 1713 rx_src_desc = hdr_desc; 1714 1715 /* 1716 * Update protocol and flow tag for MSDU 1717 * update frag index in ctx_idx field. 1718 * Reset head pointer data of nbuf before updating. 1719 */ 1720 QDF_NBUF_CB_RX_CTX_ID(head_msdu) = 0; 1721 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, head_msdu, rx_desc); 1722 1723 /* Construct destination address */ 1724 frag_addr = qdf_nbuf_get_frag_addr(head_msdu, 0); 1725 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0); 1726 /* We will come here in 2 scenario: 1727 * 1. First MSDU of MPDU with single buffer 1728 * 2. First buffer of First MSDU of MPDU with continuation 1729 * 1730 * ------------------------------------------------------------ 1731 * | SINGLE BUFFER (<= RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN)| 1732 * ------------------------------------------------------------ 1733 * 1734 * ------------------------------------------------------------ 1735 * | First BUFFER with Continuation | ... | 1736 * | (RX_MONITOR_BUFFER_SIZE - RX_PKT_TLVS_LEN) | | 1737 * ------------------------------------------------------------ 1738 */ 1739 pad_byte_pholder = 1740 (RX_MONITOR_BUFFER_SIZE - soc->rx_pkt_tlv_size) - frag_size; 1741 /* Construct destination address 1742 * -------------------------------------------------------------- 1743 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload | 1744 * | | / | 1745 * | >Frag address points here / | 1746 * | \ / | 1747 * | \ This bytes needs to / | 1748 * | \ removed to frame pkt / | 1749 * | ----------------------- | 1750 * | | | 1751 * | | | 1752 * | WIFI +LLC HDR will be added here <-| | 1753 * | | | | 1754 * | >Dest addr will point | | 1755 * | somewhere in this area | | 1756 * -------------------------------------------------------------- 1757 */ 1758 rx_dest_desc = 1759 (frag_addr + decap_hdr_pull_bytes + l2_hdr_offset) - 1760 mpdu_buf_len; 1761 /* Add WIFI and LLC header for 1st MSDU of MPDU */ 1762 qdf_mem_copy(rx_dest_desc, rx_src_desc, mpdu_buf_len); 1763 1764 frag_page_offset = 1765 (decap_hdr_pull_bytes + l2_hdr_offset) - mpdu_buf_len; 1766 1767 qdf_nbuf_move_frag_page_offset(head_msdu, 0, frag_page_offset); 1768 1769 frag_size = qdf_nbuf_get_frag_size_by_idx(head_msdu, 0); 1770 1771 if (buf_info.first_buffer && buf_info.last_buffer) { 1772 /* MSDU with single bufffer */ 1773 amsdu_pad = frag_size & 0x3; 1774 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 1775 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) { 1776 char *frag_addr_temp; 1777 1778 qdf_nbuf_trim_add_frag_size(head_msdu, 0, amsdu_pad, 1779 0); 1780 frag_addr_temp = 1781 (char *)qdf_nbuf_get_frag_addr(head_msdu, 0); 1782 frag_addr_temp = (frag_addr_temp + 1783 qdf_nbuf_get_frag_size_by_idx(head_msdu, 0)) - 1784 amsdu_pad; 1785 qdf_mem_zero(frag_addr_temp, amsdu_pad); 1786 amsdu_pad = 0; 1787 } 1788 } else { 1789 /* 1790 * First buffer of Continuation frame and hence 1791 * amsdu_padding doesn't need to be added 1792 * Increase tot_msdu_len so that amsdu_pad byte 1793 * will be calculated for last frame of MSDU 1794 */ 1795 tot_msdu_len = frag_size; 1796 amsdu_pad = 0; 1797 } 1798 1799 /* Here amsdu_pad byte will have some value if 1sf buffer was 1800 * Single buffer MSDU and dint had pholder to adjust amsdu padding 1801 * byte in the end 1802 * So dont initialize to ZERO here 1803 */ 1804 pad_byte_pholder = 0; 1805 for (msdu_curr = head_msdu; msdu_curr;) { 1806 /* frag_iter will start from 0 for second skb onwards */ 1807 if (msdu_curr == head_msdu) 1808 frags_iter = 1; 1809 else 1810 frags_iter = 0; 1811 1812 num_frags = qdf_nbuf_get_nr_frags(msdu_curr); 1813 1814 for (; frags_iter < num_frags; frags_iter++) { 1815 /* Construct destination address 1816 * ---------------------------------------------------------- 1817 * | RX_PKT_TLV | L2_HDR_PAD | Decap HDR | Payload | Pad | 1818 * | | (First buffer) | | | 1819 * | | / / | 1820 * | >Frag address points here / / | 1821 * | \ / / | 1822 * | \ This bytes needs to / / | 1823 * | \ removed to frame pkt/ / | 1824 * | ---------------------- / | 1825 * | | / Add | 1826 * | | / amsdu pad | 1827 * | LLC HDR will be added here <-| | Byte for | 1828 * | | | | last frame | 1829 * | >Dest addr will point | | if space | 1830 * | somewhere in this area | | available | 1831 * | And amsdu_pad will be created if | | | 1832 * | dint get added in last buffer | | | 1833 * | (First Buffer) | | | 1834 * ---------------------------------------------------------- 1835 */ 1836 frag_addr = 1837 qdf_nbuf_get_frag_addr(msdu_curr, frags_iter); 1838 rx_desc = frag_addr - rx_mon_tlv_size; 1839 1840 /* 1841 * Update protocol and flow tag for MSDU 1842 * update frag index in ctx_idx field 1843 */ 1844 QDF_NBUF_CB_RX_CTX_ID(msdu_curr) = frags_iter; 1845 dp_rx_mon_update_protocol_flow_tag(soc, dp_pdev, 1846 msdu_curr, rx_desc); 1847 1848 /* Read buffer info from stored data in tlvs */ 1849 hal_rx_priv_info_get_from_tlv(soc->hal_soc, rx_desc, 1850 (uint8_t *)&buf_info, 1851 sizeof(buf_info)); 1852 1853 frag_size = qdf_nbuf_get_frag_size_by_idx(msdu_curr, 1854 frags_iter); 1855 1856 /* If Middle buffer, dont add any header */ 1857 if ((!buf_info.first_buffer) && 1858 (!buf_info.last_buffer)) { 1859 tot_msdu_len += frag_size; 1860 amsdu_pad = 0; 1861 pad_byte_pholder = 0; 1862 continue; 1863 } 1864 1865 /* Calculate if current buffer has placeholder 1866 * to accommodate amsdu pad byte 1867 */ 1868 pad_byte_pholder = 1869 (RX_MONITOR_BUFFER_SIZE - soc->rx_pkt_tlv_size) 1870 - frag_size; 1871 /* 1872 * We will come here only only three condition: 1873 * 1. Msdu with single Buffer 1874 * 2. First buffer in case MSDU is spread in multiple 1875 * buffer 1876 * 3. Last buffer in case MSDU is spread in multiple 1877 * buffer 1878 * 1879 * First buffER | Last buffer 1880 * Case 1: 1 | 1 1881 * Case 2: 1 | 0 1882 * Case 3: 0 | 1 1883 * 1884 * In 3rd case only l2_hdr_padding byte will be Zero and 1885 * in other case, It will be 2 Bytes. 1886 */ 1887 if (buf_info.first_buffer) 1888 l2_hdr_offset = 1889 DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 1890 else 1891 l2_hdr_offset = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 1892 1893 if (buf_info.first_buffer) { 1894 /* Src addr from where llc header needs to be copied */ 1895 rx_src_desc = 1896 hal_rx_desc_get_80211_hdr(soc->hal_soc, 1897 rx_desc); 1898 1899 /* Size of buffer with llc header */ 1900 frag_size = frag_size - 1901 (l2_hdr_offset + decap_hdr_pull_bytes); 1902 frag_size += msdu_llc_len; 1903 1904 /* Construct destination address */ 1905 rx_dest_desc = frag_addr + 1906 decap_hdr_pull_bytes + l2_hdr_offset; 1907 rx_dest_desc = rx_dest_desc - (msdu_llc_len); 1908 1909 qdf_mem_copy(rx_dest_desc, rx_src_desc, 1910 msdu_llc_len); 1911 1912 /* 1913 * Calculate new page offset and create hole 1914 * if amsdu_pad required. 1915 */ 1916 frag_page_offset = l2_hdr_offset + 1917 decap_hdr_pull_bytes; 1918 frag_page_offset = frag_page_offset - 1919 (msdu_llc_len + amsdu_pad); 1920 1921 qdf_nbuf_move_frag_page_offset(msdu_curr, 1922 frags_iter, 1923 frag_page_offset); 1924 1925 tot_msdu_len = frag_size; 1926 /* 1927 * No amsdu padding required for first frame of 1928 * continuation buffer 1929 */ 1930 if (!buf_info.last_buffer) { 1931 amsdu_pad = 0; 1932 continue; 1933 } 1934 } else { 1935 tot_msdu_len += frag_size; 1936 } 1937 1938 /* Will reach to this place in only two case: 1939 * 1. Single buffer MSDU 1940 * 2. Last buffer of MSDU in case of multiple buf MSDU 1941 */ 1942 1943 /* Check size of buffer if amsdu padding required */ 1944 amsdu_pad = tot_msdu_len & 0x3; 1945 amsdu_pad = amsdu_pad ? (4 - amsdu_pad) : 0; 1946 1947 /* Create placeholder if current bufer can 1948 * accommodate padding. 1949 */ 1950 if (amsdu_pad && (amsdu_pad <= pad_byte_pholder)) { 1951 char *frag_addr_temp; 1952 1953 qdf_nbuf_trim_add_frag_size(msdu_curr, 1954 frags_iter, 1955 amsdu_pad, 0); 1956 frag_addr_temp = (char *)qdf_nbuf_get_frag_addr(msdu_curr, 1957 frags_iter); 1958 frag_addr_temp = (frag_addr_temp + 1959 qdf_nbuf_get_frag_size_by_idx(msdu_curr, frags_iter)) - 1960 amsdu_pad; 1961 qdf_mem_zero(frag_addr_temp, amsdu_pad); 1962 amsdu_pad = 0; 1963 } 1964 1965 /* reset tot_msdu_len */ 1966 tot_msdu_len = 0; 1967 } 1968 msdu_curr = qdf_nbuf_next(msdu_curr); 1969 } 1970 1971 dp_rx_mon_fraglist_prepare(head_msdu, tail_msdu); 1972 1973 dp_rx_mon_dest_debug("%pK: head_msdu %pK head_msdu->len %u", 1974 soc, head_msdu, head_msdu->len); 1975 1976 mpdu_stitch_done: 1977 return head_msdu; 1978 1979 mpdu_stitch_fail: 1980 dp_rx_mon_dest_err("%pK: mpdu_stitch_fail head_msdu %pK", 1981 soc, head_msdu); 1982 return NULL; 1983 } 1984 #endif 1985 1986 #ifdef DP_RX_MON_MEM_FRAG 1987 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id, 1988 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu, 1989 struct cdp_mon_status *rs) 1990 { 1991 if (qdf_nbuf_get_nr_frags(head_msdu)) 1992 return dp_rx_mon_frag_restitch_mpdu_from_msdus(soc, mac_id, 1993 head_msdu, 1994 tail_msdu, rs); 1995 else 1996 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id, 1997 head_msdu, 1998 tail_msdu, rs); 1999 } 2000 #else 2001 qdf_nbuf_t dp_rx_mon_restitch_mpdu(struct dp_soc *soc, uint32_t mac_id, 2002 qdf_nbuf_t head_msdu, qdf_nbuf_t tail_msdu, 2003 struct cdp_mon_status *rs) 2004 { 2005 return dp_rx_mon_restitch_mpdu_from_msdus(soc, mac_id, head_msdu, 2006 tail_msdu, rs); 2007 } 2008 #endif 2009 2010 #ifdef DP_RX_MON_MEM_FRAG 2011 #if defined(WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG) ||\ 2012 defined(WLAN_SUPPORT_RX_FLOW_TAG) 2013 void dp_rx_mon_update_pf_tag_to_buf_headroom(struct dp_soc *soc, 2014 qdf_nbuf_t nbuf) 2015 { 2016 qdf_nbuf_t ext_list; 2017 2018 if (qdf_unlikely(!soc)) { 2019 dp_err("Soc[%pK] Null. Can't update pftag to nbuf headroom\n", 2020 soc); 2021 qdf_assert_always(0); 2022 } 2023 2024 if (!wlan_cfg_is_rx_mon_protocol_flow_tag_enabled(soc->wlan_cfg_ctx)) 2025 return; 2026 2027 if (qdf_unlikely(!nbuf)) 2028 return; 2029 2030 /* Return if it dint came from mon Path */ 2031 if (!qdf_nbuf_get_nr_frags(nbuf)) 2032 return; 2033 2034 /* Headroom must be double of PF_TAG_SIZE as we copy it 1stly to head */ 2035 if (qdf_unlikely(qdf_nbuf_headroom(nbuf) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) { 2036 dp_err("Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]", 2037 qdf_nbuf_headroom(nbuf), DP_RX_MON_TOT_PF_TAG_LEN); 2038 return; 2039 } 2040 2041 qdf_nbuf_push_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN); 2042 qdf_mem_copy(qdf_nbuf_data(nbuf), qdf_nbuf_head(nbuf), 2043 DP_RX_MON_TOT_PF_TAG_LEN); 2044 qdf_nbuf_pull_head(nbuf, DP_RX_MON_TOT_PF_TAG_LEN); 2045 2046 ext_list = qdf_nbuf_get_ext_list(nbuf); 2047 while (ext_list) { 2048 /* Headroom must be double of PF_TAG_SIZE 2049 * as we copy it 1stly to head 2050 */ 2051 if (qdf_unlikely(qdf_nbuf_headroom(ext_list) < (DP_RX_MON_TOT_PF_TAG_LEN * 2))) { 2052 dp_err("Fraglist Nbuf avail Headroom[%d] < 2 * DP_RX_MON_PF_TAG_TOT_LEN[%lu]", 2053 qdf_nbuf_headroom(ext_list), 2054 DP_RX_MON_TOT_PF_TAG_LEN); 2055 ext_list = qdf_nbuf_queue_next(ext_list); 2056 continue; 2057 } 2058 qdf_nbuf_push_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN); 2059 qdf_mem_copy(qdf_nbuf_data(ext_list), qdf_nbuf_head(ext_list), 2060 DP_RX_MON_TOT_PF_TAG_LEN); 2061 qdf_nbuf_pull_head(ext_list, DP_RX_MON_TOT_PF_TAG_LEN); 2062 ext_list = qdf_nbuf_queue_next(ext_list); 2063 } 2064 } 2065 #endif 2066 #endif 2067 2068 #ifdef QCA_MONITOR_PKT_SUPPORT 2069 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc, 2070 struct dp_pdev *pdev, 2071 int mac_id, 2072 int mac_for_pdev) 2073 { 2074 QDF_STATUS status = QDF_STATUS_SUCCESS; 2075 2076 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2077 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2078 soc->rxdma_mon_buf_ring[mac_id] 2079 .hal_srng, 2080 RXDMA_MONITOR_BUF); 2081 2082 if (status != QDF_STATUS_SUCCESS) { 2083 dp_mon_err("Failed to send htt srng setup message for Rxdma mon buf ring"); 2084 return status; 2085 } 2086 2087 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2088 soc->rxdma_mon_dst_ring[mac_id] 2089 .hal_srng, 2090 RXDMA_MONITOR_DST); 2091 2092 if (status != QDF_STATUS_SUCCESS) { 2093 dp_mon_err("Failed to send htt srng setup message for Rxdma mon dst ring"); 2094 return status; 2095 } 2096 2097 status = htt_srng_setup(soc->htt_handle, mac_for_pdev, 2098 soc->rxdma_mon_desc_ring[mac_id] 2099 .hal_srng, 2100 RXDMA_MONITOR_DESC); 2101 2102 if (status != QDF_STATUS_SUCCESS) { 2103 dp_mon_err("Failed to send htt srng message for Rxdma mon desc ring"); 2104 return status; 2105 } 2106 } 2107 2108 return status; 2109 } 2110 #endif /* QCA_MONITOR_PKT_SUPPORT */ 2111 2112 #ifdef QCA_MONITOR_PKT_SUPPORT 2113 void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id) 2114 { 2115 struct dp_soc *soc = pdev->soc; 2116 2117 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2118 dp_srng_deinit(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2119 RXDMA_MONITOR_BUF, 0); 2120 dp_srng_deinit(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2121 RXDMA_MONITOR_DST, 0); 2122 dp_srng_deinit(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2123 RXDMA_MONITOR_DESC, 0); 2124 } 2125 } 2126 2127 void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id) 2128 { 2129 struct dp_soc *soc = pdev->soc; 2130 2131 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2132 dp_srng_free(soc, &soc->rxdma_mon_buf_ring[lmac_id]); 2133 dp_srng_free(soc, &soc->rxdma_mon_dst_ring[lmac_id]); 2134 dp_srng_free(soc, &soc->rxdma_mon_desc_ring[lmac_id]); 2135 } 2136 } 2137 2138 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id) 2139 { 2140 struct dp_soc *soc = pdev->soc; 2141 2142 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2143 if (dp_srng_init(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2144 RXDMA_MONITOR_BUF, 0, lmac_id)) { 2145 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc); 2146 goto fail1; 2147 } 2148 2149 if (dp_srng_init(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2150 RXDMA_MONITOR_DST, 0, lmac_id)) { 2151 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc); 2152 goto fail1; 2153 } 2154 2155 if (dp_srng_init(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2156 RXDMA_MONITOR_DESC, 0, lmac_id)) { 2157 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc); 2158 goto fail1; 2159 } 2160 } 2161 return QDF_STATUS_SUCCESS; 2162 2163 fail1: 2164 return QDF_STATUS_E_NOMEM; 2165 } 2166 2167 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id) 2168 { 2169 int entries; 2170 struct dp_soc *soc = pdev->soc; 2171 struct wlan_cfg_dp_pdev_ctxt *pdev_cfg_ctx = pdev->wlan_cfg_ctx; 2172 2173 if (soc->wlan_cfg_ctx->rxdma1_enable) { 2174 entries = wlan_cfg_get_dma_mon_buf_ring_size(pdev_cfg_ctx); 2175 if (dp_srng_alloc(soc, &soc->rxdma_mon_buf_ring[lmac_id], 2176 RXDMA_MONITOR_BUF, entries, 0)) { 2177 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_buf_ring ", soc); 2178 goto fail1; 2179 } 2180 entries = wlan_cfg_get_dma_rx_mon_dest_ring_size(pdev_cfg_ctx); 2181 if (dp_srng_alloc(soc, &soc->rxdma_mon_dst_ring[lmac_id], 2182 RXDMA_MONITOR_DST, entries, 0)) { 2183 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_dst_ring", soc); 2184 goto fail1; 2185 } 2186 entries = wlan_cfg_get_dma_mon_desc_ring_size(pdev_cfg_ctx); 2187 if (dp_srng_alloc(soc, &soc->rxdma_mon_desc_ring[lmac_id], 2188 RXDMA_MONITOR_DESC, entries, 0)) { 2189 dp_mon_err("%pK: " RNG_ERR "rxdma_mon_desc_ring", soc); 2190 goto fail1; 2191 } 2192 } 2193 return QDF_STATUS_SUCCESS; 2194 2195 fail1: 2196 return QDF_STATUS_E_NOMEM; 2197 } 2198 #endif 2199