1 /* 2 * Copyright (c) 2021, The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #ifndef _DP_RX_MON_1_0_H_ 18 #define _DP_RX_MON_1_0_H_ 19 20 #include <dp_rx.h> 21 /* 22 * MON_BUF_MIN_ENTRIES macro defines minimum number of network buffers 23 * to be refilled in the RXDMA monitor buffer ring at init, remaining 24 * buffers are replenished at the time of monitor vap creation 25 */ 26 #define MON_BUF_MIN_ENTRIES 64 27 28 /* 29 * The below macro defines the maximum number of ring entries that would 30 * be processed in a single instance when processing each of the non-monitoring 31 * RXDMA2SW ring. 32 */ 33 #define MON_DROP_REAP_LIMIT 64 34 35 QDF_STATUS dp_rx_pdev_mon_status_buffers_alloc(struct dp_pdev *pdev, 36 uint32_t mac_id); 37 QDF_STATUS dp_rx_pdev_mon_status_desc_pool_alloc(struct dp_pdev *pdev, 38 uint32_t mac_id); 39 void dp_rx_pdev_mon_status_desc_pool_init(struct dp_pdev *pdev, 40 uint32_t mac_id); 41 void dp_rx_pdev_mon_status_desc_pool_deinit(struct dp_pdev *pdev, 42 uint32_t mac_id); 43 void dp_rx_pdev_mon_status_desc_pool_free(struct dp_pdev *pdev, 44 uint32_t mac_id); 45 void dp_rx_pdev_mon_status_buffers_free(struct dp_pdev *pdev, uint32_t mac_id); 46 47 QDF_STATUS dp_rx_pdev_mon_desc_pool_alloc(struct dp_pdev *pdev); 48 QDF_STATUS dp_rx_pdev_mon_buffers_alloc(struct dp_pdev *pdev); 49 void dp_rx_pdev_mon_buffers_free(struct dp_pdev *pdev); 50 void dp_rx_pdev_mon_desc_pool_init(struct dp_pdev *pdev); 51 void dp_rx_pdev_mon_desc_pool_deinit(struct dp_pdev *pdev); 52 void dp_rx_pdev_mon_desc_pool_free(struct dp_pdev *pdev); 53 54 /** 55 * dp_rx_mon_dest_process() - Brain of the Rx processing functionality 56 * Called from the bottom half (tasklet/NET_RX_SOFTIRQ) 57 * @soc: core txrx main context 58 * @int_ctx: interrupt context 59 * @mac_id: mac id 60 * @quota: No. of units (packets) that can be serviced in one shot. 61 * 62 * This function implements the core of Rx functionality. This is 63 * expected to handle only non-error frames. 64 * 65 * Return: none 66 */ 67 #ifdef QCA_MONITOR_PKT_SUPPORT 68 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, 69 uint32_t mac_id, uint32_t quota); 70 71 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id); 72 QDF_STATUS 73 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id, 74 bool delayed_replenish); 75 QDF_STATUS 76 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id); 77 void 78 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id); 79 #else 80 static inline 81 void dp_rx_mon_dest_process(struct dp_soc *soc, struct dp_intr *int_ctx, 82 uint32_t mac_id, uint32_t quota) 83 { 84 } 85 86 static inline 87 void dp_rx_pdev_mon_buf_buffers_free(struct dp_pdev *pdev, uint32_t mac_id) 88 { 89 } 90 91 static inline QDF_STATUS 92 dp_rx_pdev_mon_buf_buffers_alloc(struct dp_pdev *pdev, uint32_t mac_id, 93 bool delayed_replenish) 94 { 95 return QDF_STATUS_SUCCESS; 96 } 97 98 static inline QDF_STATUS 99 dp_rx_pdev_mon_buf_desc_pool_alloc(struct dp_pdev *pdev, uint32_t mac_id) 100 { 101 return QDF_STATUS_SUCCESS; 102 } 103 104 static inline void 105 dp_rx_pdev_mon_buf_desc_pool_init(struct dp_pdev *pdev, uint32_t mac_id) 106 { 107 } 108 #endif 109 110 #if !defined(DISABLE_MON_CONFIG) && defined(MON_ENABLE_DROP_FOR_MAC) 111 /** 112 * dp_mon_dest_srng_drop_for_mac() - Drop the mon dest ring packets for 113 * a given mac 114 * @pdev: DP pdev 115 * @mac_id: mac id 116 * @force_flush: Force flush ring 117 * 118 * Return: None 119 */ 120 uint32_t 121 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id, 122 bool force_flush); 123 #else 124 #ifdef QCA_SUPPORT_FULL_MON 125 /** 126 * dp_mon_dest_srng_drop_for_mac() - Drop the mon dest ring packets for 127 * a given mac 128 * @pdev: DP pdev 129 * @mac_id: mac id 130 * 131 * Return: None 132 */ 133 uint32_t 134 dp_mon_dest_srng_drop_for_mac(struct dp_pdev *pdev, uint32_t mac_id); 135 #endif 136 #endif 137 138 /** 139 * dp_rxdma_err_process() - RxDMA error processing functionality 140 * @int_ctx: interrupt context 141 * @soc: core txrx main context 142 * @mac_id: mac id 143 * @quota: No. of units (packets) that can be serviced in one shot. 144 * 145 * Return: num of buffers processed 146 */ 147 uint32_t dp_rxdma_err_process(struct dp_intr *int_ctx, struct dp_soc *soc, 148 uint32_t mac_id, uint32_t quota); 149 150 /** 151 * dp_mon_buf_delayed_replenish() - Helper routine to replenish monitor dest buf 152 * @pdev: DP pdev object 153 * 154 * Return: None 155 */ 156 void dp_mon_buf_delayed_replenish(struct dp_pdev *pdev); 157 158 #ifdef QCA_MONITOR_PKT_SUPPORT 159 /** 160 * dp_rx_mon_link_desc_return() - Return a MPDU link descriptor to HW 161 * (WBM), following error handling 162 * 163 * @dp_pdev: core txrx pdev context 164 * @buf_addr_info: void pointer to monitor link descriptor buf addr info 165 * @mac_id: mac id which is one of 3 mac_ids 166 * 167 * Return: QDF_STATUS 168 */ 169 QDF_STATUS 170 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, 171 hal_buff_addrinfo_t buf_addr_info, 172 int mac_id); 173 #else 174 static inline QDF_STATUS 175 dp_rx_mon_link_desc_return(struct dp_pdev *dp_pdev, 176 hal_buff_addrinfo_t buf_addr_info, 177 int mac_id) 178 { 179 return QDF_STATUS_SUCCESS; 180 } 181 #endif 182 183 #if defined(WLAN_MAX_PDEVS) && (WLAN_MAX_PDEVS == 1) 184 static inline uint16_t dp_rx_mon_get_rx_pkt_tlv_size(struct dp_soc *soc) 185 { 186 return soc->curr_rx_pkt_tlv_size; 187 } 188 #else 189 static inline uint16_t dp_rx_mon_get_rx_pkt_tlv_size(struct dp_soc *soc) 190 { 191 return soc->rx_mon_pkt_tlv_size; 192 } 193 #endif 194 195 /** 196 * dp_mon_adjust_frag_len() - MPDU and MSDU may spread across 197 * multiple nbufs. This function 198 * is to return data length in 199 * fragmented buffer 200 * @soc: Datapath soc handle 201 * @total_len: pointer to remaining data length. 202 * @frag_len: pointer to data length in this fragment. 203 * @l2_hdr_pad: l2 header padding 204 */ 205 static inline void dp_mon_adjust_frag_len(struct dp_soc *soc, 206 uint32_t *total_len, 207 uint32_t *frag_len, 208 uint16_t l2_hdr_pad) 209 { 210 uint32_t rx_pkt_tlv_len = soc->rx_mon_pkt_tlv_size; 211 212 if (*total_len >= (RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len)) { 213 *frag_len = RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len - 214 l2_hdr_pad; 215 *total_len -= *frag_len; 216 } else { 217 *frag_len = *total_len; 218 *total_len = 0; 219 } 220 } 221 222 /** 223 * dp_rx_mon_frag_adjust_frag_len() - MPDU and MSDU may spread across 224 * multiple nbufs. This function is to return data length in 225 * fragmented buffer. 226 * It takes input as max_limit for any buffer(as it changes based 227 * on decap type and buffer sequence in MSDU. 228 * 229 * If MSDU is divided into multiple buffer then below format will 230 * be max limit. 231 * Decap type Non-Raw 232 *-------------------------------- 233 *| 1st | 2nd | ... | Last | 234 *| 1662 | 1664 | 1664 | <=1664 | 235 *-------------------------------- 236 * Decap type Raw 237 *-------------------------------- 238 *| 1st | 2nd | ... | Last | 239 *| 1664 | 1664 | 1664 | <=1664 | 240 *-------------------------------- 241 * 242 * It also calculate if current buffer has placeholder to keep padding byte. 243 * -------------------------------- 244 * | MAX LIMIT(1662/1664) | 245 * -------------------------------- 246 * | Actual Data | Pad byte Pholder | 247 * -------------------------------- 248 * 249 * @total_len: Remaining data length. 250 * @frag_len: Data length in this fragment. 251 * @max_limit: Max limit of current buffer/MSDU. 252 */ 253 #ifdef DP_RX_MON_MEM_FRAG 254 static inline 255 void dp_rx_mon_frag_adjust_frag_len(uint32_t *total_len, uint32_t *frag_len, 256 uint32_t max_limit) 257 { 258 if (*total_len >= max_limit) { 259 *frag_len = max_limit; 260 *total_len -= *frag_len; 261 } else { 262 *frag_len = *total_len; 263 *total_len = 0; 264 } 265 } 266 267 /** 268 * DP_RX_MON_GET_NBUF_FROM_DESC() - Get nbuf from desc 269 * @rx_desc: RX descriptor 270 * 271 * Return: nbuf address 272 */ 273 #define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \ 274 NULL 275 276 /** 277 * dp_rx_mon_add_msdu_to_list_failure_handler() - Handler for nbuf buffer 278 * attach failure 279 * 280 * @rx_tlv_hdr: rx_tlv_hdr 281 * @pdev: struct dp_pdev * 282 * @last: skb pointing to last skb in chained list at any moment 283 * @head_msdu: parent skb in the chained list 284 * @tail_msdu: Last skb in the chained list 285 * @func_name: caller function name 286 * 287 * Return: void 288 */ 289 static inline void 290 dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr, 291 struct dp_pdev *pdev, 292 qdf_nbuf_t *last, 293 qdf_nbuf_t *head_msdu, 294 qdf_nbuf_t *tail_msdu, 295 const char *func_name) 296 { 297 DP_STATS_INC(pdev, replenish.nbuf_alloc_fail, 1); 298 qdf_frag_free(rx_tlv_hdr); 299 if (head_msdu) 300 qdf_nbuf_list_free(*head_msdu); 301 dp_err("[%s] failed to allocate subsequent parent buffer to hold all frag", 302 func_name); 303 if (head_msdu) 304 *head_msdu = NULL; 305 if (last) 306 *last = NULL; 307 if (tail_msdu) 308 *tail_msdu = NULL; 309 } 310 311 /** 312 * dp_rx_mon_get_paddr_from_desc() - Get paddr from desc 313 * @rx_desc: RX descriptor 314 * 315 * Return: Physical address of the buffer 316 */ 317 static inline 318 qdf_dma_addr_t dp_rx_mon_get_paddr_from_desc(struct dp_rx_desc *rx_desc) 319 { 320 return rx_desc->paddr_buf_start; 321 } 322 323 /** 324 * DP_RX_MON_IS_BUFFER_ADDR_NULL() - Is Buffer received from hw is NULL 325 * @rx_desc: RX descriptor 326 * 327 * Return: true if the buffer is NULL, otherwise false 328 */ 329 #define DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) \ 330 (!(rx_desc->rx_buf_start)) 331 332 #define DP_RX_MON_IS_MSDU_NOT_NULL(msdu) \ 333 true 334 335 /** 336 * dp_rx_mon_buffer_free() - Free nbuf or frag memory 337 * Free nbuf if feature is disabled, else free frag. 338 * 339 * @rx_desc: Rx desc 340 */ 341 static inline void 342 dp_rx_mon_buffer_free(struct dp_rx_desc *rx_desc) 343 { 344 qdf_frag_free(rx_desc->rx_buf_start); 345 } 346 347 /** 348 * dp_rx_mon_buffer_unmap() - Unmap nbuf or frag memory 349 * Unmap nbuf if feature is disabled, else unmap frag. 350 * 351 * @soc: struct dp_soc * 352 * @rx_desc: struct dp_rx_desc * 353 * @size: Size to be unmapped 354 */ 355 static inline void 356 dp_rx_mon_buffer_unmap(struct dp_soc *soc, struct dp_rx_desc *rx_desc, 357 uint16_t size) 358 { 359 qdf_mem_unmap_page(soc->osdev, rx_desc->paddr_buf_start, 360 size, QDF_DMA_FROM_DEVICE); 361 } 362 363 /** 364 * dp_rx_mon_alloc_parent_buffer() - Allocate parent buffer to hold 365 * radiotap header and accommodate all frag memory in nr_frag. 366 * 367 * @head_msdu: Ptr to hold allocated Msdu 368 * 369 * Return: QDF_STATUS 370 */ 371 static inline 372 QDF_STATUS dp_rx_mon_alloc_parent_buffer(qdf_nbuf_t *head_msdu) 373 { 374 /* 375 * Headroom should accommodate radiotap header 376 * and protocol and flow tag for all frag 377 * Length reserved to accommodate Radiotap header 378 * is 128 bytes and length reserved for Protocol 379 * flow tag will vary based on QDF_NBUF_MAX_FRAGS. 380 */ 381 /* ------------------------------------------------- 382 * | Protocol & Flow TAG | Radiotap header| 383 * | | Length(128 B) | 384 * | ((4* QDF_NBUF_MAX_FRAGS) * 2) | | 385 * ------------------------------------------------- 386 */ 387 388 *head_msdu = qdf_nbuf_alloc_no_recycler(DP_RX_MON_MAX_MONITOR_HEADER, 389 DP_RX_MON_MAX_MONITOR_HEADER, 4); 390 391 if (!(*head_msdu)) 392 return QDF_STATUS_E_FAILURE; 393 394 qdf_mem_zero(qdf_nbuf_head(*head_msdu), qdf_nbuf_headroom(*head_msdu)); 395 396 /* Set *head_msdu->next as NULL as all msdus are 397 * mapped via nr frags 398 */ 399 qdf_nbuf_set_next(*head_msdu, NULL); 400 401 return QDF_STATUS_SUCCESS; 402 } 403 404 /** 405 * dp_rx_mon_parse_desc_buffer() - Parse desc buffer based. 406 * @dp_soc: struct dp_soc* 407 * @msdu_info: struct hal_rx_msdu_desc_info* 408 * @is_frag_p: is_frag * 409 * @total_frag_len_p: Remaining frag len to be updated 410 * @frag_len_p: frag len 411 * @l2_hdr_offset_p: l2 hdr offset 412 * @rx_desc_tlv: rx_desc_tlv 413 * @first_rx_desc_tlv: 414 * @is_frag_non_raw_p: Non raw frag 415 * @data: NBUF Data 416 * 417 * Below code will parse desc buffer, handle continuation frame, 418 * adjust frag length and update l2_hdr_padding 419 * 420 */ 421 static inline void 422 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc, 423 struct hal_rx_msdu_desc_info *msdu_info, 424 bool *is_frag_p, uint32_t *total_frag_len_p, 425 uint32_t *frag_len_p, uint16_t *l2_hdr_offset_p, 426 qdf_frag_t rx_desc_tlv, 427 void **first_rx_desc_tlv, 428 bool *is_frag_non_raw_p, void *data) 429 { 430 struct hal_rx_mon_dest_buf_info frame_info; 431 uint16_t tot_payload_len = 432 RX_MONITOR_BUFFER_SIZE - dp_soc->rx_mon_pkt_tlv_size; 433 434 if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) { 435 /* First buffer of MSDU */ 436 if (!(*is_frag_p)) { 437 /* Set total frag_len from msdu_len */ 438 *total_frag_len_p = msdu_info->msdu_len; 439 440 *is_frag_p = true; 441 if (HAL_HW_RX_DECAP_FORMAT_RAW == 442 hal_rx_tlv_decap_format_get(dp_soc->hal_soc, 443 rx_desc_tlv)) { 444 *l2_hdr_offset_p = 445 DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 446 frame_info.is_decap_raw = 1; 447 } else { 448 *l2_hdr_offset_p = 449 DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 450 frame_info.is_decap_raw = 0; 451 *is_frag_non_raw_p = true; 452 } 453 dp_rx_mon_frag_adjust_frag_len(total_frag_len_p, 454 frag_len_p, 455 tot_payload_len - 456 *l2_hdr_offset_p); 457 458 frame_info.first_buffer = 1; 459 frame_info.last_buffer = 0; 460 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 461 rx_desc_tlv, 462 (uint8_t *)&frame_info, 463 sizeof(frame_info)); 464 } else { 465 /* 466 * Continuation Middle frame 467 * Here max limit will be same for Raw and Non raw case. 468 */ 469 *l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 470 dp_rx_mon_frag_adjust_frag_len(total_frag_len_p, 471 frag_len_p, 472 tot_payload_len); 473 474 /* Update frame info if is non raw frame */ 475 if (*is_frag_non_raw_p) 476 frame_info.is_decap_raw = 0; 477 else 478 frame_info.is_decap_raw = 1; 479 480 frame_info.first_buffer = 0; 481 frame_info.last_buffer = 0; 482 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 483 rx_desc_tlv, 484 (uint8_t *)&frame_info, 485 sizeof(frame_info)); 486 } 487 } else { 488 /** 489 * Last buffer of MSDU spread among multiple buffer 490 * Here max limit will be same for Raw and Non raw case. 491 */ 492 if (*is_frag_p) { 493 *l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 494 495 dp_rx_mon_frag_adjust_frag_len(total_frag_len_p, 496 frag_len_p, 497 tot_payload_len); 498 499 /* Update frame info if is non raw frame */ 500 if (*is_frag_non_raw_p) 501 frame_info.is_decap_raw = 0; 502 else 503 frame_info.is_decap_raw = 1; 504 505 frame_info.first_buffer = 0; 506 frame_info.last_buffer = 1; 507 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 508 rx_desc_tlv, 509 (uint8_t *)&frame_info, 510 sizeof(frame_info)); 511 } else { 512 /* MSDU with single buffer */ 513 *frag_len_p = msdu_info->msdu_len; 514 if (HAL_HW_RX_DECAP_FORMAT_RAW == 515 hal_rx_tlv_decap_format_get(dp_soc->hal_soc, 516 rx_desc_tlv)) { 517 *l2_hdr_offset_p = 518 DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 519 frame_info.is_decap_raw = 1; 520 } else { 521 *l2_hdr_offset_p = 522 DP_RX_MON_NONRAW_L2_HDR_PAD_BYTE; 523 frame_info.is_decap_raw = 0; 524 } 525 526 frame_info.first_buffer = 1; 527 frame_info.last_buffer = 1; 528 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 529 rx_desc_tlv, 530 (uint8_t *)&frame_info, 531 sizeof(frame_info)); 532 } 533 /* Reset bool after complete processing of MSDU */ 534 *is_frag_p = false; 535 *is_frag_non_raw_p = false; 536 } 537 } 538 539 /** 540 * dp_rx_mon_buffer_set_pktlen() - set pktlen for buffer 541 * @msdu: MSDU 542 * @size: MSDU size 543 */ 544 static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size) 545 { 546 } 547 548 /** 549 * dp_rx_mon_add_msdu_to_list()- Add msdu to list and update head_msdu 550 * It will add reaped buffer frag to nr frag of parent msdu. 551 * @soc: DP soc handle 552 * @head_msdu: NULL if first time called else &msdu 553 * @msdu: Msdu where frag address needs to be added via nr_frag 554 * @last: Used to traverse in list if this feature is disabled. 555 * @rx_desc_tlv: Frag address 556 * @frag_len: Frag len 557 * @l2_hdr_offset: l2 hdr padding 558 */ 559 static inline 560 QDF_STATUS dp_rx_mon_add_msdu_to_list(struct dp_soc *soc, qdf_nbuf_t *head_msdu, 561 qdf_nbuf_t msdu, qdf_nbuf_t *last, 562 qdf_frag_t rx_desc_tlv, uint32_t frag_len, 563 uint32_t l2_hdr_offset) 564 { 565 uint32_t num_frags; 566 qdf_nbuf_t msdu_curr; 567 568 /* Here head_msdu and *head_msdu must not be NULL */ 569 /* Dont add frag to skb if frag length is zero. Drop frame */ 570 if (qdf_unlikely(!frag_len || !head_msdu || !(*head_msdu))) { 571 dp_err("[%s] frag_len[%d] || head_msdu[%pK] || *head_msdu is Null while adding frag to skb", 572 __func__, frag_len, head_msdu); 573 return QDF_STATUS_E_FAILURE; 574 } 575 576 /* In case of first desc of MPDU, assign curr msdu to *head_msdu */ 577 if (!qdf_nbuf_get_nr_frags(*head_msdu)) 578 msdu_curr = *head_msdu; 579 else 580 msdu_curr = *last; 581 582 /* Current msdu must not be NULL */ 583 if (qdf_unlikely(!msdu_curr)) { 584 dp_err("[%s] Current msdu can't be Null while adding frag to skb", 585 __func__); 586 return QDF_STATUS_E_FAILURE; 587 } 588 589 num_frags = qdf_nbuf_get_nr_frags(msdu_curr); 590 if (num_frags < QDF_NBUF_MAX_FRAGS) { 591 qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr, 592 soc->rx_mon_pkt_tlv_size, 593 frag_len + l2_hdr_offset, 594 RX_MONITOR_BUFFER_SIZE, 595 false); 596 if (*last != msdu_curr) 597 *last = msdu_curr; 598 return QDF_STATUS_SUCCESS; 599 } 600 601 /* Execution will reach here only if num_frags == QDF_NBUF_MAX_FRAGS */ 602 msdu_curr = NULL; 603 if ((dp_rx_mon_alloc_parent_buffer(&msdu_curr)) 604 != QDF_STATUS_SUCCESS) 605 return QDF_STATUS_E_FAILURE; 606 607 qdf_nbuf_add_rx_frag(rx_desc_tlv, msdu_curr, soc->rx_mon_pkt_tlv_size, 608 frag_len + l2_hdr_offset, RX_MONITOR_BUFFER_SIZE, 609 false); 610 611 /* Add allocated nbuf in the chain */ 612 qdf_nbuf_set_next(*last, msdu_curr); 613 614 /* Assign current msdu to last to avoid traversal */ 615 *last = msdu_curr; 616 617 return QDF_STATUS_SUCCESS; 618 } 619 620 /** 621 * dp_rx_mon_init_tail_msdu() - Initialize tail msdu 622 * 623 * @head_msdu: Parent buffer to hold MPDU data 624 * @msdu: Msdu to be updated in tail_msdu 625 * @last: last msdu 626 * @tail_msdu: Last msdu 627 */ 628 static inline 629 void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu, 630 qdf_nbuf_t last, qdf_nbuf_t *tail_msdu) 631 { 632 if (!head_msdu || !(*head_msdu)) { 633 *tail_msdu = NULL; 634 return; 635 } 636 637 if (last) 638 qdf_nbuf_set_next(last, NULL); 639 *tail_msdu = last; 640 } 641 642 /** 643 * dp_rx_mon_remove_raw_frame_fcs_len() - Remove FCS length for Raw Frame 644 * 645 * If feature is disabled, then removal happens in restitch logic. 646 * 647 * @soc: Datapath soc handle 648 * @head_msdu: Head msdu 649 * @tail_msdu: Tail msdu 650 */ 651 static inline 652 void dp_rx_mon_remove_raw_frame_fcs_len(struct dp_soc *soc, 653 qdf_nbuf_t *head_msdu, 654 qdf_nbuf_t *tail_msdu) 655 { 656 qdf_frag_t addr; 657 658 if (qdf_unlikely(!head_msdu || !tail_msdu || !(*head_msdu))) 659 return; 660 661 /* If *head_msdu is valid, then *tail_msdu must be valid */ 662 /* If head_msdu is valid, then it must have nr_frags */ 663 /* If tail_msdu is valid, then it must have nr_frags */ 664 665 /* Strip FCS_LEN for Raw frame */ 666 addr = qdf_nbuf_get_frag_addr(*head_msdu, 0); 667 addr -= soc->rx_mon_pkt_tlv_size; 668 if (hal_rx_tlv_decap_format_get(soc->hal_soc, addr) == 669 HAL_HW_RX_DECAP_FORMAT_RAW) { 670 qdf_nbuf_trim_add_frag_size(*tail_msdu, 671 qdf_nbuf_get_nr_frags(*tail_msdu) - 1, 672 -HAL_RX_FCS_LEN, 0); 673 } 674 } 675 676 /** 677 * dp_rx_mon_get_buffer_data()- Get data from desc buffer 678 * @rx_desc: desc 679 * 680 * Return address containing actual tlv content 681 */ 682 static inline 683 uint8_t *dp_rx_mon_get_buffer_data(struct dp_rx_desc *rx_desc) 684 { 685 return rx_desc->rx_buf_start; 686 } 687 688 #else 689 690 #define DP_RX_MON_GET_NBUF_FROM_DESC(rx_desc) \ 691 (rx_desc->nbuf) 692 693 static inline void 694 dp_rx_mon_add_msdu_to_list_failure_handler(void *rx_tlv_hdr, 695 struct dp_pdev *pdev, 696 qdf_nbuf_t *last, 697 qdf_nbuf_t *head_msdu, 698 qdf_nbuf_t *tail_msdu, 699 const char *func_name) 700 { 701 } 702 703 static inline 704 qdf_dma_addr_t dp_rx_mon_get_paddr_from_desc(struct dp_rx_desc *rx_desc) 705 { 706 qdf_dma_addr_t paddr = 0; 707 qdf_nbuf_t msdu = NULL; 708 709 msdu = rx_desc->nbuf; 710 if (msdu) 711 paddr = qdf_nbuf_get_frag_paddr(msdu, 0); 712 713 return paddr; 714 } 715 716 #define DP_RX_MON_IS_BUFFER_ADDR_NULL(rx_desc) \ 717 (!(rx_desc->nbuf)) 718 719 #define DP_RX_MON_IS_MSDU_NOT_NULL(msdu) \ 720 (msdu) 721 722 static inline void 723 dp_rx_mon_buffer_free(struct dp_rx_desc *rx_desc) 724 { 725 qdf_nbuf_free(rx_desc->nbuf); 726 } 727 728 static inline void 729 dp_rx_mon_buffer_unmap(struct dp_soc *soc, struct dp_rx_desc *rx_desc, 730 uint16_t size) 731 { 732 qdf_nbuf_unmap_nbytes_single(soc->osdev, rx_desc->nbuf, 733 QDF_DMA_FROM_DEVICE, size); 734 } 735 736 static inline 737 QDF_STATUS dp_rx_mon_alloc_parent_buffer(qdf_nbuf_t *head_msdu) 738 { 739 return QDF_STATUS_SUCCESS; 740 } 741 742 #ifdef QCA_WIFI_MONITOR_MODE_NO_MSDU_START_TLV_SUPPORT 743 744 #define RXDMA_DATA_DMA_BLOCK_SIZE 128 745 static inline void 746 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc, 747 struct hal_rx_msdu_desc_info *msdu_info, 748 bool *is_frag_p, uint32_t *total_frag_len_p, 749 uint32_t *frag_len_p, 750 uint16_t *l2_hdr_offset_p, 751 qdf_frag_t rx_desc_tlv, 752 void **first_rx_desc_tlv, 753 bool *is_frag_non_raw_p, void *data) 754 { 755 struct hal_rx_mon_dest_buf_info frame_info; 756 uint32_t rx_pkt_tlv_len = dp_rx_mon_get_rx_pkt_tlv_size(dp_soc); 757 758 /* 759 * HW structures call this L3 header padding 760 * -- even though this is actually the offset 761 * from the buffer beginning where the L2 762 * header begins. 763 */ 764 *l2_hdr_offset_p = 765 hal_rx_msdu_end_l3_hdr_padding_get(dp_soc->hal_soc, data); 766 767 if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) { 768 /* 769 * Set l3_hdr_pad for first frag. This can be later 770 * changed based on decap format, detected in last frag 771 */ 772 *l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 773 if (!(*is_frag_p)) { 774 *l2_hdr_offset_p = DP_RX_MON_RAW_L2_HDR_PAD_BYTE; 775 *first_rx_desc_tlv = rx_desc_tlv; 776 } 777 778 *is_frag_p = true; 779 *frag_len_p = (RX_MONITOR_BUFFER_SIZE - rx_pkt_tlv_len - 780 *l2_hdr_offset_p) & 781 ~(RXDMA_DATA_DMA_BLOCK_SIZE - 1); 782 *total_frag_len_p += *frag_len_p; 783 } else { 784 if (hal_rx_tlv_decap_format_get(dp_soc->hal_soc, rx_desc_tlv) == 785 HAL_HW_RX_DECAP_FORMAT_RAW) 786 frame_info.is_decap_raw = 1; 787 788 if (hal_rx_tlv_mpdu_len_err_get(dp_soc->hal_soc, rx_desc_tlv)) 789 frame_info.mpdu_len_err = 1; 790 791 frame_info.l2_hdr_pad = hal_rx_msdu_end_l3_hdr_padding_get( 792 dp_soc->hal_soc, rx_desc_tlv); 793 794 if (*is_frag_p) { 795 /* Last fragment of msdu */ 796 *frag_len_p = msdu_info->msdu_len - *total_frag_len_p; 797 798 /* Set this in the first frag priv data */ 799 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 800 *first_rx_desc_tlv, 801 (uint8_t *)&frame_info, 802 sizeof(frame_info)); 803 } else { 804 *frag_len_p = msdu_info->msdu_len; 805 hal_rx_priv_info_set_in_tlv(dp_soc->hal_soc, 806 rx_desc_tlv, 807 (uint8_t *)&frame_info, 808 sizeof(frame_info)); 809 } 810 *is_frag_p = false; 811 *first_rx_desc_tlv = NULL; 812 } 813 } 814 #else 815 816 static inline void 817 dp_rx_mon_parse_desc_buffer(struct dp_soc *dp_soc, 818 struct hal_rx_msdu_desc_info *msdu_info, 819 bool *is_frag_p, uint32_t *total_frag_len_p, 820 uint32_t *frag_len_p, 821 uint16_t *l2_hdr_offset_p, 822 qdf_frag_t rx_desc_tlv, 823 qdf_frag_t first_rx_desc_tlv, 824 bool *is_frag_non_raw_p, void *data) 825 { 826 /* 827 * HW structures call this L3 header padding 828 * -- even though this is actually the offset 829 * from the buffer beginning where the L2 830 * header begins. 831 */ 832 *l2_hdr_offset_p = 833 hal_rx_msdu_end_l3_hdr_padding_get(dp_soc->hal_soc, data); 834 835 if (msdu_info->msdu_flags & HAL_MSDU_F_MSDU_CONTINUATION) { 836 if (!*(is_frag_p)) { 837 *total_frag_len_p = msdu_info->msdu_len; 838 *is_frag_p = true; 839 } 840 dp_mon_adjust_frag_len(dp_soc, total_frag_len_p, frag_len_p, 841 *l2_hdr_offset_p); 842 } else { 843 if (*is_frag_p) { 844 dp_mon_adjust_frag_len(dp_soc, total_frag_len_p, 845 frag_len_p, 846 *l2_hdr_offset_p); 847 } else { 848 *frag_len_p = msdu_info->msdu_len; 849 } 850 *is_frag_p = false; 851 } 852 } 853 #endif 854 855 static inline void dp_rx_mon_buffer_set_pktlen(qdf_nbuf_t msdu, uint32_t size) 856 { 857 qdf_nbuf_set_pktlen(msdu, size); 858 } 859 860 static inline 861 QDF_STATUS dp_rx_mon_add_msdu_to_list(struct dp_soc *soc, qdf_nbuf_t *head_msdu, 862 qdf_nbuf_t msdu, qdf_nbuf_t *last, 863 qdf_frag_t rx_desc_tlv, uint32_t frag_len, 864 uint32_t l2_hdr_offset) 865 { 866 if (head_msdu && !*head_msdu) { 867 *head_msdu = msdu; 868 } else { 869 if (*last) 870 qdf_nbuf_set_next(*last, msdu); 871 } 872 *last = msdu; 873 return QDF_STATUS_SUCCESS; 874 } 875 876 static inline 877 void dp_rx_mon_init_tail_msdu(qdf_nbuf_t *head_msdu, qdf_nbuf_t msdu, 878 qdf_nbuf_t last, qdf_nbuf_t *tail_msdu) 879 { 880 if (last) 881 qdf_nbuf_set_next(last, NULL); 882 883 *tail_msdu = msdu; 884 } 885 886 static inline 887 void dp_rx_mon_remove_raw_frame_fcs_len(struct dp_soc *soc, 888 qdf_nbuf_t *head_msdu, 889 qdf_nbuf_t *tail_msdu) 890 { 891 } 892 893 static inline 894 uint8_t *dp_rx_mon_get_buffer_data(struct dp_rx_desc *rx_desc) 895 { 896 qdf_nbuf_t msdu = NULL; 897 uint8_t *data = NULL; 898 899 msdu = rx_desc->nbuf; 900 if (qdf_likely(msdu)) 901 data = qdf_nbuf_data(msdu); 902 return data; 903 } 904 905 #endif 906 907 #ifndef WLAN_SOFTUMAC_SUPPORT 908 /** 909 * dp_rx_cookie_2_mon_link_desc() - Retrieve Link descriptor based on target 910 * @pdev: core physical device context 911 * @buf_info: ptr to structure holding the buffer info 912 * @mac_id: mac number 913 * 914 * Return: link descriptor address 915 */ 916 static inline 917 void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev, 918 struct hal_buf_info *buf_info, 919 uint8_t mac_id) 920 { 921 if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) 922 return dp_rx_cookie_2_mon_link_desc_va(pdev, buf_info, 923 mac_id); 924 925 return dp_rx_cookie_2_link_desc_va(pdev->soc, buf_info); 926 } 927 928 /** 929 * dp_rx_monitor_link_desc_return() - Return Link descriptor based on target 930 * @pdev: core physical device context 931 * @p_last_buf_addr_info: MPDU Link descriptor 932 * @mac_id: mac number 933 * @bm_action: 934 * 935 * Return: QDF_STATUS 936 */ 937 static inline 938 QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev, 939 hal_buff_addrinfo_t 940 p_last_buf_addr_info, 941 uint8_t mac_id, uint8_t bm_action) 942 { 943 if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) 944 return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info, 945 mac_id); 946 947 return dp_rx_link_desc_return_by_addr(pdev->soc, p_last_buf_addr_info, 948 bm_action); 949 } 950 #else 951 static inline 952 void *dp_rx_cookie_2_mon_link_desc(struct dp_pdev *pdev, 953 struct hal_buf_info *buf_info, 954 uint8_t mac_id) 955 { 956 return dp_rx_cookie_2_mon_link_desc_va(pdev, buf_info, mac_id); 957 } 958 959 static inline 960 QDF_STATUS dp_rx_monitor_link_desc_return(struct dp_pdev *pdev, 961 hal_buff_addrinfo_t 962 p_last_buf_addr_info, 963 uint8_t mac_id, uint8_t bm_action) 964 { 965 return dp_rx_mon_link_desc_return(pdev, p_last_buf_addr_info, 966 mac_id); 967 } 968 #endif 969 970 static inline bool dp_is_rxdma_dst_ring_common(struct dp_pdev *pdev) 971 { 972 struct dp_soc *soc = pdev->soc; 973 974 return (soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev == 1); 975 } 976 977 /** 978 * dp_rxdma_get_mon_dst_ring() - Return the pointer to rxdma_err_dst_ring 979 * or mon_dst_ring based on the target 980 * @pdev: core physical device context 981 * @mac_for_pdev: mac_id number 982 * 983 * Return: ring address 984 */ 985 static inline 986 void *dp_rxdma_get_mon_dst_ring(struct dp_pdev *pdev, 987 uint8_t mac_for_pdev) 988 { 989 if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) 990 return pdev->soc->rxdma_mon_dst_ring[mac_for_pdev].hal_srng; 991 992 /* For targets with 1 RXDMA DST ring for both mac */ 993 if (dp_is_rxdma_dst_ring_common(pdev)) 994 return pdev->soc->rxdma_err_dst_ring[0].hal_srng; 995 996 return pdev->soc->rxdma_err_dst_ring[mac_for_pdev].hal_srng; 997 } 998 999 /** 1000 * dp_rxdma_get_mon_buf_ring() - Return monitor buf ring address 1001 * based on target 1002 * @pdev: core physical device context 1003 * @mac_for_pdev: mac id number 1004 * 1005 * Return: ring address 1006 */ 1007 static inline 1008 struct dp_srng *dp_rxdma_get_mon_buf_ring(struct dp_pdev *pdev, 1009 uint8_t mac_for_pdev) 1010 { 1011 if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) 1012 return &pdev->soc->rxdma_mon_buf_ring[mac_for_pdev]; 1013 1014 /* For MCL there is only 1 rx refill ring */ 1015 return &pdev->soc->rx_refill_buf_ring[0]; 1016 } 1017 1018 /** 1019 * dp_rx_get_mon_desc() - Return Rx descriptor based on target 1020 * @soc: soc handle 1021 * @cookie: cookie value 1022 * 1023 * Return: Rx descriptor 1024 */ 1025 static inline 1026 struct dp_rx_desc *dp_rx_get_mon_desc(struct dp_soc *soc, 1027 uint32_t cookie) 1028 { 1029 if (soc->wlan_cfg_ctx->rxdma1_enable) 1030 return dp_rx_cookie_2_va_mon_buf(soc, cookie); 1031 1032 return soc->arch_ops.dp_rx_desc_cookie_2_va(soc, cookie); 1033 } 1034 1035 #ifdef QCA_MONITOR_PKT_SUPPORT 1036 /* 1037 * dp_mon_htt_dest_srng_setup(): monitor dest srng setup 1038 * @soc: DP SOC handle 1039 * @pdev: DP PDEV handle 1040 * @mac_id: MAC ID 1041 * @mac_for_pdev: PDEV mac 1042 * 1043 * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure 1044 */ 1045 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc, 1046 struct dp_pdev *pdev, 1047 int mac_id, 1048 int mac_for_pdev); 1049 1050 /* 1051 * dp_mon_dest_rings_deinit(): deinit monitor dest rings 1052 * @pdev: DP PDEV handle 1053 * @lmac_id: MAC ID 1054 * 1055 * Return: status: None 1056 */ 1057 void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id); 1058 1059 /* 1060 * dp_mon_dest_rings_free(): free monitor dest rings 1061 * @pdev: DP PDEV handle 1062 * @lmac_id: MAC ID 1063 * 1064 * Return: status: None 1065 */ 1066 void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id); 1067 1068 /* 1069 * dp_mon_dest_rings_init(): init monitor dest rings 1070 * @pdev: DP PDEV handle 1071 * @lmac_id: MAC ID 1072 * 1073 * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure 1074 */ 1075 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id); 1076 1077 /* 1078 * dp_mon_dest_rings_allocate(): allocate monitor dest rings 1079 * @pdev: DP PDEV handle 1080 * @lmac_id: MAC ID 1081 * 1082 * Return: status: QDF_STATUS_SUCCESS - Success, non-zero: Failure 1083 */ 1084 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id); 1085 1086 #else 1087 QDF_STATUS dp_mon_htt_dest_srng_setup(struct dp_soc *soc, 1088 struct dp_pdev *pdev, 1089 int mac_id, 1090 int mac_for_pdev) 1091 { 1092 return QDF_STATUS_SUCCESS; 1093 } 1094 1095 static void dp_mon_dest_rings_deinit(struct dp_pdev *pdev, int lmac_id) 1096 { 1097 } 1098 1099 static void dp_mon_dest_rings_free(struct dp_pdev *pdev, int lmac_id) 1100 { 1101 } 1102 1103 static 1104 QDF_STATUS dp_mon_dest_rings_init(struct dp_pdev *pdev, int lmac_id) 1105 { 1106 return QDF_STATUS_SUCCESS; 1107 } 1108 1109 static 1110 QDF_STATUS dp_mon_dest_rings_alloc(struct dp_pdev *pdev, int lmac_id) 1111 { 1112 return QDF_STATUS_SUCCESS; 1113 } 1114 #endif /* QCA_MONITOR_PKT_SUPPORT */ 1115 1116 #endif /* _DP_RX_MON_1_0_H_ */ 1117