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