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