diff --git a/components/mlme/core/inc/wlan_mlme_main.h b/components/mlme/core/inc/wlan_mlme_main.h index faa42fa7c9..15beca7ace 100644 --- a/components/mlme/core/inc/wlan_mlme_main.h +++ b/components/mlme/core/inc/wlan_mlme_main.h @@ -186,7 +186,7 @@ struct mlme_legacy_priv { bool roam_reason_better_ap; uint32_t hb_failure_rssi; #ifdef WLAN_FEATURE_FILS_SK - struct wlan_fils_connection_info fils_con_info; + struct wlan_fils_connection_info *fils_con_info; #endif }; diff --git a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c index 71f20de155..4d943ad71b 100644 --- a/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c +++ b/components/mlme/core/src/wlan_mlme_vdev_mgr_interface.c @@ -1071,6 +1071,7 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_create(struct vdev_mlme_obj *vdev_mlme) return QDF_STATUS_E_NOMEM; } + vdev_mlme->ext_vdev_ptr->fils_con_info = NULL; target_if_cm_roam_register_tx_ops( &vdev_mlme->ext_vdev_ptr->cm_roam.tx_ops); @@ -1126,6 +1127,10 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme) mlme_free_self_disconnect_ies(vdev_mlme->vdev); mlme_free_peer_disconnect_ies(vdev_mlme->vdev); mlme_free_sae_auth_retry(vdev_mlme->vdev); + + qdf_mem_free(vdev_mlme->ext_vdev_ptr->fils_con_info); + vdev_mlme->ext_vdev_ptr->fils_con_info = NULL; + qdf_mem_free(vdev_mlme->ext_vdev_ptr); vdev_mlme->ext_vdev_ptr = NULL; diff --git a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h index 7dc8eec888..a34d21e8d0 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_public_struct.h @@ -27,6 +27,7 @@ #include #include #include +#include "wlan_cm_roam_public_struct.h" #define CFG_VALID_CHANNEL_LIST_LEN 100 @@ -524,10 +525,6 @@ struct mlme_ht_info_field_2 { #endif #ifdef WLAN_FEATURE_FILS_SK -#define FILS_MAX_KEYNAME_NAI_LENGTH 253 -#define FILS_MAX_REALM_LEN 255 -#define FILS_MAX_RRK_LENGTH 64 -#define FILS_MAX_RIK_LENGTH FILS_MAX_RRK_LENGTH /** * struct wlan_fils_connection_info - Fils connection parameters @@ -535,9 +532,11 @@ struct mlme_ht_info_field_2 { * authentication algorithm as 4 * @keyname_nai: key name network access identifier * @key_nai_length: key name network access identifier length - * @sequence_number: FILS ERP sequence number + * @erp_sequence_number: FILS ERP sequence number * @r_rk: re-authentication Root Key length * @r_rk_length: reauthentication root keys length + * @rik: Re-authentication integrity key + * @rik_length: Re-Authentication integrity key length * @realm: Realm name * @realm_len: Realm length * @akm_type: FILS connection akm @@ -545,21 +544,27 @@ struct mlme_ht_info_field_2 { * @pmk: Pairwise master key * @pmk_len: Pairwise master key length * @pmkid: Pairwise master key ID + * @fils_ft: FILS FT key + * @fils_ft_len: Length of FILS FT */ struct wlan_fils_connection_info { bool is_fils_connection; uint8_t keyname_nai[FILS_MAX_KEYNAME_NAI_LENGTH]; uint32_t key_nai_length; - uint16_t sequence_number; - uint8_t r_rk[FILS_MAX_RRK_LENGTH]; + uint32_t erp_sequence_number; + uint8_t r_rk[WLAN_FILS_MAX_RRK_LENGTH]; uint32_t r_rk_length; - uint8_t realm[FILS_MAX_REALM_LEN]; + uint8_t rik[WLAN_FILS_MAX_RIK_LENGTH]; + uint32_t rik_length; + uint8_t realm[WLAN_FILS_MAX_REALM_LEN]; uint32_t realm_len; uint8_t akm_type; uint8_t auth_type; uint8_t pmk[MAX_PMK_LEN]; uint8_t pmk_len; uint8_t pmkid[PMKID_LEN]; + uint8_t fils_ft[WLAN_FILS_FT_MAX_LEN]; + uint8_t fils_ft_len; }; #endif diff --git a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c index c6ee7bb950..293a1df190 100644 --- a/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c +++ b/components/target_if/connection_mgr/src/target_if_cm_roam_offload.c @@ -127,6 +127,14 @@ target_if_vdev_set_param(wmi_unified_t wmi_handle, uint32_t vdev_id, return wmi_unified_vdev_set_param_send(wmi_handle, ¶m); } +static QDF_STATUS target_if_cm_roam_scan_offload_mode( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{ + return wmi_unified_roam_scan_offload_mode_cmd(wmi_handle, + rso_mode_cfg); +} + /** * target_if_cm_roam_scan_bmiss_cnt() - set bmiss count to fw * @wmi_handle: wmi handle @@ -353,6 +361,7 @@ target_if_cm_roam_idle_params(wmi_unified_t wmi_handle, uint8_t command, { } #endif + /** * target_if_cm_roam_scan_offload_rssi_thresh() - Send roam scan rssi threshold * commands to wmi @@ -915,6 +924,14 @@ target_if_cm_roam_send_start(struct wlan_objmgr_vdev *vdev, } } + status = target_if_cm_roam_scan_offload_mode(wmi_handle, + &req->rso_config); + if (QDF_IS_STATUS_ERROR(status)) { + target_if_err("vdev:%d Send RSO mode cmd failed", + req->rso_config.vdev_id); + goto end; + } + status = target_if_cm_roam_scan_filter(wmi_handle, ROAM_SCAN_OFFLOAD_START, &req->scan_filter_params); diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c index e20a603d3f..86fa044eec 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c @@ -27,6 +27,7 @@ #include "wlan_cm_tgt_if_tx_api.h" #include "wlan_cm_roam_api.h" #include "wlan_mlme_vdev_mgr_interface.h" +#include "wlan_crypto_global_api.h" /** * cm_roam_scan_bmiss_cnt() - set roam beacon miss count @@ -214,6 +215,83 @@ cm_roam_idle_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, } #endif +#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_FILS_SK) +QDF_STATUS cm_roam_scan_offload_add_fils_params( + struct wlan_objmgr_psoc *psoc, + struct wlan_roam_scan_offload_params *rso_cfg, + uint8_t vdev_id) +{ + QDF_STATUS status; + uint32_t usr_name_len; + struct wlan_fils_connection_info *fils_info; + struct wlan_roam_fils_params *fils_roam_config = + &rso_cfg->fils_roam_config; + + fils_info = wlan_cm_get_fils_connection_info(psoc, vdev_id); + if (!fils_info) + return QDF_STATUS_SUCCESS; + + if (fils_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH || + fils_info->r_rk_length > WLAN_FILS_MAX_RRK_LENGTH) { + mlme_err("Fils info len error: keyname nai len(%d) rrk len(%d)", + fils_info->key_nai_length, fils_info->r_rk_length); + return QDF_STATUS_E_FAILURE; + } + + fils_roam_config->next_erp_seq_num = fils_info->erp_sequence_number; + + usr_name_len = + qdf_str_copy_all_before_char(fils_info->keyname_nai, + sizeof(fils_info->keyname_nai), + fils_roam_config->username, + sizeof(fils_roam_config->username), + '@'); + if (fils_info->key_nai_length <= usr_name_len) { + mlme_err("Fils info len error: key nai len %d, user name len %d", + fils_info->key_nai_length, usr_name_len); + return QDF_STATUS_E_INVAL; + } + + fils_roam_config->username_length = usr_name_len; + qdf_mem_copy(fils_roam_config->rrk, fils_info->r_rk, + fils_info->r_rk_length); + fils_roam_config->rrk_length = fils_info->r_rk_length; + fils_roam_config->realm_len = fils_info->key_nai_length - + fils_roam_config->username_length - 1; + qdf_mem_copy(fils_roam_config->realm, + (fils_info->keyname_nai + + fils_roam_config->username_length + 1), + fils_roam_config->realm_len); + + /* + * Set add FILS tlv true for initial FULL EAP connection and subsequent + * FILS connection. + */ + rso_cfg->add_fils_tlv = true; + mlme_debug("Fils: next_erp_seq_num %d rrk_len %d realm_len:%d", + fils_info->erp_sequence_number, + fils_info->r_rk_length, + fils_info->realm_len); + if (!fils_info->is_fils_connection) + return QDF_STATUS_SUCCESS; + + /* Update rik from crypto to fils roam config buffer */ + status = wlan_crypto_create_fils_rik(fils_info->r_rk, + fils_info->r_rk_length, + fils_info->rik, + &fils_info->rik_length); + qdf_mem_copy(fils_roam_config->rik, fils_info->rik, + fils_info->rik_length); + fils_roam_config->rik_length = fils_info->rik_length; + + fils_roam_config->fils_ft_len = fils_info->fils_ft_len; + qdf_mem_copy(fils_roam_config->fils_ft, fils_info->fils_ft, + fils_info->fils_ft_len); + + return status; +} +#endif + /** * cm_roam_mawc_params() - set roam mawc parameters * @psoc: psoc pointer diff --git a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h index 3e00822018..307cd29c97 100644 --- a/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h +++ b/components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h @@ -25,6 +25,7 @@ #ifndef _WLAN_CM_ROAM_OFFLOAD_H_ #define _WLAN_CM_ROAM_OFFLOAD_H_ +#include "qdf_str.h" #include "wlan_cm_roam_public_struct.h" #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) @@ -112,4 +113,22 @@ cm_roam_fill_rssi_change_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, QDF_STATUS cm_roam_send_disable_config(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, uint8_t cfg); -#endif + +#ifdef ROAM_OFFLOAD_V1 +#if defined(WLAN_FEATURE_ROAM_OFFLOAD) && defined(WLAN_FEATURE_FILS_SK) +QDF_STATUS cm_roam_scan_offload_add_fils_params( + struct wlan_objmgr_psoc *psoc, + struct wlan_roam_scan_offload_params *rso_cfg, + uint8_t vdev_id); +#else +static inline +QDF_STATUS cm_roam_scan_offload_add_fils_params( + struct wlan_objmgr_psoc *psoc, + struct wlan_roam_scan_offload_params *rso_cfg, + uint8_t vdev_id) +{ + return QDF_STATUS_SUCCESS; +} +#endif /* FEATURE_ROAM_OFFLOAD && WLAN_FEATURE_FILS_SK */ +#endif /* ROAM_OFFLOAD_V1 */ +#endif /* _WLAN_CM_ROAM_OFFLOAD_H_ */ diff --git a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h index f104ad0d26..7ac695d5bb 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h +++ b/components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h @@ -293,6 +293,56 @@ wlan_cm_roam_cfg_set_value(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, } #endif +#ifdef WLAN_FEATURE_FILS_SK +/** + * wlan_cm_get_fils_connection_info - Copy fils connection information from + * mlme vdev private object + * @psoc: Pointer to psoc object + * @dst_fils_info: Destination buffer to copy the fils info + * @vdev_id: vdev id + * + * Return: QDF_STATUS + */ +struct wlan_fils_connection_info *wlan_cm_get_fils_connection_info( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); + +/** + * wlan_cm_update_mlme_fils_connection_info - Update FILS connection info + * to mlme vdev private object + * @psoc: Pointer to psoc object + * @src_fils_info: Current profile FILS connection information + * @vdev_id: vdev_id + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_update_mlme_fils_connection_info( + struct wlan_objmgr_psoc *psoc, + struct wlan_fils_connection_info *src_fils_info, + uint8_t vdev_id); + +/** + * wlan_cm_update_fils_ft - Update the FILS FT derived to mlme + * @psoc: Psoc pointer + * @vdev_id: vdev id + * @fils_ft: Pointer to FILS FT + * @fils_ft_len: FILS FT length + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_cm_update_fils_ft(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *fils_ft, + uint8_t fils_ft_len); +#else +static inline +struct wlan_fils_connection_info *wlan_cm_get_fils_connection_info( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + return NULL; +} +#endif + #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * wlan_cm_roam_extract_btm_response() - Extract BTM rsp stats @@ -419,7 +469,6 @@ wlan_cm_roam_get_vendor_btm_params(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, struct wlan_cm_roam_vendor_btm_params *param); - #else static inline void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc, 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 3026d39c67..69428b24d5 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 @@ -88,6 +88,14 @@ #define REASON_ROAM_HANDOFF_DONE 52 #define REASON_ROAM_ABORT 53 +#define FILS_MAX_KEYNAME_NAI_LENGTH 253 +#define WLAN_FILS_MAX_REALM_LEN 255 +#define WLAN_FILS_MAX_RRK_LENGTH 64 +#define WLAN_FILS_MAX_RIK_LENGTH WLAN_FILS_MAX_RRK_LENGTH +#define WLAN_FILS_FT_MAX_LEN 48 + +#define WLAN_MAX_PMK_DUMP_BYTES 6 + /** * enum roam_cfg_param - Type values for roaming parameters used as index * for get/set of roaming config values(pNeighborRoamInfo in legacy) @@ -631,11 +639,8 @@ struct wlan_per_roam_config_req { #define RSSI_MIN_VALUE (-128) #define RSSI_MAX_VALUE (127) -#define WLAN_FILS_MAX_RRK_LENGTH 64 -#define WLAN_FILS_MAX_RIK_LENGTH 64 -#define WLAN_FILS_MAX_REALM_LENGTH 256 +#ifdef WLAN_FEATURE_FILS_SK #define WLAN_FILS_MAX_USERNAME_LENGTH 16 -#define WLAN_FILS_FT_MAX_LEN 48 /** * struct wlan_roam_fils_params - Roaming FILS params @@ -659,11 +664,12 @@ struct wlan_roam_fils_params { uint32_t rrk_length; uint8_t rik[WLAN_FILS_MAX_RIK_LENGTH]; uint32_t rik_length; - uint8_t realm[WLAN_FILS_MAX_REALM_LENGTH]; + uint8_t realm[WLAN_FILS_MAX_REALM_LEN]; uint32_t realm_len; uint8_t fils_ft[WLAN_FILS_FT_MAX_LEN]; uint8_t fils_ft_len; }; +#endif /** * struct wlan_roam_scan_params - Roaming scan parameters @@ -826,6 +832,8 @@ struct wlan_rso_11r_params { bool is_11r_assoc; bool is_adaptive_11r; bool enable_ft_im_roaming; + uint8_t psk_pmk[WMI_ROAM_SCAN_PSK_SIZE]; + uint32_t pmk_len; uint32_t r0kh_id_length; uint8_t r0kh_id[WMI_ROAM_R0KH_ID_MAX_LEN]; struct mobility_domain_info mdid; @@ -868,8 +876,8 @@ struct wlan_roam_scan_offload_params { uint32_t vdev_id; uint8_t is_rso_stop; /* Parameters common for LFR-3.0 and LFR-2.0 */ + bool roaming_scan_policy; struct wlan_roam_scan_mode_params rso_mode_info; - struct wlan_roam_scan_params scan_params; uint32_t assoc_ie_length; uint8_t assoc_ie[MAX_ASSOC_IE_LENGTH]; #ifdef WLAN_FEATURE_ROAM_OFFLOAD @@ -1058,6 +1066,7 @@ struct wlan_roam_start_config { * roam stop * @reason: roaming reason * @middle_of_roaming: in the middle of roaming + * @rso_config: Roam scan mode config * @roam_11k_params: 11k params * @btm_config: btm configuration * @scan_filter_params: roam scan filter parameters @@ -1069,6 +1078,7 @@ struct wlan_roam_start_config { struct wlan_roam_stop_config { uint8_t reason; uint8_t middle_of_roaming; + struct wlan_roam_scan_offload_params rso_config; struct wlan_roam_11k_offload_params roam_11k_params; struct wlan_roam_btm_config btm_config; struct wlan_roam_scan_filter_params scan_filter_params; @@ -1085,6 +1095,7 @@ struct wlan_roam_stop_config { * @scan_filter_params: roam scan filter parameters * @scan_period_params: roam scan period parameters * @rssi_change_params: roam scan rssi change parameters + * @rso_config: roam scan mode configurations * @profile_params: ap profile parameters * @rssi_params: roam scan rssi threshold parameters * @disconnect_params: disconnect params @@ -1096,6 +1107,7 @@ struct wlan_roam_update_config { struct wlan_roam_scan_filter_params scan_filter_params; struct wlan_roam_scan_period_params scan_period_params; struct wlan_roam_rssi_change_params rssi_change_params; + struct wlan_roam_scan_offload_params rso_config; struct ap_profile_params profile_params; struct wlan_roam_offload_scan_rssi_params rssi_params; struct wlan_roam_disconnect_params disconnect_params; diff --git a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c index 69c91c5c20..27c6b5aba9 100644 --- a/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c +++ b/components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c @@ -508,3 +508,116 @@ wlan_cm_roam_cfg_set_value(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, return QDF_STATUS_SUCCESS; } #endif + +#ifdef WLAN_FEATURE_FILS_SK +QDF_STATUS wlan_cm_update_mlme_fils_connection_info( + struct wlan_objmgr_psoc *psoc, + struct wlan_fils_connection_info *src_fils_info, + uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_FAILURE; + } + + if (!src_fils_info) { + qdf_mem_free(mlme_priv->fils_con_info); + mlme_priv->fils_con_info = NULL; + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_SUCCESS; + } + + if (mlme_priv->fils_con_info) + qdf_mem_free(mlme_priv->fils_con_info); + + mlme_priv->fils_con_info = + qdf_mem_malloc(sizeof(struct wlan_fils_connection_info)); + if (!mlme_priv->fils_con_info) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(mlme_priv->fils_con_info, src_fils_info, + sizeof(struct wlan_fils_connection_info)); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return QDF_STATUS_SUCCESS; +} + +struct wlan_fils_connection_info *wlan_cm_get_fils_connection_info( + struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return NULL; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return NULL; + } + + if (!mlme_priv->fils_con_info) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return NULL; + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return mlme_priv->fils_con_info; +} + +QDF_STATUS wlan_cm_update_fils_ft(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *fils_ft, + uint8_t fils_ft_len) +{ + struct wlan_objmgr_vdev *vdev; + struct mlme_legacy_priv *mlme_priv; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, + WLAN_MLME_NB_ID); + if (!vdev) { + mlme_err("vdev object is NULL"); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev); + if (!mlme_priv) { + mlme_err("vdev legacy private object is NULL"); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_FAILURE; + } + + if (!mlme_priv->fils_con_info || !fils_ft || !fils_ft_len || + !mlme_priv->fils_con_info->is_fils_connection) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + return QDF_STATUS_E_FAILURE; + } + + mlme_priv->fils_con_info->fils_ft_len = fils_ft_len; + qdf_mem_copy(mlme_priv->fils_con_info->fils_ft, fils_ft, fils_ft_len); + wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_NB_ID); + + return QDF_STATUS_SUCCESS; +} +#endif diff --git a/components/wmi/inc/wmi_unified_roam_api.h b/components/wmi/inc/wmi_unified_roam_api.h index 9004cf87ff..7a0daefa39 100644 --- a/components/wmi/inc/wmi_unified_roam_api.h +++ b/components/wmi/inc/wmi_unified_roam_api.h @@ -270,7 +270,22 @@ QDF_STATUS wmi_unified_vdev_set_pcl_cmd(wmi_unified_t wmi_handle, struct set_pcl_cmd_params *params); #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ -#ifndef ROAM_OFFLOAD_V1 +#ifdef ROAM_OFFLOAD_V1 +/** + * wmi_unified_roam_scan_offload_mode_cmd() - set roam scan parameters + * @wmi_handle: wmi handle + * @scan_cmd_fp: scan related parameters + * @rso_cfg: roam scan offload parameters + * + * This function reads the incoming @rso_cfg and fill in the destination + * WMI structure and send down the roam scan configs down to the firmware + * + * Return: QDF_STATUS_SUCCESS on success and QDF_STATUS_E_FAILURE for failure + */ +QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *rso_cfg); +#else /** * wmi_unified_roam_scan_offload_mode_cmd() - set roam scan parameters * @wmi_handle: wmi handle diff --git a/components/wmi/src/wmi_unified_roam_api.c b/components/wmi/src/wmi_unified_roam_api.c index c2c85e8597..1a511853f9 100644 --- a/components/wmi/src/wmi_unified_roam_api.c +++ b/components/wmi/src/wmi_unified_roam_api.c @@ -209,7 +209,18 @@ QDF_STATUS wmi_unified_vdev_set_pcl_cmd(wmi_unified_t wmi_handle, } #endif /* WLAN_FEATURE_ROAM_OFFLOAD */ -#ifndef ROAM_OFFLOAD_V1 +#ifdef ROAM_OFFLOAD_V1 +QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *rso_cfg) +{ + if (wmi_handle->ops->send_roam_scan_offload_mode_cmd) + return wmi_handle->ops->send_roam_scan_offload_mode_cmd( + wmi_handle, rso_cfg); + + return QDF_STATUS_E_FAILURE; +} +#else QDF_STATUS wmi_unified_roam_scan_offload_mode_cmd( wmi_unified_t wmi_handle, wmi_start_scan_cmd_fixed_param *scan_cmd_fp, diff --git a/components/wmi/src/wmi_unified_roam_tlv.c b/components/wmi/src/wmi_unified_roam_tlv.c index 5f89ace942..e950f2e838 100644 --- a/components/wmi/src/wmi_unified_roam_tlv.c +++ b/components/wmi/src/wmi_unified_roam_tlv.c @@ -1644,19 +1644,19 @@ static inline uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, #ifdef WLAN_FEATURE_ROAM_OFFLOAD /** * fill_roam_offload_11r_params() - Fill roam scan params to send it to fw - * @auth_mode: Authentication mode + * @akm: Authentication key management type * @roam_offload_11r: TLV to be filled with 11r params * @roam_req: roam request param */ static void -fill_roam_offload_11r_params(uint32_t auth_mode, +fill_roam_offload_11r_params(uint32_t akm, wmi_roam_11r_offload_tlv_param *roam_offload_11r, struct roam_offload_scan_params *roam_req) { uint8_t *psk_msk, len; - if (auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA256 || - auth_mode == WMI_AUTH_FT_RSNA_FILS_SHA384) { + if (akm == WMI_AUTH_FT_RSNA_FILS_SHA256 || + akm == WMI_AUTH_FT_RSNA_FILS_SHA384) { psk_msk = roam_req->roam_fils_params.fils_ft; len = roam_req->roam_fils_params.fils_ft_len; } else { @@ -1707,9 +1707,645 @@ wmi_fill_sae_single_pmk_param(struct roam_offload_scan_params *params, { } #endif +#endif /* ROAM_OFFLOAD_V1 */ #define ROAM_OFFLOAD_PMK_EXT_BYTES 16 +#ifdef ROAM_OFFLOAD_V1 +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +/** + * wmi_fill_roam_offload_11r_params() - Fill roam scan params to send it to fw + * @akm: Authentication key management type + * @roam_offload_11r: TLV to be filled with 11r params + * @roam_req: roam request param + */ +static void wmi_fill_roam_offload_11r_params( + uint32_t akm, + wmi_roam_11r_offload_tlv_param *roam_offload_11r, + struct wlan_roam_scan_offload_params *roam_req) +{ + struct wlan_rso_11r_params *src_11r_params; + uint8_t *psk_msk, len; + + src_11r_params = &roam_req->rso_11r_info; + + if (akm == WMI_AUTH_FT_RSNA_FILS_SHA256 || + akm == WMI_AUTH_FT_RSNA_FILS_SHA384) { + psk_msk = roam_req->fils_roam_config.fils_ft; + len = roam_req->fils_roam_config.fils_ft_len; + } else { + psk_msk = src_11r_params->psk_pmk; + len = src_11r_params->pmk_len; + } + + /* + * For SHA384 based akm, the pmk length is 48 bytes. So fill + * first 32 bytes in roam_offload_11r->psk_msk and the remaining + * bytes in roam_offload_11r->psk_msk_ext buffer + */ + roam_offload_11r->psk_msk_len = len > ROAM_OFFLOAD_PSK_MSK_BYTES ? + ROAM_OFFLOAD_PSK_MSK_BYTES : len; + qdf_mem_copy(roam_offload_11r->psk_msk, psk_msk, + roam_offload_11r->psk_msk_len); + roam_offload_11r->psk_msk_ext_len = 0; + + if (len > ROAM_OFFLOAD_PSK_MSK_BYTES) { + roam_offload_11r->psk_msk_ext_len = + len - roam_offload_11r->psk_msk_len; + qdf_mem_copy(roam_offload_11r->psk_msk_ext, + &psk_msk[roam_offload_11r->psk_msk_len], + roam_offload_11r->psk_msk_ext_len); + } +} + +/** + * wmi_is_ft_akm() - Check if the akm is FT akm. Based on the AKM 11r params + * will be sent for lfr-3.0 roaming offload + * @akm: AKM negotiated for the connection + * @roam_req: roam request sent to firmware + * + * Return: true if the akm is 11r based + */ +static bool wmi_is_ft_akm(int akm, + struct wlan_roam_scan_offload_params *roam_req) +{ + switch (akm) { + case WMI_AUTH_FT_RSNA: + case WMI_AUTH_FT_RSNA_PSK: + case WMI_AUTH_FT_RSNA_SAE: + case WMI_AUTH_FT_RSNA_SUITE_B_8021X_SHA384: + case WMI_AUTH_FT_RSNA_FILS_SHA256: + case WMI_AUTH_FT_RSNA_FILS_SHA384: + return true; + case WMI_AUTH_OPEN: + if (roam_req->rso_11r_info.mdid.mdie_present && + roam_req->rso_11r_info.is_11r_assoc) + return true; + + break; + default: + wmi_debug("Unknown akm:%d", akm); + return false; + } + + return false; +} + +/** + * wmi_get_rso_cmd_buf_len() - calculate the length needed to allocate buffer + * for RSO mode command + * @roam_req: roam request parameters + */ +static uint32_t +wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params *roam_req) +{ + wmi_tlv_buf_len_param *assoc_ies; + uint32_t buf_len; + uint32_t fils_tlv_len = 0; + int akm = roam_req->akm; + + /* + * Allocate room for wmi_roam_offload_tlv_param and + * 11i or 11r or ese roam offload tlv param + * Todo: Test if below headroom of 2 TLV header is needed + */ + buf_len = (2 * WMI_TLV_HDR_SIZE); + + if (roam_req->is_rso_stop || + !roam_req->roam_offload_enabled) { + buf_len += (4 * WMI_TLV_HDR_SIZE); + + if (!roam_req->is_rso_stop) + wmi_debug("vdev[%d]: %s roam offload: %d", + roam_req->is_rso_stop ? "RSO stop cmd." : "", + roam_req->roam_offload_enabled); + + return buf_len; + } + + wmi_debug("wmi akm = %d", akm); + + buf_len += sizeof(wmi_roam_offload_tlv_param); + buf_len += 2 * WMI_TLV_HDR_SIZE; + + if ((akm != WMI_AUTH_OPEN || roam_req->rso_ese_info.is_ese_assoc || + wmi_is_ft_akm(akm, roam_req)) && akm != WMI_AUTH_NONE) { + if (roam_req->rso_ese_info.is_ese_assoc) + buf_len += sizeof(wmi_roam_ese_offload_tlv_param); + else if (wmi_is_ft_akm(akm, roam_req)) + buf_len += sizeof(wmi_roam_11r_offload_tlv_param); + else + buf_len += sizeof(wmi_roam_11i_offload_tlv_param); + } + + buf_len += (sizeof(*assoc_ies) + (2 * WMI_TLV_HDR_SIZE) + + roundup(roam_req->assoc_ie_length, sizeof(uint32_t))); + + if (roam_req->add_fils_tlv) { + fils_tlv_len = sizeof(wmi_roam_fils_offload_tlv_param); + buf_len += WMI_TLV_HDR_SIZE + fils_tlv_len; + } + + roam_req->rso_mode_info.roam_scan_mode |= + WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; + + return buf_len; +} + +#if defined(WLAN_FEATURE_FILS_SK) +/** + * wmi_add_fils_tlv() - Add FILS TLV to roam scan offload command + * @wmi_handle: wmi handle + * @roam_req: Roam scan offload params + * @buf_ptr: command buffer to send + * @fils_tlv_len: fils tlv length + * + * Return: Updated buffer pointer + */ +static uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *roam_req, + uint8_t *buf_ptr, uint32_t fils_tlv_len) +{ + wmi_roam_fils_offload_tlv_param *fils_tlv; + wmi_erp_info *erp_info; + struct wlan_roam_fils_params *roam_fils_params; + + if (!roam_req->add_fils_tlv) + return buf_ptr; + + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, + sizeof(*fils_tlv)); + buf_ptr += WMI_TLV_HDR_SIZE; + + fils_tlv = (wmi_roam_fils_offload_tlv_param *)buf_ptr; + WMITLV_SET_HDR(&fils_tlv->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_fils_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN + (wmi_roam_fils_offload_tlv_param)); + + roam_fils_params = &roam_req->fils_roam_config; + erp_info = (wmi_erp_info *)(&fils_tlv->vdev_erp_info); + + erp_info->username_length = roam_fils_params->username_length; + qdf_mem_copy(erp_info->username, roam_fils_params->username, + erp_info->username_length); + + erp_info->next_erp_seq_num = roam_fils_params->next_erp_seq_num; + + erp_info->rRk_length = roam_fils_params->rrk_length; + qdf_mem_copy(erp_info->rRk, roam_fils_params->rrk, + erp_info->rRk_length); + + erp_info->rIk_length = roam_fils_params->rik_length; + qdf_mem_copy(erp_info->rIk, roam_fils_params->rik, + erp_info->rIk_length); + + erp_info->realm_len = roam_fils_params->realm_len; + qdf_mem_copy(erp_info->realm, roam_fils_params->realm, + erp_info->realm_len); + + buf_ptr += sizeof(*fils_tlv); + return buf_ptr; +} +#else +static inline +uint8_t *wmi_add_fils_tlv(wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *roam_req, + uint8_t *buf_ptr, uint32_t fils_tlv_len) +{ + return buf_ptr; +} +#endif + +#ifdef WLAN_SAE_SINGLE_PMK +static inline void +wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params *src_11i, + wmi_roam_11i_offload_tlv_param *roam_offload_11i) +{ + if (src_11i->is_sae_same_pmk) + roam_offload_11i->flags |= + 1 << WMI_ROAM_OFFLOAD_FLAG_SAE_SAME_PMKID; +} +#else +static inline void +wmi_fill_sae_single_pmk_param(struct wlan_rso_11i_params *src_11i, + wmi_roam_11i_offload_tlv_param *roam_offload_11i) +{} +#endif + +static QDF_STATUS +wmi_fill_rso_tlvs(wmi_unified_t wmi_handle, uint8_t *buf, + struct wlan_roam_scan_offload_params *roam_req) +{ + wmi_roam_offload_tlv_param *roam_offload_params; + wmi_roam_11i_offload_tlv_param *roam_offload_11i; + wmi_roam_11r_offload_tlv_param *roam_offload_11r; + wmi_roam_ese_offload_tlv_param *roam_offload_ese; + wmi_tlv_buf_len_param *assoc_ies; + uint32_t fils_tlv_len = 0; + int akm = roam_req->akm; + struct wlan_rso_lfr3_params *src_lfr3_params = + &roam_req->rso_lfr3_params; + struct wlan_rso_lfr3_caps *src_lfr3_caps = + &roam_req->rso_lfr3_caps; + struct wlan_rso_11i_params *src_11i_info = + &roam_req->rso_11i_info; + struct wlan_rso_ese_params *src_ese_info = + &roam_req->rso_ese_info; + struct wlan_rso_11r_params *src_11r_info = + &roam_req->rso_11r_info; + + /* For RSO stop command, dont fill 11i, 11r or ese tlv */ + if (roam_req->is_rso_stop || !roam_req->roam_offload_enabled) { + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + WMITLV_GET_STRUCT_TLVLEN(0)); + buf += WMI_TLV_HDR_SIZE; + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_BYTE, + WMITLV_GET_STRUCT_TLVLEN(0)); + + return QDF_STATUS_SUCCESS; + } + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_offload_tlv_param)); + + buf += WMI_TLV_HDR_SIZE; + roam_offload_params = (wmi_roam_offload_tlv_param *)buf; + WMITLV_SET_HDR(buf, + WMITLV_TAG_STRUC_wmi_roam_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_offload_tlv_param)); + + roam_offload_params->prefer_5g = src_lfr3_params->prefer_5ghz; + roam_offload_params->rssi_cat_gap = src_lfr3_params->roam_rssi_cat_gap; + roam_offload_params->select_5g_margin = + src_lfr3_params->select_5ghz_margin; + roam_offload_params->handoff_delay_for_rx = + src_lfr3_params->ho_delay_for_rx; + roam_offload_params->max_mlme_sw_retries = + src_lfr3_params->roam_retry_count; + roam_offload_params->no_ack_timeout = + src_lfr3_params->roam_preauth_no_ack_timeout; + roam_offload_params->reassoc_failure_timeout = + src_lfr3_params->reassoc_failure_timeout; + roam_offload_params->roam_candidate_validity_time = + src_lfr3_params->rct_validity_timer; + roam_offload_params->roam_to_current_bss_disable = + src_lfr3_params->disable_self_roam; + + /* Fill the capabilities */ + roam_offload_params->capability = src_lfr3_caps->capability; + roam_offload_params->ht_caps_info = src_lfr3_caps->ht_caps_info; + roam_offload_params->ampdu_param = src_lfr3_caps->ampdu_param; + roam_offload_params->ht_ext_cap = src_lfr3_caps->ht_ext_cap; + roam_offload_params->ht_txbf = src_lfr3_caps->ht_txbf; + roam_offload_params->asel_cap = src_lfr3_caps->asel_cap; + roam_offload_params->qos_caps = src_lfr3_caps->qos_caps; + roam_offload_params->qos_enabled = src_lfr3_caps->qos_enabled; + roam_offload_params->wmm_caps = src_lfr3_caps->wmm_caps; + qdf_mem_copy((uint8_t *)roam_offload_params->mcsset, + (uint8_t *)src_lfr3_caps->mcsset, + ROAM_OFFLOAD_NUM_MCS_SET); + + buf += sizeof(wmi_roam_offload_tlv_param); + /* + * The TLV's are in the order of 11i, 11R, ESE. Hence, + * they are filled in the same order.Depending on the + * authentication type, the other mode TLV's are nullified + * and only headers are filled. + */ + if (akm != WMI_AUTH_NONE && + (wmi_is_ft_akm(akm, roam_req) || + roam_req->rso_ese_info.is_ese_assoc)) { + if (roam_req->rso_ese_info.is_ese_assoc) { + /* Fill the length of 11i, 11r TLV as 0 */ + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + /* Start filling the ESE TLV */ + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_ese_offload_tlv_param)); + buf += WMI_TLV_HDR_SIZE; + roam_offload_ese = + (wmi_roam_ese_offload_tlv_param *)buf; + qdf_mem_copy(roam_offload_ese->krk, src_ese_info->krk, + sizeof(src_ese_info->krk)); + qdf_mem_copy(roam_offload_ese->btk, src_ese_info->btk, + sizeof(src_ese_info->btk)); + + WMITLV_SET_HDR(&roam_offload_ese->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_ese_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_ese_offload_tlv_param)); + + buf += sizeof(wmi_roam_ese_offload_tlv_param); + } else if (wmi_is_ft_akm(akm, roam_req)) { + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_11r_offload_tlv_param)); + buf += WMI_TLV_HDR_SIZE; + + roam_offload_11r = + (wmi_roam_11r_offload_tlv_param *)buf; + + roam_offload_11r->r0kh_id_len = + src_11r_info->r0kh_id_length; + qdf_mem_copy(roam_offload_11r->r0kh_id, + src_11r_info->r0kh_id, + src_11r_info->r0kh_id_length); + + wmi_fill_roam_offload_11r_params(akm, roam_offload_11r, + roam_req); + + roam_offload_11r->mdie_present = + src_11r_info->mdid.mdie_present; + roam_offload_11r->mdid = + src_11r_info->mdid.mobility_domain; + roam_offload_11r->adaptive_11r = + src_11r_info->is_adaptive_11r; + roam_offload_11r->ft_im_for_deauth = + src_11r_info->enable_ft_im_roaming; + + if (akm == WMI_AUTH_OPEN) { + /* + * If FT-Open ensure pmk length + * and r0khid len are zero + */ + roam_offload_11r->r0kh_id_len = 0; + roam_offload_11r->psk_msk_len = 0; + } + + WMITLV_SET_HDR(&roam_offload_11r->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_11r_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_11r_offload_tlv_param)); + + buf += sizeof(wmi_roam_11r_offload_tlv_param); + /* Set ESE TLV len to 0*/ + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + wmi_debug("vdev[%d] 11r TLV psk_msk_len = %d psk_msk_ext:%d", + roam_req->vdev_id, + roam_offload_11r->psk_msk_len, + roam_offload_11r->psk_msk_ext_len); + if (roam_offload_11r->psk_msk_len) + QDF_TRACE_HEX_DUMP( + QDF_MODULE_ID_WMI, + QDF_TRACE_LEVEL_DEBUG, + roam_offload_11r->psk_msk, + WLAN_MAX_PMK_DUMP_BYTES); + + if (roam_offload_11r->psk_msk_ext_len) + QDF_TRACE_HEX_DUMP( + QDF_MODULE_ID_WMI, + QDF_TRACE_LEVEL_DEBUG, + roam_offload_11r->psk_msk_ext + + (roam_offload_11r->psk_msk_ext_len - + WLAN_MAX_PMK_DUMP_BYTES), + WLAN_MAX_PMK_DUMP_BYTES); + } else { + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, + sizeof(wmi_roam_11i_offload_tlv_param)); + buf += WMI_TLV_HDR_SIZE; + + roam_offload_11i = + (wmi_roam_11i_offload_tlv_param *)buf; + + if (src_11i_info->roam_key_mgmt_offload_enabled && + src_11i_info->fw_okc) + WMI_SET_ROAM_OFFLOAD_OKC_ENABLED( + roam_offload_11i->flags); + else + WMI_SET_ROAM_OFFLOAD_OKC_DISABLED( + roam_offload_11i->flags); + + if (src_11i_info->roam_key_mgmt_offload_enabled && + src_11i_info->fw_pmksa_cache) + WMI_SET_ROAM_OFFLOAD_PMK_CACHE_ENABLED( + roam_offload_11i->flags); + else + WMI_SET_ROAM_OFFLOAD_PMK_CACHE_DISABLED( + roam_offload_11i->flags); + + wmi_fill_sae_single_pmk_param(src_11i_info, + roam_offload_11i); + + roam_offload_11i->pmk_len = + src_11i_info->pmk_len > ROAM_OFFLOAD_PMK_BYTES ? + ROAM_OFFLOAD_PMK_BYTES : src_11i_info->pmk_len; + qdf_mem_copy(roam_offload_11i->pmk, + src_11i_info->psk_pmk, + roam_offload_11i->pmk_len); + + roam_offload_11i->pmk_ext_len = + src_11i_info->pmk_len > ROAM_OFFLOAD_PMK_BYTES ? + ROAM_OFFLOAD_PMK_EXT_BYTES : 0; + qdf_mem_copy( + roam_offload_11i->pmk_ext, + &src_11i_info->psk_pmk[ROAM_OFFLOAD_PMK_BYTES], + roam_offload_11i->pmk_ext_len); + + WMITLV_SET_HDR(&roam_offload_11i->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_11i_offload_tlv_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_11i_offload_tlv_param)); + + buf += sizeof(wmi_roam_11i_offload_tlv_param); + + /* + * Set 11r TLV len to 0, since security profile is not + * FT + */ + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + /* + * Set ESE TLV len to 0 since security profile is not + * ESE + */ + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + wmi_info("LFR3: vdev:%d pmk_len = %d pmksa caching:%d OKC:%d sae_same_pmk:%d key_mgmt_offload:%d", + roam_req->vdev_id, roam_offload_11i->pmk_len, + src_11i_info->fw_pmksa_cache, + src_11i_info->fw_okc, + src_11i_info->is_sae_same_pmk, + src_11i_info->roam_key_mgmt_offload_enabled); + if (roam_offload_11i->pmk_len) + QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMI, + QDF_TRACE_LEVEL_DEBUG, + roam_offload_11i->pmk, + WLAN_MAX_PMK_DUMP_BYTES); + } + } else { + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, 0); + buf += WMI_TLV_HDR_SIZE; + } + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_STRUC, sizeof(*assoc_ies)); + buf += WMI_TLV_HDR_SIZE; + + assoc_ies = (wmi_tlv_buf_len_param *)buf; + WMITLV_SET_HDR(&assoc_ies->tlv_header, + WMITLV_TAG_STRUC_wmi_tlv_buf_len_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_tlv_buf_len_param)); + assoc_ies->buf_len = roam_req->assoc_ie_length; + + buf += sizeof(*assoc_ies); + + WMITLV_SET_HDR(buf, WMITLV_TAG_ARRAY_BYTE, + roundup(assoc_ies->buf_len, sizeof(uint32_t))); + buf += WMI_TLV_HDR_SIZE; + + if (assoc_ies->buf_len != 0) + qdf_mem_copy(buf, roam_req->assoc_ie, assoc_ies->buf_len); + + buf += qdf_roundup(assoc_ies->buf_len, sizeof(uint32_t)); + buf = wmi_add_fils_tlv(wmi_handle, roam_req, buf, fils_tlv_len); + + return QDF_STATUS_SUCCESS; +} +#else +static inline +uint32_t wmi_get_rso_buf_len(struct wlan_roam_scan_offload_params *roam_req) +{ + return 0; +} + +static inline QDF_STATUS +wmi_fill_rso_tlvs(wmi_unified_t wmi_handle, uint8_t *buf_ptr, + struct wlan_roam_scan_offload_params *roam_req) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw + * @wmi_handle: wmi handle + * @scan_cmd_fp: start scan command ptr + * @roam_req: roam request param + * + * send WMI_ROAM_SCAN_MODE TLV to firmware. It has a piggyback + * of WMI_ROAM_SCAN_MODE. + * + * Return: QDF status + */ +static QDF_STATUS +send_roam_scan_offload_mode_cmd_tlv( + wmi_unified_t wmi_handle, + struct wlan_roam_scan_offload_params *rso_req) +{ + wmi_buf_t buf = NULL; + QDF_STATUS status; + size_t len; + uint8_t *buf_ptr; + wmi_roam_scan_mode_fixed_param *roam_scan_mode_fp; + wmi_start_scan_cmd_fixed_param *scan_cmd_fp; + struct wlan_roam_scan_mode_params *src_rso_mode_info = NULL; + + /* + * Need to create a buf with roam_scan command at + * front and piggyback with scan command + */ + len = sizeof(wmi_roam_scan_mode_fixed_param) + + sizeof(wmi_start_scan_cmd_fixed_param); + len += wmi_get_rso_buf_len(rso_req); + + if (rso_req->rso_mode_info.roam_scan_mode == + (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) + len = sizeof(wmi_roam_scan_mode_fixed_param); + + buf = wmi_buf_alloc(wmi_handle, len); + if (!buf) + return QDF_STATUS_E_NOMEM; + + buf_ptr = (uint8_t *)wmi_buf_data(buf); + + src_rso_mode_info = &rso_req->rso_mode_info; + roam_scan_mode_fp = (wmi_roam_scan_mode_fixed_param *)buf_ptr; + WMITLV_SET_HDR( + &roam_scan_mode_fp->tlv_header, + WMITLV_TAG_STRUC_wmi_roam_scan_mode_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_roam_scan_mode_fixed_param)); + + roam_scan_mode_fp->min_delay_roam_trigger_reason_bitmask = + src_rso_mode_info->min_delay_roam_trigger_bitmask; + roam_scan_mode_fp->min_delay_btw_scans = + WMI_SEC_TO_MSEC(src_rso_mode_info->min_delay_btw_scans); + roam_scan_mode_fp->roam_scan_mode = src_rso_mode_info->roam_scan_mode; + roam_scan_mode_fp->vdev_id = rso_req->vdev_id; + wmi_debug("vdev_id:%d roam scan mode: %d", rso_req->vdev_id, + src_rso_mode_info->roam_scan_mode); + /* + * For supplicant disabled roaming, all other roam triggers are disabled + * so send only roam scan mode Fixed param in the command + */ + if (src_rso_mode_info->roam_scan_mode == + (WMI_ROAM_SCAN_MODE_NONE | WMI_ROAM_SCAN_MODE_ROAMOFFLOAD)) { + roam_scan_mode_fp->flags |= + WMI_ROAM_SCAN_MODE_FLAG_REPORT_STATUS; + goto send_roam_scan_mode_cmd; + } + + /* Fill in scan parameters suitable for roaming scan */ + buf_ptr += sizeof(wmi_roam_scan_mode_fixed_param); + WMITLV_SET_HDR( + buf_ptr, + WMITLV_TAG_STRUC_wmi_start_scan_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_start_scan_cmd_fixed_param)); + + scan_cmd_fp = (wmi_start_scan_cmd_fixed_param *)buf_ptr; + /* Configure roaming scan behavior (DBS/Non-DBS scan) */ + if (rso_req->roaming_scan_policy) + scan_cmd_fp->scan_ctrl_flags_ext |= + WMI_SCAN_DBS_POLICY_FORCE_NONDBS; + else + scan_cmd_fp->scan_ctrl_flags_ext |= + WMI_SCAN_DBS_POLICY_DEFAULT; + + /* Ensure there is no additional IEs */ + scan_cmd_fp->ie_len = 0; + buf += sizeof(wmi_start_scan_cmd_fixed_param); + + status = wmi_fill_rso_tlvs(wmi_handle, buf_ptr, rso_req); + if (QDF_IS_STATUS_ERROR(status)) { + wmi_buf_free(buf); + return status; + } + +send_roam_scan_mode_cmd: + wmi_mtrace(WMI_ROAM_SCAN_MODE, NO_SESSION, 0); + status = wmi_unified_cmd_send(wmi_handle, buf, + len, WMI_ROAM_SCAN_MODE); + if (QDF_IS_STATUS_ERROR(status)) + wmi_buf_free(buf); + + return status; +} +#else /** * send_roam_scan_offload_mode_cmd_tlv() - send roam scan mode request to fw * @wmi_handle: wmi handle @@ -1898,12 +2534,15 @@ send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, (auth_mode == WMI_AUTH_OPEN && roam_req->mdid.mdie_present && roam_req->is_11r_assoc))) { if (roam_req->is_ese_assoc) { + /* Fill the length of 11i, 11r TLV as 0 */ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, WMITLV_GET_STRUCT_TLVLEN(0)); buf_ptr += WMI_TLV_HDR_SIZE; WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, WMITLV_GET_STRUCT_TLVLEN(0)); buf_ptr += WMI_TLV_HDR_SIZE; + + /* Start filling the ESE TLV */ WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(wmi_roam_ese_offload_tlv_param)); buf_ptr += WMI_TLV_HDR_SIZE; @@ -1957,6 +2596,8 @@ send_roam_scan_offload_mode_cmd_tlv(wmi_unified_t wmi_handle, roam_req->is_adaptive_11r; roam_offload_11r->ft_im_for_deauth = roam_req->enable_ft_im_roaming; + roam_offload_11r->ft_im_for_deauth = + roam_req->enable_ft_im_roaming; if (auth_mode == WMI_AUTH_OPEN) { /* @@ -3272,10 +3913,8 @@ void wmi_roam_attach_tlv(wmi_unified_t wmi_handle) ops->send_roam_mawc_params_cmd = send_roam_mawc_params_cmd_tlv; ops->send_roam_scan_filter_cmd = send_roam_scan_filter_cmd_tlv; -#ifndef ROAM_OFFLOAD_V1 ops->send_roam_scan_offload_mode_cmd = send_roam_scan_offload_mode_cmd_tlv; -#endif ops->send_roam_scan_offload_ap_profile_cmd = send_roam_scan_offload_ap_profile_cmd_tlv; ops->send_roam_scan_offload_cmd = send_roam_scan_offload_cmd_tlv; diff --git a/core/cds/inc/cds_config.h b/core/cds/inc/cds_config.h index 75b30bce1c..4a0872bf23 100644 --- a/core/cds/inc/cds_config.h +++ b/core/cds/inc/cds_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2020 The Linux Foundation. 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 @@ -106,27 +106,4 @@ struct cds_config_info { uint32_t num_vdevs; bool enable_tx_compl_tsf64; }; - -#ifdef WLAN_FEATURE_FILS_SK -#define FILS_MAX_KEYNAME_NAI_LENGTH 253 -#define FILS_MAX_REALM_LEN 255 -#define FILS_MAX_RRK_LENGTH 64 -#define FILS_MAX_RIK_LENGTH FILS_MAX_RRK_LENGTH - -struct cds_fils_connection_info { - bool is_fils_connection; - uint8_t keyname_nai[FILS_MAX_KEYNAME_NAI_LENGTH]; - uint32_t key_nai_length; - uint16_t sequence_number; - uint8_t r_rk[FILS_MAX_RRK_LENGTH]; - uint32_t r_rk_length; - uint8_t realm[FILS_MAX_REALM_LEN]; - uint32_t realm_len; - uint8_t akm_type; - uint8_t auth_type; - uint8_t pmk[MAX_PMK_LEN]; - uint8_t pmk_len; - uint8_t pmkid[PMKID_LEN]; -}; -#endif #endif /* !defined( __CDS_CONFIG_H ) */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 94c01c7aa2..6a75c88b5e 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -18910,7 +18910,7 @@ static int wlan_hdd_cfg80211_set_auth_type(struct hdd_adapter *adapter, (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) static bool hdd_validate_fils_info_ptr(struct csr_roam_profile *roam_profile) { - struct cds_fils_connection_info *fils_con_info; + struct wlan_fils_connection_info *fils_con_info; fils_con_info = roam_profile->fils_con_info; if (!fils_con_info) { @@ -18943,8 +18943,8 @@ static bool wlan_hdd_fils_data_in_limits(struct cfg80211_connect_params *req) req->fils_erp_username_len, req->fils_erp_rrk_len, req->fils_erp_realm_len); - if (req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH || - req->fils_erp_realm_len > FILS_MAX_REALM_LEN || + if (req->fils_erp_rrk_len > WLAN_FILS_MAX_RRK_LENGTH || + req->fils_erp_realm_len > WLAN_FILS_MAX_REALM_LEN || req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) { hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu", req->fils_erp_username_len, req->fils_erp_rrk_len, @@ -19022,7 +19022,7 @@ static int wlan_hdd_cfg80211_set_fils_config(struct hdd_adapter *adapter, goto fils_conn_fail; roam_profile->fils_con_info->is_fils_connection = true; - roam_profile->fils_con_info->sequence_number = + roam_profile->fils_con_info->erp_sequence_number = (req->fils_erp_next_seq_num + 1); roam_profile->fils_con_info->auth_type = auth_type; @@ -23365,7 +23365,7 @@ hdd_update_connect_params_fils_info(struct hdd_adapter *adapter, QDF_STATUS status; mac_handle_t mac_handle; struct csr_roam_profile *roam_profile; - struct cds_fils_connection_info *fils_info; + struct wlan_fils_connection_info *fils_info; enum eAniAuthType auth_type; roam_profile = hdd_roam_profile(adapter); @@ -23399,10 +23399,10 @@ hdd_update_connect_params_fils_info(struct hdd_adapter *adapter, req->fils_erp_realm_len); } - fils_info->sequence_number = req->fils_erp_next_seq_num + 1; + fils_info->erp_sequence_number = req->fils_erp_next_seq_num + 1; fils_info->r_rk_length = req->fils_erp_rrk_len; - if (fils_info->r_rk_length > FILS_MAX_RRK_LENGTH) { + if (fils_info->r_rk_length > WLAN_FILS_MAX_RRK_LENGTH) { hdd_err("r_rk_length is invalid"); return -EINVAL; } diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 6382eb7d90..6c7689beb9 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -1051,9 +1051,6 @@ struct join_req { struct power_cap_info powerCap; struct supported_channels supportedChannels; bool enable_bcast_probe_rsp; -#ifdef WLAN_FEATURE_FILS_SK - struct cds_fils_connection_info fils_con_info; -#endif bool sae_pmk_cached; /* Pls make this as last variable in struct */ bool force_24ghz_in_ht20; diff --git a/core/mac/src/pe/lim/lim_process_fils.c b/core/mac/src/pe/lim/lim_process_fils.c index 15b1eb5ccd..c2876005c0 100644 --- a/core/mac/src/pe/lim/lim_process_fils.c +++ b/core/mac/src/pe/lim/lim_process_fils.c @@ -26,6 +26,7 @@ #include #include "qdf_util.h" #include "wlan_crypto_global_api.h" +#include "wlan_cm_roam_api.h" #ifdef WLAN_FEATURE_FILS_SK @@ -530,7 +531,8 @@ static void lim_generate_key_auth(struct pe_session *pe_session) * * Return: None */ -static void lim_get_keys(struct pe_session *pe_session) +static void lim_get_keys(struct mac_context *mac_ctx, + struct pe_session *pe_session) { uint8_t key_label[] = PTK_KEY_LABEL; uint8_t *data; @@ -543,6 +545,7 @@ static void lim_get_keys(struct pe_session *pe_session) uint8_t fils_ft_len = 0; uint8_t tk_len = lim_get_tk_len(pe_session->encryptType); uint8_t *buf; + QDF_STATUS status; if (!fils_info) return; @@ -611,6 +614,12 @@ static void lim_get_keys(struct pe_session *pe_session) if (pe_session->is11Rconnection && fils_ft_len) { qdf_mem_copy(fils_info->fils_ft, buf, fils_ft_len); fils_info->fils_ft_len = fils_ft_len; + status = wlan_cm_update_fils_ft(mac_ctx->psoc, + pe_session->vdev_id, + fils_info->fils_ft, + fils_ft_len); + if (QDF_IS_STATUS_ERROR(status)) + pe_err("Failed to update FILS FT to mlme"); } qdf_mem_zero(data, data_len); qdf_mem_free(data); @@ -1384,7 +1393,7 @@ bool lim_process_fils_auth_frame2(struct mac_context *mac_ctx, rx_auth_frm_body->wrapped_data_len)) return false; } - lim_get_keys(pe_session); + lim_get_keys(mac_ctx, pe_session); if (pe_session->is11Rconnection) { status = lim_generate_fils_pmkr0(pe_session); if (QDF_IS_STATUS_ERROR(status)) @@ -1404,62 +1413,63 @@ void lim_update_fils_config(struct mac_context *mac_ctx, struct join_req *sme_join_req) { struct pe_fils_session *pe_fils_info; - struct cds_fils_connection_info *fils_config_info; + struct wlan_fils_connection_info *fils_info = NULL; tDot11fIERSN dot11f_ie_rsn = {0}; uint32_t ret; - fils_config_info = &sme_join_req->fils_con_info; - pe_fils_info = session->fils_info; + fils_info = wlan_cm_get_fils_connection_info(mac_ctx->psoc, + session->vdev_id); + if (!fils_info) + return; + pe_fils_info = session->fils_info; if (!pe_fils_info) return; - if (fils_config_info->is_fils_connection == false) + if (!fils_info->is_fils_connection) return; - pe_fils_info->is_fils_connection = - fils_config_info->is_fils_connection; - pe_fils_info->keyname_nai_length = - fils_config_info->key_nai_length; - pe_fils_info->fils_rrk_len = - fils_config_info->r_rk_length; - pe_fils_info->akm = fils_config_info->akm_type; - pe_fils_info->auth = fils_config_info->auth_type; - pe_fils_info->sequence_number = fils_config_info->sequence_number; - if (fils_config_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) { + pe_fils_info->is_fils_connection = fils_info->is_fils_connection; + pe_fils_info->keyname_nai_length = fils_info->key_nai_length; + pe_fils_info->fils_rrk_len = fils_info->r_rk_length; + pe_fils_info->akm = fils_info->akm_type; + pe_fils_info->auth = fils_info->auth_type; + pe_fils_info->sequence_number = fils_info->erp_sequence_number; + + if (fils_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) { pe_err("Restricting the key_nai_length of %d to max %d", - fils_config_info->key_nai_length, + fils_info->key_nai_length, FILS_MAX_KEYNAME_NAI_LENGTH); - fils_config_info->key_nai_length = FILS_MAX_KEYNAME_NAI_LENGTH; + fils_info->key_nai_length = FILS_MAX_KEYNAME_NAI_LENGTH; } - if (fils_config_info->key_nai_length) { + if (fils_info->key_nai_length) { pe_fils_info->keyname_nai_data = - qdf_mem_malloc(fils_config_info->key_nai_length); + qdf_mem_malloc(fils_info->key_nai_length); if (!pe_fils_info->keyname_nai_data) return; qdf_mem_copy(pe_fils_info->keyname_nai_data, - fils_config_info->keyname_nai, - fils_config_info->key_nai_length); + fils_info->keyname_nai, + fils_info->key_nai_length); } - if (fils_config_info->r_rk_length) { + if (fils_info->r_rk_length) { pe_fils_info->fils_rrk = - qdf_mem_malloc(fils_config_info->r_rk_length); - if (!pe_fils_info->fils_rrk) { + qdf_mem_malloc(fils_info->r_rk_length); + if (!pe_fils_info->fils_rrk) qdf_mem_free(pe_fils_info->keyname_nai_data); return; - } - if (fils_config_info->r_rk_length <= FILS_MAX_RRK_LENGTH) + if (fils_info->r_rk_length <= WLAN_FILS_MAX_RRK_LENGTH) qdf_mem_copy(pe_fils_info->fils_rrk, - fils_config_info->r_rk, - fils_config_info->r_rk_length); + fils_info->r_rk, + fils_info->r_rk_length); } - qdf_mem_copy(pe_fils_info->fils_pmkid, fils_config_info->pmkid, + qdf_mem_copy(pe_fils_info->fils_pmkid, fils_info->pmkid, PMKID_LEN); + pe_fils_info->rsn_ie_len = sme_join_req->rsnIE.length; qdf_mem_copy(pe_fils_info->rsn_ie, sme_join_req->rsnIE.rsnIEdata, @@ -1484,25 +1494,25 @@ void lim_update_fils_config(struct mac_context *mac_ctx, else pe_err("FT-FILS: Invalid RSN IE"); - pe_fils_info->fils_pmk_len = fils_config_info->pmk_len; - if (fils_config_info->pmk_len) { + pe_fils_info->fils_pmk_len = fils_info->pmk_len; + if (fils_info->pmk_len) { pe_fils_info->fils_pmk = - qdf_mem_malloc(fils_config_info->pmk_len); + qdf_mem_malloc(fils_info->pmk_len); if (!pe_fils_info->fils_pmk) { qdf_mem_free(pe_fils_info->keyname_nai_data); qdf_mem_free(pe_fils_info->fils_rrk); return; } - qdf_mem_copy(pe_fils_info->fils_pmk, fils_config_info->pmk, - fils_config_info->pmk_len); + qdf_mem_copy(pe_fils_info->fils_pmk, fils_info->pmk, + fils_info->pmk_len); } - pe_debug("fils=%d nai-len=%d rrk_len=%d akm=%d auth=%d pmk_len=%d", - fils_config_info->is_fils_connection, - fils_config_info->key_nai_length, - fils_config_info->r_rk_length, - fils_config_info->akm_type, - fils_config_info->auth_type, - fils_config_info->pmk_len); + pe_debug("FILS: fils=%d nai-len=%d rrk_len=%d akm=%d auth=%d pmk_len=%d", + fils_info->is_fils_connection, + fils_info->key_nai_length, + fils_info->r_rk_length, + fils_info->akm_type, + fils_info->auth_type, + fils_info->pmk_len); } #define EXTENDED_IE_HEADER_LEN 3 @@ -2182,11 +2192,11 @@ void lim_update_fils_rik(struct pe_session *pe_session, */ if ((!lim_is_fils_connection(pe_session) || !pe_fils_info) && (req_buffer->is_fils_connection)) { - if (roam_fils_params->rrk_length > FILS_MAX_RRK_LENGTH) { + if (roam_fils_params->rrk_length > WLAN_FILS_MAX_RRK_LENGTH) { if (lim_is_fils_connection(pe_session)) pe_debug("FILS rrk len(%d) max (%d)", roam_fils_params->rrk_length, - FILS_MAX_RRK_LENGTH); + WLAN_FILS_MAX_RRK_LENGTH); return; } @@ -2203,12 +2213,12 @@ void lim_update_fils_rik(struct pe_session *pe_session, pe_debug("No FILS info available in the session"); return; } - if ((pe_fils_info->fils_rik_len > FILS_MAX_RIK_LENGTH) || + if (pe_fils_info->fils_rik_len > WLAN_FILS_MAX_RIK_LENGTH || !pe_fils_info->fils_rik) { if (pe_fils_info->fils_rik) pe_debug("Fils rik len(%d) max %d", pe_fils_info->fils_rik_len, - FILS_MAX_RIK_LENGTH); + WLAN_FILS_MAX_RIK_LENGTH); return; } diff --git a/core/sme/inc/csr_api.h b/core/sme/inc/csr_api.h index 91ab14f2e5..42c8a2fcc0 100644 --- a/core/sme/inc/csr_api.h +++ b/core/sme/inc/csr_api.h @@ -29,6 +29,7 @@ #include "sir_mac_prot_def.h" #include "csr_link_list.h" #include "wlan_scan_public_structs.h" +#include "wlan_mlme_public_struct.h" #define CSR_INVALID_SCANRESULT_HANDLE (NULL) @@ -718,7 +719,7 @@ struct csr_roam_profile { #ifdef WLAN_FEATURE_FILS_SK uint8_t *hlp_ie; uint32_t hlp_ie_len; - struct cds_fils_connection_info *fils_con_info; + struct wlan_fils_connection_info *fils_con_info; #endif bool force_rsne_override; }; diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index cad3332789..a82ae14b50 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -6197,7 +6197,8 @@ QDF_STATUS csr_roam_process_command(struct mac_context *mac, tSmeCmd *pCommand) if (pSession->pCurRoamProfile) { csr_roam_copy_profile(mac, pSession->pCurRoamProfile, - &pCommand->u.roamCmd.roamProfile); + &pCommand->u.roamCmd.roamProfile, + sessionId); } sme_release_global_lock(&mac->sme); } @@ -7819,8 +7820,10 @@ static bool csr_roam_process_results(struct mac_context *mac_ctx, tSmeCmd *cmd, * * Return: None */ -static void update_profile_fils_info(struct csr_roam_profile *des_profile, - struct csr_roam_profile *src_profile) +static void update_profile_fils_info(struct mac_context *mac, + struct csr_roam_profile *des_profile, + struct csr_roam_profile *src_profile, + uint8_t vdev_id) { if (!src_profile || !src_profile->fils_con_info) return; @@ -7831,14 +7834,17 @@ static void update_profile_fils_info(struct csr_roam_profile *des_profile, return; des_profile->fils_con_info = - qdf_mem_malloc(sizeof(struct cds_fils_connection_info)); + qdf_mem_malloc(sizeof(struct wlan_fils_connection_info)); if (!des_profile->fils_con_info) return; qdf_mem_copy(des_profile->fils_con_info, src_profile->fils_con_info, - sizeof(struct cds_fils_connection_info)); + sizeof(struct wlan_fils_connection_info)); + wlan_cm_update_mlme_fils_connection_info(mac->psoc, + des_profile->fils_con_info, + vdev_id); des_profile->hlp_ie = qdf_mem_malloc(src_profile->hlp_ie_len); if (!des_profile->hlp_ie) @@ -7850,13 +7856,17 @@ static void update_profile_fils_info(struct csr_roam_profile *des_profile, } #else static inline -void update_profile_fils_info(struct csr_roam_profile *des_profile, - struct csr_roam_profile *src_profile) -{ } +void update_profile_fils_info(struct mac_context *mac, + struct csr_roam_profile *des_profile, + struct csr_roam_profile *src_profile, + uint8_t vdev_id) +{} #endif + QDF_STATUS csr_roam_copy_profile(struct mac_context *mac, struct csr_roam_profile *pDstProfile, - struct csr_roam_profile *pSrcProfile) + struct csr_roam_profile *pSrcProfile, + uint8_t vdev_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; uint32_t size = 0; @@ -8023,7 +8033,7 @@ QDF_STATUS csr_roam_copy_profile(struct mac_context *mac, pDstProfile->mdid = pSrcProfile->mdid; pDstProfile->add_ie_params = pSrcProfile->add_ie_params; - update_profile_fils_info(pDstProfile, pSrcProfile); + update_profile_fils_info(mac, pDstProfile, pSrcProfile, vdev_id); pDstProfile->beacon_tx_rate = pSrcProfile->beacon_tx_rate; @@ -8177,8 +8187,8 @@ QDF_STATUS csr_roam_issue_connect(struct mac_context *mac, uint32_t sessionId, } else { /* make a copy of the profile */ status = csr_roam_copy_profile(mac, &pCommand->u. - roamCmd.roamProfile, - pProfile); + roamCmd.roamProfile, + pProfile, sessionId); if (QDF_IS_STATUS_SUCCESS(status)) pCommand->u.roamCmd.fReleaseProfile = true; } @@ -8224,7 +8234,7 @@ QDF_STATUS csr_roam_issue_reassoc(struct mac_context *mac, uint32_t sessionId, /* make a copy of the profile */ status = csr_roam_copy_profile(mac, &pCommand->u. roamCmd.roamProfile, - pProfile); + pProfile, sessionId); pCommand->u.roamCmd.fUpdateCurRoamProfile = true; } else { status = csr_roam_copy_connected_profile(mac, @@ -9960,7 +9970,7 @@ QDF_STATUS csr_roam_lfr2_issue_connect(struct mac_context *mac, SME_QOS_CSR_HANDOFF_ASSOC_REQ, NULL); csr_roam_copy_profile(mac, cur_roam_profile, - session->pCurRoamProfile); + session->pCurRoamProfile, session_id); /* make sure to put it at the head of the cmd queue */ status = csr_roam_issue_connect(mac, session_id, cur_roam_profile, hbss_list, @@ -10723,7 +10733,7 @@ csr_issue_set_context_req_helper(struct mac_context *mac_ctx, * Return: None */ static bool -csr_create_fils_realm_hash(struct cds_fils_connection_info *fils_con_info, +csr_create_fils_realm_hash(struct wlan_fils_connection_info *fils_con_info, uint8_t *tmp_hash) { uint8_t *hash; @@ -14343,7 +14353,7 @@ static QDF_STATUS csr_roam_start_wds(struct mac_context *mac, uint32_t sessionId if (pSession->pCurRoamProfile) { csr_roam_copy_profile(mac, pSession->pCurRoamProfile, - pProfile); + pProfile, sessionId); } /* Prepare some more parameters for this WDS */ csr_roam_prepare_bss_params(mac, sessionId, pProfile, @@ -14472,13 +14482,14 @@ csr_validate_and_update_fils_info(struct mac_context *mac, uint8_t cache_id[CACHE_ID_LEN] = {0}; struct qdf_mac_addr bssid; - if (!profile->fils_con_info) + if (!profile->fils_con_info) { + wlan_cm_update_mlme_fils_connection_info(mac->psoc, NULL, + vdev_id); return QDF_STATUS_SUCCESS; + } if (!profile->fils_con_info->is_fils_connection) { sme_debug("FILS_PMKSA: Not a FILS connection"); - qdf_mem_zero(&csr_join_req->fils_con_info, - sizeof(struct cds_fils_connection_info)); return QDF_STATUS_SUCCESS; } @@ -14501,20 +14512,20 @@ csr_validate_and_update_fils_info(struct mac_context *mac, csr_join_req->ssId.length, &bssid)) return QDF_STATUS_E_FAILURE; - qdf_mem_copy(&csr_join_req->fils_con_info, - profile->fils_con_info, - sizeof(struct cds_fils_connection_info)); - - return QDF_STATUS_SUCCESS; + return wlan_cm_update_mlme_fils_connection_info(mac->psoc, + profile->fils_con_info, + vdev_id); } #else -static QDF_STATUS +static inline QDF_STATUS csr_validate_and_update_fils_info(struct mac_context *mac, struct csr_roam_profile *profile, struct bss_description *bss_desc, struct join_req *csr_join_req, uint8_t vdev_id) -{ } +{ + return QDF_STATUS_SUCCESS; +} #endif #ifdef WLAN_FEATURE_SAE @@ -18213,7 +18224,189 @@ static void csr_update_driver_assoc_ies(struct mac_context *mac_ctx, csr_append_assoc_ies(mac_ctx, req_buf, WLAN_ELEMID_VENDOR, sizeof(qcn_ie), qcn_ie); } +#else +/** + * csr_cm_apend_assoc_ies() - Append specific IE to assoc IE's buffer + * @req_buf: Pointer to Roam offload scan request + * @ie_id: IE ID to be appended + * @ie_len: IE length to be appended + * @ie_data: IE data to be appended + * + * Return: None + */ +static void +csr_cm_append_assoc_ies(struct wlan_roam_scan_offload_params *rso_mode_cfg, + uint8_t ie_id, uint8_t ie_len, + const uint8_t *ie_data) +{ + uint32_t curr_length = rso_mode_cfg->assoc_ie_length; + if ((SIR_MAC_MAX_ADD_IE_LENGTH - curr_length) < ie_len) { + sme_err("Appending IE id: %d failed", ie_id); + return; + } + + rso_mode_cfg->assoc_ie[curr_length] = ie_id; + rso_mode_cfg->assoc_ie[curr_length + 1] = ie_len; + qdf_mem_copy(&rso_mode_cfg->assoc_ie[curr_length + 2], ie_data, ie_len); + rso_mode_cfg->assoc_ie_length += (ie_len + 2); +} + +#ifdef FEATURE_WLAN_ESE +static void csr_cm_esr_populate_version_ie( + struct mac_context *mac_ctx, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{ + static const uint8_t ese_ie[] = {0x0, 0x40, 0x96, 0x3, + ESE_VERSION_SUPPORTED}; + + /* Append ESE version IE if isEseIniFeatureEnabled INI is enabled */ + if (mac_ctx->mlme_cfg->lfr.ese_enabled) + csr_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_VENDOR, + sizeof(ese_ie), ese_ie); +} + +/** + * csr_cm_ese_populate_addtional_ies() - add IEs to reassoc frame + * @mac_ctx: Pointer to global mac structure + * @session: pointer to CSR session + * @req_buf: Pointer to Roam offload scan request + * + * This function populates the TSPEC ie and appends the info + * to assoc buffer. + * + * Return: None + */ +static void csr_cm_ese_populate_addtional_ies( + struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{ + uint8_t tspec_ie_hdr[SIR_MAC_OUI_WME_HDR_MIN] + = { 0x00, 0x50, 0xf2, 0x02, 0x02, 0x01 }; + uint8_t tspec_ie_buf[DOT11F_IE_WMMTSPEC_MAX_LEN], j; + ese_wmm_tspec_ie *tspec_ie; + tESETspecInfo ese_tspec; + + tspec_ie = (ese_wmm_tspec_ie *)(tspec_ie_buf + SIR_MAC_OUI_WME_HDR_MIN); + if (csr_is_wmm_supported(mac_ctx) && + mac_ctx->mlme_cfg->lfr.ese_enabled && + csr_roam_is_ese_assoc(mac_ctx, session->sessionId)) { + ese_tspec.numTspecs = sme_qos_ese_retrieve_tspec_info( + mac_ctx, session->sessionId, + (tTspecInfo *)&ese_tspec.tspec[0]); + qdf_mem_copy(tspec_ie_buf, tspec_ie_hdr, + SIR_MAC_OUI_WME_HDR_MIN); + for (j = 0; j < ese_tspec.numTspecs; j++) { + /* Populate the tspec_ie */ + ese_populate_wmm_tspec(&ese_tspec.tspec[j].tspec, + tspec_ie); + csr_cm_append_assoc_ies(rso_mode_cfg, + WLAN_ELEMID_VENDOR, + DOT11F_IE_WMMTSPEC_MAX_LEN, + tspec_ie_buf); + } + } +} +#else +static inline void csr_cm_esr_populate_version_ie( + struct mac_context *mac_ctx, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{} + +static inline void csr_cm_ese_populate_addtional_ies( + struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{} +#endif + +/** + * csr_cm_update_driver_assoc_ies - Append driver built IE's to assoc IE's + * @mac_ctx: Pointer to global mac structure + * @session: pointer to CSR session + * @rso_mode_cfg: Pointer to Roam offload scan request + * + * Return: None + */ +static void csr_cm_update_driver_assoc_ies( + struct mac_context *mac_ctx, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_mode_cfg) +{ + uint32_t csr_11henable; + bool power_caps_populated = false; + uint8_t *rrm_cap_ie_data = + (uint8_t *)&mac_ctx->rrm.rrmPEContext.rrmEnabledCaps; + uint8_t power_cap_ie_data[DOT11F_IE_POWERCAPS_MAX_LEN] = { + MIN_TX_PWR_CAP, MAX_TX_PWR_CAP}; + uint8_t max_tx_pwr_cap = 0; + uint8_t supp_chan_ie[DOT11F_IE_SUPPCHANNELS_MAX_LEN], supp_chan_ie_len; + static const uint8_t qcn_ie[] = {0x8C, 0xFD, 0xF0, 0x1, + QCN_IE_VERSION_SUBATTR_ID, + QCN_IE_VERSION_SUBATTR_DATA_LEN, + QCN_IE_VERSION_SUPPORTED, + QCN_IE_SUBVERSION_SUPPORTED}; + + /* Re-Assoc IE TLV parameters */ + rso_mode_cfg->assoc_ie_length = session->nAddIEAssocLength; + qdf_mem_copy(rso_mode_cfg->assoc_ie, session->pAddIEAssoc, + rso_mode_cfg->assoc_ie_length); + + if (session->pConnectBssDesc) + max_tx_pwr_cap = csr_get_cfg_max_tx_power( + mac_ctx, + session->pConnectBssDesc->chan_freq); + + if (max_tx_pwr_cap && max_tx_pwr_cap < MAX_TX_PWR_CAP) + power_cap_ie_data[1] = max_tx_pwr_cap; + else + power_cap_ie_data[1] = MAX_TX_PWR_CAP; + + csr_11henable = mac_ctx->mlme_cfg->gen.enabled_11h; + + if (csr_11henable && csr_is11h_supported(mac_ctx)) { + /* Append power cap IE */ + csr_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_PWRCAP, + DOT11F_IE_POWERCAPS_MAX_LEN, + power_cap_ie_data); + power_caps_populated = true; + + /* Append Supported channels IE */ + csr_add_supported_5Ghz_channels(mac_ctx, supp_chan_ie, + &supp_chan_ie_len, true); + + csr_cm_append_assoc_ies(rso_mode_cfg, + WLAN_ELEMID_SUPPCHAN, + supp_chan_ie_len, supp_chan_ie); + } + + csr_cm_esr_populate_version_ie(mac_ctx, rso_mode_cfg); + + if (mac_ctx->rrm.rrmPEContext.rrmEnable) { + /* Append RRM IE */ + csr_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_RRM, + DOT11F_IE_RRMENABLEDCAP_MAX_LEN, + rrm_cap_ie_data); + + /* Append Power cap IE if not appended already */ + if (!power_caps_populated) + csr_cm_append_assoc_ies(rso_mode_cfg, + WLAN_ELEMID_PWRCAP, + DOT11F_IE_POWERCAPS_MAX_LEN, + power_cap_ie_data); + } + + csr_cm_ese_populate_addtional_ies(mac_ctx, session, rso_mode_cfg); + + /* Append QCN IE if g_support_qcn_ie INI is enabled */ + if (mac_ctx->mlme_cfg->sta.qcn_ie_support) + csr_cm_append_assoc_ies(rso_mode_cfg, WLAN_ELEMID_VENDOR, + sizeof(qcn_ie), qcn_ie); +} +#endif + +#ifndef ROAM_OFFLOAD_V1 /** * csr_create_per_roam_request() - create PER roam offload scan request * @@ -18326,38 +18519,12 @@ QDF_STATUS csr_update_fils_config(struct mac_context *mac, uint8_t session_id, sme_err("Current Roam profile of SME session NULL"); return QDF_STATUS_E_FAILURE; } - update_profile_fils_info(dst_profile, src_profile); + update_profile_fils_info(mac, dst_profile, src_profile, + session_id); return QDF_STATUS_SUCCESS; } #ifndef ROAM_OFFLOAD_V1 -/** - * copy_all_before_char() - API to copy all character before a particular char - * @str: Source string - * @str_len: Source string legnth - * @dst: Destination string - * @dst_len: Destination string legnth - * @c: Character before which all characters need to be copied - * - * Return: length of the copied string, if success. zero otherwise. - */ -static uint32_t copy_all_before_char(char *str, uint32_t str_len, - char *dst, uint32_t dst_len, char c) -{ - uint32_t len = 0; - - if (!str) - return len; - - while ((len < str_len) && (len < dst_len) && - (*str != '\0') && (*str != c)) { - *dst++ = *str++; - len++; - } - - return len; -} - /** * csr_update_fils_params_rso() - API to update FILS params in RSO * @mac: Mac context @@ -18371,7 +18538,7 @@ static void csr_update_fils_params_rso(struct mac_context *mac, struct roam_offload_scan_req *req_buffer) { struct roam_fils_params *roam_fils_params; - struct cds_fils_connection_info *fils_info; + struct wlan_fils_connection_info *fils_info; uint32_t usr_name_len; if (!session->pCurRoamProfile) @@ -18388,17 +18555,18 @@ static void csr_update_fils_params_rso(struct mac_context *mac, roam_fils_params = &req_buffer->roam_fils_params; if ((fils_info->key_nai_length > FILS_MAX_KEYNAME_NAI_LENGTH) || - (fils_info->r_rk_length > FILS_MAX_RRK_LENGTH)) { + (fils_info->r_rk_length > WLAN_FILS_MAX_RRK_LENGTH)) { sme_err("Fils info len error: keyname nai len(%d) rrk len(%d)", fils_info->key_nai_length, fils_info->r_rk_length); return; } - usr_name_len = copy_all_before_char(fils_info->keyname_nai, - sizeof(fils_info->keyname_nai), - roam_fils_params->username, - sizeof(roam_fils_params->username), - '@'); + usr_name_len = + qdf_str_copy_all_before_char(fils_info->keyname_nai, + sizeof(fils_info->keyname_nai), + roam_fils_params->username, + sizeof(roam_fils_params->username), + '@'); if (fils_info->key_nai_length <= usr_name_len) { sme_err("Fils info len error: key nai len %d, user name len %d", fils_info->key_nai_length, usr_name_len); @@ -18408,7 +18576,7 @@ static void csr_update_fils_params_rso(struct mac_context *mac, roam_fils_params->username_length = usr_name_len; req_buffer->is_fils_connection = true; - roam_fils_params->next_erp_seq_num = fils_info->sequence_number; + roam_fils_params->next_erp_seq_num = fils_info->erp_sequence_number; roam_fils_params->rrk_length = fils_info->r_rk_length; qdf_mem_copy(roam_fils_params->rrk, fils_info->r_rk, @@ -18424,10 +18592,7 @@ static void csr_update_fils_params_rso(struct mac_context *mac, roam_fils_params->next_erp_seq_num, roam_fils_params->rrk_length, roam_fils_params->realm_len); } -#endif #else - -#ifndef ROAM_OFFLOAD_V1 static inline void csr_update_fils_params_rso(struct mac_context *mac, struct csr_roam_session *session, @@ -19724,6 +19889,359 @@ csr_cm_roam_scan_offload_ap_profile(struct mac_context *mac_ctx, mac_ctx->mlme_cfg->trig_score_delta[BTM_ROAM_TRIGGER]; } +#if defined(WLAN_SAE_SINGLE_PMK) && defined(WLAN_FEATURE_ROAM_OFFLOAD) +static bool +csr_cm_fill_rso_sae_single_pmk_info(struct mac_context *mac_ctx, + struct wlan_rso_11i_params *rso_11i_info, + uint8_t vdev_id) +{ + struct wlan_mlme_sae_single_pmk single_pmk; + struct wlan_objmgr_vdev *vdev; + + if (!mac_ctx || !req_buf) { + sme_debug("Invalid session or req buff"); + return false; + } + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("vdev is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + wlan_mlme_get_sae_single_pmk_info(vdev, &single_pmk); + + if (single_pmk.pmk_info.pmk_len && single_pmk.sae_single_pmk_ap && + mac_ctx->mlme_cfg->lfr.sae_single_pmk_feature_enabled) { + sme_debug("Update pmk with len %d same_pmk_info %d", + single_pmk.pmk_info.pmk_len, + single_pmk.sae_single_pmk_ap); + + rso_11i_info->pmk_len = single_pmk.pmk_info.pmk_len; + /* Update sae same pmk info in rso */ + qdf_mem_copy(rso_11i_info->psk_pmk, single_pmk.pmk_info.pmk, + rso_11i_info->pmk_len); + rso_11i_info->is_sae_same_pmk = single_pmk.sae_single_pmk_ap; + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + return true; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + + return false; +} +#else +static inline bool +csr_cm_fill_rso_sae_single_pmk_info(struct mac_context *mac_ctx, + struct wlan_rso_11i_params *rso_11i_info, + uint8_t vdev_id) +{ + return false; +} +#endif /* WLAN_SAE_SINGLE_PMK && WLAN_FEATURE_ROAM_OFFLOAD */ + +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#define RSN_CAPS_SHIFT 16 + +#ifdef WLAN_ADAPTIVE_11R +static void +csr_cm_update_rso_adaptive_11r(struct wlan_rso_11r_params *dst, + struct csr_roam_session *session) +{ + dst->is_adaptive_11r = session->is_adaptive_11r_connection; +} +#else +static inline void +csr_cm_update_rso_adaptive_11r(struct wlan_rso_11r_params *dst, + struct csr_roam_session *session) +{} +#endif + +#ifdef FEATURE_WLAN_ESE +static void +csr_cm_update_rso_ese_info(struct mac_context *mac, + struct wlan_roam_scan_offload_params *rso_config, + tpCsrNeighborRoamControlInfo roam_info, + struct csr_roam_session *session) +{ + enum csr_akm_type akm = + mac->roam.roamSession[session->vdev_id].connectedProfile.AuthType; + + rso_config->rso_ese_info.is_ese_assoc = + (csr_roam_is_ese_assoc(mac, session->vdev_id) && + akm == eCSR_AUTH_TYPE_OPEN_SYSTEM) || + (csr_is_auth_type_ese(akm)); + rso_config->rso_11r_info.is_11r_assoc = roam_info->is11rAssoc; +} +#else +static +csr_cm_update_rso_ese_info(struct mac_context *mac, + struct wlan_roam_scan_offload_params *rso_config, + tpCsrNeighborRoamControlInfo roam_info, + struct csr_roam_session *session) +{} +#endif + +/** + * csr_cm_roam_scan_offload_fill_lfr3_config - Fill Roam scan offload + * related configs for WMI_ROAM_SCAN_MODE command to firmware. + * @mac: Pointer to mac context + * @session: Pointer to csr_roam_session + * @vdev_id: vdev_id + * + * Return: QDF_STATUS + */ +static QDF_STATUS csr_cm_roam_scan_offload_fill_lfr3_config( + struct mac_context *mac, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_config, + uint8_t command) +{ + struct wlan_objmgr_vdev *vdev; + tSirMacCapabilityInfo self_caps; + tSirMacQosInfoStation sta_qos_info; + uint16_t *final_caps_val; + uint8_t *qos_cfg_val, temp_val; + uint32_t pmkid_modes = mac->mlme_cfg->sta.pmkid_modes; + uint32_t val = 0; + qdf_size_t val_len; + QDF_STATUS status; + tpCsrNeighborRoamControlInfo roam_info = + &mac->roam.neighborRoamInfo[session->vdev_id]; + + rso_config->roam_offload_enabled = + mac->mlme_cfg->lfr.lfr3_roaming_offload; + if (!rso_config->roam_offload_enabled) + return QDF_STATUS_SUCCESS; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, + session->vdev_id, + WLAN_LEGACY_SME_ID); + if (!vdev) { + sme_err("Vdev:%d is NULL", session->vdev_id); + return QDF_STATUS_E_FAILURE; + } + + /* FILL LFR3 specific roam scan mode TLV parameters */ + rso_config->rso_lfr3_params.roam_rssi_cat_gap = + mac->roam.configParam.bCatRssiOffset; + rso_config->rso_lfr3_params.prefer_5ghz = + (uint8_t)mac->mlme_cfg->lfr.roam_prefer_5ghz; + rso_config->rso_lfr3_params.select_5ghz_margin = + mac->mlme_cfg->gen.select_5ghz_margin; + rso_config->rso_lfr3_params.reassoc_failure_timeout = + mac->mlme_cfg->timeouts.reassoc_failure_timeout; + rso_config->rso_lfr3_params.ho_delay_for_rx = + mac->mlme_cfg->lfr.ho_delay_for_rx; + rso_config->rso_lfr3_params.roam_retry_count = + mac->mlme_cfg->lfr.roam_preauth_retry_count; + rso_config->rso_lfr3_params.roam_preauth_no_ack_timeout = + mac->mlme_cfg->lfr.roam_preauth_no_ack_timeout; + rso_config->rso_lfr3_params.rct_validity_timer = + mac->mlme_cfg->btm.rct_validity_timer; + rso_config->rso_lfr3_params.disable_self_roam = + !mac->mlme_cfg->lfr.enable_self_bss_roam; + + /* Fill LFR3 specific self capabilities for roam scan mode TLV */ + self_caps.ess = 1; + self_caps.ibss = 0; + + val = mac->mlme_cfg->wep_params.is_privacy_enabled; + if (val) + self_caps.privacy = 1; + + if (mac->mlme_cfg->ht_caps.short_preamble) + self_caps.shortPreamble = 1; + + self_caps.pbcc = 0; + self_caps.channelAgility = 0; + + if (mac->mlme_cfg->feature_flags.enable_short_slot_time_11g) + self_caps.shortSlotTime = 1; + + if (mac->mlme_cfg->gen.enabled_11h) + self_caps.spectrumMgt = 1; + + if (mac->mlme_cfg->wmm_params.qos_enabled) + self_caps.qos = 1; + + if (mac->mlme_cfg->roam_scoring.apsd_enabled) + self_caps.apsd = 1; + + self_caps.rrm = mac->rrm.rrmConfig.rrm_enabled; + + val = mac->mlme_cfg->feature_flags.enable_block_ack; + self_caps.delayedBA = + (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_DELAYED) & 1); + self_caps.immediateBA = + (uint16_t)((val >> WNI_CFG_BLOCK_ACK_ENABLED_IMMEDIATE) & 1); + final_caps_val = (uint16_t *)&self_caps; + + /* + * RSN caps arent been 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 this to firmware in the 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. + */ + rso_config->rso_lfr3_caps.capability = + (uint16_t)wlan_crypto_get_param(vdev, + WLAN_CRYPTO_PARAM_RSN_CAP); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); + + rso_config->rso_lfr3_caps.capability <<= RSN_CAPS_SHIFT; + rso_config->rso_lfr3_caps.capability |= ((*final_caps_val) & 0xFFFF); + + rso_config->rso_lfr3_caps.ht_caps_info = + *(uint16_t *)&mac->mlme_cfg->ht_caps.ht_cap_info; + rso_config->rso_lfr3_caps.ampdu_param = + *(uint8_t *)&mac->mlme_cfg->ht_caps.ampdu_params; + rso_config->rso_lfr3_caps.ht_ext_cap = + *(uint16_t *)&mac->mlme_cfg->ht_caps.ext_cap_info; + + temp_val = (uint8_t)mac->mlme_cfg->vht_caps.vht_cap_info.tx_bf_cap; + rso_config->rso_lfr3_caps.ht_txbf = temp_val & 0xFF; + temp_val = (uint8_t)mac->mlme_cfg->vht_caps.vht_cap_info.as_cap; + rso_config->rso_lfr3_caps.asel_cap = temp_val & 0xFF; + + qdf_mem_zero(&sta_qos_info, sizeof(tSirMacQosInfoStation)); + sta_qos_info.maxSpLen = + (uint8_t)mac->mlme_cfg->wmm_params.max_sp_length; + sta_qos_info.moreDataAck = 0; + sta_qos_info.qack = 0; + sta_qos_info.acbe_uapsd = SIR_UAPSD_GET(ACBE, session->uapsd_mask); + sta_qos_info.acbk_uapsd = SIR_UAPSD_GET(ACBK, session->uapsd_mask); + sta_qos_info.acvi_uapsd = SIR_UAPSD_GET(ACVI, session->uapsd_mask); + sta_qos_info.acvo_uapsd = SIR_UAPSD_GET(ACVO, session->uapsd_mask); + qos_cfg_val = (uint8_t *)&sta_qos_info; + rso_config->rso_lfr3_caps.qos_caps = (*qos_cfg_val) & 0xFF; + if (rso_config->rso_lfr3_caps.qos_caps) + rso_config->rso_lfr3_caps.qos_enabled = true; + + rso_config->rso_lfr3_caps.wmm_caps = 0x4; + + val_len = ROAM_OFFLOAD_NUM_MCS_SET; + status = + wlan_mlme_get_cfg_str((uint8_t *)rso_config->rso_lfr3_caps.mcsset, + &mac->mlme_cfg->rates.supported_mcs_set, + &val_len); + if (QDF_IS_STATUS_ERROR(status)) { + mlme_err("Failed to get CFG_SUPPORTED_MCS_SET"); + return QDF_STATUS_E_FAILURE; + } + + /* Update 11i TLV related Fields */ + rso_config->rso_11i_info.roam_key_mgmt_offload_enabled = + session->RoamKeyMgmtOffloadEnabled; + rso_config->rso_11i_info.fw_okc = + (pmkid_modes & CFG_PMKID_MODES_OKC) ? 1 : 0; + rso_config->rso_11i_info.fw_pmksa_cache = + (pmkid_modes & CFG_PMKID_MODES_PMKSA_CACHING) ? 1 : 0; + + /* Check whether to send psk_pmk or sae_single pmk info */ + if (!csr_cm_fill_rso_sae_single_pmk_info(mac, + &rso_config->rso_11i_info, + session->vdev_id)) { + rso_config->rso_11i_info.is_sae_same_pmk = false; + qdf_mem_copy(rso_config->rso_11i_info.psk_pmk, session->psk_pmk, + sizeof(rso_config->rso_11i_info.psk_pmk)); + rso_config->rso_11i_info.pmk_len = session->pmk_len; + } + + rso_config->rso_11r_info.enable_ft_im_roaming = + mac->mlme_cfg->lfr.enable_ft_im_roaming; + rso_config->rso_11r_info.r0kh_id_length = + session->ftSmeContext.r0kh_id_len; + qdf_mem_copy(rso_config->rso_11r_info.r0kh_id, + session->ftSmeContext.r0kh_id, + session->ftSmeContext.r0kh_id_len); + + csr_cm_update_rso_adaptive_11r(&rso_config->rso_11r_info, + session); + csr_cm_update_rso_ese_info(mac, rso_config, roam_info, session); + + /* TODO: Fill auth mode */ + rso_config->akm = WMI_AUTH_OPEN; + + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS +csr_cm_roam_scan_offload_fill_lfr3_config( + struct mac_context *mac, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_config, + uint8_t command) +{ + return QDF_STATUS_SUCCESS; +} +#endif + +/** + * csr_cm_roam_scan_offload_fill_rso_configs - Fill Roam scan offload related + * configs for WMI_ROAM_SCAN_MODE command to firmware. + * @mac: Pointer to mac context + * @session: Pointer to csr_roam_session + * @vdev_id: vdev_id + */ +static void csr_cm_roam_scan_offload_fill_rso_configs( + struct mac_context *mac, + struct csr_roam_session *session, + struct wlan_roam_scan_offload_params *rso_mode_cfg, + uint8_t command, uint16_t reason) +{ + uint8_t vdev_id = session->vdev_id; + tpCsrNeighborRoamControlInfo roam_info = + &mac->roam.neighborRoamInfo[vdev_id]; + uint32_t mode = 0; + bool force_rssi_trigger; + + qdf_mem_zero(rso_mode_cfg, sizeof(*rso_mode_cfg)); + + rso_mode_cfg->vdev_id = session->vdev_id; + rso_mode_cfg->is_rso_stop = (command == ROAM_SCAN_OFFLOAD_STOP); + + /* Fill ROAM SCAN mode TLV parameters */ + if (roam_info->cfgParams.emptyScanRefreshPeriod) + mode |= WMI_ROAM_SCAN_MODE_PERIODIC; + + /* TODO move this inside LFR3 specific handling*/ + force_rssi_trigger = true; + if (force_rssi_trigger) + mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; + + rso_mode_cfg->rso_mode_info.roam_scan_mode = mode; + rso_mode_cfg->rso_mode_info.min_delay_btw_scans = + mac->mlme_cfg->lfr.min_delay_btw_roam_scans; + rso_mode_cfg->rso_mode_info.min_delay_roam_trigger_bitmask = + mac->mlme_cfg->lfr.roam_trigger_reason_bitmask; + + if (reason == REASON_ROAM_STOP_ALL || + reason == REASON_DISCONNECTED || + reason == REASON_ROAM_SYNCH_FAILED) { + mode = WMI_ROAM_SCAN_MODE_NONE; + } else { + if (csr_is_roam_offload_enabled(mac)) + mode = WMI_ROAM_SCAN_MODE_NONE | + WMI_ROAM_SCAN_MODE_ROAMOFFLOAD; + else + mode = WMI_ROAM_SCAN_MODE_NONE; + } + + if (command == ROAM_SCAN_OFFLOAD_STOP) + return; + + csr_cm_roam_scan_offload_fill_lfr3_config(mac, session, rso_mode_cfg, + command); + csr_cm_update_driver_assoc_ies(mac, session, rso_mode_cfg); + cm_roam_scan_offload_add_fils_params(mac->psoc, rso_mode_cfg, + vdev_id); +} + /** * csr_cm_roam_scan_filter() - set roam scan filter parameters * @mac_ctx: global mac ctx @@ -19915,8 +20433,7 @@ wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, session = CSR_GET_SESSION(mac_ctx, vdev_id); if (!session) { - QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, - "session is null"); + sme_err("session is null %d", vdev_id); return QDF_STATUS_E_FAILURE; } @@ -19932,6 +20449,11 @@ wlan_cm_roam_fill_start_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, csr_cm_roam_scan_filter(mac_ctx, vdev_id, ROAM_SCAN_OFFLOAD_START, reason, &req->scan_filter_params); + csr_cm_roam_scan_offload_fill_rso_configs(mac_ctx, session, + &req->rso_config, + ROAM_SCAN_OFFLOAD_START, + reason); + csr_cm_roam_scan_btm_offload(mac_ctx, session, &req->btm_config); /* 11k offload is enabled during RSO Start after connect indication */ @@ -19948,6 +20470,7 @@ wlan_cm_roam_fill_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, { QDF_STATUS status = QDF_STATUS_SUCCESS; struct mac_context *mac_ctx; + struct csr_roam_session *session; mac_ctx = sme_get_mac_context(); if (!mac_ctx) { @@ -19955,6 +20478,12 @@ wlan_cm_roam_fill_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, return QDF_STATUS_E_FAILURE; } + session = CSR_GET_SESSION(mac_ctx, vdev_id); + if (!session) { + sme_err("session is null %d", vdev_id); + return QDF_STATUS_E_FAILURE; + } + if (reason == REASON_ROAM_SYNCH_FAILED) return status; else if (reason == REASON_DRIVER_DISABLED) @@ -19978,6 +20507,11 @@ wlan_cm_roam_fill_stop_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id, */ req->roam_11k_params.vdev_id = vdev_id; + csr_cm_roam_scan_offload_fill_rso_configs(mac_ctx, session, + &req->rso_config, + ROAM_SCAN_OFFLOAD_STOP, + reason); + return status; } @@ -20012,6 +20546,11 @@ wlan_cm_roam_fill_update_config_req(struct wlan_objmgr_psoc *psoc, csr_cm_roam_scan_offload_scan_period(mac_ctx, vdev_id, &req->scan_period_params); + csr_cm_roam_scan_offload_fill_rso_configs(mac_ctx, session, + &req->rso_config, + ROAM_SCAN_OFFLOAD_UPDATE_CFG, + reason); + csr_cm_roam_scan_offload_ap_profile(mac_ctx, session, &req->profile_params); @@ -21531,7 +22070,8 @@ void csr_update_fils_erp_seq_num(struct csr_roam_profile *roam_profile, uint16_t erp_next_seq_num) { if (roam_profile->fils_con_info) - roam_profile->fils_con_info->sequence_number = erp_next_seq_num; + roam_profile->fils_con_info->erp_sequence_number = + erp_next_seq_num; } #else static inline diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 00fb51a72c..0d44c0aa62 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -213,10 +213,10 @@ csr_handle_fils_scan_for_ssid_failure(struct csr_roam_profile *roam_profile, if (roam_profile && roam_profile->fils_con_info && roam_profile->fils_con_info->is_fils_connection) { sme_debug("send roam_info for FILS connection failure, seq %d", - roam_profile->fils_con_info->sequence_number); + roam_profile->fils_con_info->erp_sequence_number); roam_info->is_fils_connection = true; roam_info->fils_seq_num = - roam_profile->fils_con_info->sequence_number; + roam_profile->fils_con_info->erp_sequence_number; return true; } @@ -1332,7 +1332,7 @@ QDF_STATUS csr_scan_for_ssid(struct mac_context *mac_ctx, uint32_t session_id, else status = csr_roam_copy_profile(mac_ctx, session->scan_info.profile, - profile); + profile, session_id); if (QDF_IS_STATUS_ERROR(status)) goto error; scan_id = ucfg_scan_get_scan_id(mac_ctx->psoc); diff --git a/core/sme/src/csr/csr_host_scan_roam.c b/core/sme/src/csr/csr_host_scan_roam.c index 645df969a0..0639a8f25d 100644 --- a/core/sme/src/csr/csr_host_scan_roam.c +++ b/core/sme/src/csr/csr_host_scan_roam.c @@ -546,7 +546,7 @@ void csr_neighbor_roam_request_handoff(struct mac_context *mac_ctx, eCSR_ROAM_HANDOVER_SUCCESS); /* Free the profile.. Just to make sure we dont leak memory here */ csr_release_profile(mac_ctx, - &neighbor_roam_info->csrNeighborRoamProfile); + &neighbor_roam_info->csrNeighborRoamProfile); /* * Create the Handoff AP profile. Copy the currently connected profile * and update only the BSSID and channel number. This should happen diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 0bcd0d835e..2ff9030e0a 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -139,7 +139,8 @@ QDF_STATUS csr_roam_save_connected_bss_desc(struct mac_context *mac, QDF_STATUS csr_roam_copy_profile(struct mac_context *mac, struct csr_roam_profile *pDstProfile, - struct csr_roam_profile *pSrcProfile); + struct csr_roam_profile *pSrcProfile, + uint8_t vdev_id); QDF_STATUS csr_roam_start(struct mac_context *mac); void csr_roam_stop(struct mac_context *mac, uint32_t sessionId); diff --git a/core/sme/src/csr/csr_neighbor_roam.c b/core/sme/src/csr/csr_neighbor_roam.c index dd753ceb02..ade32e973f 100644 --- a/core/sme/src/csr/csr_neighbor_roam.c +++ b/core/sme/src/csr/csr_neighbor_roam.c @@ -1318,7 +1318,7 @@ static QDF_STATUS csr_neighbor_roam_process_handoff_req( status = csr_roam_copy_profile(mac_ctx, profile, - session->pCurRoamProfile); + session->pCurRoamProfile, session_id); if (!QDF_IS_STATUS_SUCCESS(status)) { sme_err("Profile copy failed"); goto end; diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 59175d85be..a9f169a24a 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -33,7 +33,7 @@ #include "wlan_serialization_legacy_api.h" #include "wlan_reg_services_api.h" #include "wlan_crypto_global_api.h" - +#include "wlan_cm_roam_api.h" uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = { {0x00, 0x50, 0xf2, 0x00} @@ -3554,7 +3554,9 @@ bool csr_rates_is_dot11_rate_supported(struct mac_context *mac_ctx, uint8_t rate } #ifdef WLAN_FEATURE_FILS_SK -static inline void csr_free_fils_profile_info(struct csr_roam_profile *profile) +static inline +void csr_free_fils_profile_info(struct mac_context *mac, + struct csr_roam_profile *profile) { if (profile->fils_con_info) { qdf_mem_free(profile->fils_con_info); @@ -3568,11 +3570,13 @@ static inline void csr_free_fils_profile_info(struct csr_roam_profile *profile) } } #else -static inline void csr_free_fils_profile_info(struct csr_roam_profile *profile) +static inline void csr_free_fils_profile_info(struct mac_context *mac, + struct csr_roam_profile *profile) { } #endif -void csr_release_profile(struct mac_context *mac, struct csr_roam_profile *pProfile) +void csr_release_profile(struct mac_context *mac, + struct csr_roam_profile *pProfile) { if (pProfile) { if (pProfile->BSSIDs.bssid) { @@ -3611,7 +3615,7 @@ void csr_release_profile(struct mac_context *mac, struct csr_roam_profile *pProf qdf_mem_free(pProfile->ChannelInfo.freq_list); pProfile->ChannelInfo.freq_list = NULL; } - csr_free_fils_profile_info(pProfile); + csr_free_fils_profile_info(mac, pProfile); qdf_mem_zero(pProfile, sizeof(struct csr_roam_profile)); } } diff --git a/core/wma/src/wma_scan_roam.c b/core/wma/src/wma_scan_roam.c index c2f3360753..dee146132a 100644 --- a/core/wma/src/wma_scan_roam.c +++ b/core/wma/src/wma_scan_roam.c @@ -343,6 +343,8 @@ static void wma_handle_disconnect_reason(tp_wma_handle wma_handle, (void *)del_sta_ctx, 0); } +#ifdef WLAN_FEATURE_ROAM_OFFLOAD +#ifndef ROAM_OFFLOAD_V1 /** * wma_roam_scan_offload_set_params() - Set roam scan offload params * @wma_handle: pointer to wma context @@ -354,8 +356,6 @@ static void wma_handle_disconnect_reason(tp_wma_handle wma_handle, * * Return: None */ -#ifdef WLAN_FEATURE_ROAM_OFFLOAD -#ifndef ROAM_OFFLOAD_V1 static void wma_roam_scan_offload_set_params( tp_wma_handle wma_handle, struct roam_offload_scan_params *params, @@ -453,10 +453,10 @@ int wma_roam_vdev_disconnect_event_handler(void *handle, uint8_t *event, return 0; } #else -static void wma_roam_scan_offload_set_params( - tp_wma_handle wma_handle, - struct roam_offload_scan_params *params, - struct roam_offload_scan_req *roam_req) +static inline void +wma_roam_scan_offload_set_params(tp_wma_handle wma_handle, + struct roam_offload_scan_params *params, + struct roam_offload_scan_req *roam_req) {} #endif