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