1 /* 2 * Copyright (c) 2014-2019 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_utils.c 21 * This file defines the APIs to set and get the regulatory variables. 22 */ 23 24 #include <wlan_cmn.h> 25 #include <reg_services_public_struct.h> 26 #include <wlan_objmgr_psoc_obj.h> 27 #include <wlan_objmgr_pdev_obj.h> 28 #include "reg_priv_objs.h" 29 #include "reg_utils.h" 30 #include "reg_callbacks.h" 31 #include "reg_db.h" 32 #include "reg_db_parser.h" 33 #include "reg_host_11d.h" 34 #include <scheduler_api.h> 35 #include <wlan_reg_services_api.h> 36 #include <qdf_platform.h> 37 #include "reg_services_common.h" 38 #include "reg_build_chan_list.h" 39 40 #define DEFAULT_WORLD_REGDMN 0x60 41 42 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) 43 #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) 44 45 bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch) 46 { 47 enum channel_enum ch_idx; 48 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 49 50 ch_idx = reg_get_chan_enum(ch); 51 52 if (ch_idx == INVALID_CHANNEL) 53 return false; 54 55 pdev_priv_obj = reg_get_pdev_obj(pdev); 56 57 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 58 reg_err("pdev reg obj is NULL"); 59 return false; 60 } 61 62 if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags & 63 REGULATORY_CHAN_RADAR) 64 return true; 65 66 return false; 67 } 68 69 /** 70 * reg_is_world_ctry_code() - Check if the given country code is WORLD regdomain 71 * @ctry_code: Country code value. 72 */ 73 static bool reg_is_world_ctry_code(uint16_t ctry_code) 74 { 75 if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN) 76 return true; 77 78 return false; 79 } 80 81 QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc, 82 uint8_t *country_code) 83 { 84 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 85 86 if (!country_code) { 87 reg_err("country_code is NULL"); 88 return QDF_STATUS_E_INVAL; 89 } 90 91 psoc_reg = reg_get_psoc_obj(psoc); 92 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 93 reg_err("psoc reg component is NULL"); 94 return QDF_STATUS_E_INVAL; 95 } 96 97 qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1); 98 99 return QDF_STATUS_SUCCESS; 100 } 101 102 /** 103 * reg_set_default_country() - Read the default country for the regdomain 104 * @country: country code. 105 * 106 * Return: QDF_STATUS 107 */ 108 QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc, 109 uint8_t *country) 110 { 111 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 112 113 if (!country) { 114 reg_err("country is NULL"); 115 return QDF_STATUS_E_INVAL; 116 } 117 118 psoc_reg = reg_get_psoc_obj(psoc); 119 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 120 reg_err("psoc reg component is NULL"); 121 return QDF_STATUS_E_INVAL; 122 } 123 124 reg_info("setting default_country: %s", country); 125 126 qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1); 127 128 return QDF_STATUS_SUCCESS; 129 } 130 131 bool reg_is_world_alpha2(uint8_t *alpha2) 132 { 133 if ((alpha2[0] == '0') && (alpha2[1] == '0')) 134 return true; 135 136 return false; 137 } 138 139 bool reg_is_us_alpha2(uint8_t *alpha2) 140 { 141 if ((alpha2[0] == 'U') && (alpha2[1] == 'S')) 142 return true; 143 144 return false; 145 } 146 147 QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, 148 uint8_t *country) 149 { 150 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 151 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 152 struct wlan_lmac_if_reg_tx_ops *tx_ops; 153 struct set_country country_code; 154 struct wlan_objmgr_psoc *psoc; 155 struct cc_regdmn_s rd; 156 uint8_t pdev_id; 157 158 if (!pdev) { 159 reg_err("pdev is NULL"); 160 return QDF_STATUS_E_INVAL; 161 } 162 163 if (!country) { 164 reg_err("country code is NULL"); 165 return QDF_STATUS_E_INVAL; 166 } 167 168 pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); 169 170 psoc = wlan_pdev_get_psoc(pdev); 171 172 psoc_reg = reg_get_psoc_obj(psoc); 173 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 174 reg_err("psoc reg component is NULL"); 175 return QDF_STATUS_E_INVAL; 176 } 177 178 if (!qdf_mem_cmp(psoc_reg->cur_country, country, REG_ALPHA2_LEN)) { 179 reg_err("country is not different"); 180 return QDF_STATUS_SUCCESS; 181 } 182 183 reg_debug("programming new country:%s to firmware", country); 184 185 qdf_mem_copy(country_code.country, country, REG_ALPHA2_LEN + 1); 186 country_code.pdev_id = pdev_id; 187 188 if (reg_is_world_alpha2(country)) 189 psoc_reg->world_country_pending[pdev_id] = true; 190 else 191 psoc_reg->new_user_ctry_pending[pdev_id] = true; 192 193 if (psoc_reg->offload_enabled) { 194 tx_ops = reg_get_psoc_tx_ops(psoc); 195 if (tx_ops->set_country_code) { 196 tx_ops->set_country_code(psoc, &country_code); 197 } else { 198 reg_err("country set fw handler not present"); 199 psoc_reg->new_user_ctry_pending[pdev_id] = false; 200 return QDF_STATUS_E_FAULT; 201 } 202 } else { 203 if (reg_is_world_alpha2(country)) { 204 pdev_priv_obj = reg_get_pdev_obj(pdev); 205 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 206 reg_err("reg component pdev priv is NULL"); 207 psoc_reg->new_user_ctry_pending[pdev_id] = 208 false; 209 return QDF_STATUS_E_INVAL; 210 } 211 if (reg_is_world_ctry_code( 212 pdev_priv_obj->def_region_domain)) 213 rd.cc.regdmn_id = 214 pdev_priv_obj->def_region_domain; 215 else 216 rd.cc.regdmn_id = DEFAULT_WORLD_REGDMN; 217 rd.flags = REGDMN_IS_SET; 218 } else { 219 qdf_mem_copy(rd.cc.alpha, country, REG_ALPHA2_LEN + 1); 220 rd.flags = ALPHA_IS_SET; 221 } 222 223 reg_program_chan_list(pdev, &rd); 224 } 225 226 return QDF_STATUS_SUCCESS; 227 } 228 229 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc) 230 { 231 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 232 233 psoc_reg = reg_get_psoc_obj(psoc); 234 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 235 reg_err("psoc reg component is NULL"); 236 return QDF_STATUS_E_INVAL; 237 } 238 239 reg_info("re-setting user country to default"); 240 qdf_mem_copy(psoc_reg->cur_country, 241 psoc_reg->def_country, 242 REG_ALPHA2_LEN + 1); 243 reg_debug("set cur_country %.2s", psoc_reg->cur_country); 244 245 return QDF_STATUS_SUCCESS; 246 } 247 248 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, 249 const uint8_t *country_alpha2, 250 enum country_src source) 251 { 252 if (!reg_domain_ptr) { 253 reg_err("Invalid reg domain pointer"); 254 return QDF_STATUS_E_FAULT; 255 } 256 257 *reg_domain_ptr = 0; 258 259 if (!country_alpha2) { 260 reg_err("Country code array is NULL"); 261 return QDF_STATUS_E_FAULT; 262 } 263 264 return QDF_STATUS_SUCCESS; 265 } 266 267 bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, 268 uint32_t chan) 269 { 270 enum channel_state ch_state; 271 272 ch_state = reg_get_channel_state(pdev, chan); 273 274 return (ch_state == CHANNEL_STATE_DFS) || 275 (ch_state == CHANNEL_STATE_DISABLE); 276 } 277 278 #ifdef WLAN_FEATURE_DSRC 279 bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) 280 { 281 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 282 uint32_t freq = 0; 283 284 pdev_priv_obj = reg_get_pdev_obj(pdev); 285 286 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 287 reg_err("reg pdev priv obj is NULL"); 288 return false; 289 } 290 291 if (!REG_IS_5GHZ_CH(chan)) 292 return false; 293 294 freq = reg_chan_to_freq(pdev, chan); 295 296 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 297 return false; 298 299 return true; 300 } 301 302 #else 303 304 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) 305 { 306 struct cur_regdmn_info cur_reg_dmn; 307 QDF_STATUS status; 308 309 status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); 310 if (status != QDF_STATUS_SUCCESS) { 311 reg_err("Failed to get reg domain"); 312 return false; 313 } 314 315 return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g); 316 } 317 318 bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan) 319 { 320 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 321 uint32_t freq = 0; 322 323 pdev_priv_obj = reg_get_pdev_obj(pdev); 324 325 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 326 reg_err("reg pdev priv obj is NULL"); 327 return false; 328 } 329 330 if (!REG_IS_5GHZ_CH(chan)) 331 return false; 332 333 freq = reg_chan_to_freq(pdev, chan); 334 335 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 336 freq <= REG_ETSI13_SRD_END_FREQ)) 337 return false; 338 339 return reg_is_etsi13_regdmn(pdev); 340 } 341 342 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) 343 { 344 struct wlan_objmgr_psoc *psoc; 345 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 346 347 if (!pdev) { 348 reg_alert("pdev is NULL"); 349 return true; 350 } 351 psoc = wlan_pdev_get_psoc(pdev); 352 353 psoc_priv_obj = reg_get_psoc_obj(psoc); 354 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 355 reg_alert("psoc reg component is NULL"); 356 return true; 357 } 358 359 return psoc_priv_obj->enable_srd_chan_in_master_mode && 360 reg_is_etsi13_regdmn(pdev); 361 } 362 #endif 363 364 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, 365 enum band_info band) 366 { 367 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 368 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 369 struct wlan_objmgr_psoc *psoc; 370 QDF_STATUS status; 371 372 pdev_priv_obj = reg_get_pdev_obj(pdev); 373 374 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 375 reg_err("pdev reg component is NULL"); 376 return QDF_STATUS_E_INVAL; 377 } 378 379 if (pdev_priv_obj->band_capability == band) { 380 reg_info("band is already set to %d", band); 381 return QDF_STATUS_SUCCESS; 382 } 383 384 psoc = wlan_pdev_get_psoc(pdev); 385 if (!psoc) { 386 reg_err("psoc is NULL"); 387 return QDF_STATUS_E_INVAL; 388 } 389 390 psoc_priv_obj = reg_get_psoc_obj(psoc); 391 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 392 reg_err("psoc reg component is NULL"); 393 return QDF_STATUS_E_INVAL; 394 } 395 396 reg_info("setting band_info: %d", band); 397 pdev_priv_obj->band_capability = band; 398 399 reg_compute_pdev_current_chan_list(pdev_priv_obj); 400 401 status = reg_send_scheduler_msg_sb(psoc, pdev); 402 403 return status; 404 } 405 406 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, 407 enum band_info *band) 408 { 409 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 410 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 411 struct wlan_objmgr_psoc *psoc; 412 413 pdev_priv_obj = reg_get_pdev_obj(pdev); 414 415 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 416 reg_err("pdev reg component is NULL"); 417 return QDF_STATUS_E_INVAL; 418 } 419 420 psoc = wlan_pdev_get_psoc(pdev); 421 if (!psoc) { 422 reg_err("psoc is NULL"); 423 return QDF_STATUS_E_INVAL; 424 } 425 426 psoc_priv_obj = reg_get_psoc_obj(psoc); 427 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 428 reg_err("psoc reg component is NULL"); 429 return QDF_STATUS_E_INVAL; 430 } 431 432 reg_debug("getting band_info: %d", pdev_priv_obj->band_capability); 433 *band = pdev_priv_obj->band_capability; 434 435 return QDF_STATUS_SUCCESS; 436 } 437 438 #ifdef DISABLE_CHANNEL_LIST 439 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 440 { 441 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 442 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 443 struct wlan_objmgr_psoc *psoc; 444 QDF_STATUS status; 445 446 pdev_priv_obj = reg_get_pdev_obj(pdev); 447 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 448 reg_err("pdev reg component is NULL"); 449 return QDF_STATUS_E_INVAL; 450 } 451 452 psoc = wlan_pdev_get_psoc(pdev); 453 if (!psoc) { 454 reg_err("psoc is NULL"); 455 return QDF_STATUS_E_INVAL; 456 } 457 458 psoc_priv_obj = reg_get_psoc_obj(psoc); 459 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 460 reg_err("psoc reg component is NULL"); 461 return QDF_STATUS_E_INVAL; 462 } 463 464 pdev_priv_obj->disable_cached_channels = false; 465 reg_compute_pdev_current_chan_list(pdev_priv_obj); 466 status = reg_send_scheduler_msg_sb(psoc, pdev); 467 return status; 468 } 469 470 QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, 471 uint32_t *channel_list, 472 uint32_t num_channels) 473 { 474 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 475 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 476 struct wlan_objmgr_psoc *psoc; 477 uint8_t i, j; 478 479 pdev_priv_obj = reg_get_pdev_obj(pdev); 480 481 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 482 reg_err("pdev reg component is NULL"); 483 return QDF_STATUS_E_INVAL; 484 } 485 486 psoc = wlan_pdev_get_psoc(pdev); 487 if (!psoc) { 488 reg_err("psoc is NULL"); 489 return QDF_STATUS_E_INVAL; 490 } 491 492 psoc_priv_obj = reg_get_psoc_obj(psoc); 493 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 494 reg_err("psoc reg component is NULL"); 495 return QDF_STATUS_E_INVAL; 496 } 497 if (pdev_priv_obj->num_cache_channels > 0) { 498 pdev_priv_obj->num_cache_channels = 0; 499 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 500 sizeof(pdev_priv_obj->cache_disable_chan_list)); 501 } 502 503 for (i = 0; i < num_channels; i++) { 504 for (j = 0; j < NUM_CHANNELS; j++) { 505 if (channel_list[i] == pdev_priv_obj-> 506 cur_chan_list[j].chan_num) { 507 pdev_priv_obj-> 508 cache_disable_chan_list[i].chan_num = 509 channel_list[i]; 510 pdev_priv_obj-> 511 cache_disable_chan_list[i].state = 512 pdev_priv_obj->cur_chan_list[j].state; 513 pdev_priv_obj-> 514 cache_disable_chan_list[i].chan_flags = 515 pdev_priv_obj-> 516 cur_chan_list[j].chan_flags; 517 } 518 } 519 } 520 pdev_priv_obj->num_cache_channels = num_channels; 521 522 return QDF_STATUS_SUCCESS; 523 } 524 525 void set_disable_channel_state( 526 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 527 { 528 pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; 529 } 530 #endif 531 532 #ifdef CONFIG_REG_CLIENT 533 534 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 535 bool fcc_constraint) 536 { 537 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 538 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 539 struct wlan_objmgr_psoc *psoc; 540 QDF_STATUS status; 541 542 pdev_priv_obj = reg_get_pdev_obj(pdev); 543 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 544 reg_err("pdev reg component is NULL"); 545 return QDF_STATUS_E_INVAL; 546 } 547 548 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 549 reg_info("fcc_constraint is already set to %d", fcc_constraint); 550 return QDF_STATUS_SUCCESS; 551 } 552 553 reg_info("setting set_fcc_channel: %d", fcc_constraint); 554 pdev_priv_obj->set_fcc_channel = fcc_constraint; 555 556 psoc = wlan_pdev_get_psoc(pdev); 557 if (!psoc) { 558 reg_err("psoc is NULL"); 559 return QDF_STATUS_E_INVAL; 560 } 561 562 psoc_priv_obj = reg_get_psoc_obj(psoc); 563 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 564 reg_err("psoc reg component is NULL"); 565 return QDF_STATUS_E_INVAL; 566 } 567 568 reg_compute_pdev_current_chan_list(pdev_priv_obj); 569 570 status = reg_send_scheduler_msg_sb(psoc, pdev); 571 572 return status; 573 } 574 575 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) 576 { 577 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 578 579 pdev_priv_obj = reg_get_pdev_obj(pdev); 580 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 581 reg_err("pdev reg component is NULL"); 582 return false; 583 } 584 585 if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ) 586 return false; 587 588 if (!pdev_priv_obj->set_fcc_channel) 589 return false; 590 591 return true; 592 } 593 594 #endif /* CONFIG_REG_CLIENT */ 595 596 /** 597 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 598 * @psoc: Pointer to global psoc structure. 599 * @object: Pointer to global pdev structure. 600 * @arg: Pointer to argument list. 601 */ 602 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 603 void *object, void *arg) 604 { 605 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 606 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 607 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 608 609 psoc_priv_obj = reg_get_psoc_obj(psoc); 610 if (!psoc_priv_obj) { 611 reg_err("psoc priv obj is NULL"); 612 return; 613 } 614 615 pdev_priv_obj = reg_get_pdev_obj(pdev); 616 617 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 618 reg_err("reg pdev private obj is NULL"); 619 return; 620 } 621 622 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 623 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 624 pdev_priv_obj->force_ssc_disable_indoor_channel = 625 psoc_priv_obj->force_ssc_disable_indoor_channel; 626 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 627 628 reg_compute_pdev_current_chan_list(pdev_priv_obj); 629 630 reg_send_scheduler_msg_sb(psoc, pdev); 631 } 632 633 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 634 struct reg_config_vars config_vars) 635 { 636 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 637 QDF_STATUS status; 638 639 psoc_priv_obj = reg_get_psoc_obj(psoc); 640 if (!psoc_priv_obj) { 641 reg_err("psoc priv obj is NULL"); 642 return QDF_STATUS_E_FAILURE; 643 } 644 645 psoc_priv_obj->enable_11d_supp_original = 646 config_vars.enable_11d_support; 647 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 648 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 649 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 650 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 651 psoc_priv_obj->force_ssc_disable_indoor_channel = 652 config_vars.force_ssc_disable_indoor_channel; 653 psoc_priv_obj->band_capability = config_vars.band_capability; 654 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 655 psoc_priv_obj->enable_srd_chan_in_master_mode = 656 config_vars.enable_srd_chan_in_master_mode; 657 psoc_priv_obj->enable_11d_in_world_mode = 658 config_vars.enable_11d_in_world_mode; 659 660 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 661 if (QDF_IS_STATUS_ERROR(status)) { 662 reg_err("error taking psoc ref cnt"); 663 return status; 664 } 665 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 666 reg_change_pdev_for_config, 667 NULL, 1, WLAN_REGULATORY_SB_ID); 668 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 669 670 return status; 671 } 672 673 bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) 674 { 675 enum channel_state ch_state; 676 677 ch_state = reg_get_channel_state(pdev, chan); 678 679 return ch_state == CHANNEL_STATE_DISABLE; 680 } 681 682 bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 683 { 684 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 685 686 psoc_priv_obj = reg_get_psoc_obj(psoc); 687 if (!psoc_priv_obj) { 688 reg_err("reg psoc private obj is NULL"); 689 return false; 690 } 691 692 return psoc_priv_obj->offload_enabled; 693 } 694 695 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 696 struct regulatory_channel *reg_channels, 697 uint8_t *alpha2, 698 enum dfs_reg dfs_region) 699 { 700 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 701 QDF_STATUS status; 702 uint32_t count; 703 enum direction dir; 704 uint32_t pdev_cnt; 705 706 psoc_priv_obj = reg_get_psoc_obj(psoc); 707 if (!psoc_priv_obj) { 708 reg_err("reg psoc private obj is NULL"); 709 return; 710 } 711 712 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 713 REG_ALPHA2_LEN); 714 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 715 for (count = 0; count < NUM_CHANNELS; count++) { 716 reg_channels[count].chan_num = channel_map[count].chan_num; 717 reg_channels[count].center_freq = 718 channel_map[count].center_freq; 719 reg_channels[count].nol_chan = false; 720 } 721 722 for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) { 723 qdf_mem_copy(psoc_priv_obj->mas_chan_params[pdev_cnt]. 724 mas_chan_list, reg_channels, 725 NUM_CHANNELS * sizeof(struct regulatory_channel)); 726 727 psoc_priv_obj->mas_chan_params[pdev_cnt].dfs_region = 728 dfs_region; 729 } 730 731 dir = SOUTHBOUND; 732 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 733 if (QDF_IS_STATUS_ERROR(status)) { 734 reg_err("error taking psoc ref cnt"); 735 return; 736 } 737 status = wlan_objmgr_iterate_obj_list( 738 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 739 &dir, 1, WLAN_REGULATORY_SB_ID); 740 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 741 } 742 743 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 744 uint8_t *alpha2) 745 { 746 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 747 748 psoc_priv_obj = reg_get_psoc_obj(psoc); 749 if (!psoc_priv_obj) { 750 reg_err("reg psoc private obj is NULL"); 751 return SOURCE_UNKNOWN; 752 } 753 754 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 755 756 return psoc_priv_obj->cc_src; 757 } 758 759 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev, 760 struct reg_rule_info *reg_rules) 761 { 762 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 763 764 if (!pdev) { 765 reg_err("pdev is NULL"); 766 return QDF_STATUS_E_FAILURE; 767 } 768 769 pdev_priv_obj = reg_get_pdev_obj(pdev); 770 if (!pdev_priv_obj) { 771 reg_err("pdev priv obj is NULL"); 772 return QDF_STATUS_E_FAILURE; 773 } 774 775 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 776 qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules, 777 sizeof(struct reg_rule_info)); 778 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 779 780 return QDF_STATUS_SUCCESS; 781 } 782 783 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 784 *soc_reg) 785 { 786 uint8_t ctr; 787 788 if (!soc_reg->offload_enabled) 789 return; 790 791 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 792 soc_reg->new_user_ctry_pending[ctr] = false; 793 soc_reg->new_init_ctry_pending[ctr] = false; 794 soc_reg->new_11d_ctry_pending[ctr] = false; 795 soc_reg->world_country_pending[ctr] = false; 796 } 797 } 798 799 QDF_STATUS reg_set_curr_country( 800 struct wlan_regulatory_psoc_priv_obj *soc_reg, 801 struct cur_regulatory_info *regulat_info, 802 struct wlan_lmac_if_reg_tx_ops *tx_ops) 803 { 804 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 805 uint8_t pdev_id; 806 struct set_country country_code; 807 QDF_STATUS status; 808 809 /* 810 * During SSR/WLAN restart ignore master channel list 811 * for all events and in the last event handling if 812 * current country and default country is different, send the last 813 * configured (soc_reg->cur_country) country. 814 */ 815 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 816 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 817 REG_ALPHA2_LEN))) 818 return QDF_STATUS_SUCCESS; 819 820 pdev_id = soc_reg->def_pdev_id; 821 if (soc_reg->cc_src == SOURCE_USERSPACE) 822 soc_reg->new_user_ctry_pending[pdev_id] = true; 823 else if (soc_reg->cc_src == SOURCE_11D) 824 soc_reg->new_11d_ctry_pending[pdev_id] = true; 825 else 826 soc_reg->world_country_pending[pdev_id] = true; 827 828 qdf_mem_zero(&country_code, sizeof(country_code)); 829 qdf_mem_copy(country_code.country, soc_reg->cur_country, 830 sizeof(soc_reg->cur_country)); 831 country_code.pdev_id = pdev_id; 832 833 if (!tx_ops || !tx_ops->set_country_code) { 834 reg_err("No regulatory tx_ops for set_country_code"); 835 status = QDF_STATUS_E_FAULT; 836 goto error; 837 } 838 839 status = tx_ops->set_country_code(psoc, &country_code); 840 if (QDF_IS_STATUS_ERROR(status)) { 841 reg_err("Failed to send country code to firmware"); 842 goto error; 843 } 844 845 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 846 regulat_info->alpha2, soc_reg->cur_country); 847 848 return status; 849 850 error: 851 reg_reset_ctry_pending_hints(soc_reg); 852 853 return status; 854 } 855 856 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 857 struct cur_regulatory_info *regulat_info) 858 { 859 uint8_t pdev_id; 860 861 if (!soc_reg->offload_enabled) 862 return false; 863 864 if (soc_reg->cc_src == SOURCE_UNKNOWN) 865 return false; 866 867 pdev_id = regulat_info->phy_id; 868 869 if (soc_reg->new_user_ctry_pending[pdev_id] || 870 soc_reg->new_init_ctry_pending[pdev_id] || 871 soc_reg->new_11d_ctry_pending[pdev_id] || 872 soc_reg->world_country_pending[pdev_id]) 873 return false; 874 875 return true; 876 } 877