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 18 #ifndef _DP_TX_MON_2_0_H_ 19 #define _DP_TX_MON_2_0_H_ 20 21 #include <qdf_nbuf_frag.h> 22 #include <hal_be_api_mon.h> 23 24 struct dp_mon_desc; 25 /* 26 * dp_tx_mon_buffers_alloc() - allocate tx monitor buffers 27 * @soc: DP soc handle 28 * 29 * Return: QDF_STATUS_SUCCESS: Success 30 * QDF_STATUS_E_FAILURE: Error 31 */ 32 QDF_STATUS 33 dp_tx_mon_buffers_alloc(struct dp_soc *soc, uint32_t size); 34 35 /* 36 * dp_tx_mon_buffers_free() - free tx monitor buffers 37 * @soc: dp soc handle 38 * 39 */ 40 void 41 dp_tx_mon_buffers_free(struct dp_soc *soc); 42 43 /* 44 * dp_tx_mon_desc_pool_deinit() - deinit tx monitor descriptor pool 45 * @soc: dp soc handle 46 * 47 */ 48 void 49 dp_tx_mon_buf_desc_pool_deinit(struct dp_soc *soc); 50 51 /* 52 * dp_tx_mon_desc_pool_deinit() - deinit tx monitor descriptor pool 53 * @soc: dp soc handle 54 * 55 * Return: QDF_STATUS_SUCCESS: Success 56 * QDF_STATUS_E_FAILURE: Error 57 */ 58 QDF_STATUS 59 dp_tx_mon_buf_desc_pool_init(struct dp_soc *soc); 60 61 /* 62 * dp_tx_mon_buf_desc_pool_free() - free tx monitor descriptor pool 63 * @soc: dp soc handle 64 * 65 */ 66 void dp_tx_mon_buf_desc_pool_free(struct dp_soc *soc); 67 68 /* 69 * dp_tx_mon_buf_desc_pool_alloc() - allocate tx monitor descriptor pool 70 * @soc: DP soc handle 71 * 72 * Return: QDF_STATUS_SUCCESS: Success 73 * QDF_STATUS_E_FAILURE: Error 74 */ 75 QDF_STATUS 76 dp_tx_mon_buf_desc_pool_alloc(struct dp_soc *soc); 77 78 /** 79 * dp_tx_mon_update_end_reason() - API to update end reason 80 * 81 * @mon_pdev - DP_MON_PDEV handle 82 * @ppdu_id - ppdu_id 83 * @end_reason - monitor destiantion descriptor end reason 84 * 85 * Return: void 86 */ 87 void dp_tx_mon_update_end_reason(struct dp_mon_pdev *mon_pdev, 88 int ppdu_id, int end_reason); 89 90 /* 91 * dp_tx_mon_process_status_tlv() - API to processed TLV 92 * invoked from interrupt handler 93 * 94 * @soc - DP_SOC handle 95 * @pdev - DP_PDEV handle 96 * @mon_ring_desc - descriptor status info 97 * @addr - status buffer frag address 98 * @end_offset - end offset of buffer that has valid buffer 99 * 100 * Return: QDF_STATUS 101 */ 102 QDF_STATUS dp_tx_mon_process_status_tlv(struct dp_soc *soc, 103 struct dp_pdev *pdev, 104 struct hal_mon_desc *mon_ring_desc, 105 qdf_frag_t status_frag, 106 uint32_t end_offset); 107 108 /* 109 * dp_tx_mon_process_2_0() - tx monitor interrupt process 110 * @soc: dp soc handle 111 * @int_ctx: interrupt context 112 * @mac_id: mac id 113 * @quota: quota to process 114 * 115 */ 116 uint32_t 117 dp_tx_mon_process_2_0(struct dp_soc *soc, struct dp_intr *int_ctx, 118 uint32_t mac_id, uint32_t quota); 119 120 /* The maximum buffer length allocated for radiotap for monitor status buffer */ 121 #define MAX_MONITOR_HEADER (512) 122 #define MAX_DUMMY_FRM_BODY (128) 123 124 #define MAX_STATUS_BUFFER_IN_PPDU (64) 125 #define TXMON_NO_BUFFER_SZ (64) 126 127 #define DP_BA_ACK_FRAME_SIZE (sizeof(struct ieee80211_ctlframe_addr2) + 36) 128 #define DP_ACK_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one)) 129 #define DP_CTS_FRAME_SIZE (sizeof(struct ieee80211_frame_min_one)) 130 #define DP_ACKNOACK_FRAME_SIZE (sizeof(struct ieee80211_frame) + 16) 131 132 #define DP_IEEE80211_BAR_CTL_TID_S 12 133 #define DP_IEEE80211_BAR_CTL_TID_M 0xf 134 #define DP_IEEE80211_BAR_CTL_POLICY_S 0 135 #define DP_IEEE80211_BAR_CTL_POLICY_M 0x1 136 #define DP_IEEE80211_BA_S_SEQ_S 4 137 #define DP_IEEE80211_BAR_CTL_COMBA 0x0004 138 139 #define TXMON_PPDU(ppdu_info, field) ppdu_info->field 140 #define TXMON_PPDU_USR(ppdu_info, user_index, field) \ 141 ppdu_info->hal_txmon.rx_user_status[user_index].field 142 #define TXMON_PPDU_COM(ppdu_info, field) ppdu_info->hal_txmon.rx_status.field 143 #define TXMON_PPDU_HAL(ppdu_info, field) ppdu_info->hal_txmon.field 144 145 #define HE_DATA_CNT 6 146 147 #define FRAME_CONTROL_TYPE_MASK 0x0C 148 #define FRAME_CONTROL_TYPE_SHIFT 2 149 150 #define FRAME_CONTROL_SUBTYPE_MASK 0xF0 151 #define FRAME_CONTROL_SUBTYPE_SHIFT 4 152 153 #define FRAME_CTRL_TYPE_MGMT 0x0 154 #define FRAME_CTRL_TYPE_CTRL 0x1 155 #define FRAME_CTRL_TYPE_DATA 0x2 156 157 /** 158 * bf_type - tx monitor supported Beamformed type 159 */ 160 enum bf_type { 161 NO_BF = 0, 162 LEGACY_BF, 163 SU_BF, 164 MU_BF 165 }; 166 167 /** 168 * dot11b_preamble_type - tx monitor supported 11b preamble type 169 */ 170 enum dot11b_preamble_type { 171 SHORT_PREAMBLE = 0, 172 LONG_PREAMBLE, 173 }; 174 175 /** 176 * bw_type - tx monitor supported bandwidth type 177 */ 178 enum bw_type { 179 TXMON_BW_20_MHZ = 0, 180 TXMON_BW_40_MHZ, 181 TXMON_BW_80_MHZ, 182 TXMON_BW_160_MHZ, 183 TXMON_BW_240_MHZ, 184 TXMON_BW_320_MHZ 185 }; 186 187 /** 188 * ppdu_start_reason - tx monitor supported PPDU start reason type 189 */ 190 enum ppdu_start_reason { 191 TXMON_FES_PROTECTION_FRAME, 192 TXMON_FES_AFTER_PROTECTION, 193 TXMON_FES_ONLY, 194 TXMON_RESPONSE_FRAME, 195 TXMON_TRIG_RESPONSE_FRAME, 196 TXMON_DYNAMIC_PROTECTION_FES_ONLY 197 }; 198 199 /** 200 * guard_interval - tx monitor supported Guard interval type 201 */ 202 enum guard_interval { 203 TXMON_GI_0_8_US = 0, 204 TXMON_GI_0_4_US, 205 TXMON_GI_1_6_US, 206 TXMON_GI_3_2_US 207 }; 208 209 /** 210 * RU_size_start - tx monitor supported RU size start type 211 */ 212 enum RU_size_start { 213 TXMON_RU_26 = 0, 214 TXMON_RU_52, 215 TXMON_RU_106, 216 TXMON_RU_242, 217 TXMON_RU_484, 218 TXMON_RU_996, 219 TXMON_RU_1992, 220 TXMON_RU_FULLBW_240, 221 TXMON_RU_FULLBW_320, 222 TXMON_RU_MULTI_LARGE, 223 TXMON_RU_78, 224 TXMON_RU_132 225 }; 226 227 /** 228 * response_type_expected - expected response type 229 */ 230 enum response_type_expected { 231 TXMON_RESP_NO_RESP = 0, 232 TXMON_RESP_ACK, 233 TXMON_RESP_BA_64_BITMAP, 234 TXMON_RESP_BA_256, 235 TXMON_RESP_ACTIONNOACK, 236 TXMON_RESP_ACK_BA, 237 TXMON_RESP_CTS, 238 TXMON_RESP_ACK_DATA, 239 TXMON_RESP_NDP_ACK, 240 TXMON_RESP_NDP_MODIFIED_ACK, 241 TXMON_RESP_NDP_BA, 242 TXMON_RESP_NDP_CTS, 243 TXMON_RESP_NDP_ACK_OR_NDP_MODIFIED_ACK, 244 TXMON_RESP_UL_MU_BA, 245 TXMON_RESP_UL_MU_BA_AND_DATA, 246 TXMON_RESP_UL_MU_CBF, 247 TXMON_RESP_UL_MU_FRAMES, 248 TXMON_RESP_ANY_RESP_TO_DEVICE, 249 TXMON_RESP_ANY_RESP_ACCEPTED, 250 TXMON_RESP_FRAMELESS_PHYRX_RESP_ACCEPTED, 251 TXMON_RESP_RANGING_NDP_AND_LMR, 252 TXMON_RESP_BA_512, 253 TXMON_RESP_BA_1024, 254 TXMON_RESP_UL_MU_RANGING_CTS2S, 255 TXMON_RESP_UL_MU_RANGING_NDP, 256 TXMON_RESP_UL_MU_RANGING_LMR 257 }; 258 259 /** 260 * resposne_to_respone - tx monitor supported response to response type 261 */ 262 enum resposne_to_respone { 263 TXMON_RESP_TO_RESP_NONE = 0, 264 TXMON_RESP_TO_RESP_SU_BA, 265 TXMON_RESP_TO_RESP_MU_BA, 266 TXMON_RESP_TO_RESP_CMD 267 }; 268 269 /** 270 * medium_protection_type - tx monitor supported protection type 271 */ 272 enum medium_protection_type { 273 TXMON_MEDIUM_NO_PROTECTION, 274 TXMON_MEDIUM_RTS_LEGACY, 275 TXMON_MEDIUM_RTS_11AC_STATIC_BW, 276 TXMON_MEDIUM_RTS_11AC_DYNAMIC_BW, 277 TXMON_MEDIUM_CTS2SELF, 278 TXMON_MEDIUM_QOS_NULL_NO_ACK_3ADDR, 279 TXMON_MEDIUM_QOS_NULL_NO_ACK_4ADDR, 280 }; 281 282 /** 283 * ndp_frame - tx monitor supported ndp frame type 284 */ 285 enum ndp_frame { 286 TXMON_NO_NDP_TRANSMISSION, 287 TXMON_BEAMFORMING_NDP, 288 TXMON_HE_RANGING_NDP, 289 TXMON_HE_FEEDBACK_NDP, 290 }; 291 292 /** 293 * tx_ppdu_info_type - tx monitor supported ppdu type 294 */ 295 enum tx_ppdu_info_type { 296 TX_PROT_PPDU_INFO, 297 TX_DATA_PPDU_INFO, 298 }; 299 300 /** 301 * dp_tx_ppdu_info - structure to store tx ppdu info 302 * @ppdu_id: current ppdu info ppdu id 303 * @frametype: ppdu info frame type 304 * @cur_usr_idx: current user index of ppdu info 305 * @tx_ppdu_info_dlist_elem: support adding to double linked list 306 * @tx_ppdu_info_slist_elem: support adding to single linked list 307 * @hal_txmon: hal tx monitor info for that ppdu 308 */ 309 struct dp_tx_ppdu_info { 310 uint32_t ppdu_id; 311 uint8_t frame_type; 312 uint8_t cur_usr_idx; 313 314 union { 315 TAILQ_ENTRY(dp_tx_ppdu_info) tx_ppdu_info_dlist_elem; 316 STAILQ_ENTRY(dp_tx_ppdu_info) tx_ppdu_info_slist_elem; 317 } ulist; 318 319 #define tx_ppdu_info_list_elem ulist.tx_ppdu_info_dlist_elem 320 #define tx_ppdu_info_queue_elem ulist.tx_ppdu_info_slist_elem 321 322 struct hal_tx_ppdu_info hal_txmon; 323 }; 324 325 /** 326 * dp_tx_monitor_drop_stats - structure to store tx monitor drop statistic 327 * @ppdu_drop_cnt: ppdu drop counter 328 * @mpdu_drop_cnt: mpdu drop counter 329 * @tlv_drop_cnt: tlv drop counter 330 */ 331 struct dp_tx_monitor_drop_stats { 332 uint64_t ppdu_drop_cnt; 333 uint64_t mpdu_drop_cnt; 334 uint64_t tlv_drop_cnt; 335 }; 336 337 /** 338 * dp_tx_monitor_mode - tx monitor supported mode 339 * @TX_MON_BE_DISABLE: tx monitor disable 340 * @TX_MON_BE_FULL_CAPTURE: tx monitor mode to capture full packet 341 * @TX_MON_BE_PEER_FILTER: tx monitor mode to capture peer filter 342 */ 343 enum dp_tx_monitor_mode { 344 TX_MON_BE_DISABLE, 345 TX_MON_BE_FULL_CAPTURE, 346 TX_MON_BE_PEER_FILTER, 347 }; 348 349 /** 350 * dp_tx_monitor_framework_mode - tx monitor framework mode 351 * @TX_MON_BE_FRM_WRK_DISABLE: tx monitor frame work disable 352 * @TX_MON_BE_FRM_WRK_FULL_CAPTURE: tx monitor frame work full capture 353 * @TX_MON_BE_FRM_WRK_128B_CAPTURE: tx monitor frame work 128B capture 354 */ 355 enum dp_tx_monitor_framework_mode { 356 TX_MON_BE_FRM_WRK_DISABLE, 357 TX_MON_BE_FRM_WRK_FULL_CAPTURE, 358 TX_MON_BE_FRM_WRK_128B_CAPTURE, 359 }; 360 361 #define TX_TAILQ_INSERT_TAIL(pdev, tx_ppdu_info) \ 362 do { \ 363 STAILQ_INSERT_TAIL(&pdev->tx_ppdu_info_list, \ 364 tx_ppdu_info, tx_ppdu_info_list_elem);\ 365 pdev->tx_ppdu_info_queue_depth++; \ 366 } while (0) 367 368 #define TX_TAILQ_REMOVE(pdev, tx_ppdu_info) \ 369 do { \ 370 TAILQ_REMOVE(&pdev->tx_ppdu_info_list, tx_ppdu_info, \ 371 tx_ppdu_info_list_elem); \ 372 pdev->tx_ppdu_info_queue_depth--; \ 373 } while (0) 374 375 #define TX_TAILQ_FIRST(pdev) TAILQ_FIRST(&pdev->tx_ppdu_info_list) 376 377 #define TX_TAILQ_FOREACH_SAFE(pdev, tx_ppdu_info) \ 378 do { \ 379 struct dp_tx_ppdu_info *tx_ppdu_info_next = NULL; \ 380 TAILQ_FOREACH_SAFE(tx_ppdu_info, \ 381 &pdev->tx_ppdu_info_list, \ 382 tx_ppdu_info_list_elem, \ 383 tx_ppdu_info_next); \ 384 } while (0) 385 386 #ifndef WLAN_TX_PKT_CAPTURE_ENH_BE 387 /** 388 * dp_pdev_tx_capture_be - info to store tx capture information in pdev 389 * @mode: tx monitor core framework current mode 390 * 391 * This is a dummy structure 392 */ 393 struct dp_pdev_tx_capture_be { 394 uint32_t mode; 395 }; 396 397 /** 398 * dp_peer_tx_capture_be: Tx monitor peer structure 399 * 400 * This is a dummy structure 401 */ 402 struct dp_peer_tx_capture_be { 403 }; 404 #else 405 406 /** 407 * struct dp_txmon_frag_vec - a contiguous range of physical memory address 408 * @frag_buf: frag buffer address 409 * @end_offset: byte offset within the frag buffer where valid data resides 410 */ 411 struct dp_txmon_frag_vec { 412 qdf_frag_t frag_buf; 413 uint32_t end_offset; 414 }; 415 416 /** 417 * dp_pdev_tx_capture_be - info to store tx capture information in pdev 418 * @be_ppdu_id: current ppdu id 419 * @be_end_reason_bitmap: current end reason bitmap 420 * @mode: tx monitor current mode 421 * @tx_mon_list_lock: spinlock protection to list 422 * @post_ppdu_workqueue: tx monitor workqueue representation 423 * @post_ppdu_work: tx monitor post ppdu work 424 * @tx_ppdu_info_list_depth: list depth counter 425 * @tx_ppdu_info_list: ppdu info list to hold ppdu 426 * @defer_ppdu_info_list_depth: defer ppdu list depth counter 427 * @defer_ppdu_info_list: defer ppdu info list to hold defer ppdu 428 * @tx_stats: tx monitor drop stats for that mac 429 * @tx_prot_ppdu_info: tx monitor protection ppdu info 430 * @tx_data_ppdu_info: tx monitor data ppdu info 431 * @last_prot_ppdu_info: last tx monitor protection ppdu info 432 * @last_data_ppdu_info: last tx monitor data ppdu info 433 * @prot_status_info: protection status info 434 * @data_status_info: data status info 435 * @last_frag_q_idx: last index of frag buffer 436 * @cur_frag_q_idx: current index of frag buffer 437 * @status_frag_queue: array of status frag queue to hold 64 status buffer 438 */ 439 struct dp_pdev_tx_capture_be { 440 uint32_t be_ppdu_id; 441 uint32_t be_end_reason_bitmap; 442 uint32_t mode; 443 444 qdf_spinlock_t tx_mon_list_lock; 445 446 qdf_work_t post_ppdu_work; 447 qdf_workqueue_t *post_ppdu_workqueue; 448 449 uint32_t tx_ppdu_info_list_depth; 450 451 STAILQ_HEAD(, dp_tx_ppdu_info) tx_ppdu_info_queue; 452 453 uint32_t defer_ppdu_info_list_depth; 454 455 STAILQ_HEAD(, dp_tx_ppdu_info) defer_tx_ppdu_info_queue; 456 457 struct dp_tx_monitor_drop_stats tx_stats; 458 459 struct dp_tx_ppdu_info *tx_prot_ppdu_info; 460 struct dp_tx_ppdu_info *tx_data_ppdu_info; 461 462 struct dp_tx_ppdu_info *last_prot_ppdu_info; 463 struct dp_tx_ppdu_info *last_data_ppdu_info; 464 465 struct hal_tx_status_info prot_status_info; 466 struct hal_tx_status_info data_status_info; 467 468 uint8_t last_frag_q_idx; 469 uint8_t cur_frag_q_idx; 470 struct dp_txmon_frag_vec frag_q_vec[MAX_STATUS_BUFFER_IN_PPDU]; 471 }; 472 473 /** 474 * dp_peer_tx_capture_be: Tx monitor peer structure 475 * 476 * need to be added here 477 */ 478 struct dp_peer_tx_capture_be { 479 }; 480 #endif /* WLAN_TX_PKT_CAPTURE_ENH_BE */ 481 482 /* 483 * dp_tx_mon_ppdu_info_free() - API to free dp_tx_ppdu_info 484 * @tx_ppdu_info - pointer to tx_ppdu_info 485 * 486 * Return: void 487 */ 488 void dp_tx_mon_ppdu_info_free(struct dp_tx_ppdu_info *tx_ppdu_info); 489 490 /* 491 * dp_tx_mon_free_usr_mpduq() - API to free user mpduq 492 * @tx_ppdu_info - pointer to tx_ppdu_info 493 * @usr_idx - user index 494 * 495 * Return: void 496 */ 497 void dp_tx_mon_free_usr_mpduq(struct dp_tx_ppdu_info *tx_ppdu_info, 498 uint8_t usr_idx); 499 500 /* 501 * dp_tx_mon_free_ppdu_info() - API to free dp_tx_ppdu_info 502 * @tx_ppdu_info - pointer to tx_ppdu_info 503 * 504 * Return: void 505 */ 506 void dp_tx_mon_free_ppdu_info(struct dp_tx_ppdu_info *tx_ppdu_info); 507 508 /* 509 * dp_tx_mon_get_ppdu_info() - API to allocate dp_tx_ppdu_info 510 * @pdev - pdev handle 511 * @type - type of ppdu_info data or protection 512 * @num_user - number user in a ppdu_info 513 * @ppdu_id - ppdu_id number 514 * 515 * Return: pointer to dp_tx_ppdu_info 516 */ 517 struct dp_tx_ppdu_info *dp_tx_mon_get_ppdu_info(struct dp_pdev *pdev, 518 enum tx_ppdu_info_type type, 519 uint8_t num_user, 520 uint32_t ppdu_id); 521 522 #ifdef WLAN_TX_PKT_CAPTURE_ENH_BE 523 /** 524 * dp_tx_ppdu_stats_attach_2_0 - Initialize Tx PPDU stats and enhanced capture 525 * @pdev: DP PDEV 526 * 527 * Return: none 528 */ 529 void dp_tx_ppdu_stats_attach_2_0(struct dp_pdev *pdev); 530 531 /** 532 * dp_tx_ppdu_stats_detach_2_0 - Cleanup Tx PPDU stats and enhanced capture 533 * @pdev: DP PDEV 534 * 535 * Return: none 536 */ 537 void dp_tx_ppdu_stats_detach_2_0(struct dp_pdev *pdev); 538 539 /* 540 * dp_print_pdev_tx_capture_stats_2_0: print tx capture stats 541 * @pdev: DP PDEV handle 542 * 543 * return: void 544 */ 545 void dp_print_pdev_tx_capture_stats_2_0(struct dp_pdev *pdev); 546 547 /* 548 * dp_config_enh_tx_capture_be()- API to enable/disable enhanced tx capture 549 * @pdev_handle: DP_PDEV handle 550 * @val: user provided value 551 * 552 * Return: QDF_STATUS 553 */ 554 QDF_STATUS dp_config_enh_tx_capture_2_0(struct dp_pdev *pdev, uint8_t val); 555 556 /* 557 * dp_peer_set_tx_capture_enabled_2_0() - add tx monitor peer filter 558 * @pdev: Datapath PDEV handle 559 * @peer: Datapath PEER handle 560 * @is_tx_pkt_cap_enable: flag for tx capture enable/disable 561 * @peer_mac: peer mac address 562 * 563 * Return: status 564 */ 565 QDF_STATUS dp_peer_set_tx_capture_enabled_2_0(struct dp_pdev *pdev_handle, 566 struct dp_peer *peer_handle, 567 uint8_t is_tx_pkt_cap_enable, 568 uint8_t *peer_mac); 569 #endif /* WLAN_TX_PKT_CAPTURE_ENH_BE */ 570 571 #if (defined(WIFI_MONITOR_SUPPORT) && !defined(WLAN_TX_PKT_CAPTURE_ENH_BE)) 572 /* 573 * dp_config_enh_tx_core_capture_2_0()- API to validate core framework 574 * @pdev_handle: DP_PDEV handle 575 * @val: user provided value 576 * 577 * Return: QDF_STATUS 578 */ 579 QDF_STATUS dp_config_enh_tx_core_capture_2_0(struct dp_pdev *pdev, uint8_t val); 580 #endif 581 582 #endif /* _DP_TX_MON_2_0_H_ */ 583