1 /*
2 * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2022-2023 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
cfr_is_filter_enabled(struct cfr_rcc_param * rcc_param)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
cfr_is_rcc_enabled(struct pdev_cfr * pa)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
cfr_is_rcc_enabled(struct pdev_cfr * pa)54 static bool cfr_is_rcc_enabled(struct pdev_cfr *pa)
55 {
56 return false;
57 }
58 #endif
ucfg_cfr_start_capture(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_peer * peer,struct cfr_capture_params * params)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
ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * unassoc_mac,struct cfr_capture_params * params)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
ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev * pdev,struct qdf_mac_addr * unassoc_mac)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
ucfg_cfr_set_timer(struct wlan_objmgr_pdev * pdev,uint32_t value)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
ucfg_cfr_get_timer(struct wlan_objmgr_pdev * pdev)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
cfr_iter_peer_handler(struct wlan_objmgr_pdev * pdev,void * object,void * arg)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
ucfg_cfr_get_capture_status(struct wlan_objmgr_pdev * pdev,enum cfr_capt_status * status)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
ucfg_cfr_stop_capture(struct wlan_objmgr_pdev * pdev,struct wlan_objmgr_peer * peer)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
ucfg_cfr_list_peers(struct wlan_objmgr_pdev * pdev)367 int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev)
368 {
369 return 0;
370 }
371
ucfg_cfr_stop_indication(struct wlan_objmgr_vdev * vdev)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
ucfg_cfr_capture_data(struct wlan_objmgr_psoc * psoc,uint32_t vdev_id,struct csi_cfr_header * hdr,uint32_t mem_index)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
dev_sanity_check(struct wlan_objmgr_vdev * vdev,struct wlan_objmgr_pdev ** ppdev,struct pdev_cfr ** ppcfr)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
ucfg_cfr_set_reset_bitmap(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_en_bitmap(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_ul_mu_user_mask(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_freeze_tlv_delay_cnt(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_tara_filterin_as_fp(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_capture_count(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_capture_interval_mode_sel(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_capture_interval(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_capture_duration(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_frame_type_subtype(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_bw_nss(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_set_tara_config(struct wlan_objmgr_vdev * vdev,struct cfr_wlanconfig_param * params)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
ucfg_cfr_get_cfg(struct wlan_objmgr_vdev * vdev)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_MAC_ADDR_FMT,
1001 QDF_MAC_ADDR_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_MAC_ADDR_FMT,
1005 QDF_MAC_ADDR_REF(glbl_cfg->rx_addr_mask));
1006 }
1007
1008 wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID);
1009
1010 return status;
1011 }
1012
chan_capture_status_to_str(enum chan_capture_status type)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
mac_freeze_reason_to_str(enum mac_freeze_capture_reason type)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
ucfg_cfr_rcc_dump_dbg_counters(struct wlan_objmgr_vdev * vdev)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
ucfg_cfr_rcc_clr_dbg_counters(struct wlan_objmgr_vdev * vdev)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
ucfg_cfr_rcc_dump_lut(struct wlan_objmgr_vdev * vdev)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
cfr_set_filter(struct wlan_objmgr_pdev * pdev,bool enable,struct cdp_monitor_filter * filter_val,bool cfr_enable_monitor_mode)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
ucfg_cfr_committed_rcc_config(struct wlan_objmgr_vdev * vdev)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
ucfg_cfr_suspend(struct wlan_objmgr_pdev * pdev)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
ucfg_cfr_resume(struct wlan_objmgr_pdev * pdev)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 */
ucfg_cfr_set_rcc_mode(struct wlan_objmgr_vdev * vdev,enum capture_type mode,uint8_t value)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
ucfg_cfr_get_rcc_enabled(struct wlan_objmgr_vdev * vdev)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
ucfg_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev * pdev,bool is_subscribe)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