1 /* 2 * Copyright (c) 2014-2021 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 /** 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 /** 108 * reg_set_default_country() - Read the default country for the regdomain 109 * @country: country code. 110 * 111 * Return: QDF_STATUS 112 */ 113 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc, 114 uint8_t *country) 115 { 116 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 117 118 if (!country) { 119 reg_err("country is NULL"); 120 return QDF_STATUS_E_INVAL; 121 } 122 123 psoc_reg = reg_get_psoc_obj(psoc); 124 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 125 reg_err("psoc reg component is NULL"); 126 return QDF_STATUS_E_INVAL; 127 } 128 129 reg_info("set default_country: %s", country); 130 131 qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1); 132 133 return QDF_STATUS_SUCCESS; 134 } 135 136 bool reg_is_world_alpha2(uint8_t *alpha2) 137 { 138 if ((alpha2[0] == '0') && (alpha2[1] == '0')) 139 return true; 140 141 return false; 142 } 143 144 bool reg_is_us_alpha2(uint8_t *alpha2) 145 { 146 if ((alpha2[0] == 'U') && (alpha2[1] == 'S')) 147 return true; 148 149 return false; 150 } 151 152 bool reg_is_etsi_alpha2(uint8_t *alpha2) 153 { 154 if ((alpha2[0] == 'G') && (alpha2[1] == 'B')) 155 return true; 156 157 return false; 158 } 159 160 static 161 const char *reg_get_power_mode_string(uint16_t reg_dmn_pair_id) 162 { 163 switch (reg_dmn_pair_id) { 164 case FCC3_FCCA: 165 case FCC6_FCCA: 166 return "NON_VLP"; 167 default: 168 return "VLP"; 169 } 170 } 171 172 static bool reg_ctry_domain_supports_vlp(uint8_t *alpha2) 173 { 174 uint16_t i; 175 int no_of_countries; 176 177 reg_get_num_countries(&no_of_countries); 178 for (i = 0; i < no_of_countries; i++) { 179 if (g_all_countries[i].alpha2[0] == alpha2[0] && 180 g_all_countries[i].alpha2[1] == alpha2[1]) { 181 if (!qdf_str_cmp(reg_get_power_mode_string( 182 g_all_countries[i].reg_dmn_pair_id), "NON_VLP")) 183 return false; 184 else 185 return true; 186 } 187 } 188 return true; 189 } 190 191 bool reg_ctry_support_vlp(uint8_t *alpha2) 192 { 193 if (((alpha2[0] == 'A') && (alpha2[1] == 'E')) || 194 ((alpha2[0] == 'P') && (alpha2[1] == 'E')) || 195 ((alpha2[0] == 'U') && (alpha2[1] == 'S')) || 196 !reg_ctry_domain_supports_vlp(alpha2)) 197 return false; 198 else 199 return true; 200 } 201 202 static QDF_STATUS reg_set_non_offload_country(struct wlan_objmgr_pdev *pdev, 203 struct set_country *cc) 204 { 205 struct wlan_objmgr_psoc *psoc; 206 struct wlan_lmac_if_reg_tx_ops *tx_ops; 207 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 208 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 209 struct cc_regdmn_s rd; 210 uint8_t pdev_id; 211 uint8_t phy_id; 212 213 if (!pdev) { 214 reg_err("pdev is NULL"); 215 return QDF_STATUS_E_INVAL; 216 } 217 218 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 219 psoc = wlan_pdev_get_psoc(pdev); 220 tx_ops = reg_get_psoc_tx_ops(psoc); 221 if (tx_ops->get_phy_id_from_pdev_id) 222 tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); 223 else 224 phy_id = pdev_id; 225 226 psoc_reg = reg_get_psoc_obj(psoc); 227 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 228 reg_err("psoc reg component is NULL"); 229 return QDF_STATUS_E_INVAL; 230 } 231 232 if (reg_is_world_alpha2(cc->country)) { 233 pdev_priv_obj = reg_get_pdev_obj(pdev); 234 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 235 reg_err("reg component pdev priv is NULL"); 236 psoc_reg->world_country_pending[phy_id] = false; 237 return QDF_STATUS_E_INVAL; 238 } 239 if (reg_is_world_ctry_code(pdev_priv_obj->def_region_domain)) 240 rd.cc.regdmn.reg_2g_5g_pair_id = 241 pdev_priv_obj->def_region_domain; 242 else 243 rd.cc.regdmn.reg_2g_5g_pair_id = DEFAULT_WORLD_REGDMN; 244 rd.flags = REGDMN_IS_SET; 245 } else { 246 qdf_mem_copy(rd.cc.alpha, cc->country, REG_ALPHA2_LEN + 1); 247 rd.flags = ALPHA_IS_SET; 248 } 249 250 reg_program_chan_list(pdev, &rd); 251 return QDF_STATUS_SUCCESS; 252 } 253 254 #ifdef WLAN_REG_PARTIAL_OFFLOAD 255 /** 256 * reg_restore_def_country_for_po() - API to restore country code to default 257 * value if given country is invalid for Partial Offload 258 * @offload_enabled: Is offload enabled 259 * @country: Country code 260 * @cc_country: Country code array 261 * Return- void 262 */ 263 static void reg_restore_def_country_for_po(bool offload_enabled, 264 uint8_t *country, 265 uint8_t cc_country[]){ 266 if (!offload_enabled && !reg_is_world_alpha2(country)) { 267 QDF_STATUS status; 268 269 status = reg_is_country_code_valid(country); 270 if (!QDF_IS_STATUS_SUCCESS(status)) { 271 reg_err("Unable to set country code: %s\n", country); 272 reg_err("Restoring to world domain"); 273 qdf_mem_copy(cc_country, REG_WORLD_ALPHA2, 274 REG_ALPHA2_LEN + 1); 275 } 276 } 277 } 278 #else 279 static void reg_restore_def_country_for_po(bool offload_enabled, 280 uint8_t *country, 281 uint8_t cc_country[]){ 282 } 283 #endif 284 285 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, 286 uint8_t *country) 287 { 288 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 289 struct wlan_lmac_if_reg_tx_ops *tx_ops; 290 struct set_country cc; 291 struct wlan_objmgr_psoc *psoc; 292 uint8_t pdev_id; 293 uint8_t phy_id; 294 295 if (!pdev) { 296 reg_err("pdev is NULL"); 297 return QDF_STATUS_E_INVAL; 298 } 299 300 if (!country) { 301 reg_err("country code is NULL"); 302 return QDF_STATUS_E_INVAL; 303 } 304 305 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 306 307 psoc = wlan_pdev_get_psoc(pdev); 308 309 tx_ops = reg_get_psoc_tx_ops(psoc); 310 if (tx_ops->get_phy_id_from_pdev_id) 311 tx_ops->get_phy_id_from_pdev_id(psoc, pdev_id, &phy_id); 312 else 313 phy_id = pdev_id; 314 315 psoc_reg = reg_get_psoc_obj(psoc); 316 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 317 reg_err("psoc reg component is NULL"); 318 return QDF_STATUS_E_INVAL; 319 } 320 321 if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) { 322 if (psoc_reg->cc_src == SOURCE_USERSPACE || 323 psoc_reg->cc_src == SOURCE_CORE) { 324 reg_debug("country is not different"); 325 return QDF_STATUS_E_INVAL; 326 } 327 } 328 329 reg_debug("programming new country: %s to firmware", country); 330 331 qdf_mem_copy(cc.country, country, REG_ALPHA2_LEN + 1); 332 /* 333 * Need firmware to send channel list event 334 * for all phys. Therefore set pdev_id to 0xFF. 335 */ 336 cc.pdev_id = WMI_HOST_PDEV_ID_SOC; 337 338 reg_restore_def_country_for_po(psoc_reg->offload_enabled, 339 country, 340 cc.country); 341 342 if (reg_is_world_alpha2(cc.country)) 343 psoc_reg->world_country_pending[phy_id] = true; 344 else 345 psoc_reg->new_user_ctry_pending[phy_id] = true; 346 347 if (psoc_reg->offload_enabled) { 348 tx_ops = reg_get_psoc_tx_ops(psoc); 349 if (tx_ops->set_country_code) { 350 tx_ops->set_country_code(psoc, &cc); 351 } else { 352 reg_err("country set fw handler not present"); 353 psoc_reg->new_user_ctry_pending[phy_id] = false; 354 return QDF_STATUS_E_FAULT; 355 } 356 } else { 357 return reg_set_non_offload_country(pdev, &cc); 358 } 359 360 return QDF_STATUS_SUCCESS; 361 } 362 363 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc) 364 { 365 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 366 367 psoc_reg = reg_get_psoc_obj(psoc); 368 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 369 reg_err("psoc reg component is NULL"); 370 return QDF_STATUS_E_INVAL; 371 } 372 373 qdf_mem_copy(psoc_reg->cur_country, 374 psoc_reg->def_country, 375 REG_ALPHA2_LEN + 1); 376 reg_debug("set cur_country %.2s", psoc_reg->cur_country); 377 378 return QDF_STATUS_SUCCESS; 379 } 380 381 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, 382 const uint8_t *country_alpha2, 383 enum country_src source) 384 { 385 if (!reg_domain_ptr) { 386 reg_err("Invalid reg domain pointer"); 387 return QDF_STATUS_E_FAULT; 388 } 389 390 *reg_domain_ptr = 0; 391 392 if (!country_alpha2) { 393 reg_err("Country code is NULL"); 394 return QDF_STATUS_E_FAULT; 395 } 396 397 return QDF_STATUS_SUCCESS; 398 } 399 400 #ifdef CONFIG_REG_CLIENT 401 QDF_STATUS 402 reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, 403 uint8_t *ap_ctry, uint8_t *sta_ctry, 404 enum reg_6g_ap_type *pwr_type_6g, 405 bool *ctry_code_match, 406 enum reg_6g_ap_type ap_pwr_type) 407 { 408 *pwr_type_6g = REG_INDOOR_AP; 409 410 reg_debug("Country IE:%c%c, STA country:%c%c", ap_ctry[0], 411 ap_ctry[1], sta_ctry[0], sta_ctry[1]); 412 413 if (!qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) { 414 *ctry_code_match = true; 415 return QDF_STATUS_SUCCESS; 416 } 417 418 *ctry_code_match = false; 419 /* 420 * If reg_info=0 not included, STA should operate in VLP mode. 421 * If STA country doesn't support VLP, do not return if Wi-Fi 422 * safe mode or RF test mode or enable relaxed connection policy, 423 * rather STA should operate in LPI mode. 424 * wlan_cm_get_check_6ghz_security API returns true if 425 * neither Safe mode nor RF test mode are enabled. 426 * wlan_cm_get_relaxed_6ghz_conn_policy API returns true if 427 * enabled. 428 */ 429 if (ap_pwr_type != REG_INDOOR_AP) { 430 if (wlan_reg_ctry_support_vlp(sta_ctry) && 431 wlan_reg_ctry_support_vlp(ap_ctry)) { 432 reg_debug("STA ctry doesn't match with AP ctry, switch to VLP"); 433 *pwr_type_6g = REG_VERY_LOW_POWER_AP; 434 } else { 435 reg_debug("AP or STA doesn't support VLP"); 436 *pwr_type_6g = REG_INDOOR_AP; 437 } 438 439 if (!wlan_reg_ctry_support_vlp(sta_ctry) && 440 wlan_cm_get_check_6ghz_security(psoc) && 441 !wlan_cm_get_relaxed_6ghz_conn_policy(psoc)) { 442 reg_err("VLP not supported, can't connect"); 443 return QDF_STATUS_E_NOSUPPORT; 444 } 445 } 446 447 if (ap_pwr_type == REG_INDOOR_AP) { 448 reg_debug("Indoor AP, allow STA IN LPI"); 449 *pwr_type_6g = REG_INDOOR_AP; 450 } 451 452 return QDF_STATUS_SUCCESS; 453 } 454 #endif 455 456 #ifdef FEATURE_WLAN_CH_AVOID_EXT 457 static inline 458 void reg_get_coex_unsafe_chan_nb_user_prefer( 459 struct wlan_regulatory_psoc_priv_obj 460 *psoc_priv_obj, 461 struct reg_config_vars config_vars) 462 { 463 psoc_priv_obj->coex_unsafe_chan_nb_user_prefer = 464 config_vars.coex_unsafe_chan_nb_user_prefer; 465 } 466 467 static inline 468 void reg_get_coex_unsafe_chan_reg_disable( 469 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 470 struct reg_config_vars config_vars) 471 { 472 psoc_priv_obj->coex_unsafe_chan_reg_disable = 473 config_vars.coex_unsafe_chan_reg_disable; 474 } 475 #else 476 static inline 477 void reg_get_coex_unsafe_chan_nb_user_prefer( 478 struct wlan_regulatory_psoc_priv_obj 479 *psoc_priv_obj, 480 struct reg_config_vars config_vars) 481 { 482 } 483 484 static inline 485 void reg_get_coex_unsafe_chan_reg_disable( 486 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj, 487 struct reg_config_vars config_vars) 488 { 489 } 490 #endif 491 492 #ifdef CONFIG_CHAN_FREQ_API 493 bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, 494 qdf_freq_t freq) 495 { 496 enum channel_state chan_state; 497 498 chan_state = reg_get_channel_state_for_freq(pdev, freq); 499 500 return (chan_state == CHANNEL_STATE_DFS) || 501 (chan_state == CHANNEL_STATE_DISABLE); 502 } 503 #endif /* CONFIG_CHAN_FREQ_API */ 504 505 #ifdef WLAN_FEATURE_DSRC 506 #ifdef CONFIG_CHAN_FREQ_API 507 bool reg_is_dsrc_freq(qdf_freq_t freq) 508 { 509 if (!REG_IS_5GHZ_FREQ(freq)) 510 return false; 511 512 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 513 return false; 514 515 return true; 516 } 517 #endif /*CONFIG_CHAN_FREQ_API*/ 518 #else 519 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) 520 { 521 struct cur_regdmn_info cur_reg_dmn; 522 QDF_STATUS status; 523 524 status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); 525 if (status != QDF_STATUS_SUCCESS) { 526 reg_debug_rl("Failed to get reg domain"); 527 return false; 528 } 529 530 return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g); 531 } 532 533 #ifdef CONFIG_CHAN_FREQ_API 534 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, 535 uint16_t freq) 536 { 537 if (!REG_IS_5GHZ_FREQ(freq)) 538 return false; 539 540 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 541 freq <= REG_ETSI13_SRD_END_FREQ)) 542 return false; 543 544 return reg_is_etsi13_regdmn(pdev); 545 } 546 #endif /* CONFIG_CHAN_FREQ_API */ 547 548 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) 549 { 550 struct wlan_objmgr_psoc *psoc; 551 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 552 553 if (!pdev) { 554 reg_alert("pdev is NULL"); 555 return true; 556 } 557 psoc = wlan_pdev_get_psoc(pdev); 558 559 psoc_priv_obj = reg_get_psoc_obj(psoc); 560 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 561 reg_alert("psoc reg component is NULL"); 562 return true; 563 } 564 565 return psoc_priv_obj->enable_srd_chan_in_master_mode && 566 reg_is_etsi13_regdmn(pdev); 567 } 568 #endif 569 570 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap) 571 { 572 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 573 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 574 struct wlan_objmgr_psoc *psoc; 575 QDF_STATUS status; 576 577 pdev_priv_obj = reg_get_pdev_obj(pdev); 578 579 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 580 reg_err("pdev reg component is NULL"); 581 return QDF_STATUS_E_INVAL; 582 } 583 584 if (pdev_priv_obj->band_capability == band_bitmap) { 585 reg_info("same band %d", band_bitmap); 586 return QDF_STATUS_SUCCESS; 587 } 588 589 psoc = wlan_pdev_get_psoc(pdev); 590 if (!psoc) { 591 reg_err("psoc is NULL"); 592 return QDF_STATUS_E_INVAL; 593 } 594 595 psoc_priv_obj = reg_get_psoc_obj(psoc); 596 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 597 reg_err("psoc reg component is NULL"); 598 return QDF_STATUS_E_INVAL; 599 } 600 601 reg_info("set band bitmap: %d", band_bitmap); 602 pdev_priv_obj->band_capability = band_bitmap; 603 604 reg_compute_pdev_current_chan_list(pdev_priv_obj); 605 606 status = reg_send_scheduler_msg_sb(psoc, pdev); 607 608 return status; 609 } 610 611 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, 612 uint32_t *band_bitmap) 613 { 614 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 615 616 pdev_priv_obj = reg_get_pdev_obj(pdev); 617 618 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 619 reg_err("pdev reg component is NULL"); 620 return QDF_STATUS_E_INVAL; 621 } 622 623 reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability); 624 *band_bitmap = pdev_priv_obj->band_capability; 625 626 return QDF_STATUS_SUCCESS; 627 } 628 629 #ifdef DISABLE_CHANNEL_LIST 630 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 631 { 632 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 633 struct wlan_objmgr_psoc *psoc; 634 QDF_STATUS status; 635 636 pdev_priv_obj = reg_get_pdev_obj(pdev); 637 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 638 reg_err("pdev reg component is NULL"); 639 return QDF_STATUS_E_INVAL; 640 } 641 642 psoc = wlan_pdev_get_psoc(pdev); 643 if (!psoc) { 644 reg_err("psoc is NULL"); 645 return QDF_STATUS_E_INVAL; 646 } 647 648 pdev_priv_obj->disable_cached_channels = false; 649 reg_compute_pdev_current_chan_list(pdev_priv_obj); 650 status = reg_send_scheduler_msg_sb(psoc, pdev); 651 return status; 652 } 653 654 QDF_STATUS reg_disable_cached_channels(struct wlan_objmgr_pdev *pdev) 655 { 656 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 657 struct wlan_objmgr_psoc *psoc; 658 QDF_STATUS status; 659 660 pdev_priv_obj = reg_get_pdev_obj(pdev); 661 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 662 reg_err("pdev reg component is NULL"); 663 return QDF_STATUS_E_INVAL; 664 } 665 666 psoc = wlan_pdev_get_psoc(pdev); 667 if (!psoc) { 668 reg_err("psoc is NULL"); 669 return QDF_STATUS_E_INVAL; 670 } 671 672 pdev_priv_obj->disable_cached_channels = true; 673 reg_compute_pdev_current_chan_list(pdev_priv_obj); 674 status = reg_send_scheduler_msg_sb(psoc, pdev); 675 return status; 676 } 677 678 #ifdef CONFIG_CHAN_FREQ_API 679 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, 680 uint32_t *channel_list, 681 uint32_t num_channels) 682 { 683 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 684 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 685 struct wlan_objmgr_psoc *psoc; 686 uint16_t i, j; 687 688 pdev_priv_obj = reg_get_pdev_obj(pdev); 689 690 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 691 reg_err("pdev reg component is NULL"); 692 return QDF_STATUS_E_INVAL; 693 } 694 695 psoc = wlan_pdev_get_psoc(pdev); 696 if (!psoc) { 697 reg_err("psoc is NULL"); 698 return QDF_STATUS_E_INVAL; 699 } 700 701 psoc_priv_obj = reg_get_psoc_obj(psoc); 702 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 703 reg_err("psoc reg component is NULL"); 704 return QDF_STATUS_E_INVAL; 705 } 706 if (pdev_priv_obj->num_cache_channels > 0) { 707 pdev_priv_obj->num_cache_channels = 0; 708 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 709 sizeof(pdev_priv_obj->cache_disable_chan_list)); 710 } 711 712 for (i = 0; i < num_channels; i++) { 713 for (j = 0; j < NUM_CHANNELS; j++) { 714 if (channel_list[i] == pdev_priv_obj-> 715 cur_chan_list[j].center_freq) { 716 pdev_priv_obj-> 717 cache_disable_chan_list[i].center_freq = 718 channel_list[i]; 719 pdev_priv_obj-> 720 cache_disable_chan_list[i].state = 721 pdev_priv_obj->cur_chan_list[j].state; 722 pdev_priv_obj-> 723 cache_disable_chan_list[i].chan_flags = 724 pdev_priv_obj-> 725 cur_chan_list[j].chan_flags; 726 } 727 } 728 } 729 pdev_priv_obj->num_cache_channels = num_channels; 730 731 return QDF_STATUS_SUCCESS; 732 } 733 #endif /* CONFIG_CHAN_FREQ_API */ 734 #endif 735 736 #ifdef CONFIG_REG_CLIENT 737 738 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 739 bool fcc_constraint) 740 { 741 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 742 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 743 struct wlan_objmgr_psoc *psoc; 744 QDF_STATUS status; 745 746 pdev_priv_obj = reg_get_pdev_obj(pdev); 747 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 748 reg_err("pdev reg component is NULL"); 749 return QDF_STATUS_E_INVAL; 750 } 751 752 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 753 reg_info("same fcc_constraint %d", fcc_constraint); 754 return QDF_STATUS_SUCCESS; 755 } 756 757 reg_info("set fcc_constraint: %d", fcc_constraint); 758 pdev_priv_obj->set_fcc_channel = fcc_constraint; 759 760 psoc = wlan_pdev_get_psoc(pdev); 761 if (!psoc) { 762 reg_err("psoc is NULL"); 763 return QDF_STATUS_E_INVAL; 764 } 765 766 psoc_priv_obj = reg_get_psoc_obj(psoc); 767 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 768 reg_err("psoc reg component is NULL"); 769 return QDF_STATUS_E_INVAL; 770 } 771 772 reg_compute_pdev_current_chan_list(pdev_priv_obj); 773 774 status = reg_send_scheduler_msg_sb(psoc, pdev); 775 776 return status; 777 } 778 779 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) 780 { 781 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 782 783 pdev_priv_obj = reg_get_pdev_obj(pdev); 784 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 785 reg_err("pdev reg component is NULL"); 786 return false; 787 } 788 789 if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ) 790 return false; 791 792 if (!pdev_priv_obj->set_fcc_channel) 793 return false; 794 795 return true; 796 } 797 798 #ifdef CONFIG_BAND_6GHZ 799 /** 800 * reg_is_afc_available() - check if the automated frequency control system is 801 * available, function will need to be updated once AFC is implemented 802 * @pdev: Pointer to pdev structure 803 * 804 * Return: false since the AFC system is not yet available 805 */ 806 static bool reg_is_afc_available(struct wlan_objmgr_pdev *pdev) 807 { 808 return false; 809 } 810 811 enum reg_6g_ap_type reg_decide_6g_ap_pwr_type(struct wlan_objmgr_pdev *pdev) 812 { 813 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 814 enum reg_6g_ap_type ap_pwr_type = REG_INDOOR_AP; 815 816 pdev_priv_obj = reg_get_pdev_obj(pdev); 817 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 818 reg_err("pdev reg component is NULL"); 819 return REG_VERY_LOW_POWER_AP; 820 } 821 822 if (reg_is_afc_available(pdev)) { 823 ap_pwr_type = REG_STANDARD_POWER_AP; 824 } else if (pdev_priv_obj->indoor_chan_enabled) { 825 if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_INDOOR_AP]) 826 ap_pwr_type = REG_INDOOR_AP; 827 else 828 ap_pwr_type = REG_VERY_LOW_POWER_AP; 829 } else if (pdev_priv_obj->reg_rules.num_of_6g_ap_reg_rules[REG_VERY_LOW_POWER_AP]) { 830 ap_pwr_type = REG_VERY_LOW_POWER_AP; 831 } 832 reg_debug("indoor_chan_enabled %d ap_pwr_type %d", 833 pdev_priv_obj->indoor_chan_enabled, ap_pwr_type); 834 835 reg_set_ap_pwr_and_update_chan_list(pdev, ap_pwr_type); 836 837 return ap_pwr_type; 838 } 839 #endif /* CONFIG_BAND_6GHZ */ 840 841 #endif /* CONFIG_REG_CLIENT */ 842 843 /** 844 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 845 * @psoc: Pointer to global psoc structure. 846 * @object: Pointer to global pdev structure. 847 * @arg: Pointer to argument list. 848 */ 849 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 850 void *object, void *arg) 851 { 852 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 853 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 854 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 855 856 psoc_priv_obj = reg_get_psoc_obj(psoc); 857 if (!psoc_priv_obj) { 858 reg_err("psoc priv obj is NULL"); 859 return; 860 } 861 862 pdev_priv_obj = reg_get_pdev_obj(pdev); 863 864 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 865 reg_err("reg pdev private obj is NULL"); 866 return; 867 } 868 869 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 870 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 871 pdev_priv_obj->force_ssc_disable_indoor_channel = 872 psoc_priv_obj->force_ssc_disable_indoor_channel; 873 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 874 pdev_priv_obj->sta_sap_scc_on_indoor_channel = 875 psoc_priv_obj->sta_sap_scc_on_indoor_channel; 876 877 reg_compute_pdev_current_chan_list(pdev_priv_obj); 878 879 reg_send_scheduler_msg_sb(psoc, pdev); 880 } 881 882 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 883 struct reg_config_vars config_vars) 884 { 885 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 886 QDF_STATUS status; 887 888 psoc_priv_obj = reg_get_psoc_obj(psoc); 889 if (!psoc_priv_obj) { 890 reg_err("psoc priv obj is NULL"); 891 return QDF_STATUS_E_FAILURE; 892 } 893 894 psoc_priv_obj->enable_11d_supp_original = 895 config_vars.enable_11d_support; 896 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 897 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 898 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 899 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 900 psoc_priv_obj->force_ssc_disable_indoor_channel = 901 config_vars.force_ssc_disable_indoor_channel; 902 psoc_priv_obj->band_capability = config_vars.band_capability; 903 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 904 psoc_priv_obj->enable_srd_chan_in_master_mode = 905 config_vars.enable_srd_chan_in_master_mode; 906 psoc_priv_obj->enable_11d_in_world_mode = 907 config_vars.enable_11d_in_world_mode; 908 psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode = 909 config_vars.enable_5dot9_ghz_chan_in_master_mode; 910 psoc_priv_obj->retain_nol_across_regdmn_update = 911 config_vars.retain_nol_across_regdmn_update; 912 reg_get_coex_unsafe_chan_nb_user_prefer(psoc_priv_obj, config_vars); 913 reg_get_coex_unsafe_chan_reg_disable(psoc_priv_obj, config_vars); 914 psoc_priv_obj->sta_sap_scc_on_indoor_channel = 915 config_vars.sta_sap_scc_on_indoor_channel; 916 917 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 918 if (QDF_IS_STATUS_ERROR(status)) { 919 reg_err("error taking psoc ref cnt"); 920 return status; 921 } 922 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 923 reg_change_pdev_for_config, 924 NULL, 1, WLAN_REGULATORY_SB_ID); 925 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 926 927 return status; 928 } 929 930 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 931 struct regulatory_channel *reg_channels, 932 uint8_t *alpha2, 933 enum dfs_reg dfs_region) 934 { 935 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 936 QDF_STATUS status; 937 uint32_t count; 938 enum direction dir; 939 uint32_t phy_cnt; 940 941 psoc_priv_obj = reg_get_psoc_obj(psoc); 942 if (!psoc_priv_obj) { 943 reg_err("reg psoc private obj is NULL"); 944 return; 945 } 946 947 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 948 REG_ALPHA2_LEN); 949 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 950 for (count = 0; count < NUM_CHANNELS; count++) { 951 reg_channels[count].chan_num = channel_map[count].chan_num; 952 reg_channels[count].center_freq = 953 channel_map[count].center_freq; 954 reg_channels[count].nol_chan = false; 955 } 956 957 for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) { 958 qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt]. 959 mas_chan_list, reg_channels, 960 NUM_CHANNELS * sizeof(struct regulatory_channel)); 961 962 psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region = 963 dfs_region; 964 } 965 966 dir = SOUTHBOUND; 967 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 968 if (QDF_IS_STATUS_ERROR(status)) { 969 reg_err("error taking psoc ref cnt"); 970 return; 971 } 972 status = wlan_objmgr_iterate_obj_list( 973 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 974 &dir, 1, WLAN_REGULATORY_SB_ID); 975 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 976 } 977 978 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 979 uint8_t *alpha2) 980 { 981 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 982 983 psoc_priv_obj = reg_get_psoc_obj(psoc); 984 if (!psoc_priv_obj) { 985 reg_err("reg psoc private obj is NULL"); 986 return SOURCE_UNKNOWN; 987 } 988 989 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 990 991 return psoc_priv_obj->cc_src; 992 } 993 994 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 995 *soc_reg) 996 { 997 uint8_t ctr; 998 999 if (!soc_reg->offload_enabled) 1000 return; 1001 1002 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 1003 soc_reg->new_user_ctry_pending[ctr] = false; 1004 soc_reg->new_init_ctry_pending[ctr] = false; 1005 soc_reg->new_11d_ctry_pending[ctr] = false; 1006 soc_reg->world_country_pending[ctr] = false; 1007 } 1008 } 1009 1010 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 1011 struct cur_regulatory_info *regulat_info, 1012 struct wlan_lmac_if_reg_tx_ops *tx_ops) 1013 { 1014 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 1015 struct wlan_objmgr_pdev *pdev; 1016 uint8_t pdev_id; 1017 uint8_t phy_id; 1018 uint8_t phy_num; 1019 struct set_country country_code; 1020 QDF_STATUS status; 1021 1022 /* 1023 * During SSR/WLAN restart ignore master channel list 1024 * for all events and in the last event handling if 1025 * current country and default country is different, send the last 1026 * configured (soc_reg->cur_country) country. 1027 */ 1028 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 1029 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 1030 REG_ALPHA2_LEN))) 1031 return QDF_STATUS_SUCCESS; 1032 1033 /* 1034 * Need firmware to send channel list event 1035 * for all phys. Therefore set pdev_id to 0xFF. 1036 */ 1037 pdev_id = WMI_HOST_PDEV_ID_SOC; 1038 for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) { 1039 if (soc_reg->cc_src == SOURCE_USERSPACE) 1040 soc_reg->new_user_ctry_pending[phy_num] = true; 1041 else if (soc_reg->cc_src == SOURCE_11D) 1042 soc_reg->new_11d_ctry_pending[phy_num] = true; 1043 else 1044 soc_reg->world_country_pending[phy_num] = true; 1045 } 1046 1047 qdf_mem_zero(&country_code, sizeof(country_code)); 1048 qdf_mem_copy(country_code.country, soc_reg->cur_country, 1049 sizeof(soc_reg->cur_country)); 1050 country_code.pdev_id = pdev_id; 1051 1052 if (soc_reg->offload_enabled) { 1053 if (!tx_ops || !tx_ops->set_country_code) { 1054 reg_err("No regulatory tx_ops"); 1055 status = QDF_STATUS_E_FAULT; 1056 goto error; 1057 } 1058 status = tx_ops->set_country_code(psoc, &country_code); 1059 if (QDF_IS_STATUS_ERROR(status)) { 1060 reg_err("Failed to send country code to fw"); 1061 goto error; 1062 } 1063 } else { 1064 phy_id = regulat_info->phy_id; 1065 if (tx_ops->get_pdev_id_from_phy_id) 1066 tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 1067 else 1068 pdev_id = phy_id; 1069 1070 pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, 1071 WLAN_REGULATORY_NB_ID); 1072 status = reg_set_non_offload_country(pdev, &country_code); 1073 wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID); 1074 if (QDF_IS_STATUS_ERROR(status)) { 1075 reg_err("Failed to set country code"); 1076 goto error; 1077 } 1078 } 1079 1080 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 1081 regulat_info->alpha2, soc_reg->cur_country); 1082 1083 return status; 1084 1085 error: 1086 reg_reset_ctry_pending_hints(soc_reg); 1087 1088 return status; 1089 } 1090 1091 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 1092 struct cur_regulatory_info *regulat_info) 1093 { 1094 uint8_t phy_num; 1095 1096 if (soc_reg->cc_src == SOURCE_UNKNOWN) 1097 return false; 1098 1099 phy_num = regulat_info->phy_id; 1100 if (soc_reg->new_user_ctry_pending[phy_num] || 1101 soc_reg->new_init_ctry_pending[phy_num] || 1102 soc_reg->new_11d_ctry_pending[phy_num] || 1103 soc_reg->world_country_pending[phy_num]) 1104 return false; 1105 1106 return true; 1107 } 1108