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