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