xref: /wlan-dirver/qca-wifi-host-cmn/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <wlan_cfr_ucfg_api.h>
20 #include "cfr_defs_i.h"
21 #include <wlan_cfr_utils_api.h>
22 #include <wlan_cfr_tgt_api.h>
23 #include <wlan_objmgr_peer_obj.h>
24 #include <wlan_objmgr_pdev_obj.h>
25 #include <qdf_module.h>
26 #ifdef WLAN_ENH_CFR_ENABLE
27 #include "cdp_txrx_ctrl.h"
28 #endif
29 
30 #ifdef WLAN_ENH_CFR_ENABLE
31 static bool cfr_is_filter_enabled(struct cfr_rcc_param *rcc_param)
32 {
33 	if (rcc_param->m_directed_ftm ||
34 	    rcc_param->m_all_ftm_ack ||
35 	    rcc_param->m_ndpa_ndp_directed ||
36 	    rcc_param->m_ndpa_ndp_all ||
37 	    rcc_param->m_ta_ra_filter ||
38 	    rcc_param->m_all_packet)
39 		return true;
40 	else
41 		return false;
42 }
43 
44 static bool cfr_is_rcc_enabled(struct pdev_cfr *pa)
45 {
46 	if (pa->is_cfr_rcc_capable &&
47 	    cfr_is_filter_enabled(&pa->rcc_param))
48 		return true;
49 	else
50 		return false;
51 }
52 #else
53 static bool cfr_is_rcc_enabled(struct pdev_cfr *pa)
54 {
55 	return false;
56 }
57 #endif
58 int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
59 			   struct wlan_objmgr_peer *peer,
60 			   struct cfr_capture_params *params)
61 {
62 	int status;
63 	struct pdev_cfr *pa;
64 	struct peer_cfr *pe;
65 	struct wlan_objmgr_psoc *psoc;
66 
67 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
68 	if (NULL == pa) {
69 		cfr_err("PDEV cfr object is NULL!");
70 		return -EINVAL;
71 	}
72 
73 	if (!(pa->is_cfr_capable)) {
74 		cfr_err("cfr is not supported on this chip");
75 		return -EINVAL;
76 	}
77 
78 	/* Get peer private object */
79 	pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
80 	if (NULL == pe) {
81 		cfr_err("PEER cfr object is NULL!");
82 		return -EINVAL;
83 	}
84 
85 	psoc = wlan_pdev_get_psoc(pdev);
86 	if (!psoc) {
87 		cfr_err("psoc is null!");
88 		return -EINVAL;
89 	}
90 
91 	if (!(tgt_cfr_validate_period(psoc, params->period)))
92 		return -EINVAL;
93 
94 	if (!(params->period) && (pa->cfr_timer_enable)) {
95 		cfr_err("Single shot capture is not allowed during periodic capture");
96 		return -EINVAL;
97 	}
98 
99 	if ((params->period) && !(pa->cfr_timer_enable)) {
100 		cfr_err("Global periodic timer is not enabled, configure global cfr timer");
101 	}
102 
103 	if (params->period) {
104 		if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) {
105 			cfr_err("max periodic cfr clients reached");
106 			return -EINVAL;
107 		}
108 		if (!(pe->request))
109 			pa->cfr_current_sta_count++;
110 	}
111 
112 	if (cfr_is_rcc_enabled(pa)) {
113 		cfr_err("This is not allowed since RCC is enabled");
114 		pa->cfr_timer_enable = 0;
115 		return -EINVAL;
116 	}
117 
118 	status = tgt_cfr_start_capture(pdev, peer, params);
119 
120 	if (status == 0) {
121 		pe->bandwidth = params->bandwidth;
122 		pe->period = params->period;
123 		pe->capture_method = params->method;
124 		pe->request = PEER_CFR_CAPTURE_ENABLE;
125 	} else
126 		pa->cfr_current_sta_count--;
127 
128 	return status;
129 }
130 
131 int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev,
132 				     struct qdf_mac_addr *unassoc_mac,
133 				     struct cfr_capture_params *params)
134 {
135 	int idx, idx_to_insert = -1;
136 	struct pdev_cfr *pa;
137 
138 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
139 	if (!pa) {
140 		cfr_err("Pdev cfr object is null!");
141 		return -EINVAL;
142 	}
143 
144 	if (!(pa->is_cfr_capable)) {
145 		cfr_err("CFR is not supported on this chip");
146 		return -EINVAL;
147 	}
148 
149 	if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) {
150 		cfr_err("max cfr cleint reached");
151 		return -EINVAL;
152 	}
153 
154 	for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) {
155 		/* Store first invalid entry's index, to add mac entry if not
156 		 * already present.
157 		 */
158 		if (idx_to_insert < 0) {
159 			if (pa->unassoc_pool[idx].is_valid != true)
160 				idx_to_insert = idx;
161 		}
162 
163 		/* Add new mac entry only if it is not present. If already
164 		 * present, update the capture parameters
165 		 */
166 		if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac,
167 				sizeof(struct qdf_mac_addr)) == 0) {
168 			cfr_info("Node already present. Updating params");
169 			qdf_mem_copy(&pa->unassoc_pool[idx].cfr_params,
170 				     params,
171 				     sizeof(struct cfr_capture_params));
172 			pa->unassoc_pool[idx].is_valid = true;
173 			return 0;
174 		}
175 	}
176 
177 	if (idx_to_insert < 0) {
178 		/* All the entries in the table are valid. So we have reached
179 		 * max client capacity. To add a new client, capture on one of
180 		 * the clients in table has to be stopped.
181 		 */
182 		cfr_err("Maximum client capacity reached");
183 		return -EINVAL;
184 	}
185 
186 	/* If control reaches here, we did not find mac in the table
187 	 * and we have atleast one free entry in table.
188 	 * Add the entry at index = idx_to_insert
189 	 */
190 	qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].mac,
191 		     unassoc_mac, sizeof(struct qdf_mac_addr));
192 	qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].cfr_params,
193 		     params, sizeof(struct cfr_capture_params));
194 	pa->unassoc_pool[idx_to_insert].is_valid = true;
195 	pa->cfr_current_sta_count++;
196 
197 	return 0;
198 }
199 
200 int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev,
201 				    struct qdf_mac_addr *unassoc_mac)
202 {
203 	struct pdev_cfr *pa;
204 	int idx;
205 
206 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
207 	if (!pa) {
208 		cfr_err("Pdev cfr object is NULL!");
209 		return -EINVAL;
210 	}
211 
212 	if (!(pa->is_cfr_capable)) {
213 		cfr_err("CFR is not supported on this chip");
214 		return -EINVAL;
215 	}
216 
217 	for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) {
218 		/* Remove mac only if it is present */
219 		if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac,
220 				sizeof(struct qdf_mac_addr)) == 0) {
221 			qdf_mem_zero(&pa->unassoc_pool[idx],
222 				     sizeof(struct unassoc_pool_entry));
223 			pa->cfr_current_sta_count--;
224 			return 0;
225 		}
226 	}
227 
228 	/* If mac was present in pool it would have been deleted in the
229 	 * above loop and returned from there.
230 	 * If control reached here, mac was not found. So, ignore the request.
231 	 */
232 	cfr_err("Trying to delete mac not present in pool. Ignoring request.");
233 	return 0;
234 }
235 
236 int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value)
237 {
238 	struct pdev_cfr *pa;
239 
240 	if (wlan_cfr_is_feature_disabled(pdev)) {
241 		cfr_err("cfr is disabled");
242 		return QDF_STATUS_E_NOSUPPORT;
243 	}
244 
245 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
246 	if (pa == NULL) {
247 		cfr_err("PDEV cfr object is NULL!");
248 		return -EINVAL;
249 	}
250 
251 	if (!(pa->is_cfr_capable)) {
252 		cfr_err("cfr is not supported on this chip");
253 		return -EINVAL;
254 	}
255 
256 	return tgt_cfr_enable_cfr_timer(pdev, value);
257 }
258 qdf_export_symbol(ucfg_cfr_set_timer);
259 
260 int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev)
261 {
262 	struct pdev_cfr *pa;
263 
264 	if (wlan_cfr_is_feature_disabled(pdev)) {
265 		cfr_err("cfr is disabled");
266 		return QDF_STATUS_E_NOSUPPORT;
267 	}
268 
269 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
270 	if (pa == NULL) {
271 		cfr_err("PDEV cfr object is NULL!");
272 		return -EINVAL;
273 	}
274 
275 	if (!(pa->is_cfr_capable)) {
276 		cfr_err("cfr is not supported on this chip");
277 		return -EINVAL;
278 	}
279 
280 	return pa->cfr_timer_enable;
281 }
282 qdf_export_symbol(ucfg_cfr_get_timer);
283 
284 static void cfr_iter_peer_handler(struct wlan_objmgr_pdev *pdev,
285 				  void *object, void *arg)
286 {
287 	struct wlan_objmgr_peer *peer = (struct wlan_objmgr_peer *)object;
288 	struct peer_cfr *pe;
289 	int *cfr_capt_status = (int *)arg;
290 
291 	if (*cfr_capt_status == PEER_CFR_CAPTURE_ENABLE)
292 		return;
293 
294 	if (!peer || !pdev) {
295 		cfr_err("peer or pdev object is NULL");
296 		return;
297 	}
298 
299 	if (wlan_vdev_get_selfpeer(peer->peer_objmgr.vdev) == peer)
300 		return;
301 
302 	pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
303 	if (!pe) {
304 		cfr_err("PEER cfr object is NULL!");
305 		return;
306 	}
307 
308 	if (pe->period && (pe->request == PEER_CFR_CAPTURE_ENABLE)) {
309 		*cfr_capt_status = pe->request;
310 		cfr_debug("CFR capture running for peer "
311 			  QDF_MAC_ADDR_FMT,
312 			  QDF_MAC_ADDR_REF(peer->macaddr));
313 	}
314 }
315 
316 void ucfg_cfr_get_capture_status(struct wlan_objmgr_pdev *pdev,
317 				 enum cfr_capt_status *status)
318 {
319 	*status = PEER_CFR_CAPTURE_DISABLE;
320 
321 	wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_PEER_OP,
322 					  cfr_iter_peer_handler,
323 					  status, 1, WLAN_CFR_ID);
324 }
325 qdf_export_symbol(ucfg_cfr_get_capture_status);
326 
327 int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
328 			  struct wlan_objmgr_peer *peer)
329 {
330 	int status;
331 	struct peer_cfr *pe;
332 	struct pdev_cfr *pa;
333 
334 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
335 	if (pa == NULL) {
336 		cfr_err("PDEV cfr object is NULL!");
337 		return -EINVAL;
338 	}
339 
340 	if (!(pa->is_cfr_capable)) {
341 		cfr_err("cfr is not supported on this chip");
342 		return -EINVAL;
343 	}
344 
345 	pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
346 	if (pe == NULL) {
347 		cfr_err("PEER cfr object is NULL!");
348 		return -EINVAL;
349 	}
350 
351 	if ((pe->period) && (pe->request))
352 		status = tgt_cfr_stop_capture(pdev, peer);
353 	else {
354 		cfr_err("periodic cfr not started for the client");
355 		return -EINVAL;
356 	}
357 
358 	if (status == 0) {
359 		pe->request = PEER_CFR_CAPTURE_DISABLE;
360 		pa->cfr_current_sta_count--;
361 	}
362 
363 	return status;
364 }
365 
366 int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev)
367 {
368 	return 0;
369 }
370 
371 QDF_STATUS ucfg_cfr_stop_indication(struct wlan_objmgr_vdev *vdev)
372 {
373 	if (!vdev) {
374 		cfr_err("null vdev");
375 		return QDF_STATUS_E_INVAL;
376 	}
377 
378 	return cfr_stop_indication(vdev);
379 }
380 
381 #ifdef WLAN_CFR_ADRASTEA
382 void ucfg_cfr_capture_data(struct wlan_objmgr_psoc *psoc, uint32_t vdev_id,
383 			   struct csi_cfr_header *hdr, uint32_t mem_index)
384 {
385 	struct wlan_objmgr_vdev *vdev;
386 	struct wlan_objmgr_pdev *pdev;
387 	struct pdev_cfr *pcfr;
388 	uint32_t end_magic_num = 0xBEAFDEAD;
389 	void *vaddr, *payload;
390 	u32 *rindex, *windex, payload_len;
391 	QDF_STATUS status = QDF_STATUS_SUCCESS;
392 
393 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
394 						    WLAN_CFR_ID);
395 	if (!vdev) {
396 		cfr_err("vdev is NULL");
397 		return;
398 	}
399 
400 	pdev = wlan_vdev_get_pdev(vdev);
401 	if (!pdev) {
402 		cfr_err("pdev is NULL");
403 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
404 		return;
405 	}
406 
407 	status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID);
408 	if (status != QDF_STATUS_SUCCESS) {
409 		cfr_err("Failed to get pdev reference");
410 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
411 		return;
412 	}
413 
414 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev,
415 						     WLAN_UMAC_COMP_CFR);
416 	if (!pcfr) {
417 		cfr_err("pdev is NULL");
418 		goto exit;
419 	}
420 
421 	if (!pcfr->is_cfr_capable) {
422 		cfr_err("CFR not supported on this chip");
423 		goto exit;
424 	}
425 
426 	hdr->cmn.vendorid               = CFR_VENDOR_ID;
427 	hdr->cmn.cfr_metadata_version   = CFR_META_VERSION_1;
428 	hdr->cmn.cfr_data_version       = CFR_DATA_VERSION_1;
429 	hdr->cmn.chip_type              = CFR_CAPTURE_RADIO_ADRASTEA;
430 	hdr->cmn.pltform_type           = CFR_PLATFORM_TYPE_ARM;
431 	hdr->cmn.cfr_metadata_len       = CFR_META_DATA_LEN;
432 
433 	vaddr = pcfr->cfr_mem_chunk.vaddr;
434 	rindex = (u32 *)vaddr;
435 	windex = rindex + 1;
436 
437 	/*
438 	 * mem_index is having the index of the address where CFR dump wrriten,
439 	 * find data pointer from mem index and start address of memory.
440 	 */
441 	payload = vaddr + mem_index;
442 	payload_len = hdr->u.meta_legacy.length;
443 
444 	/* Write data into streamfs */
445 	tgt_cfr_info_send(pdev, hdr, sizeof(struct csi_cfr_header),
446 			  payload, payload_len, &end_magic_num,
447 			  sizeof(uint32_t));
448 
449 	/*
450 	 * Updating the read index to the number of bytes read by host, it will
451 	 * help in writing next capture.
452 	 * ignoring 4 byte for FW magic number from the actual allocated memory
453 	 * length to avoid corruption in magic number. This memory is circular
454 	 * so after complation of one round, Skipping the first 8 byte as they
455 	 * are for read index and write index.
456 	 */
457 	if (((*rindex) + payload_len) <= (pcfr->cfr_mem_chunk.len - 4))
458 		(*rindex) += payload_len;
459 	else if (((*rindex) + payload_len) > (pcfr->cfr_mem_chunk.len - 4))
460 		(*rindex) = (payload_len + 8);
461 
462 exit:
463 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
464 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
465 }
466 #endif
467 
468 #ifdef WLAN_ENH_CFR_ENABLE
469 
470 static
471 QDF_STATUS dev_sanity_check(struct wlan_objmgr_vdev *vdev,
472 			    struct wlan_objmgr_pdev **ppdev,
473 			    struct pdev_cfr **ppcfr)
474 {
475 	QDF_STATUS status = QDF_STATUS_SUCCESS;
476 
477 	if (!vdev) {
478 		cfr_err("vdev is NULL");
479 		return QDF_STATUS_E_NULL_VALUE;
480 	}
481 
482 	*ppdev = wlan_vdev_get_pdev(vdev);
483 
484 	if (!*ppdev) {
485 		cfr_err("pdev is NULL");
486 		return QDF_STATUS_E_NULL_VALUE;
487 	}
488 
489 	status = wlan_objmgr_pdev_try_get_ref(*ppdev, WLAN_CFR_ID);
490 	if (status != QDF_STATUS_SUCCESS) {
491 		cfr_err("Failed to get pdev reference");
492 		return status;
493 	}
494 
495 	*ppcfr = wlan_objmgr_pdev_get_comp_private_obj(*ppdev,
496 						     WLAN_UMAC_COMP_CFR);
497 
498 	if (!(*ppcfr)) {
499 		cfr_err("pdev object for CFR is null");
500 		wlan_objmgr_pdev_release_ref(*ppdev, WLAN_CFR_ID);
501 		return QDF_STATUS_E_NULL_VALUE;
502 	}
503 
504 	if (!(*ppcfr)->is_cfr_rcc_capable) {
505 		cfr_err("cfr is not supported on this chip");
506 		wlan_objmgr_pdev_release_ref(*ppdev, WLAN_CFR_ID);
507 		return QDF_STATUS_E_NOSUPPORT;
508 	}
509 
510 	return status;
511 }
512 
513 /*
514  * This is needed only in case of m_ta_ra_filter mode.
515  * If user wants to reset the group configurations to default values,
516  * then this handler will come into action.
517  *
518  * If user wants to reset the configurations of 0th, 1st and 3rd group,
519  * then the input should be :
520  *
521  *               wlanconfig ath0 cfr reset_cfg 0xb
522  *
523  */
524 
525 QDF_STATUS ucfg_cfr_set_reset_bitmap(struct wlan_objmgr_vdev *vdev,
526 				     struct cfr_wlanconfig_param *params)
527 {
528 	struct pdev_cfr *pcfr = NULL;
529 	struct wlan_objmgr_pdev *pdev = NULL;
530 	QDF_STATUS status = QDF_STATUS_SUCCESS;
531 
532 	status = dev_sanity_check(vdev, &pdev, &pcfr);
533 	if (status != QDF_STATUS_SUCCESS)
534 		return status;
535 
536 	pcfr->rcc_param.modified_in_curr_session |= params->reset_cfg;
537 	tgt_cfr_default_ta_ra_cfg(pdev, &pcfr->rcc_param,
538 				  true, params->reset_cfg);
539 
540 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
541 
542 	return status;
543 }
544 
545 #ifdef WLAN_ENH_CFR_ENABLE
546 /*
547  * This is needed only in case of m_ta_ra_filter mode.
548  * After providing all the group configurations, user should provide
549  * the information about which groups need to be enabled.
550  * Based on that FW will enable the configurations for CFR groups.
551  * If user has to enable only 0th group, then input should be :
552  *
553  *               wlanconfig ath0 cfr en_cfg 0x1
554  *
555  * Enable the bitmap from user provided configuration into cfr_rcc_param.
556  */
557 
558 QDF_STATUS ucfg_cfr_set_en_bitmap(struct wlan_objmgr_vdev *vdev,
559 				  struct cfr_wlanconfig_param *params)
560 {
561 	struct pdev_cfr *pcfr = NULL;
562 	struct wlan_objmgr_pdev *pdev = NULL;
563 	QDF_STATUS status = QDF_STATUS_SUCCESS;
564 
565 	status = dev_sanity_check(vdev, &pdev, &pcfr);
566 	if (status != QDF_STATUS_SUCCESS)
567 		return status;
568 
569 	pcfr->rcc_param.filter_group_bitmap = params->en_cfg;
570 
571 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
572 
573 	return status;
574 }
575 #endif
576 
577 /*
578  * Copy user provided input for ul_mu_user_mask into cfr_rcc_param.
579  */
580 
581 QDF_STATUS
582 ucfg_cfr_set_ul_mu_user_mask(struct wlan_objmgr_vdev *vdev,
583 			     struct cfr_wlanconfig_param *params)
584 {
585 	struct pdev_cfr *pcfr = NULL;
586 	struct wlan_objmgr_pdev *pdev = NULL;
587 	QDF_STATUS status = QDF_STATUS_SUCCESS;
588 
589 	status = dev_sanity_check(vdev, &pdev, &pcfr);
590 	if (status != QDF_STATUS_SUCCESS)
591 		return status;
592 
593 	pcfr->rcc_param.ul_mu_user_mask_lower = params->ul_mu_user_mask_lower;
594 	pcfr->rcc_param.ul_mu_user_mask_upper = params->ul_mu_user_mask_upper;
595 
596 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
597 
598 	return status;
599 }
600 
601 /*
602  * FREEZE_TLV_DELAY_CNT_* registers are used for FREEZE TLV timeout mechanism
603  * in MAC side. In case MAC send FREEZE TLV to PHY too late due to
604  * long AST delay, PHY ucode may not handle it well or it will impact
605  * next frame’s normal processing, then MAC needs to drop FREEZE TLV
606  * sending process after reaching the threshold.
607  *
608  * This handler will copy user provided input for freeze_tlv_delay_cnt
609  * into cfr_rcc_param.
610  */
611 
612 QDF_STATUS
613 ucfg_cfr_set_freeze_tlv_delay_cnt(struct wlan_objmgr_vdev *vdev,
614 				  struct cfr_wlanconfig_param *params)
615 {
616 	struct pdev_cfr *pcfr = NULL;
617 	struct wlan_objmgr_pdev *pdev = NULL;
618 	QDF_STATUS status = QDF_STATUS_SUCCESS;
619 
620 	status = dev_sanity_check(vdev, &pdev, &pcfr);
621 	if (status != QDF_STATUS_SUCCESS)
622 		return status;
623 
624 	pcfr->rcc_param.freeze_tlv_delay_cnt_en =
625 		params->freeze_tlv_delay_cnt_en;
626 
627 	pcfr->rcc_param.freeze_tlv_delay_cnt_thr =
628 		params->freeze_tlv_delay_cnt_thr;
629 
630 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
631 
632 	return status;
633 }
634 
635 /*
636  * Configure ta_ra_filter_in_as_fp from the provided configuration into
637  * cfr_rcc_param. All fixed parameters needed to be stored into cfr_rcc_param.
638  */
639 QDF_STATUS
640 ucfg_cfr_set_tara_filterin_as_fp(struct wlan_objmgr_vdev *vdev,
641 				 struct cfr_wlanconfig_param *params)
642 {
643 	struct pdev_cfr *pcfr = NULL;
644 	struct wlan_objmgr_pdev *pdev = NULL;
645 	QDF_STATUS status = QDF_STATUS_SUCCESS;
646 
647 	status = dev_sanity_check(vdev, &pdev, &pcfr);
648 	if (status != QDF_STATUS_SUCCESS)
649 		return status;
650 
651 	if (!pcfr->is_mo_marking_support) {
652 		cfr_err("MO marking support not available to filter as FP/MO");
653 		status = QDF_STATUS_E_NOSUPPORT;
654 	} else {
655 		pcfr->rcc_param.en_ta_ra_filter_in_as_fp =
656 			params->en_ta_ra_filter_in_as_fp;
657 	}
658 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
659 
660 	return status;
661 }
662 
663 /*
664  * Set the capture count from the provided configuration into cfr_rcc_param.
665  * All fixed parameters are needed to be stored into cfr_rcc_param.
666  */
667 QDF_STATUS
668 ucfg_cfr_set_capture_count(struct wlan_objmgr_vdev *vdev,
669 			   struct cfr_wlanconfig_param *params)
670 {
671 	struct pdev_cfr *pcfr = NULL;
672 	struct wlan_objmgr_pdev *pdev = NULL;
673 	QDF_STATUS status = QDF_STATUS_SUCCESS;
674 
675 	status = dev_sanity_check(vdev, &pdev, &pcfr);
676 	if (status != QDF_STATUS_SUCCESS)
677 		return status;
678 
679 	if (!pcfr->is_cap_interval_mode_sel_support) {
680 		cfr_err("Capture count support not enabled");
681 		status = QDF_STATUS_E_NOSUPPORT;
682 	} else {
683 		pcfr->rcc_param.capture_count = params->cap_count;
684 	}
685 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
686 
687 	return status;
688 }
689 
690 /*
691  * Set interval mode sel nob from the provided configuration into cfr_rcc_param.
692  * All fixed parameters are needed to be stored into cfr_rcc_param
693  */
694 QDF_STATUS
695 ucfg_cfr_set_capture_interval_mode_sel(struct wlan_objmgr_vdev *vdev,
696 				       struct cfr_wlanconfig_param *params)
697 {
698 	struct pdev_cfr *pcfr = NULL;
699 	struct wlan_objmgr_pdev *pdev = NULL;
700 	QDF_STATUS status = QDF_STATUS_SUCCESS;
701 
702 	status = dev_sanity_check(vdev, &pdev, &pcfr);
703 	if (status != QDF_STATUS_SUCCESS)
704 		return status;
705 
706 	if (!pcfr->is_cap_interval_mode_sel_support) {
707 		cfr_err("Capture count support not enabled");
708 		status = QDF_STATUS_E_NOSUPPORT;
709 	} else {
710 		pcfr->rcc_param.capture_intval_mode_sel =
711 			params->cap_intval_mode_sel;
712 	}
713 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
714 
715 	return status;
716 }
717 
718 /*
719  * Set capture interval from the provided configuration into cfr_rcc_param.
720  * All fixed parameters are needed to be stored into cfr_rcc_param.
721  */
722 
723 QDF_STATUS
724 ucfg_cfr_set_capture_interval(struct wlan_objmgr_vdev *vdev,
725 			      struct cfr_wlanconfig_param *params)
726 {
727 	struct pdev_cfr *pcfr = NULL;
728 	struct wlan_objmgr_pdev *pdev = NULL;
729 	QDF_STATUS status = QDF_STATUS_SUCCESS;
730 
731 	status = dev_sanity_check(vdev, &pdev, &pcfr);
732 	if (status != QDF_STATUS_SUCCESS)
733 		return status;
734 
735 	if (pcfr->rcc_param.capture_duration > params->cap_intvl) {
736 		cfr_err("Capture interval should be more than capture duration");
737 		status = QDF_STATUS_E_INVAL;
738 	} else {
739 		pcfr->rcc_param.capture_interval = params->cap_intvl;
740 	}
741 
742 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
743 
744 	return status;
745 }
746 
747 /*
748  * Set capture duration from the provided configuration into cfr_rcc_param.
749  * All fixed parameters are needed to be stored into cfr_rcc_param.
750  */
751 
752 QDF_STATUS
753 ucfg_cfr_set_capture_duration(struct wlan_objmgr_vdev *vdev,
754 			      struct cfr_wlanconfig_param *params)
755 {
756 	struct pdev_cfr *pcfr = NULL;
757 	struct wlan_objmgr_pdev *pdev = NULL;
758 	QDF_STATUS status = QDF_STATUS_SUCCESS;
759 
760 	status = dev_sanity_check(vdev, &pdev, &pcfr);
761 	if (status != QDF_STATUS_SUCCESS)
762 		return status;
763 
764 	if (pcfr->rcc_param.capture_interval &&
765 	    (params->cap_dur > pcfr->rcc_param.capture_interval)) {
766 		cfr_err("Capture duration is exceeding capture interval");
767 		status = QDF_STATUS_E_INVAL;
768 	} else {
769 		pcfr->rcc_param.capture_duration = params->cap_dur;
770 	}
771 
772 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
773 
774 	return status;
775 }
776 
777 /*
778  * Copy user provided group parameters( type/ subtype of mgmt, ctrl, data )
779  * into curr_cfg instance of ta_ra_cfr_cfg.
780  * Set valid mask for the provided configuration.
781  * Set modified_in_curr_session for the particular group.
782  */
783 
784 QDF_STATUS
785 ucfg_cfr_set_frame_type_subtype(struct wlan_objmgr_vdev *vdev,
786 				struct cfr_wlanconfig_param *params)
787 {
788 	struct pdev_cfr *pcfr = NULL;
789 	struct wlan_objmgr_pdev *pdev = NULL;
790 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
791 	QDF_STATUS status = QDF_STATUS_SUCCESS;
792 
793 	status = dev_sanity_check(vdev, &pdev, &pcfr);
794 	if (status != QDF_STATUS_SUCCESS)
795 		return status;
796 
797 	/* Populating current config based on user's input */
798 	curr_cfg = &pcfr->rcc_param.curr[params->grp_id];
799 	curr_cfg->mgmt_subtype_filter = params->expected_mgmt_subtype;
800 	curr_cfg->ctrl_subtype_filter = params->expected_ctrl_subtype;
801 	curr_cfg->data_subtype_filter = params->expected_data_subtype;
802 
803 	curr_cfg->valid_mgmt_subtype = 1;
804 	curr_cfg->valid_ctrl_subtype = 1;
805 	curr_cfg->valid_data_subtype = 1;
806 
807 	qdf_set_bit(params->grp_id,
808 		    &pcfr->rcc_param.modified_in_curr_session);
809 
810 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
811 
812 	return status;
813 }
814 
815 /*
816  * Copy user provided group parameters( BW and NSS )
817  * into curr_cfg instance of ta_ra_cfr_cfg.
818  * Set valid mask for the provided configuration.
819  * Set modified_in_curr_session for the particular group.
820  */
821 
822 QDF_STATUS ucfg_cfr_set_bw_nss(struct wlan_objmgr_vdev *vdev,
823 			       struct cfr_wlanconfig_param *params)
824 {
825 	struct pdev_cfr *pcfr = NULL;
826 	struct wlan_objmgr_pdev *pdev = NULL;
827 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
828 	QDF_STATUS status = QDF_STATUS_SUCCESS;
829 
830 	status = dev_sanity_check(vdev, &pdev, &pcfr);
831 	if (status != QDF_STATUS_SUCCESS)
832 		return status;
833 
834 	/* Populating current config based on user's input */
835 	curr_cfg = &pcfr->rcc_param.curr[params->grp_id];
836 	curr_cfg->bw = params->bw;
837 	curr_cfg->nss = params->nss;
838 
839 	curr_cfg->valid_bw_mask = 1;
840 	curr_cfg->valid_nss_mask = 1;
841 
842 	qdf_set_bit(params->grp_id,
843 		    &pcfr->rcc_param.modified_in_curr_session);
844 
845 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
846 
847 	return status;
848 }
849 
850 /*
851  * Copy user provided group parameters( TA, RA, TA_MASK, RA_MASK )
852  * into curr_cfg instance of ta_ra_cfr_cfg.
853  * Set valid mask for the provided configuration.
854  * Set modified_in_curr_session for the particular group.
855  */
856 
857 QDF_STATUS ucfg_cfr_set_tara_config(struct wlan_objmgr_vdev *vdev,
858 				    struct cfr_wlanconfig_param *params)
859 {
860 	struct pdev_cfr *pcfr = NULL;
861 	struct wlan_objmgr_pdev *pdev = NULL;
862 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
863 	QDF_STATUS status = QDF_STATUS_SUCCESS;
864 
865 	status = dev_sanity_check(vdev, &pdev, &pcfr);
866 	if (status != QDF_STATUS_SUCCESS)
867 		return status;
868 
869 	curr_cfg = &pcfr->rcc_param.curr[params->grp_id];
870 	qdf_mem_copy(curr_cfg->tx_addr, params->ta, QDF_MAC_ADDR_SIZE);
871 	qdf_mem_copy(curr_cfg->rx_addr, params->ra, QDF_MAC_ADDR_SIZE);
872 	qdf_mem_copy(curr_cfg->tx_addr_mask,
873 		     params->ta_mask, QDF_MAC_ADDR_SIZE);
874 	qdf_mem_copy(curr_cfg->rx_addr_mask,
875 		     params->ra_mask, QDF_MAC_ADDR_SIZE);
876 
877 	curr_cfg->valid_ta = 1;
878 	curr_cfg->valid_ta_mask = 1;
879 	curr_cfg->valid_ra = 1;
880 	curr_cfg->valid_ra_mask = 1;
881 
882 	qdf_set_bit(params->grp_id,
883 		    &pcfr->rcc_param.modified_in_curr_session);
884 
885 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
886 
887 	return status;
888 }
889 
890 QDF_STATUS ucfg_cfr_get_cfg(struct wlan_objmgr_vdev *vdev)
891 {
892 	struct pdev_cfr *pcfr = NULL;
893 	struct wlan_objmgr_pdev *pdev = NULL;
894 	struct ta_ra_cfr_cfg *glbl_cfg = NULL;
895 	QDF_STATUS status = QDF_STATUS_SUCCESS;
896 	uint8_t grp_id;
897 
898 	status = dev_sanity_check(vdev, &pdev, &pcfr);
899 	if (status != QDF_STATUS_SUCCESS)
900 		return status;
901 	if (!cfr_is_filter_enabled(&pcfr->rcc_param)) {
902 		cfr_err(" All RCC modes are disabled");
903 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
904 		return status;
905 	}
906 
907 	cfr_err("CAPTURE MODE:\n");
908 
909 	cfr_err("m_directed_ftm is : %s\n",
910 		pcfr->rcc_param.m_directed_ftm ?
911 		"enabled" : "disabled");
912 	cfr_err("m_all_ftm_ack is : %s\n",
913 		pcfr->rcc_param.m_all_ftm_ack ?
914 		"enabled" : "disabled");
915 	cfr_err("m_ndpa_ndp_directed is: %s\n",
916 		pcfr->rcc_param.m_ndpa_ndp_directed ?
917 		"enabled" : "disabled");
918 	cfr_err("m_ndpa_ndp_all is : %s\n",
919 		pcfr->rcc_param.m_ndpa_ndp_all ?
920 		"enabled" : "disabled");
921 	cfr_err("m_ta_ra_filter is : %s\n",
922 		pcfr->rcc_param.m_ta_ra_filter ?
923 		"enabled" : "disabled");
924 	cfr_err("m_all_packet is : %s\n",
925 		pcfr->rcc_param.m_all_packet ?
926 		"enabled" : "disabled");
927 
928 	cfr_err("capture duration : %u usec\n",
929 		pcfr->rcc_param.capture_duration);
930 	cfr_err("capture interval : %u usec\n",
931 		pcfr->rcc_param.capture_interval);
932 	cfr_err("capture count : %u\n",
933 		pcfr->rcc_param.capture_count);
934 	cfr_err("capture interval mode sel : %u\n",
935 		pcfr->rcc_param.capture_intval_mode_sel);
936 	cfr_err("UL MU User mask lower : %u\n",
937 		pcfr->rcc_param.ul_mu_user_mask_lower);
938 	cfr_err("UL MU User mask upper : %u\n",
939 		pcfr->rcc_param.ul_mu_user_mask_upper);
940 	cfr_err("Freeze TLV delay count is : %s\n",
941 		pcfr->rcc_param.freeze_tlv_delay_cnt_en ?
942 		"enabled" : "disabled");
943 	cfr_err("Freeze TLV delay count threshold : %u\n",
944 		pcfr->rcc_param.freeze_tlv_delay_cnt_thr);
945 	cfr_err("Enabled CFG id bitmap : 0x%x\n",
946 		pcfr->rcc_param.filter_group_bitmap);
947 	cfr_err(" Modified cfg id bitmap : %lu\n",
948 		pcfr->rcc_param.modified_in_curr_session);
949 
950 	cfr_err("TARA_CONFIG details:\n");
951 
952 	for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
953 		glbl_cfg = &pcfr->global[grp_id];
954 
955 		cfr_err("Config ID: %d\n", grp_id);
956 		cfr_err("Bandwidth :0x%x\n", glbl_cfg->bw);
957 		cfr_err("NSS : 0x%x\n", glbl_cfg->nss);
958 		cfr_err("valid_ta: %d\n", glbl_cfg->valid_ta);
959 		cfr_err("valid_ta_mask: %d\n", glbl_cfg->valid_ta_mask);
960 		cfr_err("valid_ra: %d\n", glbl_cfg->valid_ra);
961 		cfr_err("valid_ra_mask: %d\n", glbl_cfg->valid_ra_mask);
962 		cfr_err("valid_bw_mask: %d\n", glbl_cfg->valid_bw_mask);
963 		cfr_err("valid_nss_mask: %d\n", glbl_cfg->valid_nss_mask);
964 		cfr_err("valid_mgmt_subtype: %d\n",
965 			glbl_cfg->valid_mgmt_subtype);
966 		cfr_err("valid_ctrl_subtype: %d\n",
967 			glbl_cfg->valid_ctrl_subtype);
968 		cfr_err("valid_data_subtype: %d\n",
969 			glbl_cfg->valid_data_subtype);
970 		cfr_err("Mgmt subtype : 0x%x\n",
971 			glbl_cfg->mgmt_subtype_filter);
972 		cfr_err("CTRL subtype : 0x%x\n",
973 			glbl_cfg->ctrl_subtype_filter);
974 		cfr_err("Data subtype : 0x%x\n",
975 			glbl_cfg->data_subtype_filter);
976 		cfr_err("TX Addr: " QDF_MAC_ADDR_FMT,
977 			QDF_MAC_ADDR_REF(glbl_cfg->tx_addr));
978 		cfr_err("TX Addr Mask: " QDF_FULL_MAC_FMT,
979 			QDF_FULL_MAC_REF(glbl_cfg->tx_addr_mask));
980 		cfr_err("RX Addr: " QDF_MAC_ADDR_FMT,
981 			QDF_MAC_ADDR_REF(glbl_cfg->rx_addr));
982 		cfr_err("RX Addr Mask: " QDF_FULL_MAC_FMT,
983 			QDF_FULL_MAC_REF(glbl_cfg->rx_addr_mask));
984 	}
985 
986 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
987 
988 	return status;
989 }
990 
991 static const char *chan_capture_status_to_str(enum chan_capture_status type)
992 {
993 	switch (type) {
994 	case CAPTURE_IDLE:
995 		return "CAPTURE_IDLE";
996 	case CAPTURE_BUSY:
997 		return "CAPTURE_BUSY";
998 	case CAPTURE_ACTIVE:
999 		return "CAPTURE_ACTIVE";
1000 	case CAPTURE_NO_BUFFER:
1001 		return "CAPTURE_NO_BUFFER";
1002 	default:
1003 		return "INVALID";
1004 	}
1005 }
1006 
1007 static const
1008 char *mac_freeze_reason_to_str(enum mac_freeze_capture_reason type)
1009 {
1010 	switch (type) {
1011 	case FREEZE_REASON_TM:
1012 		return "FREEZE_REASON_TM";
1013 	case FREEZE_REASON_FTM:
1014 		return "FREEZE_REASON_FTM";
1015 	case FREEZE_REASON_ACK_RESP_TO_TM_FTM:
1016 		return "FREEZE_REASON_ACK_RESP_TO_TM_FTM";
1017 	case FREEZE_REASON_TA_RA_TYPE_FILTER:
1018 		return "FREEZE_REASON_TA_RA_TYPE_FILTER";
1019 	case FREEZE_REASON_NDPA_NDP:
1020 		return "FREEZE_REASON_NDPA_NDP";
1021 	case FREEZE_REASON_ALL_PACKET:
1022 		return "FREEZE_REASON_ALL_PACKET";
1023 	default:
1024 		return "INVALID";
1025 	}
1026 }
1027 
1028 QDF_STATUS ucfg_cfr_rcc_dump_dbg_counters(struct wlan_objmgr_vdev *vdev)
1029 {
1030 	struct pdev_cfr *pcfr = NULL;
1031 	struct wlan_objmgr_pdev *pdev = NULL;
1032 	struct wlan_objmgr_psoc *psoc = NULL;
1033 	struct cdp_cfr_rcc_stats *cfr_rcc_stats = NULL;
1034 	uint8_t stats_cnt;
1035 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1036 
1037 	status = dev_sanity_check(vdev, &pdev, &pcfr);
1038 	if (status != QDF_STATUS_SUCCESS)
1039 		return status;
1040 
1041 	psoc = wlan_pdev_get_psoc(pdev);
1042 	if (!psoc) {
1043 		cfr_err("psoc is null!");
1044 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1045 		return QDF_STATUS_E_NULL_VALUE;
1046 	}
1047 
1048 	cfr_err("total_tx_evt_cnt = %llu\n",
1049 		pcfr->total_tx_evt_cnt);
1050 	cfr_err("dbr_evt_cnt = %llu\n",
1051 		pcfr->dbr_evt_cnt);
1052 	cfr_err("rx_tlv_evt_cnt = %llu\n",
1053 		pcfr->rx_tlv_evt_cnt);
1054 	cfr_err("release_cnt = %llu\n",
1055 		pcfr->release_cnt);
1056 	cfr_err("Error cnt:\n");
1057 	cfr_err("flush_dbr_cnt = %llu\n",
1058 		pcfr->flush_dbr_cnt);
1059 	cfr_err("invalid_dma_length_cnt = %llu\n",
1060 		pcfr->invalid_dma_length_cnt);
1061 	cfr_err("flush_timeout_dbr_cnt = %llu\n",
1062 		pcfr->flush_timeout_dbr_cnt);
1063 	cfr_err("tx_peer_status_cfr_fail = %llu\n",
1064 		pcfr->tx_peer_status_cfr_fail);
1065 	cfr_err("tx_evt_status_cfr_fail = %llu\n",
1066 		pcfr->tx_evt_status_cfr_fail);
1067 	cfr_err("tx_dbr_cookie_lookup_fail = %llu\n",
1068 		pcfr->tx_dbr_cookie_lookup_fail);
1069 	cfr_err("PPDU id mismatch for same cookie:\n");
1070 	cfr_err("clear_txrx_event = %llu\n",
1071 		pcfr->clear_txrx_event);
1072 	cfr_err("cfr_dma_aborts = %llu\n",
1073 		pcfr->cfr_dma_aborts);
1074 
1075 	cfr_rcc_stats = qdf_mem_malloc(sizeof(struct cdp_cfr_rcc_stats));
1076 	if (!cfr_rcc_stats) {
1077 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1078 		return QDF_STATUS_E_NOMEM;
1079 	}
1080 
1081 	cdp_get_cfr_dbg_stats(wlan_psoc_get_dp_handle(psoc),
1082 			      wlan_objmgr_pdev_get_pdev_id(pdev),
1083 			      cfr_rcc_stats);
1084 
1085 	cfr_err("bb_captured_channel_cnt: %llu\n",
1086 		cfr_rcc_stats->bb_captured_channel_cnt);
1087 	cfr_err("bb_captured_timeout_cnt: %llu\n",
1088 		cfr_rcc_stats->bb_captured_timeout_cnt);
1089 	cfr_err("rx_loc_info_valid_cnt: %llu\n",
1090 		cfr_rcc_stats->rx_loc_info_valid_cnt);
1091 
1092 	cfr_err("Channel capture status:\n");
1093 	for (stats_cnt = 0; stats_cnt < CAPTURE_MAX; stats_cnt++) {
1094 		cfr_err("%s = %llu\n",
1095 			chan_capture_status_to_str(stats_cnt),
1096 			cfr_rcc_stats->chan_capture_status[stats_cnt]);
1097 	}
1098 
1099 	cfr_err("Freeze reason:\n");
1100 	for (stats_cnt = 0; stats_cnt < FREEZE_REASON_MAX; stats_cnt++) {
1101 		cfr_err("%s = %llu\n",
1102 			mac_freeze_reason_to_str(stats_cnt),
1103 			cfr_rcc_stats->reason_cnt[stats_cnt]);
1104 	}
1105 
1106 	qdf_mem_free(cfr_rcc_stats);
1107 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1108 
1109 	return status;
1110 }
1111 
1112 QDF_STATUS ucfg_cfr_rcc_clr_dbg_counters(struct wlan_objmgr_vdev *vdev)
1113 {
1114 	struct pdev_cfr *pcfr = NULL;
1115 	struct wlan_objmgr_pdev *pdev = NULL;
1116 	struct wlan_objmgr_psoc *psoc = NULL;
1117 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1118 
1119 	status = dev_sanity_check(vdev, &pdev, &pcfr);
1120 	if (status != QDF_STATUS_SUCCESS)
1121 		return status;
1122 
1123 	psoc = wlan_pdev_get_psoc(pdev);
1124 	if (!psoc) {
1125 		cfr_err("psoc is null!");
1126 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1127 		return QDF_STATUS_E_NULL_VALUE;
1128 	}
1129 	cdp_cfr_clr_dbg_stats(wlan_psoc_get_dp_handle(psoc),
1130 			      wlan_objmgr_pdev_get_pdev_id(pdev));
1131 
1132 	pcfr->dbr_evt_cnt = 0;
1133 	pcfr->release_cnt = 0;
1134 	pcfr->total_tx_evt_cnt = 0;
1135 	pcfr->rx_tlv_evt_cnt = 0;
1136 	pcfr->flush_dbr_cnt = 0;
1137 	pcfr->flush_timeout_dbr_cnt = 0;
1138 	pcfr->invalid_dma_length_cnt = 0;
1139 	pcfr->clear_txrx_event = 0;
1140 	pcfr->cfr_dma_aborts = 0;
1141 	pcfr->tx_peer_status_cfr_fail = 0;
1142 	pcfr->tx_evt_status_cfr_fail = 0;
1143 	pcfr->tx_dbr_cookie_lookup_fail = 0;
1144 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1145 
1146 	return status;
1147 }
1148 
1149 QDF_STATUS ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev *vdev)
1150 {
1151 	struct wlan_objmgr_pdev *pdev = NULL;
1152 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1153 
1154 	if (!vdev) {
1155 		cfr_err("vdev is NULL");
1156 		return QDF_STATUS_E_INVAL;
1157 	}
1158 
1159 	pdev = wlan_vdev_get_pdev(vdev);
1160 	if (!pdev) {
1161 		cfr_err("pdev is NULL");
1162 		return QDF_STATUS_E_INVAL;
1163 	}
1164 
1165 	if (wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID) !=
1166 	    QDF_STATUS_SUCCESS) {
1167 		return QDF_STATUS_E_INVAL;
1168 	}
1169 
1170 	cfr_err("LUT table:");
1171 	tgt_cfr_dump_lut_enh(pdev);
1172 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1173 
1174 	return status;
1175 }
1176 
1177 static void cfr_set_filter(struct wlan_objmgr_pdev *pdev, bool enable,
1178 			   struct cdp_monitor_filter *filter_val)
1179 {
1180 	struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
1181 
1182 	cfr_info("pdev_id=%d\n", wlan_objmgr_pdev_get_pdev_id(pdev));
1183 
1184 	cdp_cfr_filter(wlan_psoc_get_dp_handle(psoc),
1185 		       wlan_objmgr_pdev_get_pdev_id(pdev),
1186 		       enable,
1187 		       filter_val);
1188 }
1189 
1190 #ifdef WLAN_ENH_CFR_ENABLE
1191 /*
1192  * With the initiation of commit command, this handler will be triggered.
1193  *
1194  * Starts the procedure of forming the TLVs.
1195  * If Host succeeds to send WMI command to FW, after TLV processing, then it
1196  * will save the previous CFR configurations into one instance ta_ra_cfr_cfg,
1197  * called glbl_cfg and update the current config to default state for the
1198  * next commit session.
1199  *
1200  * Finally, reset the counter (modified_in_curr_session) to 0 before moving to
1201  * next commit session.
1202  *
1203  */
1204 
1205 QDF_STATUS ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev *vdev)
1206 {
1207 	struct pdev_cfr *pcfr = NULL;
1208 	struct wlan_objmgr_pdev *pdev = NULL;
1209 	struct wlan_objmgr_psoc *psoc = NULL;
1210 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1211 	struct cdp_monitor_filter filter_val = {0};
1212 
1213 	status = dev_sanity_check(vdev, &pdev, &pcfr);
1214 	if (status != QDF_STATUS_SUCCESS)
1215 		return status;
1216 
1217 	psoc = wlan_pdev_get_psoc(pdev);
1218 
1219 	if (!psoc) {
1220 		cfr_err("psoc is null!");
1221 		wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1222 		return QDF_STATUS_E_NULL_VALUE;
1223 	}
1224 
1225 	pcfr->rcc_param.vdev_id = wlan_vdev_get_id(vdev);
1226 
1227 	/*
1228 	 * If capture mode is valid, then Host:
1229 	 * Subscribes for PPDU status TLVs in monitor status ring.
1230 	 * Sets filter type to either FP or MO, based on the capture mode.
1231 	 * Starts the LUT_AGE_TIMER of 1sec.
1232 	 *
1233 	 * If capture mode is disabled, then Host:
1234 	 * unsubscribes for PPDU status TLVs in monitor status ring.
1235 	 * Sets filter type to 0.
1236 	 * Stops the LUT_AGE_TIMER.
1237 	 *
1238 	 */
1239 
1240 	if (cfr_is_filter_enabled(&pcfr->rcc_param)) {
1241 		if (pcfr->cfr_timer_enable) {
1242 			cfr_err("Not allowed: Periodic capture is enabled.\n");
1243 			wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1244 			return QDF_STATUS_E_NOSUPPORT;
1245 		}
1246 
1247 		if (pcfr->rcc_param.m_all_ftm_ack) {
1248 			filter_val.mode |= MON_FILTER_PASS |
1249 					   MON_FILTER_OTHER;
1250 			filter_val.fp_mgmt |= FILTER_MGMT_ACTION;
1251 			filter_val.mo_mgmt |= FILTER_MGMT_ACTION;
1252 		}
1253 
1254 		if (pcfr->rcc_param.m_ndpa_ndp_all) {
1255 			filter_val.mode |= MON_FILTER_PASS |
1256 					   MON_FILTER_OTHER;
1257 			filter_val.fp_ctrl |= FILTER_CTRL_VHT_NDP;
1258 			filter_val.mo_ctrl |= FILTER_CTRL_VHT_NDP;
1259 		}
1260 
1261 		if (pcfr->rcc_param.m_all_packet) {
1262 			filter_val.mode |= MON_FILTER_PASS |
1263 					   MON_FILTER_OTHER;
1264 			filter_val.fp_mgmt |= FILTER_MGMT_ALL;
1265 			filter_val.mo_mgmt |= FILTER_MGMT_ALL;
1266 			filter_val.fp_ctrl |= FILTER_CTRL_ALL;
1267 			filter_val.mo_ctrl |= FILTER_CTRL_ALL;
1268 			filter_val.fp_data |= FILTER_DATA_ALL;
1269 			filter_val.mo_data |= FILTER_DATA_ALL;
1270 		}
1271 
1272 		/*
1273 		 * M_TA_RA in monitor other is as intensive as M_ALL pkt
1274 		 * Support only FP in M_TA_RA mode
1275 		 */
1276 		if (pcfr->rcc_param.m_ta_ra_filter) {
1277 			filter_val.mode |= MON_FILTER_PASS |
1278 					   MON_FILTER_OTHER;
1279 			filter_val.fp_mgmt |= FILTER_MGMT_ALL;
1280 			filter_val.mo_mgmt |= FILTER_MGMT_ALL;
1281 			filter_val.fp_ctrl |= FILTER_CTRL_ALL;
1282 			filter_val.mo_ctrl |= FILTER_CTRL_ALL;
1283 			filter_val.fp_data |= FILTER_DATA_ALL;
1284 			filter_val.mo_data |= FILTER_DATA_ALL;
1285 		}
1286 
1287 		if (pcfr->rcc_param.m_directed_ftm) {
1288 			filter_val.mode |= MON_FILTER_PASS;
1289 			filter_val.fp_mgmt |= FILTER_MGMT_ACTION;
1290 		}
1291 
1292 		if (pcfr->rcc_param.m_ndpa_ndp_directed) {
1293 			filter_val.mode |= MON_FILTER_PASS;
1294 			filter_val.fp_ctrl |= FILTER_CTRL_VHT_NDP;
1295 		}
1296 
1297 		if (!cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc),
1298 				    wlan_objmgr_pdev_get_pdev_id(pdev)))
1299 			tgt_cfr_start_lut_age_timer(pdev);
1300 		cfr_set_filter(pdev, 1, &filter_val);
1301 	} else {
1302 		if (cdp_get_cfr_rcc(wlan_psoc_get_dp_handle(psoc),
1303 				    wlan_objmgr_pdev_get_pdev_id(pdev)))
1304 			tgt_cfr_stop_lut_age_timer(pdev);
1305 		cfr_set_filter(pdev, 0, &filter_val);
1306 	}
1307 
1308 	/* Trigger wmi to start the TLV processing. */
1309 	status = tgt_cfr_config_rcc(pdev, &pcfr->rcc_param);
1310 	if (status == QDF_STATUS_SUCCESS) {
1311 		cfr_info("CFR commit done\n");
1312 		/* Update global config */
1313 		tgt_cfr_update_global_cfg(pdev);
1314 
1315 		/* Bring curr_cfg to default state for next commit session */
1316 		tgt_cfr_default_ta_ra_cfg(pdev, &pcfr->rcc_param,
1317 					  false, MAX_RESET_CFG_ENTRY);
1318 	} else {
1319 		cfr_err("CFR commit failed");
1320 	}
1321 
1322 	pcfr->rcc_param.num_grp_tlvs = 0;
1323 	pcfr->rcc_param.modified_in_curr_session = 0;
1324 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1325 
1326 	return status;
1327 }
1328 
1329 #ifdef WLAN_CFR_PM
1330 QDF_STATUS ucfg_cfr_suspend(struct wlan_objmgr_pdev *pdev)
1331 {
1332 	struct pdev_cfr *pcfr;
1333 
1334 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
1335 				pdev, WLAN_UMAC_COMP_CFR);
1336 
1337 	if (!pcfr) {
1338 		cfr_err("null pcfr");
1339 		return QDF_STATUS_E_INVAL;
1340 	}
1341 
1342 	return cfr_allow_suspend(pcfr);
1343 }
1344 
1345 QDF_STATUS ucfg_cfr_resume(struct wlan_objmgr_pdev *pdev)
1346 {
1347 	struct pdev_cfr *pcfr;
1348 
1349 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
1350 				pdev, WLAN_UMAC_COMP_CFR);
1351 
1352 	if (!pcfr) {
1353 		cfr_err("null pcfr");
1354 		return QDF_STATUS_E_INVAL;
1355 	}
1356 
1357 	return cfr_prevent_suspend(pcfr);
1358 }
1359 #endif
1360 /*
1361  * This handler is used to enable / disable the capture mode.
1362  *
1363  */
1364 QDF_STATUS ucfg_cfr_set_rcc_mode(struct wlan_objmgr_vdev *vdev,
1365 				 enum capture_type mode, uint8_t value)
1366 {
1367 	struct pdev_cfr *pcfr = NULL;
1368 	struct wlan_objmgr_pdev *pdev = NULL;
1369 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1370 
1371 	status = dev_sanity_check(vdev, &pdev, &pcfr);
1372 	if (status != QDF_STATUS_SUCCESS)
1373 		return status;
1374 
1375 	switch (mode) {
1376 	case RCC_DIRECTED_FTM_FILTER:
1377 		pcfr->rcc_param.m_directed_ftm = value;
1378 		break;
1379 	case RCC_ALL_FTM_ACK_FILTER:
1380 		pcfr->rcc_param.m_all_ftm_ack = value;
1381 		break;
1382 	case RCC_DIRECTED_NDPA_NDP_FILTER:
1383 		pcfr->rcc_param.m_ndpa_ndp_directed = value;
1384 		break;
1385 	case RCC_NDPA_NDP_ALL_FILTER:
1386 		pcfr->rcc_param.m_ndpa_ndp_all = value;
1387 		break;
1388 	case RCC_TA_RA_FILTER:
1389 		pcfr->rcc_param.m_ta_ra_filter = value;
1390 		break;
1391 	case RCC_ALL_PACKET_FILTER:
1392 		pcfr->rcc_param.m_all_packet = value;
1393 		break;
1394 	case RCC_DIS_ALL_MODE:
1395 		pcfr->rcc_param.m_directed_ftm = value;
1396 		pcfr->rcc_param.m_all_ftm_ack = value;
1397 		pcfr->rcc_param.m_ndpa_ndp_directed = value;
1398 		pcfr->rcc_param.m_ndpa_ndp_all = value;
1399 		pcfr->rcc_param.m_ta_ra_filter = value;
1400 		pcfr->rcc_param.m_all_packet = value;
1401 		break;
1402 
1403 	default:
1404 		break;
1405 	}
1406 
1407 	cfr_debug("<CFR_UMAC> Capture mode set by user: 0x%x\n", value);
1408 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1409 
1410 	return status;
1411 }
1412 #endif
1413 
1414 bool ucfg_cfr_get_rcc_enabled(struct wlan_objmgr_vdev *vdev)
1415 {
1416 	struct pdev_cfr *pcfr = NULL;
1417 	struct wlan_objmgr_pdev *pdev = NULL;
1418 	QDF_STATUS status = QDF_STATUS_SUCCESS;
1419 	bool rcc_enabled = false;
1420 
1421 	status = dev_sanity_check(vdev, &pdev, &pcfr);
1422 	if (status != QDF_STATUS_SUCCESS)
1423 		return false;
1424 
1425 	rcc_enabled = cfr_is_filter_enabled(&pcfr->rcc_param);
1426 	wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1427 
1428 	return rcc_enabled;
1429 }
1430 
1431 #ifdef WLAN_ENH_CFR_ENABLE
1432 QDF_STATUS ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
1433 					bool is_subscribe)
1434 {
1435 	return tgt_cfr_subscribe_ppdu_desc(pdev, is_subscribe);
1436 }
1437 #endif
1438 #endif
1439