[NEUS7920-218] [9610][7885][7872][7570] wlbt: Drv Changes for Wpa3
authorKavitha Velayutham <k.velayutham@samsung.com>
Tue, 30 Oct 2018 13:39:34 +0000 (19:09 +0530)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 28 Jun 2019 14:45:02 +0000 (23:45 +0900)
Driver changes for Wpa3

SCSC-Bug-Id: SSB-48137
Change-Id: Ifc30ea1c04dab0de30756752efe6c86faf1a7ce8
Signed-off-by: Kavitha Velayutham <k.velayutham@samsung.com>
16 files changed:
arch/arm64/configs/erd9610_defconfig
drivers/net/wireless/scsc/Kconfig
drivers/net/wireless/scsc/cfg80211_ops.c
drivers/net/wireless/scsc/dev.h
drivers/net/wireless/scsc/fapi.h
drivers/net/wireless/scsc/mlme.c
drivers/net/wireless/scsc/mlme.h
drivers/net/wireless/scsc/rx.c
drivers/net/wireless/scsc/sap_mlme.c
drivers/net/wireless/scsc/sap_mlme.h
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/wireless/Kconfig
net/wireless/nl80211.c
net/wireless/rdev-ops.h
net/wireless/trace.h

index 07fdaf8d3e344626aac82ed1872621d7a6e4c6ee..33ef5b27d7a09e110e528e901614700da2ff02db 100644 (file)
@@ -262,6 +262,7 @@ CONFIG_SCSC_WLAN_DEBUG=y
 CONFIG_SCSC_WLAN_WIFI_SHARING=y
 # CONFIG_SCSC_WLAN_SINGLE_ANTENNA is not set
 # CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE is not set
+CONFIG_SCSC_WLAN_SAE_CONFIG=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_KEYRESET=y
 CONFIG_KEYBOARD_GPIO=y
index 675aa64314abe942695fa69993be0a85cbe13c1c..3acc6cfb3decb021090094fa749bc22ed7cb04cb 100755 (executable)
@@ -156,6 +156,12 @@ config SCSC_WLAN_WIFI_SHARING
        ---help---
          This option tells if wifi sharing is supported or not.
 
+config SCSC_WLAN_SAE_CONFIG
+        bool "Wpa3 Support"
+        default n
+        ---help---
+          This option tells if wpa3  is supported or not.
+
 config SCSC_WLAN_ENABLE_MAC_RANDOMISATION
         bool "Wifi Mac Randomization Support"
         default n
