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