1 /*
2 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 <wifi_radar_defs_i.h>
20 #include <qdf_types.h>
21 #include <wlan_objmgr_pdev_obj.h>
22 #include <wlan_objmgr_vdev_obj.h>
23 #include <wlan_objmgr_peer_obj.h>
24 #include <qdf_streamfs.h>
25 #include <target_if.h>
26 #include <target_if_direct_buf_rx_api.h>
27 #include <wlan_osif_priv.h>
28
29 QDF_STATUS
wlan_wifi_radar_psoc_obj_create_handler(struct wlan_objmgr_psoc * psoc,void * arg)30 wlan_wifi_radar_psoc_obj_create_handler(
31 struct wlan_objmgr_psoc *psoc, void *arg)
32 {
33 struct psoc_wifi_radar *wifi_radar_sc = NULL;
34
35 wifi_radar_sc =
36 (struct psoc_wifi_radar *)qdf_mem_malloc(sizeof(*wifi_radar_sc));
37 if (!wifi_radar_sc) {
38 wifi_radar_err("Failed to allocate wifi_radar_ctx object\n");
39 return QDF_STATUS_E_NOMEM;
40 }
41
42 wifi_radar_sc->psoc_obj = psoc;
43
44 wlan_objmgr_psoc_component_obj_attach(psoc, WLAN_UMAC_COMP_WIFI_RADAR,
45 (void *)wifi_radar_sc,
46 QDF_STATUS_SUCCESS);
47
48 return QDF_STATUS_SUCCESS;
49 }
50
51 QDF_STATUS
wlan_wifi_radar_psoc_obj_destroy_handler(struct wlan_objmgr_psoc * psoc,void * arg)52 wlan_wifi_radar_psoc_obj_destroy_handler(
53 struct wlan_objmgr_psoc *psoc, void *arg)
54 {
55 struct psoc_wifi_radar *wifi_radar_sc = NULL;
56
57 wifi_radar_sc = wlan_objmgr_psoc_get_comp_private_obj(
58 psoc, WLAN_UMAC_COMP_WIFI_RADAR);
59 if (wifi_radar_sc) {
60 wlan_objmgr_psoc_component_obj_detach(
61 psoc, WLAN_UMAC_COMP_WIFI_RADAR, (void *)wifi_radar_sc);
62 qdf_mem_free(wifi_radar_sc);
63 }
64
65 return QDF_STATUS_SUCCESS;
66 }
67
68 QDF_STATUS
wlan_wifi_radar_pdev_obj_create_handler(struct wlan_objmgr_pdev * pdev,void * arg)69 wlan_wifi_radar_pdev_obj_create_handler(
70 struct wlan_objmgr_pdev *pdev, void *arg)
71 {
72 struct pdev_wifi_radar *pa = NULL;
73
74 if (!pdev) {
75 wifi_radar_err("PDEV is NULL\n");
76 return QDF_STATUS_E_FAILURE;
77 }
78
79 wlan_pdev_nif_feat_ext_cap_set(pdev, WLAN_PDEV_FEXT_WIFI_RADAR_ENABLE);
80
81 pa = (struct pdev_wifi_radar *)
82 qdf_mem_malloc(sizeof(struct pdev_wifi_radar));
83 if (!pa) {
84 wifi_radar_err("Failed to allocate pdev object\n");
85 return QDF_STATUS_E_NOMEM;
86 }
87 pa->pdev_obj = pdev;
88 wlan_objmgr_pdev_component_obj_attach(pdev, WLAN_UMAC_COMP_WIFI_RADAR,
89 (void *)pa, QDF_STATUS_SUCCESS);
90
91 return QDF_STATUS_SUCCESS;
92 }
93
94 QDF_STATUS
wlan_wifi_radar_pdev_obj_destroy_handler(struct wlan_objmgr_pdev * pdev,void * arg)95 wlan_wifi_radar_pdev_obj_destroy_handler(
96 struct wlan_objmgr_pdev *pdev, void *arg)
97 {
98 struct pdev_wifi_radar *pa = NULL;
99 uint32_t idx;
100
101 if (!pdev) {
102 wifi_radar_err("PDEV is NULL\n");
103 return QDF_STATUS_E_FAILURE;
104 }
105
106 pa =
107 wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_WIFI_RADAR);
108 if (pa) {
109 wlan_objmgr_pdev_component_obj_detach(
110 pdev, WLAN_UMAC_COMP_WIFI_RADAR, (void *)pa);
111 qdf_mem_free(pa);
112 }
113
114 return QDF_STATUS_SUCCESS;
115 }
116
117 QDF_STATUS
wlan_wifi_radar_peer_obj_create_handler(struct wlan_objmgr_peer * peer,void * arg)118 wlan_wifi_radar_peer_obj_create_handler(
119 struct wlan_objmgr_peer *peer, void *arg)
120 {
121 struct peer_wifi_radar *pe = NULL;
122 struct wlan_objmgr_vdev *vdev;
123 struct wlan_objmgr_pdev *pdev = NULL;
124
125 if (!peer) {
126 wifi_radar_err("PEER is NULL\n");
127 return QDF_STATUS_E_FAILURE;
128 }
129
130 vdev = wlan_peer_get_vdev(peer);
131 if (vdev)
132 pdev = wlan_vdev_get_pdev(vdev);
133
134 if (!pdev) {
135 wifi_radar_err("PDEV is NULL\n");
136 return QDF_STATUS_E_FAILURE;
137 }
138
139 if (wlan_wifi_radar_is_feature_disabled(pdev)) {
140 wifi_radar_info("WiFi Radar is disabled");
141 return QDF_STATUS_E_NOSUPPORT;
142 }
143
144 pe = (struct peer_wifi_radar *)
145 qdf_mem_malloc(sizeof(struct peer_wifi_radar));
146 if (!pe) {
147 wifi_radar_err("Failed to allocate peer_wifi_radar object\n");
148 return QDF_STATUS_E_FAILURE;
149 }
150
151 pe->peer_obj = peer;
152
153 wlan_objmgr_peer_component_obj_attach(peer, WLAN_UMAC_COMP_WIFI_RADAR,
154 (void *)pe, QDF_STATUS_SUCCESS);
155 return QDF_STATUS_SUCCESS;
156 }
157
158 QDF_STATUS
wlan_wifi_radar_peer_obj_destroy_handler(struct wlan_objmgr_peer * peer,void * arg)159 wlan_wifi_radar_peer_obj_destroy_handler(
160 struct wlan_objmgr_peer *peer, void *arg)
161 {
162 struct peer_wifi_radar *pe = NULL;
163 struct wlan_objmgr_vdev *vdev;
164 struct wlan_objmgr_pdev *pdev = NULL;
165
166 if (!peer) {
167 wifi_radar_err("PEER is NULL\n");
168 return QDF_STATUS_E_FAILURE;
169 }
170
171 vdev = wlan_peer_get_vdev(peer);
172 if (vdev)
173 pdev = wlan_vdev_get_pdev(vdev);
174
175 if (wlan_wifi_radar_is_feature_disabled(pdev)) {
176 wifi_radar_info("WiFi Radar is disabled");
177 return QDF_STATUS_E_NOSUPPORT;
178 }
179
180 pe =
181 wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_WIFI_RADAR);
182 if (pe) {
183 wlan_objmgr_peer_component_obj_detach(
184 peer, WLAN_UMAC_COMP_WIFI_RADAR, (void *)pe);
185 qdf_mem_free(pe);
186 }
187
188 return QDF_STATUS_SUCCESS;
189 }
190
191 /**
192 * wifi_radar_get_dev_name() - Get net device name from pdev
193 * @pdev: objmgr pdev
194 *
195 * Return: netdev name
196 */
wifi_radar_get_dev_name(struct wlan_objmgr_pdev * pdev)197 static char *wifi_radar_get_dev_name(struct wlan_objmgr_pdev *pdev)
198 {
199 struct pdev_osif_priv *pdev_ospriv;
200 struct qdf_net_if *nif;
201
202 pdev_ospriv = wlan_pdev_get_ospriv(pdev);
203 if (!pdev_ospriv) {
204 wifi_radar_err("pdev_ospriv is NULL\n");
205 return NULL;
206 }
207
208 nif = pdev_ospriv->nif;
209 if (!nif) {
210 wifi_radar_err("pdev nif is NULL\n");
211 return NULL;
212 }
213
214 return qdf_net_if_get_devname(nif);
215 }
216
wifi_radar_streamfs_init(struct wlan_objmgr_pdev * pdev)217 QDF_STATUS wifi_radar_streamfs_init(struct wlan_objmgr_pdev *pdev)
218 {
219 struct pdev_wifi_radar *pa = NULL;
220 char *devname;
221 char folder[32];
222
223 if (!pdev) {
224 wifi_radar_err("PDEV is NULL");
225 return QDF_STATUS_E_FAILURE;
226 }
227
228 if (wlan_wifi_radar_is_feature_disabled(pdev)) {
229 wifi_radr_info("WiFi Radar is disabled");
230 return QDF_STATUS_COMP_DISABLED;
231 }
232
233 pa = wlan_objmgr_pdev_get_comp_private_obj(
234 pdev, WLAN_UMAC_COMP_WIFI_RADAR);
235
236 if (!pa) {
237 wifi_radar_err("pdev_wifi_radar is NULL");
238 return QDF_STATUS_E_FAILURE;
239 }
240
241 if (!pa->is_wifi_radar_capable) {
242 wifi_radar_err("WiFi Radar is not supported");
243 return QDF_STATUS_E_FAILURE;
244 }
245
246 devname = wifi_radar_get_dev_name(pdev);
247 if (!devname) {
248 wifi_radar_err("devname is NULL");
249 return QDF_STATUS_E_FAILURE;
250 }
251
252 snprintf(folder, sizeof(folder), "wifi-radar%s", devname);
253
254 pa->dir_ptr = qdf_streamfs_create_dir((const char *)folder, NULL);
255
256 if (!pa->dir_ptr) {
257 wifi_radar_err("Directory create failed");
258 return QDF_STATUS_E_FAILURE;
259 }
260
261 pa->chan_ptr = qdf_streamfs_open("wifi_radar_dump", pa->dir_ptr,
262 pa->subbuf_size,
263 pa->num_subbufs, NULL);
264
265 if (!pa->chan_ptr) {
266 wifi_radar_err("Chan create failed");
267 qdf_streamfs_remove_dir_recursive(pa->dir_ptr);
268 pa->dir_ptr = NULL;
269 return QDF_STATUS_E_FAILURE;
270 }
271
272 return QDF_STATUS_SUCCESS;
273 }
274
wifi_radar_streamfs_remove(struct wlan_objmgr_pdev * pdev)275 QDF_STATUS wifi_radar_streamfs_remove(struct wlan_objmgr_pdev *pdev)
276 {
277 struct pdev_wifi_radar *pa = NULL;
278
279 if (wlan_wifi_radar_is_feature_disabled(pdev)) {
280 wifi_radar_info("WiFi Radar is disabled");
281 return QDF_STATUS_COMP_DISABLED;
282 }
283
284 pa = wlan_objmgr_pdev_get_comp_private_obj(
285 pdev, WLAN_UMAC_COMP_WIFI_RADAR);
286 if (pa) {
287 if (pa->chan_ptr) {
288 qdf_streamfs_close(pa->chan_ptr);
289 pa->chan_ptr = NULL;
290 }
291
292 if (pa->dir_ptr) {
293 qdf_streamfs_remove_dir_recursive(pa->dir_ptr);
294 pa->dir_ptr = NULL;
295 }
296
297 } else {
298 return QDF_STATUS_E_FAILURE;
299 }
300 return QDF_STATUS_SUCCESS;
301 }
302
wifi_radar_streamfs_write(struct pdev_wifi_radar * pa,const void * write_data,size_t write_len)303 QDF_STATUS wifi_radar_streamfs_write(
304 struct pdev_wifi_radar *pa, const void *write_data,
305 size_t write_len)
306 {
307 if (pa->chan_ptr) {
308 /* write to channel buffer */
309 qdf_streamfs_write(pa->chan_ptr, (const void *)write_data,
310 write_len);
311 } else {
312 return QDF_STATUS_E_FAILURE;
313 }
314 return QDF_STATUS_SUCCESS;
315 }
316
wifi_radar_streamfs_flush(struct pdev_wifi_radar * pa)317 QDF_STATUS wifi_radar_streamfs_flush(struct pdev_wifi_radar *pa)
318 {
319 if (pa->chan_ptr) {
320 /* Flush the data write to channel buffer */
321 qdf_streamfs_flush(pa->chan_ptr);
322 } else {
323 return QDF_STATUS_E_FAILURE;
324 }
325 return QDF_STATUS_SUCCESS;
326 }
327