diff --git a/umac/regulatory/core/src/reg_utils.c b/umac/regulatory/core/src/reg_utils.c index ca82b046b72d..e46d47262744 100644 --- a/umac/regulatory/core/src/reg_utils.c +++ b/umac/regulatory/core/src/reg_utils.c @@ -39,8 +39,11 @@ #include "reg_build_chan_list.h" #include "wlan_cm_bss_score_param.h" #include "wmi_unified_param.h" +#include "qdf_str.h" #define DEFAULT_WORLD_REGDMN 0x60 +#define FCC3_FCCA 0x3A +#define FCC6_FCCA 0x14 #define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj) #define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj) @@ -180,6 +183,48 @@ bool reg_is_etsi_alpha2(uint8_t *alpha2) return false; } +static +const char *reg_get_power_mode_string(uint16_t reg_dmn_pair_id) +{ + switch (reg_dmn_pair_id) { + case FCC3_FCCA: + case FCC6_FCCA: + return "NON_VLP"; + default: + return "VLP"; + } +} + +static bool reg_ctry_domain_supports_vlp(uint8_t *alpha2) +{ + uint16_t i; + int no_of_countries; + + reg_get_num_countries(&no_of_countries); + for (i = 0; i < no_of_countries; i++) { + if (g_all_countries[i].alpha2[0] == alpha2[0] && + g_all_countries[i].alpha2[1] == alpha2[1]) { + if (!qdf_str_cmp(reg_get_power_mode_string( + g_all_countries[i].reg_dmn_pair_id), "NON_VLP")) + return false; + else + return true; + } + } + return true; +} + +bool reg_ctry_support_vlp(uint8_t *alpha2) +{ + if (((alpha2[0] == 'A') && (alpha2[1] == 'E')) || + ((alpha2[0] == 'P') && (alpha2[1] == 'E')) || + ((alpha2[0] == 'U') && (alpha2[1] == 'S')) || + !reg_ctry_domain_supports_vlp(alpha2)) + return false; + else + return true; +} + QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, uint8_t *country) { @@ -338,40 +383,44 @@ reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, { *pwr_type_6g = REG_INDOOR_AP; - if (qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) { - reg_debug("Country IE:%c%c, STA country:%c%c", ap_ctry[0], - ap_ctry[1], sta_ctry[0], sta_ctry[1]); - *ctry_code_match = false; + reg_debug("Country IE:%c%c, STA country:%c%c", ap_ctry[0], + ap_ctry[1], sta_ctry[0], sta_ctry[1]); - /** - * Do not return if Wi-Fi safe mode or RF test mode is - * enabled, rather STA should operate in LPI mode. - * wlan_cm_get_check_6ghz_security API returns true if - * neither Safe mode nor RF test mode are enabled. - */ - if (wlan_reg_is_us(sta_ctry) && + if (!qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) { + *ctry_code_match = true; + return QDF_STATUS_SUCCESS; + } + + *ctry_code_match = false; + /* + * If reg_info=0 not included, STA should operate in VLP mode. + * If STA country doesn't support VLP, do not return if Wi-Fi + * safe mode or RF test mode or enable relaxed connection policy, + * rather STA should operate in LPI mode. + * wlan_cm_get_check_6ghz_security API returns true if + * neither Safe mode nor RF test mode are enabled. + */ + if (ap_pwr_type != REG_INDOOR_AP) { + if (wlan_reg_ctry_support_vlp(sta_ctry)) + *pwr_type_6g = REG_VERY_LOW_POWER_AP; + if (!wlan_reg_ctry_support_vlp(sta_ctry) && wlan_cm_get_check_6ghz_security(psoc)) { - reg_err("US VLP not in place yet, connection not allowed"); + reg_err("VLP not supported, can't connect"); return QDF_STATUS_E_NOSUPPORT; } + } - if (wlan_reg_is_etsi(sta_ctry) && - ap_pwr_type != REG_MAX_AP_TYPE) { - if (!(wlan_reg_is_us(ap_ctry) && - ap_pwr_type == REG_INDOOR_AP)) { - reg_debug("STA ctry:%c%c, doesn't match with AP ctry, switch to VLP", - sta_ctry[0], sta_ctry[1]); - *pwr_type_6g = REG_VERY_LOW_POWER_AP; - } - } + if (wlan_reg_ctry_support_vlp(sta_ctry) && + wlan_reg_ctry_support_vlp(ap_ctry) && + ap_pwr_type == REG_INDOOR_AP) { + reg_debug("STA ctry doesn't match with AP ctry, switch to VLP"); + *pwr_type_6g = REG_VERY_LOW_POWER_AP; + } - if (wlan_reg_is_us(ap_ctry) && ap_pwr_type == REG_INDOOR_AP) { - reg_debug("AP ctry:%c%c, AP power type:%d, allow STA IN LPI", - ap_ctry[0], ap_ctry[1], ap_pwr_type); - *pwr_type_6g = REG_INDOOR_AP; - } - } else { - *ctry_code_match = true; + if (!wlan_reg_ctry_support_vlp(ap_ctry) && + ap_pwr_type == REG_INDOOR_AP) { + reg_debug("VLP not supported by AP, allow STA IN LPI"); + *pwr_type_6g = REG_INDOOR_AP; } return QDF_STATUS_SUCCESS; diff --git a/umac/regulatory/core/src/reg_utils.h b/umac/regulatory/core/src/reg_utils.h index e151a8fd3b94..8b2852e8876a 100644 --- a/umac/regulatory/core/src/reg_utils.h +++ b/umac/regulatory/core/src/reg_utils.h @@ -260,6 +260,14 @@ bool reg_is_us_alpha2(uint8_t *alpha2); */ bool reg_is_etsi_alpha2(uint8_t *alpha2); +/** + * reg_ctry_support_vlp - Does country code supports VLP + * @alpha2: country code pointer + * + * Return: true or false + */ +bool reg_ctry_support_vlp(uint8_t *alpha2); + /** * reg_set_country() - Set the current regulatory country * @pdev: pdev device for country information @@ -443,6 +451,11 @@ static inline bool reg_is_world_alpha2(uint8_t *alpha2) return false; } +static inline bool reg_ctry_support_vlp(uint8_t *alpha2) +{ + return false; +} + static inline bool reg_is_us_alpha2(uint8_t *alpha2) { return false; diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 99a67981c385..187708519c04 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -1062,6 +1062,14 @@ bool wlan_reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev, uint8_t chan_num); #endif /* CONFIG_CHAN_NUM_API */ +/** + * wlan_reg_ctry_support_vlp() - Country supports VLP or not + * @country: The country information + * + * Return: true or false + */ +bool wlan_reg_ctry_support_vlp(uint8_t *country); + /** * wlan_reg_set_country() - Set the current regulatory country * @pdev: The physical dev to set current country for diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index b9bec25b2e6d..ff2c1bf67ceb 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -667,6 +667,11 @@ bool wlan_reg_is_etsi(uint8_t *country) return reg_is_etsi_alpha2(country); } +bool wlan_reg_ctry_support_vlp(uint8_t *country) +{ + return reg_ctry_support_vlp(country); +} + void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc, void *cbk, void *arg) {