staging: ath6kl: open/shared auth implementation
authorNaveen Singh <nsingh@atheros.com>
Fri, 29 Apr 2011 17:02:31 +0000 (20:02 +0300)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 3 May 2011 19:09:43 +0000 (12:09 -0700)
If the wpa_supplicant conf file supplies both open and shared
algorithm, and AP is configured as shared then connection never
happens. Since it is a FMAC driver additional logic is added in
driver which first detects this, then tries open algorithm for the
first time and when it fails tries the shared algo.

kvalo: fix style issues

Signed-off-by: Naveen Singh <nsingh@atheros.com>
Signed-off-by: Kalle Valo <kalle.valo@atheros.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/ath6kl/include/common/wmi.h
drivers/staging/ath6kl/os/linux/ar6000_drv.c
drivers/staging/ath6kl/os/linux/cfg80211.c
drivers/staging/ath6kl/os/linux/include/ar6000_drv.h

index 24636e6..6549839 100644 (file)
@@ -521,6 +521,11 @@ typedef enum {
     LEAP_AUTH           = 0x04,  /* different from IEEE_AUTH_MODE definitions */
 } DOT11_AUTH_MODE;
 
+enum {
+       AUTH_IDLE,
+       AUTH_OPEN_IN_PROGRESS,
+};
+
 typedef enum {
     NONE_AUTH           = 0x01,
     WPA_AUTH            = 0x02,
index 1c7c159..93ebff4 100644 (file)
@@ -1678,6 +1678,7 @@ ar6000_avail_ev(void *context, void *hif_handle)
     wdev->netdev = dev;
     ar->arNetworkType = INFRA_NETWORK;
     ar->smeState = SME_DISCONNECTED;
+    ar->arAutoAuthStage = AUTH_IDLE;
 
     init_netdev(dev, ifname);
 
index f6e3817..efd4ae5 100644 (file)
@@ -172,6 +172,12 @@ ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type)
     case NL80211_AUTHTYPE_NETWORK_EAP:
         ar->arDot11AuthMode = LEAP_AUTH;
         break;
+
+    case NL80211_AUTHTYPE_AUTOMATIC:
+        ar->arDot11AuthMode = OPEN_AUTH;
+        ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
+        break;
+
     default:
         ar->arDot11AuthMode = OPEN_AUTH;
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -460,6 +466,8 @@ ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel,
     assocReqLen -= assocReqIeOffset;
     assocRespLen -= assocRespIeOffset;
 
+    ar->arAutoAuthStage = AUTH_IDLE;
+
     if((ADHOC_NETWORK & networkType)) {
         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -633,6 +641,8 @@ ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
                                u8 *assocInfo, u16 protocolReasonStatus)
 {
 
+    u16 status;
+
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
 
     if (ar->scan_request) {
@@ -663,23 +673,70 @@ ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason,
             /* connect cmd failed */
             wmi_disconnect_cmd(ar->arWmi);
         } else if (reason == DISCONNECT_CMD) {
-            /* connection loss due to disconnect cmd or low rssi */
-            ar->arConnectPending = false;   
-            if (ar->smeState == SME_CONNECTING) {
-                cfg80211_connect_result(ar->arNetDev, bssid,
-                                        NULL, 0,
-                                        NULL, 0,
-                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                        GFP_KERNEL);
-            } else {
-                cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
-            }
-            ar->smeState = SME_DISCONNECTED;
-        }
+               if (ar->arAutoAuthStage) {
+                       /*
+                        * If the current auth algorithm is open try shared
+                        * and make autoAuthStage idle. We do not make it
+                        * leap for now being.
+                        */
+                       if (ar->arDot11AuthMode == OPEN_AUTH) {
+                               struct ar_key *key = NULL;
+                               key = &ar->keys[ar->arDefTxKeyIndex];
+                               if (down_interruptible(&ar->arSem)) {
+                                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
+                                       return;
+                               }
+
+
+                               ar->arDot11AuthMode = SHARED_AUTH;
+                               ar->arAutoAuthStage = AUTH_IDLE;
+
+                               wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
+                                               ar->arPairwiseCrypto,
+                                               GROUP_USAGE | TX_USAGE,
+                                               key->key_len,
+                                               NULL,
+                                               key->key, KEY_OP_INIT_VAL, NULL,
+                                               NO_SYNC_WMIFLAG);
+
+                               status = wmi_connect_cmd(ar->arWmi,
+                                                        ar->arNetworkType,
+                                                        ar->arDot11AuthMode,
+                                                        ar->arAuthMode,
+                                                        ar->arPairwiseCrypto,
+                                                        ar->arPairwiseCryptoLen,
+                                                        ar->arGroupCrypto,
+                                                        ar->arGroupCryptoLen,
+                                                        ar->arSsidLen,
+                                                        ar->arSsid,
+                                                        ar->arReqBssid,
+                                                        ar->arChannelHint,
+                                                        ar->arConnectCtrlFlags);
+                               up(&ar->arSem);
+
+                       } else if (ar->arDot11AuthMode == SHARED_AUTH) {
+                               /* should not reach here */
+                       }
+               } else {
+                       ar->arConnectPending = false;
+                       if (ar->smeState == SME_CONNECTING) {
+                               cfg80211_connect_result(ar->arNetDev, bssid,
+                                                       NULL, 0,
+                                                       NULL, 0,
+                                                       WLAN_STATUS_UNSPECIFIED_FAILURE,
+                                                       GFP_KERNEL);
+                       } else {
+                               cfg80211_disconnected(ar->arNetDev,
+                                                     reason,
+                                                     NULL, 0,
+                                                     GFP_KERNEL);
+                       }
+                       ar->smeState = SME_DISCONNECTED;
+               }
+       }
     } else {
-        if (reason != DISCONNECT_CMD) {
-            wmi_disconnect_cmd(ar->arWmi);
-        }
+           if (reason != DISCONNECT_CMD)
+                   wmi_disconnect_cmd(ar->arWmi);
     }
 }
 
index b466e7f..0c50c7a 100644 (file)
@@ -653,6 +653,7 @@ struct ar6_softc {
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
     void                    *arApDev;
 #endif
+    u8 arAutoAuthStage;
 };
 
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT