1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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 /** 21 * DOC: reg_priv_objs.c 22 * This file defines the APIs to create regulatory private PSOC and PDEV 23 * objects. 24 */ 25 26 #include <wlan_cmn.h> 27 #include <reg_services_public_struct.h> 28 #include <wlan_objmgr_psoc_obj.h> 29 #include <wlan_objmgr_pdev_obj.h> 30 #include <qdf_lock.h> 31 #include "reg_priv_objs.h" 32 #include "reg_utils.h" 33 #include "reg_services_common.h" 34 #include "reg_build_chan_list.h" 35 #include "reg_host_11d.h" 36 #include "reg_callbacks.h" 37 #ifdef CONFIG_AFC_SUPPORT 38 #include <cfg_ucfg_api.h> 39 #endif 40 41 struct wlan_regulatory_psoc_priv_obj *reg_get_psoc_obj( 42 struct wlan_objmgr_psoc *psoc) 43 { 44 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 45 46 if (!psoc) { 47 reg_alert("psoc is NULL"); 48 return NULL; 49 } 50 psoc_priv_obj = wlan_objmgr_psoc_get_comp_private_obj( 51 psoc, WLAN_UMAC_COMP_REGULATORY); 52 53 return psoc_priv_obj; 54 } 55 56 struct wlan_regulatory_pdev_priv_obj *reg_get_pdev_obj( 57 struct wlan_objmgr_pdev *pdev) 58 { 59 struct wlan_regulatory_pdev_priv_obj *pdev_reg; 60 61 if (!pdev) { 62 reg_alert("pdev is NULL"); 63 return NULL; 64 } 65 66 pdev_reg = wlan_objmgr_pdev_get_comp_private_obj( 67 pdev, WLAN_UMAC_COMP_REGULATORY); 68 69 return pdev_reg; 70 } 71 72 /* 73 * reg_set_5dot9_ghz_chan_in_master_mode - Set 5.9GHz channels to operate 74 * in master mode. 75 * @soc_reg_obj - Pointer to soc_reg_obj. 76 * 77 * Return: void 78 * 79 */ 80 #ifdef CONFIG_REG_CLIENT 81 static void 82 reg_set_5dot9_ghz_chan_in_master_mode(struct wlan_regulatory_psoc_priv_obj 83 *soc_reg_obj) 84 { 85 soc_reg_obj->enable_5dot9_ghz_chan_in_master_mode = false; 86 } 87 #else 88 static void 89 reg_set_5dot9_ghz_chan_in_master_mode(struct wlan_regulatory_psoc_priv_obj 90 *soc_reg_obj) 91 { 92 soc_reg_obj->enable_5dot9_ghz_chan_in_master_mode = true; 93 } 94 #endif 95 96 QDF_STATUS wlan_regulatory_psoc_obj_created_notification( 97 struct wlan_objmgr_psoc *psoc, void *arg_list) 98 { 99 struct wlan_regulatory_psoc_priv_obj *soc_reg_obj; 100 struct regulatory_channel *mas_chan_list; 101 enum channel_enum chan_enum; 102 QDF_STATUS status; 103 uint8_t i; 104 uint8_t phy_cnt; 105 106 soc_reg_obj = qdf_mem_common_alloc(sizeof(*soc_reg_obj)); 107 if (!soc_reg_obj) 108 return QDF_STATUS_E_NOMEM; 109 110 soc_reg_obj->offload_enabled = false; 111 soc_reg_obj->psoc_ptr = psoc; 112 soc_reg_obj->dfs_enabled = true; 113 soc_reg_obj->band_capability = (BIT(REG_BAND_2G) | BIT(REG_BAND_5G) | 114 BIT(REG_BAND_6G)); 115 soc_reg_obj->enable_11d_supp = false; 116 soc_reg_obj->indoor_chan_enabled = true; 117 soc_reg_obj->force_ssc_disable_indoor_channel = false; 118 soc_reg_obj->vdev_cnt_11d = 0; 119 soc_reg_obj->vdev_id_for_11d_scan = INVALID_VDEV_ID; 120 soc_reg_obj->restart_beaconing = CH_AVOID_RULE_RESTART; 121 soc_reg_obj->enable_srd_chan_in_master_mode = 0xFF; 122 soc_reg_obj->enable_11d_in_world_mode = false; 123 soc_reg_obj->five_dot_nine_ghz_supported = false; 124 reg_set_5dot9_ghz_chan_in_master_mode(soc_reg_obj); 125 soc_reg_obj->retain_nol_across_regdmn_update = false; 126 soc_reg_obj->is_ext_tpc_supported = false; 127 soc_reg_obj->sta_sap_scc_on_indoor_channel = true; 128 soc_reg_obj->set_fcc_channel = false; 129 soc_reg_obj->p2p_indoor_ch_support = false; 130 131 for (i = 0; i < MAX_STA_VDEV_CNT; i++) 132 soc_reg_obj->vdev_ids_11d[i] = INVALID_VDEV_ID; 133 134 qdf_spinlock_create(&soc_reg_obj->cbk_list_lock); 135 136 for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) { 137 mas_chan_list = 138 soc_reg_obj->mas_chan_params[phy_cnt].mas_chan_list; 139 soc_reg_obj->chan_list_recvd[phy_cnt] = false; 140 141 for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) { 142 mas_chan_list[chan_enum].chan_flags |= 143 REGULATORY_CHAN_DISABLED; 144 mas_chan_list[chan_enum].state = CHANNEL_STATE_DISABLE; 145 mas_chan_list[chan_enum].nol_chan = false; 146 } 147 } 148 149 status = wlan_objmgr_psoc_component_obj_attach( 150 psoc, WLAN_UMAC_COMP_REGULATORY, soc_reg_obj, 151 QDF_STATUS_SUCCESS); 152 if (QDF_IS_STATUS_ERROR(status)) { 153 qdf_spinlock_destroy(&soc_reg_obj->cbk_list_lock); 154 qdf_mem_common_free(soc_reg_obj); 155 reg_err("Obj attach failed"); 156 return status; 157 } 158 159 reg_debug("reg psoc obj created with status %d", status); 160 161 return status; 162 } 163 164 QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification( 165 struct wlan_objmgr_psoc *psoc, void *arg_list) 166 { 167 QDF_STATUS status; 168 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 169 170 psoc_priv_obj = reg_get_psoc_obj(psoc); 171 if (!psoc_priv_obj) { 172 reg_err_rl("NULL reg psoc priv obj"); 173 return QDF_STATUS_E_FAULT; 174 } 175 176 psoc_priv_obj->psoc_ptr = NULL; 177 qdf_spinlock_destroy(&psoc_priv_obj->cbk_list_lock); 178 179 status = wlan_objmgr_psoc_component_obj_detach( 180 psoc, WLAN_UMAC_COMP_REGULATORY, psoc_priv_obj); 181 182 if (status != QDF_STATUS_SUCCESS) 183 reg_err_rl("psoc_priv_obj private obj detach failed"); 184 185 reg_debug("reg psoc obj detached"); 186 187 qdf_mem_common_free(psoc_priv_obj); 188 189 return status; 190 } 191 192 #ifdef DISABLE_UNII_SHARED_BANDS 193 /** 194 * reg_reset_unii_5g_bitmap() - Reset the value of unii_5g_bitmap. 195 * @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj. 196 * 197 * Return : void 198 */ 199 static void 200 reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 201 { 202 pdev_priv_obj->unii_5g_bitmap = 0x0; 203 } 204 #else 205 static void inline 206 reg_reset_unii_5g_bitmap(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 207 { 208 } 209 #endif 210 211 #if defined(CONFIG_BAND_6GHZ) 212 #if defined(CONFIG_REG_CLIENT) 213 /** 214 * reg_init_def_client_type() - Initialize the regulatory 6G client type. 215 * 216 * @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj. 217 * 218 * Return : void 219 */ 220 static void 221 reg_init_def_client_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 222 { 223 pdev_priv_obj->reg_cur_6g_client_mobility_type = REG_DEFAULT_CLIENT; 224 } 225 #else 226 static void 227 reg_init_def_client_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 228 { 229 pdev_priv_obj->reg_cur_6g_client_mobility_type = REG_SUBORDINATE_CLIENT; 230 } 231 #endif 232 233 /** 234 * reg_init_6g_vars() - Initialize the regulatory 6G variables viz. 235 * AP power type, client mobility type, rnr tpe usable and unspecified ap 236 * usable. 237 * @pdev_priv_obj: pointer to wlan_regulatory_pdev_priv_obj. 238 * 239 * Return : void 240 */ 241 static void 242 reg_init_6g_vars(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 243 { 244 reg_set_ap_pwr_type(pdev_priv_obj); 245 pdev_priv_obj->reg_rnr_tpe_usable = false; 246 pdev_priv_obj->reg_unspecified_ap_usable = false; 247 reg_init_def_client_type(pdev_priv_obj); 248 } 249 #else 250 static void 251 reg_init_6g_vars(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 252 { 253 } 254 #endif 255 256 #ifdef CONFIG_AFC_SUPPORT 257 static void 258 reg_create_afc_cb_spinlock(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 259 { 260 qdf_spinlock_create(&pdev_priv_obj->afc_cb_lock); 261 } 262 263 static void 264 reg_destroy_afc_cb_spinlock(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 265 { 266 qdf_spinlock_destroy(&pdev_priv_obj->afc_cb_lock); 267 } 268 269 static void 270 reg_init_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 271 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 272 { 273 pdev_priv_obj->is_reg_noaction_on_afc_pwr_evt = 274 psoc_priv_obj->is_afc_reg_noaction; 275 } 276 277 static inline void 278 reg_set_pdev_afc_dev_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 279 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj) 280 { 281 pdev_priv_obj->reg_afc_dev_deployment_type = 282 psoc_priv_obj->reg_afc_dev_type; 283 } 284 #else 285 static inline void 286 reg_create_afc_cb_spinlock(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 287 { 288 } 289 290 static inline void 291 reg_destroy_afc_cb_spinlock(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 292 { 293 } 294 295 static void 296 reg_init_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 297 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 298 { 299 } 300 301 static inline void 302 reg_set_pdev_afc_dev_type(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj, 303 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj) 304 { 305 } 306 #endif 307 308 QDF_STATUS wlan_regulatory_pdev_obj_created_notification( 309 struct wlan_objmgr_pdev *pdev, void *arg_list) 310 { 311 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 312 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 313 struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap_ptr; 314 struct wlan_objmgr_psoc *parent_psoc; 315 uint8_t pdev_id; 316 uint8_t phy_id; 317 uint32_t cnt; 318 uint32_t range_2g_low, range_2g_high; 319 uint32_t range_5g_low, range_5g_high; 320 QDF_STATUS status; 321 struct wlan_lmac_if_reg_tx_ops *tx_ops; 322 enum direction dir; 323 wlan_objmgr_ref_dbgid dbg_id; 324 325 pdev_priv_obj = qdf_mem_common_alloc(sizeof(*pdev_priv_obj)); 326 if (!pdev_priv_obj) 327 return QDF_STATUS_E_NOMEM; 328 329 parent_psoc = wlan_pdev_get_psoc(pdev); 330 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 331 tx_ops = reg_get_psoc_tx_ops(parent_psoc); 332 333 if (tx_ops->get_phy_id_from_pdev_id) 334 tx_ops->get_phy_id_from_pdev_id(parent_psoc, pdev_id, &phy_id); 335 else 336 phy_id = pdev_id; 337 338 psoc_priv_obj = reg_get_psoc_obj(parent_psoc); 339 if (!psoc_priv_obj) { 340 reg_err("reg psoc private obj is NULL"); 341 qdf_mem_common_free(pdev_priv_obj); 342 return QDF_STATUS_E_FAULT; 343 } 344 345 pdev_priv_obj->pdev_ptr = pdev; 346 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 347 pdev_priv_obj->set_fcc_channel = psoc_priv_obj->set_fcc_channel; 348 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 349 pdev_priv_obj->indoor_chan_enabled = 350 psoc_priv_obj->indoor_chan_enabled; 351 reg_set_keep_6ghz_sta_cli_connection(pdev, false); 352 353 reg_set_pdev_afc_dev_type(pdev_priv_obj, psoc_priv_obj); 354 355 pdev_priv_obj->en_chan_144 = true; 356 reg_reset_unii_5g_bitmap(pdev_priv_obj); 357 358 qdf_spinlock_create(&pdev_priv_obj->reg_rules_lock); 359 reg_create_afc_cb_spinlock(pdev_priv_obj); 360 361 reg_cap_ptr = psoc_priv_obj->reg_cap; 362 pdev_priv_obj->force_ssc_disable_indoor_channel = 363 psoc_priv_obj->force_ssc_disable_indoor_channel; 364 pdev_priv_obj->sta_sap_scc_on_indoor_channel = 365 psoc_priv_obj->sta_sap_scc_on_indoor_channel; 366 pdev_priv_obj->p2p_indoor_ch_support = 367 psoc_priv_obj->p2p_indoor_ch_support; 368 369 for (cnt = 0; cnt < PSOC_MAX_PHY_REG_CAP; cnt++) { 370 if (!reg_cap_ptr) { 371 qdf_mem_common_free(pdev_priv_obj); 372 reg_err("reg cap ptr is NULL"); 373 return QDF_STATUS_E_FAULT; 374 } 375 376 if (reg_cap_ptr->phy_id == phy_id) 377 break; 378 reg_cap_ptr++; 379 } 380 381 if (cnt == PSOC_MAX_PHY_REG_CAP) { 382 qdf_mem_common_free(pdev_priv_obj); 383 reg_err("extended capabilities not found for pdev"); 384 return QDF_STATUS_E_FAULT; 385 } 386 387 range_2g_low = reg_cap_ptr->low_2ghz_chan; 388 range_2g_high = reg_cap_ptr->high_2ghz_chan; 389 range_5g_low = reg_cap_ptr->low_5ghz_chan; 390 range_5g_high = reg_cap_ptr->high_5ghz_chan; 391 392 pdev_priv_obj->range_2g_low = range_2g_low; 393 pdev_priv_obj->range_2g_high = range_2g_high; 394 pdev_priv_obj->range_5g_low = range_5g_low; 395 pdev_priv_obj->range_5g_high = range_5g_high; 396 pdev_priv_obj->wireless_modes = reg_cap_ptr->wireless_modes; 397 reg_init_6g_vars(pdev_priv_obj); 398 pdev_priv_obj->chan_list_recvd = 399 psoc_priv_obj->chan_list_recvd[phy_id]; 400 401 status = wlan_objmgr_pdev_component_obj_attach( 402 pdev, WLAN_UMAC_COMP_REGULATORY, pdev_priv_obj, 403 QDF_STATUS_SUCCESS); 404 if (QDF_IS_STATUS_ERROR(status)) { 405 reg_err("Obj attach failed"); 406 qdf_mem_common_free(pdev_priv_obj); 407 return status; 408 } 409 410 if (psoc_priv_obj->offload_enabled) { 411 dbg_id = WLAN_REGULATORY_NB_ID; 412 dir = NORTHBOUND; 413 } else { 414 dbg_id = WLAN_REGULATORY_SB_ID; 415 dir = SOUTHBOUND; 416 } 417 418 wlan_objmgr_pdev_get_ref(pdev, dbg_id); 419 reg_propagate_mas_chan_list_to_pdev(parent_psoc, pdev, &dir); 420 wlan_objmgr_pdev_release_ref(pdev, dbg_id); 421 422 reg_init_afc_vars(psoc_priv_obj, pdev_priv_obj); 423 424 if (!psoc_priv_obj->is_11d_offloaded) 425 reg_11d_host_scan_init(parent_psoc); 426 427 reg_debug("reg pdev obj created with status %d", status); 428 429 return status; 430 } 431 432 #ifdef CONFIG_AFC_SUPPORT 433 /** 434 * reg_free_chan_obj() - Free the AFC chan object and chan eirp object 435 * information 436 * @afc_chan_info: Pointer to afc_chan_info 437 * 438 * Return: void 439 */ 440 static void reg_free_chan_obj(struct afc_chan_obj *afc_chan_info) 441 { 442 if (afc_chan_info->chan_eirp_info) 443 qdf_mem_free(afc_chan_info->chan_eirp_info); 444 } 445 446 /** 447 * reg_free_afc_pwr_info() - Free the AFC power information object 448 * @pdev_priv_obj: Pointer to pdev_priv_obj 449 * 450 * Return: void 451 */ 452 void 453 reg_free_afc_pwr_info(struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 454 { 455 struct reg_fw_afc_power_event *power_info; 456 uint8_t i; 457 458 power_info = pdev_priv_obj->power_info; 459 if (!power_info) 460 return; 461 462 if (power_info->afc_freq_info) 463 qdf_mem_free(power_info->afc_freq_info); 464 465 if (!power_info->afc_chan_info) 466 return; 467 468 for (i = 0; i < power_info->num_chan_objs; i++) 469 reg_free_chan_obj(&power_info->afc_chan_info[i]); 470 471 if (power_info->afc_chan_info) 472 qdf_mem_free(power_info->afc_chan_info); 473 474 qdf_mem_free(power_info); 475 pdev_priv_obj->power_info = NULL; 476 } 477 #endif 478 479 QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification( 480 struct wlan_objmgr_pdev *pdev, void *arg_list) 481 { 482 QDF_STATUS status; 483 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 484 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 485 uint32_t pdev_id; 486 487 pdev_priv_obj = reg_get_pdev_obj(pdev); 488 489 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 490 491 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 492 reg_err("reg pdev private obj is NULL"); 493 return QDF_STATUS_E_FAILURE; 494 } 495 496 psoc_priv_obj = reg_get_psoc_obj(wlan_pdev_get_psoc(pdev)); 497 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 498 reg_err("reg psoc private obj is NULL"); 499 return QDF_STATUS_E_FAILURE; 500 } 501 502 if (!psoc_priv_obj->is_11d_offloaded) 503 reg_11d_host_scan_deinit(wlan_pdev_get_psoc(pdev)); 504 505 reg_free_afc_pwr_info(pdev_priv_obj); 506 pdev_priv_obj->pdev_ptr = NULL; 507 508 status = wlan_objmgr_pdev_component_obj_detach( 509 pdev, WLAN_UMAC_COMP_REGULATORY, pdev_priv_obj); 510 511 if (status != QDF_STATUS_SUCCESS) 512 reg_err("reg pdev private obj detach failed"); 513 514 reg_debug("reg pdev obj deleted"); 515 516 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 517 reg_reset_reg_rules(&pdev_priv_obj->reg_rules); 518 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 519 520 reg_destroy_afc_cb_spinlock(pdev_priv_obj); 521 qdf_spinlock_destroy(&pdev_priv_obj->reg_rules_lock); 522 523 qdf_mem_common_free(pdev_priv_obj); 524 525 return status; 526 } 527