1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 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_utils.c 22 * This file defines the APIs to set and get the regulatory variables. 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 "reg_priv_objs.h" 30 #include "reg_utils.h" 31 #include "reg_callbacks.h" 32 #include "reg_db.h" 33 #include "reg_db_parser.h" 34 #include "reg_host_11d.h" 35 #include <scheduler_api.h> 36 #include <wlan_reg_services_api.h> 37 #include <qdf_platform.h> 38 #include "reg_services_common.h" 39 #include "reg_build_chan_list.h" 40 #include "wlan_cm_bss_score_param.h" 41 #include "qdf_str.h" 42 #include "wmi_unified_param.h" 43 44 #define DEFAULT_WORLD_REGDMN 0x60 45 #define FCC3_FCCA 0x3A 46 #define FCC6_FCCA 0x14 47 48 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) 49 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) 50 51 #ifdef CONFIG_CHAN_FREQ_API 52 bool reg_chan_has_dfs_attribute_for_freq(struct wlan_objmgr_pdev *pdev, 53 qdf_freq_t freq) 54 { 55 enum channel_enum ch_idx; 56 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 57 58 ch_idx = reg_get_chan_enum_for_freq(freq); 59 60 if (reg_is_chan_enum_invalid(ch_idx)) 61 return false; 62 63 pdev_priv_obj = reg_get_pdev_obj(pdev); 64 65 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 66 reg_err("pdev reg obj is NULL"); 67 return false; 68 } 69 70 if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags & 71 REGULATORY_CHAN_RADAR) 72 return true; 73 74 return false; 75 } 76 #endif /* CONFIG_CHAN_FREQ_API */ 77 78 bool reg_is_world_ctry_code(uint16_t ctry_code) 79 { 80 if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN) 81 return true; 82 83 return false; 84 } 85 86 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc, 87 uint8_t *country_code) 88 { 89 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 90 91 if (!country_code) { 92 reg_err("country_code is NULL"); 93 return QDF_STATUS_E_INVAL; 94 } 95 96 psoc_reg = reg_get_psoc_obj(psoc); 97 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 98 reg_err("psoc reg component is NULL"); 99 return QDF_STATUS_E_INVAL; 100 } 101 102 qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1); 103 104 return QDF_STATUS_SUCCESS; 105 } 106 107 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc, 108 uint8_t *country) 109 { 110 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 111 112 if (!country) { 113 reg_err("country is NULL"); 114 return QDF_STATUS_E_INVAL; 115 } 116 117 psoc_reg = reg_get_psoc_obj(psoc); 118 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 119 reg_err("psoc reg component is NULL"); 120 return QDF_STATUS_E_INVAL; 121 } 122 123 reg_info("set default_country: %s", country); 124 125 qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1); 126 127 return QDF_STATUS_SUCCESS; 128 } 129 130 bool reg_is_world_alpha2(uint8_t *alpha2) 131 { 132 if ((alpha2[0] == '0') && (alpha2[1] == '0')) 133 return true; 134 135 return false; 136 } 137 138 bool reg_is_us_alpha2(uint8_t *alpha2) 139 { 140 if ((alpha2[0] == 'U') && (alpha2[1] == 'S')) 141 return true; 142 143 return false; 144 } 145 146 bool reg_is_etsi_alpha2(uint8_t *alpha2) 147 { 148 if ((alpha2[0] == 'G') && (alpha2[1] == 'B')) 149 return true; 150 151 return false; 152 } 153 154 static 155 const char *reg_get_power_mode_string(uint16_t reg_dmn_pair_id) 156 { 157 switch (reg_dmn_pair_id) { 158 case FCC3_FCCA: 159 case FCC6_FCCA: 160 return "NON_VLP"; 161 default: 162 return "VLP"; 163 } 164 } 165 166 static bool reg_ctry_domain_supports_vlp(uint8_t *alpha2) 167 { 168 uint16_t i; 169 int no_of_countries; 170 171 reg_get_num_countries(&no_of_countries); 172 for (i = 0; i < no_of_countries; i++) { 173 if (g_all_countries[i].alpha2[0] == alpha2[0] && 174 g_all_countries[i].alpha2[1] == alpha2[1]) { 175 if (!qdf_str_cmp(reg_get_power_mode_string( 176 g_all_countries[i].reg_dmn_pair_id), "NON_VLP")) 177 return false; 178 else 179 return true; 180 } 181 } 182 return true; 183 } 184 185 bool reg_ctry_support_vlp(uint8_t *alpha2) 186 { 187 if (((alpha2[0] == 'A') && (alpha2[1] == 'E')) || 188 ((alpha2[0] == 'P') && (alpha2[1] == 'E')) || 189 ((alpha2[0] == 'U') && (alpha2[1] == 'S')) || 190 !reg_ctry_domain_supports_vlp(alpha2)) 191 return false; 192 else 193 return true; 194 } 195 196 static QDF_STATUS reg_set_non_offload_country(struct wlan_objmgr_pdev *pdev, 197 struct set_country *cc) 198 { 199 struct wlan_objmgr_psoc *psoc; 200 struct wlan_lmac_if_reg_tx_ops *tx_ops; 201 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 202 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 203 struct cc_regdmn_s rd; 204 uint8_t pdev_id; 205 uint8_t phy_id; 206 207 if (!pdev) { 208 reg_err("pdev is NULL"); 209 return QDF_STATUS_E_INVAL; 210 } 211 212 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 213 psoc = wlan_pdev_get_psoc(pdev); 214 tx_ops = reg_get_psoc_tx_ops(psoc); 215 if (tx_ops->get_phy_id_from_pdev_id) 216 tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); 217 else 218 phy_id = pdev_id; 219 220 psoc_reg = reg_get_psoc_obj(psoc); 221 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 222 reg_err("psoc reg component is NULL"); 223 return QDF_STATUS_E_INVAL; 224 } 225 226 if (reg_is_world_alpha2(cc->country)) { 227 pdev_priv_obj = reg_get_pdev_obj(pdev); 228 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 229 reg_err("reg component pdev priv is NULL"); 230 psoc_reg->world_country_pending[phy_id] = false; 231 return QDF_STATUS_E_INVAL; 232 } 233 if (reg_is_world_ctry_code(pdev_priv_obj->def_region_domain)) 234 rd.cc.regdmn.reg_2g_5g_pair_id = 235 pdev_priv_obj->def_region_domain; 236 else 237 rd.cc.regdmn.reg_2g_5g_pair_id = DEFAULT_WORLD_REGDMN; 238 rd.flags = REGDMN_IS_SET; 239 } else { 240 qdf_mem_copy(rd.cc.alpha, cc->country, REG_ALPHA2_LEN + 1); 241 rd.flags = ALPHA_IS_SET; 242 } 243 244 reg_program_chan_list(pdev, &rd); 245 return QDF_STATUS_SUCCESS; 246 } 247 248 #ifdef WLAN_REG_PARTIAL_OFFLOAD 249 /** 250 * reg_restore_def_country_for_po() - API to restore country code to default 251 * value if given country is invalid for Partial Offload 252 * @offload_enabled: Is offload enabled 253 * @country: Country code 254 * @cc_country: Country code array 255 * Return- void 256 */ 257 static void reg_restore_def_country_for_po(bool offload_enabled, 258 uint8_t *country, 259 uint8_t cc_country[]){ 260 if (!offload_enabled && !reg_is_world_alpha2(country)) { 261 QDF_STATUS status; 262 263 status = reg_is_country_code_valid(country); 264 if (!QDF_IS_STATUS_SUCCESS(status)) { 265 reg_err("Unable to set country code: %s\n", country); 266 reg_err("Restoring to world domain"); 267 qdf_mem_copy(cc_country, REG_WORLD_ALPHA2, 268 REG_ALPHA2_LEN + 1); 269 } 270 } 271 } 272 #else 273 static void reg_restore_def_country_for_po(bool offload_enabled, 274 uint8_t *country, 275 uint8_t cc_country[]){ 276 } 277 #endif 278 279 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, 280 uint8_t *country) 281 { 282 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 283 struct wlan_lmac_if_reg_tx_ops *tx_ops; 284 struct set_country cc; 285 struct wlan_objmgr_psoc *psoc; 286 uint8_t pdev_id; 287 uint8_t phy_id; 288 289 if (!pdev) { 290 reg_err("pdev is NULL"); 291 return QDF_STATUS_E_INVAL; 292 } 293 294 if (!country) { 295 reg_err("country code is NULL"); 296 return QDF_STATUS_E_INVAL; 297 } 298 299 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 300 301 psoc = wlan_pdev_get_psoc(pdev); 302 303 tx_ops = reg_get_psoc_tx_ops(psoc); 304 if (tx_ops->get_phy_id_from_pdev_id) 305 tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); 306 else 307 phy_id = pdev_id; 308 309 psoc_reg = reg_get_psoc_obj(psoc); 310 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 311 reg_err("psoc reg component is NULL"); 312 return QDF_STATUS_E_INVAL; 313 } 314 315 if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) { 316 if (psoc_reg->cc_src == SOURCE_USERSPACE || 317 psoc_reg->cc_src == SOURCE_CORE) { 318 reg_debug("country is not different"); 319 return QDF_STATUS_E_INVAL; 320 } 321 } 322 323 reg_debug("programming new country: %s to firmware", country); 324 325 qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1); 326 /* 327 * Need firmware to send channel list event 328 * for all phys. Therefore set pdev_id to 0xFF. 329 */ 330 cc.pdev_id = WMI_HOST_PDEV_ID_SOC; 331 332 reg_restore_def_country_for_po(psoc_reg->offload_enabled, 333 country, 334 cc.country); 335 336 if (reg_is_world_alpha2(cc.country)) 337 psoc_reg->world_country_pending[phy_id] = true; 338 else 339 psoc_reg->new_user_ctry_pending[phy_id] = true; 340 341 if (psoc_reg->offload_enabled) { 342 tx_ops = reg_get_psoc_tx_ops(psoc); 343 if (tx_ops->set_country_code) { 344 tx_ops->set_country_code(psoc, &cc); 345 } else { 346 reg_err("country set fw handler not present"); 347 psoc_reg->new_user_ctry_pending[phy_id] = false; 348 return QDF_STATUS_E_FAULT; 349 } 350 } else { 351 return reg_set_non_offload_country(pdev, &cc); 352 } 353 354 return QDF_STATUS_SUCCESS; 355 } 356 357 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc) 358 { 359 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 360 361 psoc_reg = reg_get_psoc_obj(psoc); 362 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 363 reg_err("psoc reg component is NULL"); 364 return QDF_STATUS_E_INVAL; 365 } 366 367 qdf_mem_copy(psoc_reg->cur_country, 368 psoc_reg->def_country, 369 REG_ALPHA2_LEN + 1); 370 reg_debug("set cur_country %.2s", psoc_reg->cur_country); 371 372 return QDF_STATUS_SUCCESS; 373 } 374 375 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, 376 const uint8_t *country_alpha2, 377 enum country_src source) 378 { 379 if (!reg_domain_ptr) { 380 reg_err("Invalid reg domain pointer"); 381 return QDF_STATUS_E_FAULT; 382 } 383 384 *reg_domain_ptr = 0; 385 386 if (!country_alpha2) { 387 reg_err("Country code is NULL"); 388 return QDF_STATUS_E_FAULT; 389 } 390 391 return QDF_STATUS_SUCCESS; 392 } 393 394 #if defined(CONFIG_REG_CLIENT) && defined(CONFIG_BAND_6GHZ) 395 QDF_STATUS 396 reg_get_6ghz_cli_pwr_type_per_ap_pwr_type( 397 struct wlan_objmgr_pdev *pdev, 398 enum reg_6g_ap_type ap_pwr_type, 399 enum supported_6g_pwr_types *cli_pwr_type) 400 { 401 enum reg_6g_client_type client_type; 402 403 reg_get_cur_6g_client_type(pdev, &client_type); 404 405 if (client_type == REG_DEFAULT_CLIENT) { 406 if (ap_pwr_type == REG_INDOOR_AP) 407 *cli_pwr_type = REG_CLI_DEF_LPI; 408 else if (ap_pwr_type == REG_VERY_LOW_POWER_AP) 409 *cli_pwr_type = REG_CLI_DEF_VLP; 410 else if (ap_pwr_type == REG_STANDARD_POWER_AP) 411 *cli_pwr_type = REG_CLI_DEF_SP; 412 else 413 return QDF_STATUS_E_FAILURE; 414 } else if (client_type == REG_SUBORDINATE_CLIENT) { 415 if (ap_pwr_type == REG_INDOOR_AP) 416 *cli_pwr_type = REG_CLI_SUB_LPI; 417 else if (ap_pwr_type == REG_VERY_LOW_POWER_AP) 418 *cli_pwr_type = REG_CLI_SUB_VLP; 419 else if (ap_pwr_type == REG_STANDARD_POWER_AP) 420 *cli_pwr_type = REG_CLI_SUB_SP; 421 else 422 return QDF_STATUS_E_FAILURE; 423 } else { 424 return QDF_STATUS_E_FAILURE; 425 } 426 427 return QDF_STATUS_SUCCESS; 428 } 429 #endif 430 431 #ifdef CONFIG_REG_CLIENT 432 #ifdef CONFIG_BAND_6GHZ 433 /** 434 * reg_check_if_6g_pwr_type_supp_for_chan() - Check if 6 GHz power type is 435 * supported for the channel 436 * @pdev: Pointer to pdev 437 * @pwr_type: 6 GHz power type 438 * @chan_idx: Connection channel index 439 * 440 * Return: Return QDF_STATUS_SUCCESS if 6 GHz power type supported for 441 * the given channel, else return QDF_STATUS_E_FAILURE. 442 */ 443 static 444 QDF_STATUS reg_check_if_6g_pwr_type_supp_for_chan( 445 struct wlan_objmgr_pdev *pdev, 446 enum reg_6g_ap_type pwr_type, 447 enum channel_enum chan_idx) 448 { 449 struct super_chan_info *super_chan_list; 450 enum channel_state *chan_state_arr; 451 uint32_t *chan_flags_arr; 452 enum supported_6g_pwr_types cli_pwr_type; 453 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 454 uint16_t sup_idx; 455 456 pdev_priv_obj = reg_get_pdev_obj(pdev); 457 if (!pdev_priv_obj) { 458 reg_err("pdev priv obj null"); 459 return QDF_STATUS_E_FAILURE; 460 } 461 462 sup_idx = reg_convert_enum_to_6g_idx(chan_idx); 463 if (sup_idx >= NUM_6GHZ_CHANNELS) { 464 reg_err("Invalid channel"); 465 return QDF_STATUS_E_NOSUPPORT; 466 } 467 468 if (QDF_IS_STATUS_ERROR(reg_get_6ghz_cli_pwr_type_per_ap_pwr_type( 469 pdev, pwr_type, &cli_pwr_type))) 470 goto no_support; 471 472 super_chan_list = pdev_priv_obj->super_chan_list; 473 chan_state_arr = super_chan_list[sup_idx].state_arr; 474 chan_flags_arr = super_chan_list[sup_idx].chan_flags_arr; 475 if (reg_is_state_allowed(chan_state_arr[cli_pwr_type]) && 476 !(chan_flags_arr[cli_pwr_type] & REGULATORY_CHAN_DISABLED)) 477 return QDF_STATUS_SUCCESS; 478 479 no_support: 480 reg_err("6 GHz power type = %d not supported for 6 GHz channel idx = %d", 481 cli_pwr_type, sup_idx); 482 return QDF_STATUS_E_NOSUPPORT; 483 } 484 485 QDF_STATUS 486 reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc, 487 struct wlan_objmgr_pdev *pdev, 488 enum reg_6g_ap_type *pwr_type_6g, 489 enum reg_6g_ap_type ap_pwr_type, 490 uint32_t chan_freq) 491 { 492 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 493 enum channel_enum chan_idx = reg_get_chan_enum_for_freq(chan_freq); 494 495 *pwr_type_6g = ap_pwr_type; 496 pdev_priv_obj = reg_get_pdev_obj(pdev); 497 if (!pdev_priv_obj) { 498 reg_err("pdev priv obj null"); 499 return QDF_STATUS_E_FAILURE; 500 } 501 502 /* 503 * If AP doesn't advertise 6 GHz power type or advertised invalid power 504 * type, select VLP power type if VLP rules are present for the 505 * connection channel, if not select LPI power type if LPI rules are 506 * present for connection channel, otherwise don't connect. 507 */ 508 if (ap_pwr_type < REG_INDOOR_AP || 509 ap_pwr_type >= REG_CURRENT_MAX_AP_TYPE) { 510 if (QDF_IS_STATUS_SUCCESS( 511 reg_check_if_6g_pwr_type_supp_for_chan(pdev, 512 REG_VERY_LOW_POWER_AP, 513 chan_idx))) { 514 reg_debug("Invalid AP power type: %d , selected power type: %d", 515 ap_pwr_type, REG_VERY_LOW_POWER_AP); 516 *pwr_type_6g = REG_VERY_LOW_POWER_AP; 517 return QDF_STATUS_SUCCESS; 518 } else if (QDF_IS_STATUS_SUCCESS( 519 reg_check_if_6g_pwr_type_supp_for_chan(pdev, 520 REG_INDOOR_AP, 521 chan_idx))) { 522 reg_debug("Invalid AP power type: %d , selected power type: %d", 523 ap_pwr_type, REG_INDOOR_AP); 524 *pwr_type_6g = REG_INDOOR_AP; 525 return QDF_STATUS_SUCCESS; 526 } else { 527 reg_err("Invalid AP power type: %d, couldn't find suitable power type", 528 ap_pwr_type); 529 return QDF_STATUS_E_NOSUPPORT; 530 } 531 } 532 533 if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type] && 534 QDF_IS_STATUS_SUCCESS(reg_check_if_6g_pwr_type_supp_for_chan( 535 pdev, 536 ap_pwr_type, chan_idx))) { 537 reg_debug("AP power type: %d , is supported by client", 538 ap_pwr_type); 539 return QDF_STATUS_SUCCESS; 540 } 541 542 if (ap_pwr_type == REG_INDOOR_AP) { 543 if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] && 544 QDF_IS_STATUS_SUCCESS( 545 reg_check_if_6g_pwr_type_supp_for_chan(pdev, 546 REG_VERY_LOW_POWER_AP, 547 chan_idx))) { 548 *pwr_type_6g = REG_VERY_LOW_POWER_AP; 549 reg_debug("AP power type = %d, selected power type = %d", 550 ap_pwr_type, *pwr_type_6g); 551 return QDF_STATUS_SUCCESS; 552 } else { 553 goto no_support; 554 } 555 } else if (ap_pwr_type == REG_STANDARD_POWER_AP) { 556 if (pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[REG_VERY_LOW_POWER_AP] && 557 QDF_IS_STATUS_SUCCESS( 558 reg_check_if_6g_pwr_type_supp_for_chan(pdev, 559 REG_VERY_LOW_POWER_AP, 560 chan_idx))) { 561 if (wlan_cm_get_disable_vlp_sta_conn_to_sp_ap(psoc)) { 562 reg_debug("AP SP and STA VLP connection disabled"); 563 return QDF_STATUS_E_NOSUPPORT; 564 } 565 *pwr_type_6g = REG_VERY_LOW_POWER_AP; 566 reg_debug("AP power type = %d, selected power type = %d", 567 ap_pwr_type, *pwr_type_6g); 568 return QDF_STATUS_SUCCESS; 569 } else { 570 goto no_support; 571 } 572 } 573 574 no_support: 575 reg_err("AP power type = %d, not supported", ap_pwr_type); 576 return QDF_STATUS_E_NOSUPPORT; 577 } 578 #else 579 QDF_STATUS 580 reg_get_best_6g_power_type(struct wlan_objmgr_psoc *psoc, 581 struct wlan_objmgr_pdev *pdev, 582 enum reg_6g_ap_type *pwr_type_6g, 583 enum reg_6g_ap_type ap_pwr_type, 584 uint32_t chan_freq) 585 { 586 return QDF_STATUS_SUCCESS; 587 } 588 #endif 589 #endif 590 591 #ifdef FEATURE_WLAN_CH_AVOID_EXT 592 static inline 593 void reg_get_coex_unsafe_chan_nb_user_prefer( 594 struct wlan_regulatory_psoc_priv_obj 595 *psoc_priv_obj, 596 struct reg_config_vars config_vars) 597 { 598 psoc_priv_obj->coex_unsafe_chan_nb_user_prefer = 599 config_vars.coex_unsafe_chan_nb_user_prefer; 600 } 601 602 static inline 603 void reg_get_coex_unsafe_chan_reg_disable( 604 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 605 struct reg_config_vars config_vars) 606 { 607 psoc_priv_obj->coex_unsafe_chan_reg_disable = 608 config_vars.coex_unsafe_chan_reg_disable; 609 } 610 #else 611 static inline 612 void reg_get_coex_unsafe_chan_nb_user_prefer( 613 struct wlan_regulatory_psoc_priv_obj 614 *psoc_priv_obj, 615 struct reg_config_vars config_vars) 616 { 617 } 618 619 static inline 620 void reg_get_coex_unsafe_chan_reg_disable( 621 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 622 struct reg_config_vars config_vars) 623 { 624 } 625 #endif 626 627 #ifdef CONFIG_CHAN_FREQ_API 628 bool reg_is_passive_or_disable_for_pwrmode( 629 struct wlan_objmgr_pdev *pdev, 630 qdf_freq_t freq, 631 enum supported_6g_pwr_types in_6g_pwr_mode) 632 { 633 enum channel_state chan_state; 634 635 chan_state = reg_get_channel_state_for_pwrmode(pdev, freq, 636 in_6g_pwr_mode); 637 638 return (chan_state == CHANNEL_STATE_DFS) || 639 (chan_state == CHANNEL_STATE_DISABLE); 640 } 641 #endif /* CONFIG_CHAN_FREQ_API */ 642 643 #ifdef WLAN_FEATURE_DSRC 644 #ifdef CONFIG_CHAN_FREQ_API 645 bool reg_is_dsrc_freq(qdf_freq_t freq) 646 { 647 if (!REG_IS_5GHZ_FREQ(freq)) 648 return false; 649 650 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 651 return false; 652 653 return true; 654 } 655 #endif /*CONFIG_CHAN_FREQ_API*/ 656 #else 657 bool reg_is_etsi_regdmn(struct wlan_objmgr_pdev *pdev) 658 { 659 struct cur_regdmn_info cur_reg_dmn; 660 QDF_STATUS status; 661 662 status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); 663 if (status != QDF_STATUS_SUCCESS) { 664 reg_debug_rl("Failed to get reg domain"); 665 return false; 666 } 667 668 return reg_etsi_regdmn(cur_reg_dmn.dmn_id_5g); 669 } 670 671 #ifdef CONFIG_CHAN_FREQ_API 672 bool reg_is_etsi_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, 673 uint16_t freq) 674 { 675 if (!REG_IS_5GHZ_FREQ(freq)) 676 return false; 677 678 if (!(freq >= REG_ETSI_SRD_START_FREQ && 679 freq <= REG_ETSI_SRD_END_FREQ)) 680 return false; 681 682 return reg_is_etsi_regdmn(pdev); 683 } 684 #endif /* CONFIG_CHAN_FREQ_API */ 685 686 bool reg_is_etsi_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) 687 { 688 struct wlan_objmgr_psoc *psoc; 689 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 690 691 if (!pdev) { 692 reg_alert("pdev is NULL"); 693 return true; 694 } 695 psoc = wlan_pdev_get_psoc(pdev); 696 697 psoc_priv_obj = reg_get_psoc_obj(psoc); 698 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 699 reg_alert("psoc reg component is NULL"); 700 return true; 701 } 702 703 return psoc_priv_obj->enable_srd_chan_in_master_mode && 704 reg_is_etsi_regdmn(pdev); 705 } 706 #endif 707 708 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap) 709 { 710 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 711 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 712 struct wlan_objmgr_psoc *psoc; 713 QDF_STATUS status; 714 715 pdev_priv_obj = reg_get_pdev_obj(pdev); 716 717 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 718 reg_err("pdev reg component is NULL"); 719 return QDF_STATUS_E_INVAL; 720 } 721 722 /* 723 * If SET_FCC_CHANNEL 0 command is received first then 6 GHz band would 724 * be disabled and band_capability would be set to 3 but existing 6 GHz 725 * STA and P2P client connections won't be disconnected. 726 * If set band comes again for 6 GHz band disabled and band_bitmap is 727 * equal to band_capability, proceed to disable 6 GHz band completely. 728 */ 729 if (pdev_priv_obj->band_capability == band_bitmap && 730 !reg_get_keep_6ghz_sta_cli_connection(pdev)) { 731 reg_info("same band %d", band_bitmap); 732 return QDF_STATUS_SUCCESS; 733 } 734 735 /* 736 * If in current band_capability 6 GHz bit is not set, in current 737 * request 6 GHz band might be enabled/disabled. Hence reset 738 * reg_set_keep_6ghz_sta_cli_connection flag. 739 */ 740 if (!reg_is_6ghz_band_set(pdev)) { 741 status = reg_set_keep_6ghz_sta_cli_connection(pdev, false); 742 if (QDF_IS_STATUS_ERROR(status)) 743 return status; 744 } 745 746 psoc = wlan_pdev_get_psoc(pdev); 747 if (!psoc) { 748 reg_err("psoc is NULL"); 749 return QDF_STATUS_E_INVAL; 750 } 751 752 psoc_priv_obj = reg_get_psoc_obj(psoc); 753 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 754 reg_err("psoc reg component is NULL"); 755 return QDF_STATUS_E_INVAL; 756 } 757 758 reg_info("set band bitmap: %d", band_bitmap); 759 pdev_priv_obj->band_capability = band_bitmap; 760 761 reg_compute_pdev_current_chan_list(pdev_priv_obj); 762 763 status = reg_send_scheduler_msg_sb(psoc, pdev); 764 765 return status; 766 } 767 768 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, 769 uint32_t *band_bitmap) 770 { 771 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 772 773 pdev_priv_obj = reg_get_pdev_obj(pdev); 774 775 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 776 reg_err("pdev reg component is NULL"); 777 return QDF_STATUS_E_INVAL; 778 } 779 780 reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability); 781 *band_bitmap = pdev_priv_obj->band_capability; 782 783 return QDF_STATUS_SUCCESS; 784 } 785 786 #ifdef DISABLE_CHANNEL_LIST 787 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 788 { 789 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 790 struct wlan_objmgr_psoc *psoc; 791 QDF_STATUS status; 792 793 pdev_priv_obj = reg_get_pdev_obj(pdev); 794 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 795 reg_err("pdev reg component is NULL"); 796 return QDF_STATUS_E_INVAL; 797 } 798 799 psoc = wlan_pdev_get_psoc(pdev); 800 if (!psoc) { 801 reg_err("psoc is NULL"); 802 return QDF_STATUS_E_INVAL; 803 } 804 805 pdev_priv_obj->disable_cached_channels = false; 806 reg_compute_pdev_current_chan_list(pdev_priv_obj); 807 status = reg_send_scheduler_msg_sb(psoc, pdev); 808 return status; 809 } 810 811 QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) 812 { 813 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 814 struct wlan_objmgr_psoc *psoc; 815 QDF_STATUS status; 816 817 pdev_priv_obj = reg_get_pdev_obj(pdev); 818 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 819 reg_err("pdev reg component is NULL"); 820 return QDF_STATUS_E_INVAL; 821 } 822 823 psoc = wlan_pdev_get_psoc(pdev); 824 if (!psoc) { 825 reg_err("psoc is NULL"); 826 return QDF_STATUS_E_INVAL; 827 } 828 829 pdev_priv_obj->disable_cached_channels = true; 830 reg_compute_pdev_current_chan_list(pdev_priv_obj); 831 status = reg_send_scheduler_msg_sb(psoc, pdev); 832 return status; 833 } 834 835 #ifdef CONFIG_CHAN_FREQ_API 836 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, 837 uint32_t *channel_list, 838 uint32_t num_channels) 839 { 840 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 841 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 842 struct wlan_objmgr_psoc *psoc; 843 uint16_t i, j; 844 845 pdev_priv_obj = reg_get_pdev_obj(pdev); 846 847 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 848 reg_err("pdev reg component is NULL"); 849 return QDF_STATUS_E_INVAL; 850 } 851 852 psoc = wlan_pdev_get_psoc(pdev); 853 if (!psoc) { 854 reg_err("psoc is NULL"); 855 return QDF_STATUS_E_INVAL; 856 } 857 858 psoc_priv_obj = reg_get_psoc_obj(psoc); 859 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 860 reg_err("psoc reg component is NULL"); 861 return QDF_STATUS_E_INVAL; 862 } 863 if (pdev_priv_obj->num_cache_channels > 0) { 864 pdev_priv_obj->num_cache_channels = 0; 865 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 866 sizeof(pdev_priv_obj->cache_disable_chan_list)); 867 } 868 869 for (i = 0; i < num_channels; i++) { 870 for (j = 0; j < NUM_CHANNELS; j++) { 871 if (channel_list[i] == pdev_priv_obj-> 872 cur_chan_list[j].center_freq) { 873 pdev_priv_obj-> 874 cache_disable_chan_list[i].center_freq = 875 channel_list[i]; 876 pdev_priv_obj-> 877 cache_disable_chan_list[i].state = 878 pdev_priv_obj->cur_chan_list[j].state; 879 pdev_priv_obj-> 880 cache_disable_chan_list[i].chan_flags = 881 pdev_priv_obj-> 882 cur_chan_list[j].chan_flags; 883 } 884 } 885 } 886 pdev_priv_obj->num_cache_channels = num_channels; 887 888 return QDF_STATUS_SUCCESS; 889 } 890 #endif /* CONFIG_CHAN_FREQ_API */ 891 #endif 892 893 #ifdef CONFIG_REG_CLIENT 894 bool reg_get_keep_6ghz_sta_cli_connection(struct wlan_objmgr_pdev *pdev) 895 { 896 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 897 898 pdev_priv_obj = reg_get_pdev_obj(pdev); 899 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 900 reg_err("pdev reg component is NULL"); 901 return false; 902 } 903 904 return pdev_priv_obj->keep_6ghz_sta_cli_connection; 905 } 906 907 QDF_STATUS reg_set_keep_6ghz_sta_cli_connection(struct wlan_objmgr_pdev *pdev, 908 bool keep_6ghz_sta_cli_connection) 909 { 910 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 911 912 pdev_priv_obj = reg_get_pdev_obj(pdev); 913 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 914 reg_err("pdev reg component is NULL"); 915 return QDF_STATUS_E_INVAL; 916 } 917 918 pdev_priv_obj->keep_6ghz_sta_cli_connection = 919 keep_6ghz_sta_cli_connection; 920 921 reg_debug("set keep_6ghz_sta_cli_connection = %d", 922 keep_6ghz_sta_cli_connection); 923 return QDF_STATUS_SUCCESS; 924 } 925 926 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 927 bool fcc_constraint) 928 { 929 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 930 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 931 struct wlan_objmgr_psoc *psoc; 932 933 pdev_priv_obj = reg_get_pdev_obj(pdev); 934 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 935 reg_err("pdev reg component is NULL"); 936 return QDF_STATUS_E_INVAL; 937 } 938 939 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 940 reg_debug("same fcc_constraint %d", fcc_constraint); 941 return QDF_STATUS_SUCCESS; 942 } 943 944 reg_debug("set fcc_constraint: %d", fcc_constraint); 945 946 psoc = wlan_pdev_get_psoc(pdev); 947 if (!psoc) { 948 reg_err("psoc is NULL"); 949 return QDF_STATUS_E_INVAL; 950 } 951 952 psoc_priv_obj = reg_get_psoc_obj(psoc); 953 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 954 reg_err("psoc reg component is NULL"); 955 return QDF_STATUS_E_INVAL; 956 } 957 958 psoc_priv_obj->set_fcc_channel = fcc_constraint; 959 pdev_priv_obj->set_fcc_channel = fcc_constraint; 960 961 return QDF_STATUS_SUCCESS; 962 } 963 964 bool reg_is_6ghz_band_set(struct wlan_objmgr_pdev *pdev) 965 { 966 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 967 968 pdev_priv_obj = reg_get_pdev_obj(pdev); 969 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 970 reg_err("pdev reg component is NULL"); 971 return false; 972 } 973 974 if (!(pdev_priv_obj->band_capability & BIT(REG_BAND_6G))) 975 return false; 976 977 return true; 978 } 979 980 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) 981 { 982 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 983 984 pdev_priv_obj = reg_get_pdev_obj(pdev); 985 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 986 reg_err("pdev reg component is NULL"); 987 return false; 988 } 989 990 if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ) 991 return false; 992 993 if (!pdev_priv_obj->set_fcc_channel) 994 return false; 995 996 return true; 997 } 998 999 uint32_t reg_get_country_max_allowed_bw(struct wlan_objmgr_pdev *pdev) 1000 { 1001 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 1002 struct wlan_objmgr_psoc *psoc; 1003 1004 psoc = wlan_pdev_get_psoc(pdev); 1005 if (!psoc) { 1006 reg_err("psoc is NULL"); 1007 return 0; 1008 } 1009 1010 psoc_priv_obj = reg_get_psoc_obj(psoc); 1011 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 1012 reg_err("psoc reg component is NULL"); 1013 return 0; 1014 } 1015 1016 return psoc_priv_obj->country_max_allowed_bw; 1017 } 1018 1019 bool reg_is_user_country_set_allowed(struct wlan_objmgr_psoc *psoc) 1020 { 1021 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 1022 1023 psoc_reg = reg_get_psoc_obj(psoc); 1024 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 1025 reg_err("psoc reg component is NULL"); 1026 return false; 1027 } 1028 1029 if (!psoc_reg->user_ctry_priority && 1030 psoc_reg->enable_11d_supp_original) { 1031 reg_err_rl("country set from userspace is not allowed"); 1032 return false; 1033 } 1034 1035 return true; 1036 } 1037 1038 bool reg_is_fcc_constraint_set(struct wlan_objmgr_pdev *pdev) 1039 { 1040 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 1041 1042 pdev_priv_obj = reg_get_pdev_obj(pdev); 1043 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 1044 reg_err("pdev reg component is NULL"); 1045 return false; 1046 } 1047 1048 if (!pdev_priv_obj->set_fcc_channel) 1049 return false; 1050 1051 return true; 1052 } 1053 #endif /* CONFIG_REG_CLIENT */ 1054 1055 /** 1056 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 1057 * @psoc: Pointer to global psoc structure. 1058 * @object: Pointer to global pdev structure. 1059 * @arg: Pointer to argument list. 1060 */ 1061 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 1062 void *object, void *arg) 1063 { 1064 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 1065 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 1066 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 1067 1068 psoc_priv_obj = reg_get_psoc_obj(psoc); 1069 if (!psoc_priv_obj) { 1070 reg_err("psoc priv obj is NULL"); 1071 return; 1072 } 1073 1074 pdev_priv_obj = reg_get_pdev_obj(pdev); 1075 1076 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 1077 reg_err("reg pdev private obj is NULL"); 1078 return; 1079 } 1080 1081 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 1082 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 1083 pdev_priv_obj->force_ssc_disable_indoor_channel = 1084 psoc_priv_obj->force_ssc_disable_indoor_channel; 1085 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 1086 pdev_priv_obj->sta_sap_scc_on_indoor_channel = 1087 psoc_priv_obj->sta_sap_scc_on_indoor_channel; 1088 pdev_priv_obj->p2p_indoor_ch_support = 1089 psoc_priv_obj->p2p_indoor_ch_support; 1090 1091 reg_compute_pdev_current_chan_list(pdev_priv_obj); 1092 1093 reg_send_scheduler_msg_sb(psoc, pdev); 1094 } 1095 1096 #if defined(CONFIG_BAND_6GHZ) && defined(CONFIG_AFC_SUPPORT) 1097 static inline void 1098 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 1099 struct reg_config_vars *config_vars) 1100 { 1101 psoc_priv_obj->enable_6ghz_sp_pwrmode_supp = 1102 config_vars->enable_6ghz_sp_pwrmode_supp; 1103 psoc_priv_obj->afc_disable_timer_check = 1104 config_vars->afc_disable_timer_check; 1105 psoc_priv_obj->afc_disable_request_id_check = 1106 config_vars->afc_disable_request_id_check; 1107 psoc_priv_obj->is_afc_reg_noaction = 1108 config_vars->is_afc_reg_noaction; 1109 } 1110 #else 1111 static inline void 1112 reg_set_afc_vars(struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 1113 struct reg_config_vars *config_vars) 1114 { 1115 } 1116 #endif 1117 1118 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 1119 struct reg_config_vars config_vars) 1120 { 1121 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 1122 QDF_STATUS status; 1123 1124 psoc_priv_obj = reg_get_psoc_obj(psoc); 1125 if (!psoc_priv_obj) { 1126 reg_err("psoc priv obj is NULL"); 1127 return QDF_STATUS_E_FAILURE; 1128 } 1129 1130 psoc_priv_obj->enable_11d_supp_original = 1131 config_vars.enable_11d_support; 1132 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 1133 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 1134 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 1135 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 1136 psoc_priv_obj->force_ssc_disable_indoor_channel = 1137 config_vars.force_ssc_disable_indoor_channel; 1138 psoc_priv_obj->band_capability = config_vars.band_capability; 1139 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 1140 psoc_priv_obj->enable_srd_chan_in_master_mode = 1141 config_vars.enable_srd_chan_in_master_mode; 1142 psoc_priv_obj->enable_11d_in_world_mode = 1143 config_vars.enable_11d_in_world_mode; 1144 psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode = 1145 config_vars.enable_5dot9_ghz_chan_in_master_mode; 1146 psoc_priv_obj->retain_nol_across_regdmn_update = 1147 config_vars.retain_nol_across_regdmn_update; 1148 reg_get_coex_unsafe_chan_nb_user_prefer(psoc_priv_obj, config_vars); 1149 reg_get_coex_unsafe_chan_reg_disable(psoc_priv_obj, config_vars); 1150 psoc_priv_obj->sta_sap_scc_on_indoor_channel = 1151 config_vars.sta_sap_scc_on_indoor_channel; 1152 psoc_priv_obj->p2p_indoor_ch_support = 1153 config_vars.p2p_indoor_ch_support; 1154 1155 reg_set_afc_vars(psoc_priv_obj, &config_vars); 1156 1157 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 1158 if (QDF_IS_STATUS_ERROR(status)) { 1159 reg_err("error taking psoc ref cnt"); 1160 return status; 1161 } 1162 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 1163 reg_change_pdev_for_config, 1164 NULL, 1, WLAN_REGULATORY_SB_ID); 1165 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 1166 1167 return status; 1168 } 1169 1170 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 1171 struct regulatory_channel *reg_channels, 1172 uint8_t *alpha2, 1173 enum dfs_reg dfs_region) 1174 { 1175 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 1176 QDF_STATUS status; 1177 uint32_t count; 1178 enum direction dir; 1179 uint32_t phy_cnt; 1180 1181 psoc_priv_obj = reg_get_psoc_obj(psoc); 1182 if (!psoc_priv_obj) { 1183 reg_err("reg psoc private obj is NULL"); 1184 return; 1185 } 1186 1187 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 1188 REG_ALPHA2_LEN); 1189 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 1190 for (count = 0; count < NUM_CHANNELS; count++) { 1191 reg_channels[count].chan_num = channel_map[count].chan_num; 1192 reg_channels[count].center_freq = 1193 channel_map[count].center_freq; 1194 reg_channels[count].nol_chan = false; 1195 } 1196 1197 for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) { 1198 qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt]. 1199 mas_chan_list, reg_channels, 1200 NUM_CHANNELS * sizeof(struct regulatory_channel)); 1201 1202 psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region = 1203 dfs_region; 1204 } 1205 1206 dir = SOUTHBOUND; 1207 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 1208 if (QDF_IS_STATUS_ERROR(status)) { 1209 reg_err("error taking psoc ref cnt"); 1210 return; 1211 } 1212 status = wlan_objmgr_iterate_obj_list( 1213 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 1214 &dir, 1, WLAN_REGULATORY_SB_ID); 1215 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 1216 } 1217 1218 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 1219 uint8_t *alpha2) 1220 { 1221 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 1222 1223 psoc_priv_obj = reg_get_psoc_obj(psoc); 1224 if (!psoc_priv_obj) { 1225 reg_err("reg psoc private obj is NULL"); 1226 return SOURCE_UNKNOWN; 1227 } 1228 1229 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 1230 1231 return psoc_priv_obj->cc_src; 1232 } 1233 1234 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 1235 *soc_reg) 1236 { 1237 uint8_t ctr; 1238 1239 if (!soc_reg->offload_enabled) 1240 return; 1241 1242 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 1243 soc_reg->new_user_ctry_pending[ctr] = false; 1244 soc_reg->new_init_ctry_pending[ctr] = false; 1245 soc_reg->new_11d_ctry_pending[ctr] = false; 1246 soc_reg->world_country_pending[ctr] = false; 1247 } 1248 } 1249 1250 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 1251 struct cur_regulatory_info *regulat_info, 1252 struct wlan_lmac_if_reg_tx_ops *tx_ops) 1253 { 1254 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 1255 struct wlan_objmgr_pdev *pdev; 1256 uint8_t pdev_id; 1257 uint8_t phy_id; 1258 uint8_t phy_num; 1259 struct set_country country_code; 1260 QDF_STATUS status; 1261 1262 /* 1263 * During SSR/WLAN restart ignore master channel list 1264 * for all events and in the last event handling if 1265 * current country and default country is different, send the last 1266 * configured (soc_reg->cur_country) country. 1267 */ 1268 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 1269 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 1270 REG_ALPHA2_LEN))) 1271 return QDF_STATUS_SUCCESS; 1272 1273 /* 1274 * Need firmware to send channel list event 1275 * for all phys. Therefore set pdev_id to 0xFF. 1276 */ 1277 pdev_id = WMI_HOST_PDEV_ID_SOC; 1278 for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) { 1279 if (soc_reg->cc_src == SOURCE_USERSPACE) 1280 soc_reg->new_user_ctry_pending[phy_num] = true; 1281 else if (soc_reg->cc_src == SOURCE_11D) 1282 soc_reg->new_11d_ctry_pending[phy_num] = true; 1283 else 1284 soc_reg->world_country_pending[phy_num] = true; 1285 } 1286 1287 qdf_mem_zero(&country_code, sizeof(country_code)); 1288 qdf_mem_copy(country_code.country, soc_reg->cur_country, 1289 sizeof(soc_reg->cur_country)); 1290 country_code.pdev_id = pdev_id; 1291 1292 if (soc_reg->offload_enabled) { 1293 if (!tx_ops || !tx_ops->set_country_code) { 1294 reg_err("No regulatory tx_ops"); 1295 status = QDF_STATUS_E_FAULT; 1296 goto error; 1297 } 1298 status = tx_ops->set_country_code(psoc, &country_code); 1299 if (QDF_IS_STATUS_ERROR(status)) { 1300 reg_err("Failed to send country code to fw"); 1301 goto error; 1302 } 1303 } else { 1304 phy_id = regulat_info->phy_id; 1305 if (tx_ops->get_pdev_id_from_phy_id) 1306 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 1307 else 1308 pdev_id = phy_id; 1309 1310 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, 1311 WLAN_REGULATORY_NB_ID); 1312 status = reg_set_non_offload_country(pdev, &country_code); 1313 wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID); 1314 if (QDF_IS_STATUS_ERROR(status)) { 1315 reg_err("Failed to set country code"); 1316 goto error; 1317 } 1318 } 1319 1320 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 1321 regulat_info->alpha2, soc_reg->cur_country); 1322 1323 return status; 1324 1325 error: 1326 reg_reset_ctry_pending_hints(soc_reg); 1327 1328 return status; 1329 } 1330 1331 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 1332 struct cur_regulatory_info *regulat_info) 1333 { 1334 uint8_t phy_num; 1335 1336 if (soc_reg->cc_src == SOURCE_UNKNOWN) 1337 return false; 1338 1339 phy_num = regulat_info->phy_id; 1340 if (soc_reg->new_user_ctry_pending[phy_num] || 1341 soc_reg->new_init_ctry_pending[phy_num] || 1342 soc_reg->new_11d_ctry_pending[phy_num] || 1343 soc_reg->world_country_pending[phy_num]) 1344 return false; 1345 1346 return true; 1347 } 1348