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.reg_2g_5g_pair_id = 262 pdev_priv_obj->def_region_domain; 263 else 264 rd.cc.regdmn.reg_2g_5g_pair_id = 265 DEFAULT_WORLD_REGDMN; 266 rd.flags = REGDMN_IS_SET; 267 } else { 268 qdf_mem_copy(rd.cc.alpha, cc.country, 269 REG_ALPHA2_LEN + 1); 270 rd.flags = ALPHA_IS_SET; 271 } 272 273 reg_program_chan_list(pdev, &rd); 274 } 275 276 return QDF_STATUS_SUCCESS; 277 } 278 279 QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc) 280 { 281 struct wlan_regulatory_psoc_priv_obj *psoc_reg; 282 283 psoc_reg = reg_get_psoc_obj(psoc); 284 if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) { 285 reg_err("psoc reg component is NULL"); 286 return QDF_STATUS_E_INVAL; 287 } 288 289 qdf_mem_copy(psoc_reg->cur_country, 290 psoc_reg->def_country, 291 REG_ALPHA2_LEN + 1); 292 reg_debug("set cur_country %.2s", psoc_reg->cur_country); 293 294 return QDF_STATUS_SUCCESS; 295 } 296 297 QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, 298 const uint8_t *country_alpha2, 299 enum country_src source) 300 { 301 if (!reg_domain_ptr) { 302 reg_err("Invalid reg domain pointer"); 303 return QDF_STATUS_E_FAULT; 304 } 305 306 *reg_domain_ptr = 0; 307 308 if (!country_alpha2) { 309 reg_err("Country code is NULL"); 310 return QDF_STATUS_E_FAULT; 311 } 312 313 return QDF_STATUS_SUCCESS; 314 } 315 316 #ifdef CONFIG_CHAN_NUM_API 317 bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, 318 uint8_t chan) 319 { 320 enum channel_state ch_state; 321 322 ch_state = reg_get_channel_state(pdev, chan); 323 324 return (ch_state == CHANNEL_STATE_DFS) || 325 (ch_state == CHANNEL_STATE_DISABLE); 326 } 327 #endif /* CONFIG_CHAN_NUM_API */ 328 329 #ifdef CONFIG_CHAN_FREQ_API 330 bool reg_is_passive_or_disable_for_freq(struct wlan_objmgr_pdev *pdev, 331 qdf_freq_t freq) 332 { 333 enum channel_state chan_state; 334 335 chan_state = reg_get_channel_state_for_freq(pdev, freq); 336 337 return (chan_state == CHANNEL_STATE_DFS) || 338 (chan_state == CHANNEL_STATE_DISABLE); 339 } 340 #endif /* CONFIG_CHAN_FREQ_API */ 341 342 #ifdef WLAN_FEATURE_DSRC 343 #ifdef CONFIG_CHAN_FREQ_API 344 bool reg_is_dsrc_freq(qdf_freq_t freq) 345 { 346 if (!REG_IS_5GHZ_FREQ(freq)) 347 return false; 348 349 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 350 return false; 351 352 return true; 353 } 354 #endif /*CONFIG_CHAN_FREQ_API*/ 355 356 #ifdef CONFIG_CHAN_NUM_API 357 bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) 358 { 359 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 360 qdf_freq_t freq = 0; 361 362 pdev_priv_obj = reg_get_pdev_obj(pdev); 363 364 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 365 reg_err("reg pdev priv obj is NULL"); 366 return false; 367 } 368 369 if (!REG_IS_5GHZ_CH(chan)) 370 return false; 371 372 freq = reg_chan_to_freq(pdev, chan); 373 374 if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ)) 375 return false; 376 377 return true; 378 } 379 #endif /* CONFIG_CHAN_NUM_API */ 380 381 #else 382 383 bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev) 384 { 385 struct cur_regdmn_info cur_reg_dmn; 386 QDF_STATUS status; 387 388 status = reg_get_curr_regdomain(pdev, &cur_reg_dmn); 389 if (status != QDF_STATUS_SUCCESS) { 390 reg_debug_rl("Failed to get reg domain"); 391 return false; 392 } 393 394 return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g); 395 } 396 397 #ifdef CONFIG_CHAN_FREQ_API 398 bool reg_is_etsi13_srd_chan_for_freq(struct wlan_objmgr_pdev *pdev, 399 uint16_t freq) 400 { 401 if (!REG_IS_5GHZ_FREQ(freq)) 402 return false; 403 404 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 405 freq <= REG_ETSI13_SRD_END_FREQ)) 406 return false; 407 408 return reg_is_etsi13_regdmn(pdev); 409 } 410 #endif /* CONFIG_CHAN_FREQ_API */ 411 412 #ifdef CONFIG_CHAN_NUM_API 413 bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint8_t chan) 414 { 415 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 416 qdf_freq_t freq = 0; 417 418 pdev_priv_obj = reg_get_pdev_obj(pdev); 419 420 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 421 reg_err("reg pdev priv obj is NULL"); 422 return false; 423 } 424 425 if (!REG_IS_5GHZ_CH(chan)) 426 return false; 427 428 freq = reg_chan_to_freq(pdev, chan); 429 430 if (!(freq >= REG_ETSI13_SRD_START_FREQ && 431 freq <= REG_ETSI13_SRD_END_FREQ)) 432 return false; 433 434 return reg_is_etsi13_regdmn(pdev); 435 } 436 #endif /* CONFIG_CHAN_NUM_API */ 437 438 bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev) 439 { 440 struct wlan_objmgr_psoc *psoc; 441 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 442 443 if (!pdev) { 444 reg_alert("pdev is NULL"); 445 return true; 446 } 447 psoc = wlan_pdev_get_psoc(pdev); 448 449 psoc_priv_obj = reg_get_psoc_obj(psoc); 450 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 451 reg_alert("psoc reg component is NULL"); 452 return true; 453 } 454 455 return psoc_priv_obj->enable_srd_chan_in_master_mode && 456 reg_is_etsi13_regdmn(pdev); 457 } 458 #endif 459 460 QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, uint32_t band_bitmap) 461 { 462 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 463 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 464 struct wlan_objmgr_psoc *psoc; 465 QDF_STATUS status; 466 467 pdev_priv_obj = reg_get_pdev_obj(pdev); 468 469 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 470 reg_err("pdev reg component is NULL"); 471 return QDF_STATUS_E_INVAL; 472 } 473 474 if (pdev_priv_obj->band_capability == band_bitmap) { 475 reg_info("same band %d", band_bitmap); 476 return QDF_STATUS_SUCCESS; 477 } 478 479 psoc = wlan_pdev_get_psoc(pdev); 480 if (!psoc) { 481 reg_err("psoc is NULL"); 482 return QDF_STATUS_E_INVAL; 483 } 484 485 psoc_priv_obj = reg_get_psoc_obj(psoc); 486 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 487 reg_err("psoc reg component is NULL"); 488 return QDF_STATUS_E_INVAL; 489 } 490 491 reg_info("set band bitmap: %d", band_bitmap); 492 pdev_priv_obj->band_capability = band_bitmap; 493 494 reg_compute_pdev_current_chan_list(pdev_priv_obj); 495 496 status = reg_send_scheduler_msg_sb(psoc, pdev); 497 498 return status; 499 } 500 501 QDF_STATUS reg_get_band(struct wlan_objmgr_pdev *pdev, 502 uint32_t *band_bitmap) 503 { 504 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 505 506 pdev_priv_obj = reg_get_pdev_obj(pdev); 507 508 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 509 reg_err("pdev reg component is NULL"); 510 return QDF_STATUS_E_INVAL; 511 } 512 513 reg_debug("get band bitmap: %d", pdev_priv_obj->band_capability); 514 *band_bitmap = pdev_priv_obj->band_capability; 515 516 return QDF_STATUS_SUCCESS; 517 } 518 519 #ifdef DISABLE_CHANNEL_LIST 520 QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev) 521 { 522 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 523 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 524 struct wlan_objmgr_psoc *psoc; 525 QDF_STATUS status; 526 527 pdev_priv_obj = reg_get_pdev_obj(pdev); 528 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 529 reg_err("pdev reg component is NULL"); 530 return QDF_STATUS_E_INVAL; 531 } 532 533 psoc = wlan_pdev_get_psoc(pdev); 534 if (!psoc) { 535 reg_err("psoc is NULL"); 536 return QDF_STATUS_E_INVAL; 537 } 538 539 psoc_priv_obj = reg_get_psoc_obj(psoc); 540 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 541 reg_err("psoc reg component is NULL"); 542 return QDF_STATUS_E_INVAL; 543 } 544 545 pdev_priv_obj->disable_cached_channels = false; 546 reg_compute_pdev_current_chan_list(pdev_priv_obj); 547 status = reg_send_scheduler_msg_sb(psoc, pdev); 548 return status; 549 } 550 551 #ifdef CONFIG_CHAN_FREQ_API 552 QDF_STATUS reg_cache_channel_freq_state(struct wlan_objmgr_pdev *pdev, 553 uint32_t *channel_list, 554 uint32_t num_channels) 555 { 556 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 557 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 558 struct wlan_objmgr_psoc *psoc; 559 uint16_t i, j; 560 561 pdev_priv_obj = reg_get_pdev_obj(pdev); 562 563 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 564 reg_err("pdev reg component is NULL"); 565 return QDF_STATUS_E_INVAL; 566 } 567 568 psoc = wlan_pdev_get_psoc(pdev); 569 if (!psoc) { 570 reg_err("psoc is NULL"); 571 return QDF_STATUS_E_INVAL; 572 } 573 574 psoc_priv_obj = reg_get_psoc_obj(psoc); 575 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 576 reg_err("psoc reg component is NULL"); 577 return QDF_STATUS_E_INVAL; 578 } 579 if (pdev_priv_obj->num_cache_channels > 0) { 580 pdev_priv_obj->num_cache_channels = 0; 581 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 582 sizeof(pdev_priv_obj->cache_disable_chan_list)); 583 } 584 585 for (i = 0; i < num_channels; i++) { 586 for (j = 0; j < NUM_CHANNELS; j++) { 587 if (channel_list[i] == pdev_priv_obj-> 588 cur_chan_list[j].center_freq) { 589 pdev_priv_obj-> 590 cache_disable_chan_list[i].center_freq = 591 channel_list[i]; 592 pdev_priv_obj-> 593 cache_disable_chan_list[i].state = 594 pdev_priv_obj->cur_chan_list[j].state; 595 pdev_priv_obj-> 596 cache_disable_chan_list[i].chan_flags = 597 pdev_priv_obj-> 598 cur_chan_list[j].chan_flags; 599 } 600 } 601 } 602 pdev_priv_obj->num_cache_channels = num_channels; 603 604 return QDF_STATUS_SUCCESS; 605 } 606 #endif /* CONFIG_CHAN_FREQ_API */ 607 608 #ifdef CONFIG_CHAN_NUM_API 609 QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev, 610 uint32_t *channel_list, 611 uint32_t num_channels) 612 { 613 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 614 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 615 struct wlan_objmgr_psoc *psoc; 616 uint8_t i, j; 617 618 pdev_priv_obj = reg_get_pdev_obj(pdev); 619 620 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 621 reg_err("pdev reg component is NULL"); 622 return QDF_STATUS_E_INVAL; 623 } 624 625 psoc = wlan_pdev_get_psoc(pdev); 626 if (!psoc) { 627 reg_err("psoc is NULL"); 628 return QDF_STATUS_E_INVAL; 629 } 630 631 psoc_priv_obj = reg_get_psoc_obj(psoc); 632 if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) { 633 reg_err("psoc reg component is NULL"); 634 return QDF_STATUS_E_INVAL; 635 } 636 if (pdev_priv_obj->num_cache_channels > 0) { 637 pdev_priv_obj->num_cache_channels = 0; 638 qdf_mem_zero(&pdev_priv_obj->cache_disable_chan_list, 639 sizeof(pdev_priv_obj->cache_disable_chan_list)); 640 } 641 642 for (i = 0; i < num_channels; i++) { 643 for (j = 0; j < NUM_CHANNELS; j++) { 644 if (channel_list[i] == pdev_priv_obj-> 645 cur_chan_list[j].chan_num) { 646 pdev_priv_obj-> 647 cache_disable_chan_list[i].chan_num = 648 channel_list[i]; 649 pdev_priv_obj-> 650 cache_disable_chan_list[i].state = 651 pdev_priv_obj->cur_chan_list[j].state; 652 pdev_priv_obj-> 653 cache_disable_chan_list[i].chan_flags = 654 pdev_priv_obj-> 655 cur_chan_list[j].chan_flags; 656 } 657 } 658 } 659 pdev_priv_obj->num_cache_channels = num_channels; 660 661 return QDF_STATUS_SUCCESS; 662 } 663 #endif /* CONFIG_CHAN_NUM_API */ 664 void set_disable_channel_state( 665 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj) 666 { 667 pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state; 668 } 669 #endif 670 671 #ifdef CONFIG_REG_CLIENT 672 673 QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev, 674 bool fcc_constraint) 675 { 676 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 677 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 678 struct wlan_objmgr_psoc *psoc; 679 QDF_STATUS status; 680 681 pdev_priv_obj = reg_get_pdev_obj(pdev); 682 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 683 reg_err("pdev reg component is NULL"); 684 return QDF_STATUS_E_INVAL; 685 } 686 687 if (pdev_priv_obj->set_fcc_channel == fcc_constraint) { 688 reg_info("same fcc_constraint %d", fcc_constraint); 689 return QDF_STATUS_SUCCESS; 690 } 691 692 reg_info("set fcc_constraint: %d", fcc_constraint); 693 pdev_priv_obj->set_fcc_channel = fcc_constraint; 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 707 reg_compute_pdev_current_chan_list(pdev_priv_obj); 708 709 status = reg_send_scheduler_msg_sb(psoc, pdev); 710 711 return status; 712 } 713 714 bool reg_get_fcc_constraint(struct wlan_objmgr_pdev *pdev, uint32_t freq) 715 { 716 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 717 718 pdev_priv_obj = reg_get_pdev_obj(pdev); 719 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 720 reg_err("pdev reg component is NULL"); 721 return false; 722 } 723 724 if (freq != CHAN_12_CENT_FREQ && freq != CHAN_13_CENT_FREQ) 725 return false; 726 727 if (!pdev_priv_obj->set_fcc_channel) 728 return false; 729 730 return true; 731 } 732 733 #endif /* CONFIG_REG_CLIENT */ 734 735 /** 736 * reg_change_pdev_for_config() - Update user configuration in pdev private obj. 737 * @psoc: Pointer to global psoc structure. 738 * @object: Pointer to global pdev structure. 739 * @arg: Pointer to argument list. 740 */ 741 static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc, 742 void *object, void *arg) 743 { 744 struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; 745 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 746 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 747 748 psoc_priv_obj = reg_get_psoc_obj(psoc); 749 if (!psoc_priv_obj) { 750 reg_err("psoc priv obj is NULL"); 751 return; 752 } 753 754 pdev_priv_obj = reg_get_pdev_obj(pdev); 755 756 if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) { 757 reg_err("reg pdev private obj is NULL"); 758 return; 759 } 760 761 pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled; 762 pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled; 763 pdev_priv_obj->force_ssc_disable_indoor_channel = 764 psoc_priv_obj->force_ssc_disable_indoor_channel; 765 pdev_priv_obj->band_capability = psoc_priv_obj->band_capability; 766 767 reg_compute_pdev_current_chan_list(pdev_priv_obj); 768 769 reg_send_scheduler_msg_sb(psoc, pdev); 770 } 771 772 QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc, 773 struct reg_config_vars config_vars) 774 { 775 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 776 QDF_STATUS status; 777 778 psoc_priv_obj = reg_get_psoc_obj(psoc); 779 if (!psoc_priv_obj) { 780 reg_err("psoc priv obj is NULL"); 781 return QDF_STATUS_E_FAILURE; 782 } 783 784 psoc_priv_obj->enable_11d_supp_original = 785 config_vars.enable_11d_support; 786 psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval; 787 psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority; 788 psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled; 789 psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled; 790 psoc_priv_obj->force_ssc_disable_indoor_channel = 791 config_vars.force_ssc_disable_indoor_channel; 792 psoc_priv_obj->band_capability = config_vars.band_capability; 793 psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing; 794 psoc_priv_obj->enable_srd_chan_in_master_mode = 795 config_vars.enable_srd_chan_in_master_mode; 796 psoc_priv_obj->enable_11d_in_world_mode = 797 config_vars.enable_11d_in_world_mode; 798 psoc_priv_obj->enable_5dot9_ghz_chan_in_master_mode = 799 config_vars.enable_5dot9_ghz_chan_in_master_mode; 800 psoc_priv_obj->retain_nol_across_regdmn_update = 801 config_vars.retain_nol_across_regdmn_update; 802 803 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 804 if (QDF_IS_STATUS_ERROR(status)) { 805 reg_err("error taking psoc ref cnt"); 806 return status; 807 } 808 status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, 809 reg_change_pdev_for_config, 810 NULL, 1, WLAN_REGULATORY_SB_ID); 811 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 812 813 return status; 814 } 815 816 bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 817 { 818 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 819 820 psoc_priv_obj = reg_get_psoc_obj(psoc); 821 if (!psoc_priv_obj) { 822 reg_err("reg psoc private obj is NULL"); 823 return false; 824 } 825 826 return psoc_priv_obj->offload_enabled; 827 } 828 829 void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc, 830 struct regulatory_channel *reg_channels, 831 uint8_t *alpha2, 832 enum dfs_reg dfs_region) 833 { 834 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 835 QDF_STATUS status; 836 uint32_t count; 837 enum direction dir; 838 uint32_t phy_cnt; 839 840 psoc_priv_obj = reg_get_psoc_obj(psoc); 841 if (!psoc_priv_obj) { 842 reg_err("reg psoc private obj is NULL"); 843 return; 844 } 845 846 qdf_mem_copy(psoc_priv_obj->cur_country, alpha2, 847 REG_ALPHA2_LEN); 848 reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country); 849 for (count = 0; count < NUM_CHANNELS; count++) { 850 reg_channels[count].chan_num = channel_map[count].chan_num; 851 reg_channels[count].center_freq = 852 channel_map[count].center_freq; 853 reg_channels[count].nol_chan = false; 854 } 855 856 for (phy_cnt = 0; phy_cnt < PSOC_MAX_PHY_REG_CAP; phy_cnt++) { 857 qdf_mem_copy(psoc_priv_obj->mas_chan_params[phy_cnt]. 858 mas_chan_list, reg_channels, 859 NUM_CHANNELS * sizeof(struct regulatory_channel)); 860 861 psoc_priv_obj->mas_chan_params[phy_cnt].dfs_region = 862 dfs_region; 863 } 864 865 dir = SOUTHBOUND; 866 status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID); 867 if (QDF_IS_STATUS_ERROR(status)) { 868 reg_err("error taking psoc ref cnt"); 869 return; 870 } 871 status = wlan_objmgr_iterate_obj_list( 872 psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev, 873 &dir, 1, WLAN_REGULATORY_SB_ID); 874 wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID); 875 } 876 877 enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc, 878 uint8_t *alpha2) 879 { 880 struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj; 881 882 psoc_priv_obj = reg_get_psoc_obj(psoc); 883 if (!psoc_priv_obj) { 884 reg_err("reg psoc private obj is NULL"); 885 return SOURCE_UNKNOWN; 886 } 887 888 qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1); 889 890 return psoc_priv_obj->cc_src; 891 } 892 893 QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev, 894 struct reg_rule_info *reg_rules) 895 { 896 struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; 897 898 if (!pdev) { 899 reg_err("pdev is NULL"); 900 return QDF_STATUS_E_FAILURE; 901 } 902 903 pdev_priv_obj = reg_get_pdev_obj(pdev); 904 if (!pdev_priv_obj) { 905 reg_err("pdev priv obj is NULL"); 906 return QDF_STATUS_E_FAILURE; 907 } 908 909 qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock); 910 qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules, 911 sizeof(struct reg_rule_info)); 912 qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock); 913 914 return QDF_STATUS_SUCCESS; 915 } 916 917 void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj 918 *soc_reg) 919 { 920 uint8_t ctr; 921 922 if (!soc_reg->offload_enabled) 923 return; 924 925 for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) { 926 soc_reg->new_user_ctry_pending[ctr] = false; 927 soc_reg->new_init_ctry_pending[ctr] = false; 928 soc_reg->new_11d_ctry_pending[ctr] = false; 929 soc_reg->world_country_pending[ctr] = false; 930 } 931 } 932 933 QDF_STATUS reg_set_curr_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 934 struct cur_regulatory_info *regulat_info, 935 struct wlan_lmac_if_reg_tx_ops *tx_ops) 936 { 937 struct wlan_objmgr_psoc *psoc = regulat_info->psoc; 938 uint8_t pdev_id; 939 uint8_t phy_num; 940 struct set_country country_code; 941 QDF_STATUS status; 942 943 /* 944 * During SSR/WLAN restart ignore master channel list 945 * for all events and in the last event handling if 946 * current country and default country is different, send the last 947 * configured (soc_reg->cur_country) country. 948 */ 949 if ((regulat_info->num_phy != regulat_info->phy_id + 1) || 950 (!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2, 951 REG_ALPHA2_LEN))) 952 return QDF_STATUS_SUCCESS; 953 954 /* 955 * Need firmware to send channel list event 956 * for all phys. Therefore set pdev_id to 0xFF 957 */ 958 pdev_id = 0xFF; 959 for (phy_num = 0; phy_num < regulat_info->num_phy; phy_num++) { 960 if (soc_reg->cc_src == SOURCE_USERSPACE) 961 soc_reg->new_user_ctry_pending[phy_num] = true; 962 else if (soc_reg->cc_src == SOURCE_11D) 963 soc_reg->new_11d_ctry_pending[phy_num] = true; 964 else 965 soc_reg->world_country_pending[phy_num] = true; 966 } 967 968 qdf_mem_zero(&country_code, sizeof(country_code)); 969 qdf_mem_copy(country_code.country, soc_reg->cur_country, 970 sizeof(soc_reg->cur_country)); 971 country_code.pdev_id = pdev_id; 972 973 if (!tx_ops || !tx_ops->set_country_code) { 974 reg_err("No regulatory tx_ops"); 975 status = QDF_STATUS_E_FAULT; 976 goto error; 977 } 978 979 status = tx_ops->set_country_code(psoc, &country_code); 980 if (QDF_IS_STATUS_ERROR(status)) { 981 reg_err("Failed to send country code to fw"); 982 goto error; 983 } 984 985 reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s", 986 regulat_info->alpha2, soc_reg->cur_country); 987 988 return status; 989 990 error: 991 reg_reset_ctry_pending_hints(soc_reg); 992 993 return status; 994 } 995 996 bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg, 997 struct cur_regulatory_info *regulat_info) 998 { 999 uint8_t phy_num; 1000 1001 if (!soc_reg->offload_enabled) 1002 return false; 1003 1004 if (soc_reg->cc_src == SOURCE_UNKNOWN) 1005 return false; 1006 1007 phy_num = regulat_info->phy_id; 1008 if (soc_reg->new_user_ctry_pending[phy_num] || 1009 soc_reg->new_init_ctry_pending[phy_num] || 1010 soc_reg->new_11d_ctry_pending[phy_num] || 1011 soc_reg->world_country_pending[phy_num]) 1012 return false; 1013 1014 return true; 1015 } 1016