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