1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * 6 * Permission to use, copy, modify, and/or distribute this software for 7 * any purpose with or without fee is hereby granted, provided that the 8 * above copyright notice and this permission notice appear in all 9 * copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 * PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 /** 22 * DOC: target_if_reg.c 23 * This file contains regulatory target interfaces. 24 */ 25 26 #include <wmi_unified_api.h> 27 #include <reg_services_public_struct.h> 28 #include <wlan_reg_tgt_api.h> 29 #include <target_if.h> 30 #include <target_if_reg.h> 31 #include <wmi_unified_reg_api.h> 32 #include <qdf_platform.h> 33 #include <target_if_reg_11d.h> 34 #include <target_if_reg_lte.h> 35 #include <wlan_reg_ucfg_api.h> 36 37 /** 38 * get_chan_list_cc_event_id() - Get chan_list_cc event i 39 * 40 * Return: Event id 41 */ 42 static inline uint32_t get_chan_list_cc_event_id(void) 43 { 44 return wmi_reg_chan_list_cc_event_id; 45 } 46 47 /** 48 * tgt_if_regulatory_is_regdb_offloaded() - Check if regdb is offloaded 49 * @psoc: Pointer to psoc 50 * 51 * Return: true if regdb if offloaded, else false 52 */ 53 static bool tgt_if_regulatory_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc) 54 { 55 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 56 57 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 58 59 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 60 if (!reg_rx_ops) { 61 target_if_err("reg_rx_ops is NULL"); 62 return false; 63 } 64 65 if (!wmi_handle) 66 return false; 67 68 if (reg_rx_ops->reg_ignore_fw_reg_offload_ind && 69 reg_rx_ops->reg_ignore_fw_reg_offload_ind(psoc)) { 70 target_if_debug("User disabled regulatory offload from ini"); 71 return 0; 72 } 73 74 return wmi_service_enabled(wmi_handle, wmi_service_regulatory_db); 75 } 76 77 /** 78 * tgt_if_regulatory_is_6ghz_supported() - Check if 6ghz is supported 79 * @psoc: Pointer to psoc 80 * 81 * Return: true if regdb if offloaded, else false 82 */ 83 static bool tgt_if_regulatory_is_6ghz_supported(struct wlan_objmgr_psoc *psoc) 84 { 85 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 86 87 if (!wmi_handle) 88 return false; 89 90 return wmi_service_enabled(wmi_handle, wmi_service_6ghz_support); 91 } 92 93 /** 94 * tgt_if_regulatory_is_5dot9_ghz_supported() - Check if 5.9ghz is supported 95 * @psoc: Pointer to psoc 96 * 97 * Return: true if regdb if offloaded, else false 98 */ 99 static bool 100 tgt_if_regulatory_is_5dot9_ghz_supported(struct wlan_objmgr_psoc *psoc) 101 { 102 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 103 104 if (!wmi_handle) 105 return false; 106 107 return wmi_service_enabled(wmi_handle, wmi_service_5dot9_ghz_support); 108 } 109 110 /** 111 * tgt_if_regulatory_is_there_serv_ready_extn() - Check for service ready 112 * extension 113 * @psoc: Pointer to psoc object 114 * 115 * Return: true if service ready extension is present, else false. 116 */ 117 static bool tgt_if_regulatory_is_there_serv_ready_extn( 118 struct wlan_objmgr_psoc *psoc) 119 { 120 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 121 122 if (!wmi_handle) 123 return false; 124 125 return wmi_service_enabled(wmi_handle, wmi_service_ext_msg); 126 } 127 128 /** 129 * target_if_regulatory_get_rx_ops() - Get regdb rx ops 130 * @psoc: Pointer to psoc object 131 * 132 * Return: Reg rx_ops 133 */ 134 struct wlan_lmac_if_reg_rx_ops * 135 target_if_regulatory_get_rx_ops(struct wlan_objmgr_psoc *psoc) 136 { 137 struct wlan_lmac_if_rx_ops *rx_ops; 138 139 rx_ops = wlan_psoc_get_lmac_if_rxops(psoc); 140 if (!rx_ops) { 141 target_if_err("rx_ops is NULL"); 142 return NULL; 143 } 144 145 return &rx_ops->reg_rx_ops; 146 } 147 148 struct wlan_lmac_if_reg_tx_ops * 149 target_if_regulatory_get_tx_ops(struct wlan_objmgr_psoc *psoc) 150 { 151 struct wlan_lmac_if_tx_ops *tx_ops; 152 153 tx_ops = wlan_psoc_get_lmac_if_txops(psoc); 154 if (!tx_ops) { 155 target_if_err("tx_ops is NULL"); 156 return NULL; 157 } 158 159 return &tx_ops->reg_ops; 160 } 161 162 QDF_STATUS target_if_reg_set_offloaded_info(struct wlan_objmgr_psoc *psoc) 163 { 164 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 165 166 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 167 if (!reg_rx_ops) { 168 target_if_err("reg_rx_ops is NULL"); 169 return QDF_STATUS_E_FAILURE; 170 } 171 172 if (reg_rx_ops->reg_set_regdb_offloaded) 173 reg_rx_ops->reg_set_regdb_offloaded( 174 psoc, 175 tgt_if_regulatory_is_regdb_offloaded(psoc)); 176 177 if (reg_rx_ops->reg_set_11d_offloaded) 178 reg_rx_ops->reg_set_11d_offloaded( 179 psoc, tgt_if_regulatory_is_11d_offloaded(psoc)); 180 181 return QDF_STATUS_SUCCESS; 182 } 183 184 QDF_STATUS target_if_reg_set_6ghz_info(struct wlan_objmgr_psoc *psoc) 185 { 186 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 187 188 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 189 if (!reg_rx_ops) { 190 target_if_err("reg_rx_ops is NULL"); 191 return QDF_STATUS_E_FAILURE; 192 } 193 194 if (reg_rx_ops->reg_set_6ghz_supported) 195 reg_rx_ops->reg_set_6ghz_supported( 196 psoc, 197 tgt_if_regulatory_is_6ghz_supported(psoc)); 198 199 return QDF_STATUS_SUCCESS; 200 } 201 202 QDF_STATUS target_if_reg_set_5dot9_ghz_info(struct wlan_objmgr_psoc *psoc) 203 { 204 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 205 206 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 207 if (!reg_rx_ops) { 208 target_if_err("reg_rx_ops is NULL"); 209 return QDF_STATUS_E_FAILURE; 210 } 211 212 if (reg_rx_ops->reg_set_5dot9_ghz_supported) 213 reg_rx_ops->reg_set_5dot9_ghz_supported( 214 psoc, 215 tgt_if_regulatory_is_5dot9_ghz_supported(psoc)); 216 217 return QDF_STATUS_SUCCESS; 218 } 219 220 bool 221 target_if_reg_is_reg_cc_ext_event_host_supported(struct wlan_objmgr_psoc *psoc) 222 { 223 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 224 bool reg_ext_cc_supp = false; 225 226 reg_tx_ops = target_if_regulatory_get_tx_ops(psoc); 227 if (!reg_tx_ops) { 228 target_if_err("reg_tx_ops is NULL"); 229 return reg_ext_cc_supp; 230 } 231 232 if (reg_tx_ops->register_master_ext_handler) 233 reg_ext_cc_supp = true; 234 235 return reg_ext_cc_supp; 236 } 237 238 /** 239 * tgt_reg_chan_list_update_handler() - Channel list update handler 240 * @handle: scn handle 241 * @event_buf: pointer to event buffer 242 * @len: buffer length 243 * 244 * Return: 0 on success 245 */ 246 static int tgt_reg_chan_list_update_handler(ol_scn_t handle, uint8_t *event_buf, 247 uint32_t len) 248 { 249 struct wlan_objmgr_psoc *psoc; 250 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 251 struct cur_regulatory_info *reg_info; 252 QDF_STATUS status; 253 struct wmi_unified *wmi_handle; 254 int ret_val = 0; 255 256 TARGET_IF_ENTER(); 257 258 psoc = target_if_get_psoc_from_scn_hdl(handle); 259 if (!psoc) { 260 target_if_err("psoc ptr is NULL"); 261 return -EINVAL; 262 } 263 264 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 265 if (!reg_rx_ops) { 266 target_if_err("reg_rx_ops is NULL"); 267 return -EINVAL; 268 } 269 270 if (!reg_rx_ops->master_list_handler) { 271 target_if_err("master_list_handler is NULL"); 272 return -EINVAL; 273 } 274 275 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 276 if (!wmi_handle) { 277 target_if_err("invalid wmi handle"); 278 return -EINVAL; 279 } 280 281 reg_info = qdf_mem_malloc(sizeof(*reg_info)); 282 if (!reg_info) 283 return -ENOMEM; 284 285 if (wmi_extract_reg_chan_list_update_event(wmi_handle, 286 event_buf, reg_info, len) 287 != QDF_STATUS_SUCCESS) { 288 target_if_err("Extraction of channel list event failed"); 289 ret_val = -EFAULT; 290 goto clean; 291 } 292 293 if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 294 target_if_err_rl("phy_id %d is out of bounds", 295 reg_info->phy_id); 296 ret_val = -EFAULT; 297 goto clean; 298 } 299 300 reg_info->psoc = psoc; 301 302 status = reg_rx_ops->master_list_handler(reg_info); 303 if (status != QDF_STATUS_SUCCESS) { 304 target_if_err("Failed to process master channel list handler"); 305 ret_val = -EFAULT; 306 } 307 308 clean: 309 qdf_mem_free(reg_info->reg_rules_2g_ptr); 310 qdf_mem_free(reg_info->reg_rules_5g_ptr); 311 qdf_mem_free(reg_info); 312 313 TARGET_IF_EXIT(); 314 315 return ret_val; 316 } 317 318 /** 319 * tgt_if_regulatory_register_master_list_handler() - Register master channel 320 * list 321 * @psoc: Pointer to psoc 322 * @arg: Pointer to argument list 323 * 324 * Return: QDF_STATUS 325 */ 326 static QDF_STATUS tgt_if_regulatory_register_master_list_handler( 327 struct wlan_objmgr_psoc *psoc, void *arg) 328 { 329 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 330 331 if (!wmi_handle) 332 return QDF_STATUS_E_FAILURE; 333 334 return wmi_unified_register_event_handler( 335 wmi_handle, wmi_reg_chan_list_cc_event_id, 336 tgt_reg_chan_list_update_handler, WMI_RX_WORK_CTX); 337 } 338 339 /** 340 * tgt_if_regulatory_unregister_master_list_handler() - Unregister master 341 * channel list 342 * @psoc: Pointer to psoc 343 * @arg: Pointer to argument list 344 * 345 * Return: QDF_STATUS 346 */ 347 static QDF_STATUS tgt_if_regulatory_unregister_master_list_handler( 348 struct wlan_objmgr_psoc *psoc, void *arg) 349 { 350 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 351 352 if (!wmi_handle) 353 return QDF_STATUS_E_FAILURE; 354 355 return wmi_unified_unregister_event_handler( 356 wmi_handle, wmi_reg_chan_list_cc_event_id); 357 } 358 359 #ifdef CONFIG_BAND_6GHZ 360 #ifdef CONFIG_REG_CLIENT 361 /** 362 * tgt_mem_free_fcc_rules() - Free regulatory fcc rules 363 * @reg_info: Pointer to regulatory info 364 * 365 */ 366 static void tgt_reg_mem_free_fcc_rules(struct cur_regulatory_info *reg_info) 367 { 368 qdf_mem_free(reg_info->fcc_rules_ptr); 369 } 370 #else 371 static void tgt_reg_mem_free_fcc_rules(struct cur_regulatory_info *reg_info) 372 { 373 } 374 #endif 375 376 /** 377 * tgt_reg_chan_list_ext_update_handler() - Extended channel list update handler 378 * @handle: scn handle 379 * @event_buf: pointer to event buffer 380 * @len: buffer length 381 * 382 * Return: 0 on success 383 */ 384 static int tgt_reg_chan_list_ext_update_handler(ol_scn_t handle, 385 uint8_t *event_buf, 386 uint32_t len) 387 { 388 struct wlan_objmgr_psoc *psoc; 389 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 390 struct cur_regulatory_info *reg_info; 391 QDF_STATUS status; 392 struct wmi_unified *wmi_handle; 393 int ret_val = 0; 394 uint32_t i; 395 396 TARGET_IF_ENTER(); 397 398 psoc = target_if_get_psoc_from_scn_hdl(handle); 399 if (!psoc) { 400 target_if_err("psoc ptr is NULL"); 401 return -EINVAL; 402 } 403 404 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 405 if (!reg_rx_ops) { 406 target_if_err("reg_rx_ops is NULL"); 407 return -EINVAL; 408 } 409 410 if (!reg_rx_ops->master_list_ext_handler) { 411 target_if_err("master_list_ext_handler is NULL"); 412 return -EINVAL; 413 } 414 415 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 416 if (!wmi_handle) { 417 target_if_err("invalid wmi handle"); 418 return -EINVAL; 419 } 420 421 reg_info = qdf_mem_malloc(sizeof(*reg_info)); 422 if (!reg_info) 423 return -ENOMEM; 424 425 status = wmi_extract_reg_chan_list_ext_update_event(wmi_handle, 426 event_buf, 427 reg_info, len); 428 if (!QDF_IS_STATUS_SUCCESS(status)) { 429 target_if_err("Extraction of ext channel list event failed"); 430 ret_val = -EFAULT; 431 goto clean; 432 } 433 434 if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 435 target_if_err_rl("phy_id %d is out of bounds", 436 reg_info->phy_id); 437 ret_val = -EFAULT; 438 goto clean; 439 } 440 441 reg_info->psoc = psoc; 442 443 status = reg_rx_ops->master_list_ext_handler(reg_info); 444 if (!QDF_IS_STATUS_SUCCESS(status)) { 445 target_if_err("Failed to process master ext channel list handler"); 446 ret_val = -EFAULT; 447 } 448 449 clean: 450 qdf_mem_free(reg_info->reg_rules_2g_ptr); 451 qdf_mem_free(reg_info->reg_rules_5g_ptr); 452 tgt_reg_mem_free_fcc_rules(reg_info); 453 454 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 455 qdf_mem_free(reg_info->reg_rules_6g_ap_ptr[i]); 456 qdf_mem_free(reg_info-> 457 reg_rules_6g_client_ptr[i][REG_DEFAULT_CLIENT]); 458 qdf_mem_free(reg_info-> 459 reg_rules_6g_client_ptr[i][REG_SUBORDINATE_CLIENT]); 460 } 461 462 qdf_mem_free(reg_info); 463 464 TARGET_IF_EXIT(); 465 466 return ret_val; 467 } 468 469 /** 470 * tgt_if_regulatory_register_master_list_ext_handler() - Register extended 471 * master channel list event handler 472 * @psoc: Pointer to psoc 473 * @arg: Pointer to argument list 474 * 475 * Return: QDF_STATUS 476 */ 477 static QDF_STATUS tgt_if_regulatory_register_master_list_ext_handler( 478 struct wlan_objmgr_psoc *psoc, void *arg) 479 { 480 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 481 482 if (!wmi_handle) 483 return QDF_STATUS_E_FAILURE; 484 485 return wmi_unified_register_event_handler( 486 wmi_handle, wmi_reg_chan_list_cc_ext_event_id, 487 tgt_reg_chan_list_ext_update_handler, WMI_RX_WORK_CTX); 488 } 489 490 /** 491 * tgt_if_regulatory_unregister_master_list_ext_handler() - Unregister extended 492 * master channel list event handler 493 * @psoc: Pointer to psoc 494 * @arg: Pointer to argument list 495 * 496 * Return: QDF_STATUS 497 */ 498 static QDF_STATUS tgt_if_regulatory_unregister_master_list_ext_handler( 499 struct wlan_objmgr_psoc *psoc, void *arg) 500 { 501 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 502 503 if (!wmi_handle) 504 return QDF_STATUS_E_FAILURE; 505 506 return wmi_unified_unregister_event_handler( 507 wmi_handle, wmi_reg_chan_list_cc_ext_event_id); 508 } 509 510 #ifdef CONFIG_AFC_SUPPORT 511 /** 512 * tgt_afc_event_handler() - Handler for AFC Event 513 * @handle: scn handle 514 * @event_buf: pointer to event buffer 515 * @len: buffer length 516 * 517 * Return: 0 on success 518 */ 519 static int 520 tgt_afc_event_handler(ol_scn_t handle, uint8_t *event_buf, uint32_t len) 521 { 522 struct wlan_objmgr_psoc *psoc; 523 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 524 struct afc_regulatory_info *afc_info; 525 QDF_STATUS status; 526 struct wmi_unified *wmi_handle; 527 int ret_val = 0; 528 529 TARGET_IF_ENTER(); 530 531 psoc = target_if_get_psoc_from_scn_hdl(handle); 532 if (!psoc) { 533 target_if_err("psoc ptr is NULL"); 534 return -EINVAL; 535 } 536 537 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 538 if (!reg_rx_ops) { 539 target_if_err("reg_rx_ops is NULL"); 540 return -EINVAL; 541 } 542 543 if (!reg_rx_ops->afc_event_handler) { 544 target_if_err("afc_event_handler is NULL"); 545 return -EINVAL; 546 } 547 548 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 549 if (!wmi_handle) { 550 target_if_err("invalid wmi handle"); 551 return -EINVAL; 552 } 553 554 afc_info = qdf_mem_malloc(sizeof(*afc_info)); 555 if (!afc_info) 556 return -ENOMEM; 557 558 status = wmi_extract_afc_event(wmi_handle, event_buf, afc_info, len); 559 if (!QDF_IS_STATUS_SUCCESS(status)) { 560 target_if_err("Extraction of AFC event failed"); 561 ret_val = -EFAULT; 562 goto clean; 563 } 564 565 if (afc_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 566 target_if_err_rl("phy_id %d is out of bounds", 567 afc_info->phy_id); 568 ret_val = -EFAULT; 569 goto clean; 570 } 571 572 afc_info->psoc = psoc; 573 574 status = reg_rx_ops->afc_event_handler(afc_info); 575 if (!QDF_IS_STATUS_SUCCESS(status)) { 576 target_if_err("Failed to process AFC event handler"); 577 ret_val = -EFAULT; 578 goto clean; 579 } 580 581 clean: 582 qdf_mem_free(afc_info); 583 TARGET_IF_EXIT(); 584 585 return ret_val; 586 } 587 588 /** 589 * tgt_if_regulatory_register_afc_event_handler() - Register AFC event 590 * handler 591 * @psoc: Pointer to psoc 592 * @arg: Pointer to argument list 593 * 594 * Return: QDF_STATUS 595 */ 596 static QDF_STATUS tgt_if_regulatory_register_afc_event_handler( 597 struct wlan_objmgr_psoc *psoc, void *arg) 598 { 599 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 600 601 if (!wmi_handle) 602 return QDF_STATUS_E_FAILURE; 603 604 return wmi_unified_register_event_handler( 605 wmi_handle, wmi_afc_event_id, 606 tgt_afc_event_handler, WMI_RX_WORK_CTX); 607 } 608 609 /** 610 * tgt_if_regulatory_unregister_afc_event_handler() - Unregister AFC event 611 * handler 612 * @psoc: Pointer to psoc 613 * @arg: Pointer to argument list 614 * 615 * Return: QDF_STATUS 616 */ 617 static QDF_STATUS 618 tgt_if_regulatory_unregister_afc_event_handler(struct wlan_objmgr_psoc *psoc, 619 void *arg) 620 { 621 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 622 623 if (!wmi_handle) 624 return QDF_STATUS_E_FAILURE; 625 626 return wmi_unified_unregister_event_handler( 627 wmi_handle, wmi_afc_event_id); 628 } 629 #endif 630 #endif 631 632 /** 633 * tgt_if_regulatory_set_country_code() - Set country code 634 * @psoc: Pointer to psoc 635 * @arg: Pointer to argument list 636 * 637 * Return: QDF_STATUS 638 */ 639 static QDF_STATUS tgt_if_regulatory_set_country_code( 640 struct wlan_objmgr_psoc *psoc, void *arg) 641 { 642 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 643 644 if (!wmi_handle) 645 return QDF_STATUS_E_FAILURE; 646 647 return wmi_unified_set_country_cmd_send(wmi_handle, arg); 648 } 649 650 /** 651 * tgt_if_regulatory_set_user_country_code() - Set user country code 652 * @psoc: Pointer to psoc 653 * @pdev_id: Pdev id 654 * @rd: Pointer to regdomain structure 655 * 656 * Return: QDF_STATUS 657 */ 658 static QDF_STATUS tgt_if_regulatory_set_user_country_code( 659 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, struct cc_regdmn_s *rd) 660 { 661 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 662 663 if (!wmi_handle) 664 return QDF_STATUS_E_FAILURE; 665 666 if (wmi_unified_set_user_country_code_cmd_send( 667 wmi_handle, pdev_id, rd) != QDF_STATUS_SUCCESS 668 ) { 669 target_if_err("Set user country code failed"); 670 return QDF_STATUS_E_FAILURE; 671 } 672 673 return QDF_STATUS_SUCCESS; 674 } 675 676 QDF_STATUS tgt_if_regulatory_modify_freq_range(struct wlan_objmgr_psoc *psoc) 677 { 678 struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; 679 680 reg_cap = ucfg_reg_get_hal_reg_cap(psoc); 681 if (!reg_cap) { 682 target_if_err("reg cap is NULL"); 683 return QDF_STATUS_E_FAILURE; 684 } 685 686 if (!(reg_cap->wireless_modes & HOST_REGDMN_MODE_11A)) { 687 reg_cap->low_5ghz_chan = 0; 688 reg_cap->high_5ghz_chan = 0; 689 } 690 691 if (!(reg_cap->wireless_modes & 692 (HOST_REGDMN_MODE_11B | HOST_REGDMN_MODE_PUREG))) { 693 reg_cap->low_2ghz_chan = 0; 694 reg_cap->high_2ghz_chan = 0; 695 } 696 697 target_if_debug("phy_id = %d - low_2ghz_chan = %d high_2ghz_chan = %d low_5ghz_chan = %d high_5ghz_chan = %d", 698 reg_cap->phy_id, 699 reg_cap->low_2ghz_chan, 700 reg_cap->high_2ghz_chan, 701 reg_cap->low_5ghz_chan, 702 reg_cap->high_5ghz_chan); 703 704 return QDF_STATUS_SUCCESS; 705 } 706 707 #ifdef CONFIG_REG_CLIENT 708 /** 709 * tgt_if_regulatory_send_ctl_info() - Send CTL info to firmware 710 * @psoc: Pointer to psoc 711 * @params: Pointer to reg control params 712 * 713 * Return: QDF_STATUS 714 */ 715 static QDF_STATUS 716 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 717 struct reg_ctl_params *params) 718 { 719 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 720 721 if (!wmi_handle) 722 return QDF_STATUS_E_FAILURE; 723 724 return wmi_unified_send_regdomain_info_to_fw_cmd(wmi_handle, 725 params->regd, 726 params->regd_2g, 727 params->regd_5g, 728 params->ctl_2g, 729 params->ctl_5g); 730 } 731 #else 732 static QDF_STATUS 733 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 734 struct reg_ctl_params *params) 735 { 736 return QDF_STATUS_SUCCESS; 737 } 738 #endif 739 740 /** 741 * tgt_if_regulatory_get_phy_id_from_pdev_id() - Get phy_id from pdev_id 742 * @psoc: Pointer to psoc 743 * @pdev_id: Pdev id 744 * @phy_id: phy_id 745 * 746 * Return: QDF_STATUS 747 */ 748 static QDF_STATUS tgt_if_regulatory_get_phy_id_from_pdev_id( 749 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *phy_id) 750 { 751 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 752 uint8_t ret; 753 754 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) { 755 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 756 return QDF_STATUS_E_FAILURE; 757 } 758 759 /* By default pdev_id and phy_id have one to one mapping */ 760 *phy_id = pdev_id; 761 762 if (!(tgt_if_handle && 763 tgt_if_handle->info.is_pdevid_to_phyid_map)) 764 return QDF_STATUS_SUCCESS; 765 766 ret = tgt_if_handle->info.pdev_id_to_phy_id_map[pdev_id]; 767 768 if (ret < PSOC_MAX_PHY_REG_CAP) { 769 *phy_id = ret; 770 } else { 771 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 772 return QDF_STATUS_E_FAILURE; 773 } 774 775 return QDF_STATUS_SUCCESS; 776 } 777 778 /** 779 * tgt_if_regulatory_get_pdev_id_from_phy_id() - Get pdev_id for phy_id 780 * @psoc: Pointer to psoc 781 * @phy_id: Phy id 782 * @pdev_id: Pdev id 783 * 784 * Return: QDF_STATUS 785 */ 786 static QDF_STATUS tgt_if_regulatory_get_pdev_id_from_phy_id( 787 struct wlan_objmgr_psoc *psoc, uint8_t phy_id, uint8_t *pdev_id) 788 { 789 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 790 uint8_t i; 791 792 if (phy_id >= PSOC_MAX_PHY_REG_CAP) { 793 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 794 return QDF_STATUS_E_FAILURE; 795 } 796 797 /* By default pdev_id and phy_id have one to one mapping */ 798 *pdev_id = phy_id; 799 800 if (!(tgt_if_handle && 801 tgt_if_handle->info.is_pdevid_to_phyid_map)) 802 return QDF_STATUS_SUCCESS; 803 804 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 805 if (tgt_if_handle->info.pdev_id_to_phy_id_map[i] == phy_id) 806 break; 807 } 808 809 if (i < WLAN_UMAC_MAX_PDEVS) { 810 *pdev_id = i; 811 } else { 812 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 813 return QDF_STATUS_E_FAILURE; 814 } 815 816 return QDF_STATUS_SUCCESS; 817 } 818 819 #ifdef CONFIG_BAND_6GHZ 820 static void target_if_register_master_ext_handler( 821 struct wlan_lmac_if_reg_tx_ops *reg_ops) 822 { 823 reg_ops->register_master_ext_handler = 824 tgt_if_regulatory_register_master_list_ext_handler; 825 826 reg_ops->unregister_master_ext_handler = 827 tgt_if_regulatory_unregister_master_list_ext_handler; 828 } 829 830 #ifdef CONFIG_AFC_SUPPORT 831 static void target_if_register_afc_event_handler( 832 struct wlan_lmac_if_reg_tx_ops *reg_ops) 833 { 834 reg_ops->register_afc_event_handler = 835 tgt_if_regulatory_register_afc_event_handler; 836 837 reg_ops->unregister_afc_event_handler = 838 tgt_if_regulatory_unregister_afc_event_handler; 839 } 840 841 static void target_if_register_acs_trigger_for_afc 842 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 843 { 844 reg_ops->trigger_acs_for_afc = NULL; 845 } 846 #else 847 static void target_if_register_afc_event_handler( 848 struct wlan_lmac_if_reg_tx_ops *reg_ops) 849 { 850 } 851 852 static void target_if_register_acs_trigger_for_afc 853 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 854 { 855 } 856 #endif 857 #else 858 static inline void 859 target_if_register_master_ext_handler(struct wlan_lmac_if_reg_tx_ops *reg_ops) 860 { 861 } 862 863 static void target_if_register_afc_event_handler( 864 struct wlan_lmac_if_reg_tx_ops *reg_ops) 865 { 866 } 867 868 static void target_if_register_acs_trigger_for_afc 869 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 870 { 871 } 872 #endif 873 874 static QDF_STATUS 875 tgt_if_regulatory_set_tpc_power(struct wlan_objmgr_psoc *psoc, 876 uint8_t vdev_id, 877 struct reg_tpc_power_info *param) 878 { 879 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 880 881 if (!wmi_handle) 882 return QDF_STATUS_E_FAILURE; 883 884 return wmi_unified_send_set_tpc_power_cmd(wmi_handle, vdev_id, param); 885 } 886 887 #ifdef CONFIG_AFC_SUPPORT 888 /** 889 * tgt_if_regulatory_send_afc_cmd() - Send AFC command to the FW 890 * 891 * @psoc: Pointer to psoc 892 * @pdev_id: Pdev id 893 * @param: Pointer to hold AFC indication. 894 * 895 * Return: QDF_STATUS_SUCCESS if WMI_AFC_CMD is sent, else QDF_STATUS_E_FAILURE 896 */ 897 static QDF_STATUS 898 tgt_if_regulatory_send_afc_cmd(struct wlan_objmgr_psoc *psoc, 899 uint8_t pdev_id, 900 struct reg_afc_resp_rx_ind_info *param) 901 { 902 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 903 904 if (!wmi_handle) 905 return QDF_STATUS_E_FAILURE; 906 907 return wmi_unified_send_afc_cmd(wmi_handle, pdev_id, param); 908 } 909 910 static void 911 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 912 { 913 reg_ops->send_afc_ind = tgt_if_regulatory_send_afc_cmd; 914 } 915 #else 916 static void 917 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 918 { 919 } 920 #endif 921 922 /** 923 * tgt_if_regulatory_is_ext_tpc_supported() - Check if FW supports new 924 * WMI command for TPC power 925 * 926 * @psoc: Pointer to psoc 927 * 928 * Return: true if FW supports new WMI command for TPC, else false 929 */ 930 static bool 931 tgt_if_regulatory_is_ext_tpc_supported(struct wlan_objmgr_psoc *psoc) 932 { 933 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 934 935 if (!wmi_handle) 936 return false; 937 938 return wmi_service_enabled(wmi_handle, 939 wmi_service_ext_tpc_reg_support); 940 } 941 942 QDF_STATUS target_if_regulatory_set_ext_tpc(struct wlan_objmgr_psoc *psoc) 943 { 944 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 945 946 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 947 if (!reg_rx_ops) { 948 target_if_err("reg_rx_ops is NULL"); 949 return QDF_STATUS_E_FAILURE; 950 } 951 952 if (reg_rx_ops->reg_set_ext_tpc_supported) 953 reg_rx_ops->reg_set_ext_tpc_supported( 954 psoc, 955 tgt_if_regulatory_is_ext_tpc_supported(psoc)); 956 957 return QDF_STATUS_SUCCESS; 958 } 959 960 #if defined(CONFIG_BAND_6GHZ) 961 /** 962 * tgt_if_regulatory_is_lower_6g_edge_ch_supp() - Check if lower 6ghz 963 * edge channel (5935MHz) is supported 964 * @psoc: Pointer to psoc 965 * 966 * Return: true if channel is supported, else false 967 */ 968 static bool 969 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 970 { 971 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 972 973 if (!wmi_handle) 974 return false; 975 976 return wmi_service_enabled(wmi_handle, 977 wmi_service_lower_6g_edge_ch_supp); 978 } 979 980 /** 981 * tgt_if_regulatory_is_upper_6g_edge_ch_disabled() - Check if upper 982 * 6ghz edge channel (7115MHz) is disabled 983 * @psoc: Pointer to psoc 984 * 985 * Return: true if channel is disabled, else false 986 */ 987 static bool 988 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 989 { 990 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 991 992 if (!wmi_handle) 993 return false; 994 995 return wmi_service_enabled(wmi_handle, 996 wmi_service_disable_upper_6g_edge_ch_supp); 997 } 998 999 QDF_STATUS 1000 target_if_reg_set_lower_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 1001 { 1002 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1003 1004 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1005 if (!reg_rx_ops) { 1006 target_if_err("reg_rx_ops is NULL"); 1007 return QDF_STATUS_E_FAILURE; 1008 } 1009 1010 if (reg_rx_ops->reg_set_lower_6g_edge_ch_supp) 1011 reg_rx_ops->reg_set_lower_6g_edge_ch_supp( 1012 psoc, 1013 tgt_if_regulatory_is_lower_6g_edge_ch_supp(psoc)); 1014 1015 return QDF_STATUS_SUCCESS; 1016 } 1017 1018 QDF_STATUS 1019 target_if_reg_set_disable_upper_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 1020 { 1021 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1022 1023 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1024 if (!reg_rx_ops) { 1025 target_if_err("reg_rx_ops is NULL"); 1026 return QDF_STATUS_E_FAILURE; 1027 } 1028 1029 if (reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp) 1030 reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp( 1031 psoc, 1032 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(psoc)); 1033 1034 return QDF_STATUS_SUCCESS; 1035 } 1036 #else 1037 static inline bool 1038 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 1039 { 1040 return false; 1041 } 1042 1043 static inline bool 1044 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 1045 { 1046 return false; 1047 } 1048 #endif 1049 1050 #if defined(CONFIG_AFC_SUPPORT) 1051 QDF_STATUS 1052 target_if_reg_set_afc_dev_type(struct wlan_objmgr_psoc *psoc, 1053 struct target_psoc_info *tgt_hdl) 1054 { 1055 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1056 struct tgt_info *info; 1057 1058 if (!tgt_hdl) { 1059 target_if_err("target_psoc_info is null"); 1060 return QDF_STATUS_E_FAILURE; 1061 } 1062 1063 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1064 if (!reg_rx_ops) { 1065 target_if_err("reg_rx_ops is NULL"); 1066 return QDF_STATUS_E_FAILURE; 1067 } 1068 1069 info = (&tgt_hdl->info); 1070 1071 if (reg_rx_ops->reg_set_afc_dev_type) 1072 reg_rx_ops->reg_set_afc_dev_type( 1073 psoc, 1074 info->service_ext2_param.afc_dev_type); 1075 1076 return QDF_STATUS_SUCCESS; 1077 } 1078 1079 QDF_STATUS 1080 target_if_reg_get_afc_dev_type(struct wlan_objmgr_psoc *psoc, 1081 enum reg_afc_dev_deploy_type *reg_afc_dev_type) 1082 { 1083 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1084 1085 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1086 if (!reg_rx_ops) { 1087 target_if_err("reg_rx_ops is NULL"); 1088 return QDF_STATUS_E_FAILURE; 1089 } 1090 1091 if (reg_rx_ops->reg_get_afc_dev_type) 1092 reg_rx_ops->reg_get_afc_dev_type( 1093 psoc, 1094 reg_afc_dev_type); 1095 1096 return QDF_STATUS_SUCCESS; 1097 } 1098 #endif 1099 1100 /** 1101 * tgt_if_reg_is_chip_11be_cap() - Finds out if the hardware is capable 1102 * of 11BE. The capability bit is read from mac_phy_cap populated by the 1103 * FW per pdev. 1104 * @psoc: Pointer to psoc 1105 * @phy_id: phy_id 1106 * 1107 * Return: True if chip is 11BE capable, false otherwise. 1108 */ 1109 #ifdef WLAN_FEATURE_11BE 1110 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc, 1111 uint16_t phy_id) 1112 { 1113 struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap; 1114 struct target_psoc_info *tgt_hdl; 1115 uint8_t pdev_id; 1116 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 1117 1118 reg_tx_ops = target_if_regulatory_get_tx_ops(psoc); 1119 1120 if (!reg_tx_ops) { 1121 target_if_err("reg_tx_ops is NULL"); 1122 return false; 1123 } 1124 1125 if (reg_tx_ops->get_pdev_id_from_phy_id) 1126 reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 1127 else 1128 pdev_id = phy_id; 1129 1130 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); 1131 if (tgt_hdl) { 1132 mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl); 1133 if (!mac_phy_cap_arr) 1134 return false; 1135 mac_phy_cap = &mac_phy_cap_arr[pdev_id]; 1136 if (mac_phy_cap && mac_phy_cap->supports_11be) 1137 return true; 1138 } 1139 return false; 1140 } 1141 #else 1142 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc, 1143 uint16_t phy_id) 1144 { 1145 return false; 1146 } 1147 #endif 1148 1149 QDF_STATUS target_if_register_regulatory_tx_ops( 1150 struct wlan_lmac_if_tx_ops *tx_ops) 1151 { 1152 struct wlan_lmac_if_reg_tx_ops *reg_ops = &tx_ops->reg_ops; 1153 1154 reg_ops->register_master_handler = 1155 tgt_if_regulatory_register_master_list_handler; 1156 1157 reg_ops->unregister_master_handler = 1158 tgt_if_regulatory_unregister_master_list_handler; 1159 1160 target_if_register_master_ext_handler(reg_ops); 1161 1162 target_if_register_afc_event_handler(reg_ops); 1163 1164 reg_ops->set_country_code = tgt_if_regulatory_set_country_code; 1165 1166 reg_ops->fill_umac_legacy_chanlist = NULL; 1167 1168 reg_ops->set_country_failed = NULL; 1169 1170 target_if_register_acs_trigger_for_afc(reg_ops); 1171 1172 reg_ops->register_11d_new_cc_handler = 1173 tgt_if_regulatory_register_11d_new_cc_handler; 1174 1175 reg_ops->unregister_11d_new_cc_handler = 1176 tgt_if_regulatory_unregister_11d_new_cc_handler; 1177 1178 reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan; 1179 1180 reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan; 1181 1182 reg_ops->is_there_serv_ready_extn = 1183 tgt_if_regulatory_is_there_serv_ready_extn; 1184 1185 reg_ops->set_user_country_code = 1186 tgt_if_regulatory_set_user_country_code; 1187 1188 reg_ops->register_ch_avoid_event_handler = 1189 tgt_if_regulatory_register_ch_avoid_event_handler; 1190 1191 reg_ops->unregister_ch_avoid_event_handler = 1192 tgt_if_regulatory_unregister_ch_avoid_event_handler; 1193 1194 reg_ops->send_ctl_info = tgt_if_regulatory_send_ctl_info; 1195 1196 reg_ops->get_phy_id_from_pdev_id = 1197 tgt_if_regulatory_get_phy_id_from_pdev_id; 1198 1199 reg_ops->get_pdev_id_from_phy_id = 1200 tgt_if_regulatory_get_pdev_id_from_phy_id; 1201 1202 reg_ops->set_tpc_power = tgt_if_regulatory_set_tpc_power; 1203 1204 reg_ops->get_opclass_tbl_idx = NULL; 1205 1206 tgt_if_register_afc_callback(reg_ops); 1207 1208 reg_ops->is_chip_11be = tgt_if_reg_is_chip_11be_cap; 1209 1210 return QDF_STATUS_SUCCESS; 1211 } 1212