Subject: Sync up cfg80211 patch from staging-next tree

1.Return correct scan complete status to the cfg80211 module based on
  the value returned from the hardware.
 
  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=3f2fd78e68cdea8805c92b72008b9eb42f6580f6

2.A bug was observed during the reconnection phase in the WPA/WPA2-PSK scenario
  where the EAPOL frames were going encrypted during an auto reconnection
  attempt. The initial 4-way handshake would go fine but then the driver
  was getting a command to set default keys sometime later. Setting of an
  incorrect flag (TX_USAGE) in the hadrware was causing the EAPOL frames during
  the subsequent 4-way handshake attempts to go encrypted causing the AP to
  reject the station.
  
  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=e8763b5fe88a0ef8858cd614d961578d34b673a0

3.Adding state in driver to track the sme state. The connect/disconnect
  events from the driver were messing up the state maintained within the
  cfg80211 module.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=98b6d2381a2812eba27a4cec3e8242262b0e5f01

4.If a scan operation is pending and in between a disconnect
  event is received from firmware the scan results never get
  sent back to cfg80211. This causes a scan failure and yields
  a device/resource busy state upon retries. If a disconnect
  event is received and scan is pending return the scan done
  to the cfg80211 to enable futher scans to be issued.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=3c9d2f6c14ebbfdc97945f8f8c023f1fde86732b

5.If a heavy traffic is undergoing and a link is lost (bcn miss),
  wlan driver does a reconnection on its own and after connection
  is re-established, reports it as ROAM_EVENT to cfg. Now this event
  is handled as work queue. It could very well happen that by the
  time this event gets handled, cfg would have aged out the bss and
  we get the following WARN_ON in __cfg80211_roamed function in file
  net/wireless/sme.c.

        /* internal error -- how did we get to CONNECTED w/o BSS? */
        if (WARN_ON(!wdev->current_bss)) {
                return;
        }
  To resolve the issue we report the BSS whenever we send a connect or
  roam event to the cfg.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=60c87f1453e8d53e14941c2d99861a21282942a5

6.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.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=9ae62107fb9010e902e60259c6a461c68885d0c7

7.A call to cfg80211_get_bss should be accompanied by a call to
  cfg80211_put_bss in error-handling code.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=d93089df1b752e4da048cd7f4749d29120b65e55

8.implementing the cfg ops that gets called when iw dev wlan0
  link is issued by user. The ops that needs to be implemented
  is get_station.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=10ceaac958b0b04d6939ec114b7182d78d2a0027

9.The kernel panic happens when we try to complete a pending
  scan request while going to suspend state. The cause for this
  kernel panic is accessing a freed memory (ar->arWmin). This
  is freed before ar6k_cfg80211_scanComplete_event() getting
  called where it is dereferenced.

  
http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=0d422f4237ce515678ebbb8781881e5d2e58b9d4

Signed-off-by: Samuel Chang <[email protected]>

diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h    
2011-06-15 02:06:12.863498128 +0800
+++ 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h
 2011-06-29 08:31:52.440455388 +0800
@@ -552,6 +552,11 @@
     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,
diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c   
2011-06-15 02:06:12.859498118 +0800
+++ 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c
        2011-06-29 09:34:20.847042734 +0800
@@ -1946,6 +1946,8 @@
         SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
         wdev->netdev = dev;
         arPriv->arNetworkType = INFRA_NETWORK;
+        ar->smeState = SME_DISCONNECTED;
+        arPriv->arAutoAuthStage = AUTH_IDLE;
 #endif /* ATH6K_CONFIG_CFG80211 */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c     
2011-06-15 02:06:12.863498128 +0800
+++ 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c
  2011-06-29 11:09:42.519414972 +0800
@@ -169,6 +169,10 @@
     case NL80211_AUTHTYPE_NETWORK_EAP:
         arPriv->arDot11AuthMode = LEAP_AUTH;
         break;
+    case NL80211_AUTHTYPE_AUTOMATIC:
+        arPriv->arDot11AuthMode = OPEN_AUTH;
+        arPriv->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
+        break;
     default:
         arPriv->arDot11AuthMode = OPEN_AUTH;
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -245,11 +249,11 @@
     AR_SOFTC_T     *ar     = arPriv->arSoftc;
     AR_SOFTC_STA_T *arSta  = &arPriv->arSta;
     A_STATUS status;
-    A_UINT8 keyUsage = 0;
     const unsigned char wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
     unsigned char *ie = sme->ie;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+    ar->smeState = SME_CONNECTING;
 
     if(ar->arWmiReady == FALSE) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
@@ -303,12 +307,6 @@
             return -EINTR;
         }
     }
