diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h index 2035b9a2e495..9a027bc6a11f 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h @@ -202,6 +202,8 @@ struct wlan_cm_roam_vendor_btm_params { * floor in dB * @bg_rssi_threshold: Value of rssi threshold to trigger roaming * after background scan. + * @num_allowed_authmode: Number of allowerd authmode + * @allowed_authmode: List of allowed authmode other than connected */ struct ap_profile { uint32_t flags; @@ -213,6 +215,8 @@ struct ap_profile { uint32_t rsn_mcastmgmtcipherset; uint32_t rssi_abs_thresh; uint8_t bg_rssi_threshold; + uint32_t num_allowed_authmode; + uint32_t allowed_authmode[WLAN_CRYPTO_AUTH_MAX]; }; /** diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 29bf1c2ccf48..a401cb56ea0e 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -2497,9 +2497,11 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, wmi_roam_score_delta_param *score_delta_param; wmi_roam_cnd_min_rssi_param *min_rssi_param; enum roam_trigger_reason trig_reason; + uint32_t *authmode_list; + int i; len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile); - len += sizeof(*score_param); + len += sizeof(*score_param) + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; if (!wmi_service_enabled(wmi_handle, wmi_service_configure_roam_trigger_param_support)) { @@ -2507,7 +2509,18 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param); len += WMI_TLV_HDR_SIZE; len += NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param); + } else { + len += 2 * WMI_TLV_HDR_SIZE; } + + if (ap_profile->profile.num_allowed_authmode) { + len += WMI_TLV_HDR_SIZE; + len += ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t); + } else { + len += WMI_TLV_HDR_SIZE; + } + buf = wmi_buf_alloc(wmi_handle, len); if (!buf) return QDF_STATUS_E_NOMEM; @@ -2757,7 +2770,58 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle, convert_roam_trigger_reason(trig_reason); min_rssi_param->candidate_min_rssi = ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi; + + buf_ptr += sizeof(*min_rssi_param); + } else { + /* set zero TLV's for roam_score_delta_param_list */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* set zero TLV's for roam_cnd_min_rssi_param_list */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; } + + /* set zero TLV's for roam_cnd_vendor_scoring_param */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* set zero TLV's for owe_ap_profile */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + + /* List of Allowed authmode other than the connected akm */ + if (ap_profile->profile.num_allowed_authmode) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, + (ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t))); + + buf_ptr += WMI_TLV_HDR_SIZE; + + authmode_list = (uint32_t *)buf_ptr; + for (i = 0; i < ap_profile->profile.num_allowed_authmode; i++) + authmode_list[i] = + ap_profile->profile.allowed_authmode[i]; + + wmi_debug("[Allowed Authmode]: num_allowed_authmode: %d", + ap_profile->profile.num_allowed_authmode); + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG, + authmode_list, + ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t)); + buf_ptr += ap_profile->profile.num_allowed_authmode * + sizeof(uint32_t); + } else { + /* set zero TLV's for allowed_authmode */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf_ptr += WMI_TLV_HDR_SIZE; + } + wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0); status = wmi_unified_cmd_send(wmi_handle, buf, len, WMI_ROAM_AP_PROFILE); diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 001524cb863b..6240409f667c 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -20884,6 +20884,12 @@ static void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) hdd_err("Failed to set akm type %0x to crypto component", set_val); + status = wlan_crypto_set_vdev_param(vdev, + WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT, + set_val); + if (QDF_IS_STATUS_ERROR(status)) + hdd_err("Failed to set original akm type %0x to crypto component", + set_val); } /** @@ -20937,8 +20943,11 @@ static void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev, /* Reset to none */ HDD_SET_BIT(set_val, WLAN_CRYPTO_KEY_MGMT_NONE); wlan_crypto_set_vdev_param(vdev, - WLAN_CRYPTO_PARAM_KEY_MGMT, - set_val); + WLAN_CRYPTO_PARAM_KEY_MGMT, + set_val); + wlan_crypto_set_vdev_param(vdev, + WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT, + set_val); } if (req->crypto.n_ciphers_pairwise) { hdd_populate_crypto_cipher_type(req->crypto.ciphers_pairwise[0], diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 7433c5275baa..f495aa4a976a 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2024 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 @@ -1788,9 +1788,9 @@ void lim_fill_join_rsp_ht_caps(struct pe_session *session, #ifdef WLAN_FEATURE_ROAM_OFFLOAD #ifdef WLAN_FEATURE_11W -static void pe_set_rmf_caps(struct mac_context *mac_ctx, - struct pe_session *ft_session, - struct roam_offload_synch_ind *roam_synch) +static void pe_update_crypto_params(struct mac_context *mac_ctx, + struct pe_session *ft_session, + struct roam_offload_synch_ind *roam_synch) { uint8_t *assoc_body; uint16_t len; @@ -1855,9 +1855,10 @@ static void pe_set_rmf_caps(struct mac_context *mac_ctx, lim_get_vdev_rmf_capable(mac_ctx, ft_session); } #else -static inline void pe_set_rmf_caps(struct mac_context *mac_ctx, - struct pe_session *ft_session, - struct roam_offload_synch_ind *roam_synch) +static inline +void pe_update_crypto_params(struct mac_context *mac_ctx, + struct pe_session *ft_session, + struct roam_offload_synch_ind *roam_synch) { } #endif @@ -2624,7 +2625,7 @@ pe_roam_synch_callback(struct mac_context *mac_ctx, /* Next routine will update nss and vdev_nss with AP's capabilities */ lim_fill_ft_session(mac_ctx, bss_desc, ft_session_ptr, session_ptr, roam_sync_ind_ptr->phy_mode); - pe_set_rmf_caps(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); + pe_update_crypto_params(mac_ctx, ft_session_ptr, roam_sync_ind_ptr); /* Next routine may update nss based on dot11Mode */ lim_ft_prepare_add_bss_req(mac_ctx, ft_session_ptr, bss_desc); if (session_ptr->is11Rconnection) diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 30ae3af59a1c..d0a1d23c0fd2 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -10789,23 +10789,6 @@ csr_cm_roam_fill_11w_params(struct mac_context *mac_ctx, } } -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -static void -csr_cm_roam_fill_rsn_caps(struct mac_context *mac, uint8_t vdev_id, - uint16_t *rsn_caps) -{ - tCsrRoamConnectedProfile *profile; - - /* Copy the self RSN capabilities in roam offload request */ - profile = &mac->roam.roamSession[vdev_id].connectedProfile; - *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; - *rsn_caps &= ~WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; - if (profile->MFPRequired) - *rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_REQUIRED; - if (profile->MFPCapable) - *rsn_caps |= WLAN_CRYPTO_RSN_CAP_MFP_ENABLED; -} -#endif #else static inline void csr_update_pmf_cap_from_profile(struct csr_roam_profile *profile, @@ -10817,13 +10800,6 @@ void csr_cm_roam_fill_11w_params(struct mac_context *mac_ctx, uint8_t vdev_id, struct ap_profile_params *req) {} - -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -static inline -void csr_cm_roam_fill_rsn_caps(struct mac_context *mac, uint8_t vdev_id, - uint16_t *rsn_caps) -{} -#endif #endif QDF_STATUS csr_fill_filter_from_vdev_crypto(struct mac_context *mac_ctx, @@ -17995,7 +17971,9 @@ csr_cm_roam_fill_crypto_params(struct mac_context *mac_ctx, struct ap_profile *profile) { struct wlan_objmgr_vdev *vdev; - int32_t uccipher, authmode, mccipher, akm; + int32_t uccipher, authmode, mccipher, akm, key_mgmt; + int32_t num_allowed_authmode = 0; + enum wlan_crypto_key_mgmt i; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, session->vdev_id, @@ -18019,6 +17997,25 @@ csr_cm_roam_fill_crypto_params(struct mac_context *mac_ctx, /* Group cipher suite */ profile->rsn_mcastcipherset = cm_crypto_cipher_wmi_cipher(mccipher); + + /* Get keymgmt from self security info */ + key_mgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_ORIG_KEY_MGMT); + + for (i = 0; i < WLAN_CRYPTO_KEY_MGMT_MAX; i++) { + /* + * Send AKM in allowed list which are not present in connected + * akm + */ + if (QDF_HAS_PARAM(key_mgmt, i) && + num_allowed_authmode < WLAN_CRYPTO_AUTH_MAX) { + profile->allowed_authmode[num_allowed_authmode++] = + cm_crypto_authmode_to_wmi_authmode(authmode, + (key_mgmt & (1 << i)), + uccipher); + } + } + + profile->num_allowed_authmode = num_allowed_authmode; } /** @@ -18608,6 +18605,8 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config( uint16_t rsn_caps = 0; tpCsrNeighborRoamControlInfo roam_info = &mac->roam.neighborRoamInfo[vdev_id]; + struct wlan_objmgr_vdev *vdev; + int32_t crypto_rsn = 0; rso_config->roam_offload_enabled = mac->mlme_cfg->lfr.lfr3_roaming_offload; @@ -18672,16 +18671,29 @@ static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config( (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); final_caps_val = (uint16_t *)&self_caps; - /* - * Self rsn caps aren't sent to firmware, so in case of PMF required, - * the firmware connects to a non PMF AP advertising PMF not required - * in the re-assoc request which violates protocol. - * So send self RSN caps to firmware in roam SCAN offload command to - * let it configure the params in the re-assoc request too. - * Instead of making another infra, send the RSN-CAPS in MSB of - * beacon Caps. - */ - csr_cm_roam_fill_rsn_caps(mac, vdev_id, &rsn_caps); + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, + vdev_id, + WLAN_LEGACY_SME_ID); + if (vdev) { + /* + * Self rsn caps aren't sent to firmware, so in case of PMF + * required, the firmware connects to a non PMF AP advertising + * PMF not required in the re-assoc request which violates + * protocol. So send self RSN caps to firmware in roam SCAN + * offload command to let it configure the params in the + * re-assoc request too. Instead of making another infra, send + * the RSN-CAPS in MSB of beacon Caps. + */ + crypto_rsn = wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_RSN_CAP); + if (crypto_rsn < 0) + sme_err("Invalid RSN capabilities"); + else + rsn_caps = (uint16_t)crypto_rsn; + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + } + rso_config->rso_lfr3_caps.capability = (rsn_caps << RSN_CAPS_SHIFT) | ((*final_caps_val) & 0xFFFF);