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