xref: /wlan-dirver/qca-wifi-host-cmn/target_if/cfr/src/target_if_cfr_6490.c (revision 6d768494e5ce14eb1603a695c86739d12ecc6ec2)
1 /*
2  * Copyright (c) 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 /**
20  * DOC : target_if_cfr_6490.c
21  *
22  * Target interface of CFR for QCA6490 implementation
23  *
24  */
25 
26 #include <cdp_txrx_ctrl.h>
27 #include "target_if_cfr.h"
28 #include <qdf_nbuf.h>
29 #include "wlan_cfr_utils_api.h"
30 #include "target_if_cfr_6490.h"
31 #include "target_if_cfr_6018.h"
32 #include "init_deinit_lmac.h"
33 #include "cfg_ucfg_api.h"
34 #include "cfr_cfg.h"
35 
36 static wdi_event_subscribe g_cfr_subscribe;
37 
38 static void target_cfr_callback(void *pdev_obj, enum WDI_EVENT event,
39 				void *data, u_int16_t peer_id,
40 				uint32_t status)
41 {
42 	struct wlan_objmgr_pdev *pdev;
43 	qdf_nbuf_t nbuf = (qdf_nbuf_t)data;
44 	qdf_nbuf_t data_clone;
45 
46 	pdev = (struct wlan_objmgr_pdev *)pdev_obj;
47 	if (qdf_unlikely((!pdev || !data))) {
48 		cfr_err("Invalid pdev %pK or data %pK for event %d",
49 			pdev, data, event);
50 		qdf_nbuf_free(nbuf);
51 		return;
52 	}
53 
54 	if (event != WDI_EVENT_RX_PPDU_DESC) {
55 		cfr_debug("event is %d", event);
56 		qdf_nbuf_free(nbuf);
57 		return;
58 	}
59 
60 	data_clone = qdf_nbuf_clone(nbuf);
61 	if (data_clone)
62 		wlan_cfr_rx_tlv_process(pdev, (void *)data_clone);
63 
64 	qdf_nbuf_free(nbuf);
65 }
66 
67 QDF_STATUS
68 target_if_cfr_subscribe_ppdu_desc(struct wlan_objmgr_pdev *pdev,
69 				  bool is_subscribe)
70 {
71 	ol_txrx_soc_handle soc;
72 	struct wlan_objmgr_psoc *psoc;
73 	struct pdev_cfr *pcfr;
74 
75 	if (!pdev) {
76 		cfr_err("Null pdev");
77 		return QDF_STATUS_E_INVAL;
78 	}
79 
80 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
81 				pdev, WLAN_UMAC_COMP_CFR);
82 	if (!pcfr) {
83 		cfr_err("pcfr is NULL");
84 		return QDF_STATUS_E_INVAL;
85 	}
86 
87 	psoc = wlan_pdev_get_psoc(pdev);
88 	if (!psoc) {
89 		cfr_err("Null psoc");
90 		return QDF_STATUS_E_INVAL;
91 	}
92 
93 	soc = wlan_psoc_get_dp_handle(psoc);
94 	if (!soc) {
95 		cfr_err("Null soc");
96 		return QDF_STATUS_E_INVAL;
97 	}
98 
99 	g_cfr_subscribe.callback = target_cfr_callback;
100 	g_cfr_subscribe.context = pdev;
101 	cdp_set_cfr_rcc(soc, 0, is_subscribe);
102 	cdp_enable_mon_reap_timer(soc, 0, is_subscribe);
103 	if (is_subscribe) {
104 		if (cdp_wdi_event_sub(soc, 0, &g_cfr_subscribe,
105 				      WDI_EVENT_RX_PPDU_DESC)) {
106 			cfr_err("wdi event sub fail");
107 			return QDF_STATUS_E_FAILURE;
108 		}
109 	} else {
110 		if (cdp_wdi_event_unsub(soc, 0, &g_cfr_subscribe,
111 					WDI_EVENT_RX_PPDU_DESC)) {
112 			cfr_err("wdi event unsub fail");
113 			return QDF_STATUS_E_FAILURE;
114 		}
115 	}
116 
117 	return QDF_STATUS_SUCCESS;
118 }
119 
120 QDF_STATUS cfr_6490_init_pdev(struct wlan_objmgr_psoc *psoc,
121 			      struct wlan_objmgr_pdev *pdev)
122 {
123 	struct pdev_cfr *cfr_pdev;
124 	struct psoc_cfr *cfr_psoc;
125 	struct wmi_unified *wmi_handle = NULL;
126 	bool cfr_capable;
127 	QDF_STATUS status;
128 
129 	if (!psoc || !pdev) {
130 		cfr_err("null pdev or psoc");
131 		return QDF_STATUS_E_FAILURE;
132 	}
133 
134 	cfr_pdev = wlan_objmgr_pdev_get_comp_private_obj(
135 					pdev, WLAN_UMAC_COMP_CFR);
136 	if (!cfr_pdev) {
137 		cfr_err("null pdev cfr");
138 		return QDF_STATUS_E_FAILURE;
139 	}
140 
141 	cfr_psoc = wlan_objmgr_psoc_get_comp_private_obj(
142 					psoc, WLAN_UMAC_COMP_CFR);
143 
144 	if (!cfr_psoc) {
145 		cfr_err("null psoc cfr");
146 		return QDF_STATUS_E_FAILURE;
147 	}
148 
149 	wmi_handle = lmac_get_pdev_wmi_handle(pdev);
150 	if (!wmi_handle) {
151 		cfr_err("null wmi handle");
152 		return QDF_STATUS_E_FAILURE;
153 	}
154 
155 	if (wlan_cfr_is_feature_disabled(pdev)) {
156 		cfr_pdev->is_cfr_capable = 0;
157 		cfr_psoc->is_cfr_capable = 0;
158 		cfr_info("cfr disabled");
159 		return QDF_STATUS_SUCCESS;
160 	}
161 
162 	cfr_capable = wmi_service_enabled(wmi_handle,
163 					  wmi_service_cfr_capture_support);
164 	cfr_pdev->is_cfr_capable = cfr_capable;
165 	cfr_psoc->is_cfr_capable = cfr_capable;
166 	if (!cfr_capable) {
167 		cfr_err("FW doesn't support CFR");
168 		return QDF_STATUS_SUCCESS;
169 	}
170 
171 	status = cfr_6018_init_pdev(psoc, pdev);
172 	cfr_pdev->chip_type = CFR_CAPTURE_RADIO_HSP;
173 
174 	return status;
175 }
176 
177 QDF_STATUS cfr_6490_deinit_pdev(struct wlan_objmgr_psoc *psoc,
178 				struct wlan_objmgr_pdev *pdev)
179 {
180 	struct pdev_cfr *pcfr;
181 
182 	if (!psoc || !pdev) {
183 		cfr_err("null pdev or psoc");
184 		return QDF_STATUS_E_FAILURE;
185 	}
186 
187 	pcfr = wlan_objmgr_pdev_get_comp_private_obj(
188 					pdev, WLAN_UMAC_COMP_CFR);
189 	if (!pcfr) {
190 		cfr_err("null pdev cfr");
191 		return QDF_STATUS_E_FAILURE;
192 	}
193 
194 	if (!pcfr->is_cfr_capable) {
195 		cfr_info("cfr disabled or FW not support");
196 		return QDF_STATUS_SUCCESS;
197 	}
198 
199 	return cfr_6018_deinit_pdev(psoc, pdev);
200 }
201