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