-    up(&arPriv->arPrivSem);
-    
-    if(down_interruptible(&arPriv->arPrivSem)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", 
__func__));
-        return -ERESTARTSYS;
-    }
 
     if(arPriv->arConnected == TRUE &&
        arPriv->arSsidLen == sme->ssid_len &&
@@ -317,7 +315,9 @@
         status = wmi_reconnect_cmd(arPriv->arWmi,
                                    arSta->arReqBssid,
                                    arPriv->arChannelHint);
-        
+
+        up(&arPriv->arPrivSem);
+
         if (status != A_OK) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", 
__func__));
             return -EIO;
@@ -375,14 +375,9 @@
         key->cipher = arPriv->arPairwiseCrypto;
         arPriv->arDefTxKeyIndex = sme->key_idx;
 
-       if (arPriv->arAuthMode & (WPA_PSK_AUTH | WPA2_PSK_AUTH))
-               keyUsage =  GROUP_USAGE;
-       else
-               keyUsage =  GROUP_USAGE | TX_USAGE;
-
         wmi_addKey_cmd(arPriv->arWmi, sme->key_idx,
                     arPriv->arPairwiseCrypto,
-                    keyUsage,
+                    GROUP_USAGE | TX_USAGE,
                     key->key_len,
                     NULL,
                     key->key, KEY_OP_INIT_VAL, NULL,
@@ -467,6 +462,7 @@
     unsigned char *ptr_ie_buf = ie_buf;
     unsigned char *ieeemgmtbuf = NULL;
     A_UINT8 source_mac[ATH_MAC_LEN];
+    AR_SOFTC_T     *ar     = arPriv->arSoftc;
 
     A_UINT8 assocReqIeOffset = sizeof(A_UINT16)  +  /* capinfo*/
                                sizeof(A_UINT16);    /* listen interval */
@@ -480,6 +476,7 @@
 
     assocReqLen -= assocReqIeOffset;
     assocRespLen -= assocRespIeOffset;
+    arPriv->arAutoAuthStage = AUTH_IDLE;
 
     if((ADHOC_NETWORK & networkType)) {
         if(NL80211_IFTYPE_ADHOC != arPriv->wdev->iftype) {
@@ -508,7 +505,15 @@
                            ((ADHOC_NETWORK & networkType) ? 
WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
                            ((ADHOC_NETWORK & networkType) ? 
WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
 
-    if(!bss) {
+       /*
+        * Earlier we were updating the cfg about bss by making a beacon frame
+        * only if the entry for bss is not there. This can have some issue if
+        * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+        * event is handled through a work queue and by the time it really gets
+        * handled, BSS would have been aged out. So it is better to update the
+        * cfg about BSS irrespective of its entry being present right now or
+        * not.
+        */
         if (ADHOC_NETWORK & networkType) {
             /* construct 802.11 mgmt beacon */
             if(ptr_ie_buf) {
@@ -549,6 +554,7 @@
         if(!ieeemgmtbuf) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                             ("%s: ieeeMgmtbuf alloc error\n", __func__));
+            cfg80211_put_bss(bss);
             return;
         }
 
@@ -578,7 +584,6 @@
                                         signal, GFP_ATOMIC);
         A_FREE(ieeemgmtbuf);
         cfg80211_put_bss(bss);
-    }
 
     if((ADHOC_NETWORK & networkType)) {
         cfg80211_ibss_joined(arPriv->arNetDev, bssid, GFP_ATOMIC);
@@ -587,6 +592,7 @@
 
     if (FALSE == arPriv->arConnected) {
         /* inform connect result to cfg80211 */
+        ar->smeState = SME_DISCONNECTED;
         cfg80211_connect_result(arPriv->arNetDev, bssid,
                                 assocReqIe, assocReqLen,
                                 assocRespIe, assocRespLen,
@@ -648,6 +654,14 @@
                                A_UINT8 *bssid, A_UINT8 assocRespLen,
                                A_UINT8 *assocInfo, A_UINT16 
protocolReasonStatus)
 {
+    A_UINT16 status;
+       AR_SOFTC_STA_T *arSta  = &arPriv->arSta;
+       AR_SOFTC_T *ar = (AR_SOFTC_T *)arPriv->arSoftc;
+
+       if (arPriv->scan_request) {
+               cfg80211_scan_done(arPriv->scan_request, true);
+        arPriv->scan_request = NULL;
+    }
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
 
@@ -670,18 +684,74 @@
         }
     }
 
-    if(FALSE == arPriv->arConnected) {
+       if(true == arSta->arConnectPending) {
         if(NO_NETWORK_AVAIL == reason) {
             /* connect cmd failed */
-            cfg80211_connect_result(arPriv->arNetDev, bssid,
-                                    NULL, 0,
-                                    NULL, 0,
-                                    WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                    GFP_ATOMIC);
-        }
+            wmi_disconnect_cmd(arPriv->arWmi);
+        } else if (reason == DISCONNECT_CMD) {
+               if (arPriv->arAutoAuthStage) {
+                       /*
+                        * If the current auth algorithm is open try shared
+                        * and make autoAuthStage idle. We do not make it
+                        * leap for now being.
+                        */
+                       if (arPriv->arDot11AuthMode == OPEN_AUTH) {
+                               struct ar_key *key = NULL;
+                               key = &arPriv->keys[arPriv->arDefTxKeyIndex];
+                               if (down_interruptible(&ar->arSem)) {
+                                       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: 
busy, couldn't get access\n", __func__));
+                                       return;
+                               }
+
+                               arPriv->arDot11AuthMode = SHARED_AUTH;
+                               arPriv->arAutoAuthStage = AUTH_IDLE;
+
+                               wmi_addKey_cmd(arPriv->arWmi, 
arPriv->arDefTxKeyIndex,
+                                               arPriv->arPairwiseCrypto,
+                                               GROUP_USAGE | TX_USAGE,
+                                               key->key_len,
+                                               NULL,
+                                               key->key, KEY_OP_INIT_VAL, NULL,
+                                               NO_SYNC_WMIFLAG);
+
+                               status = wmi_connect_cmd(arPriv->arWmi,
+                                                        arPriv->arNetworkType,
+                                                        
arPriv->arDot11AuthMode,
+                                                        arPriv->arAuthMode,
+                                                        
arPriv->arPairwiseCrypto,
+                                                        
arPriv->arPairwiseCryptoLen,
+                                                        arPriv->arGroupCrypto,
+                                                        
arPriv->arGroupCryptoLen,
+                                                        arPriv->arSsidLen,
+                                                        arPriv->arSsid,
+                                                        arSta->arReqBssid,
+                                                        arPriv->arChannelHint,
+                                                        
arSta->arConnectCtrlFlags);
+                               up(&ar->arSem);
+
+                       } else if (arPriv->arDot11AuthMode == SHARED_AUTH) {
+                               /* should not reach here */
+                       }
+               } else {
+                       arSta->arConnectPending = false;
+                       if (ar->smeState == SME_CONNECTING) {
+                               cfg80211_connect_result(arPriv->arNetDev, bssid,
+                                                       NULL, 0,
+                                                       NULL, 0,
+                                                       
WLAN_STATUS_UNSPECIFIED_FAILURE,
+                                                       GFP_ATOMIC);
+                       } else {
+                               cfg80211_disconnected(arPriv->arNetDev,
+                                                     reason,
+                                                     NULL, 0,
+                                                     GFP_ATOMIC);
+                       }
+                       ar->smeState = SME_DISCONNECTED;
+               }
+       }
     } else {
-        /* connection loss due to disconnect cmd or low rssi */
-        cfg80211_disconnected(arPriv->arNetDev, reason, NULL, 0, GFP_ATOMIC);
+           if (reason != DISCONNECT_CMD)
+                   wmi_disconnect_cmd(arPriv->arWmi);
     }
 }
 
@@ -818,10 +888,11 @@
     if(arPriv->scan_request)
     {
         /* Translate data to cfg80211 mgmt format */
+       if (arPriv->arWmi)
         wmi_iterate_nodes(arPriv->arWmi, ar6k_cfg80211_scan_node, 
arPriv->wdev->wiphy);
 
-        cfg80211_scan_done(arPriv->scan_request,
-                          (status & A_ECANCELED) ? true : false);
+        cfg80211_scan_done(arPriv->scan_request,
+            ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
 
         if(arPriv->scan_request->n_ssids &&
            arPriv->scan_request->ssids[0].ssid_len) {
@@ -1032,6 +1103,7 @@
     AR_SOFTC_T     *ar     = arPriv->arSoftc;
     struct ar_key *key = NULL;
     A_STATUS status = A_OK;
+    u8 key_usage;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
 
@@ -1058,10 +1130,15 @@
         return -EINVAL;
     }
 
+    key_usage = GROUP_USAGE;
+    if (WEP_CRYPT == arPriv->arPairwiseCrypto) {
+        key_usage |= TX_USAGE;
+    }
+
     arPriv->arDefTxKeyIndex = key_index;
     key = &arPriv->keys[arPriv->arDefTxKeyIndex];
     status = wmi_addKey_cmd(arPriv->arWmi, arPriv->arDefTxKeyIndex,
-                            arPriv->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
+                            arPriv->arPairwiseCrypto, key_usage,
                             key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
                             NULL, SYNC_BOTH_WMIFLAG);
     if (status != A_OK) {
@@ -1473,6 +1550,152 @@
     WLAN_CIPHER_SUITE_CCMP,
 };
 
+bool is_rate_legacy(s32 rate)
+{
+       static const s32 legacy[] = { 1000, 2000, 5500, 11000,
+                                     6000, 9000, 12000, 18000, 24000,
+                                     36000, 48000, 54000 };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(legacy); i++) {
+               if (rate == legacy[i])
+                       return true;
+       }
+
+       return false;
+}
+
+bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
+{
+       static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
+                                   52000, 58500, 65000, 72200 };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(ht20); i++) {
+               if (rate == ht20[i]) {
+                       if (i == ARRAY_SIZE(ht20) - 1)
+                               /* last rate uses sgi */
+                               *sgi = true;
+                       else
+                               *sgi = false;
+
+                       *mcs = i;
+                       return true;
+               }
+       }
+       return false;
+}
+
+bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
+{
+       static const s32 ht40[] = { 13500, 27000, 40500, 54000,
+                                   81000, 108000, 121500, 135000,
+                                   150000 };
+       u8 i;
+
+       for (i = 0; i < ARRAY_SIZE(ht40); i++) {
+               if (rate == ht40[i]) {
+                       if (i == ARRAY_SIZE(ht40) - 1)
+                               /* last rate uses sgi */
+                               *sgi = true;
+                       else
+                               *sgi = false;
+
+                       *mcs = i;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
+                           u8 *mac, struct station_info *sinfo)
+{
+       AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev);
+       AR_SOFTC_T     *ar     = arPriv->arSoftc;
+       long left;
+       bool sgi;
+       s32 rate;
+       int ret;
+       u8 mcs;
+
+       if (memcmp(mac, arPriv->arBssid, ETH_ALEN) != 0)
+               return -ENOENT;
+
+       if (down_interruptible(&ar->arSem))
+               return -EBUSY;
+
+       arPriv->statsUpdatePending = true;
+
+       ret = wmi_get_stats_cmd(arPriv->arWmi);
+
+       if (ret != 0) {
+               up(&ar->arSem);
+               return -EIO;
+       }
+
+       left = wait_event_interruptible_timeout(arPriv->arEvent,
+                                               arPriv->statsUpdatePending == 
false,
+                                               wmitimeout * HZ);
+
+       up(&ar->arSem);
+
+       if (left == 0)
+               return -ETIMEDOUT;
+       else if (left < 0)
+               return left;
+
+       if (arPriv->arTargetStats.rx_bytes) {
+               sinfo->rx_bytes = arPriv->arTargetStats.rx_bytes;
+               sinfo->filled |= STATION_INFO_RX_BYTES;
+               sinfo->rx_packets = arPriv->arTargetStats.rx_packets;
+               sinfo->filled |= STATION_INFO_RX_PACKETS;
+       }
+
+       if (arPriv->arTargetStats.tx_bytes) {
+               sinfo->tx_bytes = arPriv->arTargetStats.tx_bytes;
+               sinfo->filled |= STATION_INFO_TX_BYTES;
+               sinfo->tx_packets = arPriv->arTargetStats.tx_packets;
+               sinfo->filled |= STATION_INFO_TX_PACKETS;
+       }
+
+       sinfo->signal = arPriv->arTargetStats.cs_rssi;
+       sinfo->filled |= STATION_INFO_SIGNAL;
+
+       rate = arPriv->arTargetStats.tx_unicast_rate;
+
+       if (is_rate_legacy(rate)) {
+               sinfo->txrate.legacy = rate / 100;
+       } else if (is_rate_ht20(rate, &mcs, &sgi)) {
+               if (sgi) {
+                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+                       sinfo->txrate.mcs = mcs - 1;
+               } else {
+                       sinfo->txrate.mcs = mcs;
+               }
+
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+       } else if (is_rate_ht40(rate, &mcs, &sgi)) {
+               if (sgi) {
+                       sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+                       sinfo->txrate.mcs = mcs - 1;
+               } else {
+                       sinfo->txrate.mcs = mcs;
+               }
+
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+               sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+       } else {
+               WARN(1, "invalid rate: %d", rate);
+               return 0;
+       }
+
+       sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+       return 0;
+}
+
 static struct
 cfg80211_ops ar6k_cfg80211_ops = {
     .change_virtual_intf = ar6k_cfg80211_change_iface,
@@ -1493,6 +1716,7 @@
     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
     .join_ibss = ar6k_cfg80211_join_ibss,
     .leave_ibss = ar6k_cfg80211_leave_ibss,
+    .get_station = ar6k_get_station,
 };
 
 struct wireless_dev *
diff -ruN 
kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h   
2011-06-15 02:06:12.863498128 +0800
+++ 
kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
        2011-06-29 08:32:44.112711621 +0800
@@ -427,6 +427,13 @@
     A_UINT8     seq_len;
     A_UINT32    cipher;
 };
+
+enum {
+    SME_DISCONNECTED,
+    SME_CONNECTING,
+    SME_CONNECTED
+};
+
 #endif /* ATH6K_CONFIG_CFG80211 */
 
 
@@ -574,6 +581,7 @@
     A_UINT8                 rxMetaVersion;
     A_INT32                 (*exitCallback)(void *config);  /* generic 
callback at AR6K exit */
     HIF_DEVICE_OS_DEVICE_INFO   osDevInfo;
+    A_UINT32                smeState;
     A_UINT16                arWlanPowerState;
     A_BOOL                  arPlatPowerOff;
     USER_RSSI_CPENSATION    rssi_compensation_param;
@@ -729,6 +737,7 @@
     AR_SOFTC_T              *arSoftc;
     A_UINT8                 arHoldConnection;
     A_UINT8                 num_sta;
+    A_UINT8                 arAutoAuthStage;
 }AR_SOFTC_DEV_T;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
Subject: Sync up cfg80211 patch from staging-next tree


1.Return correct scan complete status to the cfg80211 module based on
  the value returned from the hardware.
 
  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=3f2fd78e68cdea8805c92b72008b9eb42f6580f6

2.A bug was observed during the reconnection phase in the WPA/WPA2-PSK scenario
  where the EAPOL frames were going encrypted during an auto reconnection
  attempt. The initial 4-way handshake would go fine but then the driver
  was getting a command to set default keys sometime later. Setting of an
  incorrect flag (TX_USAGE) in the hadrware was causing the EAPOL frames during
  the subsequent 4-way handshake attempts to go encrypted causing the AP to
  reject the station.
  
  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=e8763b5fe88a0ef8858cd614d961578d34b673a0

3.Adding state in driver to track the sme state. The connect/disconnect
  events from the driver were messing up the state maintained within the
  cfg80211 module.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=98b6d2381a2812eba27a4cec3e8242262b0e5f01

4.If a scan operation is pending and in between a disconnect
  event is received from firmware the scan results never get
  sent back to cfg80211. This causes a scan failure and yields
  a device/resource busy state upon retries. If a disconnect
  event is received and scan is pending return the scan done
  to the cfg80211 to enable futher scans to be issued.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=3c9d2f6c14ebbfdc97945f8f8c023f1fde86732b

5.If a heavy traffic is undergoing and a link is lost (bcn miss),
  wlan driver does a reconnection on its own and after connection
  is re-established, reports it as ROAM_EVENT to cfg. Now this event
  is handled as work queue. It could very well happen that by the
  time this event gets handled, cfg would have aged out the bss and
  we get the following WARN_ON in __cfg80211_roamed function in file
  net/wireless/sme.c.

        /* internal error -- how did we get to CONNECTED w/o BSS? */
        if (WARN_ON(!wdev->current_bss)) {
                return;
        }
  To resolve the issue we report the BSS whenever we send a connect or
  roam event to the cfg.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=60c87f1453e8d53e14941c2d99861a21282942a5

6.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.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=9ae62107fb9010e902e60259c6a461c68885d0c7

7.A call to cfg80211_get_bss should be accompanied by a call to
  cfg80211_put_bss in error-handling code.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=d93089df1b752e4da048cd7f4749d29120b65e55

8.implementing the cfg ops that gets called when iw dev wlan0
  link is issued by user. The ops that needs to be implemented
  is get_station.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=10ceaac958b0b04d6939ec114b7182d78d2a0027

9.The kernel panic happens when we try to complete a pending
  scan request while going to suspend state. The cause for this
  kernel panic is accessing a freed memory (ar->arWmin). This
  is freed before ar6k_cfg80211_scanComplete_event() getting
  called where it is dereferenced.

  http://git.kernel.org/?p=linux/kernel/git/gregkh/staging-2.6.git;a=commitdiff;h=0d422f4237ce515678ebbb8781881e5d2e58b9d4

Signed-off-by: Samuel Chang <[email protected]>

diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h	2011-06-15 02:06:12.863498128 +0800
+++ kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h	2011-06-29 08:31:52.440455388 +0800
@@ -552,6 +552,11 @@
     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,
diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c	2011-06-15 02:06:12.859498118 +0800
+++ kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c	2011-06-29 09:34:20.847042734 +0800
@@ -1946,6 +1946,8 @@
         SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
         wdev->netdev = dev;
         arPriv->arNetworkType = INFRA_NETWORK;
+        ar->smeState = SME_DISCONNECTED;
+	 arPriv->arAutoAuthStage = AUTH_IDLE;
 #endif /* ATH6K_CONFIG_CFG80211 */
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c	2011-06-15 02:06:12.863498128 +0800
+++ kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c	2011-06-29 11:09:42.519414972 +0800
@@ -169,6 +169,10 @@
     case NL80211_AUTHTYPE_NETWORK_EAP:
         arPriv->arDot11AuthMode = LEAP_AUTH;
         break;
+    case NL80211_AUTHTYPE_AUTOMATIC:
+        arPriv->arDot11AuthMode = OPEN_AUTH;
+        arPriv->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
+        break;
     default:
         arPriv->arDot11AuthMode = OPEN_AUTH;
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -245,11 +249,11 @@
     AR_SOFTC_T     *ar     = arPriv->arSoftc;
     AR_SOFTC_STA_T *arSta  = &arPriv->arSta;
     A_STATUS status;
-    A_UINT8 keyUsage = 0;
     const unsigned char wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
     unsigned char *ie = sme->ie;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
+    ar->smeState = SME_CONNECTING;
 
     if(ar->arWmiReady == FALSE) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
@@ -303,12 +307,6 @@
             return -EINTR;
         }
     }
