Merge "wlan: Trigger/handle SAE using cfg80211" into wlan-driver.lnx.1.0
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index b47942a..26be742 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -197,6 +197,53 @@
eRoamCmdStatus roamStatus,
eCsrRoamResult roamResult );
+#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(hdd_adapter_t *adapter,
+ tCsrRoamInfo *roam_info)
+{
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ 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) {
+ hddLog(LOGE, FL("SAE info in NULL"));
+ return;
+ }
+ flags = vos_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;
+ vos_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes,
+ VOS_MAC_ADDR_SIZE);
+ vos_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);
+ hddLog(LOG1, FL("SAE: sent cmd"));
+}
+#else
+static void wlan_hdd_sae_callback(hdd_adapter_t *adapter,
+ tCsrRoamInfo *roam_info)
+{ }
+#endif
+
v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx,
eConnectionState connState )
{
@@ -4333,6 +4380,12 @@
else
hddLog(LOG1, FL("UPDATE_SCAN_RESULT returned NULL"));
}
+
+ case eCSR_ROAM_SAE_COMPUTE:
+ if (pRoamInfo)
+ wlan_hdd_sae_callback(pAdapter, pRoamInfo);
+ break;
+
case eCSR_ROAM_STA_CHANNEL_SWITCH:
{
hdd_adapter_t *pHostapdAdapter = NULL;
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 6a05948..a3ed21f 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -9141,7 +9141,8 @@
}
#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
@@ -19507,6 +19508,64 @@
}
#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)
+{
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ int ret;
+
+ if (hdd_get_conparam() == VOS_FTM_MODE) {
+ hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
+ return -EPERM;
+ }
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (ret)
+ return ret;
+
+ hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
+ params->status);
+
+ sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, 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;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+#endif
+
#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
struct net_device *dev,
@@ -22548,5 +22607,9 @@
.channel_switch = wlan_hdd_cfg80211_channel_switch,
#endif
+#if defined(WLAN_FEATURE_SAE) && \
+ defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
+ .external_auth = wlan_hdd_cfg80211_external_auth,
+#endif
};
diff --git a/CORE/VOSS/src/vos_sched.c b/CORE/VOSS/src/vos_sched.c
index 19d6f0b..2fa2b6a 100644
--- a/CORE/VOSS/src/vos_sched.c
+++ b/CORE/VOSS/src/vos_sched.c
@@ -2226,3 +2226,13 @@
vos_dump_stack(TX_Thread);
vos_dump_stack(RX_Thread);
}
+
+int vos_get_gfp_flags(void)
+{
+ int flags = GFP_KERNEL;
+
+ if (in_interrupt() || in_atomic() || irqs_disabled())
+ flags = GFP_ATOMIC;
+
+ return flags;
+}
diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h
index 3a92a65..8d75a8b 100644
--- a/CORE/VOSS/src/vos_sched.h
+++ b/CORE/VOSS/src/vos_sched.h
@@ -550,5 +550,11 @@
bool vos_is_wd_thread(int threadId);
void vos_dump_stack(uint8_t value);
void vos_dump_thread_stacks(int threadId);
-
+/**
+ * vos_get_gfp_flags(): get GFP flags
+ *
+ * Based on the scheduled context, return GFP flags
+ * Return: gfp flags
+ */
+int vos_get_gfp_flags(void);
#endif // #if !defined __VOSS_SCHED_H