aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2009-10-16 01:18:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:48:27 -0400
commit9829e1b510214956bc9d5e278be49d781e1a6fbf (patch)
tree412d0c279ee0a341ad467da3d466e7d8f505b1fd
parent56e3f085f5b5e49cca37a3d1b0aa4266b984eb12 (diff)
iwmc3200wifi: Try shared auth when open WEP fails
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>
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c28
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c28
4 files changed, 53 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 25fb8dfd83b5..cad511afd907 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -793,7 +793,7 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
793 return ret; 793 return ret;
794 794
795 ret = wait_event_interruptible_timeout(iwm->mlme_queue, 795 ret = wait_event_interruptible_timeout(iwm->mlme_queue,
796 (iwm->umac_profile_active == 0), 2 * HZ); 796 (iwm->umac_profile_active == 0), 5 * HZ);
797 797
798 return ret ? 0 : -EBUSY; 798 return ret ? 0 : -EBUSY;
799} 799}
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index fe0ab80994dd..c4a01f2a6028 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -285,6 +285,7 @@ struct iwm_priv {
285 u8 *eeprom; 285 u8 *eeprom;
286 struct timer_list watchdog; 286 struct timer_list watchdog;
287 struct work_struct reset_worker; 287 struct work_struct reset_worker;
288 struct work_struct auth_retry_worker;
288 struct mutex mutex; 289 struct mutex mutex;
289 290
290 u8 *req_ie; 291 u8 *req_ie;
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 3147fe7b5130..952701e6127e 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -207,6 +207,33 @@ static void iwm_reset_worker(struct work_struct *work)
207 mutex_unlock(&iwm->mutex); 207 mutex_unlock(&iwm->mutex);
208} 208}
209 209
210static void iwm_auth_retry_worker(struct work_struct *work)
211{
212 struct iwm_priv *iwm;
213 int i, ret;
214
215 iwm = container_of(work, struct iwm_priv, auth_retry_worker);
216 if (iwm->umac_profile_active) {
217 ret = iwm_invalidate_mlme_profile(iwm);
218 if (ret < 0)
219 return;
220 }
221
222 iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
223
224 ret = iwm_send_mlme_profile(iwm);
225 if (ret < 0)
226 return;
227
228 for (i = 0; i < IWM_NUM_KEYS; i++)
229 if (iwm->keys[i].key_len)
230 iwm_set_key(iwm, 0, &iwm->keys[i]);
231
232 iwm_set_tx_key(iwm, iwm->default_key);
233}
234
235
236
210static void iwm_watchdog(unsigned long data) 237static void iwm_watchdog(unsigned long data)
211{ 238{
212 struct iwm_priv *iwm = (struct iwm_priv *)data; 239 struct iwm_priv *iwm = (struct iwm_priv *)data;
@@ -240,6 +267,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
240 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work); 267 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
241 INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work); 268 INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
242 INIT_WORK(&iwm->reset_worker, iwm_reset_worker); 269 INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
270 INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
243 INIT_LIST_HEAD(&iwm->bss_list); 271 INIT_LIST_HEAD(&iwm->bss_list);
244 272
245 skb_queue_head_init(&iwm->rx_list); 273 skb_queue_head_init(&iwm->rx_list);
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 648f84a83705..5fa0a63ef0bf 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -501,6 +501,18 @@ static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
501 return 0; 501 return 0;
502} 502}
503 503
504static u8 iwm_is_open_wep_profile(struct iwm_priv *iwm)
505{
506 if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
507 iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
508 (iwm->umac_profile->sec.ucast_cipher ==
509 iwm->umac_profile->sec.mcast_cipher) &&
510 (iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_OPEN))
511 return 1;
512
513 return 0;
514}
515
504static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, 516static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
505 unsigned long buf_size, 517 unsigned long buf_size,
506 struct iwm_wifi_cmd *cmd) 518 struct iwm_wifi_cmd *cmd)
@@ -566,11 +578,17 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
566 goto ibss; 578 goto ibss;
567 579
568 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status)) 580 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
569 cfg80211_connect_result(iwm_to_ndev(iwm), 581 if (!iwm_is_open_wep_profile(iwm)) {
570 complete->bssid, 582 cfg80211_connect_result(iwm_to_ndev(iwm),
571 NULL, 0, NULL, 0, 583 complete->bssid,
572 WLAN_STATUS_UNSPECIFIED_FAILURE, 584 NULL, 0, NULL, 0,
573 GFP_KERNEL); 585 WLAN_STATUS_UNSPECIFIED_FAILURE,
586 GFP_KERNEL);
587 } else {
588 /* Let's try shared WEP auth */
589 IWM_ERR(iwm, "Trying WEP shared auth\n");
590 schedule_work(&iwm->auth_retry_worker);
591 }
574 else 592 else
575 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, 593 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
576 GFP_KERNEL); 594 GFP_KERNEL);