index e3d2eff6ec7d5cf3d9226c2548ebcde0869760c3..42c2da2a624affc3b03edc948a78849ccd23cdb3 100755 (executable)
@@ -1075,8 +1075,24 @@ int slsi_connect(struct wiphy *wiphy, struct net_device *dev,
         */
        netif_carrier_on(dev);
        ndev_vif->sta.vif_status = SLSI_VIF_STATUS_CONNECTING;
-       r = slsi_mlme_connect(sdev, dev, sme, channel, bssid);
+       if (sme->auth_type == NL80211_AUTHTYPE_SAE && (sme->flags & CONNECT_REQ_EXTERNAL_AUTH_SUPPORT)) {
+               const u8 *rsn;
+
+               ndev_vif->sta.crypto.wpa_versions = 3;
+               rsn = cfg80211_find_ie(WLAN_EID_RSN, ndev_vif->sta.sta_bss->ies->data, ndev_vif->sta.sta_bss->ies->len);
+               if (rsn) {
+                       int pos;
+
+                       pos = 7 + 2 + (rsn[8] * 4) + 2;
+                       ndev_vif->sta.crypto.akm_suites[0] = ((rsn[pos + 4] << 24) | (rsn[pos + 3] << 16) | (rsn[pos + 2] << 8) | (rsn[pos + 1]));
+               }
+
+               SLSI_NET_DBG1(dev, SLSI_CFG80211, "RSN IE: : %1d\n", ndev_vif->sta.crypto.akm_suites[0]);
+       } else {
+               ndev_vif->sta.crypto.wpa_versions = 0;
+       }
 
+       r = slsi_mlme_connect(sdev, dev, sme, channel, bssid);
        if (r != 0) {
                ndev_vif->sta.is_wps = false;
                SLSI_NET_ERR(dev, "connect failed: %d\n", r);
@@ -2681,8 +2697,8 @@ static int slsi_wlan_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev,
        int                r = 0;
        struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
 
-       slsi_wlan_dump_public_action_subtype(sdev, mgmt, true);
-
+       if (!ieee80211_is_auth(mgmt->frame_control))
+               slsi_wlan_dump_public_action_subtype(sdev, mgmt, true);
        if (!ndev_vif->activated) {
                r = slsi_wlan_unsync_vif_activate(sdev, dev, chan, wait);
                if (r)
@@ -2696,7 +2712,12 @@ static int slsi_wlan_mgmt_tx(struct slsi_dev *sdev, struct net_device *dev,
                queue_delayed_work(sdev->device_wq, &ndev_vif->unsync.hs2_del_vif_work, msecs_to_jiffies(wait));
        } else {
                /* vif is active*/
-               if (ndev_vif->vif_type == FAPI_VIFTYPE_UNSYNCHRONISED) {
+               if (ieee80211_is_auth(mgmt->frame_control)) {
+                       SLSI_NET_DBG1(dev, SLSI_CFG80211, "Transmit on the current frequency\n");
+                       r = slsi_mlme_send_frame_mgmt(sdev, dev, buf, len, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME, FAPI_MESSAGETYPE_IEEE80211_MGMT_NOT_ACTION, host_tag, 0, wait * 1000, 0);
+                       if (r)
+                               return r;
+               } else if (ndev_vif->vif_type == FAPI_VIFTYPE_UNSYNCHRONISED) {
                        cancel_delayed_work(&ndev_vif->unsync.hs2_del_vif_work);
                        /*even if we fail to cancel the delayed work, we shall go ahead and send action frames*/
                        if (ndev_vif->driver_channel != chan->hw_value) {
@@ -2791,16 +2812,19 @@ int slsi_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
 
        SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
 
-       SLSI_NET_DBG2(dev, SLSI_CFG80211, "Mgmt Frame Tx: iface_num = %d, channel = %d, wait = %d, noAck = %d,"
-                     "offchannel = %d, mgmt->frame_control = %d, vif_type = %d\n", ndev_vif->ifnum, chan->hw_value,
-                     wait, dont_wait_for_ack, offchan, mgmt->frame_control, ndev_vif->vif_type);
+       if (!(ieee80211_is_auth(mgmt->frame_control))) {
+               SLSI_NET_DBG2(dev, SLSI_CFG80211, "Mgmt Frame Tx: iface_num = %d, channel = %d, wait = %d, noAck = %d,"
+                             "offchannel = %d, mgmt->frame_control = %d, vif_type = %d\n", ndev_vif->ifnum, chan->hw_value,
+                             wait, dont_wait_for_ack, offchan, mgmt->frame_control, ndev_vif->vif_type);
+       } else {
+               SLSI_NET_DBG2(dev, SLSI_CFG80211, "Received Auth Frame");
+       }
 
        if (!(ieee80211_is_mgmt(mgmt->frame_control))) {
                SLSI_NET_ERR(dev, "Drop Tx frame: Not a Management frame\n");
                r = -EINVAL;
                goto exit;
        }
-
        if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) {
                r = slsi_wlan_mgmt_tx(SDEV_FROM_WIPHY(wiphy), dev, chan, wait, buf, len, dont_wait_for_ack, cookie);
                goto exit;
@@ -2912,6 +2936,18 @@ int slsi_set_txq_params(struct wiphy *wiphy, struct net_device *ndev,
        return r;
 }
 
+int slsi_synchronised_response(struct wiphy *wiphy, struct net_device *dev,
+                              struct cfg80211_external_auth_params *params)
+{
+       struct slsi_dev                   *sdev = SDEV_FROM_WIPHY(wiphy);
+       struct netdev_vif                 *ndev_vif = netdev_priv(dev);
+       int r;
+
+       SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+       r = slsi_mlme_synchronised_response(sdev, dev, params);
+       SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+       return r;
+}
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
 static int slsi_update_ft_ies(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
 {
@@ -3004,6 +3040,7 @@ static struct cfg80211_ops slsi_ops = {
        .mgmt_tx = slsi_mgmt_tx,
        .mgmt_tx_cancel_wait = slsi_mgmt_tx_cancel_wait,
        .set_txq_params = slsi_set_txq_params,
+       .external_auth = slsi_synchronised_response,
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
        .set_mac_acl = slsi_set_mac_acl,
        .update_ft_ies = slsi_update_ft_ies,
@@ -3178,12 +3215,14 @@ static const struct ieee80211_txrx_stypes
                                   ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
        [NL80211_IFTYPE_AP] = {
                .tx = 0xffff,
-               .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
+               .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
+                     BIT(IEEE80211_STYPE_AUTH >> 4)
        },
        [NL80211_IFTYPE_STATION] = {
                .tx = 0xffff,
                .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
-                     BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+                     BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+                     BIT(IEEE80211_STYPE_AUTH >> 4)
        },
        [NL80211_IFTYPE_P2P_GO] = {
                .tx = 0xffff,
@@ -3408,6 +3447,9 @@ struct slsi_dev                           *slsi_cfg80211_new(struct device *dev)
 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
        wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
 #endif
+#endif
+#ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
+       wiphy->features |= NL80211_FEATURE_SAE;
 #endif
        return sdev;
 }
index f74715cae579fc19ae1f1d66e252853acde7b703..b808dcaa484843cc8652ef6b75457c7f8f65dfe1 100755 (executable)
@@ -555,6 +555,7 @@ struct slsi_vif_sta {
 
        /*This structure is used to store last disconnected bss info and valid even when vif is deactivated. */
        struct slsi_last_connected_bss last_connected_bss;
+       struct cfg80211_crypto_settings crypto;
 };
 
 struct slsi_vif_unsync {
index b72e3a9dffbd84337e5c4614fde3db4b1f6df135..e167d8d70fa0356a0e181878b57a9f96e84614d8 100644 (file)
@@ -424,6 +424,8 @@ static inline struct slsi_skb_cb *slsi_skb_cb_init(struct sk_buff *skb)
 #define FAPI_MESSAGETYPE_WAI_MESSAGE          0x0007
 #define FAPI_MESSAGETYPE_PERIODIC_OFFLOAD     0x0008
 #define FAPI_MESSAGETYPE_IEEE80211_ACTION     0x0010
+/* TBD: Auto generate to add this */
+#define FAPI_MESSAGETYPE_IEEE80211_MGMT_NOT_ACTION 0x0011
 
 #define FAPI_MODE_SOURCE     0x0001
 #define FAPI_MODE_SINK       0x0002
index d38507b3dc71601afdb6269b3d4e562a3abb36c9..fc23b078969a8d3587ef354ed1dec8608f360aa0 100755 (executable)
@@ -2169,6 +2169,9 @@ int slsi_mlme_connect(struct slsi_dev *sdev, struct net_device *dev, struct cfg8
        case NL80211_AUTHTYPE_OPEN_SYSTEM:
        case NL80211_AUTHTYPE_SHARED_KEY:
                break;
+       case NL80211_AUTHTYPE_SAE:
+               auth_type = NL80211_AUTHTYPE_NETWORK_EAP;
+               break;
        case NL80211_AUTHTYPE_AUTOMATIC:
                /* In case of WEP, need to try both open and shared.
                 * FW does this if auth is shared_key. So set it to shared.
@@ -2889,6 +2892,33 @@ int slsi_mlme_powermgt(struct slsi_dev *sdev, struct net_device *dev, u16 power_
        return slsi_mlme_powermgt_unlocked(sdev, dev, power_mode);
 }
 
+int slsi_mlme_synchronised_response(struct slsi_dev *sdev, struct net_device *dev,
+                                   struct cfg80211_external_auth_params *params)
+{
+       struct netdev_vif *ndev_vif = netdev_priv(dev);
+       struct sk_buff    *req;
+       struct sk_buff    *cfm;
+       if (ndev_vif->activated) {
+               SLSI_NET_DBG3(dev, SLSI_MLME, "MLME_SPARE_SIGNAL_1_RES\n");
+
+               req = fapi_alloc(mlme_spare_signal_1_res, MLME_SPARE_SIGNAL_1_RES, ndev_vif->ifnum, 0);
+               if (!req)
+                       return -ENOMEM;
+
+               fapi_set_low16_u32(req, u.mlme_spare_signal_1_res.spare_1, params->status);
+               fapi_set_high16_u32(req, u.mlme_spare_signal_1_res.spare_1, *(u16 *)(&params->bssid[0]));
+               fapi_set_u32(req, u.mlme_spare_signal_1_res.spare_2, *(u32 *)(&params->bssid[2]));
+
+               SLSI_NET_DBG2(dev, SLSI_MLME, "mlme_synchronised_response(vif:%d) status:%d\n",
+                             ndev_vif->ifnum, params->status);
+               cfm = slsi_mlme_req_no_cfm(sdev, dev, req);
+               if (cfm)
+                       SLSI_NET_ERR(dev, "Received cfm for MLME_SPARE_SIGNAL_1_RES\n");
+       } else
+               SLSI_NET_DBG1(dev, SLSI_MLME, "vif is not active");
+
+       return 0;
+}
 int slsi_mlme_register_action_frame(struct slsi_dev *sdev, struct net_device *dev, u32 af_bitmap_active, u32 af_bitmap_suspended)
 {
        struct netdev_vif *ndev_vif = netdev_priv(dev);
index dd9e6ed8c15b609ad51f8d12fa74a33082080b9e..230d1602dc855bbc5d8897182474e2ed05099677 100755 (executable)
@@ -212,6 +212,8 @@ int slsi_mlme_connect_scan(struct slsi_dev *sdev, struct net_device *dev,
 int slsi_mlme_powermgt(struct slsi_dev *sdev, struct net_device *dev, u16 ps_mode);
 int slsi_mlme_powermgt_unlocked(struct slsi_dev *sdev, struct net_device *dev, u16 ps_mode);
 int slsi_mlme_register_action_frame(struct slsi_dev *sdev, struct net_device *dev,  u32 af_bitmap_active, u32 af_bitmap_suspended);
+int slsi_mlme_synchronised_response(struct slsi_dev *sdev, struct net_device *dev,
+                                   struct cfg80211_external_auth_params *params);
 int slsi_mlme_channel_switch(struct slsi_dev *sdev, struct net_device *dev,  u16 center_freq, u16 chan_info);
 int slsi_mlme_add_info_elements(struct slsi_dev *sdev, struct net_device *dev,  u16 purpose, const u8 *ies, const u16 ies_len);
 int slsi_mlme_send_frame_mgmt(struct slsi_dev *sdev, struct net_device *dev, const u8 *frame, int frame_len, u16 data_desc, u16 msg_type, u16 host_tag, u16 freq, u32 dwell_time, u32 period);
index f8a24d3069dcf21309cc2ed2ae92c6686f220a38..aacfe0a32091b7e57acccac5c3f6d40faf13768d 100755 (executable)
@@ -1588,6 +1588,32 @@ void slsi_rx_buffered_frames(struct slsi_dev *sdev, struct net_device *dev, stru
        }
 }
 
+void slsi_rx_synchronised_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
+{
+       struct netdev_vif *ndev_vif = netdev_priv(dev);
+       const u8  *connecting_ssid = NULL;
+       struct cfg80211_external_auth_params auth_request;
+       int r;
+
+       SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
+       SLSI_NET_DBG1(dev, SLSI_MLME, "Received slsi_rx_synchronised_ind\n");
+       if (ndev_vif->sta.sta_bss->ies->len)
+               connecting_ssid = cfg80211_find_ie(WLAN_EID_SSID, ndev_vif->sta.sta_bss->ies->data,
+                                                  ndev_vif->sta.sta_bss->ies->len);
+
+       auth_request.action = NL80211_EXTERNAL_AUTH_START;
+       memcpy(auth_request.bssid, ndev_vif->sta.sta_bss->bssid, ETH_ALEN);
+       if (connecting_ssid && (connecting_ssid[1] > 0)) {
+               memcpy(auth_request.ssid.ssid, &connecting_ssid[2], connecting_ssid[1]);
+               auth_request.ssid.ssid_len = connecting_ssid[1];
+       }
+       auth_request.key_mgmt_suite = ndev_vif->sta.crypto.akm_suites[0];
+       r = cfg80211_external_auth_request(dev, &auth_request, GFP_KERNEL);
+       if (r)
+               SLSI_NET_DBG1(dev, SLSI_MLME, "cfg80211_external_auth_request failed");
+       SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
+}
+
 void slsi_rx_connected_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
 {
        struct netdev_vif *ndev_vif = netdev_priv(dev);
@@ -1817,6 +1843,28 @@ void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct s
                scsc_log_collector_schedule_collection(SCSC_LOG_HOST_WLAN, SCSC_LOG_HOST_WLAN_REASON_CONNECT_ERR);
 #endif
                status = fw_result_code;
+#ifdef CONFIG_SCSC_WLAN_SAE_CONFIG
+       if (ndev_vif->sta.crypto.wpa_versions == 3) {
+               const u8  *connecting_ssid = NULL;
+               int r;
+               struct cfg80211_external_auth_params auth_request;
+
+               if (ndev_vif->sta.sta_bss->ies->len)
+                       connecting_ssid = cfg80211_find_ie(WLAN_EID_SSID, ndev_vif->sta.sta_bss->ies->data,
+                                                          ndev_vif->sta.sta_bss->ies->len);
+
+               auth_request.action = NL80211_EXTERNAL_AUTH_ABORT;
+               memcpy(auth_request.bssid, ndev_vif->sta.sta_bss->bssid, ETH_ALEN);
+               if (connecting_ssid && (connecting_ssid[1] > 0)) {
+                       memcpy(auth_request.ssid.ssid, &connecting_ssid[2], connecting_ssid[1]);
+                       auth_request.ssid.ssid_len = connecting_ssid[1];
+               }
+               auth_request.key_mgmt_suite = ndev_vif->sta.crypto.akm_suites[0];
+               r = cfg80211_external_auth_request(dev, &auth_request, GFP_KERNEL);
+               if (r)
+                       SLSI_NET_DBG1(dev, SLSI_MLME, "cfg80211_external_auth_request Abort failed");
+       }
+#endif
        } else {
                SLSI_INFO(sdev, "Received Association Response\n");
                if (!peer || !peer->assoc_ie) {
@@ -2314,9 +2362,12 @@ void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, s
                if (!mgmt_len)
                        goto exit;
                mgmt = fapi_get_mgmt(skb);
+               if (ieee80211_is_auth(mgmt->frame_control)) {
+                       cfg80211_rx_mgmt(&ndev_vif->wdev, frequency, 0, (const u8 *)mgmt, mgmt_len, GFP_ATOMIC);
+                       goto exit;
+               }
                if (WARN_ON(!(ieee80211_is_action(mgmt->frame_control))))
                        goto exit;
-
                if (SLSI_IS_VIF_INDEX_WLAN(ndev_vif)) {
 #ifdef CONFIG_SCSC_WLAN_WES_NCHO
                        if (slsi_is_wes_action_frame(mgmt)) {
index 2610eb0f3facab4910896dc9e7064ab698d143cd..35936de57e16173dec14ea77e9f36d4843dd4ac5 100755 (executable)
@@ -191,6 +191,10 @@ static int slsi_rx_netdev_mlme(struct slsi_dev *sdev, struct net_device *dev, st
                slsi_kfree_skb(skb);
                break;
 #endif
+       case MLME_SPARE_SIGNAL_1_IND:
+               slsi_rx_synchronised_ind(sdev, dev, skb);
+               slsi_kfree_skb(skb);
+               break;
        default:
                slsi_kfree_skb(skb);
                SLSI_NET_ERR(dev, "Unhandled Ind: 0x%.4x\n", id);
index e30887e7f31dbacb21aa533fe230dd6d9454fac4..29e8efa71a03ababa203f9464a92ba80c981d7f4 100755 (executable)
@@ -15,6 +15,7 @@ int sap_mlme_deinit(void);
 void slsi_rx_scan_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
 void slsi_rx_scan_done_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
 void slsi_rx_channel_switched_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
+void slsi_rx_synchronised_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
 void slsi_rx_connect_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
 void slsi_rx_connected_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
 void slsi_rx_received_frame_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb);
index ea0ed58db97e2116131bab1931ec11dae10764c4..7c57ce16a9bddc783f43ed9231e0891397a1eb51 100644 (file)
@@ -1897,11 +1897,18 @@ struct cfg80211_auth_request {
  * @ASSOC_REQ_DISABLE_HT:  Disable HT (802.11n)
  * @ASSOC_REQ_DISABLE_VHT:  Disable VHT
  * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association
+ * @CONNECT_REQ_EXTERNAL_AUTH_SUPPORT: User space indicates external
+ *  authentication capability. Drivers can offload authentication to
+ *  userspace if this flag is set. Only applicable for cfg80211_connect()
+ *  request (connect callback).
  */
 enum cfg80211_assoc_req_flags {
-       ASSOC_REQ_DISABLE_HT            = BIT(0),
-       ASSOC_REQ_DISABLE_VHT           = BIT(1),
-       ASSOC_REQ_USE_RRM               = BIT(2),
+       ASSOC_REQ_DISABLE_HT                    = BIT(0),
+       ASSOC_REQ_DISABLE_VHT                   = BIT(1),
+       ASSOC_REQ_USE_RRM                       = BIT(2),
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       CONNECT_REQ_EXTERNAL_AUTH_SUPPORT       = BIT(3),
+#endif
 };
 
 /**
@@ -2586,6 +2593,34 @@ struct cfg80211_pmk_conf {
        const u8 *pmk;
        const u8 *pmk_r0_name;
 };
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * struct cfg80211_external_auth_params - Trigger External authentication.
+ *
+ * Commonly used across the external auth request and event interfaces.
+ *
+ * @action: action type / trigger for external authentication. Only significant
+ *     for the authentication request event interface (driver to user space).
+ * @bssid: BSSID of the peer with which the authentication has
+ *     to happen. Used by both the authentication request event and
+ *     authentication response command interface.
+ * @ssid: SSID of the AP.  Used by both the authentication request event and
+ *     authentication response command interface.
+ * @key_mgmt_suite: AKM suite of the respective authentication. Used by the
+ *     authentication request event interface.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful authentication,
+ *     use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
+ *     the real status code for failures. Used only for the authentication
+ *     response command interface (user space to driver).
+ */
+struct cfg80211_external_auth_params {
+       enum nl80211_external_auth_action action;
+       u8 bssid[ETH_ALEN] __aligned(2);
+       struct cfg80211_ssid ssid;
+       unsigned int key_mgmt_suite;
+       u16 status;
+};
+#endif
 
 /**
  * struct cfg80211_ops - backend description for wireless configuration
@@ -2910,6 +2945,9 @@ struct cfg80211_pmk_conf {
  *     (invoked with the wireless_dev mutex held)
  * @del_pmk: delete the previously configured PMK for the given authenticator.
  *     (invoked with the wireless_dev mutex held)
+ *
+ * @external_auth: indicates result of offloaded authentication processing from
+ *     user space
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3203,6 +3241,10 @@ struct cfg80211_ops {
                           const struct cfg80211_pmk_conf *conf);
        int     (*del_pmk)(struct wiphy *wiphy, struct net_device *dev,
                           const u8 *aa);
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       int     (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
+                                struct cfg80211_external_auth_params *params);
+#endif
 };
 
 /*
@@ -6188,6 +6230,19 @@ void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
 /* ethtool helper */
 void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
 
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * cfg80211_external_auth_request - userspace request for authentication
+ * @netdev: network device
+ * @params: External authentication parameters
+ * @gfp: allocation flags
+ * Returns: 0 on success, < 0 on error
+ */
+int cfg80211_external_auth_request(struct net_device *netdev,
+                                  struct cfg80211_external_auth_params *params,
+                                  gfp_t gfp);
+#endif
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
index f41ea5af22eed7802e301c4d621184a421945620..3b456638071f3b2a4f5017f48292a0166257b8e6 100644 (file)
  *     configured PMK for the authenticator address identified by
  *     &NL80211_ATTR_MAC.
  *
+ * @NL80211_CMD_EXTERNAL_AUTH: This interface is exclusively defined for host
+ *     drivers that do not define separate commands for authentication and
+ *     association, but rely on user space for the authentication to happen.
+ *     This interface acts both as the event request (driver to user space)
+ *     to trigger the authentication and command response (userspace to
+ *     driver) to indicate the authentication status.
+ *
+ *     User space uses the %NL80211_CMD_CONNECT command to the host driver to
+ *     trigger a connection. The host driver selects a BSS and further uses
+ *     this interface to offload only the authentication part to the user
+ *     space. Authentication frames are passed between the driver and user
+ *     space through the %NL80211_CMD_FRAME interface. Host driver proceeds
+ *     further with the association after getting successful authentication
+ *     status. User space indicates the authentication status through
+ *     %NL80211_ATTR_STATUS_CODE attribute in %NL80211_CMD_EXTERNAL_AUTH
+ *     command interface.
+ *
+ *     Host driver reports this status on an authentication failure to the
+ *     user space through the connect result as the user space would have
+ *     initiated the connection through the connect request.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -1184,7 +1205,9 @@ enum nl80211_commands {
 
        NL80211_CMD_SET_PMK,
        NL80211_CMD_DEL_PMK,
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       NL80211_CMD_EXTERNAL_AUTH,
+#endif
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
@@ -2139,6 +2162,16 @@ enum nl80211_commands {
  *     the driver or is not needed (because roaming used the Fast Transition
  *     protocol).
  *
+ * @NL80211_ATTR_EXTERNAL_AUTH_ACTION: Identify the requested external
+ *     authentication operation (u32 attribute with an
+ *     &enum nl80211_external_auth_action value). This is used with the
+ *     &NL80211_CMD_EXTERNAL_AUTH request event.
+ * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
+ *     space supports external authentication. This attribute shall be used
+ *     only with %NL80211_CMD_CONNECT request. The driver may offload
+ *     authentication processing to user space if this capability is indicated
+ *     in NL80211_CMD_CONNECT requests from the user space.
+ *
  * @NUM_NL80211_ATTR: total number of nl80211_attrs available
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2564,6 +2597,10 @@ enum nl80211_attrs {
        NL80211_ATTR_WANT_1X_4WAY_HS,
        NL80211_ATTR_PMKR0_NAME,
        NL80211_ATTR_PORT_AUTHORIZED,
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       NL80211_ATTR_EXTERNAL_AUTH_ACTION,
+       NL80211_ATTR_EXTERNAL_AUTH_SUPPORT,
+#endif
 
        /* add attributes here, update the policy in nl80211.c */
 
@@ -5418,5 +5455,16 @@ enum nl80211_nan_match_attributes {
        NUM_NL80211_NAN_MATCH_ATTR,
        NL80211_NAN_MATCH_ATTR_MAX = NUM_NL80211_NAN_MATCH_ATTR - 1
 };
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+/**
+ * nl80211_external_auth_action - Action to perform with external
+ *     authentication request. Used by NL80211_ATTR_EXTERNAL_AUTH_ACTION.
+ * @NL80211_EXTERNAL_AUTH_START: Start the authentication.
+ * @NL80211_EXTERNAL_AUTH_ABORT: Abort the ongoing authentication.
+ */
+enum nl80211_external_auth_action {
+       NL80211_EXTERNAL_AUTH_START,
+       NL80211_EXTERNAL_AUTH_ABORT,
+};
+#endif
 #endif /* __LINUX_NL80211_H */
index 01ff97b5d277fdefadfd171fd43f373c49a541e0..f168e98eb1cebc7bc1d5a4c895b59f3adee274c7 100755 (executable)
@@ -130,6 +130,17 @@ config CFG80211_DEFAULT_PS
          applications instead -- they need to register their network
          latency requirement, see Documentation/power/pm_qos_interface.txt.
 
+config CFG80211_SLSI_SAE
+        bool "Enable SAE in Kernel"
+        depends on CFG80211
+        default y
+        help
+          This option enables sae in kernel.
+
+          This Option enables SAE in CFG.
+          This option needs to be enabled if the kernel version by default doesnt
+          support SAE.
+
 config CFG80211_DEBUGFS
        bool "cfg80211 DebugFS entries"
        depends on CFG80211
index 46e9812d13c02afa92d6ab70ca111ed282568cd9..108db3b84bd5b6330f14d958cbae26a677bf02e0 100644 (file)
@@ -421,6 +421,9 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
        [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
        [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
        [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
+#endif
 };
 
 /* policy for the key attributes */
@@ -3864,8 +3867,8 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
                        return false;
                return true;
        case NL80211_CMD_CONNECT:
-               /* SAE not supported yet */
-               if (auth_type == NL80211_AUTHTYPE_SAE)
+               if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
+                   auth_type == NL80211_AUTHTYPE_SAE)
                        return false;
                /* FILS with SK PFS or PK not supported yet */
                if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
@@ -9051,7 +9054,10 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
                kzfree(connkeys);
                return -EINVAL;
        }
-
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]))
+               connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
+#endif
        wdev_lock(dev->ieee80211_ptr);
 
        err = cfg80211_connect(rdev, dev, &connect, connkeys,
@@ -12376,6 +12382,43 @@ static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
        return ret;
 }
 
+#ifdef CONFIG_CFG80211_SLSI_SAE
+static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct net_device *dev = info->user_ptr[1];
+       struct cfg80211_external_auth_params params;
+
+       if (!rdev->ops->external_auth)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_SSID])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_BSSID])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_STATUS_CODE])
+               return -EINVAL;
+
+       memset(&params, 0, sizeof(params));
+
+       params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+       if (params.ssid.ssid_len == 0 ||
+           params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
+               return -EINVAL;
+       memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
+              params.ssid.ssid_len);
+
+       memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
+              ETH_ALEN);
+
+       params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
+
+       return rdev_external_auth(rdev, dev, &params);
+}
+#endif
+
 #define NL80211_FLAG_NEED_WIPHY                0x01
 #define NL80211_FLAG_NEED_NETDEV       0x02
 #define NL80211_FLAG_NEED_RTNL         0x04
@@ -13265,6 +13308,16 @@ static const struct genl_ops nl80211_ops[] = {
                .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
                                  NL80211_FLAG_NEED_RTNL,
        },
+#ifdef CONFIG_CFG80211_SLSI_SAE
+       {
+               .cmd = NL80211_CMD_EXTERNAL_AUTH,
+               .doit = nl80211_external_auth,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+#endif
 
 };
 
@@ -13591,7 +13644,6 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
 {
        struct sk_buff *msg;
        void *hdr;
-
        msg = nlmsg_new(100 + len, gfp);
        if (!msg)
                return;
@@ -15248,6 +15300,48 @@ void nl80211_send_ap_stopped(struct wireless_dev *wdev)
        nlmsg_free(msg);
 }
 
+#ifdef CONFIG_CFG80211_SLSI_SAE
+int cfg80211_external_auth_request(struct net_device *dev,
+                                  struct cfg80211_external_auth_params *params,
+                                  gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+
+       if (!wdev->conn_owner_nlportid)
+               return -EINVAL;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+       if (!msg)
+               return -ENOMEM;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
+       if (!hdr)
+               goto nla_put_failure;
+
+       if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
+           nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
+           nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
+           nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
+                       params->action) ||
+           nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
+           nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
+                   params->ssid.ssid))
+               goto nla_put_failure;
+
+       genlmsg_end(msg, hdr);
+       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
+                       wdev->conn_owner_nlportid);
+       return 0;
+
+ nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(cfg80211_external_auth_request);
+#endif
 /* initialisation/exit functions */
 
 int __init nl80211_init(void)
index 0c06240d25afc9da33ddd23c09c719cd2c06ebce..0081dc3ef343874fa63dd003944f0ce39bb4856a 100644 (file)
@@ -1190,4 +1190,21 @@ static inline int rdev_del_pmk(struct cfg80211_registered_device *rdev,
        trace_rdev_return_int(&rdev->wiphy, ret);
        return ret;
 }
+
+#ifdef CONFIG_CFG80211_SLSI_SAE
+static inline int
+rdev_external_auth(struct cfg80211_registered_device *rdev,
+                  struct net_device *dev,
+                  struct cfg80211_external_auth_params *params)
+{
+       int ret = -EOPNOTSUPP;
+
+       trace_rdev_external_auth(&rdev->wiphy, dev, params);
+       if (rdev->ops->external_auth)
+               ret = rdev->ops->external_auth(&rdev->wiphy, dev, params);
+       trace_rdev_return_int(&rdev->wiphy, ret);
+       return ret;
+}
+#endif
+
 #endif /* __CFG80211_RDEV_OPS */
index f3353fe5b35b89fb1b0572a2890f47133ed146c9..0580f278d6d7fbdd2db569cb3aa138fcddbc8fd1 100644 (file)
@@ -2319,6 +2319,31 @@ TRACE_EVENT(rdev_del_pmk,
                  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(aa))
 );
 
