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