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 /** 361 * tgt_reg_chan_list_ext_update_handler() - Extended channel list update handler 362 * @handle: scn handle 363 * @event_buf: pointer to event buffer 364 * @len: buffer length 365 * 366 * Return: 0 on success 367 */ 368 static int tgt_reg_chan_list_ext_update_handler(ol_scn_t handle, 369 uint8_t *event_buf, 370 uint32_t len) 371 { 372 struct wlan_objmgr_psoc *psoc; 373 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 374 struct cur_regulatory_info *reg_info; 375 QDF_STATUS status; 376 struct wmi_unified *wmi_handle; 377 int ret_val = 0; 378 uint32_t i; 379 380 TARGET_IF_ENTER(); 381 382 psoc = target_if_get_psoc_from_scn_hdl(handle); 383 if (!psoc) { 384 target_if_err("psoc ptr is NULL"); 385 return -EINVAL; 386 } 387 388 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 389 if (!reg_rx_ops) { 390 target_if_err("reg_rx_ops is NULL"); 391 return -EINVAL; 392 } 393 394 if (!reg_rx_ops->master_list_ext_handler) { 395 target_if_err("master_list_ext_handler is NULL"); 396 return -EINVAL; 397 } 398 399 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 400 if (!wmi_handle) { 401 target_if_err("invalid wmi handle"); 402 return -EINVAL; 403 } 404 405 reg_info = qdf_mem_malloc(sizeof(*reg_info)); 406 if (!reg_info) 407 return -ENOMEM; 408 409 status = wmi_extract_reg_chan_list_ext_update_event(wmi_handle, 410 event_buf, 411 reg_info, len); 412 if (!QDF_IS_STATUS_SUCCESS(status)) { 413 target_if_err("Extraction of ext channel list event failed"); 414 ret_val = -EFAULT; 415 goto clean; 416 } 417 418 if (reg_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 419 target_if_err_rl("phy_id %d is out of bounds", 420 reg_info->phy_id); 421 ret_val = -EFAULT; 422 goto clean; 423 } 424 425 reg_info->psoc = psoc; 426 427 status = reg_rx_ops->master_list_ext_handler(reg_info); 428 if (!QDF_IS_STATUS_SUCCESS(status)) { 429 target_if_err("Failed to process master ext channel list handler"); 430 ret_val = -EFAULT; 431 } 432 433 clean: 434 qdf_mem_free(reg_info->reg_rules_2g_ptr); 435 qdf_mem_free(reg_info->reg_rules_5g_ptr); 436 437 for (i = 0; i < REG_CURRENT_MAX_AP_TYPE; i++) { 438 qdf_mem_free(reg_info->reg_rules_6g_ap_ptr[i]); 439 qdf_mem_free(reg_info-> 440 reg_rules_6g_client_ptr[i][REG_DEFAULT_CLIENT]); 441 qdf_mem_free(reg_info-> 442 reg_rules_6g_client_ptr[i][REG_SUBORDINATE_CLIENT]); 443 } 444 445 qdf_mem_free(reg_info); 446 447 TARGET_IF_EXIT(); 448 449 return ret_val; 450 } 451 452 /** 453 * tgt_if_regulatory_register_master_list_ext_handler() - Register extended 454 * master channel list event handler 455 * @psoc: Pointer to psoc 456 * @arg: Pointer to argument list 457 * 458 * Return: QDF_STATUS 459 */ 460 static QDF_STATUS tgt_if_regulatory_register_master_list_ext_handler( 461 struct wlan_objmgr_psoc *psoc, void *arg) 462 { 463 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 464 465 if (!wmi_handle) 466 return QDF_STATUS_E_FAILURE; 467 468 return wmi_unified_register_event_handler( 469 wmi_handle, wmi_reg_chan_list_cc_ext_event_id, 470 tgt_reg_chan_list_ext_update_handler, WMI_RX_WORK_CTX); 471 } 472 473 /** 474 * tgt_if_regulatory_unregister_master_list_ext_handler() - Unregister extended 475 * master channel list event handler 476 * @psoc: Pointer to psoc 477 * @arg: Pointer to argument list 478 * 479 * Return: QDF_STATUS 480 */ 481 static QDF_STATUS tgt_if_regulatory_unregister_master_list_ext_handler( 482 struct wlan_objmgr_psoc *psoc, void *arg) 483 { 484 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 485 486 if (!wmi_handle) 487 return QDF_STATUS_E_FAILURE; 488 489 return wmi_unified_unregister_event_handler( 490 wmi_handle, wmi_reg_chan_list_cc_ext_event_id); 491 } 492 493 #ifdef CONFIG_AFC_SUPPORT 494 /** 495 * tgt_afc_event_handler() - Handler for AFC Event 496 * @handle: scn handle 497 * @event_buf: pointer to event buffer 498 * @len: buffer length 499 * 500 * Return: 0 on success 501 */ 502 static int 503 tgt_afc_event_handler(ol_scn_t handle, uint8_t *event_buf, uint32_t len) 504 { 505 struct wlan_objmgr_psoc *psoc; 506 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 507 struct afc_regulatory_info *afc_info; 508 QDF_STATUS status; 509 struct wmi_unified *wmi_handle; 510 int ret_val = 0; 511 512 TARGET_IF_ENTER(); 513 514 psoc = target_if_get_psoc_from_scn_hdl(handle); 515 if (!psoc) { 516 target_if_err("psoc ptr is NULL"); 517 return -EINVAL; 518 } 519 520 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 521 if (!reg_rx_ops) { 522 target_if_err("reg_rx_ops is NULL"); 523 return -EINVAL; 524 } 525 526 if (!reg_rx_ops->afc_event_handler) { 527 target_if_err("afc_event_handler is NULL"); 528 return -EINVAL; 529 } 530 531 wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 532 if (!wmi_handle) { 533 target_if_err("invalid wmi handle"); 534 return -EINVAL; 535 } 536 537 afc_info = qdf_mem_malloc(sizeof(*afc_info)); 538 if (!afc_info) 539 return -ENOMEM; 540 541 status = wmi_extract_afc_event(wmi_handle, event_buf, afc_info, len); 542 if (!QDF_IS_STATUS_SUCCESS(status)) { 543 target_if_err("Extraction of AFC event failed"); 544 ret_val = -EFAULT; 545 goto clean; 546 } 547 548 if (afc_info->phy_id >= PSOC_MAX_PHY_REG_CAP) { 549 target_if_err_rl("phy_id %d is out of bounds", 550 afc_info->phy_id); 551 ret_val = -EFAULT; 552 goto clean; 553 } 554 555 afc_info->psoc = psoc; 556 557 status = reg_rx_ops->afc_event_handler(afc_info); 558 if (!QDF_IS_STATUS_SUCCESS(status)) { 559 target_if_err("Failed to process AFC event handler"); 560 ret_val = -EFAULT; 561 goto clean; 562 } 563 564 clean: 565 qdf_mem_free(afc_info); 566 TARGET_IF_EXIT(); 567 568 return ret_val; 569 } 570 571 /** 572 * tgt_if_regulatory_register_afc_event_handler() - Register AFC event 573 * handler 574 * @psoc: Pointer to psoc 575 * @arg: Pointer to argument list 576 * 577 * Return: QDF_STATUS 578 */ 579 static QDF_STATUS tgt_if_regulatory_register_afc_event_handler( 580 struct wlan_objmgr_psoc *psoc, void *arg) 581 { 582 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 583 584 if (!wmi_handle) 585 return QDF_STATUS_E_FAILURE; 586 587 return wmi_unified_register_event_handler( 588 wmi_handle, wmi_afc_event_id, 589 tgt_afc_event_handler, WMI_RX_WORK_CTX); 590 } 591 592 /** 593 * tgt_if_regulatory_unregister_afc_event_handler() - Unregister AFC event 594 * handler 595 * @psoc: Pointer to psoc 596 * @arg: Pointer to argument list 597 * 598 * Return: QDF_STATUS 599 */ 600 static QDF_STATUS 601 tgt_if_regulatory_unregister_afc_event_handler(struct wlan_objmgr_psoc *psoc, 602 void *arg) 603 { 604 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 605 606 if (!wmi_handle) 607 return QDF_STATUS_E_FAILURE; 608 609 return wmi_unified_unregister_event_handler( 610 wmi_handle, wmi_afc_event_id); 611 } 612 #endif 613 #endif 614 615 /** 616 * tgt_if_regulatory_set_country_code() - Set country code 617 * @psoc: Pointer to psoc 618 * @arg: Pointer to argument list 619 * 620 * Return: QDF_STATUS 621 */ 622 static QDF_STATUS tgt_if_regulatory_set_country_code( 623 struct wlan_objmgr_psoc *psoc, void *arg) 624 { 625 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 626 627 if (!wmi_handle) 628 return QDF_STATUS_E_FAILURE; 629 630 return wmi_unified_set_country_cmd_send(wmi_handle, arg); 631 } 632 633 /** 634 * tgt_if_regulatory_set_user_country_code() - Set user country code 635 * @psoc: Pointer to psoc 636 * @pdev_id: Pdev id 637 * @rd: Pointer to regdomain structure 638 * 639 * Return: QDF_STATUS 640 */ 641 static QDF_STATUS tgt_if_regulatory_set_user_country_code( 642 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, struct cc_regdmn_s *rd) 643 { 644 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 645 646 if (!wmi_handle) 647 return QDF_STATUS_E_FAILURE; 648 649 if (wmi_unified_set_user_country_code_cmd_send( 650 wmi_handle, pdev_id, rd) != QDF_STATUS_SUCCESS 651 ) { 652 target_if_err("Set user country code failed"); 653 return QDF_STATUS_E_FAILURE; 654 } 655 656 return QDF_STATUS_SUCCESS; 657 } 658 659 QDF_STATUS tgt_if_regulatory_modify_freq_range(struct wlan_objmgr_psoc *psoc) 660 { 661 struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap; 662 663 reg_cap = ucfg_reg_get_hal_reg_cap(psoc); 664 if (!reg_cap) { 665 target_if_err("reg cap is NULL"); 666 return QDF_STATUS_E_FAILURE; 667 } 668 669 if (!(reg_cap->wireless_modes & HOST_REGDMN_MODE_11A)) { 670 reg_cap->low_5ghz_chan = 0; 671 reg_cap->high_5ghz_chan = 0; 672 } 673 674 if (!(reg_cap->wireless_modes & 675 (HOST_REGDMN_MODE_11B | HOST_REGDMN_MODE_PUREG))) { 676 reg_cap->low_2ghz_chan = 0; 677 reg_cap->high_2ghz_chan = 0; 678 } 679 680 target_if_debug("phy_id = %d - low_2ghz_chan = %d high_2ghz_chan = %d low_5ghz_chan = %d high_5ghz_chan = %d", 681 reg_cap->phy_id, 682 reg_cap->low_2ghz_chan, 683 reg_cap->high_2ghz_chan, 684 reg_cap->low_5ghz_chan, 685 reg_cap->high_5ghz_chan); 686 687 return QDF_STATUS_SUCCESS; 688 } 689 690 #ifdef CONFIG_REG_CLIENT 691 /** 692 * tgt_if_regulatory_send_ctl_info() - Send CTL info to firmware 693 * @psoc: Pointer to psoc 694 * @params: Pointer to reg control params 695 * 696 * Return: QDF_STATUS 697 */ 698 static QDF_STATUS 699 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 700 struct reg_ctl_params *params) 701 { 702 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 703 704 if (!wmi_handle) 705 return QDF_STATUS_E_FAILURE; 706 707 return wmi_unified_send_regdomain_info_to_fw_cmd(wmi_handle, 708 params->regd, 709 params->regd_2g, 710 params->regd_5g, 711 params->ctl_2g, 712 params->ctl_5g); 713 } 714 #else 715 static QDF_STATUS 716 tgt_if_regulatory_send_ctl_info(struct wlan_objmgr_psoc *psoc, 717 struct reg_ctl_params *params) 718 { 719 return QDF_STATUS_SUCCESS; 720 } 721 #endif 722 723 /** 724 * tgt_if_regulatory_get_phy_id_from_pdev_id() - Get phy_id from pdev_id 725 * @psoc: Pointer to psoc 726 * @pdev_id: Pdev id 727 * @phy_id: phy_id 728 * 729 * Return: QDF_STATUS 730 */ 731 static QDF_STATUS tgt_if_regulatory_get_phy_id_from_pdev_id( 732 struct wlan_objmgr_psoc *psoc, uint8_t pdev_id, uint8_t *phy_id) 733 { 734 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 735 uint8_t ret; 736 737 if (pdev_id >= WLAN_UMAC_MAX_PDEVS) { 738 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 739 return QDF_STATUS_E_FAILURE; 740 } 741 742 /* By default pdev_id and phy_id have one to one mapping */ 743 *phy_id = pdev_id; 744 745 if (!(tgt_if_handle && 746 tgt_if_handle->info.is_pdevid_to_phyid_map)) 747 return QDF_STATUS_SUCCESS; 748 749 ret = tgt_if_handle->info.pdev_id_to_phy_id_map[pdev_id]; 750 751 if (ret < PSOC_MAX_PHY_REG_CAP) { 752 *phy_id = ret; 753 } else { 754 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 755 return QDF_STATUS_E_FAILURE; 756 } 757 758 return QDF_STATUS_SUCCESS; 759 } 760 761 /** 762 * tgt_if_regulatory_get_pdev_id_from_phy_id() - Get pdev_id for phy_id 763 * @psoc: Pointer to psoc 764 * @phy_id: Phy id 765 * @pdev_id: Pdev id 766 * 767 * Return: QDF_STATUS 768 */ 769 static QDF_STATUS tgt_if_regulatory_get_pdev_id_from_phy_id( 770 struct wlan_objmgr_psoc *psoc, uint8_t phy_id, uint8_t *pdev_id) 771 { 772 struct target_psoc_info *tgt_if_handle = psoc->tgt_if_handle; 773 uint8_t i; 774 775 if (phy_id >= PSOC_MAX_PHY_REG_CAP) { 776 target_if_err("phy_id is greater than PSOC_MAX_PHY_REG_CAP"); 777 return QDF_STATUS_E_FAILURE; 778 } 779 780 /* By default pdev_id and phy_id have one to one mapping */ 781 *pdev_id = phy_id; 782 783 if (!(tgt_if_handle && 784 tgt_if_handle->info.is_pdevid_to_phyid_map)) 785 return QDF_STATUS_SUCCESS; 786 787 for (i = 0; i < WLAN_UMAC_MAX_PDEVS; i++) { 788 if (tgt_if_handle->info.pdev_id_to_phy_id_map[i] == phy_id) 789 break; 790 } 791 792 if (i < WLAN_UMAC_MAX_PDEVS) { 793 *pdev_id = i; 794 } else { 795 target_if_err("pdev_id is greater than WLAN_UMAC_MAX_PDEVS"); 796 return QDF_STATUS_E_FAILURE; 797 } 798 799 return QDF_STATUS_SUCCESS; 800 } 801 802 #ifdef CONFIG_BAND_6GHZ 803 static void target_if_register_master_ext_handler( 804 struct wlan_lmac_if_reg_tx_ops *reg_ops) 805 { 806 reg_ops->register_master_ext_handler = 807 tgt_if_regulatory_register_master_list_ext_handler; 808 809 reg_ops->unregister_master_ext_handler = 810 tgt_if_regulatory_unregister_master_list_ext_handler; 811 } 812 813 #ifdef CONFIG_AFC_SUPPORT 814 static void target_if_register_afc_event_handler( 815 struct wlan_lmac_if_reg_tx_ops *reg_ops) 816 { 817 reg_ops->register_afc_event_handler = 818 tgt_if_regulatory_register_afc_event_handler; 819 820 reg_ops->unregister_afc_event_handler = 821 tgt_if_regulatory_unregister_afc_event_handler; 822 } 823 824 static void target_if_register_acs_trigger_for_afc 825 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 826 { 827 reg_ops->trigger_acs_for_afc = NULL; 828 } 829 #else 830 static void target_if_register_afc_event_handler( 831 struct wlan_lmac_if_reg_tx_ops *reg_ops) 832 { 833 } 834 835 static void target_if_register_acs_trigger_for_afc 836 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 837 { 838 } 839 #endif 840 #else 841 static inline void 842 target_if_register_master_ext_handler(struct wlan_lmac_if_reg_tx_ops *reg_ops) 843 { 844 } 845 846 static void target_if_register_afc_event_handler( 847 struct wlan_lmac_if_reg_tx_ops *reg_ops) 848 { 849 } 850 851 static void target_if_register_acs_trigger_for_afc 852 (struct wlan_lmac_if_reg_tx_ops *reg_ops) 853 { 854 } 855 #endif 856 857 static QDF_STATUS 858 tgt_if_regulatory_set_tpc_power(struct wlan_objmgr_psoc *psoc, 859 uint8_t vdev_id, 860 struct reg_tpc_power_info *param) 861 { 862 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 863 864 if (!wmi_handle) 865 return QDF_STATUS_E_FAILURE; 866 867 return wmi_unified_send_set_tpc_power_cmd(wmi_handle, vdev_id, param); 868 } 869 870 #ifdef CONFIG_AFC_SUPPORT 871 /** 872 * tgt_if_regulatory_send_afc_cmd() - Send AFC command to the FW 873 * 874 * @psoc: Pointer to psoc 875 * @pdev_id: Pdev id 876 * @param: Pointer to hold AFC indication. 877 * 878 * Return: QDF_STATUS_SUCCESS if WMI_AFC_CMD is sent, else QDF_STATUS_E_FAILURE 879 */ 880 static QDF_STATUS 881 tgt_if_regulatory_send_afc_cmd(struct wlan_objmgr_psoc *psoc, 882 uint8_t pdev_id, 883 struct reg_afc_resp_rx_ind_info *param) 884 { 885 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 886 887 if (!wmi_handle) 888 return QDF_STATUS_E_FAILURE; 889 890 return wmi_unified_send_afc_cmd(wmi_handle, pdev_id, param); 891 } 892 893 static void 894 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 895 { 896 reg_ops->send_afc_ind = tgt_if_regulatory_send_afc_cmd; 897 } 898 #else 899 static void 900 tgt_if_register_afc_callback(struct wlan_lmac_if_reg_tx_ops *reg_ops) 901 { 902 } 903 #endif 904 905 /** 906 * tgt_if_regulatory_is_ext_tpc_supported() - Check if FW supports new 907 * WMI command for TPC power 908 * 909 * @psoc: Pointer to psoc 910 * 911 * Return: true if FW supports new WMI command for TPC, else false 912 */ 913 static bool 914 tgt_if_regulatory_is_ext_tpc_supported(struct wlan_objmgr_psoc *psoc) 915 { 916 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 917 918 if (!wmi_handle) 919 return false; 920 921 return wmi_service_enabled(wmi_handle, 922 wmi_service_ext_tpc_reg_support); 923 } 924 925 QDF_STATUS target_if_regulatory_set_ext_tpc(struct wlan_objmgr_psoc *psoc) 926 { 927 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 928 929 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 930 if (!reg_rx_ops) { 931 target_if_err("reg_rx_ops is NULL"); 932 return QDF_STATUS_E_FAILURE; 933 } 934 935 if (reg_rx_ops->reg_set_ext_tpc_supported) 936 reg_rx_ops->reg_set_ext_tpc_supported( 937 psoc, 938 tgt_if_regulatory_is_ext_tpc_supported(psoc)); 939 940 return QDF_STATUS_SUCCESS; 941 } 942 943 #if defined(CONFIG_BAND_6GHZ) 944 /** 945 * tgt_if_regulatory_is_lower_6g_edge_ch_supp() - Check if lower 6ghz 946 * edge channel (5935MHz) is supported 947 * @psoc: Pointer to psoc 948 * 949 * Return: true if channel is supported, else false 950 */ 951 static bool 952 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 953 { 954 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 955 956 if (!wmi_handle) 957 return false; 958 959 return wmi_service_enabled(wmi_handle, 960 wmi_service_lower_6g_edge_ch_supp); 961 } 962 963 /** 964 * tgt_if_regulatory_is_upper_6g_edge_ch_disabled() - Check if upper 965 * 6ghz edge channel (7115MHz) is disabled 966 * @psoc: Pointer to psoc 967 * 968 * Return: true if channel is disabled, else false 969 */ 970 static bool 971 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 972 { 973 wmi_unified_t wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); 974 975 if (!wmi_handle) 976 return false; 977 978 return wmi_service_enabled(wmi_handle, 979 wmi_service_disable_upper_6g_edge_ch_supp); 980 } 981 982 QDF_STATUS 983 target_if_reg_set_lower_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 984 { 985 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 986 987 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 988 if (!reg_rx_ops) { 989 target_if_err("reg_rx_ops is NULL"); 990 return QDF_STATUS_E_FAILURE; 991 } 992 993 if (reg_rx_ops->reg_set_lower_6g_edge_ch_supp) 994 reg_rx_ops->reg_set_lower_6g_edge_ch_supp( 995 psoc, 996 tgt_if_regulatory_is_lower_6g_edge_ch_supp(psoc)); 997 998 return QDF_STATUS_SUCCESS; 999 } 1000 1001 QDF_STATUS 1002 target_if_reg_set_disable_upper_6g_edge_ch_info(struct wlan_objmgr_psoc *psoc) 1003 { 1004 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1005 1006 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1007 if (!reg_rx_ops) { 1008 target_if_err("reg_rx_ops is NULL"); 1009 return QDF_STATUS_E_FAILURE; 1010 } 1011 1012 if (reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp) 1013 reg_rx_ops->reg_set_disable_upper_6g_edge_ch_supp( 1014 psoc, 1015 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(psoc)); 1016 1017 return QDF_STATUS_SUCCESS; 1018 } 1019 #else 1020 static inline bool 1021 tgt_if_regulatory_is_lower_6g_edge_ch_supp(struct wlan_objmgr_psoc *psoc) 1022 { 1023 return false; 1024 } 1025 1026 static inline bool 1027 tgt_if_regulatory_is_upper_6g_edge_ch_disabled(struct wlan_objmgr_psoc *psoc) 1028 { 1029 return false; 1030 } 1031 #endif 1032 1033 #if defined(CONFIG_AFC_SUPPORT) 1034 QDF_STATUS 1035 target_if_reg_set_afc_dev_type(struct wlan_objmgr_psoc *psoc, 1036 struct target_psoc_info *tgt_hdl) 1037 { 1038 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1039 struct tgt_info *info; 1040 1041 if (!tgt_hdl) { 1042 target_if_err("target_psoc_info is null"); 1043 return QDF_STATUS_E_FAILURE; 1044 } 1045 1046 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1047 if (!reg_rx_ops) { 1048 target_if_err("reg_rx_ops is NULL"); 1049 return QDF_STATUS_E_FAILURE; 1050 } 1051 1052 info = (&tgt_hdl->info); 1053 1054 if (reg_rx_ops->reg_set_afc_dev_type) 1055 reg_rx_ops->reg_set_afc_dev_type( 1056 psoc, 1057 info->service_ext2_param.afc_dev_type); 1058 1059 return QDF_STATUS_SUCCESS; 1060 } 1061 1062 QDF_STATUS 1063 target_if_reg_get_afc_dev_type(struct wlan_objmgr_psoc *psoc, 1064 enum reg_afc_dev_deploy_type *reg_afc_dev_type) 1065 { 1066 struct wlan_lmac_if_reg_rx_ops *reg_rx_ops; 1067 1068 reg_rx_ops = target_if_regulatory_get_rx_ops(psoc); 1069 if (!reg_rx_ops) { 1070 target_if_err("reg_rx_ops is NULL"); 1071 return QDF_STATUS_E_FAILURE; 1072 } 1073 1074 if (reg_rx_ops->reg_get_afc_dev_type) 1075 reg_rx_ops->reg_get_afc_dev_type( 1076 psoc, 1077 reg_afc_dev_type); 1078 1079 return QDF_STATUS_SUCCESS; 1080 } 1081 #endif 1082 1083 /** 1084 * tgt_if_reg_is_chip_11be_cap() - Finds out if the hardware is capable 1085 * of 11BE. The capability bit is read from mac_phy_cap populated by the 1086 * FW per pdev. 1087 * @psoc: Pointer to psoc 1088 * @phy_id: phy_id 1089 * 1090 * Return: True if chip is 11BE capable, false otherwise. 1091 */ 1092 #ifdef WLAN_FEATURE_11BE 1093 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc, 1094 uint16_t phy_id) 1095 { 1096 struct wlan_psoc_host_mac_phy_caps *mac_phy_cap_arr, *mac_phy_cap; 1097 struct target_psoc_info *tgt_hdl; 1098 uint8_t pdev_id; 1099 struct wlan_lmac_if_reg_tx_ops *reg_tx_ops; 1100 1101 reg_tx_ops = target_if_regulatory_get_tx_ops(psoc); 1102 1103 if (!reg_tx_ops) { 1104 target_if_err("reg_tx_ops is NULL"); 1105 return false; 1106 } 1107 1108 if (reg_tx_ops->get_pdev_id_from_phy_id) 1109 reg_tx_ops->get_pdev_id_from_phy_id(psoc, phy_id, &pdev_id); 1110 else 1111 pdev_id = phy_id; 1112 1113 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc); 1114 if (tgt_hdl) { 1115 mac_phy_cap_arr = target_psoc_get_mac_phy_cap(tgt_hdl); 1116 if (!mac_phy_cap_arr) 1117 return false; 1118 mac_phy_cap = &mac_phy_cap_arr[pdev_id]; 1119 if (mac_phy_cap && mac_phy_cap->supports_11be) 1120 return true; 1121 } 1122 return false; 1123 } 1124 #else 1125 static bool tgt_if_reg_is_chip_11be_cap(struct wlan_objmgr_psoc *psoc, 1126 uint16_t phy_id) 1127 { 1128 return false; 1129 } 1130 #endif 1131 1132 QDF_STATUS target_if_register_regulatory_tx_ops( 1133 struct wlan_lmac_if_tx_ops *tx_ops) 1134 { 1135 struct wlan_lmac_if_reg_tx_ops *reg_ops = &tx_ops->reg_ops; 1136 1137 reg_ops->register_master_handler = 1138 tgt_if_regulatory_register_master_list_handler; 1139 1140 reg_ops->unregister_master_handler = 1141 tgt_if_regulatory_unregister_master_list_handler; 1142 1143 target_if_register_master_ext_handler(reg_ops); 1144 1145 target_if_register_afc_event_handler(reg_ops); 1146 1147 reg_ops->set_country_code = tgt_if_regulatory_set_country_code; 1148 1149 reg_ops->fill_umac_legacy_chanlist = NULL; 1150 1151 reg_ops->set_country_failed = NULL; 1152 1153 target_if_register_acs_trigger_for_afc(reg_ops); 1154 1155 reg_ops->register_11d_new_cc_handler = 1156 tgt_if_regulatory_register_11d_new_cc_handler; 1157 1158 reg_ops->unregister_11d_new_cc_handler = 1159 tgt_if_regulatory_unregister_11d_new_cc_handler; 1160 1161 reg_ops->start_11d_scan = tgt_if_regulatory_start_11d_scan; 1162 1163 reg_ops->stop_11d_scan = tgt_if_regulatory_stop_11d_scan; 1164 1165 reg_ops->is_there_serv_ready_extn = 1166 tgt_if_regulatory_is_there_serv_ready_extn; 1167 1168 reg_ops->set_user_country_code = 1169 tgt_if_regulatory_set_user_country_code; 1170 1171 reg_ops->register_ch_avoid_event_handler = 1172 tgt_if_regulatory_register_ch_avoid_event_handler; 1173 1174 reg_ops->unregister_ch_avoid_event_handler = 1175 tgt_if_regulatory_unregister_ch_avoid_event_handler; 1176 1177 reg_ops->send_ctl_info = tgt_if_regulatory_send_ctl_info; 1178 1179 reg_ops->get_phy_id_from_pdev_id = 1180 tgt_if_regulatory_get_phy_id_from_pdev_id; 1181 1182 reg_ops->get_pdev_id_from_phy_id = 1183 tgt_if_regulatory_get_pdev_id_from_phy_id; 1184 1185 reg_ops->set_tpc_power = tgt_if_regulatory_set_tpc_power; 1186 1187 reg_ops->get_opclass_tbl_idx = NULL; 1188 1189 tgt_if_register_afc_callback(reg_ops); 1190 1191 reg_ops->is_chip_11be = tgt_if_reg_is_chip_11be_cap; 1192 1193 return QDF_STATUS_SUCCESS; 1194 } 1195