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 #ifdef DISABLE_CHANNEL_LIST 407 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 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 QDF_STATUS status; 413 414 pdev_priv_obj = reg_get_pdev_obj(pdev); 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 pdev_priv_obj->disable_cached_channels = false; 433 reg_compute_pdev_current_chan_list(pdev_priv_obj); 434 status = reg_send_scheduler_msg_sb(psoc, pdev); 435 return status; 436 } 437 438 QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, 439 uint32_t *channel_list, 440 uint32_t num_channels) 441 { 442 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 443 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 444 struct wlan_objmgr_psoc *psoc; 445 uint8_t i, j; 446 447 pdev_priv_obj = reg_get_pdev_obj(pdev); 448 449 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 450 reg_err("pdev reg component is NULL"); 451 return QDF_STATUS_E_INVAL; 452 } 453 454 psoc = wlan_pdev_get_psoc(pdev); 455 if (!psoc) { 456 reg_err("psoc is NULL"); 457 return QDF_STATUS_E_INVAL; 458 } 459 460 psoc_priv_obj = reg_get_psoc_obj(psoc); 461 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 462 reg_err("psoc reg component is NULL"); 463 return QDF_STATUS_E_INVAL; 464 } 465 if (pdev_priv_obj->num_cache_channels > 0) { 466 pdev_priv_obj->num_cache_channels = 0; 467 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 468 sizeof(pdev_priv_obj->cache_disable_chan_list)); 469 } 470 471 for (i = 0; i < num_channels; i++) { 472 for (j = 0; j < NUM_CHANNELS; j++) { 473 if (channel_list[i] == pdev_priv_obj-> 474 cur_chan_list[j].chan_num) { 475 pdev_priv_obj-> 476 cache_disable_chan_list[i].chan_num = 477 channel_list[i]; 478 pdev_priv_obj-> 479 cache_disable_chan_list[i].state = 480 pdev_priv_obj->cur_chan_list[j].state; 481 pdev_priv_obj-> 482 cache_disable_chan_list[i].chan_flags = 483 pdev_priv_obj-> 484 cur_chan_list[j].chan_flags; 485 } 486 } 487 } 488 pdev_priv_obj->num_cache_channels = num_channels; 489 490 return QDF_STATUS_SUCCESS; 491 } 492 493 void set_disable_channel_state( 494 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 495 { 496 pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; 497 } 498 #endif 499 500 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 501 bool fcc_constraint) 502 { 503 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 504 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 505 struct wlan_objmgr_psoc *psoc; 506 QDF_STATUS status; 507 508 pdev_priv_obj = reg_get_pdev_obj(pdev); 509 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 510 reg_err("pdev reg component is NULL"); 511 return QDF_STATUS_E_INVAL; 512 } 513 514 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 515 reg_info("fcc_constraint is already set to %d", fcc_constraint); 516 return QDF_STATUS_SUCCESS; 517 } 518 519 reg_info("setting set_fcc_channel: %d", fcc_constraint); 520 pdev_priv_obj->set_fcc_channel = fcc_constraint; 521 522 psoc = wlan_pdev_get_psoc(pdev); 523 if (!psoc) { 524 reg_err("psoc is NULL"); 525 return QDF_STATUS_E_INVAL; 526 } 527 528 psoc_priv_obj = reg_get_psoc_obj(psoc); 529 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 530 reg_err("psoc reg component is NULL"); 531 return QDF_STATUS_E_INVAL; 532 } 533 534 reg_compute_pdev_current_chan_list(pdev_priv_obj); 535 536 status = reg_send_scheduler_msg_sb(psoc, pdev); 537 538 return status; 539 } 540 541 /** 542 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 543 * @psoc: Pointer to global psoc structure. 544 * @object: Pointer to global pdev structure. 545 * @arg: Pointer to argument list. 546 */ 547 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 548 void *object, void *arg) 549 { 550 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 551 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 552 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 553 554 psoc_priv_obj = reg_get_psoc_obj(psoc); 555 if (!psoc_priv_obj) { 556 reg_err("psoc priv obj is NULL"); 557 return; 558 } 559 560 pdev_priv_obj = reg_get_pdev_obj(pdev); 561 562 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 563 reg_err("reg pdev private obj is NULL"); 564 return; 565 } 566 567 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 568 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 569 pdev_priv_obj->force_ssc_disable_indoor_channel = 570 psoc_priv_obj->force_ssc_disable_indoor_channel; 571 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 572 573 reg_compute_pdev_current_chan_list(pdev_priv_obj); 574 575 reg_send_scheduler_msg_sb(psoc, pdev); 576 } 577 578 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 579 struct reg_config_vars config_vars) 580 { 581 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 582 QDF_STATUS status; 583 584 psoc_priv_obj = reg_get_psoc_obj(psoc); 585 if (!psoc_priv_obj) { 586 reg_err("psoc priv obj is NULL"); 587 return QDF_STATUS_E_FAILURE; 588 } 589 590 psoc_priv_obj->enable_11d_supp_original = 591 config_vars.enable_11d_support; 592 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 593 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 594 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 595 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 596 psoc_priv_obj->force_ssc_disable_indoor_channel = 597 config_vars.force_ssc_disable_indoor_channel; 598 psoc_priv_obj->band_capability = config_vars.band_capability; 599 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 600 psoc_priv_obj->enable_srd_chan_in_master_mode = 601 config_vars.enable_srd_chan_in_master_mode; 602 psoc_priv_obj->enable_11d_in_world_mode = 603 config_vars.enable_11d_in_world_mode; 604 605 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 606 if (QDF_IS_STATUS_ERROR(status)) { 607 reg_err("error taking psoc ref cnt"); 608 return status; 609 } 610 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 611 reg_change_pdev_for_config, 612 NULL, 1, WLAN_REGULATORY_SB_ID); 613 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 614 615 return status; 616 } 617 618 bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan) 619 { 620 enum channel_state ch_state; 621 622 ch_state = reg_get_channel_state(pdev, chan); 623 624 return ch_state == CHANNEL_STATE_DISABLE; 625 } 626 627 bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 628 { 629 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 630 631 psoc_priv_obj = reg_get_psoc_obj(psoc); 632 if (!psoc_priv_obj) { 633 reg_err("reg psoc private obj is NULL"); 634 return false; 635 } 636 637 return psoc_priv_obj->offload_enabled; 638 } 639 640 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 641 struct regulatory_channel *reg_channels, 642 uint8_t *alpha2, 643 enum dfs_reg dfs_region) 644 { 645 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 646 QDF_STATUS status; 647 uint32_t count; 648 enum direction dir; 649 uint32_t pdev_cnt; 650 651 psoc_priv_obj = reg_get_psoc_obj(psoc); 652 if (!psoc_priv_obj) { 653 reg_err("reg psoc private obj is NULL"); 654 return; 655 } 656 657 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 658 REG_ALPHA2_LEN); 659 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 660 for (count = 0; count < NUM_CHANNELS; count++) { 661 reg_channels[count].chan_num = channel_map[count].chan_num; 662 reg_channels[count].center_freq = 663 channel_map[count].center_freq; 664 reg_channels[count].nol_chan = false; 665 } 666 667 for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) { 668 qdf_mem_copy(psoc_priv_obj->mas_chan_params[pdev_cnt]. 669 mas_chan_list, reg_channels, 670 NUM_CHANNELS * sizeof(struct regulatory_channel)); 671 672 psoc_priv_obj->mas_chan_params[pdev_cnt].dfs_region = 673 dfs_region; 674 } 675 676 dir = SOUTHBOUND; 677 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 678 if (QDF_IS_STATUS_ERROR(status)) { 679 reg_err("error taking psoc ref cnt"); 680 return; 681 } 682 status = wlan_objmgr_iterate_obj_list( 683 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 684 &dir, 1, WLAN_REGULATORY_SB_ID); 685 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 686 } 687 688 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 689 uint8_t *alpha2) 690 { 691 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 692 693 psoc_priv_obj = reg_get_psoc_obj(psoc); 694 if (!psoc_priv_obj) { 695 reg_err("reg psoc private obj is NULL"); 696 return SOURCE_UNKNOWN; 697 } 698 699 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 700 701 return psoc_priv_obj->cc_src; 702 } 703 704 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev, 705 struct reg_rule_info *reg_rules) 706 { 707 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 708 709 if (!pdev) { 710 reg_err("pdev is NULL"); 711 return QDF_STATUS_E_FAILURE; 712 } 713 714 pdev_priv_obj = reg_get_pdev_obj(pdev); 715 if (!pdev_priv_obj) { 716 reg_err("pdev priv obj is NULL"); 717 return QDF_STATUS_E_FAILURE; 718 } 719 720 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 721 qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules, 722 sizeof(struct reg_rule_info)); 723 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 724 725 return QDF_STATUS_SUCCESS; 726 } 727 728 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 729 *soc_reg) 730 { 731 uint8_t ctr; 732 733 if (!soc_reg->offload_enabled) 734 return; 735 736 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 737 soc_reg->new_user_ctry_pending[ctr] = false; 738 soc_reg->new_init_ctry_pending[ctr] = false; 739 soc_reg->new_11d_ctry_pending[ctr] = false; 740 soc_reg->world_country_pending[ctr] = false; 741 } 742 } 743 744 QDF_STATUS reg_set_curr_country( 745 struct wlan_regulatory_psoc_priv_obj *soc_reg, 746 struct cur_regulatory_info *regulat_info, 747 struct wlan_lmac_if_reg_tx_ops *tx_ops) 748 { 749 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 750 uint8_t pdev_id; 751 struct set_country country_code; 752 QDF_STATUS status; 753 754 /* 755 * During SSR/WLAN restart ignore master channel list 756 * for all events and in the last event handling if 757 * current country and default country is different, send the last 758 * configured (soc_reg->cur_country) country. 759 */ 760 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 761 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 762 REG_ALPHA2_LEN))) 763 return QDF_STATUS_SUCCESS; 764 765 pdev_id = soc_reg->def_pdev_id; 766 if (soc_reg->cc_src == SOURCE_USERSPACE) 767 soc_reg->new_user_ctry_pending[pdev_id] = true; 768 else if (soc_reg->cc_src == SOURCE_11D) 769 soc_reg->new_11d_ctry_pending[pdev_id] = true; 770 else 771 soc_reg->world_country_pending[pdev_id] = true; 772 773 qdf_mem_zero(&country_code, sizeof(country_code)); 774 qdf_mem_copy(country_code.country, soc_reg->cur_country, 775 sizeof(soc_reg->cur_country)); 776 country_code.pdev_id = pdev_id; 777 778 if (!tx_ops || !tx_ops->set_country_code) { 779 reg_err("No regulatory tx_ops for set_country_code"); 780 status = QDF_STATUS_E_FAULT; 781 goto error; 782 } 783 784 status = tx_ops->set_country_code(psoc, &country_code); 785 if (QDF_IS_STATUS_ERROR(status)) { 786 reg_err("Failed to send country code to firmware"); 787 goto error; 788 } 789 790 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 791 regulat_info->alpha2, soc_reg->cur_country); 792 793 return status; 794 795 error: 796 reg_reset_ctry_pending_hints(soc_reg); 797 798 return status; 799 } 800 801 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 802 struct cur_regulatory_info *regulat_info) 803 { 804 uint8_t pdev_id; 805 806 if (!soc_reg->offload_enabled) 807 return false; 808 809 if (soc_reg->cc_src == SOURCE_UNKNOWN) 810 return false; 811 812 pdev_id = regulat_info->phy_id; 813 814 if (soc_reg->new_user_ctry_pending[pdev_id] || 815 soc_reg->new_init_ctry_pending[pdev_id] || 816 soc_reg->new_11d_ctry_pending[pdev_id] || 817 soc_reg->world_country_pending[pdev_id]) 818 return false; 819 820 return true; 821 } 822