iwmc3200wifi: Try shared auth when open WEP fails
authorSamuel Ortiz <sameo@linux.intel.com>
Fri, 16 Oct 2009 05:18:57 +0000 (13:18 +0800)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 27 Oct 2009 20:48:27 +0000 (16:48 -0400)
When we fail to associate with an open WEP AP, we fall back to shared auth.
This allows us to support joining a shared auth WEP AP with iwconfig.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwmc3200wifi/commands.c
drivers/net/wireless/iwmc3200wifi/iwm.h
drivers/net/wireless/iwmc3200wifi/main.c
drivers/net/wireless/iwmc3200wifi/rx.c

index 25fb8dfd83b52b7ce350c94b58f4257ead687a21..cad511afd90759df67bf3459bf131957b4d3b34f 100644 (file)
@@ -793,7 +793,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
                return ret;
 
        ret = wait_event_interruptible_timeout(iwm->mlme_queue,
-                               (iwm->umac_profile_active == 0), 2 * HZ);
+                               (iwm->umac_profile_active == 0), 5 * HZ);
 
        return ret ? 0 : -EBUSY;
 }
index fe0ab80994dd917625e9ff6562e62bb43b3a13cf..c4a01f2a6028a8070637a58285570c7bd8ce524e 100644 (file)
@@ -285,6 +285,7 @@ struct iwm_priv {
        u8 *eeprom;
        struct timer_list watchdog;
        struct work_struct reset_worker;
+       struct work_struct auth_retry_worker;
        struct mutex mutex;
 
        u8 *req_ie;
index 3147fe7b5130734adb188c24d9169a4c20f72b5f..952701e6127e72ceaa8ec94ecde77003a0fb331a 100644 (file)
@@ -207,6 +207,33 @@ static void iwm_reset_worker(struct work_struct *work)
        mutex_unlock(&iwm->mutex);
 }
 
+static void iwm_auth_retry_worker(struct work_struct *work)
+{
+       struct iwm_priv *iwm;
+       int i, ret;
+
+       iwm = container_of(work, struct iwm_priv, auth_retry_worker);
+       if (iwm->umac_profile_active) {
+               ret = iwm_invalidate_mlme_profile(iwm);
+               if (ret < 0)
+                       return;
+       }
+
+       iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+
+       ret = iwm_send_mlme_profile(iwm);
+       if (ret < 0)
+               return;
+
+       for (i = 0; i < IWM_NUM_KEYS; i++)
+               if (iwm->keys[i].key_len)
+                       iwm_set_key(iwm, 0, &iwm->keys[i]);
+
+       iwm_set_tx_key(iwm, iwm->default_key);
+}
+
+
+
 static void iwm_watchdog(unsigned long data)
 {
        struct iwm_priv *iwm = (struct iwm_priv *)data;
@@ -240,6 +267,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
        INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
        INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
        INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
+       INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
        INIT_LIST_HEAD(&iwm->bss_list);
 
        skb_queue_head_init(&iwm->rx_list);
index 648f84a83705e5ff71f824e6670384c108c260e4..5fa0a63ef0bf0182ffe43d4d1837fb2806593a6d 100644 (file)
@@ -501,6 +501,18 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
        return 0;
 }
 
+static u8 iwm_is_open_wep_profile(struct iwm_priv *iwm)
+{
+       if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
+            iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
+           (iwm->umac_profile->sec.ucast_cipher ==
+            iwm->umac_profile->sec.mcast_cipher) &&
+           (iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN))
+              return 1;
+
+       return 0;
+}
+
 static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
                                   unsigned long buf_size,
                                   struct iwm_wifi_cmd *cmd)
@@ -566,11 +578,17 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
                        goto ibss;
 
                if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
-                       cfg80211_connect_result(iwm_to_ndev(iwm),
-                                               complete->bssid,
-                                               NULL, 0, NULL, 0,
-                                               WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                               GFP_KERNEL);
+                       if (!iwm_is_open_wep_profile(iwm)) {
+                               cfg80211_connect_result(iwm_to_ndev(iwm),
+                                              complete->bssid,
+                                              NULL, 0, NULL, 0,
+                                              WLAN_STATUS_UNSPECIFIED_FAILURE,
+                                              GFP_KERNEL);
+                       } else {
+                               /* Let's try shared WEP auth */
+                               IWM_ERR(iwm, "Trying WEP shared auth\n");
+                               schedule_work(&iwm->auth_retry_worker);
+                       }
                else
                        cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
                                              GFP_KERNEL);