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