-    up(&arPriv->arPrivSem);
-    
-    if(down_interruptible(&arPriv->arPrivSem)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
-        return -ERESTARTSYS;
-    }
 
     if(arPriv->arConnected == TRUE &&
        arPriv->arSsidLen == sme->ssid_len &&
@@ -317,7 +315,9 @@
         status = wmi_reconnect_cmd(arPriv->arWmi,
                                    arSta->arReqBssid,
                                    arPriv->arChannelHint);
-        
+
+	 up(&arPriv->arPrivSem);
+
         if (status != A_OK) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
             return -EIO;
@@ -375,14 +375,9 @@
         key->cipher = arPriv->arPairwiseCrypto;
         arPriv->arDefTxKeyIndex = sme->key_idx;
 
-       if (arPriv->arAuthMode & (WPA_PSK_AUTH | WPA2_PSK_AUTH))
-               keyUsage =  GROUP_USAGE;
-       else
-               keyUsage =  GROUP_USAGE | TX_USAGE;
-
         wmi_addKey_cmd(arPriv->arWmi, sme->key_idx,
                     arPriv->arPairwiseCrypto,
-                    keyUsage,
+                    GROUP_USAGE | TX_USAGE,
                     key->key_len,
                     NULL,
                     key->key, KEY_OP_INIT_VAL, NULL,
@@ -467,6 +462,7 @@
     unsigned char *ptr_ie_buf = ie_buf;
     unsigned char *ieeemgmtbuf = NULL;
     A_UINT8 source_mac[ATH_MAC_LEN];
+    AR_SOFTC_T     *ar     = arPriv->arSoftc;
 
     A_UINT8 assocReqIeOffset = sizeof(A_UINT16)  +  /* capinfo*/
                                sizeof(A_UINT16);    /* listen interval */
@@ -480,6 +476,7 @@
 
     assocReqLen -= assocReqIeOffset;
     assocRespLen -= assocRespIeOffset;
+    arPriv->arAutoAuthStage = AUTH_IDLE;
 
     if((ADHOC_NETWORK & networkType)) {
         if(NL80211_IFTYPE_ADHOC != arPriv->wdev->iftype) {
@@ -508,7 +505,15 @@
                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
 
-    if(!bss) {
+	/*
+	 * Earlier we were updating the cfg about bss by making a beacon frame
+	 * only if the entry for bss is not there. This can have some issue if
+	 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+	 * event is handled through a work queue and by the time it really gets
+	 * handled, BSS would have been aged out. So it is better to update the
+	 * cfg about BSS irrespective of its entry being present right now or
+	 * not.
+	 */
         if (ADHOC_NETWORK & networkType) {
             /* construct 802.11 mgmt beacon */
             if(ptr_ie_buf) {
@@ -549,6 +554,7 @@
         if(!ieeemgmtbuf) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                             ("%s: ieeeMgmtbuf alloc error\n", __func__));
+	     cfg80211_put_bss(bss);
             return;
         }
 
@@ -578,7 +584,6 @@
                                         signal, GFP_ATOMIC);
         A_FREE(ieeemgmtbuf);
         cfg80211_put_bss(bss);
-    }
 
     if((ADHOC_NETWORK & networkType)) {
         cfg80211_ibss_joined(arPriv->arNetDev, bssid, GFP_ATOMIC);
@@ -587,6 +592,7 @@
 
     if (FALSE == arPriv->arConnected) {
         /* inform connect result to cfg80211 */
+	 ar->smeState = SME_DISCONNECTED;
         cfg80211_connect_result(arPriv->arNetDev, bssid,
                                 assocReqIe, assocReqLen,
                                 assocRespIe, assocRespLen,
@@ -648,6 +654,14 @@
                                A_UINT8 *bssid, A_UINT8 assocRespLen,
                                A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
 {
+    A_UINT16 status;
+	AR_SOFTC_STA_T *arSta  = &arPriv->arSta;
+	AR_SOFTC_T *ar = (AR_SOFTC_T *)arPriv->arSoftc;
+
+	if (arPriv->scan_request) {
+		cfg80211_scan_done(arPriv->scan_request, true);
+        arPriv->scan_request = NULL;
+    }
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
 
@@ -670,18 +684,74 @@
         }
     }
 
-    if(FALSE == arPriv->arConnected) {
+	if(true == arSta->arConnectPending) {
         if(NO_NETWORK_AVAIL == reason) {
             /* connect cmd failed */
-            cfg80211_connect_result(arPriv->arNetDev, bssid,
-                                    NULL, 0,
-                                    NULL, 0,
-                                    WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                    GFP_ATOMIC);
-        }
+            wmi_disconnect_cmd(arPriv->arWmi);
+        } else if (reason == DISCONNECT_CMD) {
+		if (arPriv->arAutoAuthStage) {
+			/*
+			 * If the current auth algorithm is open try shared
+			 * and make autoAuthStage idle. We do not make it
+			 * leap for now being.
+			 */
+			if (arPriv->arDot11AuthMode == OPEN_AUTH) {
+				struct ar_key *key = NULL;
+				key = &arPriv->keys[arPriv->arDefTxKeyIndex];
+				if (down_interruptible(&ar->arSem)) {
+					AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
+					return;
+				}
+
+				arPriv->arDot11AuthMode = SHARED_AUTH;
+				arPriv->arAutoAuthStage = AUTH_IDLE;
+
+				wmi_addKey_cmd(arPriv->arWmi, arPriv->arDefTxKeyIndex,
+						arPriv->arPairwiseCrypto,
+						GROUP_USAGE | TX_USAGE,
+						key->key_len,
+						NULL,
+						key->key, KEY_OP_INIT_VAL, NULL,
+						NO_SYNC_WMIFLAG);
+
+				status = wmi_connect_cmd(arPriv->arWmi,
+							 arPriv->arNetworkType,
+							 arPriv->arDot11AuthMode,
+							 arPriv->arAuthMode,
+							 arPriv->arPairwiseCrypto,
+							 arPriv->arPairwiseCryptoLen,
+							 arPriv->arGroupCrypto,
+							 arPriv->arGroupCryptoLen,
+							 arPriv->arSsidLen,
+							 arPriv->arSsid,
+							 arSta->arReqBssid,
+							 arPriv->arChannelHint,
+							 arSta->arConnectCtrlFlags);
+				up(&ar->arSem);
+
+			} else if (arPriv->arDot11AuthMode == SHARED_AUTH) {
+				/* should not reach here */
+			}
+		} else {
+			arSta->arConnectPending = false;
+			if (ar->smeState == SME_CONNECTING) {
+				cfg80211_connect_result(arPriv->arNetDev, bssid,
+							NULL, 0,
+							NULL, 0,
+							WLAN_STATUS_UNSPECIFIED_FAILURE,
+							GFP_ATOMIC);
+			} else {
+				cfg80211_disconnected(arPriv->arNetDev,
+						      reason,
+						      NULL, 0,
+						      GFP_ATOMIC);
+			}
+			ar->smeState = SME_DISCONNECTED;
+		}
+	}
     } else {
-        /* connection loss due to disconnect cmd or low rssi */
-        cfg80211_disconnected(arPriv->arNetDev, reason, NULL, 0, GFP_ATOMIC);
+	    if (reason != DISCONNECT_CMD)
+		    wmi_disconnect_cmd(arPriv->arWmi);
     }
 }
 
@@ -818,10 +888,11 @@
     if(arPriv->scan_request)
     {
         /* Translate data to cfg80211 mgmt format */
+	if (arPriv->arWmi)
         wmi_iterate_nodes(arPriv->arWmi, ar6k_cfg80211_scan_node, arPriv->wdev->wiphy);
 
-        cfg80211_scan_done(arPriv->scan_request,
-                          (status & A_ECANCELED) ? true : false);
+	 cfg80211_scan_done(arPriv->scan_request,
+            ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
 
         if(arPriv->scan_request->n_ssids &&
            arPriv->scan_request->ssids[0].ssid_len) {
@@ -1032,6 +1103,7 @@
     AR_SOFTC_T     *ar     = arPriv->arSoftc;
     struct ar_key *key = NULL;
     A_STATUS status = A_OK;
+    u8 key_usage;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
 
@@ -1058,10 +1130,15 @@
         return -EINVAL;
     }
 
+    key_usage = GROUP_USAGE;
+    if (WEP_CRYPT == arPriv->arPairwiseCrypto) {
+        key_usage |= TX_USAGE;
+    }
+
     arPriv->arDefTxKeyIndex = key_index;
     key = &arPriv->keys[arPriv->arDefTxKeyIndex];
     status = wmi_addKey_cmd(arPriv->arWmi, arPriv->arDefTxKeyIndex,
-                            arPriv->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
+                            arPriv->arPairwiseCrypto, key_usage,
                             key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
                             NULL, SYNC_BOTH_WMIFLAG);
     if (status != A_OK) {
@@ -1473,6 +1550,152 @@
     WLAN_CIPHER_SUITE_CCMP,
 };
 
+bool is_rate_legacy(s32 rate)
+{
+	static const s32 legacy[] = { 1000, 2000, 5500, 11000,
+				      6000, 9000, 12000, 18000, 24000,
+				      36000, 48000, 54000 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(legacy); i++) {
+		if (rate == legacy[i])
+			return true;
+	}
+
+	return false;
+}
+
+bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
+{
+	static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
+				    52000, 58500, 65000, 72200 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(ht20); i++) {
+		if (rate == ht20[i]) {
+			if (i == ARRAY_SIZE(ht20) - 1)
+				/* last rate uses sgi */
+				*sgi = true;
+			else
+				*sgi = false;
+
+			*mcs = i;
+			return true;
+		}
+	}
+	return false;
+}
+
+bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
+{
+	static const s32 ht40[] = { 13500, 27000, 40500, 54000,
+				    81000, 108000, 121500, 135000,
+				    150000 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(ht40); i++) {
+		if (rate == ht40[i]) {
+			if (i == ARRAY_SIZE(ht40) - 1)
+				/* last rate uses sgi */
+				*sgi = true;
+			else
+				*sgi = false;
+
+			*mcs = i;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
+			    u8 *mac, struct station_info *sinfo)
+{
+	AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev);
+	AR_SOFTC_T     *ar     = arPriv->arSoftc;
+	long left;
+	bool sgi;
+	s32 rate;
+	int ret;
+	u8 mcs;
+
+	if (memcmp(mac, arPriv->arBssid, ETH_ALEN) != 0)
+		return -ENOENT;
+
+	if (down_interruptible(&ar->arSem))
+		return -EBUSY;
+
+	arPriv->statsUpdatePending = true;
+
+	ret = wmi_get_stats_cmd(arPriv->arWmi);
+
+	if (ret != 0) {
+		up(&ar->arSem);
+		return -EIO;
+	}
+
+	left = wait_event_interruptible_timeout(arPriv->arEvent,
+						arPriv->statsUpdatePending == false,
+						wmitimeout * HZ);
+
+	up(&ar->arSem);
+
+	if (left == 0)
+		return -ETIMEDOUT;
+	else if (left < 0)
+		return left;
+
+	if (arPriv->arTargetStats.rx_bytes) {
+		sinfo->rx_bytes = arPriv->arTargetStats.rx_bytes;
+		sinfo->filled |= STATION_INFO_RX_BYTES;
+		sinfo->rx_packets = arPriv->arTargetStats.rx_packets;
+		sinfo->filled |= STATION_INFO_RX_PACKETS;
+	}
+
+	if (arPriv->arTargetStats.tx_bytes) {
+		sinfo->tx_bytes = arPriv->arTargetStats.tx_bytes;
+		sinfo->filled |= STATION_INFO_TX_BYTES;
+		sinfo->tx_packets = arPriv->arTargetStats.tx_packets;
+		sinfo->filled |= STATION_INFO_TX_PACKETS;
+	}
+
+	sinfo->signal = arPriv->arTargetStats.cs_rssi;
+	sinfo->filled |= STATION_INFO_SIGNAL;
+
+	rate = arPriv->arTargetStats.tx_unicast_rate;
+
+	if (is_rate_legacy(rate)) {
+		sinfo->txrate.legacy = rate / 100;
+	} else if (is_rate_ht20(rate, &mcs, &sgi)) {
+		if (sgi) {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+			sinfo->txrate.mcs = mcs - 1;
+		} else {
+			sinfo->txrate.mcs = mcs;
+		}
+
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+	} else if (is_rate_ht40(rate, &mcs, &sgi)) {
+		if (sgi) {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+			sinfo->txrate.mcs = mcs - 1;
+		} else {
+			sinfo->txrate.mcs = mcs;
+		}
+
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+	} else {
+		WARN(1, "invalid rate: %d", rate);
+		return 0;
+	}
+
+	sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+	return 0;
+}
+
 static struct
 cfg80211_ops ar6k_cfg80211_ops = {
     .change_virtual_intf = ar6k_cfg80211_change_iface,
@@ -1493,6 +1716,7 @@
     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
     .join_ibss = ar6k_cfg80211_join_ibss,
     .leave_ibss = ar6k_cfg80211_leave_ibss,
+    .get_station = ar6k_get_station,
 };
 
 struct wireless_dev *
diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
--- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h	2011-06-15 02:06:12.863498128 +0800
+++ kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h	2011-06-29 08:32:44.112711621 +0800
@@ -427,6 +427,13 @@
     A_UINT8     seq_len;
     A_UINT32    cipher;
 };
+
+enum {
+    SME_DISCONNECTED,
+    SME_CONNECTING,
+    SME_CONNECTED
+};
+
 #endif /* ATH6K_CONFIG_CFG80211 */
 
 
@@ -574,6 +581,7 @@
     A_UINT8                 rxMetaVersion;
     A_INT32                 (*exitCallback)(void *config);  /* generic callback at AR6K exit */
     HIF_DEVICE_OS_DEVICE_INFO   osDevInfo;
+    A_UINT32                smeState;
     A_UINT16                arWlanPowerState;
     A_BOOL                  arPlatPowerOff;
     USER_RSSI_CPENSATION    rssi_compensation_param;
@@ -729,6 +737,7 @@
     AR_SOFTC_T              *arSoftc;
     A_UINT8                 arHoldConnection;
     A_UINT8                 num_sta;
+    A_UINT8                 arAutoAuthStage;
 }AR_SOFTC_DEV_T;
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to