1 /* 2 * Copyright (c) 2020-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 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 }; 53 54 void dp_mon_filter_show_filter(struct dp_mon_pdev *mon_pdev, 55 enum dp_mon_filter_mode mode, 56 struct dp_mon_filter *filter) 57 { 58 struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; 59 60 DP_MON_FILTER_PRINT("[%s]: Valid: %d", 61 dp_mon_filter_mode_type_to_str[mode], 62 filter->valid); 63 DP_MON_FILTER_PRINT("mpdu_start: %d", tlv_filter->mpdu_start); 64 DP_MON_FILTER_PRINT("msdu_start: %d", tlv_filter->msdu_start); 65 DP_MON_FILTER_PRINT("packet: %d", tlv_filter->packet); 66 DP_MON_FILTER_PRINT("msdu_end: %d", tlv_filter->msdu_end); 67 DP_MON_FILTER_PRINT("mpdu_end: %d", tlv_filter->mpdu_end); 68 DP_MON_FILTER_PRINT("packet_header: %d", 69 tlv_filter->packet_header); 70 DP_MON_FILTER_PRINT("attention: %d", tlv_filter->attention); 71 DP_MON_FILTER_PRINT("ppdu_start: %d", tlv_filter->ppdu_start); 72 DP_MON_FILTER_PRINT("ppdu_end: %d", tlv_filter->ppdu_end); 73 DP_MON_FILTER_PRINT("ppdu_end_user_stats: %d", 74 tlv_filter->ppdu_end_user_stats); 75 DP_MON_FILTER_PRINT("ppdu_end_user_stats_ext: %d", 76 tlv_filter->ppdu_end_user_stats_ext); 77 DP_MON_FILTER_PRINT("ppdu_end_status_done: %d", 78 tlv_filter->ppdu_end_status_done); 79 DP_MON_FILTER_PRINT("header_per_msdu: %d", tlv_filter->header_per_msdu); 80 DP_MON_FILTER_PRINT("enable_fp: %d", tlv_filter->enable_fp); 81 DP_MON_FILTER_PRINT("enable_md: %d", tlv_filter->enable_md); 82 DP_MON_FILTER_PRINT("enable_mo: %d", tlv_filter->enable_mo); 83 DP_MON_FILTER_PRINT("fp_mgmt_filter: 0x%x", tlv_filter->fp_mgmt_filter); 84 DP_MON_FILTER_PRINT("mo_mgmt_filter: 0x%x", tlv_filter->mo_mgmt_filter); 85 DP_MON_FILTER_PRINT("fp_ctrl_filter: 0x%x", tlv_filter->fp_ctrl_filter); 86 DP_MON_FILTER_PRINT("mo_ctrl_filter: 0x%x", tlv_filter->mo_ctrl_filter); 87 DP_MON_FILTER_PRINT("fp_data_filter: 0x%x", tlv_filter->fp_data_filter); 88 DP_MON_FILTER_PRINT("mo_data_filter: 0x%x", tlv_filter->mo_data_filter); 89 DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter); 90 DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter); 91 DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter); 92 } 93 94 /** 95 * dp_mon_filter_h2t_setup() - Setup the filter for the Target setup 96 * @soc: DP soc handle 97 * @pdev: DP pdev handle 98 * @srng_type: The srng type for which filter wll be set 99 * @tlv_filter: tlv filter 100 */ 101 void dp_mon_filter_h2t_setup(struct dp_soc *soc, struct dp_pdev *pdev, 102 enum dp_mon_filter_srng_type srng_type, 103 struct dp_mon_filter *filter) 104 { 105 int32_t current_mode = 0; 106 struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter; 107 struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev; 108 109 /* 110 * Loop through all the modes. 111 */ 112 for (current_mode = 0; current_mode < DP_MON_FILTER_MAX_MODE; 113 current_mode++) { 114 struct dp_mon_filter *mon_filter = 115 &mon_pdev->filter[current_mode][srng_type]; 116 uint32_t src_filter = 0, dst_filter = 0; 117 118 /* 119 * Check if the correct mode is enabled or not. 120 */ 121 if (!mon_filter->valid) 122 continue; 123 124 filter->valid = true; 125 126 /* 127 * Set the super bit fields 128 */ 129 src_filter = 130 DP_MON_FILTER_GET(&mon_filter->tlv_filter, FILTER_TLV); 131 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_TLV); 132 dst_filter |= src_filter; 133 DP_MON_FILTER_SET(tlv_filter, FILTER_TLV, dst_filter); 134 135 /* 136 * Set the filter management filter. 137 */ 138 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 139 FILTER_FP_MGMT); 140 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_MGMT); 141 dst_filter |= src_filter; 142 DP_MON_FILTER_SET(tlv_filter, FILTER_FP_MGMT, dst_filter); 143 144 /* 145 * Set the monitor other management filter. 146 */ 147 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 148 FILTER_MO_MGMT); 149 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_MGMT); 150 dst_filter |= src_filter; 151 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_MGMT, dst_filter); 152 153 /* 154 * Set the filter pass control filter. 155 */ 156 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 157 FILTER_FP_CTRL); 158 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_CTRL); 159 dst_filter |= src_filter; 160 DP_MON_FILTER_SET(tlv_filter, FILTER_FP_CTRL, dst_filter); 161 162 /* 163 * Set the monitor other control filter. 164 */ 165 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 166 FILTER_MO_CTRL); 167 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_CTRL); 168 dst_filter |= src_filter; 169 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_CTRL, dst_filter); 170 171 /* 172 * Set the filter pass data filter. 173 */ 174 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 175 FILTER_FP_DATA); 176 dst_filter = DP_MON_FILTER_GET(tlv_filter, 177 FILTER_FP_DATA); 178 dst_filter |= src_filter; 179 DP_MON_FILTER_SET(tlv_filter, 180 FILTER_FP_DATA, dst_filter); 181 182 /* 183 * Set the monitor other data filter. 184 */ 185 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 186 FILTER_MO_DATA); 187 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_DATA); 188 dst_filter |= src_filter; 189 DP_MON_FILTER_SET(tlv_filter, FILTER_MO_DATA, dst_filter); 190 191 /* 192 * Set the monitor direct data filter. 193 */ 194 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 195 FILTER_MD_DATA); 196 dst_filter = DP_MON_FILTER_GET(tlv_filter, 197 FILTER_MD_DATA); 198 dst_filter |= src_filter; 199 DP_MON_FILTER_SET(tlv_filter, 200 FILTER_MD_DATA, dst_filter); 201 202 /* 203 * Set the monitor direct management filter. 204 */ 205 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 206 FILTER_MD_MGMT); 207 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_MGMT); 208 dst_filter |= src_filter; 209 DP_MON_FILTER_SET(tlv_filter, FILTER_MD_MGMT, dst_filter); 210 211 /* 212 * Set the monitor direct management filter. 213 */ 214 src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter, 215 FILTER_MD_CTRL); 216 dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL); 217 dst_filter |= src_filter; 218 DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter); 219 } 220 221 dp_mon_filter_show_filter(mon_pdev, 0, filter); 222 } 223 224 QDF_STATUS 225 dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc, 226 struct dp_pdev *pdev, 227 enum dp_mon_filter_srng_type srng_type, 228 struct htt_rx_ring_tlv_filter *tlv_filter) 229 { 230 int mac_id; 231 int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx); 232 QDF_STATUS status = QDF_STATUS_SUCCESS; 233 234 /* 235 * Overwrite the max_mac_rings for the status rings. 236 */ 237 if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS) 238 dp_is_hw_dbs_enable(soc, &max_mac_rings); 239 240 dp_mon_filter_info("%pK: srng type %d Max_mac_rings %d ", 241 soc, srng_type, max_mac_rings); 242 243 /* 244 * Loop through all MACs per radio and set the filter to the individual 245 * macs. For MCL 246 */ 247 for (mac_id = 0; mac_id < max_mac_rings; mac_id++) { 248 int mac_for_pdev = 249 dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id); 250 int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id); 251 int hal_ring_type, ring_buf_size; 252 hal_ring_handle_t hal_ring_hdl; 253 254 switch (srng_type) { 255 case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF: 256 hal_ring_hdl = pdev->rx_mac_buf_ring[lmac_id].hal_srng; 257 hal_ring_type = RXDMA_BUF; 258 ring_buf_size = RX_DATA_BUFFER_SIZE; 259 break; 260 261 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS: 262 /* 263 * If two back to back HTT msg sending happened in 264 * short time, the second HTT msg source SRNG HP 265 * writing has chance to fail, this has been confirmed 266 * by HST HW. 267 * for monitor mode, here is the last HTT msg for sending. 268 * if the 2nd HTT msg for monitor status ring sending failed, 269 * HW won't provide anything into 2nd monitor status ring. 270 * as a WAR, add some delay before 2nd HTT msg start sending, 271 * > 2us is required per HST HW, delay 100 us for safe. 272 */ 273 if (mac_id) 274 qdf_udelay(100); 275 276 hal_ring_hdl = 277 soc->rxdma_mon_status_ring[lmac_id].hal_srng; 278 hal_ring_type = RXDMA_MONITOR_STATUS; 279 ring_buf_size = RX_MON_STATUS_BUF_SIZE; 280 break; 281 282 case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF: 283 hal_ring_hdl = 284 soc->rxdma_mon_buf_ring[lmac_id].hal_srng; 285 hal_ring_type = RXDMA_MONITOR_BUF; 286 ring_buf_size = RX_DATA_BUFFER_SIZE; 287 break; 288 289 case DP_MON_FILTER_SRNG_TYPE_RXMON_DEST: 290 hal_ring_hdl = 291 soc->rxdma_mon_dst_ring[lmac_id].hal_srng; 292 hal_ring_type = RXDMA_MONITOR_DST; 293 ring_buf_size = RX_DATA_BUFFER_SIZE; 294 break; 295 default: 296 return QDF_STATUS_E_FAILURE; 297 } 298 299 if (!hal_ring_hdl) 300 continue; 301 302 status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev, 303 hal_ring_hdl, hal_ring_type, 304 ring_buf_size, 305 tlv_filter); 306 if (status != QDF_STATUS_SUCCESS) 307 return status; 308 } 309 310 return status; 311 } 312 313 #ifdef QCA_ENHANCED_STATS_SUPPORT 314 void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev) 315 { 316 struct dp_mon_ops *mon_ops = NULL; 317 318 mon_ops = dp_mon_ops_get(pdev->soc); 319 if (mon_ops && mon_ops->mon_filter_setup_enhanced_stats) 320 mon_ops->mon_filter_setup_enhanced_stats(pdev); 321 } 322 323 void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev) 324 { 325 struct dp_mon_ops *mon_ops = NULL; 326 327 mon_ops = dp_mon_ops_get(pdev->soc); 328 if (mon_ops && mon_ops->mon_filter_reset_enhanced_stats) 329 mon_ops->mon_filter_reset_enhanced_stats(pdev); 330 } 331 #endif /* QCA_ENHANCED_STATS_SUPPORT */ 332 333 #ifdef QCA_MCOPY_SUPPORT 334 void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev) 335 { 336 struct dp_mon_ops *mon_ops = NULL; 337 338 mon_ops = dp_mon_ops_get(pdev->soc); 339 if (mon_ops && mon_ops->mon_filter_setup_mcopy_mode) 340 mon_ops->mon_filter_setup_mcopy_mode(pdev); 341 } 342 343 void dp_mon_filter_reset_mcopy_mode(struct dp_pdev *pdev) 344 { 345 struct dp_mon_ops *mon_ops = NULL; 346 347 mon_ops = dp_mon_ops_get(pdev->soc); 348 if (mon_ops && mon_ops->mon_filter_reset_mcopy_mode) 349 mon_ops->mon_filter_reset_mcopy_mode(pdev); 350 } 351 #endif /* QCA_MCOPY_SUPPORT */ 352 353 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC) 354 void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev) 355 { 356 struct dp_mon_ops *mon_ops = NULL; 357 358 mon_ops = dp_mon_ops_get(pdev->soc); 359 if (mon_ops && mon_ops->mon_filter_setup_smart_monitor) 360 mon_ops->mon_filter_setup_smart_monitor(pdev); 361 } 362 363 void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev) 364 { 365 struct dp_mon_ops *mon_ops = NULL; 366 367 mon_ops = dp_mon_ops_get(pdev->soc); 368 if (mon_ops && mon_ops->mon_filter_reset_smart_monitor) 369 mon_ops->mon_filter_reset_smart_monitor(pdev); 370 } 371 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */ 372 373 #ifdef WLAN_RX_PKT_CAPTURE_ENH 374 void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev) 375 { 376 struct dp_mon_ops *mon_ops = NULL; 377 378 mon_ops = dp_mon_ops_get(pdev->soc); 379 if (mon_ops && mon_ops->mon_filter_setup_rx_enh_capture) 380 mon_ops->mon_filter_setup_rx_enh_capture(pdev); 381 } 382 383 void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev) 384 { 385 struct dp_mon_ops *mon_ops = NULL; 386 387 mon_ops = dp_mon_ops_get(pdev->soc); 388 if (mon_ops && mon_ops->mon_filter_reset_rx_enh_capture) 389 mon_ops->mon_filter_reset_rx_enh_capture(pdev); 390 } 391 #endif /* WLAN_RX_PKT_CAPTURE_ENH */ 392 393 void dp_mon_filter_setup_mon_mode(struct dp_pdev *pdev) 394 { 395 struct dp_mon_ops *mon_ops = NULL; 396 397 mon_ops = dp_mon_ops_get(pdev->soc); 398 if (mon_ops && mon_ops->mon_filter_setup_rx_mon_mode) 399 mon_ops->mon_filter_setup_rx_mon_mode(pdev); 400 if (mon_ops && mon_ops->mon_filter_setup_tx_mon_mode) 401 mon_ops->mon_filter_setup_tx_mon_mode(pdev); 402 } 403 404 void dp_mon_filter_reset_mon_mode(struct dp_pdev *pdev) 405 { 406 struct dp_mon_ops *mon_ops = NULL; 407 408 mon_ops = dp_mon_ops_get(pdev->soc); 409 if (mon_ops && mon_ops->mon_filter_reset_rx_mon_mode) 410 mon_ops->mon_filter_reset_rx_mon_mode(pdev); 411 if (mon_ops && mon_ops->mon_filter_reset_tx_mon_mode) 412 mon_ops->mon_filter_reset_tx_mon_mode(pdev); 413 } 414 415 #ifdef WDI_EVENT_ENABLE 416 void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev) 417 { 418 struct dp_mon_ops *mon_ops = NULL; 419 420 mon_ops = dp_mon_ops_get(pdev->soc); 421 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_full) 422 mon_ops->mon_filter_setup_rx_pkt_log_full(pdev); 423 } 424 425 void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev) 426 { 427 struct dp_mon_ops *mon_ops = NULL; 428 429 mon_ops = dp_mon_ops_get(pdev->soc); 430 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_full) 431 mon_ops->mon_filter_reset_rx_pkt_log_full(pdev); 432 } 433 434 void dp_mon_filter_setup_rx_pkt_log_lite(struct dp_pdev *pdev) 435 { 436 struct dp_mon_ops *mon_ops = NULL; 437 438 mon_ops = dp_mon_ops_get(pdev->soc); 439 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_lite) 440 mon_ops->mon_filter_setup_rx_pkt_log_lite(pdev); 441 } 442 443 void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev) 444 { 445 struct dp_mon_ops *mon_ops = NULL; 446 447 mon_ops = dp_mon_ops_get(pdev->soc); 448 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_lite) 449 mon_ops->mon_filter_reset_rx_pkt_log_lite(pdev); 450 } 451 452 void dp_mon_filter_setup_rx_pkt_log_cbf(struct dp_pdev *pdev) 453 { 454 struct dp_mon_ops *mon_ops = NULL; 455 456 mon_ops = dp_mon_ops_get(pdev->soc); 457 if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_cbf) 458 mon_ops->mon_filter_setup_rx_pkt_log_cbf(pdev); 459 } 460 461 void dp_mon_filter_reset_rx_pktlog_cbf(struct dp_pdev *pdev) 462 { 463 struct dp_mon_ops *mon_ops = NULL; 464 465 mon_ops = dp_mon_ops_get(pdev->soc); 466 if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_cbf) 467 mon_ops->mon_filter_reset_rx_pkt_log_cbf(pdev); 468 } 469 470 #ifdef BE_PKTLOG_SUPPORT 471 void dp_mon_filter_setup_pktlog_hybrid(struct dp_pdev *pdev) 472 { 473 struct dp_mon_ops *mon_ops = NULL; 474 475 mon_ops = dp_mon_ops_get(pdev->soc); 476 if (mon_ops && mon_ops->mon_filter_setup_pktlog_hybrid) 477 mon_ops->mon_filter_setup_pktlog_hybrid(pdev); 478 } 479 480 void dp_mon_filter_reset_pktlog_hybrid(struct dp_pdev *pdev) 481 { 482 struct dp_mon_ops *mon_ops = NULL; 483 484 mon_ops = dp_mon_ops_get(pdev->soc); 485 if (mon_ops && mon_ops->mon_filter_reset_pktlog_hybrid) 486 mon_ops->mon_filter_reset_pktlog_hybrid(pdev); 487 } 488 #endif 489 #endif /* WDI_EVENT_ENABLE */ 490 491 QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev) 492 { 493 struct dp_mon_ops *mon_ops = NULL; 494 495 mon_ops = dp_mon_ops_get(pdev->soc); 496 if (!mon_ops) { 497 dp_mon_filter_err("Mon ops uninitialized"); 498 return QDF_STATUS_E_FAILURE; 499 } 500 501 if (mon_ops && mon_ops->tx_mon_filter_update) 502 mon_ops->tx_mon_filter_update(pdev); 503 504 if (mon_ops && mon_ops->rx_mon_filter_update) 505 mon_ops->rx_mon_filter_update(pdev); 506 507 return QDF_STATUS_SUCCESS; 508 } 509 510 #ifdef QCA_ENHANCED_STATS_SUPPORT 511 void dp_mon_filters_reset(struct dp_pdev *pdev) 512 { 513 dp_mon_filter_reset_enhanced_stats(pdev); 514 dp_mon_filter_reset_mon_mode(pdev); 515 dp_mon_filter_update(pdev); 516 } 517 #else 518 void dp_mon_filters_reset(struct dp_pdev *pdev) 519 { 520 } 521 #endif 522 523 void 524 dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev, 525 enum dp_mon_filter_srng_type mon_srng_type) 526 { 527 struct htt_rx_ring_tlv_filter tlv_filter = {0}; 528 529 if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type, 530 &tlv_filter) != QDF_STATUS_SUCCESS) { 531 dp_mon_filter_err("%pK: Monitor destinatin ring filter setting failed", 532 soc); 533 } 534 } 535 536 void dp_mon_filter_set_mon_cmn(struct dp_mon_pdev *mon_pdev, 537 struct dp_mon_filter *filter) 538 { 539 filter->tlv_filter.mpdu_start = 1; 540 filter->tlv_filter.msdu_start = 1; 541 filter->tlv_filter.packet = 1; 542 filter->tlv_filter.msdu_end = 1; 543 filter->tlv_filter.mpdu_end = 1; 544 filter->tlv_filter.packet_header = 1; 545 filter->tlv_filter.attention = 1; 546 filter->tlv_filter.ppdu_start = 0; 547 filter->tlv_filter.ppdu_end = 0; 548 filter->tlv_filter.ppdu_end_user_stats = 0; 549 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 550 filter->tlv_filter.ppdu_end_status_done = 0; 551 filter->tlv_filter.header_per_msdu = 1; 552 filter->tlv_filter.enable_fp = 553 (mon_pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0; 554 filter->tlv_filter.enable_mo = 555 (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0; 556 557 filter->tlv_filter.fp_mgmt_filter = mon_pdev->fp_mgmt_filter; 558 filter->tlv_filter.fp_ctrl_filter = mon_pdev->fp_ctrl_filter; 559 filter->tlv_filter.fp_data_filter = mon_pdev->fp_data_filter; 560 filter->tlv_filter.mo_mgmt_filter = mon_pdev->mo_mgmt_filter; 561 filter->tlv_filter.mo_ctrl_filter = mon_pdev->mo_ctrl_filter; 562 filter->tlv_filter.mo_data_filter = mon_pdev->mo_data_filter; 563 filter->tlv_filter.offset_valid = false; 564 } 565 566 void dp_mon_filter_set_status_cmn(struct dp_mon_pdev *mon_pdev, 567 struct dp_mon_filter *filter) 568 { 569 filter->tlv_filter.mpdu_start = 1; 570 filter->tlv_filter.msdu_start = 0; 571 filter->tlv_filter.packet = 0; 572 filter->tlv_filter.msdu_end = 0; 573 filter->tlv_filter.mpdu_end = 0; 574 filter->tlv_filter.attention = 0; 575 filter->tlv_filter.ppdu_start = 1; 576 filter->tlv_filter.ppdu_end = 1; 577 filter->tlv_filter.ppdu_end_user_stats = 1; 578 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 579 filter->tlv_filter.ppdu_end_status_done = 1; 580 filter->tlv_filter.enable_fp = 1; 581 filter->tlv_filter.enable_md = 0; 582 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL; 583 filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL; 584 filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL; 585 filter->tlv_filter.offset_valid = false; 586 587 if (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) { 588 filter->tlv_filter.enable_mo = 1; 589 filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL; 590 filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL; 591 filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL; 592 } else { 593 filter->tlv_filter.enable_mo = 0; 594 } 595 } 596 597 void dp_mon_filter_set_status_cbf(struct dp_pdev *pdev, 598 struct dp_mon_filter *filter) 599 { 600 filter->tlv_filter.mpdu_start = 1; 601 filter->tlv_filter.msdu_start = 0; 602 filter->tlv_filter.packet = 0; 603 filter->tlv_filter.msdu_end = 0; 604 filter->tlv_filter.mpdu_end = 0; 605 filter->tlv_filter.attention = 0; 606 filter->tlv_filter.ppdu_start = 1; 607 filter->tlv_filter.ppdu_end = 1; 608 filter->tlv_filter.ppdu_end_user_stats = 1; 609 filter->tlv_filter.ppdu_end_user_stats_ext = 1; 610 filter->tlv_filter.ppdu_end_status_done = 1; 611 filter->tlv_filter.enable_fp = 1; 612 filter->tlv_filter.enable_md = 0; 613 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 614 filter->tlv_filter.fp_ctrl_filter = 0; 615 filter->tlv_filter.fp_data_filter = 0; 616 filter->tlv_filter.offset_valid = false; 617 filter->tlv_filter.enable_mo = 0; 618 } 619 620 void dp_mon_filter_set_cbf_cmn(struct dp_pdev *pdev, 621 struct dp_mon_filter *filter) 622 { 623 filter->tlv_filter.mpdu_start = 1; 624 filter->tlv_filter.msdu_start = 1; 625 filter->tlv_filter.packet = 1; 626 filter->tlv_filter.msdu_end = 1; 627 filter->tlv_filter.mpdu_end = 1; 628 filter->tlv_filter.attention = 1; 629 filter->tlv_filter.ppdu_start = 0; 630 filter->tlv_filter.ppdu_end = 0; 631 filter->tlv_filter.ppdu_end_user_stats = 0; 632 filter->tlv_filter.ppdu_end_user_stats_ext = 0; 633 filter->tlv_filter.ppdu_end_status_done = 0; 634 filter->tlv_filter.enable_fp = 1; 635 filter->tlv_filter.enable_md = 0; 636 filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK; 637 filter->tlv_filter.offset_valid = false; 638 filter->tlv_filter.enable_mo = 0; 639 } 640 641 /** 642 * dp_mon_filter_dealloc() - Deallocate the filter objects to be stored in 643 * the radio object. 644 * @pdev: DP pdev handle 645 */ 646 void dp_mon_filter_dealloc(struct dp_mon_pdev *mon_pdev) 647 { 648 enum dp_mon_filter_mode mode; 649 struct dp_mon_filter **mon_filter = NULL; 650 651 if (!mon_pdev) { 652 dp_mon_filter_err("Monitor pdev Context is null"); 653 return; 654 } 655 656 mon_filter = mon_pdev->filter; 657 658 /* 659 * Check if the monitor filters are already allocated to the mon_pdev. 660 */ 661 if (!mon_filter) { 662 dp_mon_filter_err("Found NULL memmory for the Monitor filter"); 663 return; 664 } 665 666 /* 667 * Iterate through the every mode and free the filter object. 668 */ 669 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 670 if (!mon_filter[mode]) { 671 continue; 672 } 673 674 qdf_mem_free(mon_filter[mode]); 675 mon_filter[mode] = NULL; 676 } 677 678 qdf_mem_free(mon_filter); 679 mon_pdev->filter = NULL; 680 } 681 682 /** 683 * dp_mon_filter_alloc() - Allocate the filter objects to be stored in 684 * the radio object. 685 * @mon_pdev: Monitor pdev handle 686 */ 687 struct dp_mon_filter **dp_mon_filter_alloc(struct dp_mon_pdev *mon_pdev) 688 { 689 struct dp_mon_filter **mon_filter = NULL; 690 enum dp_mon_filter_mode mode; 691 692 if (!mon_pdev) { 693 dp_mon_filter_err("pdev Context is null"); 694 return NULL; 695 } 696 697 mon_filter = (struct dp_mon_filter **)qdf_mem_malloc( 698 (sizeof(struct dp_mon_filter *) * 699 DP_MON_FILTER_MAX_MODE)); 700 if (!mon_filter) { 701 dp_mon_filter_err("Monitor filter mem allocation failed"); 702 return NULL; 703 } 704 705 qdf_mem_zero(mon_filter, 706 sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE); 707 708 /* 709 * Allocate the memory for filters for different srngs for each modes. 710 */ 711 for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) { 712 mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) * 713 DP_MON_FILTER_SRNG_TYPE_MAX); 714 /* Assign the mon_filter to the pdev->filter such 715 * that the dp_mon_filter_dealloc() can free up the filters. */ 716 if (!mon_filter[mode]) { 717 mon_pdev->filter = mon_filter; 718 goto fail; 719 } 720 } 721 722 return mon_filter; 723 fail: 724 dp_mon_filter_dealloc(mon_pdev); 725 return NULL; 726 } 727