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