xref: /wlan-dirver/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr.c (revision a86b23ee68a2491aede2e03991f3fb37046f4e41)
1 /*
2  * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <target_if_cfr.h>
20 #include <wlan_tgt_def_config.h>
21 #include <target_type.h>
22 #include <hif_hw_version.h>
23 #include <target_if.h>
24 #include <wlan_lmac_if_def.h>
25 #include <wlan_osif_priv.h>
26 #include <init_deinit_lmac.h>
27 #include <wlan_cfr_utils_api.h>
28 #include <wlan_objmgr_pdev_obj.h>
29 #include <target_if_cfr_6018.h>
30 #ifdef CFR_USE_FIXED_FOLDER
31 #include "target_if_cfr_6490.h"
32 #include "wlan_reg_services_api.h"
33 #else
34 #include <target_if_cfr_8074v2.h>
35 #endif
36 
37 int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev,
38 			       struct wlan_objmgr_peer *peer)
39 {
40 	struct peer_cfr *pe;
41 	struct peer_cfr_params param = {0};
42 	struct wmi_unified *pdev_wmi_handle = NULL;
43 	struct wlan_objmgr_vdev *vdev = {0};
44 	struct pdev_cfr *pdev_cfrobj;
45 	int retv = 0;
46 
47 	pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR);
48 	if (pe == NULL)
49 		return -EINVAL;
50 
51 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
52 	if (!pdev_wmi_handle) {
53 		cfr_err("pdev wmi handle NULL");
54 		return -EINVAL;
55 	}
56 	vdev = wlan_peer_get_vdev(peer);
57 
58 	qdf_mem_set(&param, sizeof(param), 0);
59 
60 	param.request = PEER_CFR_CAPTURE_DISABLE;
61 	param.macaddr = wlan_peer_get_macaddr(peer);
62 	param.vdev_id = wlan_vdev_get_id(vdev);
63 
64 	param.periodicity = pe->period;
65 	param.bandwidth = pe->bandwidth;
66 	param.capture_method = pe->capture_method;
67 
68 	retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, &param);
69 
70 	pdev_cfrobj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
71 							    WLAN_UMAC_COMP_CFR);
72 	if (!pdev_cfrobj) {
73 		cfr_err("pdev object for CFR is null");
74 		return -EINVAL;
75 	}
76 	cfr_err("CFR capture stats for this capture:");
77 	cfr_err("DBR event count = %llu, Tx event count = %llu "
78 		"Release count = %llu",
79 		pdev_cfrobj->dbr_evt_cnt, pdev_cfrobj->tx_evt_cnt,
80 		pdev_cfrobj->release_cnt);
81 
82 	pdev_cfrobj->dbr_evt_cnt = 0;
83 	pdev_cfrobj->tx_evt_cnt  = 0;
84 	pdev_cfrobj->release_cnt = 0;
85 	pdev_cfrobj->tx_peer_status_cfr_fail = 0;
86 	pdev_cfrobj->tx_evt_status_cfr_fail = 0;
87 	pdev_cfrobj->tx_dbr_cookie_lookup_fail = 0;
88 
89 	return retv;
90 }
91 
92 int target_if_cfr_start_capture(struct wlan_objmgr_pdev *pdev,
93 				struct wlan_objmgr_peer *peer,
94 				struct cfr_capture_params *cfr_params)
95 {
96 	struct peer_cfr_params param = {0};
97 	struct wmi_unified *pdev_wmi_handle = NULL;
98 	struct wlan_objmgr_vdev *vdev;
99 	int retv = 0;
100 
101 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
102 	if (!pdev_wmi_handle) {
103 		cfr_err("pdev wmi handle NULL");
104 		return -EINVAL;
105 	}
106 	vdev = wlan_peer_get_vdev(peer);
107 	qdf_mem_set(&param, sizeof(param), 0);
108 
109 	param.request = PEER_CFR_CAPTURE_ENABLE;
110 	param.macaddr = wlan_peer_get_macaddr(peer);
111 	param.vdev_id = wlan_vdev_get_id(vdev);
112 
113 	param.periodicity = cfr_params->period;
114 	param.bandwidth = cfr_params->bandwidth;
115 	param.capture_method = cfr_params->method;
116 
117 	retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, &param);
118 	return retv;
119 }
120 
121 int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev,
122 				 uint32_t param_id, uint32_t param_value)
123 {
124 	struct pdev_params pparam;
125 	uint32_t pdev_id;
126 	struct wmi_unified *pdev_wmi_handle = NULL;
127 
128 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
129 	if (pdev_id < 0)
130 		return -EINVAL;
131 
132 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
133 	if (!pdev_wmi_handle) {
134 		cfr_err("pdev wmi handle NULL");
135 		return -EINVAL;
136 	}
137 	qdf_mem_set(&pparam, sizeof(pparam), 0);
138 	pparam.param_id = param_id;
139 	pparam.param_value = param_value;
140 
141 	return wmi_unified_pdev_param_send(pdev_wmi_handle,
142 					   &pparam, pdev_id);
143 }
144 
145 int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev,
146 				   uint32_t cfr_timer)
147 {
148 	struct pdev_cfr *pa;
149 	int retval;
150 
151 	pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
152 	if (pa == NULL)
153 		return QDF_STATUS_E_FAILURE;
154 
155 	if (!cfr_timer) {
156 	     /* disable periodic cfr capture */
157 		retval =
158 	target_if_cfr_pdev_set_param(pdev,
159 				     wmi_pdev_param_per_peer_prd_cfr_enable,
160 				     WMI_HOST_PEER_CFR_TIMER_DISABLE);
161 
162 		if (retval == QDF_STATUS_SUCCESS)
163 			pa->cfr_timer_enable = 0;
164 	} else {
165 	    /* enable periodic cfr capture (default base timer is 10ms ) */
166 		retval =
167 	target_if_cfr_pdev_set_param(pdev,
168 				     wmi_pdev_param_per_peer_prd_cfr_enable,
169 				     WMI_HOST_PEER_CFR_TIMER_ENABLE);
170 
171 		if (retval == QDF_STATUS_SUCCESS)
172 			pa->cfr_timer_enable = 1;
173 	}
174 
175 	return retval;
176 }
177 
178 int target_if_cfr_get_target_type(struct wlan_objmgr_psoc *psoc)
179 {
180 	uint32_t target_type = 0;
181 	struct wlan_lmac_if_target_tx_ops *target_type_tx_ops;
182 	struct wlan_lmac_if_tx_ops *tx_ops;
183 
184 	tx_ops = wlan_psoc_get_lmac_if_txops(psoc);
185 	if (!tx_ops) {
186 		cfr_err("tx_ops is NULL");
187 		return target_type;
188 	}
189 	target_type_tx_ops = &tx_ops->target_tx_ops;
190 
191 	if (target_type_tx_ops->tgt_get_tgt_type)
192 		target_type = target_type_tx_ops->tgt_get_tgt_type(psoc);
193 
194 	return target_type;
195 }
196 
197 #ifdef CFR_USE_FIXED_FOLDER
198 int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc,
199 			    struct wlan_objmgr_pdev *pdev)
200 {
201 	uint32_t target_type;
202 	QDF_STATUS status;
203 
204 	target_type = target_if_cfr_get_target_type(psoc);
205 
206 	if (target_type == TARGET_TYPE_QCA6490) {
207 		status = cfr_6490_init_pdev(psoc, pdev);
208 	} else {
209 		cfr_info("unsupport chip");
210 		status = QDF_STATUS_SUCCESS;
211 	}
212 
213 	return qdf_status_to_os_return(status);
214 }
215 
216 int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc,
217 			      struct wlan_objmgr_pdev *pdev)
218 {
219 	uint32_t target_type;
220 	QDF_STATUS status;
221 
222 	target_type = target_if_cfr_get_target_type(psoc);
223 
224 	if (target_type == TARGET_TYPE_QCA6490) {
225 		status = cfr_6490_deinit_pdev(psoc, pdev);
226 	} else {
227 		cfr_info("unsupport chip");
228 		status = QDF_STATUS_SUCCESS;
229 	}
230 
231 	return qdf_status_to_os_return(status);
232 }
233 #else
234 int target_if_cfr_init_pdev(struct wlan_objmgr_psoc *psoc,
235 			    struct wlan_objmgr_pdev *pdev)
236 {
237 	uint32_t target_type;
238 	struct pdev_cfr *pa;
239 	struct psoc_cfr *cfr_sc;
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 		return QDF_STATUS_E_FAILURE;
249 
250 	/* Reset unassociated entries for every init */
251 	qdf_mem_zero(&pa->unassoc_pool[0], MAX_CFR_ENABLED_CLIENTS *
252 		     sizeof(struct unassoc_pool_entry));
253 
254 	cfr_sc = wlan_objmgr_psoc_get_comp_private_obj(psoc,
255 						       WLAN_UMAC_COMP_CFR);
256 
257 	if (cfr_sc == NULL)
258 		return QDF_STATUS_E_FAILURE;
259 
260 	target_type = target_if_cfr_get_target_type(psoc);
261 
262 	if (target_type == TARGET_TYPE_QCA8074V2) {
263 		pa->is_cfr_capable = cfr_sc->is_cfr_capable;
264 		return cfr_8074v2_init_pdev(psoc, pdev);
265 	} else if ((target_type == TARGET_TYPE_IPQ4019) ||
266 		   (target_type == TARGET_TYPE_QCA9984) ||
267 		   (target_type == TARGET_TYPE_QCA9888)) {
268 
269 		pa->is_cfr_capable = cfr_sc->is_cfr_capable;
270 
271 		return cfr_wifi2_0_init_pdev(psoc, pdev);
272 	} else if ((target_type == TARGET_TYPE_QCA6018) ||
273 		   (target_type == TARGET_TYPE_QCN9000)) {
274 		pa->is_cfr_capable = cfr_sc->is_cfr_capable;
275 		return cfr_6018_init_pdev(psoc, pdev);
276 	} else
277 		return QDF_STATUS_E_NOSUPPORT;
278 }
279 
280 int target_if_cfr_deinit_pdev(struct wlan_objmgr_psoc *psoc,
281 			      struct wlan_objmgr_pdev *pdev)
282 {
283 	uint32_t target_type;
284 
285 	if (wlan_cfr_is_feature_disabled(pdev)) {
286 		cfr_err("cfr is disabled");
287 		return QDF_STATUS_E_NOSUPPORT;
288 	}
289 
290 	target_type = target_if_cfr_get_target_type(psoc);
291 
292 	if (target_type == TARGET_TYPE_QCA8074V2) {
293 		return cfr_8074v2_deinit_pdev(psoc, pdev);
294 	} else if ((target_type == TARGET_TYPE_IPQ4019) ||
295 		   (target_type == TARGET_TYPE_QCA9984) ||
296 		   (target_type == TARGET_TYPE_QCA9888)) {
297 
298 		return cfr_wifi2_0_deinit_pdev(psoc, pdev);
299 	} else if ((target_type == TARGET_TYPE_QCA6018) ||
300 		   (target_type == TARGET_TYPE_QCN9000)) {
301 		return cfr_6018_deinit_pdev(psoc, pdev);
302 	} else
303 		return QDF_STATUS_E_NOSUPPORT;
304 }
305 #endif
306 
307 #ifdef WLAN_ENH_CFR_ENABLE
308 #ifdef QCA_WIFI_QCA6490
309 static uint8_t target_if_cfr_get_mac_id(struct wlan_objmgr_pdev *pdev)
310 {
311 	struct wlan_objmgr_vdev *vdev;
312 	struct wlan_channel *bss_chan;
313 	struct pdev_cfr *pcfr;
314 	uint8_t mac_id = 0;
315 
316 	if (!pdev) {
317 		cfr_err("null pdev");
318 		return mac_id;
319 	}
320 
321 	mac_id = wlan_objmgr_pdev_get_pdev_id(pdev);
322 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR);
323 	if (!pcfr)  {
324 		cfr_err("null pcfr");
325 		return mac_id;
326 	}
327 
328 	if (pcfr->rcc_param.vdev_id == CFR_INVALID_VDEV_ID)
329 		return mac_id;
330 
331 	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev,
332 						    pcfr->rcc_param.vdev_id,
333 						    WLAN_CFR_ID);
334 	if (!vdev) {
335 		cfr_err("null vdev");
336 		return mac_id;
337 	}
338 
339 	bss_chan = wlan_vdev_mlme_get_bss_chan(vdev);
340 	if (!bss_chan) {
341 		cfr_info("null bss chan");
342 		wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
343 		return mac_id;
344 	}
345 
346 	cfr_debug("bss freq %d", bss_chan->ch_freq);
347 	if (wlan_reg_is_24ghz_ch_freq(bss_chan->ch_freq))
348 		mac_id = CFR_MAC_ID_24G;
349 	else
350 		mac_id = CFR_MAC_ID_5G;
351 
352 	pcfr->rcc_param.srng_id = mac_id;
353 	wlan_objmgr_vdev_release_ref(vdev, WLAN_CFR_ID);
354 
355 	return mac_id;
356 }
357 
358 static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev)
359 {
360 	return target_if_cfr_get_mac_id(pdev);
361 }
362 #else
363 static uint8_t target_if_cfr_get_pdev_id(struct wlan_objmgr_pdev *pdev)
364 {
365 	return wlan_objmgr_pdev_get_pdev_id(pdev);
366 }
367 #endif /* QCA_WIFI_QCA6490 */
368 
369 QDF_STATUS target_if_cfr_config_rcc(struct wlan_objmgr_pdev *pdev,
370 				    struct cfr_rcc_param *rcc_info)
371 {
372 	QDF_STATUS status;
373 	struct wmi_unified *pdev_wmi_handle = NULL;
374 
375 	pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev);
376 	if (!pdev_wmi_handle) {
377 		cfr_err("pdev_wmi_handle is null");
378 		return QDF_STATUS_E_NULL_VALUE;
379 	}
380 
381 	rcc_info->pdev_id = target_if_cfr_get_pdev_id(pdev);
382 	rcc_info->num_grp_tlvs =
383 		count_set_bits(rcc_info->modified_in_curr_session);
384 
385 	status = wmi_unified_send_cfr_rcc_cmd(pdev_wmi_handle, rcc_info);
386 	return status;
387 }
388 
389 void target_if_cfr_default_ta_ra_config(struct cfr_rcc_param *rcc_info,
390 					bool allvalid, uint16_t reset_cfg)
391 {
392 	struct ta_ra_cfr_cfg *curr_cfg = NULL;
393 	int grp_id;
394 	unsigned long bitmap = reset_cfg;
395 	uint8_t def_mac[QDF_MAC_ADDR_SIZE] = {0xFF, 0xFF, 0xFF,
396 		0xFF, 0xFF, 0xFF};
397 	uint8_t null_mac[QDF_MAC_ADDR_SIZE] = {0x00, 0x00, 0x00,
398 		0x00, 0x00, 0x00};
399 
400 	for (grp_id = 0; grp_id < MAX_TA_RA_ENTRIES; grp_id++) {
401 		if (qdf_test_bit(grp_id, &bitmap)) {
402 			curr_cfg = &rcc_info->curr[grp_id];
403 			qdf_mem_copy(curr_cfg->tx_addr,
404 				     null_mac, QDF_MAC_ADDR_SIZE);
405 			qdf_mem_copy(curr_cfg->tx_addr_mask,
406 				     def_mac, QDF_MAC_ADDR_SIZE);
407 			qdf_mem_copy(curr_cfg->rx_addr,
408 				     null_mac, QDF_MAC_ADDR_SIZE);
409 			qdf_mem_copy(curr_cfg->rx_addr_mask,
410 				     def_mac, QDF_MAC_ADDR_SIZE);
411 			curr_cfg->bw = 0xf;
412 			curr_cfg->nss = 0xff;
413 			curr_cfg->mgmt_subtype_filter = 0;
414 			curr_cfg->ctrl_subtype_filter = 0;
415 			curr_cfg->data_subtype_filter = 0;
416 			if (!allvalid) {
417 				curr_cfg->valid_ta = 0;
418 				curr_cfg->valid_ta_mask = 0;
419 				curr_cfg->valid_ra = 0;
420 				curr_cfg->valid_ra_mask = 0;
421 				curr_cfg->valid_bw_mask = 0;
422 				curr_cfg->valid_nss_mask = 0;
423 				curr_cfg->valid_mgmt_subtype = 0;
424 				curr_cfg->valid_ctrl_subtype = 0;
425 				curr_cfg->valid_data_subtype = 0;
426 			} else {
427 				curr_cfg->valid_ta = 1;
428 				curr_cfg->valid_ta_mask = 1;
429 				curr_cfg->valid_ra = 1;
430 				curr_cfg->valid_ra_mask = 1;
431 				curr_cfg->valid_bw_mask = 1;
432 				curr_cfg->valid_nss_mask = 1;
433 				curr_cfg->valid_mgmt_subtype = 1;
434 				curr_cfg->valid_ctrl_subtype = 1;
435 				curr_cfg->valid_data_subtype = 1;
436 			}
437 		}
438 	}
439 }
440 #endif
441 
442 #ifdef WLAN_ENH_CFR_ENABLE
443 #ifdef CFR_USE_FIXED_FOLDER
444 static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops)
445 {
446 	tx_ops->cfr_tx_ops.cfr_subscribe_ppdu_desc =
447 				target_if_cfr_subscribe_ppdu_desc;
448 }
449 #else
450 static void target_if_enh_cfr_add_ops(struct wlan_lmac_if_tx_ops *tx_ops)
451 {
452 }
453 #endif /* CFR_USE_FIXED_FOLDER */
454 static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
455 {
456 	tx_ops->cfr_tx_ops.cfr_config_rcc =
457 		target_if_cfr_config_rcc;
458 	tx_ops->cfr_tx_ops.cfr_start_lut_timer =
459 		target_if_cfr_start_lut_age_timer;
460 	tx_ops->cfr_tx_ops.cfr_stop_lut_timer =
461 		target_if_cfr_stop_lut_age_timer;
462 	tx_ops->cfr_tx_ops.cfr_default_ta_ra_cfg =
463 		target_if_cfr_default_ta_ra_config;
464 	tx_ops->cfr_tx_ops.cfr_dump_lut_enh =
465 		target_if_cfr_dump_lut_enh;
466 	tx_ops->cfr_tx_ops.cfr_rx_tlv_process =
467 		target_if_cfr_rx_tlv_process;
468 	tx_ops->cfr_tx_ops.cfr_update_global_cfg =
469 		target_if_cfr_update_global_cfg;
470 	target_if_enh_cfr_add_ops(tx_ops);
471 }
472 #else
473 static void target_if_enh_cfr_tx_ops(struct wlan_lmac_if_tx_ops *tx_ops)
474 {
475 }
476 #endif
477 
478 void target_if_cfr_tx_ops_register(struct wlan_lmac_if_tx_ops *tx_ops)
479 {
480 	tx_ops->cfr_tx_ops.cfr_init_pdev =
481 		target_if_cfr_init_pdev;
482 	tx_ops->cfr_tx_ops.cfr_deinit_pdev =
483 		target_if_cfr_deinit_pdev;
484 	tx_ops->cfr_tx_ops.cfr_enable_cfr_timer =
485 		target_if_cfr_enable_cfr_timer;
486 	tx_ops->cfr_tx_ops.cfr_start_capture =
487 		target_if_cfr_start_capture;
488 	tx_ops->cfr_tx_ops.cfr_stop_capture =
489 		target_if_cfr_stop_capture;
490 	target_if_enh_cfr_tx_ops(tx_ops);
491 }
492 
493 void target_if_cfr_set_cfr_support(struct wlan_objmgr_psoc *psoc,
494 				   uint8_t value)
495 {
496 	struct wlan_lmac_if_rx_ops *rx_ops;
497 
498 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
499 	if (!rx_ops) {
500 		cfr_err("rx_ops is NULL");
501 		return;
502 	}
503 	if (rx_ops->cfr_rx_ops.cfr_support_set)
504 		rx_ops->cfr_rx_ops.cfr_support_set(psoc, value);
505 }
506 
507 void target_if_cfr_info_send(struct wlan_objmgr_pdev *pdev, void *head,
508 			     size_t hlen, void *data, size_t dlen, void *tail,
509 			     size_t tlen)
510 {
511 	struct wlan_objmgr_psoc *psoc;
512 	struct wlan_lmac_if_rx_ops *rx_ops;
513 
514 	psoc = wlan_pdev_get_psoc(pdev);
515 
516 	rx_ops = wlan_psoc_get_lmac_if_rxops(psoc);
517 	if (!rx_ops) {
518 		cfr_err("rx_ops is NULL");
519 		return;
520 	}
521 	if (rx_ops->cfr_rx_ops.cfr_info_send)
522 		rx_ops->cfr_rx_ops.cfr_info_send(pdev, head, hlen, data, dlen,
523 						 tail, tlen);
524 }
525