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