xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/dp_mon_filter.c (revision de1e7e7e129e3f35eaee7ba04135d2734e70c50a)
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