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