1 /* 2 * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 #include <dp_types.h> 20 #include <dp_htt.h> 21 #include <dp_internal.h> 22 #include <dp_rx_mon.h> 23 #include <dp_mon_filter.h> 24 #include <dp_mon.h> 25 26 /* 27 * dp_mon_filter_mode_type_to_str 28 * Monitor Filter mode to string 29 */ 30 int8_t *dp_mon_filter_mode_type_to_str[DP_MON_FILTER_MAX_MODE] = { 31 #ifdef QCA_ENHANCED_STATS_SUPPORT 32 "DP MON FILTER ENHACHED STATS MODE", 33 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 34 #ifdef QCA_MCOPY_SUPPORT 35 "DP MON FILTER MCOPY MODE", 36 #endif /* QCA_MCOPY_SUPPORT */ 37 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) 38 "DP MON FILTER SMART MONITOR MODE", 39 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ 40 "DP_MON FILTER MONITOR MODE", 41 #ifdef WLAN_RX_PKT_CAPTURE_ENH 42 "DP MON FILTER RX CAPTURE MODE", 43 #endif /* WLAN_RX_PKT_CAPTURE_ENH */ 44 #ifdef WDI_EVENT_ENABLE 45 "DP MON FILTER PKT LOG FULL MODE", 46 "DP MON FILTER PKT LOG LITE MODE", 47 "DP MON FILTER PKT LOG CBF MODE", 48 #ifdef BE_PKTLOG_SUPPORT 49 "DP MON FILTER PKT LOG HYBRID MODE", 50 #endif 51 #endif /* WDI_EVENT_ENABLE */ 52 #ifdef QCA_UNDECODED_METADATA_SUPPORT 53 "DP MON FILTER RX UNDECODED METADATA CAPTURE MODE", 54 #endif 55 }; 56 57 #if defined(WLAN_PKT_CAPTURE_RX_2_0) || defined(CONFIG_WORD_BASED_TLV) || \ 58 defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE) 59 static inline 60 void dp_mon_filter_show_filter_1(struct htt_rx_ring_tlv_filter *tlv_filter) 61 { 62 DP_MON_FILTER_PRINT("rx_hdr_length: %d", tlv_filter->rx_hdr_length); 63 DP_MON_FILTER_PRINT("mgmt_dma_length: %d", tlv_filter->mgmt_dma_length); 64 DP_MON_FILTER_PRINT("ctrl_dma_length: %d", tlv_filter->ctrl_dma_length); 65 DP_MON_FILTER_PRINT("data_dma_length: %d", tlv_filter->data_dma_length); 66 } 67 #else 68 static inline 69 void dp_mon_filter_show_filter_1(struct htt_rx_ring_tlv_filter *tlv_filter) 70 { 71 } 72 #endif 73 74 void dp_mon_filter_show_filter(struct dp_mon_pdev *mon_pdev, 75 enum dp_mon_filter_mode mode, 76 struct dp_mon_filter *filter) 77 { 78 struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; 79 80 DP_MON_FILTER_PRINT("[%s]: Valid: %d", 81 dp_mon_filter_mode_type_to_str[mode], 82 filter->valid); 83 dp_mon_filter_show_filter_1(tlv_filter); 84 DP_MON_FILTER_PRINT("mpdu_start: %d", tlv_filter->mpdu_start); 85 DP_MON_FILTER_PRINT("msdu_start: %d", tlv_filter->msdu_start); 86 DP_MON_FILTER_PRINT("packet: %d", tlv_filter->packet); 87 DP_MON_FILTER_PRINT("msdu_end: %d", tlv_filter->msdu_end); 88 DP_MON_FILTER_PRINT("mpdu_end: %d", tlv_filter->mpdu_end); 89 DP_MON_FILTER_PRINT("packet_header: %d", 90 tlv_filter->packet_header); 91 DP_MON_FILTER_PRINT("attention: %d", tlv_filter->attention); 92 DP_MON_FILTER_PRINT("ppdu_start: %d", tlv_filter->ppdu_start); 93 DP_MON_FILTER_PRINT("ppdu_end: %d", tlv_filter->ppdu_end); 94 DP_MON_FILTER_PRINT("ppdu_end_user_stats: %d", 95 tlv_filter->ppdu_end_user_stats); 96 DP_MON_FILTER_PRINT("ppdu_end_user_stats_ext: %d", 97 tlv_filter->ppdu_end_user_stats_ext); 98 DP_MON_FILTER_PRINT("ppdu_end_status_done: %d", 99 tlv_filter->ppdu_end_status_done); 100 DP_MON_FILTER_PRINT("ppdu_start_user_info: %d", 101 tlv_filter->ppdu_start_user_info); 102 DP_MON_FILTER_PRINT("header_per_msdu: %d", tlv_filter->header_per_msdu); 103 DP_MON_FILTER_PRINT("enable_fp: %d", tlv_filter->enable_fp); 104 DP_MON_FILTER_PRINT("enable_md: %d", tlv_filter->enable_md); 105 DP_MON_FILTER_PRINT("enable_mo: %d", tlv_filter->enable_mo); 106 DP_MON_FILTER_PRINT("fp_mgmt_filter: 0x%x", tlv_filter->fp_mgmt_filter); 107 DP_MON_FILTER_PRINT("mo_mgmt_filter: 0x%x", tlv_filter->mo_mgmt_filter); 108 DP_MON_FILTER_PRINT("fp_ctrl_filter: 0x%x", tlv_filter->fp_ctrl_filter); 109 DP_MON_FILTER_PRINT("mo_ctrl_filter: 0x%x", tlv_filter->mo_ctrl_filter); 110 DP_MON_FILTER_PRINT("fp_data_filter: 0x%x", tlv_filter->fp_data_filter); 111 DP_MON_FILTER_PRINT("mo_data_filter: 0x%x", tlv_filter->mo_data_filter); 112 DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter); 113 DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter); 114 DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter); 115 #ifdef QCA_UNDECODED_METADATA_SUPPORT 116 DP_MON_FILTER_PRINT("fp_phy_err: %d", tlv_filter->fp_phy_err); 117 DP_MON_FILTER_PRINT("fp_phy_err_buf_src: %d", 118 tlv_filter->fp_phy_err_buf_src); 119 DP_MON_FILTER_PRINT("fp_phy_err_buf_dest: %d", 120 tlv_filter->fp_phy_err_buf_dest); 121 DP_MON_FILTER_PRINT("phy_err_mask: 0x%x", tlv_filter->phy_err_mask); 122 DP_MON_FILTER_PRINT("phy_err_mask_cont: 0x%x", 123 tlv_filter->phy_err_mask_cont); 124 #endif 125 DP_MON_FILTER_PRINT("mon_mac_filter: %d", 126 tlv_filter->enable_mon_mac_filter); 127 } 128 129 #ifdef QCA_UNDECODED_METADATA_SUPPORT 130 static inline void 131 dp_mon_set_fp_phy_err_filter(struct htt_rx_ring_tlv_filter *tlv_filter, 132 struct dp_mon_filter *mon_filter) 133 { 134 if (mon_filter->tlv_filter.phy_err_filter_valid) { 135 tlv_filter->fp_phy_err = 136 mon_filter->tlv_filter.fp_phy_err; 137 tlv_filter->fp_phy_err_buf_src = 138 mon_filter->tlv_filter.fp_phy_err_buf_src; 139 tlv_filter->fp_phy_err_buf_dest = 140 mon_filter->tlv_filter.fp_phy_err_buf_dest; 141 tlv_filter->phy_err_mask = 142 mon_filter->tlv_filter.phy_err_mask; 143 tlv_filter->phy_err_mask_cont = 144 mon_filter->tlv_filter.phy_err_mask_cont; 145 tlv_filter->phy_err_filter_valid = 146 mon_filter->tlv_filter.phy_err_filter_valid; 147 } 148 } 149 #else 150 static inline void 151 dp_mon_set_fp_phy_err_filter(struct htt_rx_ring_tlv_filter *tlv_filter, 152 struct dp_mon_filter *mon_filter) 153 { 154 } 155 #endif 156 157 void dp_mon_filter_h2t_setup(struct dp_soc *soc, struct dp_pdev *pdev, 158 enum dp_mon_filter_srng_type srng_type, 159 struct dp_mon_filter *filter) 160 { 161 int32_t current_mode = 0; 162 struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; 163 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 164 165 /* 166 * Loop through all the modes. 167 */ 168 for (current_mode = 0; current_mode < DP_MON_FILTER_MAX_MODE; 169 current_mode++) { 170 struct dp_mon_filter *mon_filter = 171 &mon_pdev->filter[current_mode][srng_type]; 172 uint32_t src_filter = 0, dst_filter = 0; 173 174 /* 175 * Check if the correct mode is enabled or not. 176 */ 177 if (!mon_filter->valid) 178 continue; 179 180 filter->valid = true; 181 182 /* 183 * Set the super bit fields 184 */ 185 src_filter = 186 DP_MON_FILTER_GET(&mon_filter->tlv_filter, FILTER_TLV); 187 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_TLV); 188 dst_filter |= src_filter; 189 DP_MON_FILTER_SET(tlv_filter, FILTER_TLV, dst_filter); 190 191 /* 192 * Set the filter management filter. 193 */ 194 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 195 FILTER_FP_MGMT); 196 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_MGMT); 197 dst_filter |= src_filter; 198 DP_MON_FILTER_SET(tlv_filter, FILTER_FP_MGMT, dst_filter); 199 200 /* 201 * Set the monitor other management filter. 202 */ 203 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 204 FILTER_MO_MGMT); 205 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_MGMT); 206 dst_filter |= src_filter; 207 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_MGMT, dst_filter); 208 209 /* 210 * Set the filter pass control filter. 211 */ 212 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 213 FILTER_FP_CTRL); 214 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_CTRL); 215 dst_filter |= src_filter; 216 DP_MON_FILTER_SET(tlv_filter, FILTER_FP_CTRL, dst_filter); 217 218 /* 219 * Set the monitor other control filter. 220 */ 221 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 222 FILTER_MO_CTRL); 223 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_CTRL); 224 dst_filter |= src_filter; 225 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_CTRL, dst_filter); 226 227 /* 228 * Set the filter pass data filter. 229 */ 230 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 231 FILTER_FP_DATA); 232 dst_filter = DP_MON_FILTER_GET(tlv_filter, 233 FILTER_FP_DATA); 234 dst_filter |= src_filter; 235 DP_MON_FILTER_SET(tlv_filter, 236 FILTER_FP_DATA, dst_filter); 237 238 /* 239 * Set the monitor other data filter. 240 */ 241 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 242 FILTER_MO_DATA); 243 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_DATA); 244 dst_filter |= src_filter; 245 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_DATA, dst_filter); 246 247 /* 248 * Set the monitor direct data filter. 249 */ 250 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 251 FILTER_MD_DATA); 252 dst_filter = DP_MON_FILTER_GET(tlv_filter, 253 FILTER_MD_DATA); 254 dst_filter |= src_filter; 255 DP_MON_FILTER_SET(tlv_filter, 256 FILTER_MD_DATA, dst_filter); 257 258 /* 259 * Set the monitor direct management filter. 260 */ 261 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 262 FILTER_MD_MGMT); 263 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_MGMT); 264 dst_filter |= src_filter; 265 DP_MON_FILTER_SET(tlv_filter, FILTER_MD_MGMT, dst_filter); 266 267 /* 268 * Set the monitor direct management filter. 269 */ 270 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 271 FILTER_MD_CTRL); 272 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL); 273 dst_filter |= src_filter; 274 DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter); 275 276 dp_mon_set_fp_phy_err_filter(tlv_filter, mon_filter); 277 tlv_filter->enable_mon_mac_filter = 278 mon_filter->tlv_filter.enable_mon_mac_filter; 279 DP_RX_MON_FILTER_SET_RX_HDR_LEN(tlv_filter, 280 mon_filter->tlv_filter); 281 } 282 283 dp_mon_filter_show_filter(mon_pdev, 0, filter); 284 } 285 286 /** 287 * dp_mon_skip_filter_config() - Check if filter config need to be skipped 288 * @soc: DP soc context 289 * 290 * Return: true if yes, false if not 291 */ 292 static inline 293 bool dp_mon_skip_filter_config(struct dp_soc *soc) 294 { 295 if (soc->cdp_soc.ol_ops->get_con_mode && 296 soc->cdp_soc.ol_ops->get_con_mode() == 297 QDF_GLOBAL_MISSION_MODE && 298 !(QDF_MONITOR_FLAG_OTHER_BSS & soc->mon_flags)) 299 return true; 300 else 301 return false; 302 } 303 304 /** 305 * dp_update_num_mac_rings() - Update number of MAC rings based on connection 306 * mode and DBS check 307 * @soc: DP soc context 308 * @mon_mac_rings: Pointer to variable for number of mac rings 309 * 310 * Return: None 311 */ 312 static void 313 dp_update_num_mac_rings(struct dp_soc *soc, int *mon_mac_rings) 314 { 315 if (soc->cdp_soc.ol_ops->get_con_mode && 316 soc->cdp_soc.ol_ops->get_con_mode() == 317 QDF_GLOBAL_MISSION_MODE && 318 (QDF_MONITOR_FLAG_OTHER_BSS & soc->mon_flags)) { 319 *mon_mac_rings = 1; 320 } else { 321 dp_update_num_mac_rings_for_dbs(soc, mon_mac_rings); 322 } 323 } 324 325 QDF_STATUS 326 dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc, 327 struct dp_pdev *pdev, 328 enum dp_mon_filter_srng_type srng_type, 329 struct htt_rx_ring_tlv_filter *tlv_filter) 330 { 331 int mac_id; 332 int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); 333 QDF_STATUS status = QDF_STATUS_SUCCESS; 334 uint32_t target_type = hal_get_target_type(soc->hal_soc); 335 336 if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF && 337 dp_mon_skip_filter_config(soc)) { 338 dp_mon_filter_info("skip rxdma_buf filter cfg for lpc mode"); 339 return QDF_STATUS_SUCCESS; 340 } 341 342 /* 343 * Overwrite the max_mac_rings for the status rings. 344 */ 345 if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS) 346 dp_update_num_mac_rings(soc, &max_mac_rings); 347 348 dp_mon_filter_info("%pK: srng type %d Max_mac_rings %d ", 349 soc, srng_type, max_mac_rings); 350 351 /* 352 * Loop through all MACs per radio and set the filter to the individual 353 * macs. For MCL 354 */ 355 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 356 int mac_for_pdev = 357 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 358 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); 359 int hal_ring_type, ring_buf_size; 360 hal_ring_handle_t hal_ring_hdl; 361 362 switch (srng_type) { 363 case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: 364 if (target_type == TARGET_TYPE_QCN9160) { 365 hal_ring_hdl = 366 soc->rx_refill_buf_ring[lmac_id].hal_srng; 367 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 368 } else { 369 hal_ring_hdl = 370 pdev->rx_mac_buf_ring[lmac_id].hal_srng; 371 ring_buf_size = RX_DATA_BUFFER_SIZE; 372 } 373 hal_ring_type = RXDMA_BUF; 374 break; 375 376 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: 377 /* 378 * If two back to back HTT msg sending happened in 379 * short time, the second HTT msg source SRNG HP 380 * writing has chance to fail, this has been confirmed 381 * by HST HW. 382 * for monitor mode, here is the last HTT msg for sending. 383 * if the 2nd HTT msg for monitor status ring sending failed, 384 * HW won't provide anything into 2nd monitor status ring. 385 * as a WAR, add some delay before 2nd HTT msg start sending, 386 * > 2us is required per HST HW, delay 100 us for safe. 387 */ 388 if (mac_id) 389 qdf_udelay(100); 390 391 hal_ring_hdl = 392 soc->rxdma_mon_status_ring[lmac_id].hal_srng; 393 hal_ring_type = RXDMA_MONITOR_STATUS; 394 ring_buf_size = RX_MON_STATUS_BUF_SIZE; 395 break; 396 397 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: 398 hal_ring_hdl = 399 soc->rxdma_mon_buf_ring[lmac_id].hal_srng; 400 hal_ring_type = RXDMA_MONITOR_BUF; 401 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 402 break; 403 404 case DP_MON_FILTER_SRNG_TYPE_RXMON_DEST: 405 hal_ring_hdl = 406 soc->rxdma_mon_dst_ring[lmac_id].hal_srng; 407 hal_ring_type = RXDMA_MONITOR_DST; 408 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 409 break; 410 default: 411 return QDF_STATUS_E_FAILURE; 412 } 413 414 if (!hal_ring_hdl) 415 continue; 416 417 status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 418 hal_ring_hdl, hal_ring_type, 419 ring_buf_size, 420 tlv_filter); 421 if (status != QDF_STATUS_SUCCESS) 422 return status; 423 } 424 425 return status; 426 } 427 428 #ifdef QCA_ENHANCED_STATS_SUPPORT 429 void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev) 430 { 431 struct dp_mon_ops *mon_ops = NULL; 432 433 mon_ops = dp_mon_ops_get(pdev->soc); 434 if (mon_ops && mon_ops->mon_filter_setup_enhanced_stats) 435 mon_ops->mon_filter_setup_enhanced_stats(pdev); 436 } 437 438 void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev) 439 { 440 struct dp_mon_ops *mon_ops = NULL; 441 442 mon_ops = dp_mon_ops_get(pdev->soc); 443 if (mon_ops && mon_ops->mon_filter_reset_enhanced_stats) 444 mon_ops->mon_filter_reset_enhanced_stats(pdev); 445 } 446 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 447 448 #ifdef QCA_UNDECODED_METADATA_SUPPORT 449 void dp_mon_filter_setup_undecoded_metadata_mode(struct dp_pdev *pdev) 450 { 451 struct dp_mon_ops *mon_ops = NULL; 452 453 mon_ops = dp_mon_ops_get(pdev->soc); 454 if (mon_ops && mon_ops->mon_filter_setup_undecoded_metadata_capture) 455 mon_ops->mon_filter_setup_undecoded_metadata_capture(pdev); 456 } 457 458 void dp_mon_filter_reset_undecoded_metadata_mode(struct dp_pdev *pdev) 459 { 460 struct dp_mon_ops *mon_ops = NULL; 461 462 mon_ops = dp_mon_ops_get(pdev->soc); 463 if (mon_ops && mon_ops->mon_filter_reset_undecoded_metadata_capture) 464 mon_ops->mon_filter_reset_undecoded_metadata_capture(pdev); 465 } 466 #endif /* QCA_UNDECODED_METADATA_SUPPORT */ 467 468 #ifdef QCA_MCOPY_SUPPORT 469 void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev) 470 { 471 struct dp_mon_ops *mon_ops = NULL; 472 473 mon_ops = dp_mon_ops_get(pdev->soc); 474 if (mon_ops && mon_ops->mon_filter_setup_mcopy_mode) 475 mon_ops->mon_filter_setup_mcopy_mode(pdev); 476 } 477 478 void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev) 479 { 480 struct dp_mon_ops *mon_ops = NULL; 481 482 mon_ops = dp_mon_ops_get(pdev->soc); 483 if (mon_ops && mon_ops->mon_filter_reset_mcopy_mode) 484 mon_ops->mon_filter_reset_mcopy_mode(pdev); 485 } 486 #endif /* QCA_MCOPY_SUPPORT */ 487 488 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) 489 void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev) 490 { 491 struct dp_mon_ops *mon_ops = NULL; 492 493 mon_ops = dp_mon_ops_get(pdev->soc); 494 if (mon_ops && mon_ops->mon_filter_setup_smart_monitor) 495 mon_ops->mon_filter_setup_smart_monitor(pdev); 496 } 497 498 void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev) 499 { 500 struct dp_mon_ops *mon_ops = NULL; 501 502 mon_ops = dp_mon_ops_get(pdev->soc); 503 if (mon_ops && mon_ops->mon_filter_reset_smart_monitor) 504 mon_ops->mon_filter_reset_smart_monitor(pdev); 505 } 506 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ 507 508 void dp_mon_filter_set_reset_mon_mac_filter(struct dp_pdev *pdev, bool val) 509 { 510 struct dp_mon_ops *mon_ops = NULL; 511 512 mon_ops = dp_mon_ops_get(pdev->soc); 513 if (mon_ops && mon_ops->mon_filter_set_reset_mon_mac_filter) 514 mon_ops->mon_filter_set_reset_mon_mac_filter(pdev, val); 515 } 516 517 #ifdef WLAN_RX_PKT_CAPTURE_ENH 518 void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev) 519 { 520 struct dp_mon_ops *mon_ops = NULL; 521 522 mon_ops = dp_mon_ops_get(pdev->soc); 523 if (mon_ops && mon_ops->mon_filter_setup_rx_enh_capture) 524 mon_ops->mon_filter_setup_rx_enh_capture(pdev); 525 } 526 527 void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev) 528 { 529 struct dp_mon_ops *mon_ops = NULL; 530 531 mon_ops = dp_mon_ops_get(pdev->soc); 532 if (mon_ops && mon_ops->mon_filter_reset_rx_enh_capture) 533 mon_ops->mon_filter_reset_rx_enh_capture(pdev); 534 } 535 #endif /* WLAN_RX_PKT_CAPTURE_ENH */ 536 537 void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev) 538 { 539 struct dp_mon_ops *mon_ops = NULL; 540 541 mon_ops = dp_mon_ops_get(pdev->soc); 542 if (mon_ops && mon_ops->mon_filter_setup_rx_mon_mode) 543 mon_ops->mon_filter_setup_rx_mon_mode(pdev); 544 } 545 546 void dp_mon_filter_setup_tx_mon_mode(struct dp_pdev *pdev) 547 { 548 struct dp_mon_ops *mon_ops = NULL; 549 550 mon_ops = dp_mon_ops_get(pdev->soc); 551 if (mon_ops && mon_ops->mon_filter_setup_tx_mon_mode) 552 mon_ops->mon_filter_setup_tx_mon_mode(pdev); 553 } 554 555 void dp_mon_filter_reset_tx_mon_mode(struct dp_pdev *pdev) 556 { 557 struct dp_mon_ops *mon_ops = NULL; 558 559 mon_ops = dp_mon_ops_get(pdev->soc); 560 if (mon_ops && mon_ops->mon_filter_reset_tx_mon_mode) 561 mon_ops->mon_filter_reset_tx_mon_mode(pdev); 562 } 563 564 void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev) 565 { 566 struct dp_mon_ops *mon_ops = NULL; 567 568 mon_ops = dp_mon_ops_get(pdev->soc); 569 if (mon_ops && mon_ops->mon_filter_reset_rx_mon_mode) 570 mon_ops->mon_filter_reset_rx_mon_mode(pdev); 571 } 572 573 #if defined(WLAN_PKT_CAPTURE_RX_2_0) || defined(CONFIG_WORD_BASED_TLV) || \ 574 defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE) 575 void dp_rx_mon_hdr_length_set(uint32_t *msg_word, 576 struct htt_rx_ring_tlv_filter *tlv_filter) 577 { 578 if (!msg_word || !tlv_filter) 579 return; 580 581 HTT_RX_RING_SELECTION_CFG_RX_HDR_LEN_SET(*msg_word, 582 tlv_filter->rx_hdr_length); 583 } 584 #else 585 void dp_rx_mon_hdr_length_set(uint32_t *msg_word, 586 struct htt_rx_ring_tlv_filter *tlv_filter) 587 { 588 } 589 #endif 590 591 #ifdef WDI_EVENT_ENABLE 592 void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev) 593 { 594 struct dp_mon_ops *mon_ops = NULL; 595 596 mon_ops = dp_mon_ops_get(pdev->soc); 597 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_full) 598 mon_ops->mon_filter_setup_rx_pkt_log_full(pdev); 599 } 600 601 void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev) 602 { 603 struct dp_mon_ops *mon_ops = NULL; 604 605 mon_ops = dp_mon_ops_get(pdev->soc); 606 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_full) 607 mon_ops->mon_filter_reset_rx_pkt_log_full(pdev); 608 } 609 610 void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev) 611 { 612 struct dp_mon_ops *mon_ops = NULL; 613 614 mon_ops = dp_mon_ops_get(pdev->soc); 615 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_lite) 616 mon_ops->mon_filter_setup_rx_pkt_log_lite(pdev); 617 } 618 619 void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev) 620 { 621 struct dp_mon_ops *mon_ops = NULL; 622 623 mon_ops = dp_mon_ops_get(pdev->soc); 624 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_lite) 625 mon_ops->mon_filter_reset_rx_pkt_log_lite(pdev); 626 } 627 628 void dp_mon_filter_setup_rx_pkt_log_cbf(struct dp_pdev *pdev) 629 { 630 struct dp_mon_ops *mon_ops = NULL; 631 632 mon_ops = dp_mon_ops_get(pdev->soc); 633 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_cbf) 634 mon_ops->mon_filter_setup_rx_pkt_log_cbf(pdev); 635 } 636 637 void dp_mon_filter_reset_rx_pktlog_cbf(struct dp_pdev *pdev) 638 { 639 struct dp_mon_ops *mon_ops = NULL; 640 641 mon_ops = dp_mon_ops_get(pdev->soc); 642 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_cbf) 643 mon_ops->mon_filter_reset_rx_pkt_log_cbf(pdev); 644 } 645 646 #ifdef BE_PKTLOG_SUPPORT 647 void dp_mon_filter_setup_pktlog_hybrid(struct dp_pdev *pdev) 648 { 649 struct dp_mon_ops *mon_ops = NULL; 650 651 mon_ops = dp_mon_ops_get(pdev->soc); 652 if (mon_ops && mon_ops->mon_filter_setup_pktlog_hybrid) 653 mon_ops->mon_filter_setup_pktlog_hybrid(pdev); 654 } 655 656 void dp_mon_filter_reset_pktlog_hybrid(struct dp_pdev *pdev) 657 { 658 struct dp_mon_ops *mon_ops = NULL; 659 660 mon_ops = dp_mon_ops_get(pdev->soc); 661 if (mon_ops && mon_ops->mon_filter_reset_pktlog_hybrid) 662 mon_ops->mon_filter_reset_pktlog_hybrid(pdev); 663 } 664 #endif 665 #endif /* WDI_EVENT_ENABLE */ 666 667 QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev) 668 { 669 struct dp_mon_ops *mon_ops = NULL; 670 671 mon_ops = dp_mon_ops_get(pdev->soc); 672 if (!mon_ops) { 673 dp_mon_filter_err("Rx mon filter update failed ops uninitialized"); 674 return QDF_STATUS_E_FAILURE; 675 } 676 677 if (mon_ops && mon_ops->rx_mon_filter_update) 678 mon_ops->rx_mon_filter_update(pdev); 679 680 return QDF_STATUS_SUCCESS; 681 } 682 683 QDF_STATUS dp_tx_mon_filter_update(struct dp_pdev *pdev) 684 { 685 struct dp_mon_ops *mon_ops = NULL; 686 687 mon_ops = dp_mon_ops_get(pdev->soc); 688 if (!mon_ops) { 689 dp_mon_filter_err("Tx mon filter update failed ops uninitialized"); 690 return QDF_STATUS_E_FAILURE; 691 } 692 693 if (mon_ops && mon_ops->tx_mon_filter_update) 694 mon_ops->tx_mon_filter_update(pdev); 695 696 return QDF_STATUS_SUCCESS; 697 } 698 699 #ifdef QCA_ENHANCED_STATS_SUPPORT 700 void dp_mon_filters_reset(struct dp_pdev *pdev) 701 { 702 dp_mon_filter_reset_enhanced_stats(pdev); 703 dp_mon_filter_reset_mon_mode(pdev); 704 dp_mon_filter_update(pdev); 705 } 706 #else 707 void dp_mon_filters_reset(struct dp_pdev *pdev) 708 { 709 } 710 #endif 711 712 void 713 dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev, 714 enum dp_mon_filter_srng_type mon_srng_type) 715 { 716 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 717 718 if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type, 719 &tlv_filter) != QDF_STATUS_SUCCESS) { 720 dp_mon_filter_err("%pK: Monitor destination ring filter setting failed", 721 soc); 722 } 723 } 724 725 /** 726 * dp_mon_filter_adjust() - adjust the mon filters per target basis 727 * @pdev: DP pdev handle 728 * @filter: DP mon filter 729 * 730 * Return: None 731 */ 732 static inline 733 void dp_mon_filter_adjust(struct dp_pdev *pdev, struct dp_mon_filter *filter) 734 { 735 struct dp_soc *soc = pdev->soc; 736 737 switch (hal_get_target_type(soc->hal_soc)) { 738 case TARGET_TYPE_KIWI: 739 case TARGET_TYPE_MANGO: 740 case TARGET_TYPE_PEACH: 741 filter->tlv_filter.msdu_start = 0; 742 filter->tlv_filter.mpdu_end = 0; 743 filter->tlv_filter.packet_header = 0; 744 filter->tlv_filter.attention = 0; 745 break; 746 default: 747 break; 748 } 749 } 750 751 void dp_mon_filter_set_mon_cmn(struct dp_pdev *pdev, 752 struct dp_mon_filter *filter) 753 { 754 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 755 756 filter->tlv_filter.mpdu_start = 1; 757 filter->tlv_filter.msdu_start = 1; 758 filter->tlv_filter.packet = 1; 759 filter->tlv_filter.msdu_end = 1; 760 filter->tlv_filter.mpdu_end = 1; 761 filter->tlv_filter.packet_header = 1; 762 filter->tlv_filter.attention = 1; 763 filter->tlv_filter.ppdu_start = 0; 764 filter->tlv_filter.ppdu_end = 0; 765 filter->tlv_filter.ppdu_end_user_stats = 0; 766 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 767 filter->tlv_filter.ppdu_end_status_done = 0; 768 filter->tlv_filter.header_per_msdu = 1; 769 filter->tlv_filter.enable_fp = 770 (mon_pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; 771 filter->tlv_filter.enable_mo = 772 (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; 773 774 filter->tlv_filter.fp_mgmt_filter = mon_pdev->fp_mgmt_filter; 775 filter->tlv_filter.fp_ctrl_filter = mon_pdev->fp_ctrl_filter; 776 filter->tlv_filter.fp_data_filter = mon_pdev->fp_data_filter; 777 filter->tlv_filter.mo_mgmt_filter = mon_pdev->mo_mgmt_filter; 778 filter->tlv_filter.mo_ctrl_filter = mon_pdev->mo_ctrl_filter; 779 filter->tlv_filter.mo_data_filter = mon_pdev->mo_data_filter; 780 filter->tlv_filter.offset_valid = false; 781 dp_mon_filter_adjust(pdev, filter); 782 } 783 784 void dp_mon_filter_set_status_cmn(struct dp_mon_pdev *mon_pdev, 785 struct dp_mon_filter *filter) 786 { 787 filter->tlv_filter.mpdu_start = 1; 788 filter->tlv_filter.msdu_start = 0; 789 filter->tlv_filter.packet = 0; 790 filter->tlv_filter.msdu_end = 0; 791 filter->tlv_filter.mpdu_end = 0; 792 filter->tlv_filter.attention = 0; 793 filter->tlv_filter.ppdu_start = 1; 794 filter->tlv_filter.ppdu_end = 1; 795 filter->tlv_filter.ppdu_end_user_stats = 1; 796 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 797 filter->tlv_filter.ppdu_end_status_done = 1; 798 filter->tlv_filter.ppdu_start_user_info = 1; 799 filter->tlv_filter.enable_fp = 1; 800 filter->tlv_filter.enable_md = 0; 801 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; 802 filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; 803 filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL; 804 filter->tlv_filter.offset_valid = false; 805 806 if (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) { 807 filter->tlv_filter.enable_mo = 1; 808 filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; 809 filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; 810 filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL; 811 } else { 812 filter->tlv_filter.enable_mo = 0; 813 } 814 } 815 816 void dp_mon_filter_set_status_cbf(struct dp_pdev *pdev, 817 struct dp_mon_filter *filter) 818 { 819 filter->tlv_filter.mpdu_start = 1; 820 filter->tlv_filter.msdu_start = 0; 821 filter->tlv_filter.packet = 0; 822 filter->tlv_filter.msdu_end = 0; 823 filter->tlv_filter.mpdu_end = 0; 824 filter->tlv_filter.attention = 0; 825 filter->tlv_filter.ppdu_start = 1; 826 filter->tlv_filter.ppdu_end = 1; 827 filter->tlv_filter.ppdu_end_user_stats = 1; 828 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 829 filter->tlv_filter.ppdu_end_status_done = 1; 830 filter->tlv_filter.ppdu_start_user_info = 1; 831 filter->tlv_filter.enable_fp = 1; 832 filter->tlv_filter.enable_md = 0; 833 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 834 filter->tlv_filter.fp_ctrl_filter = 0; 835 filter->tlv_filter.fp_data_filter = 0; 836 filter->tlv_filter.offset_valid = false; 837 filter->tlv_filter.enable_mo = 0; 838 } 839 840 void dp_mon_filter_set_cbf_cmn(struct dp_pdev *pdev, 841 struct dp_mon_filter *filter) 842 { 843 filter->tlv_filter.mpdu_start = 1; 844 filter->tlv_filter.msdu_start = 1; 845 filter->tlv_filter.packet = 1; 846 filter->tlv_filter.msdu_end = 1; 847 filter->tlv_filter.mpdu_end = 1; 848 filter->tlv_filter.attention = 1; 849 filter->tlv_filter.ppdu_start = 0; 850 filter->tlv_filter.ppdu_end = 0; 851 filter->tlv_filter.ppdu_end_user_stats = 0; 852 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 853 filter->tlv_filter.ppdu_end_status_done = 0; 854 filter->tlv_filter.ppdu_start_user_info = 0; 855 filter->tlv_filter.enable_fp = 1; 856 filter->tlv_filter.enable_md = 0; 857 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 858 filter->tlv_filter.offset_valid = false; 859 filter->tlv_filter.enable_mo = 0; 860 } 861 862 void dp_mon_filter_dealloc(struct dp_mon_pdev *mon_pdev) 863 { 864 enum dp_mon_filter_mode mode; 865 struct dp_mon_filter **mon_filter = NULL; 866 867 if (!mon_pdev) { 868 dp_mon_filter_err("Monitor pdev Context is null"); 869 return; 870 } 871 872 mon_filter = mon_pdev->filter; 873 874 /* 875 * Check if the monitor filters are already allocated to the mon_pdev. 876 */ 877 if (!mon_filter) { 878 dp_mon_filter_err("Found NULL memory for the Monitor filter"); 879 return; 880 } 881 882 /* 883 * Iterate through the every mode and free the filter object. 884 */ 885 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 886 if (!mon_filter[mode]) { 887 continue; 888 } 889 890 qdf_mem_free(mon_filter[mode]); 891 mon_filter[mode] = NULL; 892 } 893 894 qdf_mem_free(mon_filter); 895 mon_pdev->filter = NULL; 896 } 897 898 struct dp_mon_filter **dp_mon_filter_alloc(struct dp_mon_pdev *mon_pdev) 899 { 900 struct dp_mon_filter **mon_filter = NULL; 901 enum dp_mon_filter_mode mode; 902 903 if (!mon_pdev) { 904 dp_mon_filter_err("pdev Context is null"); 905 return NULL; 906 } 907 908 mon_filter = (struct dp_mon_filter **)qdf_mem_malloc( 909 (sizeof(struct dp_mon_filter *) * 910 DP_MON_FILTER_MAX_MODE)); 911 if (!mon_filter) { 912 dp_mon_filter_err("Monitor filter mem allocation failed"); 913 return NULL; 914 } 915 916 qdf_mem_zero(mon_filter, 917 sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE); 918 919 /* 920 * Allocate the memory for filters for different srngs for each modes. 921 */ 922 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 923 mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) * 924 DP_MON_FILTER_SRNG_TYPE_MAX); 925 /* Assign the mon_filter to the pdev->filter such 926 * that the dp_mon_filter_dealloc() can free up the filters. */ 927 if (!mon_filter[mode]) { 928 mon_pdev->filter = mon_filter; 929 goto fail; 930 } 931 } 932 933 return mon_filter; 934 fail: 935 dp_mon_filter_dealloc(mon_pdev); 936 return NULL; 937 } 938 939 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 940 QDF_STATUS dp_mon_set_local_pkt_capture_running(struct dp_mon_pdev *mon_pdev, 941 bool val) 942 { 943 if (!mon_pdev) { 944 dp_mon_filter_err("Invalid monitor pdev"); 945 return QDF_STATUS_E_FAILURE; 946 } 947 948 mon_pdev->is_local_pkt_capture_running = val; 949 dp_mon_filter_debug("local_pkt_capture_running is set to %d", val); 950 return QDF_STATUS_SUCCESS; 951 } 952 953 bool dp_mon_get_is_local_pkt_capture_running(struct cdp_soc_t *cdp_soc, 954 uint8_t pdev_id) 955 { 956 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 957 struct dp_pdev *pdev = 958 dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 959 struct dp_mon_pdev *mon_pdev; 960 961 if (!pdev || !pdev->monitor_pdev) { 962 dp_mon_filter_err("Invalid pdev_id %u", pdev_id); 963 return false; 964 } 965 966 mon_pdev = pdev->monitor_pdev; 967 968 return mon_pdev->is_local_pkt_capture_running; 969 } 970 971 static void 972 dp_mon_set_local_pkt_capture_rx_filter(struct dp_pdev *pdev, 973 struct cdp_monitor_filter *src_filter) 974 { 975 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 976 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 977 enum dp_mon_filter_srng_type srng_type; 978 struct dp_mon_filter dst_filter = {0}; 979 980 dst_filter.valid = true; 981 dp_mon_filter_set_status_cmn(mon_pdev, &dst_filter); 982 983 dst_filter.tlv_filter.packet_header = 1; 984 dst_filter.tlv_filter.header_per_msdu = 1; 985 dst_filter.tlv_filter.rx_hdr_length = RX_HDR_DMA_LENGTH_256B; 986 dst_filter.tlv_filter.fp_mgmt_filter = src_filter->fp_mgmt; 987 dst_filter.tlv_filter.fp_ctrl_filter = src_filter->fp_ctrl; 988 dst_filter.tlv_filter.fp_data_filter = src_filter->fp_data; 989 dst_filter.tlv_filter.enable_fp = src_filter->mode; 990 dst_filter.tlv_filter.enable_md = 0; 991 dst_filter.tlv_filter.enable_mo = 0; 992 993 dp_mon_filter_show_filter(mon_pdev, mode, &dst_filter); 994 995 /* Store the above filter */ 996 srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 997 mon_pdev->filter[mode][srng_type] = dst_filter; 998 } 999 1000 static void dp_mon_clear_local_pkt_capture_rx_filter(struct dp_pdev *pdev) 1001 { 1002 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1003 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 1004 enum dp_mon_filter_srng_type srng_type = 1005 DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 1006 struct dp_mon_filter filter = {0}; 1007 1008 mon_pdev->filter[mode][srng_type] = filter; 1009 } 1010 1011 static void dp_mon_reset_local_pkt_capture_rx_filter(struct dp_pdev *pdev) 1012 { 1013 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 1014 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 1015 enum dp_mon_filter_srng_type srng_type = 1016 DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 1017 struct dp_mon_filter filter = {0}; 1018 1019 filter.valid = true; 1020 mon_pdev->filter[mode][srng_type] = filter; 1021 dp_mon_pdev_filter_init(mon_pdev); 1022 } 1023 1024 static inline void 1025 dp_mon_init_local_pkt_capture_queue(struct dp_mon_pdev *mon_pdev) 1026 { 1027 qdf_spin_lock_bh(&mon_pdev->lpc_lock); 1028 qdf_nbuf_queue_init(&mon_pdev->msdu_queue); 1029 qdf_nbuf_queue_init(&mon_pdev->mpdu_queue); 1030 mon_pdev->first_mpdu = true; 1031 qdf_spin_unlock_bh(&mon_pdev->lpc_lock); 1032 } 1033 1034 static inline void 1035 dp_mon_free_local_pkt_capture_queue(struct dp_mon_pdev *mon_pdev) 1036 { 1037 qdf_spin_lock_bh(&mon_pdev->lpc_lock); 1038 qdf_nbuf_queue_free(&mon_pdev->msdu_queue); 1039 qdf_nbuf_queue_free(&mon_pdev->mpdu_queue); 1040 qdf_spin_unlock_bh(&mon_pdev->lpc_lock); 1041 } 1042 1043 QDF_STATUS dp_mon_start_local_pkt_capture(struct cdp_soc_t *cdp_soc, 1044 uint8_t pdev_id, 1045 struct cdp_monitor_filter *filter) 1046 { 1047 bool local_pkt_capture_running; 1048 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 1049 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1050 struct dp_mon_pdev *mon_pdev; 1051 QDF_STATUS status = QDF_STATUS_SUCCESS; 1052 1053 if (!pdev) { 1054 dp_mon_filter_err("pdev Context is null"); 1055 return QDF_STATUS_E_INVAL; 1056 } 1057 1058 mon_pdev = pdev->monitor_pdev; 1059 local_pkt_capture_running = 1060 dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id); 1061 if (local_pkt_capture_running) { 1062 dp_mon_filter_err("Can't start local pkt capture. Already running"); 1063 return QDF_STATUS_E_ALREADY; 1064 } 1065 1066 mon_pdev->mon_filter_mode = filter->mode; 1067 mon_pdev->fp_mgmt_filter = filter->fp_mgmt; 1068 mon_pdev->fp_ctrl_filter = filter->fp_ctrl; 1069 mon_pdev->fp_data_filter = filter->fp_data; 1070 1071 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1072 dp_mon_set_local_pkt_capture_rx_filter(pdev, filter); 1073 status = dp_mon_filter_update(pdev); 1074 if (QDF_IS_STATUS_ERROR(status)) { 1075 dp_mon_clear_local_pkt_capture_rx_filter(pdev); 1076 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1077 dp_mon_filter_err("local pkt capture set rx filter failed"); 1078 return status; 1079 } 1080 1081 dp_mon_filter_setup_tx_mon_mode(pdev); 1082 status = dp_tx_mon_filter_update(pdev); 1083 if (QDF_IS_STATUS_ERROR(status)) { 1084 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1085 dp_mon_filter_err("local pkt capture set tx filter failed"); 1086 return status; 1087 } 1088 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1089 1090 dp_mon_filter_debug("local pkt capture tx filter set"); 1091 1092 dp_mon_init_local_pkt_capture_queue(mon_pdev); 1093 dp_mon_set_local_pkt_capture_running(mon_pdev, true); 1094 return status; 1095 } 1096 1097 QDF_STATUS dp_mon_stop_local_pkt_capture(struct cdp_soc_t *cdp_soc, 1098 uint8_t pdev_id) 1099 { 1100 bool local_pkt_capture_running; 1101 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 1102 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1103 struct dp_mon_pdev *mon_pdev; 1104 QDF_STATUS status = QDF_STATUS_SUCCESS; 1105 1106 if (!pdev) { 1107 dp_mon_filter_err("pdev Context is null"); 1108 return QDF_STATUS_E_INVAL; 1109 } 1110 1111 mon_pdev = pdev->monitor_pdev; 1112 local_pkt_capture_running = 1113 dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id); 1114 if (!local_pkt_capture_running) { 1115 dp_mon_filter_err("Local pkt capture is not running"); 1116 return QDF_STATUS_SUCCESS; 1117 } 1118 1119 dp_mon_set_local_pkt_capture_running(mon_pdev, false); 1120 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1121 dp_mon_reset_local_pkt_capture_rx_filter(pdev); 1122 status = dp_mon_filter_update(pdev); 1123 if (QDF_IS_STATUS_ERROR(status)) { 1124 dp_mon_filter_err("local pkt capture set rx filter failed"); 1125 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1126 return status; 1127 } 1128 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1129 1130 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1131 dp_mon_filter_reset_tx_mon_mode(pdev); 1132 dp_tx_mon_filter_update(pdev); 1133 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1134 dp_mon_filter_debug("local pkt capture stopped"); 1135 1136 dp_mon_free_local_pkt_capture_queue(mon_pdev); 1137 1138 return QDF_STATUS_SUCCESS; 1139 } 1140 1141 #endif /* WLAN_FEATURE_LOCAL_PKT_CAPTURE */ 1142