1 /* 2 * Copyright (c) 2017-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 * DOC: wifi_pos_api.c 20 * This file defines the APIs wifi_pos component. 21 */ 22 23 #include "wifi_pos_api.h" 24 #include "wifi_pos_utils_i.h" 25 #include "wifi_pos_main_i.h" 26 #include "os_if_wifi_pos.h" 27 #include "target_if_wifi_pos.h" 28 #include "wlan_objmgr_cmn.h" 29 #include "wlan_objmgr_global_obj.h" 30 #include "wlan_objmgr_psoc_obj.h" 31 #include "wlan_lmac_if_def.h" 32 33 QDF_STATUS wifi_pos_init(void) 34 { 35 QDF_STATUS status; 36 37 wifi_pos_lock_init(); 38 39 /* register psoc create handler functions. */ 40 status = wlan_objmgr_register_psoc_create_handler( 41 WLAN_UMAC_COMP_WIFI_POS, 42 wifi_pos_psoc_obj_created_notification, 43 NULL); 44 if (QDF_IS_STATUS_ERROR(status)) { 45 wifi_pos_err("register_psoc_create_handler failed, status: %d", 46 status); 47 return status; 48 } 49 50 /* register psoc delete handler functions. */ 51 status = wlan_objmgr_register_psoc_destroy_handler( 52 WLAN_UMAC_COMP_WIFI_POS, 53 wifi_pos_psoc_obj_destroyed_notification, 54 NULL); 55 if (QDF_IS_STATUS_ERROR(status)) { 56 wifi_pos_err("register_psoc_destroy_handler failed, status: %d", 57 status); 58 } 59 60 return status; 61 } 62 63 QDF_STATUS wifi_pos_deinit(void) 64 { 65 QDF_STATUS status; 66 67 /* deregister psoc create handler functions. */ 68 status = wlan_objmgr_unregister_psoc_create_handler( 69 WLAN_UMAC_COMP_WIFI_POS, 70 wifi_pos_psoc_obj_created_notification, 71 NULL); 72 if (QDF_IS_STATUS_ERROR(status)) { 73 wifi_pos_err("unregister_psoc_create_handler failed, status: %d", 74 status); 75 return status; 76 } 77 78 /* deregister psoc delete handler functions. */ 79 status = wlan_objmgr_unregister_psoc_destroy_handler( 80 WLAN_UMAC_COMP_WIFI_POS, 81 wifi_pos_psoc_obj_destroyed_notification, 82 NULL); 83 if (QDF_IS_STATUS_ERROR(status)) { 84 wifi_pos_err("unregister_psoc_destroy_handler failed, status: %d", 85 status); 86 } 87 88 wifi_pos_lock_deinit(); 89 90 return QDF_STATUS_SUCCESS; 91 } 92 93 QDF_STATUS wifi_pos_psoc_enable(struct wlan_objmgr_psoc *psoc) 94 { 95 QDF_STATUS status; 96 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 97 98 tx_ops = wifi_pos_get_tx_ops(psoc); 99 if (!tx_ops) { 100 wifi_pos_err("tx_ops is null"); 101 return QDF_STATUS_E_NULL_VALUE; 102 } 103 104 status = tx_ops->wifi_pos_register_events(psoc); 105 106 if (QDF_IS_STATUS_ERROR(status)) 107 wifi_pos_err("target_if_wifi_pos_register_events failed"); 108 109 return status; 110 } 111 112 QDF_STATUS wifi_pos_psoc_disable(struct wlan_objmgr_psoc *psoc) 113 { 114 QDF_STATUS status; 115 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 116 117 tx_ops = wifi_pos_get_tx_ops(psoc); 118 if (!tx_ops) { 119 wifi_pos_err("tx_ops is null"); 120 return QDF_STATUS_E_NULL_VALUE; 121 } 122 123 status = tx_ops->wifi_pos_deregister_events(psoc); 124 125 if (QDF_IS_STATUS_ERROR(status)) 126 wifi_pos_err("target_if_wifi_pos_deregister_events failed"); 127 128 return QDF_STATUS_SUCCESS; 129 } 130 131 void wifi_pos_set_oem_target_type(struct wlan_objmgr_psoc *psoc, uint32_t val) 132 { 133 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 134 wifi_pos_get_psoc_priv_obj(psoc); 135 136 if (!wifi_pos_psoc) { 137 wifi_pos_err("wifi_pos priv obj is null"); 138 return; 139 } 140 141 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 142 wifi_pos_psoc->oem_target_type = val; 143 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 144 } 145 146 void wifi_pos_set_oem_fw_version(struct wlan_objmgr_psoc *psoc, uint32_t val) 147 { 148 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 149 wifi_pos_get_psoc_priv_obj(psoc); 150 151 if (!wifi_pos_psoc) { 152 wifi_pos_err("wifi_pos priv obj is null"); 153 return; 154 } 155 156 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 157 wifi_pos_psoc->oem_fw_version = val; 158 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 159 } 160 161 void wifi_pos_set_drv_ver_major(struct wlan_objmgr_psoc *psoc, uint8_t val) 162 { 163 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 164 wifi_pos_get_psoc_priv_obj(psoc); 165 166 if (!wifi_pos_psoc) { 167 wifi_pos_err("wifi_pos priv obj is null"); 168 return; 169 } 170 171 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 172 wifi_pos_psoc->driver_version.major = val; 173 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 174 } 175 176 void wifi_pos_set_drv_ver_minor(struct wlan_objmgr_psoc *psoc, uint8_t val) 177 { 178 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 179 wifi_pos_get_psoc_priv_obj(psoc); 180 181 if (!wifi_pos_psoc) { 182 wifi_pos_err("wifi_pos priv obj is null"); 183 return; 184 } 185 186 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 187 wifi_pos_psoc->driver_version.minor = val; 188 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 189 } 190 191 void wifi_pos_set_drv_ver_patch(struct wlan_objmgr_psoc *psoc, uint8_t val) 192 { 193 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 194 wifi_pos_get_psoc_priv_obj(psoc); 195 196 if (!wifi_pos_psoc) { 197 wifi_pos_err("wifi_pos priv obj is null"); 198 return; 199 } 200 201 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 202 wifi_pos_psoc->driver_version.patch = val; 203 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 204 } 205 206 void wifi_pos_set_drv_ver_build(struct wlan_objmgr_psoc *psoc, uint8_t val) 207 { 208 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 209 wifi_pos_get_psoc_priv_obj(psoc); 210 211 if (!wifi_pos_psoc) { 212 wifi_pos_err("wifi_pos priv obj is null"); 213 return; 214 } 215 216 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 217 wifi_pos_psoc->driver_version.build = val; 218 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 219 } 220 221 void wifi_pos_set_dwell_time_min(struct wlan_objmgr_psoc *psoc, uint16_t val) 222 { 223 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 224 wifi_pos_get_psoc_priv_obj(psoc); 225 226 if (!wifi_pos_psoc) { 227 wifi_pos_err("wifi_pos priv obj is null"); 228 return; 229 } 230 231 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 232 wifi_pos_psoc->allowed_dwell_time_min = val; 233 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 234 } 235 void wifi_pos_set_dwell_time_max(struct wlan_objmgr_psoc *psoc, uint16_t val) 236 { 237 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 238 wifi_pos_get_psoc_priv_obj(psoc); 239 240 if (!wifi_pos_psoc) { 241 wifi_pos_err("wifi_pos priv obj is null"); 242 return; 243 } 244 245 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 246 wifi_pos_psoc->allowed_dwell_time_max = val; 247 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 248 } 249 250 void wifi_pos_set_current_dwell_time_max(struct wlan_objmgr_psoc *psoc, 251 uint16_t val) 252 { 253 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 254 wifi_pos_get_psoc_priv_obj(psoc); 255 256 if (!wifi_pos_psoc) { 257 wifi_pos_err("wifi_pos priv obj is null"); 258 return; 259 } 260 261 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 262 wifi_pos_psoc->current_dwell_time_max = val; 263 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 264 } 265 266 void wifi_pos_set_current_dwell_time_min(struct wlan_objmgr_psoc *psoc, 267 uint16_t val) 268 { 269 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 270 wifi_pos_get_psoc_priv_obj(psoc); 271 272 if (!wifi_pos_psoc) { 273 wifi_pos_err("wifi_pos priv obj is null"); 274 return; 275 } 276 277 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 278 wifi_pos_psoc->current_dwell_time_max = val; 279 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 280 } 281 282 uint32_t wifi_pos_get_app_pid(struct wlan_objmgr_psoc *psoc) 283 { 284 uint32_t app_pid; 285 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 286 wifi_pos_get_psoc_priv_obj(psoc); 287 288 if (!wifi_pos_psoc) { 289 wifi_pos_err("wifi_pos priv obj is null"); 290 return 0; 291 } 292 293 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 294 app_pid = wifi_pos_psoc->app_pid; 295 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 296 297 return app_pid; 298 299 } 300 301 bool wifi_pos_is_app_registered(struct wlan_objmgr_psoc *psoc) 302 { 303 bool is_app_registered; 304 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 305 wifi_pos_get_psoc_priv_obj(psoc); 306 307 if (!wifi_pos_psoc) { 308 wifi_pos_err("wifi_pos priv obj is null"); 309 return false; 310 } 311 312 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 313 is_app_registered = wifi_pos_psoc->is_app_registered; 314 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 315 316 return is_app_registered; 317 } 318 319 #ifdef WLAN_FEATURE_CIF_CFR 320 QDF_STATUS wifi_pos_init_cir_cfr_rings(struct wlan_objmgr_psoc *psoc, 321 void *hal_soc, uint8_t num_mac, void *buf) 322 { 323 return target_if_wifi_pos_init_cir_cfr_rings(psoc, hal_soc, 324 num_mac, buf); 325 } 326 #endif 327 328 QDF_STATUS wifi_pos_register_get_phy_mode_cb( 329 struct wlan_objmgr_psoc *psoc, 330 void (*handler)(uint8_t, uint32_t, uint32_t *)) 331 { 332 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 333 334 if (!psoc) { 335 wifi_pos_err("psoc is null"); 336 return QDF_STATUS_E_NULL_VALUE; 337 } 338 339 if (!handler) { 340 wifi_pos_err("Null callback"); 341 return QDF_STATUS_E_NULL_VALUE; 342 } 343 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 344 if (!wifi_pos_psoc) { 345 wifi_pos_err("wifi_pos priv obj is null"); 346 return QDF_STATUS_E_NULL_VALUE; 347 } 348 349 wifi_pos_psoc->wifi_pos_get_phy_mode = handler; 350 351 return QDF_STATUS_SUCCESS; 352 } 353 354 QDF_STATUS wifi_pos_register_get_fw_phy_mode_for_freq_cb( 355 struct wlan_objmgr_psoc *psoc, 356 void (*handler)(uint32_t, uint32_t, uint32_t *)) 357 { 358 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 359 360 if (!psoc) { 361 wifi_pos_err("psoc is null"); 362 return QDF_STATUS_E_NULL_VALUE; 363 } 364 365 if (!handler) { 366 wifi_pos_err("Null callback"); 367 return QDF_STATUS_E_NULL_VALUE; 368 } 369 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 370 if (!wifi_pos_psoc) { 371 wifi_pos_err("wifi_pos priv obj is null"); 372 return QDF_STATUS_E_NULL_VALUE; 373 } 374 375 wifi_pos_psoc->wifi_pos_get_fw_phy_mode_for_freq = handler; 376 377 return QDF_STATUS_SUCCESS; 378 } 379 380 QDF_STATUS wifi_pos_register_send_action( 381 struct wlan_objmgr_psoc *psoc, 382 void (*handler)(struct wlan_objmgr_psoc *psoc, 383 uint32_t sub_type, 384 uint8_t *buf, 385 uint32_t buf_len)) 386 { 387 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 388 389 if (!psoc) { 390 wifi_pos_err("psoc is null"); 391 return QDF_STATUS_E_NULL_VALUE; 392 } 393 394 if (!handler) { 395 wifi_pos_err("Null callback"); 396 return QDF_STATUS_E_NULL_VALUE; 397 } 398 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 399 if (!wifi_pos_psoc) { 400 wifi_pos_err("wifi_pos priv obj is null"); 401 return QDF_STATUS_E_NULL_VALUE; 402 } 403 404 wifi_pos_psoc->wifi_pos_send_action = handler; 405 406 return QDF_STATUS_SUCCESS; 407 } 408