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