+#ifdef CONFIG_CFG80211_SLSI_SAE
+TRACE_EVENT(rdev_external_auth,
+           TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
+                    struct cfg80211_external_auth_params *params),
+           TP_ARGS(wiphy, netdev, params),
+           TP_STRUCT__entry(WIPHY_ENTRY
+                            NETDEV_ENTRY
+                            MAC_ENTRY(bssid)
+                            __array(u8, ssid, IEEE80211_MAX_SSID_LEN + 1)
+                            __field(u16, status)
+           ),
+           TP_fast_assign(WIPHY_ASSIGN;
+                          NETDEV_ASSIGN;
+                          MAC_ASSIGN(bssid, params->bssid);
+                          memset(__entry->ssid, 0, IEEE80211_MAX_SSID_LEN + 1);
+                          memcpy(__entry->ssid, params->ssid.ssid,
+                                 params->ssid.ssid_len);
+                          __entry->status = params->status;
+           ),
+           TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", bssid: " MAC_PR_FMT
+                     ", ssid: %s, status: %u", WIPHY_PR_ARG, NETDEV_PR_ARG,
+                     __entry->bssid, __entry->ssid, __entry->status)
+);
+#endif
+
 /*************************************************************
  *          cfg80211 exported functions traces              *
  *************************************************************/