diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index b1eecf4ba42a..459b41e4a9c4 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -164,6 +164,56 @@ static const int beacon_filter_table[] = { #endif }; +#if defined(WLAN_FEATURE_SAE) && \ + defined(CFG80211_EXTERNAL_AUTH_SUPPORT) +/** + * wlan_hdd_sae_callback() - Sends SAE info to supplicant + * @adapter: pointer adapter context + * @roam_info: pointer to roam info + * + * This API is used to send required SAE info to trigger SAE in supplicant. + * + * Return: None + */ +static void wlan_hdd_sae_callback(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info) +{ + struct hdd_context *hdd_ctx = adapter->hdd_ctx; + int flags; + struct sir_sae_info *sae_info = roam_info->sae_info; + struct cfg80211_external_auth_params params = {0}; + + if (wlan_hdd_validate_context(hdd_ctx)) + return; + + if (!sae_info) { + hdd_err("SAE info in NULL"); + return; + } + + flags = cds_get_gfp_flags(); + + params.key_mgmt_suite = 0x00; + params.key_mgmt_suite |= 0x0F << 8; + params.key_mgmt_suite |= 0xAC << 16; + params.key_mgmt_suite |= 0x8 << 24; + + params.action = NL80211_EXTERNAL_AUTH_START; + qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId, + sae_info->ssid.length); + params.ssid.ssid_len = sae_info->ssid.length; + + cfg80211_external_auth_request(adapter->dev, ¶ms, flags); + hdd_debug("SAE: sent cmd"); +} +#else +static inline void wlan_hdd_sae_callback(struct hdd_adapter *adapter, + struct csr_roam_info *roam_info) +{ } +#endif + /** * hdd_conn_set_authenticated() - set authentication state * @adapter: pointer to the adapter @@ -4824,6 +4874,11 @@ hdd_sme_roam_callback(void *pContext, struct csr_roam_info *roam_info, complete(&adapter->roaming_comp_var); break; + case eCSR_ROAM_SAE_COMPUTE: + if (roam_info) + wlan_hdd_sae_callback(adapter, roam_info); + break; + default: break; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6140ebf4e961..6c40e37f774d 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -15118,7 +15118,8 @@ static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy) } #endif -#ifdef WLAN_FEATURE_SAE +#if defined(WLAN_FEATURE_SAE) && \ + defined(CFG80211_EXTERNAL_AUTH_SUPPORT) /** * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature * @wiphy: Pointer to wiphy @@ -22249,6 +22250,69 @@ static int wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy, } #endif +#if defined(WLAN_FEATURE_SAE) && \ + defined(CFG80211_EXTERNAL_AUTH_SUPPORT) +/** + * __wlan_hdd_cfg80211_external_auth() - Handle external auth + * @wiphy: Pointer to wireless phy + * @dev: net device + * @params: Pointer to external auth params + * + * Return: 0 on success, negative errno on failure + */ +static int +__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_external_auth_params *params) +{ + struct hdd_context *hdd_ctx = wiphy_priv(wiphy); + struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev); + int ret; + + if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) { + hdd_err("Command not allowed in FTM mode"); + return -EPERM; + } + + if (wlan_hdd_validate_session_id(adapter->session_id)) { + hdd_err("invalid session id: %d", adapter->session_id); + return -EINVAL; + } + + ret = wlan_hdd_validate_context(hdd_ctx); + if (ret) + return ret; + + + hdd_debug("external_auth status: %d", params->status); + sme_handle_sae_msg(hdd_ctx->hHal, adapter->session_id, params->status); + + return ret; +} + +/** + * wlan_hdd_cfg80211_external_auth() - Handle external auth + * @wiphy: Pointer to wireless phy + * @dev: net device + * @params: Pointer to external auth params + * + * Return: 0 on success, negative errno on failure + */ +static int +wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, + struct net_device *dev, + struct cfg80211_external_auth_params *params) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params); + cds_ssr_unprotect(__func__); + + return ret; +} +#endif + /** * wlan_hdd_chan_info_cb() - channel info callback * @chan_info: struct scan_chan_info @@ -22544,4 +22608,8 @@ static struct cfg80211_ops wlan_hdd_cfg80211_ops = { (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))) .update_connect_params = wlan_hdd_cfg80211_update_connect_params, #endif +#if defined(WLAN_FEATURE_SAE) && \ + defined(CFG80211_EXTERNAL_AUTH_SUPPORT) + .external_auth = wlan_hdd_cfg80211_external_auth, +#endif };