qcacld-3.0: Add support for allowed_authmode

Currently, STA doesn't support roam between WPA2 to WPA3
security or vice versa. To support this feature, host sends
list of allowed_authmode. So that Firmware will check and
roam on those authmode.

Fix, add support for allowed_authmode list in ap_profile.

Change-Id: I438a133a434ea12ec34680997ace358fd4910028
CRs-Fixed: 3782230
This commit is contained in:
Srikanth Marepalli 2023-11-06 23:09:45 +05:30 • committed by Ravindra Konda
commit efc7596334
5 changed files with 136 additions and 46 deletions

View file

@ -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];
};
/**

View file

@ -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);

View file

@ -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],

View file

@ -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)

View file

@ -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);