libertas: add auto auth mode feature
authorAmitkumar Karwar <akarwar@marvell.com>
Fri, 26 Feb 2010 01:16:36 +0000 (17:16 -0800)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 24 Mar 2010 20:02:37 +0000 (16:02 -0400)
Auto auth mode is enabled by default. If user doesn't specify the
auth mode, while association driver will first try with open mode
and then with shared key mode. If user specifies an auth mode,
auto auth is disabled and driver will not try association with
another auth mode.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/wext.c

index f03d5e4e59c31c1da78c271d4665f158825c712f..95d3d4c5e08b40100e8364d81c0b66ff3f55311f 100644 (file)
@@ -31,6 +31,9 @@ u8 lbs_bg_rates[MAX_RATES] =
 0x00, 0x00 };
 
 
+static int assoc_helper_wep_keys(struct lbs_private *priv,
+               struct assoc_request *assoc_req);
+
 /**
  *  @brief This function finds common rates between rates and card rates.
  *
@@ -610,7 +613,7 @@ static int lbs_assoc_post(struct lbs_private *priv,
 
        if (status_code) {
                lbs_mac_event_disconnected(priv);
-               ret = -1;
+               ret = status_code;
                goto done;
        }
 
@@ -813,7 +816,24 @@ static int lbs_try_associate(struct lbs_private *priv,
                goto out;
 
        ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
+       /* If the association fails with current auth mode, let's
+        * try by changing the auth mode
+        */
+       if ((priv->authtype_auto) &&
+                       (ret == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) &&
+                       (assoc_req->secinfo.wep_enabled) &&
+                       (priv->connect_status != LBS_CONNECTED)) {
+               if (priv->secinfo.auth_mode == IW_AUTH_ALG_OPEN_SYSTEM)
+                       priv->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
+               else
+                       priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
+               if (!assoc_helper_wep_keys(priv, assoc_req))
+                       ret = lbs_associate(priv, assoc_req,
+                                               CMD_802_11_ASSOCIATE);
+       }
 
+       if (ret)
+               ret = -1;
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
index 6977ee82021411ecebba130a2a10c6b5c40992df..058d1720242ea3d99e3aedd06777e0350c5ca754 100644 (file)
@@ -133,6 +133,7 @@ struct lbs_private {
        u8 wpa_ie_len;
        u16 wep_tx_keyidx;
        struct enc_key wep_keys[4];
+       u8 authtype_auto;
 
        /* Wake On LAN */
        uint32_t wol_criteria;
index 28a1c9d1627a7cb0a73c36d07b25d594d17d00d3..3c889f43d909b50671d1a6b7047ee3d05a4dbe81 100644 (file)
@@ -835,6 +835,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
        priv->is_auto_deep_sleep_enabled = 0;
        priv->wakeup_dev_required = 0;
        init_waitqueue_head(&priv->ds_awake_q);
+       priv->authtype_auto = 1;
 
        mutex_init(&priv->lock);
 
index 71f88a08e0906200b6053fcb5875dbeed91da894..aad6263dee6d59057da5f2cac4e1bb98f5a8946b 100644 (file)
@@ -1440,8 +1440,10 @@ static int lbs_set_encode(struct net_device *dev,
                set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
 
        if (dwrq->flags & IW_ENCODE_RESTRICTED) {
+               priv->authtype_auto = 0;
                assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
        } else if (dwrq->flags & IW_ENCODE_OPEN) {
+               priv->authtype_auto = 0;
                assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
        }
 
@@ -1620,8 +1622,10 @@ static int lbs_set_encodeext(struct net_device *dev,
                        goto out;
 
                if (dwrq->flags & IW_ENCODE_RESTRICTED) {
+                       priv->authtype_auto = 0;
                        assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
                } else if (dwrq->flags & IW_ENCODE_OPEN) {
+                       priv->authtype_auto = 0;
                        assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
                }