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