From d92d4981a529fb395e51666db4c95e5caaefc38e Mon Sep 17 00:00:00 2001 From: Sheenam Monga Date: Thu, 12 Oct 2023 18:48:34 +0530 Subject: [PATCH 1/4] qcacmn: Don't set power mode to VLP for all countries Set LPI power mode for countries & domain that don't support VLP. Change-Id: I799a0d5beb23a4f0f613269d981ce61c86bcb5c1 CRs-Fixed: 3200465 --- umac/regulatory/core/src/reg_utils.c | 105 +++++++++++++----- umac/regulatory/core/src/reg_utils.h | 13 +++ .../dispatcher/inc/wlan_reg_services_api.h | 10 +- .../dispatcher/src/wlan_reg_services_api.c | 7 +- 4 files changed, 105 insertions(+), 30 deletions(-) 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) { From 82bd127e2d001a943cefaab3774414368fff44ee Mon Sep 17 00:00:00 2001 From: Asutosh Mohapatra Date: Wed, 11 Oct 2023 23:23:29 +0530 Subject: [PATCH 2/4] qcacmn: Do not allow connection if STA VLP not supported If country code for AP and STA are same and if STA does not support VLP mode for a particular channel and if AP power type is misconfigured to VLP mode, do not allow connection to that AP as per regulatory guidelines. Change-Id: Ie3bb980df25a15c4d9d7e566663e28950414f733 CRs-Fixed: 3362142 --- umac/regulatory/core/src/reg_utils.c | 34 +++++++++++++++++-- umac/regulatory/core/src/reg_utils.h | 3 ++ .../dispatcher/inc/wlan_reg_services_api.h | 3 ++ .../dispatcher/src/wlan_reg_services_api.c | 3 +- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/umac/regulatory/core/src/reg_utils.c b/umac/regulatory/core/src/reg_utils.c index e46d47262744..d759460a8926 100644 --- a/umac/regulatory/core/src/reg_utils.c +++ b/umac/regulatory/core/src/reg_utils.c @@ -374,20 +374,36 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, } #ifdef CONFIG_REG_CLIENT +#ifdef CONFIG_BAND_6GHZ QDF_STATUS reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t *ap_ctry, uint8_t *sta_ctry, enum reg_6g_ap_type *pwr_type_6g, bool *ctry_code_match, enum reg_6g_ap_type ap_pwr_type) { - *pwr_type_6g = REG_INDOOR_AP; + struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - reg_debug("Country IE:%c%c, STA country:%c%c", ap_ctry[0], - ap_ctry[1], sta_ctry[0], sta_ctry[1]); + *pwr_type_6g = REG_INDOOR_AP; + pdev_priv_obj = reg_get_pdev_obj(pdev); + if (!pdev_priv_obj) { + reg_err("pdev priv obj null"); + return QDF_STATUS_E_FAILURE; + } + + reg_debug("STA country: %c%c, AP country: %c%c, AP power type: %d", + sta_ctry[0], sta_ctry[1], ap_ctry[0], ap_ctry[1], + ap_pwr_type); if (!qdf_mem_cmp(ap_ctry, sta_ctry, REG_ALPHA2_LEN)) { *ctry_code_match = true; + if (ap_pwr_type == REG_VERY_LOW_POWER_AP) { + if (!pdev_priv_obj->reg_rules.num_of_6g_client_reg_rules[ap_pwr_type]) { + reg_err("VLP not supported, can't connect"); + return QDF_STATUS_E_NOSUPPORT; + } + } return QDF_STATUS_SUCCESS; } @@ -425,6 +441,18 @@ reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#else +QDF_STATUS +reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, + uint8_t *ap_ctry, uint8_t *sta_ctry, + enum reg_6g_ap_type *pwr_type_6g, + bool *ctry_code_match, + enum reg_6g_ap_type ap_pwr_type) +{ + return QDF_STATUS_SUCCESS; +} +#endif #endif #ifdef CONFIG_CHAN_NUM_API diff --git a/umac/regulatory/core/src/reg_utils.h b/umac/regulatory/core/src/reg_utils.h index 8b2852e8876a..069a04220aed 100644 --- a/umac/regulatory/core/src/reg_utils.h +++ b/umac/regulatory/core/src/reg_utils.h @@ -300,6 +300,8 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, #ifdef CONFIG_REG_CLIENT /** * reg_get_6g_power_type_for_ctry() - Return power type for 6G based on cntry IE + * @psoc: pointer to psoc + * @pdev: pointer to pdev * @ap_ctry: ptr to country string in country IE * @sta_ctry: ptr to sta programmed country * @pwr_type_6g: ptr to 6G power type @@ -309,6 +311,7 @@ QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, */ QDF_STATUS reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t *ap_ctry, uint8_t *sta_ctry, enum reg_6g_ap_type *pwr_type_6g, bool *ctry_code_match, diff --git a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h index 187708519c04..5019ea4e8afe 100644 --- a/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h +++ b/umac/regulatory/dispatcher/inc/wlan_reg_services_api.h @@ -543,6 +543,8 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, /** * wlan_reg_get_6g_power_type_for_ctry() - Return power type for 6G based * on country IE + * @psoc: pointer to psoc + * @pdev: pointer to pdev * @ap_ctry: ptr to country string in country IE * @sta_ctry: ptr to sta programmed country * @pwr_type_6g: ptr to 6G power type @@ -552,6 +554,7 @@ QDF_STATUS wlan_reg_read_current_country(struct wlan_objmgr_psoc *psoc, */ QDF_STATUS wlan_reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t *ap_ctry, uint8_t *sta_ctry, enum reg_6g_ap_type *pwr_type_6g, bool *ctry_code_match, diff --git a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c index ff2c1bf67ceb..95ed22420a5b 100644 --- a/umac/regulatory/dispatcher/src/wlan_reg_services_api.c +++ b/umac/regulatory/dispatcher/src/wlan_reg_services_api.c @@ -88,12 +88,13 @@ QDF_STATUS wlan_reg_get_max_5g_bw_from_regdomain(uint16_t regdmn, #ifdef CONFIG_REG_CLIENT QDF_STATUS wlan_reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_pdev *pdev, uint8_t *ap_ctry, uint8_t *sta_ctry, enum reg_6g_ap_type *pwr_type_6g, bool *ctry_code_match, enum reg_6g_ap_type ap_pwr_type) { - return reg_get_6g_power_type_for_ctry(psoc, ap_ctry, sta_ctry, + return reg_get_6g_power_type_for_ctry(psoc, pdev, ap_ctry, sta_ctry, pwr_type_6g, ctry_code_match, ap_pwr_type); } From 241659c576013d22d698b4f083f61c570c66d857 Mon Sep 17 00:00:00 2001 From: Asutosh Mohapatra Date: Wed, 11 Oct 2023 23:30:24 +0530 Subject: [PATCH 3/4] qcacmn: Don't use LPI as default power type Currently host uses LPI as default power type when STA and AP country is same without checking if powertype advertised by AP is valid for client or not. To address this issue default to power type advertised by AP. Change-Id: I59144b020bed5af49dea8fdaad0e59daa556fefe CRs-Fixed: 3381295 --- umac/regulatory/core/src/reg_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/umac/regulatory/core/src/reg_utils.c b/umac/regulatory/core/src/reg_utils.c index d759460a8926..479bfaec20f4 100644 --- a/umac/regulatory/core/src/reg_utils.c +++ b/umac/regulatory/core/src/reg_utils.c @@ -385,7 +385,7 @@ reg_get_6g_power_type_for_ctry(struct wlan_objmgr_psoc *psoc, { struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj; - *pwr_type_6g = REG_INDOOR_AP; + *pwr_type_6g = ap_pwr_type; pdev_priv_obj = reg_get_pdev_obj(pdev); if (!pdev_priv_obj) { reg_err("pdev priv obj null"); From 825d21edcb0dce2417da51cd881dc0ef5c5334ad Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Fri, 1 Dec 2023 10:16:57 +0530 Subject: [PATCH 4/4] qcacmn: Add sanity check to fix OOB issue Add sanity check to fix OOB issue while generating scan entries for beacon CRs-Fixed: 3591858 Change-Id: I35b362bc89ab10fa2d2d6660263c726692384e07 --- umac/scan/dispatcher/src/wlan_scan_utils_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 49be228eac36..bff9e3b812c4 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -2642,9 +2642,9 @@ util_scan_parse_beacon_frame(struct wlan_objmgr_pdev *pdev, mbssid_ie = util_scan_find_ie(WLAN_ELEMID_MULTIPLE_BSSID, (uint8_t *)&bcn->ie, ie_len); if (mbssid_ie) { - if (mbssid_ie[1] <= 0) { + if (mbssid_ie[TAG_LEN_POS] < VALID_ELEM_LEAST_LEN) { scm_debug("MBSSID IE length is wrong %d", - mbssid_ie[1]); + mbssid_ie[TAG_LEN_POS]); return status; } qdf_mem_copy(&mbssid_info.trans_bssid,