xref: /wlan-dirver/qca-wifi-host-cmn/dp/wifi3.0/monitor/dp_mon_filter.c (revision 6b801c30d6a98fe9c4a8d7f8032538a9de770395)
1 /*
2  * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 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 #if defined(WLAN_PKT_CAPTURE_RX_2_0) || defined(CONFIG_WORD_BASED_TLV) || \
58 	defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE)
59 static inline
60 void dp_mon_filter_show_filter_1(struct htt_rx_ring_tlv_filter *tlv_filter)
61 {
62 	DP_MON_FILTER_PRINT("rx_hdr_length: %d", tlv_filter->rx_hdr_length);
63 	DP_MON_FILTER_PRINT("mgmt_dma_length: %d", tlv_filter->mgmt_dma_length);
64 	DP_MON_FILTER_PRINT("ctrl_dma_length: %d", tlv_filter->ctrl_dma_length);
65 	DP_MON_FILTER_PRINT("data_dma_length: %d", tlv_filter->data_dma_length);
66 }
67 #else
68 static inline
69 void dp_mon_filter_show_filter_1(struct htt_rx_ring_tlv_filter *tlv_filter)
70 {
71 }
72 #endif
73 
74 void dp_mon_filter_show_filter(struct dp_mon_pdev *mon_pdev,
75 			       enum dp_mon_filter_mode mode,
76 			       struct dp_mon_filter *filter)
77 {
78 	struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter;
79 
80 	DP_MON_FILTER_PRINT("[%s]: Valid: %d",
81 			    dp_mon_filter_mode_type_to_str[mode],
82 			    filter->valid);
83 	dp_mon_filter_show_filter_1(tlv_filter);
84 	DP_MON_FILTER_PRINT("mpdu_start: %d", tlv_filter->mpdu_start);
85 	DP_MON_FILTER_PRINT("msdu_start: %d", tlv_filter->msdu_start);
86 	DP_MON_FILTER_PRINT("packet: %d", tlv_filter->packet);
87 	DP_MON_FILTER_PRINT("msdu_end: %d", tlv_filter->msdu_end);
88 	DP_MON_FILTER_PRINT("mpdu_end: %d", tlv_filter->mpdu_end);
89 	DP_MON_FILTER_PRINT("packet_header: %d",
90 			    tlv_filter->packet_header);
91 	DP_MON_FILTER_PRINT("attention: %d", tlv_filter->attention);
92 	DP_MON_FILTER_PRINT("ppdu_start: %d", tlv_filter->ppdu_start);
93 	DP_MON_FILTER_PRINT("ppdu_end: %d", tlv_filter->ppdu_end);
94 	DP_MON_FILTER_PRINT("ppdu_end_user_stats: %d",
95 			    tlv_filter->ppdu_end_user_stats);
96 	DP_MON_FILTER_PRINT("ppdu_end_user_stats_ext: %d",
97 			    tlv_filter->ppdu_end_user_stats_ext);
98 	DP_MON_FILTER_PRINT("ppdu_end_status_done: %d",
99 			    tlv_filter->ppdu_end_status_done);
100 	DP_MON_FILTER_PRINT("ppdu_start_user_info: %d",
101 			    tlv_filter->ppdu_start_user_info);
102 	DP_MON_FILTER_PRINT("header_per_msdu: %d", tlv_filter->header_per_msdu);
103 	DP_MON_FILTER_PRINT("enable_fp: %d", tlv_filter->enable_fp);
104 	DP_MON_FILTER_PRINT("enable_md: %d", tlv_filter->enable_md);
105 	DP_MON_FILTER_PRINT("enable_mo: %d", tlv_filter->enable_mo);
106 	DP_MON_FILTER_PRINT("fp_mgmt_filter: 0x%x", tlv_filter->fp_mgmt_filter);
107 	DP_MON_FILTER_PRINT("mo_mgmt_filter: 0x%x", tlv_filter->mo_mgmt_filter);
108 	DP_MON_FILTER_PRINT("fp_ctrl_filter: 0x%x", tlv_filter->fp_ctrl_filter);
109 	DP_MON_FILTER_PRINT("mo_ctrl_filter: 0x%x", tlv_filter->mo_ctrl_filter);
110 	DP_MON_FILTER_PRINT("fp_data_filter: 0x%x", tlv_filter->fp_data_filter);
111 	DP_MON_FILTER_PRINT("mo_data_filter: 0x%x", tlv_filter->mo_data_filter);
112 	DP_MON_FILTER_PRINT("md_data_filter: 0x%x", tlv_filter->md_data_filter);
113 	DP_MON_FILTER_PRINT("md_mgmt_filter: 0x%x", tlv_filter->md_mgmt_filter);
114 	DP_MON_FILTER_PRINT("md_ctrl_filter: 0x%x", tlv_filter->md_ctrl_filter);
115 #ifdef QCA_UNDECODED_METADATA_SUPPORT
116 	DP_MON_FILTER_PRINT("fp_phy_err: %d", tlv_filter->fp_phy_err);
117 	DP_MON_FILTER_PRINT("fp_phy_err_buf_src: %d",
118 			    tlv_filter->fp_phy_err_buf_src);
119 	DP_MON_FILTER_PRINT("fp_phy_err_buf_dest: %d",
120 			    tlv_filter->fp_phy_err_buf_dest);
121 	DP_MON_FILTER_PRINT("phy_err_mask: 0x%x", tlv_filter->phy_err_mask);
122 	DP_MON_FILTER_PRINT("phy_err_mask_cont: 0x%x",
123 			    tlv_filter->phy_err_mask_cont);
124 #endif
125 	DP_MON_FILTER_PRINT("mon_mac_filter: %d",
126 			    tlv_filter->enable_mon_mac_filter);
127 }
128 
129 #ifdef QCA_UNDECODED_METADATA_SUPPORT
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 	if (mon_filter->tlv_filter.phy_err_filter_valid) {
135 		tlv_filter->fp_phy_err =
136 			mon_filter->tlv_filter.fp_phy_err;
137 		tlv_filter->fp_phy_err_buf_src =
138 			mon_filter->tlv_filter.fp_phy_err_buf_src;
139 		tlv_filter->fp_phy_err_buf_dest =
140 			mon_filter->tlv_filter.fp_phy_err_buf_dest;
141 		tlv_filter->phy_err_mask =
142 			mon_filter->tlv_filter.phy_err_mask;
143 		tlv_filter->phy_err_mask_cont =
144 			mon_filter->tlv_filter.phy_err_mask_cont;
145 		tlv_filter->phy_err_filter_valid =
146 			mon_filter->tlv_filter.phy_err_filter_valid;
147 	}
148 }
149 #else
150 static inline void
151 dp_mon_set_fp_phy_err_filter(struct htt_rx_ring_tlv_filter *tlv_filter,
152 			     struct dp_mon_filter *mon_filter)
153 {
154 }
155 #endif
156 
157 void dp_mon_filter_h2t_setup(struct dp_soc *soc, struct dp_pdev *pdev,
158 			     enum dp_mon_filter_srng_type srng_type,
159 			     struct dp_mon_filter *filter)
160 {
161 	int32_t current_mode = 0;
162 	struct htt_rx_ring_tlv_filter *tlv_filter = &filter->tlv_filter;
163 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
164 
165 	/*
166 	 * Loop through all the modes.
167 	 */
168 	for (current_mode = 0; current_mode < DP_MON_FILTER_MAX_MODE;
169 						current_mode++) {
170 		struct dp_mon_filter *mon_filter =
171 			&mon_pdev->filter[current_mode][srng_type];
172 		uint32_t src_filter = 0, dst_filter = 0;
173 
174 		/*
175 		 * Check if the correct mode is enabled or not.
176 		 */
177 		if (!mon_filter->valid)
178 			continue;
179 
180 		filter->valid = true;
181 
182 		/*
183 		 * Set the super bit fields
184 		 */
185 		src_filter =
186 			DP_MON_FILTER_GET(&mon_filter->tlv_filter, FILTER_TLV);
187 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_TLV);
188 		dst_filter |= src_filter;
189 		DP_MON_FILTER_SET(tlv_filter, FILTER_TLV, dst_filter);
190 
191 		/*
192 		 * Set the filter management filter.
193 		 */
194 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
195 					       FILTER_FP_MGMT);
196 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_MGMT);
197 		dst_filter |= src_filter;
198 		DP_MON_FILTER_SET(tlv_filter, FILTER_FP_MGMT, dst_filter);
199 
200 		/*
201 		 * Set the monitor other management filter.
202 		 */
203 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
204 					       FILTER_MO_MGMT);
205 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_MGMT);
206 		dst_filter |= src_filter;
207 		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_MGMT, dst_filter);
208 
209 		/*
210 		 * Set the filter pass control filter.
211 		 */
212 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
213 					       FILTER_FP_CTRL);
214 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_FP_CTRL);
215 		dst_filter |= src_filter;
216 		DP_MON_FILTER_SET(tlv_filter, FILTER_FP_CTRL, dst_filter);
217 
218 		/*
219 		 * Set the monitor other control filter.
220 		 */
221 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
222 					       FILTER_MO_CTRL);
223 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_CTRL);
224 		dst_filter |= src_filter;
225 		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_CTRL, dst_filter);
226 
227 		/*
228 		 * Set the filter pass data filter.
229 		 */
230 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
231 					       FILTER_FP_DATA);
232 		dst_filter = DP_MON_FILTER_GET(tlv_filter,
233 					       FILTER_FP_DATA);
234 		dst_filter |= src_filter;
235 		DP_MON_FILTER_SET(tlv_filter,
236 				  FILTER_FP_DATA, dst_filter);
237 
238 		/*
239 		 * Set the monitor other data filter.
240 		 */
241 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
242 					       FILTER_MO_DATA);
243 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MO_DATA);
244 		dst_filter |= src_filter;
245 		DP_MON_FILTER_SET(tlv_filter, FILTER_MO_DATA, dst_filter);
246 
247 		/*
248 		 * Set the monitor direct data filter.
249 		 */
250 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
251 					       FILTER_MD_DATA);
252 		dst_filter = DP_MON_FILTER_GET(tlv_filter,
253 					       FILTER_MD_DATA);
254 		dst_filter |= src_filter;
255 		DP_MON_FILTER_SET(tlv_filter,
256 				  FILTER_MD_DATA, dst_filter);
257 
258 		/*
259 		 * Set the monitor direct management filter.
260 		 */
261 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
262 					       FILTER_MD_MGMT);
263 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_MGMT);
264 		dst_filter |= src_filter;
265 		DP_MON_FILTER_SET(tlv_filter, FILTER_MD_MGMT, dst_filter);
266 
267 		/*
268 		 * Set the monitor direct management filter.
269 		 */
270 		src_filter = DP_MON_FILTER_GET(&mon_filter->tlv_filter,
271 					       FILTER_MD_CTRL);
272 		dst_filter = DP_MON_FILTER_GET(tlv_filter, FILTER_MD_CTRL);
273 		dst_filter |= src_filter;
274 		DP_MON_FILTER_SET(tlv_filter, FILTER_MD_CTRL, dst_filter);
275 
276 		dp_mon_set_fp_phy_err_filter(tlv_filter, mon_filter);
277 		tlv_filter->enable_mon_mac_filter =
278 				mon_filter->tlv_filter.enable_mon_mac_filter;
279 		DP_RX_MON_FILTER_SET_RX_HDR_LEN(tlv_filter,
280 						mon_filter->tlv_filter);
281 	}
282 
283 	dp_mon_filter_show_filter(mon_pdev, 0, filter);
284 }
285 
286 /**
287  * dp_mon_skip_filter_config() - Check if filter config need to be skipped
288  * @soc: DP soc context
289  *
290  * Return: true if yes, false if not
291  */
292 static inline
293 bool dp_mon_skip_filter_config(struct dp_soc *soc)
294 {
295 	if (soc->cdp_soc.ol_ops->get_con_mode &&
296 	    soc->cdp_soc.ol_ops->get_con_mode() ==
297 	    QDF_GLOBAL_MISSION_MODE &&
298 	    !(QDF_MONITOR_FLAG_OTHER_BSS & soc->mon_flags))
299 		return true;
300 	else
301 		return false;
302 }
303 
304 QDF_STATUS
305 dp_mon_ht2_rx_ring_cfg(struct dp_soc *soc,
306 		       struct dp_pdev *pdev,
307 		       enum dp_mon_filter_srng_type srng_type,
308 		       struct htt_rx_ring_tlv_filter *tlv_filter)
309 {
310 	int mac_id;
311 	int max_mac_rings = wlan_cfg_get_num_mac_rings(pdev->wlan_cfg_ctx);
312 	QDF_STATUS status = QDF_STATUS_SUCCESS;
313 	uint32_t target_type = hal_get_target_type(soc->hal_soc);
314 
315 	if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF &&
316 	    dp_mon_skip_filter_config(soc)) {
317 		dp_mon_filter_info("skip rxdma_buf filter cfg for lpc mode");
318 		return QDF_STATUS_SUCCESS;
319 	}
320 
321 	/*
322 	 * Overwrite the max_mac_rings for the status rings.
323 	 */
324 	if (srng_type == DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS)
325 		dp_update_num_mac_rings_for_dbs(soc, &max_mac_rings);
326 
327 	dp_mon_filter_info("%pK: srng type %d Max_mac_rings %d ",
328 			   soc, srng_type, max_mac_rings);
329 
330 	/*
331 	 * Loop through all MACs per radio and set the filter to the individual
332 	 * macs. For MCL
333 	 */
334 	for (mac_id = 0; mac_id < max_mac_rings; mac_id++) {
335 		int mac_for_pdev =
336 			dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
337 		int lmac_id = dp_get_lmac_id_for_pdev_id(soc, mac_id, pdev->pdev_id);
338 		int hal_ring_type, ring_buf_size;
339 		hal_ring_handle_t hal_ring_hdl;
340 
341 		switch (srng_type) {
342 		case DP_MON_FILTER_SRNG_TYPE_RXDMA_BUF:
343 			if (target_type == TARGET_TYPE_QCN9160) {
344 				hal_ring_hdl =
345 				soc->rx_refill_buf_ring[lmac_id].hal_srng;
346 				ring_buf_size = RX_MONITOR_BUFFER_SIZE;
347 			} else {
348 				hal_ring_hdl =
349 					pdev->rx_mac_buf_ring[lmac_id].hal_srng;
350 				ring_buf_size = RX_DATA_BUFFER_SIZE;
351 			}
352 			hal_ring_type = RXDMA_BUF;
353 			break;
354 
355 		case DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS:
356 			/*
357 			 * If two back to back HTT msg sending happened in
358 			 * short time, the second HTT msg source SRNG HP
359 			 * writing has chance to fail, this has been confirmed
360 			 * by HST HW.
361 			 * for monitor mode, here is the last HTT msg for sending.
362 			 * if the 2nd HTT msg for monitor status ring sending failed,
363 			 * HW won't provide anything into 2nd monitor status ring.
364 			 * as a WAR, add some delay before 2nd HTT msg start sending,
365 			 * > 2us is required per HST HW, delay 100 us for safe.
366 			 */
367 			if (mac_id)
368 				qdf_udelay(100);
369 
370 			hal_ring_hdl =
371 				soc->rxdma_mon_status_ring[lmac_id].hal_srng;
372 			hal_ring_type = RXDMA_MONITOR_STATUS;
373 			ring_buf_size = RX_MON_STATUS_BUF_SIZE;
374 			break;
375 
376 		case DP_MON_FILTER_SRNG_TYPE_RXDMA_MON_BUF:
377 			hal_ring_hdl =
378 				soc->rxdma_mon_buf_ring[lmac_id].hal_srng;
379 			hal_ring_type = RXDMA_MONITOR_BUF;
380 			ring_buf_size = RX_MONITOR_BUFFER_SIZE;
381 			break;
382 
383 		case DP_MON_FILTER_SRNG_TYPE_RXMON_DEST:
384 			hal_ring_hdl =
385 				soc->rxdma_mon_dst_ring[lmac_id].hal_srng;
386 			hal_ring_type = RXDMA_MONITOR_DST;
387 			ring_buf_size = RX_MONITOR_BUFFER_SIZE;
388 			break;
389 		default:
390 			return QDF_STATUS_E_FAILURE;
391 		}
392 
393 		if (!hal_ring_hdl)
394 			continue;
395 
396 		status = htt_h2t_rx_ring_cfg(soc->htt_handle, mac_for_pdev,
397 					     hal_ring_hdl, hal_ring_type,
398 					     ring_buf_size,
399 					     tlv_filter);
400 		if (status != QDF_STATUS_SUCCESS)
401 			return status;
402 	}
403 
404 	return status;
405 }
406 
407 #ifdef QCA_ENHANCED_STATS_SUPPORT
408 void dp_mon_filter_setup_enhanced_stats(struct dp_pdev *pdev)
409 {
410 	struct dp_mon_ops *mon_ops = NULL;
411 
412 	mon_ops = dp_mon_ops_get(pdev->soc);
413 	if (mon_ops && mon_ops->mon_filter_setup_enhanced_stats)
414 		mon_ops->mon_filter_setup_enhanced_stats(pdev);
415 }
416 
417 void dp_mon_filter_reset_enhanced_stats(struct dp_pdev *pdev)
418 {
419 	struct dp_mon_ops *mon_ops = NULL;
420 
421 	mon_ops = dp_mon_ops_get(pdev->soc);
422 	if (mon_ops && mon_ops->mon_filter_reset_enhanced_stats)
423 		mon_ops->mon_filter_reset_enhanced_stats(pdev);
424 }
425 #endif /* QCA_ENHANCED_STATS_SUPPORT */
426 
427 #ifdef QCA_UNDECODED_METADATA_SUPPORT
428 void dp_mon_filter_setup_undecoded_metadata_mode(struct dp_pdev *pdev)
429 {
430 	struct dp_mon_ops *mon_ops = NULL;
431 
432 	mon_ops = dp_mon_ops_get(pdev->soc);
433 	if (mon_ops && mon_ops->mon_filter_setup_undecoded_metadata_capture)
434 		mon_ops->mon_filter_setup_undecoded_metadata_capture(pdev);
435 }
436 
437 void dp_mon_filter_reset_undecoded_metadata_mode(struct dp_pdev *pdev)
438 {
439 	struct dp_mon_ops *mon_ops = NULL;
440 
441 	mon_ops = dp_mon_ops_get(pdev->soc);
442 	if (mon_ops && mon_ops->mon_filter_reset_undecoded_metadata_capture)
443 		mon_ops->mon_filter_reset_undecoded_metadata_capture(pdev);
444 }
445 #endif /* QCA_UNDECODED_METADATA_SUPPORT */
446 
447 #ifdef QCA_MCOPY_SUPPORT
448 void dp_mon_filter_setup_mcopy_mode(struct dp_pdev *pdev)
449 {
450 	struct dp_mon_ops *mon_ops = NULL;
451 
452 	mon_ops = dp_mon_ops_get(pdev->soc);
453 	if (mon_ops && mon_ops->mon_filter_setup_mcopy_mode)
454 		mon_ops->mon_filter_setup_mcopy_mode(pdev);
455 }
456 
457 void dp_mon_filter_reset_mcopy_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_reset_mcopy_mode)
463 		mon_ops->mon_filter_reset_mcopy_mode(pdev);
464 }
465 #endif /* QCA_MCOPY_SUPPORT */
466 
467 #if defined(ATH_SUPPORT_NAC_RSSI) || defined(ATH_SUPPORT_NAC)
468 void dp_mon_filter_setup_smart_monitor(struct dp_pdev *pdev)
469 {
470 	struct dp_mon_ops *mon_ops = NULL;
471 
472 	mon_ops = dp_mon_ops_get(pdev->soc);
473 	if (mon_ops && mon_ops->mon_filter_setup_smart_monitor)
474 		mon_ops->mon_filter_setup_smart_monitor(pdev);
475 }
476 
477 void dp_mon_filter_reset_smart_monitor(struct dp_pdev *pdev)
478 {
479 	struct dp_mon_ops *mon_ops = NULL;
480 
481 	mon_ops = dp_mon_ops_get(pdev->soc);
482 	if (mon_ops && mon_ops->mon_filter_reset_smart_monitor)
483 		mon_ops->mon_filter_reset_smart_monitor(pdev);
484 }
485 #endif /* ATH_SUPPORT_NAC_RSSI || ATH_SUPPORT_NAC */
486 
487 void dp_mon_filter_set_reset_mon_mac_filter(struct dp_pdev *pdev, bool val)
488 {
489 	struct dp_mon_ops *mon_ops = NULL;
490 
491 	mon_ops = dp_mon_ops_get(pdev->soc);
492 	if (mon_ops && mon_ops->mon_filter_set_reset_mon_mac_filter)
493 		mon_ops->mon_filter_set_reset_mon_mac_filter(pdev, val);
494 }
495 
496 #ifdef WLAN_RX_PKT_CAPTURE_ENH
497 void dp_mon_filter_setup_rx_enh_capture(struct dp_pdev *pdev)
498 {
499 	struct dp_mon_ops *mon_ops = NULL;
500 
501 	mon_ops = dp_mon_ops_get(pdev->soc);
502 	if (mon_ops && mon_ops->mon_filter_setup_rx_enh_capture)
503 		mon_ops->mon_filter_setup_rx_enh_capture(pdev);
504 }
505 
506 void dp_mon_filter_reset_rx_enh_capture(struct dp_pdev *pdev)
507 {
508 	struct dp_mon_ops *mon_ops = NULL;
509 
510 	mon_ops = dp_mon_ops_get(pdev->soc);
511 	if (mon_ops && mon_ops->mon_filter_reset_rx_enh_capture)
512 		mon_ops->mon_filter_reset_rx_enh_capture(pdev);
513 }
514 #endif /* WLAN_RX_PKT_CAPTURE_ENH */
515 
516 void dp_mon_filter_setup_mon_mode(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_mon_mode)
522 		mon_ops->mon_filter_setup_rx_mon_mode(pdev);
523 }
524 
525 void dp_mon_filter_setup_tx_mon_mode(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_setup_tx_mon_mode)
531 		mon_ops->mon_filter_setup_tx_mon_mode(pdev);
532 }
533 
534 void dp_mon_filter_reset_tx_mon_mode(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_reset_tx_mon_mode)
540 		mon_ops->mon_filter_reset_tx_mon_mode(pdev);
541 }
542 
543 void dp_mon_filter_reset_mon_mode(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_mon_mode)
549 		mon_ops->mon_filter_reset_rx_mon_mode(pdev);
550 }
551 
552 #if defined(WLAN_PKT_CAPTURE_RX_2_0) || defined(CONFIG_WORD_BASED_TLV) || \
553 	defined(WLAN_FEATURE_LOCAL_PKT_CAPTURE)
554 void dp_rx_mon_hdr_length_set(uint32_t *msg_word,
555 			      struct htt_rx_ring_tlv_filter *tlv_filter)
556 {
557 	if (!msg_word || !tlv_filter)
558 		return;
559 
560 	HTT_RX_RING_SELECTION_CFG_RX_HDR_LEN_SET(*msg_word,
561 						 tlv_filter->rx_hdr_length);
562 }
563 #else
564 void dp_rx_mon_hdr_length_set(uint32_t *msg_word,
565 			      struct htt_rx_ring_tlv_filter *tlv_filter)
566 {
567 }
568 #endif
569 
570 #ifdef WDI_EVENT_ENABLE
571 void dp_mon_filter_setup_rx_pkt_log_full(struct dp_pdev *pdev)
572 {
573 	struct dp_mon_ops *mon_ops = NULL;
574 
575 	mon_ops = dp_mon_ops_get(pdev->soc);
576 	if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_full)
577 		mon_ops->mon_filter_setup_rx_pkt_log_full(pdev);
578 }
579 
580 void dp_mon_filter_reset_rx_pkt_log_full(struct dp_pdev *pdev)
581 {
582 	struct dp_mon_ops *mon_ops = NULL;
583 
584 	mon_ops = dp_mon_ops_get(pdev->soc);
585 	if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_full)
586 		mon_ops->mon_filter_reset_rx_pkt_log_full(pdev);
587 }
588 
589 void dp_mon_filter_setup_rx_pkt_log_lite(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 && mon_ops->mon_filter_setup_rx_pkt_log_lite)
595 		mon_ops->mon_filter_setup_rx_pkt_log_lite(pdev);
596 }
597 
598 void dp_mon_filter_reset_rx_pkt_log_lite(struct dp_pdev *pdev)
599 {
600 	struct dp_mon_ops *mon_ops = NULL;
601 
602 	mon_ops = dp_mon_ops_get(pdev->soc);
603 	if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_lite)
604 		mon_ops->mon_filter_reset_rx_pkt_log_lite(pdev);
605 }
606 
607 void dp_mon_filter_setup_rx_pkt_log_cbf(struct dp_pdev *pdev)
608 {
609 	struct dp_mon_ops *mon_ops = NULL;
610 
611 	mon_ops = dp_mon_ops_get(pdev->soc);
612 	if (mon_ops && mon_ops->mon_filter_setup_rx_pkt_log_cbf)
613 		mon_ops->mon_filter_setup_rx_pkt_log_cbf(pdev);
614 }
615 
616 void dp_mon_filter_reset_rx_pktlog_cbf(struct dp_pdev *pdev)
617 {
618 	struct dp_mon_ops *mon_ops = NULL;
619 
620 	mon_ops = dp_mon_ops_get(pdev->soc);
621 	if (mon_ops && mon_ops->mon_filter_reset_rx_pkt_log_cbf)
622 		mon_ops->mon_filter_reset_rx_pkt_log_cbf(pdev);
623 }
624 
625 #ifdef BE_PKTLOG_SUPPORT
626 void dp_mon_filter_setup_pktlog_hybrid(struct dp_pdev *pdev)
627 {
628 	struct dp_mon_ops *mon_ops = NULL;
629 
630 	mon_ops = dp_mon_ops_get(pdev->soc);
631 	if (mon_ops && mon_ops->mon_filter_setup_pktlog_hybrid)
632 		mon_ops->mon_filter_setup_pktlog_hybrid(pdev);
633 }
634 
635 void dp_mon_filter_reset_pktlog_hybrid(struct dp_pdev *pdev)
636 {
637 	struct dp_mon_ops *mon_ops = NULL;
638 
639 	mon_ops = dp_mon_ops_get(pdev->soc);
640 	if (mon_ops && mon_ops->mon_filter_reset_pktlog_hybrid)
641 		mon_ops->mon_filter_reset_pktlog_hybrid(pdev);
642 }
643 #endif
644 #endif /* WDI_EVENT_ENABLE */
645 
646 QDF_STATUS dp_mon_filter_update(struct dp_pdev *pdev)
647 {
648 	struct dp_mon_ops *mon_ops = NULL;
649 
650 	mon_ops = dp_mon_ops_get(pdev->soc);
651 	if (!mon_ops) {
652 		dp_mon_filter_err("Rx mon filter update failed ops uninitialized");
653 		return QDF_STATUS_E_FAILURE;
654 	}
655 
656 	if (mon_ops && mon_ops->rx_mon_filter_update)
657 		mon_ops->rx_mon_filter_update(pdev);
658 
659 	return QDF_STATUS_SUCCESS;
660 }
661 
662 QDF_STATUS dp_tx_mon_filter_update(struct dp_pdev *pdev)
663 {
664 	struct dp_mon_ops *mon_ops = NULL;
665 
666 	mon_ops = dp_mon_ops_get(pdev->soc);
667 	if (!mon_ops) {
668 		dp_mon_filter_err("Tx mon filter update failed ops uninitialized");
669 		return QDF_STATUS_E_FAILURE;
670 	}
671 
672 	if (mon_ops && mon_ops->tx_mon_filter_update)
673 		mon_ops->tx_mon_filter_update(pdev);
674 
675 	return QDF_STATUS_SUCCESS;
676 }
677 
678 #ifdef QCA_ENHANCED_STATS_SUPPORT
679 void dp_mon_filters_reset(struct dp_pdev *pdev)
680 {
681 	dp_mon_filter_reset_enhanced_stats(pdev);
682 	dp_mon_filter_reset_mon_mode(pdev);
683 	dp_mon_filter_update(pdev);
684 }
685 #else
686 void dp_mon_filters_reset(struct dp_pdev *pdev)
687 {
688 }
689 #endif
690 
691 void
692 dp_mon_filter_reset_mon_srng(struct dp_soc *soc, struct dp_pdev *pdev,
693 			     enum dp_mon_filter_srng_type mon_srng_type)
694 {
695 	struct htt_rx_ring_tlv_filter tlv_filter = {0};
696 
697 	if (dp_mon_ht2_rx_ring_cfg(soc, pdev, mon_srng_type,
698 				   &tlv_filter) != QDF_STATUS_SUCCESS) {
699 		dp_mon_filter_err("%pK: Monitor destination ring filter setting failed",
700 				  soc);
701 	}
702 }
703 
704 /**
705  * dp_mon_filter_adjust() - adjust the mon filters per target basis
706  * @pdev: DP pdev handle
707  * @filter: DP mon filter
708  *
709  * Return: None
710  */
711 static inline
712 void dp_mon_filter_adjust(struct dp_pdev *pdev, struct dp_mon_filter *filter)
713 {
714 	struct dp_soc *soc = pdev->soc;
715 
716 	switch (hal_get_target_type(soc->hal_soc)) {
717 	case TARGET_TYPE_KIWI:
718 	case TARGET_TYPE_MANGO:
719 	case TARGET_TYPE_PEACH:
720 		filter->tlv_filter.msdu_start = 0;
721 		filter->tlv_filter.mpdu_end = 0;
722 		filter->tlv_filter.packet_header = 0;
723 		filter->tlv_filter.attention = 0;
724 		break;
725 	default:
726 		break;
727 	}
728 }
729 
730 void dp_mon_filter_set_mon_cmn(struct dp_pdev *pdev,
731 			       struct dp_mon_filter *filter)
732 {
733 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
734 
735 	filter->tlv_filter.mpdu_start = 1;
736 	filter->tlv_filter.msdu_start = 1;
737 	filter->tlv_filter.packet = 1;
738 	filter->tlv_filter.msdu_end = 1;
739 	filter->tlv_filter.mpdu_end = 1;
740 	filter->tlv_filter.packet_header = 1;
741 	filter->tlv_filter.attention = 1;
742 	filter->tlv_filter.ppdu_start = 0;
743 	filter->tlv_filter.ppdu_end = 0;
744 	filter->tlv_filter.ppdu_end_user_stats = 0;
745 	filter->tlv_filter.ppdu_end_user_stats_ext = 0;
746 	filter->tlv_filter.ppdu_end_status_done = 0;
747 	filter->tlv_filter.header_per_msdu = 1;
748 	filter->tlv_filter.enable_fp =
749 		(mon_pdev->mon_filter_mode & MON_FILTER_PASS) ? 1 : 0;
750 	filter->tlv_filter.enable_mo =
751 		(mon_pdev->mon_filter_mode & MON_FILTER_OTHER) ? 1 : 0;
752 
753 	filter->tlv_filter.fp_mgmt_filter = mon_pdev->fp_mgmt_filter;
754 	filter->tlv_filter.fp_ctrl_filter = mon_pdev->fp_ctrl_filter;
755 	filter->tlv_filter.fp_data_filter = mon_pdev->fp_data_filter;
756 	filter->tlv_filter.mo_mgmt_filter = mon_pdev->mo_mgmt_filter;
757 	filter->tlv_filter.mo_ctrl_filter = mon_pdev->mo_ctrl_filter;
758 	filter->tlv_filter.mo_data_filter = mon_pdev->mo_data_filter;
759 	filter->tlv_filter.offset_valid = false;
760 	dp_mon_filter_adjust(pdev, filter);
761 }
762 
763 void dp_mon_filter_set_status_cmn(struct dp_mon_pdev *mon_pdev,
764 				  struct dp_mon_filter *filter)
765 {
766 	filter->tlv_filter.mpdu_start = 1;
767 	filter->tlv_filter.msdu_start = 0;
768 	filter->tlv_filter.packet = 0;
769 	filter->tlv_filter.msdu_end = 0;
770 	filter->tlv_filter.mpdu_end = 0;
771 	filter->tlv_filter.attention = 0;
772 	filter->tlv_filter.ppdu_start = 1;
773 	filter->tlv_filter.ppdu_end = 1;
774 	filter->tlv_filter.ppdu_end_user_stats = 1;
775 	filter->tlv_filter.ppdu_end_user_stats_ext = 1;
776 	filter->tlv_filter.ppdu_end_status_done = 1;
777 	filter->tlv_filter.ppdu_start_user_info = 1;
778 	filter->tlv_filter.enable_fp = 1;
779 	filter->tlv_filter.enable_md = 0;
780 	filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ALL;
781 	filter->tlv_filter.fp_ctrl_filter = FILTER_CTRL_ALL;
782 	filter->tlv_filter.fp_data_filter = FILTER_DATA_ALL;
783 	filter->tlv_filter.offset_valid = false;
784 
785 	if (mon_pdev->mon_filter_mode & MON_FILTER_OTHER) {
786 		filter->tlv_filter.enable_mo = 1;
787 		filter->tlv_filter.mo_mgmt_filter = FILTER_MGMT_ALL;
788 		filter->tlv_filter.mo_ctrl_filter = FILTER_CTRL_ALL;
789 		filter->tlv_filter.mo_data_filter = FILTER_DATA_ALL;
790 	} else {
791 		filter->tlv_filter.enable_mo = 0;
792 	}
793 }
794 
795 void dp_mon_filter_set_status_cbf(struct dp_pdev *pdev,
796 				  struct dp_mon_filter *filter)
797 {
798 	filter->tlv_filter.mpdu_start = 1;
799 	filter->tlv_filter.msdu_start = 0;
800 	filter->tlv_filter.packet = 0;
801 	filter->tlv_filter.msdu_end = 0;
802 	filter->tlv_filter.mpdu_end = 0;
803 	filter->tlv_filter.attention = 0;
804 	filter->tlv_filter.ppdu_start = 1;
805 	filter->tlv_filter.ppdu_end = 1;
806 	filter->tlv_filter.ppdu_end_user_stats = 1;
807 	filter->tlv_filter.ppdu_end_user_stats_ext = 1;
808 	filter->tlv_filter.ppdu_end_status_done = 1;
809 	filter->tlv_filter.ppdu_start_user_info = 1;
810 	filter->tlv_filter.enable_fp = 1;
811 	filter->tlv_filter.enable_md = 0;
812 	filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK;
813 	filter->tlv_filter.fp_ctrl_filter = 0;
814 	filter->tlv_filter.fp_data_filter = 0;
815 	filter->tlv_filter.offset_valid = false;
816 	filter->tlv_filter.enable_mo = 0;
817 }
818 
819 void dp_mon_filter_set_cbf_cmn(struct dp_pdev *pdev,
820 			       struct dp_mon_filter *filter)
821 {
822 	filter->tlv_filter.mpdu_start = 1;
823 	filter->tlv_filter.msdu_start = 1;
824 	filter->tlv_filter.packet = 1;
825 	filter->tlv_filter.msdu_end = 1;
826 	filter->tlv_filter.mpdu_end = 1;
827 	filter->tlv_filter.attention = 1;
828 	filter->tlv_filter.ppdu_start = 0;
829 	filter->tlv_filter.ppdu_end =  0;
830 	filter->tlv_filter.ppdu_end_user_stats = 0;
831 	filter->tlv_filter.ppdu_end_user_stats_ext = 0;
832 	filter->tlv_filter.ppdu_end_status_done = 0;
833 	filter->tlv_filter.ppdu_start_user_info = 0;
834 	filter->tlv_filter.enable_fp = 1;
835 	filter->tlv_filter.enable_md = 0;
836 	filter->tlv_filter.fp_mgmt_filter = FILTER_MGMT_ACT_NO_ACK;
837 	filter->tlv_filter.offset_valid = false;
838 	filter->tlv_filter.enable_mo = 0;
839 }
840 
841 void dp_mon_filter_dealloc(struct dp_mon_pdev *mon_pdev)
842 {
843 	enum dp_mon_filter_mode mode;
844 	struct dp_mon_filter **mon_filter = NULL;
845 
846 	if (!mon_pdev) {
847 		dp_mon_filter_err("Monitor pdev Context is null");
848 		return;
849 	}
850 
851 	mon_filter = mon_pdev->filter;
852 
853 	/*
854 	 * Check if the monitor filters are already allocated to the mon_pdev.
855 	 */
856 	if (!mon_filter) {
857 		dp_mon_filter_err("Found NULL memory for the Monitor filter");
858 		return;
859 	}
860 
861 	/*
862 	 * Iterate through the every mode and free the filter object.
863 	 */
864 	for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) {
865 		if (!mon_filter[mode]) {
866 			continue;
867 		}
868 
869 		qdf_mem_free(mon_filter[mode]);
870 		mon_filter[mode] = NULL;
871 	}
872 
873 	qdf_mem_free(mon_filter);
874 	mon_pdev->filter = NULL;
875 }
876 
877 struct dp_mon_filter **dp_mon_filter_alloc(struct dp_mon_pdev *mon_pdev)
878 {
879 	struct dp_mon_filter **mon_filter = NULL;
880 	enum dp_mon_filter_mode mode;
881 
882 	if (!mon_pdev) {
883 		dp_mon_filter_err("pdev Context is null");
884 		return NULL;
885 	}
886 
887 	mon_filter = (struct dp_mon_filter **)qdf_mem_malloc(
888 			(sizeof(struct dp_mon_filter *) *
889 			 DP_MON_FILTER_MAX_MODE));
890 	if (!mon_filter) {
891 		dp_mon_filter_err("Monitor filter mem allocation failed");
892 		return NULL;
893 	}
894 
895 	qdf_mem_zero(mon_filter,
896 		     sizeof(struct dp_mon_filter *) * DP_MON_FILTER_MAX_MODE);
897 
898 	/*
899 	 * Allocate the memory for filters for different srngs for each modes.
900 	 */
901 	for (mode = 0; mode < DP_MON_FILTER_MAX_MODE; mode++) {
902 		mon_filter[mode] = qdf_mem_malloc(sizeof(struct dp_mon_filter) *
903 						  DP_MON_FILTER_SRNG_TYPE_MAX);
904 		/* Assign the mon_filter to the pdev->filter such
905 		 * that the dp_mon_filter_dealloc() can free up the filters. */
906 		if (!mon_filter[mode]) {
907 			mon_pdev->filter = mon_filter;
908 			goto fail;
909 		}
910 	}
911 
912 	return mon_filter;
913 fail:
914 	dp_mon_filter_dealloc(mon_pdev);
915 	return NULL;
916 }
917 
918 #ifdef WLAN_FEATURE_LOCAL_PKT_CAPTURE
919 QDF_STATUS dp_mon_set_local_pkt_capture_running(struct dp_mon_pdev *mon_pdev,
920 						bool val)
921 {
922 	if (!mon_pdev) {
923 		dp_mon_filter_err("Invalid monitor pdev");
924 		return QDF_STATUS_E_FAILURE;
925 	}
926 
927 	mon_pdev->is_local_pkt_capture_running = val;
928 	dp_mon_filter_debug("local_pkt_capture_running is set to %d", val);
929 	return QDF_STATUS_SUCCESS;
930 }
931 
932 bool dp_mon_get_is_local_pkt_capture_running(struct cdp_soc_t *cdp_soc,
933 					     uint8_t pdev_id)
934 {
935 	struct dp_soc *soc = (struct dp_soc *)cdp_soc;
936 	struct dp_pdev *pdev =
937 		dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
938 	struct dp_mon_pdev *mon_pdev;
939 
940 	if (!pdev || !pdev->monitor_pdev) {
941 		dp_mon_filter_err("Invalid pdev_id %u", pdev_id);
942 		return false;
943 	}
944 
945 	mon_pdev = pdev->monitor_pdev;
946 
947 	return mon_pdev->is_local_pkt_capture_running;
948 }
949 
950 static void
951 dp_mon_set_local_pkt_capture_rx_filter(struct dp_pdev *pdev,
952 				       struct cdp_monitor_filter *src_filter)
953 {
954 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
955 	enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE;
956 	enum dp_mon_filter_srng_type srng_type;
957 	struct dp_mon_filter dst_filter = {0};
958 
959 	dst_filter.valid = true;
960 	dp_mon_filter_set_status_cmn(mon_pdev, &dst_filter);
961 
962 	dst_filter.tlv_filter.packet_header = 1;
963 	dst_filter.tlv_filter.header_per_msdu = 1;
964 	dst_filter.tlv_filter.rx_hdr_length = RX_HDR_DMA_LENGTH_256B;
965 	dst_filter.tlv_filter.fp_mgmt_filter = src_filter->fp_mgmt;
966 	dst_filter.tlv_filter.fp_ctrl_filter = src_filter->fp_ctrl;
967 	dst_filter.tlv_filter.fp_data_filter = src_filter->fp_data;
968 	dst_filter.tlv_filter.enable_fp = src_filter->mode;
969 	dst_filter.tlv_filter.enable_md = 0;
970 	dst_filter.tlv_filter.enable_mo = 0;
971 
972 	dp_mon_filter_show_filter(mon_pdev, mode, &dst_filter);
973 
974 	/* Store the above filter */
975 	srng_type = DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
976 	mon_pdev->filter[mode][srng_type] = dst_filter;
977 }
978 
979 static void dp_mon_clear_local_pkt_capture_rx_filter(struct dp_pdev *pdev)
980 {
981 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
982 	enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE;
983 	enum dp_mon_filter_srng_type srng_type =
984 				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
985 	struct dp_mon_filter filter = {0};
986 
987 	mon_pdev->filter[mode][srng_type] = filter;
988 }
989 
990 static void dp_mon_reset_local_pkt_capture_rx_filter(struct dp_pdev *pdev)
991 {
992 	struct dp_mon_pdev *mon_pdev = pdev->monitor_pdev;
993 	enum dp_mon_filter_mode mode = DP_MON_FILTER_MONITOR_MODE;
994 	enum dp_mon_filter_srng_type srng_type =
995 				DP_MON_FILTER_SRNG_TYPE_RXDMA_MONITOR_STATUS;
996 	struct dp_mon_filter filter = {0};
997 
998 	filter.valid = true;
999 	mon_pdev->filter[mode][srng_type] = filter;
1000 	dp_mon_pdev_filter_init(mon_pdev);
1001 }
1002 
1003 QDF_STATUS dp_mon_start_local_pkt_capture(struct cdp_soc_t *cdp_soc,
1004 					  uint8_t pdev_id,
1005 					  struct cdp_monitor_filter *filter)
1006 {
1007 	bool local_pkt_capture_running;
1008 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
1009 	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
1010 	struct dp_mon_pdev *mon_pdev;
1011 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1012 
1013 	if (!pdev) {
1014 		dp_mon_filter_err("pdev Context is null");
1015 		return QDF_STATUS_E_INVAL;
1016 	}
1017 
1018 	mon_pdev = pdev->monitor_pdev;
1019 	local_pkt_capture_running =
1020 		dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id);
1021 	if (local_pkt_capture_running) {
1022 		dp_mon_filter_err("Can't start local pkt capture. Already running");
1023 		return QDF_STATUS_E_ALREADY;
1024 	}
1025 
1026 	mon_pdev->mon_filter_mode = filter->mode;
1027 	mon_pdev->fp_mgmt_filter = filter->fp_mgmt;
1028 	mon_pdev->fp_ctrl_filter = filter->fp_ctrl;
1029 	mon_pdev->fp_data_filter = filter->fp_data;
1030 
1031 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
1032 	dp_mon_set_local_pkt_capture_rx_filter(pdev, filter);
1033 	status = dp_mon_filter_update(pdev);
1034 	if (QDF_IS_STATUS_ERROR(status)) {
1035 		dp_mon_clear_local_pkt_capture_rx_filter(pdev);
1036 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1037 		dp_mon_filter_err("local pkt capture set rx filter failed");
1038 		return status;
1039 	}
1040 
1041 	dp_mon_filter_setup_tx_mon_mode(pdev);
1042 	status = dp_tx_mon_filter_update(pdev);
1043 	if (QDF_IS_STATUS_ERROR(status)) {
1044 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1045 		dp_mon_filter_err("local pkt capture set tx filter failed");
1046 		return status;
1047 	}
1048 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1049 
1050 	dp_mon_filter_debug("local pkt capture tx filter set");
1051 
1052 	dp_mon_set_local_pkt_capture_running(mon_pdev, true);
1053 	return status;
1054 }
1055 
1056 QDF_STATUS dp_mon_stop_local_pkt_capture(struct cdp_soc_t *cdp_soc,
1057 					 uint8_t pdev_id)
1058 {
1059 	bool local_pkt_capture_running;
1060 	struct dp_soc *soc = cdp_soc_t_to_dp_soc(cdp_soc);
1061 	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
1062 	struct dp_mon_pdev *mon_pdev;
1063 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1064 
1065 	if (!pdev) {
1066 		dp_mon_filter_err("pdev Context is null");
1067 		return QDF_STATUS_E_INVAL;
1068 	}
1069 
1070 	mon_pdev = pdev->monitor_pdev;
1071 	local_pkt_capture_running =
1072 			dp_mon_get_is_local_pkt_capture_running(cdp_soc, pdev_id);
1073 	if (!local_pkt_capture_running) {
1074 		dp_mon_filter_err("Local pkt capture is not running");
1075 		return QDF_STATUS_SUCCESS;
1076 	}
1077 
1078 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
1079 	dp_mon_reset_local_pkt_capture_rx_filter(pdev);
1080 	status = dp_mon_filter_update(pdev);
1081 	if (QDF_IS_STATUS_ERROR(status)) {
1082 		dp_mon_filter_err("local pkt capture set rx filter failed");
1083 		qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1084 		return status;
1085 	}
1086 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1087 
1088 	qdf_spin_lock_bh(&mon_pdev->mon_lock);
1089 	dp_mon_filter_reset_tx_mon_mode(pdev);
1090 	dp_tx_mon_filter_update(pdev);
1091 	qdf_spin_unlock_bh(&mon_pdev->mon_lock);
1092 	dp_mon_filter_debug("local pkt capture stopped");
1093 
1094 	dp_mon_set_local_pkt_capture_running(mon_pdev, false);
1095 	return QDF_STATUS_SUCCESS;
1096 }
1097 
1098 #endif /* WLAN_FEATURE_LOCAL_PKT_CAPTURE */
1099