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 QDF_STATUS 305 dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc, 306 struct dp_pdev *pdev, 307 enum dp_mon_filter_srng_type srng_type, 308 struct htt_rx_ring_tlv_filter *tlv_filter) 309 { 310 int mac_id; 311 int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); 312 QDF_STATUS status = QDF_STATUS_SUCCESS; 313 uint32_t target_type = hal_get_target_type(soc->hal_soc); 314 315 if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF && 316 dp_mon_skip_filter_config(soc)) { 317 dp_mon_filter_info("skip rxdma_buf filter cfg for lpc mode"); 318 return QDF_STATUS_SUCCESS; 319 } 320 321 /* 322 * Overwrite the max_mac_rings for the status rings. 323 */ 324 if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS) 325 dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings); 326 327 dp_mon_filter_info("%pK: srng type %d Max_mac_rings %d ", 328 soc, srng_type, max_mac_rings); 329 330 /* 331 * Loop through all MACs per radio and set the filter to the individual 332 * macs. For MCL 333 */ 334 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 335 int mac_for_pdev = 336 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 337 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); 338 int hal_ring_type, ring_buf_size; 339 hal_ring_handle_t hal_ring_hdl; 340 341 switch (srng_type) { 342 case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: 343 if (target_type == TARGET_TYPE_QCN9160) { 344 hal_ring_hdl = 345 soc->rx_refill_buf_ring[lmac_id].hal_srng; 346 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 347 } else { 348 hal_ring_hdl = 349 pdev->rx_mac_buf_ring[lmac_id].hal_srng; 350 ring_buf_size = RX_DATA_BUFFER_SIZE; 351 } 352 hal_ring_type = RXDMA_BUF; 353 break; 354 355 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: 356 /* 357 * If two back to back HTT msg sending happened in 358 * short time, the second HTT msg source SRNG HP 359 * writing has chance to fail, this has been confirmed 360 * by HST HW. 361 * for monitor mode, here is the last HTT msg for sending. 362 * if the 2nd HTT msg for monitor status ring sending failed, 363 * HW won't provide anything into 2nd monitor status ring. 364 * as a WAR, add some delay before 2nd HTT msg start sending, 365 * > 2us is required per HST HW, delay 100 us for safe. 366 */ 367 if (mac_id) 368 qdf_udelay(100); 369 370 hal_ring_hdl = 371 soc->rxdma_mon_status_ring[lmac_id].hal_srng; 372 hal_ring_type = RXDMA_MONITOR_STATUS; 373 ring_buf_size = RX_MON_STATUS_BUF_SIZE; 374 break; 375 376 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: 377 hal_ring_hdl = 378 soc->rxdma_mon_buf_ring[lmac_id].hal_srng; 379 hal_ring_type = RXDMA_MONITOR_BUF; 380 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 381 break; 382 383 case DP_MON_FILTER_SRNG_TYPE_RXMON_DEST: 384 hal_ring_hdl = 385 soc->rxdma_mon_dst_ring[lmac_id].hal_srng; 386 hal_ring_type = RXDMA_MONITOR_DST; 387 ring_buf_size = RX_MONITOR_BUFFER_SIZE; 388 break; 389 default: 390 return QDF_STATUS_E_FAILURE; 391 } 392 393 if (!hal_ring_hdl) 394 continue; 395 396 status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 397 hal_ring_hdl, hal_ring_type, 398 ring_buf_size, 399 tlv_filter); 400 if (status != QDF_STATUS_SUCCESS) 401 return status; 402 } 403 404 return status; 405 } 406 407 #ifdef QCA_ENHANCED_STATS_SUPPORT 408 void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev) 409 { 410 struct dp_mon_ops *mon_ops = NULL; 411 412 mon_ops = dp_mon_ops_get(pdev->soc); 413 if (mon_ops && mon_ops->mon_filter_setup_enhanced_stats) 414 mon_ops->mon_filter_setup_enhanced_stats(pdev); 415 } 416 417 void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev) 418 { 419 struct dp_mon_ops *mon_ops = NULL; 420 421 mon_ops = dp_mon_ops_get(pdev->soc); 422 if (mon_ops && mon_ops->mon_filter_reset_enhanced_stats) 423 mon_ops->mon_filter_reset_enhanced_stats(pdev); 424 } 425 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 426 427 #ifdef QCA_UNDECODED_METADATA_SUPPORT 428 void dp_mon_filter_setup_undecoded_metadata_mode(struct dp_pdev *pdev) 429 { 430 struct dp_mon_ops *mon_ops = NULL; 431 432 mon_ops = dp_mon_ops_get(pdev->soc); 433 if (mon_ops && mon_ops->mon_filter_setup_undecoded_metadata_capture) 434 mon_ops->mon_filter_setup_undecoded_metadata_capture(pdev); 435 } 436 437 void dp_mon_filter_reset_undecoded_metadata_mode(struct dp_pdev *pdev) 438 { 439 struct dp_mon_ops *mon_ops = NULL; 440 441 mon_ops = dp_mon_ops_get(pdev->soc); 442 if (mon_ops && mon_ops->mon_filter_reset_undecoded_metadata_capture) 443 mon_ops->mon_filter_reset_undecoded_metadata_capture(pdev); 444 } 445 #endif /* QCA_UNDECODED_METADATA_SUPPORT */ 446 447 #ifdef QCA_MCOPY_SUPPORT 448 void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev) 449 { 450 struct dp_mon_ops *mon_ops = NULL; 451 452 mon_ops = dp_mon_ops_get(pdev->soc); 453 if (mon_ops && mon_ops->mon_filter_setup_mcopy_mode) 454 mon_ops->mon_filter_setup_mcopy_mode(pdev); 455 } 456 457 void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev) 458 { 459 struct dp_mon_ops *mon_ops = NULL; 460 461 mon_ops = dp_mon_ops_get(pdev->soc); 462 if (mon_ops && mon_ops->mon_filter_reset_mcopy_mode) 463 mon_ops->mon_filter_reset_mcopy_mode(pdev); 464 } 465 #endif /* QCA_MCOPY_SUPPORT */ 466 467 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) 468 void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev) 469 { 470 struct dp_mon_ops *mon_ops = NULL; 471 472 mon_ops = dp_mon_ops_get(pdev->soc); 473 if (mon_ops && mon_ops->mon_filter_setup_smart_monitor) 474 mon_ops->mon_filter_setup_smart_monitor(pdev); 475 } 476 477 void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev) 478 { 479 struct dp_mon_ops *mon_ops = NULL; 480 481 mon_ops = dp_mon_ops_get(pdev->soc); 482 if (mon_ops && mon_ops->mon_filter_reset_smart_monitor) 483 mon_ops->mon_filter_reset_smart_monitor(pdev); 484 } 485 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ 486 487 void dp_mon_filter_set_reset_mon_mac_filter(struct dp_pdev *pdev, bool val) 488 { 489 struct dp_mon_ops *mon_ops = NULL; 490 491 mon_ops = dp_mon_ops_get(pdev->soc); 492 if (mon_ops && mon_ops->mon_filter_set_reset_mon_mac_filter) 493 mon_ops->mon_filter_set_reset_mon_mac_filter(pdev, val); 494 } 495 496 #ifdef WLAN_RX_PKT_CAPTURE_ENH 497 void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev) 498 { 499 struct dp_mon_ops *mon_ops = NULL; 500 501 mon_ops = dp_mon_ops_get(pdev->soc); 502 if (mon_ops && mon_ops->mon_filter_setup_rx_enh_capture) 503 mon_ops->mon_filter_setup_rx_enh_capture(pdev); 504 } 505 506 void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev) 507 { 508 struct dp_mon_ops *mon_ops = NULL; 509 510 mon_ops = dp_mon_ops_get(pdev->soc); 511 if (mon_ops && mon_ops->mon_filter_reset_rx_enh_capture) 512 mon_ops->mon_filter_reset_rx_enh_capture(pdev); 513 } 514 #endif /* WLAN_RX_PKT_CAPTURE_ENH */ 515 516 void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev) 517 { 518 struct dp_mon_ops *mon_ops = NULL; 519 520 mon_ops = dp_mon_ops_get(pdev->soc); 521 if (mon_ops && mon_ops->mon_filter_setup_rx_mon_mode) 522 mon_ops->mon_filter_setup_rx_mon_mode(pdev); 523 } 524 525 void dp_mon_filter_setup_tx_mon_mode(struct dp_pdev *pdev) 526 { 527 struct dp_mon_ops *mon_ops = NULL; 528 529 mon_ops = dp_mon_ops_get(pdev->soc); 530 if (mon_ops && mon_ops->mon_filter_setup_tx_mon_mode) 531 mon_ops->mon_filter_setup_tx_mon_mode(pdev); 532 } 533 534 void dp_mon_filter_reset_tx_mon_mode(struct dp_pdev *pdev) 535 { 536 struct dp_mon_ops *mon_ops = NULL; 537 538 mon_ops = dp_mon_ops_get(pdev->soc); 539 if (mon_ops && mon_ops->mon_filter_reset_tx_mon_mode) 540 mon_ops->mon_filter_reset_tx_mon_mode(pdev); 541 } 542 543 void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev) 544 { 545 struct dp_mon_ops *mon_ops = NULL; 546 547 mon_ops = dp_mon_ops_get(pdev->soc); 548 if (mon_ops && mon_ops->mon_filter_reset_rx_mon_mode) 549 mon_ops->mon_filter_reset_rx_mon_mode(pdev); 550 } 551 552 #if defined(WLAN_PKT_CAPTURE_RX_2_0) || defined(CONFIG_WORD_BASED_TLV) || \ 553 defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE) 554 void dp_rx_mon_hdr_length_set(uint32_t *msg_word, 555 struct htt_rx_ring_tlv_filter *tlv_filter) 556 { 557 if (!msg_word || !tlv_filter) 558 return; 559 560 HTT_RX_RING_SELECTION_CFG_RX_HDR_LEN_SET(*msg_word, 561 tlv_filter->rx_hdr_length); 562 } 563 #else 564 void dp_rx_mon_hdr_length_set(uint32_t *msg_word, 565 struct htt_rx_ring_tlv_filter *tlv_filter) 566 { 567 } 568 #endif 569 570 #ifdef WDI_EVENT_ENABLE 571 void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev) 572 { 573 struct dp_mon_ops *mon_ops = NULL; 574 575 mon_ops = dp_mon_ops_get(pdev->soc); 576 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_full) 577 mon_ops->mon_filter_setup_rx_pkt_log_full(pdev); 578 } 579 580 void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev) 581 { 582 struct dp_mon_ops *mon_ops = NULL; 583 584 mon_ops = dp_mon_ops_get(pdev->soc); 585 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_full) 586 mon_ops->mon_filter_reset_rx_pkt_log_full(pdev); 587 } 588 589 void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev) 590 { 591 struct dp_mon_ops *mon_ops = NULL; 592 593 mon_ops = dp_mon_ops_get(pdev->soc); 594 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_lite) 595 mon_ops->mon_filter_setup_rx_pkt_log_lite(pdev); 596 } 597 598 void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev) 599 { 600 struct dp_mon_ops *mon_ops = NULL; 601 602 mon_ops = dp_mon_ops_get(pdev->soc); 603 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_lite) 604 mon_ops->mon_filter_reset_rx_pkt_log_lite(pdev); 605 } 606 607 void dp_mon_filter_setup_rx_pkt_log_cbf(struct dp_pdev *pdev) 608 { 609 struct dp_mon_ops *mon_ops = NULL; 610 611 mon_ops = dp_mon_ops_get(pdev->soc); 612 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_cbf) 613 mon_ops->mon_filter_setup_rx_pkt_log_cbf(pdev); 614 } 615 616 void dp_mon_filter_reset_rx_pktlog_cbf(struct dp_pdev *pdev) 617 { 618 struct dp_mon_ops *mon_ops = NULL; 619 620 mon_ops = dp_mon_ops_get(pdev->soc); 621 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_cbf) 622 mon_ops->mon_filter_reset_rx_pkt_log_cbf(pdev); 623 } 624 625 #ifdef BE_PKTLOG_SUPPORT 626 void dp_mon_filter_setup_pktlog_hybrid(struct dp_pdev *pdev) 627 { 628 struct dp_mon_ops *mon_ops = NULL; 629 630 mon_ops = dp_mon_ops_get(pdev->soc); 631 if (mon_ops && mon_ops->mon_filter_setup_pktlog_hybrid) 632 mon_ops->mon_filter_setup_pktlog_hybrid(pdev); 633 } 634 635 void dp_mon_filter_reset_pktlog_hybrid(struct dp_pdev *pdev) 636 { 637 struct dp_mon_ops *mon_ops = NULL; 638 639 mon_ops = dp_mon_ops_get(pdev->soc); 640 if (mon_ops && mon_ops->mon_filter_reset_pktlog_hybrid) 641 mon_ops->mon_filter_reset_pktlog_hybrid(pdev); 642 } 643 #endif 644 #endif /* WDI_EVENT_ENABLE */ 645 646 QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev) 647 { 648 struct dp_mon_ops *mon_ops = NULL; 649 650 mon_ops = dp_mon_ops_get(pdev->soc); 651 if (!mon_ops) { 652 dp_mon_filter_err("Rx mon filter update failed ops uninitialized"); 653 return QDF_STATUS_E_FAILURE; 654 } 655 656 if (mon_ops && mon_ops->rx_mon_filter_update) 657 mon_ops->rx_mon_filter_update(pdev); 658 659 return QDF_STATUS_SUCCESS; 660 } 661 662 QDF_STATUS dp_tx_mon_filter_update(struct dp_pdev *pdev) 663 { 664 struct dp_mon_ops *mon_ops = NULL; 665 666 mon_ops = dp_mon_ops_get(pdev->soc); 667 if (!mon_ops) { 668 dp_mon_filter_err("Tx mon filter update failed ops uninitialized"); 669 return QDF_STATUS_E_FAILURE; 670 } 671 672 if (mon_ops && mon_ops->tx_mon_filter_update) 673 mon_ops->tx_mon_filter_update(pdev); 674 675 return QDF_STATUS_SUCCESS; 676 } 677 678 #ifdef QCA_ENHANCED_STATS_SUPPORT 679 void dp_mon_filters_reset(struct dp_pdev *pdev) 680 { 681 dp_mon_filter_reset_enhanced_stats(pdev); 682 dp_mon_filter_reset_mon_mode(pdev); 683 dp_mon_filter_update(pdev); 684 } 685 #else 686 void dp_mon_filters_reset(struct dp_pdev *pdev) 687 { 688 } 689 #endif 690 691 void 692 dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev, 693 enum dp_mon_filter_srng_type mon_srng_type) 694 { 695 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 696 697 if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type, 698 &tlv_filter) != QDF_STATUS_SUCCESS) { 699 dp_mon_filter_err("%pK: Monitor destination ring filter setting failed", 700 soc); 701 } 702 } 703 704 /** 705 * dp_mon_filter_adjust() - adjust the mon filters per target basis 706 * @pdev: DP pdev handle 707 * @filter: DP mon filter 708 * 709 * Return: None 710 */ 711 static inline 712 void dp_mon_filter_adjust(struct dp_pdev *pdev, struct dp_mon_filter *filter) 713 { 714 struct dp_soc *soc = pdev->soc; 715 716 switch (hal_get_target_type(soc->hal_soc)) { 717 case TARGET_TYPE_KIWI: 718 case TARGET_TYPE_MANGO: 719 case TARGET_TYPE_PEACH: 720 filter->tlv_filter.msdu_start = 0; 721 filter->tlv_filter.mpdu_end = 0; 722 filter->tlv_filter.packet_header = 0; 723 filter->tlv_filter.attention = 0; 724 break; 725 default: 726 break; 727 } 728 } 729 730 void dp_mon_filter_set_mon_cmn(struct dp_pdev *pdev, 731 struct dp_mon_filter *filter) 732 { 733 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 734 735 filter->tlv_filter.mpdu_start = 1; 736 filter->tlv_filter.msdu_start = 1; 737 filter->tlv_filter.packet = 1; 738 filter->tlv_filter.msdu_end = 1; 739 filter->tlv_filter.mpdu_end = 1; 740 filter->tlv_filter.packet_header = 1; 741 filter->tlv_filter.attention = 1; 742 filter->tlv_filter.ppdu_start = 0; 743 filter->tlv_filter.ppdu_end = 0; 744 filter->tlv_filter.ppdu_end_user_stats = 0; 745 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 746 filter->tlv_filter.ppdu_end_status_done = 0; 747 filter->tlv_filter.header_per_msdu = 1; 748 filter->tlv_filter.enable_fp = 749 (mon_pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; 750 filter->tlv_filter.enable_mo = 751 (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; 752 753 filter->tlv_filter.fp_mgmt_filter = mon_pdev->fp_mgmt_filter; 754 filter->tlv_filter.fp_ctrl_filter = mon_pdev->fp_ctrl_filter; 755 filter->tlv_filter.fp_data_filter = mon_pdev->fp_data_filter; 756 filter->tlv_filter.mo_mgmt_filter = mon_pdev->mo_mgmt_filter; 757 filter->tlv_filter.mo_ctrl_filter = mon_pdev->mo_ctrl_filter; 758 filter->tlv_filter.mo_data_filter = mon_pdev->mo_data_filter; 759 filter->tlv_filter.offset_valid = false; 760 dp_mon_filter_adjust(pdev, filter); 761 } 762 763 void dp_mon_filter_set_status_cmn(struct dp_mon_pdev *mon_pdev, 764 struct dp_mon_filter *filter) 765 { 766 filter->tlv_filter.mpdu_start = 1; 767 filter->tlv_filter.msdu_start = 0; 768 filter->tlv_filter.packet = 0; 769 filter->tlv_filter.msdu_end = 0; 770 filter->tlv_filter.mpdu_end = 0; 771 filter->tlv_filter.attention = 0; 772 filter->tlv_filter.ppdu_start = 1; 773 filter->tlv_filter.ppdu_end = 1; 774 filter->tlv_filter.ppdu_end_user_stats = 1; 775 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 776 filter->tlv_filter.ppdu_end_status_done = 1; 777 filter->tlv_filter.ppdu_start_user_info = 1; 778 filter->tlv_filter.enable_fp = 1; 779 filter->tlv_filter.enable_md = 0; 780 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; 781 filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; 782 filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL; 783 filter->tlv_filter.offset_valid = false; 784 785 if (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) { 786 filter->tlv_filter.enable_mo = 1; 787 filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; 788 filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; 789 filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL; 790 } else { 791 filter->tlv_filter.enable_mo = 0; 792 } 793 } 794 795 void dp_mon_filter_set_status_cbf(struct dp_pdev *pdev, 796 struct dp_mon_filter *filter) 797 { 798 filter->tlv_filter.mpdu_start = 1; 799 filter->tlv_filter.msdu_start = 0; 800 filter->tlv_filter.packet = 0; 801 filter->tlv_filter.msdu_end = 0; 802 filter->tlv_filter.mpdu_end = 0; 803 filter->tlv_filter.attention = 0; 804 filter->tlv_filter.ppdu_start = 1; 805 filter->tlv_filter.ppdu_end = 1; 806 filter->tlv_filter.ppdu_end_user_stats = 1; 807 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 808 filter->tlv_filter.ppdu_end_status_done = 1; 809 filter->tlv_filter.ppdu_start_user_info = 1; 810 filter->tlv_filter.enable_fp = 1; 811 filter->tlv_filter.enable_md = 0; 812 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 813 filter->tlv_filter.fp_ctrl_filter = 0; 814 filter->tlv_filter.fp_data_filter = 0; 815 filter->tlv_filter.offset_valid = false; 816 filter->tlv_filter.enable_mo = 0; 817 } 818 819 void dp_mon_filter_set_cbf_cmn(struct dp_pdev *pdev, 820 struct dp_mon_filter *filter) 821 { 822 filter->tlv_filter.mpdu_start = 1; 823 filter->tlv_filter.msdu_start = 1; 824 filter->tlv_filter.packet = 1; 825 filter->tlv_filter.msdu_end = 1; 826 filter->tlv_filter.mpdu_end = 1; 827 filter->tlv_filter.attention = 1; 828 filter->tlv_filter.ppdu_start = 0; 829 filter->tlv_filter.ppdu_end = 0; 830 filter->tlv_filter.ppdu_end_user_stats = 0; 831 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 832 filter->tlv_filter.ppdu_end_status_done = 0; 833 filter->tlv_filter.ppdu_start_user_info = 0; 834 filter->tlv_filter.enable_fp = 1; 835 filter->tlv_filter.enable_md = 0; 836 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 837 filter->tlv_filter.offset_valid = false; 838 filter->tlv_filter.enable_mo = 0; 839 } 840 841 void dp_mon_filter_dealloc(struct dp_mon_pdev *mon_pdev) 842 { 843 enum dp_mon_filter_mode mode; 844 struct dp_mon_filter **mon_filter = NULL; 845 846 if (!mon_pdev) { 847 dp_mon_filter_err("Monitor pdev Context is null"); 848 return; 849 } 850 851 mon_filter = mon_pdev->filter; 852 853 /* 854 * Check if the monitor filters are already allocated to the mon_pdev. 855 */ 856 if (!mon_filter) { 857 dp_mon_filter_err("Found NULL memory for the Monitor filter"); 858 return; 859 } 860 861 /* 862 * Iterate through the every mode and free the filter object. 863 */ 864 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 865 if (!mon_filter[mode]) { 866 continue; 867 } 868 869 qdf_mem_free(mon_filter[mode]); 870 mon_filter[mode] = NULL; 871 } 872 873 qdf_mem_free(mon_filter); 874 mon_pdev->filter = NULL; 875 } 876 877 struct dp_mon_filter **dp_mon_filter_alloc(struct dp_mon_pdev *mon_pdev) 878 { 879 struct dp_mon_filter **mon_filter = NULL; 880 enum dp_mon_filter_mode mode; 881 882 if (!mon_pdev) { 883 dp_mon_filter_err("pdev Context is null"); 884 return NULL; 885 } 886 887 mon_filter = (struct dp_mon_filter **)qdf_mem_malloc( 888 (sizeof(struct dp_mon_filter *) * 889 DP_MON_FILTER_MAX_MODE)); 890 if (!mon_filter) { 891 dp_mon_filter_err("Monitor filter mem allocation failed"); 892 return NULL; 893 } 894 895 qdf_mem_zero(mon_filter, 896 sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE); 897 898 /* 899 * Allocate the memory for filters for different srngs for each modes. 900 */ 901 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 902 mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) * 903 DP_MON_FILTER_SRNG_TYPE_MAX); 904 /* Assign the mon_filter to the pdev->filter such 905 * that the dp_mon_filter_dealloc() can free up the filters. */ 906 if (!mon_filter[mode]) { 907 mon_pdev->filter = mon_filter; 908 goto fail; 909 } 910 } 911 912 return mon_filter; 913 fail: 914 dp_mon_filter_dealloc(mon_pdev); 915 return NULL; 916 } 917 918 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE 919 QDF_STATUS dp_mon_set_local_pkt_capture_running(struct dp_mon_pdev *mon_pdev, 920 bool val) 921 { 922 if (!mon_pdev) { 923 dp_mon_filter_err("Invalid monitor pdev"); 924 return QDF_STATUS_E_FAILURE; 925 } 926 927 mon_pdev->is_local_pkt_capture_running = val; 928 dp_mon_filter_debug("local_pkt_capture_running is set to %d", val); 929 return QDF_STATUS_SUCCESS; 930 } 931 932 bool dp_mon_get_is_local_pkt_capture_running(struct cdp_soc_t *cdp_soc, 933 uint8_t pdev_id) 934 { 935 struct dp_soc *soc = (struct dp_soc *)cdp_soc; 936 struct dp_pdev *pdev = 937 dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 938 struct dp_mon_pdev *mon_pdev; 939 940 if (!pdev || !pdev->monitor_pdev) { 941 dp_mon_filter_err("Invalid pdev_id %u", pdev_id); 942 return false; 943 } 944 945 mon_pdev = pdev->monitor_pdev; 946 947 return mon_pdev->is_local_pkt_capture_running; 948 } 949 950 static void 951 dp_mon_set_local_pkt_capture_rx_filter(struct dp_pdev *pdev, 952 struct cdp_monitor_filter *src_filter) 953 { 954 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 955 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 956 enum dp_mon_filter_srng_type srng_type; 957 struct dp_mon_filter dst_filter = {0}; 958 959 dst_filter.valid = true; 960 dp_mon_filter_set_status_cmn(mon_pdev, &dst_filter); 961 962 dst_filter.tlv_filter.packet_header = 1; 963 dst_filter.tlv_filter.header_per_msdu = 1; 964 dst_filter.tlv_filter.rx_hdr_length = RX_HDR_DMA_LENGTH_256B; 965 dst_filter.tlv_filter.fp_mgmt_filter = src_filter->fp_mgmt; 966 dst_filter.tlv_filter.fp_ctrl_filter = src_filter->fp_ctrl; 967 dst_filter.tlv_filter.fp_data_filter = src_filter->fp_data; 968 dst_filter.tlv_filter.enable_fp = src_filter->mode; 969 dst_filter.tlv_filter.enable_md = 0; 970 dst_filter.tlv_filter.enable_mo = 0; 971 972 dp_mon_filter_show_filter(mon_pdev, mode, &dst_filter); 973 974 /* Store the above filter */ 975 srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 976 mon_pdev->filter[mode][srng_type] = dst_filter; 977 } 978 979 static void dp_mon_clear_local_pkt_capture_rx_filter(struct dp_pdev *pdev) 980 { 981 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 982 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 983 enum dp_mon_filter_srng_type srng_type = 984 DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 985 struct dp_mon_filter filter = {0}; 986 987 mon_pdev->filter[mode][srng_type] = filter; 988 } 989 990 static void dp_mon_reset_local_pkt_capture_rx_filter(struct dp_pdev *pdev) 991 { 992 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 993 enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE; 994 enum dp_mon_filter_srng_type srng_type = 995 DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS; 996 struct dp_mon_filter filter = {0}; 997 998 filter.valid = true; 999 mon_pdev->filter[mode][srng_type] = filter; 1000 dp_mon_pdev_filter_init(mon_pdev); 1001 } 1002 1003 QDF_STATUS dp_mon_start_local_pkt_capture(struct cdp_soc_t *cdp_soc, 1004 uint8_t pdev_id, 1005 struct cdp_monitor_filter *filter) 1006 { 1007 bool local_pkt_capture_running; 1008 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 1009 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1010 struct dp_mon_pdev *mon_pdev; 1011 QDF_STATUS status = QDF_STATUS_SUCCESS; 1012 1013 if (!pdev) { 1014 dp_mon_filter_err("pdev Context is null"); 1015 return QDF_STATUS_E_INVAL; 1016 } 1017 1018 mon_pdev = pdev->monitor_pdev; 1019 local_pkt_capture_running = 1020 dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id); 1021 if (local_pkt_capture_running) { 1022 dp_mon_filter_err("Can't start local pkt capture. Already running"); 1023 return QDF_STATUS_E_ALREADY; 1024 } 1025 1026 mon_pdev->mon_filter_mode = filter->mode; 1027 mon_pdev->fp_mgmt_filter = filter->fp_mgmt; 1028 mon_pdev->fp_ctrl_filter = filter->fp_ctrl; 1029 mon_pdev->fp_data_filter = filter->fp_data; 1030 1031 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1032 dp_mon_set_local_pkt_capture_rx_filter(pdev, filter); 1033 status = dp_mon_filter_update(pdev); 1034 if (QDF_IS_STATUS_ERROR(status)) { 1035 dp_mon_clear_local_pkt_capture_rx_filter(pdev); 1036 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1037 dp_mon_filter_err("local pkt capture set rx filter failed"); 1038 return status; 1039 } 1040 1041 dp_mon_filter_setup_tx_mon_mode(pdev); 1042 status = dp_tx_mon_filter_update(pdev); 1043 if (QDF_IS_STATUS_ERROR(status)) { 1044 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1045 dp_mon_filter_err("local pkt capture set tx filter failed"); 1046 return status; 1047 } 1048 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1049 1050 dp_mon_filter_debug("local pkt capture tx filter set"); 1051 1052 dp_mon_set_local_pkt_capture_running(mon_pdev, true); 1053 return status; 1054 } 1055 1056 QDF_STATUS dp_mon_stop_local_pkt_capture(struct cdp_soc_t *cdp_soc, 1057 uint8_t pdev_id) 1058 { 1059 bool local_pkt_capture_running; 1060 struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc); 1061 struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id); 1062 struct dp_mon_pdev *mon_pdev; 1063 QDF_STATUS status = QDF_STATUS_SUCCESS; 1064 1065 if (!pdev) { 1066 dp_mon_filter_err("pdev Context is null"); 1067 return QDF_STATUS_E_INVAL; 1068 } 1069 1070 mon_pdev = pdev->monitor_pdev; 1071 local_pkt_capture_running = 1072 dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id); 1073 if (!local_pkt_capture_running) { 1074 dp_mon_filter_err("Local pkt capture is not running"); 1075 return QDF_STATUS_SUCCESS; 1076 } 1077 1078 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1079 dp_mon_reset_local_pkt_capture_rx_filter(pdev); 1080 status = dp_mon_filter_update(pdev); 1081 if (QDF_IS_STATUS_ERROR(status)) { 1082 dp_mon_filter_err("local pkt capture set rx filter failed"); 1083 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1084 return status; 1085 } 1086 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1087 1088 qdf_spin_lock_bh(&mon_pdev->mon_lock); 1089 dp_mon_filter_reset_tx_mon_mode(pdev); 1090 dp_tx_mon_filter_update(pdev); 1091 qdf_spin_unlock_bh(&mon_pdev->mon_lock); 1092 dp_mon_filter_debug("local pkt capture stopped"); 1093 1094 dp_mon_set_local_pkt_capture_running(mon_pdev, false); 1095 return QDF_STATUS_SUCCESS; 1096 } 1097 1098 #endif /* WLAN_FEATURE_LOCAL_PKT_CAPTURE */ 1099