diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index bef091a2ba..8326baffa1 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -112,10 +112,14 @@ struct wlan_mlme_roaming_config { * roam config info * @roam_sm: Structure containing roaming state related details * @roam_config: Roaming configurations structure + * @sae_single_pmk: Details for sae roaming using single pmk */ struct wlan_mlme_roam { struct wlan_mlme_roam_state_info roam_sm; struct wlan_mlme_roaming_config roam_cfg; +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) + struct wlan_mlme_sae_single_pmk sae_single_pmk; +#endif }; /** diff --git a/components/mlme/core/src/wlan_mlme_main.c b/components/mlme/core/src/wlan_mlme_main.c index e67b29588e..ac4b40fbe3 100644 --- a/components/mlme/core/src/wlan_mlme_main.c +++ b/components/mlme/core/src/wlan_mlme_main.c @@ -1432,7 +1432,7 @@ mlme_init_adaptive_11r_cfg(struct wlan_objmgr_psoc *psoc, } #endif -#ifdef WLAN_SAE_SINGLE_PMK +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) /** * mlme_init_sae_single_pmk_cfg() - initialize sae_same_pmk_config * flag @@ -1445,7 +1445,7 @@ static void mlme_init_sae_single_pmk_cfg(struct wlan_objmgr_psoc *psoc, struct wlan_mlme_lfr_cfg *lfr) { - lfr->sae_same_pmk_feature_enabled = cfg_get(psoc, CFG_SAE_SINGLE_PMK); + lfr->sae_single_pmk_feature_enabled = cfg_get(psoc, CFG_SAE_SINGLE_PMK); } #else @@ -1475,6 +1475,7 @@ static void mlme_init_roam_offload_cfg(struct wlan_objmgr_psoc *psoc, cfg_get(psoc, CFG_LFR_IDLE_ROAM_PACKET_COUNT); lfr->idle_roam_min_rssi = cfg_get(psoc, CFG_LFR_IDLE_ROAM_MIN_RSSI); lfr->idle_roam_band = cfg_get(psoc, CFG_LFR_IDLE_ROAM_BAND); + mlme_init_sae_single_pmk_cfg(psoc, lfr); } #else @@ -1708,7 +1709,6 @@ static void mlme_init_lfr_cfg(struct wlan_objmgr_psoc *psoc, mlme_init_bss_load_trigger_params(psoc, &lfr->bss_load_trig); mlme_init_adaptive_11r_cfg(psoc, lfr); mlme_init_subnet_detection(psoc, lfr); - mlme_init_sae_single_pmk_cfg(psoc, lfr); } static uint32_t diff --git a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h index 703fa19bf6..6981e59cf6 100644 --- a/components/mlme/dispatcher/inc/cfg_mlme_lfr.h +++ b/components/mlme/dispatcher/inc/cfg_mlme_lfr.h @@ -2414,13 +2414,13 @@ #define LFR_SUBNET_DETECTION_ALL #endif -#ifdef WLAN_SAE_SINGLE_PMK +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) /* * - * sae_same_pmk_feature_enabled - Enable/disable sae single pmk feature. + * sae_single_pmk_feature_enabled - Enable/disable sae single pmk feature. * @Min: 0 * @Max: 1 - * @Default: 1 + * @Default: 0 * * This INI is to enable/disable SAE Roaming with same PMK/PMKID feature support * @@ -2433,9 +2433,9 @@ * */ #define CFG_SAE_SINGLE_PMK CFG_INI_BOOL( \ - "sae_same_pmk_feature_enabled", \ - true, \ - "Enable/disable SAE Roaming with same PMK/PMKID") + "sae_single_pmk_feature_enabled", \ + false, \ + "Enable/disable SAE Roaming with single PMK/PMKID") #define SAE_SINGLE_PMK_ALL CFG(CFG_SAE_SINGLE_PMK) #else diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index d7b2df56ea..a0bd6e59b6 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -2302,6 +2302,41 @@ char *mlme_get_roam_trigger_str(uint32_t roam_scan_trigger); */ void mlme_get_converted_timestamp(uint32_t timestamp, char *time); +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * wlan_mlme_set_sae_single_pmk_bss_cap - API to set WPA3 single pmk AP IE + * @psoc: Pointer to psoc object + * @vdev_id: vdev id + * @val: value to be set + * + * Return : None + */ +void wlan_mlme_set_sae_single_pmk_bss_cap(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool val); + +/** + * wlan_mlme_update_sae_single_pmk - API to update mlme_pmkid_info + * @vdev: vdev object + * @sae_single_pmk: pointer to sae_single_pmk_info struct + * + * Return : None + */ +void +wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *sae_single_pmk); +#else +static inline void +wlan_mlme_set_sae_single_pmk_bss_cap(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool val) +{ +} + +static inline void +wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *sae_single_pmk) +{ +} +#endif /** * mlme_get_roam_fail_reason_str() - Get fail string from enum * WMI_ROAM_FAIL_REASON_ID diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 832dd01ea0..d4b3021f40 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -67,6 +67,8 @@ #define CFG_MAX_STR_LEN 256 #define MAX_VENDOR_IES_LEN 1532 +#define CFG_MAX_PMK_LEN 64 + #define CFG_VALID_CHANNEL_LIST_STRING_LEN (CFG_VALID_CHANNEL_LIST_LEN * 4) #define DEFAULT_ROAM_TRIGGER_BITMAP 0xFFFFFFFF @@ -1521,8 +1523,8 @@ struct bss_load_trigger { * @fw_akm_bitmap: Supported Akm suites of firmware * @roam_full_scan_period: Idle period in seconds between two successive * full channel roam scans - * @sae_same_pmk_feature_enabled: Contains value of ini - * sae_same_pmk_feature_enabled + * @sae_single_pmk_feature_enabled: Contains value of ini + * sae_single_pmk_feature_enabled */ struct wlan_mlme_lfr_cfg { bool mawc_roam_enabled; @@ -1626,8 +1628,8 @@ struct wlan_mlme_lfr_cfg { uint32_t roam_scan_period_after_inactivity; uint32_t fw_akm_bitmap; uint32_t roam_full_scan_period; -#ifdef WLAN_SAE_SINGLE_PMK - bool sae_same_pmk_feature_enabled; +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) + bool sae_single_pmk_feature_enabled; #endif }; @@ -2321,6 +2323,27 @@ enum pkt_origin { HOST }; +/** + * struct mlme_pmk_info - SAE Roaming using single pmk info + * @pmk: pmk + * @pmk_len: pmk length + */ +struct mlme_pmk_info { + uint8_t pmk[CFG_MAX_PMK_LEN]; + uint8_t pmk_len; +}; + +/** + * struct wlan_mlme_sae_single_pmk - SAE Roaming using single pmk configuration + * structure + * @sae_single_pmk_ap: Current connected AP has VSIE or not + * @pmk_info: pmk information + */ +struct wlan_mlme_sae_single_pmk { + bool sae_single_pmk_ap; + struct mlme_pmk_info pmk_info; +}; + /** * struct mlme_roam_debug_info - Roam debug information storage structure. * @trigger: Roam trigger related data diff --git a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h index c054f05f8a..322a4bf7b4 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_ucfg_api.h @@ -1206,6 +1206,26 @@ ucfg_mlme_get_delay_before_vdev_stop(struct wlan_objmgr_psoc *psoc, QDF_STATUS ucfg_mlme_get_roam_bmiss_final_bcnt(struct wlan_objmgr_psoc *psoc, uint8_t *val); + +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * ucfg_mlme_update_sae_single_pmk_info() - Update sae_single_pmk_info + * @vdev: pointer to VDEV common object + * @pmk_info: Pointer mlme pmkid info + * + * Return: None + */ +void +ucfg_mlme_update_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *pmk_info); +#else +static inline void +ucfg_mlme_update_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *pmk_info) +{ +} +#endif + /** * ucfg_mlme_get_roam_bmiss_first_bcnt() - Get roam bmiss final count * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index 45b9e6ca98..6b6576c371 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -3589,6 +3589,57 @@ void mlme_get_converted_timestamp(uint32_t timestamp, char *time) (timestamp % 1000) * 1000); } +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +void wlan_mlme_set_sae_single_pmk_bss_cap(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, bool val) +{ + struct mlme_legacy_priv *mlme_priv; + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_OBJMGR_ID); + + if (!vdev) { + mlme_err("get vdev failed"); + return; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); + mlme_legacy_err("vdev legacy private object is NULL"); + return; + } + + mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap = val; + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID); +} + +void wlan_mlme_update_sae_single_pmk(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *sae_single_pmk) +{ + struct mlme_legacy_priv *mlme_priv; + uint32_t keymgmt; + bool is_sae_connection = false; + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_legacy_err("vdev legacy private object is NULL"); + return; + } + + keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT); + + if (keymgmt & (1 << WLAN_CRYPTO_KEY_MGMT_SAE)) + is_sae_connection = true; + + if (mlme_priv->mlme_roam.sae_single_pmk.sae_single_pmk_ap && + is_sae_connection) + mlme_priv->mlme_roam.sae_single_pmk.pmk_info = *sae_single_pmk; +} +#endif + char *mlme_get_roam_fail_reason_str(uint32_t result) { switch (result) { diff --git a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c index 48106a4e41..3cfef044eb 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c @@ -963,6 +963,14 @@ ucfg_mlme_get_delay_before_vdev_stop(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +void ucfg_mlme_update_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + struct mlme_pmk_info *sae_single_pmk) +{ + wlan_mlme_update_sae_single_pmk(vdev, sae_single_pmk); +} +#endif + QDF_STATUS ucfg_mlme_get_roam_bmiss_final_bcnt(struct wlan_objmgr_psoc *psoc, uint8_t *val) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 0c549a55fe..27a7273c03 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -21212,6 +21212,39 @@ static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy, return errno; } +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * wlan_update_sae_single_pmk_info() - Update a separate pmk information + * structure to support sae roaming using same pmk + * @vdev: vdev common object + * @pmk_cache: Pointer to pmk cache info + * + * Return: None + */ +static void wlan_update_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + tPmkidCacheInfo *pmk_cache) +{ + struct mlme_pmk_info *pmk_info; + + pmk_info = qdf_mem_malloc(sizeof(*pmk_info)); + if (!pmk_info) + return; + + qdf_mem_copy(pmk_info->pmk, pmk_cache->pmk, pmk_cache->pmk_len); + pmk_info->pmk_len = pmk_cache->pmk_len; + + ucfg_mlme_update_sae_single_pmk_info(vdev, pmk_info); + + qdf_mem_zero(pmk_info, sizeof(*pmk_info)); + qdf_mem_free(pmk_info); + +} +#else +static void wlan_update_sae_single_pmk_info(struct wlan_objmgr_vdev *vdev, + tPmkidCacheInfo *pmk_cache) +{ +} +#endif static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, tPmkidCacheInfo *pmk_cache) { @@ -21238,6 +21271,9 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter, qdf_mem_zero(pmksa, sizeof(*pmksa)); qdf_mem_free(pmksa); } + + wlan_update_sae_single_pmk_info(vdev, pmk_cache); + hdd_objmgr_put_vdev(vdev); return result; diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 9f2dd32892..dc740fae57 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -710,6 +710,9 @@ struct bss_description { #endif uint32_t assoc_disallowed; uint32_t adaptive_11r_ap; +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) + uint32_t is_single_pmk; +#endif /* Please keep the structure 4 bytes aligned above the ieFields */ uint32_t ieFields[1]; }; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 2d51b99f9e..7ce06a5f0f 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -15262,6 +15262,35 @@ static void csr_handle_iot_ap_no_common_he_rates(struct mac_context *mac, } #endif +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * csr_update_sae_single_pmk_ap_cap() - Function to update sae single pmk ap ie + * @mac: pointer to mac context + * @bss_desc: BSS Descriptor + * @vdev_id: Vdev id + * @akm: Akm type + * + * Return: true if sae single pmk feature is enabled + */ +static void +csr_update_sae_single_pmk_ap_cap(struct mac_context *mac, + struct bss_description *bss_desc, + uint8_t vdev_id, enum csr_akm_type akm) +{ + if (akm == eCSR_AUTH_TYPE_SAE && + mac->mlme_cfg->lfr.sae_single_pmk_feature_enabled) + wlan_mlme_set_sae_single_pmk_bss_cap(mac->psoc, vdev_id, + bss_desc->is_single_pmk); +} +#else +static inline void +csr_update_sae_single_pmk_ap_cap(struct mac_context *mac, + struct bss_description *bss_desc, + uint8_t vdev_id, enum csr_akm_type akm) +{ +} +#endif + /** * The communication between HDD and LIM is thru mailbox (MB). * Both sides will access the data structure "struct join_req". @@ -15414,6 +15443,9 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId, akm = pProfile->negotiatedAuthType; csr_join_req->akm = csr_convert_csr_to_ani_akm_type(akm); + csr_update_sae_single_pmk_ap_cap(mac, pBssDescription, + sessionId, akm); + if (bss_freq <= 2484 && !mac->mlme_cfg->vht_caps.vht_cap_info.b24ghz_band && dot11mode == MLME_DOT11_MODE_11AC) { diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index ede88897ee..4a00b68a65 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -2338,6 +2338,29 @@ static bool csr_is_assoc_disallowed(struct mac_context *mac_ctx, return mbo_ie.assoc_disallowed.present; } +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +/** + * csr_fill_single_pmk_ap_cap_from_scan_entry() - WAP3_SPMK VSIE from scan + * entry + * @bss_desc: BSS Descriptor + * @scan_entry: scan entry + * + * Return: None + */ +static void +csr_fill_single_pmk_ap_cap_from_scan_entry(struct bss_description *bss_desc, + struct scan_cache_entry *scan_entry) +{ + bss_desc->is_single_pmk = util_scan_entry_single_pmk(scan_entry); +} + +#else +static inline void +csr_fill_single_pmk_ap_cap_from_scan_entry(struct bss_description *bss_desc, + struct scan_cache_entry *scan_entry) +{ +} +#endif static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, struct scan_cache_entry *scan_entry, struct tag_csrscan_result **p_result) @@ -2435,6 +2458,9 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, bss_desc->assoc_disallowed = csr_is_assoc_disallowed(mac_ctx, scan_entry); bss_desc->adaptive_11r_ap = scan_entry->adaptive_11r_ap; + + csr_fill_single_pmk_ap_cap_from_scan_entry(bss_desc, scan_entry); + qdf_mem_copy(&bss_desc->mbssid_info, &scan_entry->mbssid_info, sizeof(struct scan_mbssid_info));