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