1 /* 2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 /** 20 * DOC: wifi_pos_api.c 21 * This file defines the APIs wifi_pos component. 22 */ 23 24 #include <wlan_lmac_if_def.h> 25 #include "wifi_pos_api.h" 26 #include "wifi_pos_utils_i.h" 27 #include "wifi_pos_main_i.h" 28 #include "os_if_wifi_pos.h" 29 #include "target_if_wifi_pos.h" 30 #include "wlan_objmgr_cmn.h" 31 #include "wlan_objmgr_global_obj.h" 32 #include "wlan_objmgr_psoc_obj.h" 33 #include "wlan_lmac_if_def.h" 34 35 QDF_STATUS wifi_pos_init(void) 36 { 37 QDF_STATUS status; 38 39 wifi_pos_lock_init(); 40 41 /* register psoc create handler functions. */ 42 status = wlan_objmgr_register_psoc_create_handler( 43 WLAN_UMAC_COMP_WIFI_POS, 44 wifi_pos_psoc_obj_created_notification, 45 NULL); 46 if (QDF_IS_STATUS_ERROR(status)) { 47 wifi_pos_err("register_psoc_create_handler failed, status: %d", 48 status); 49 return status; 50 } 51 52 /* register psoc delete handler functions. */ 53 status = wlan_objmgr_register_psoc_destroy_handler( 54 WLAN_UMAC_COMP_WIFI_POS, 55 wifi_pos_psoc_obj_destroyed_notification, 56 NULL); 57 if (QDF_IS_STATUS_ERROR(status)) { 58 wifi_pos_err("register_psoc_destroy_handler failed, status: %d", 59 status); 60 } 61 62 return status; 63 } 64 65 QDF_STATUS wifi_pos_deinit(void) 66 { 67 QDF_STATUS status; 68 69 /* deregister psoc create handler functions. */ 70 status = wlan_objmgr_unregister_psoc_create_handler( 71 WLAN_UMAC_COMP_WIFI_POS, 72 wifi_pos_psoc_obj_created_notification, 73 NULL); 74 if (QDF_IS_STATUS_ERROR(status)) { 75 wifi_pos_err("unregister_psoc_create_handler failed, status: %d", 76 status); 77 return status; 78 } 79 80 /* deregister psoc delete handler functions. */ 81 status = wlan_objmgr_unregister_psoc_destroy_handler( 82 WLAN_UMAC_COMP_WIFI_POS, 83 wifi_pos_psoc_obj_destroyed_notification, 84 NULL); 85 if (QDF_IS_STATUS_ERROR(status)) { 86 wifi_pos_err("unregister_psoc_destroy_handler failed, status: %d", 87 status); 88 } 89 90 wifi_pos_lock_deinit(); 91 92 return QDF_STATUS_SUCCESS; 93 } 94 95 QDF_STATUS wifi_pos_psoc_enable(struct wlan_objmgr_psoc *psoc) 96 { 97 QDF_STATUS status; 98 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 99 100 tx_ops = wifi_pos_get_tx_ops(psoc); 101 if (!tx_ops) { 102 wifi_pos_err("tx_ops is null"); 103 return QDF_STATUS_E_NULL_VALUE; 104 } 105 106 status = tx_ops->wifi_pos_register_events(psoc); 107 108 if (QDF_IS_STATUS_ERROR(status)) 109 wifi_pos_err("target_if_wifi_pos_register_events failed"); 110 111 return status; 112 } 113 114 QDF_STATUS wifi_pos_psoc_disable(struct wlan_objmgr_psoc *psoc) 115 { 116 QDF_STATUS status; 117 struct wlan_lmac_if_wifi_pos_tx_ops *tx_ops; 118 119 tx_ops = wifi_pos_get_tx_ops(psoc); 120 if (!tx_ops) { 121 wifi_pos_err("tx_ops is null"); 122 return QDF_STATUS_E_NULL_VALUE; 123 } 124 125 status = tx_ops->wifi_pos_deregister_events(psoc); 126 127 if (QDF_IS_STATUS_ERROR(status)) 128 wifi_pos_err("target_if_wifi_pos_deregister_events failed"); 129 130 return QDF_STATUS_SUCCESS; 131 } 132 133 void wifi_pos_set_oem_target_type(struct wlan_objmgr_psoc *psoc, uint32_t val) 134 { 135 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 136 wifi_pos_get_psoc_priv_obj(psoc); 137 138 if (!wifi_pos_psoc) { 139 wifi_pos_err("wifi_pos priv obj is null"); 140 return; 141 } 142 143 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 144 wifi_pos_psoc->oem_target_type = val; 145 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 146 } 147 148 void wifi_pos_set_oem_fw_version(struct wlan_objmgr_psoc *psoc, uint32_t val) 149 { 150 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 151 wifi_pos_get_psoc_priv_obj(psoc); 152 153 if (!wifi_pos_psoc) { 154 wifi_pos_err("wifi_pos priv obj is null"); 155 return; 156 } 157 158 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 159 wifi_pos_psoc->oem_fw_version = val; 160 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 161 } 162 163 void wifi_pos_set_drv_ver_major(struct wlan_objmgr_psoc *psoc, uint8_t val) 164 { 165 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 166 wifi_pos_get_psoc_priv_obj(psoc); 167 168 if (!wifi_pos_psoc) { 169 wifi_pos_err("wifi_pos priv obj is null"); 170 return; 171 } 172 173 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 174 wifi_pos_psoc->driver_version.major = val; 175 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 176 } 177 178 void wifi_pos_set_drv_ver_minor(struct wlan_objmgr_psoc *psoc, uint8_t val) 179 { 180 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 181 wifi_pos_get_psoc_priv_obj(psoc); 182 183 if (!wifi_pos_psoc) { 184 wifi_pos_err("wifi_pos priv obj is null"); 185 return; 186 } 187 188 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 189 wifi_pos_psoc->driver_version.minor = val; 190 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 191 } 192 193 void wifi_pos_set_drv_ver_patch(struct wlan_objmgr_psoc *psoc, uint8_t val) 194 { 195 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 196 wifi_pos_get_psoc_priv_obj(psoc); 197 198 if (!wifi_pos_psoc) { 199 wifi_pos_err("wifi_pos priv obj is null"); 200 return; 201 } 202 203 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 204 wifi_pos_psoc->driver_version.patch = val; 205 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 206 } 207 208 void wifi_pos_set_drv_ver_build(struct wlan_objmgr_psoc *psoc, uint8_t val) 209 { 210 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 211 wifi_pos_get_psoc_priv_obj(psoc); 212 213 if (!wifi_pos_psoc) { 214 wifi_pos_err("wifi_pos priv obj is null"); 215 return; 216 } 217 218 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 219 wifi_pos_psoc->driver_version.build = val; 220 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 221 } 222 223 void wifi_pos_set_dwell_time_min(struct wlan_objmgr_psoc *psoc, uint16_t val) 224 { 225 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 226 wifi_pos_get_psoc_priv_obj(psoc); 227 228 if (!wifi_pos_psoc) { 229 wifi_pos_err("wifi_pos priv obj is null"); 230 return; 231 } 232 233 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 234 wifi_pos_psoc->allowed_dwell_time_min = val; 235 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 236 } 237 void wifi_pos_set_dwell_time_max(struct wlan_objmgr_psoc *psoc, uint16_t val) 238 { 239 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 240 wifi_pos_get_psoc_priv_obj(psoc); 241 242 if (!wifi_pos_psoc) { 243 wifi_pos_err("wifi_pos priv obj is null"); 244 return; 245 } 246 247 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 248 wifi_pos_psoc->allowed_dwell_time_max = val; 249 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 250 } 251 252 void wifi_pos_set_current_dwell_time_max(struct wlan_objmgr_psoc *psoc, 253 uint16_t val) 254 { 255 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 256 wifi_pos_get_psoc_priv_obj(psoc); 257 258 if (!wifi_pos_psoc) { 259 wifi_pos_err("wifi_pos priv obj is null"); 260 return; 261 } 262 263 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 264 wifi_pos_psoc->current_dwell_time_max = val; 265 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 266 } 267 268 void wifi_pos_set_current_dwell_time_min(struct wlan_objmgr_psoc *psoc, 269 uint16_t val) 270 { 271 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 272 wifi_pos_get_psoc_priv_obj(psoc); 273 274 if (!wifi_pos_psoc) { 275 wifi_pos_err("wifi_pos priv obj is null"); 276 return; 277 } 278 279 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 280 wifi_pos_psoc->current_dwell_time_max = val; 281 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 282 } 283 284 uint32_t wifi_pos_get_app_pid(struct wlan_objmgr_psoc *psoc) 285 { 286 uint32_t app_pid; 287 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 288 wifi_pos_get_psoc_priv_obj(psoc); 289 290 if (!wifi_pos_psoc) { 291 wifi_pos_err("wifi_pos priv obj is null"); 292 return 0; 293 } 294 295 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 296 app_pid = wifi_pos_psoc->app_pid; 297 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 298 299 return app_pid; 300 301 } 302 303 bool wifi_pos_is_app_registered(struct wlan_objmgr_psoc *psoc) 304 { 305 bool is_app_registered; 306 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc = 307 wifi_pos_get_psoc_priv_obj(psoc); 308 309 if (!wifi_pos_psoc) { 310 wifi_pos_err("wifi_pos priv obj is null"); 311 return false; 312 } 313 314 qdf_spin_lock_bh(&wifi_pos_psoc->wifi_pos_lock); 315 is_app_registered = wifi_pos_psoc->is_app_registered; 316 qdf_spin_unlock_bh(&wifi_pos_psoc->wifi_pos_lock); 317 318 return is_app_registered; 319 } 320 321 #ifdef WLAN_FEATURE_CIF_CFR 322 QDF_STATUS wifi_pos_init_cir_cfr_rings(struct wlan_objmgr_psoc *psoc, 323 void *hal_soc, uint8_t num_mac, void *buf) 324 { 325 return target_if_wifi_pos_init_cir_cfr_rings(psoc, hal_soc, 326 num_mac, buf); 327 } 328 #endif 329 330 QDF_STATUS 331 wifi_pos_register_get_phy_mode_cb(struct wlan_objmgr_psoc *psoc, 332 void (*handler)(qdf_freq_t, uint32_t, 333 uint32_t *)) 334 { 335 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 336 337 if (!psoc) { 338 wifi_pos_err("psoc is null"); 339 return QDF_STATUS_E_NULL_VALUE; 340 } 341 342 if (!handler) { 343 wifi_pos_err("Null callback"); 344 return QDF_STATUS_E_NULL_VALUE; 345 } 346 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 347 if (!wifi_pos_psoc) { 348 wifi_pos_err("wifi_pos priv obj is null"); 349 return QDF_STATUS_E_NULL_VALUE; 350 } 351 352 wifi_pos_psoc->wifi_pos_get_phy_mode = handler; 353 354 return QDF_STATUS_SUCCESS; 355 } 356 357 QDF_STATUS wifi_pos_register_get_fw_phy_mode_for_freq_cb( 358 struct wlan_objmgr_psoc *psoc, 359 void (*handler)(uint32_t, uint32_t, uint32_t *)) 360 { 361 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 362 363 if (!psoc) { 364 wifi_pos_err("psoc is null"); 365 return QDF_STATUS_E_NULL_VALUE; 366 } 367 368 if (!handler) { 369 wifi_pos_err("Null callback"); 370 return QDF_STATUS_E_NULL_VALUE; 371 } 372 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 373 if (!wifi_pos_psoc) { 374 wifi_pos_err("wifi_pos priv obj is null"); 375 return QDF_STATUS_E_NULL_VALUE; 376 } 377 378 wifi_pos_psoc->wifi_pos_get_fw_phy_mode_for_freq = handler; 379 380 return QDF_STATUS_SUCCESS; 381 } 382 383 #ifndef CNSS_GENL 384 QDF_STATUS wifi_pos_register_get_pdev_id_by_dev_name( 385 struct wlan_objmgr_psoc *psoc, 386 QDF_STATUS (*handler)(char *dev_name, uint8_t *pdev_id, 387 struct wlan_objmgr_psoc **psoc)) 388 { 389 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 390 391 if (!psoc) { 392 wifi_pos_err("psoc is null"); 393 return QDF_STATUS_E_NULL_VALUE; 394 } 395 396 if (!handler) { 397 wifi_pos_err("Null callback"); 398 return QDF_STATUS_E_NULL_VALUE; 399 } 400 401 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 402 if (!wifi_pos_psoc) { 403 wifi_pos_err("wifi_pos priv obj is null"); 404 return QDF_STATUS_E_NULL_VALUE; 405 } 406 407 wifi_pos_psoc->wifi_pos_get_pdev_id_by_dev_name = handler; 408 409 return QDF_STATUS_SUCCESS; 410 } 411 412 #ifdef WLAN_RTT_MEASUREMENT_NOTIFICATION 413 QDF_STATUS wifi_pos_register_measurement_request_notification( 414 struct wlan_objmgr_psoc *psoc, 415 QDF_STATUS (*handler)(struct wlan_objmgr_pdev *pdev, 416 struct rtt_channel_info *chinfo)) 417 { 418 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 419 420 if (!psoc) { 421 wifi_pos_err("psoc is null"); 422 return QDF_STATUS_E_NULL_VALUE; 423 } 424 425 if (!handler) { 426 wifi_pos_err("Null callback"); 427 return QDF_STATUS_E_NULL_VALUE; 428 } 429 430 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 431 if (!wifi_pos_psoc) { 432 wifi_pos_err("wifi_pos priv obj is null"); 433 return QDF_STATUS_E_NULL_VALUE; 434 } 435 436 wifi_pos_psoc->wifi_pos_measurement_request_notification = handler; 437 438 return QDF_STATUS_SUCCESS; 439 } 440 #endif /* WLAN_RTT_MEASUREMENT_NOTIFICATION */ 441 442 QDF_STATUS wifi_pos_register_get_max_fw_phymode_for_channels( 443 struct wlan_objmgr_psoc *psoc, 444 QDF_STATUS (*handler)(struct wlan_objmgr_pdev *pdev, 445 struct wifi_pos_channel_power *chan_list, 446 uint16_t wifi_pos_num_chans)) 447 { 448 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 449 450 if (!psoc) { 451 wifi_pos_err("psoc is null"); 452 return QDF_STATUS_E_NULL_VALUE; 453 } 454 455 if (!handler) { 456 wifi_pos_err("Null callback"); 457 return QDF_STATUS_E_NULL_VALUE; 458 } 459 460 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 461 if (!wifi_pos_psoc) { 462 wifi_pos_err("wifi_pos priv obj is null"); 463 return QDF_STATUS_E_NULL_VALUE; 464 } 465 466 wifi_pos_psoc->wifi_pos_get_max_fw_phymode_for_channels = handler; 467 468 return QDF_STATUS_SUCCESS; 469 } 470 #endif /* CNSS_GENL */ 471 472 QDF_STATUS wifi_pos_register_send_action( 473 struct wlan_objmgr_psoc *psoc, 474 void (*handler)(struct wlan_objmgr_psoc *psoc, 475 uint32_t sub_type, 476 uint8_t *buf, 477 uint32_t buf_len)) 478 { 479 struct wifi_pos_psoc_priv_obj *wifi_pos_psoc; 480 481 if (!psoc) { 482 wifi_pos_err("psoc is null"); 483 return QDF_STATUS_E_NULL_VALUE; 484 } 485 486 if (!handler) { 487 wifi_pos_err("Null callback"); 488 return QDF_STATUS_E_NULL_VALUE; 489 } 490 wifi_pos_psoc = wifi_pos_get_psoc_priv_obj(psoc); 491 if (!wifi_pos_psoc) { 492 wifi_pos_err("wifi_pos priv obj is null"); 493 return QDF_STATUS_E_NULL_VALUE; 494 } 495 496 wifi_pos_psoc->wifi_pos_send_action = handler; 497 498 return QDF_STATUS_SUCCESS; 499 } 500