aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c18
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c29
3 files changed, 40 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 74964ee93bb7..f5c2d6f3fd43 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -178,6 +178,7 @@ struct iwm_key {
178#define IWM_STATUS_SCAN_ABORTING 2 178#define IWM_STATUS_SCAN_ABORTING 2
179#define IWM_STATUS_SME_CONNECTING 3 179#define IWM_STATUS_SME_CONNECTING 3
180#define IWM_STATUS_ASSOCIATED 4 180#define IWM_STATUS_ASSOCIATED 4
181#define IWM_STATUS_RESETTING 5
181 182
182struct iwm_tx_queue { 183struct iwm_tx_queue {
183 int id; 184 int id;
@@ -317,6 +318,7 @@ int iwm_mode_to_nl80211_iftype(int mode);
317int iwm_priv_init(struct iwm_priv *iwm); 318int iwm_priv_init(struct iwm_priv *iwm);
318void iwm_priv_deinit(struct iwm_priv *iwm); 319void iwm_priv_deinit(struct iwm_priv *iwm);
319void iwm_reset(struct iwm_priv *iwm); 320void iwm_reset(struct iwm_priv *iwm);
321void iwm_resetting(struct iwm_priv *iwm);
320void iwm_tx_credit_init_pools(struct iwm_priv *iwm, 322void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
321 struct iwm_umac_notif_alive *alive); 323 struct iwm_umac_notif_alive *alive);
322int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb); 324int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index fc7fce44a9d7..6a5b76acb645 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -187,7 +187,8 @@ static void iwm_reset_worker(struct work_struct *work)
187 memcpy(iwm->umac_profile, profile, sizeof(*profile)); 187 memcpy(iwm->umac_profile, profile, sizeof(*profile));
188 iwm_send_mlme_profile(iwm); 188 iwm_send_mlme_profile(iwm);
189 kfree(profile); 189 kfree(profile);
190 } 190 } else
191 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
191 192
192 out: 193 out:
193 mutex_unlock(&iwm->mutex); 194 mutex_unlock(&iwm->mutex);
@@ -200,7 +201,7 @@ static void iwm_watchdog(unsigned long data)
200 IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n"); 201 IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
201 202
202 if (modparam_reset) 203 if (modparam_reset)
203 schedule_work(&iwm->reset_worker); 204 iwm_resetting(iwm);
204} 205}
205 206
206int iwm_priv_init(struct iwm_priv *iwm) 207int iwm_priv_init(struct iwm_priv *iwm)
@@ -284,7 +285,11 @@ void iwm_reset(struct iwm_priv *iwm)
284 if (test_bit(IWM_STATUS_READY, &iwm->status)) 285 if (test_bit(IWM_STATUS_READY, &iwm->status))
285 iwm_target_reset(iwm); 286 iwm_target_reset(iwm);
286 287
287 iwm->status = 0; 288 if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
289 iwm->status = 0;
290 set_bit(IWM_STATUS_RESETTING, &iwm->status);
291 } else
292 iwm->status = 0;
288 iwm->scan_id = 1; 293 iwm->scan_id = 1;
289 294
290 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { 295 list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
@@ -300,6 +305,13 @@ void iwm_reset(struct iwm_priv *iwm)
300 iwm_link_off(iwm); 305 iwm_link_off(iwm);
301} 306}
302 307
308void iwm_resetting(struct iwm_priv *iwm)
309{
310 set_bit(IWM_STATUS_RESETTING, &iwm->status);
311
312 schedule_work(&iwm->reset_worker);
313}
314
303/* 315/*
304 * Notification code: 316 * Notification code:
305 * 317 *
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 2daa58633e6f..14950b147f91 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -118,6 +118,8 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
118 IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status)); 118 IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
119 IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status)); 119 IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
120 120
121 iwm_resetting(iwm);
122
121 return 0; 123 return 0;
122} 124}
123 125
@@ -528,11 +530,19 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
528 if (iwm->conf.mode == UMAC_MODE_IBSS) 530 if (iwm->conf.mode == UMAC_MODE_IBSS)
529 goto ibss; 531 goto ibss;
530 532
531 cfg80211_connect_result(iwm_to_ndev(iwm), 533 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
534 cfg80211_connect_result(iwm_to_ndev(iwm),
535 complete->bssid,
536 iwm->req_ie, iwm->req_ie_len,
537 iwm->resp_ie, iwm->resp_ie_len,
538 WLAN_STATUS_SUCCESS,
539 GFP_KERNEL);
540 else
541 cfg80211_roamed(iwm_to_ndev(iwm),
532 complete->bssid, 542 complete->bssid,
533 iwm->req_ie, iwm->req_ie_len, 543 iwm->req_ie, iwm->req_ie_len,
534 iwm->resp_ie, iwm->resp_ie_len, 544 iwm->resp_ie, iwm->resp_ie_len,
535 WLAN_STATUS_SUCCESS, GFP_KERNEL); 545 GFP_KERNEL);
536 break; 546 break;
537 case UMAC_ASSOC_COMPLETE_FAILURE: 547 case UMAC_ASSOC_COMPLETE_FAILURE:
538 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 548 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
@@ -551,19 +561,26 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
551 if (iwm->conf.mode == UMAC_MODE_IBSS) 561 if (iwm->conf.mode == UMAC_MODE_IBSS)
552 goto ibss; 562 goto ibss;
553 563
554 cfg80211_connect_result(iwm_to_ndev(iwm), complete->bssid, 564 if (!test_bit(IWM_STATUS_RESETTING, &iwm->status))
555 NULL, 0, NULL, 0, 565 cfg80211_connect_result(iwm_to_ndev(iwm),
556 WLAN_STATUS_UNSPECIFIED_FAILURE, 566 complete->bssid,
557 GFP_KERNEL); 567 NULL, 0, NULL, 0,
568 WLAN_STATUS_UNSPECIFIED_FAILURE,
569 GFP_KERNEL);
570 else
571 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0,
572 GFP_KERNEL);
558 break; 573 break;
559 default: 574 default:
560 break; 575 break;
561 } 576 }
562 577
578 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
563 return 0; 579 return 0;
564 580
565 ibss: 581 ibss:
566 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL); 582 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
583 clear_bit(IWM_STATUS_RESETTING, &iwm->status);
567 return 0; 584 return 0;
568} 585}
569 586