diff options
author | Samuel Ortiz <sameo@linux.intel.com> | 2009-09-01 15:14:05 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-09-01 12:48:28 -0400 |
commit | d210176eaaed0c7883caba52665bcfb5d420c660 (patch) | |
tree | 1ac8c392c188e330be24496d42f9e5d9846ef36b /drivers/net/wireless/iwmc3200wifi/main.c | |
parent | d04bd6283cf7433d56f3d8f648f1d6963fda4fdc (diff) | |
download | linux-d210176eaaed0c7883caba52665bcfb5d420c660.tar.bz2 |
iwmc3200wifi: Handle UMAC stalls and UMAC assert properly
When UMAC stalls or asserts, we want to reset the device. But when we're
associated, the current reset worker will end up calling
cfg80211_connect_result() with the cfg80211 sme layer knowing that we're
reassociating. That ends up with some ugly warnings.
With this patch we're telling the upper layer that we've roamed if
reassociation succeeds, and that we're disconnected if it fails.
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi/main.c')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/main.c | 18 |
1 files changed, 15 insertions, 3 deletions
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) memcpy(iwm->umac_profile, profile, sizeof(*profile)); iwm_send_mlme_profile(iwm); kfree(profile); - } + } else + clear_bit(IWM_STATUS_RESETTING, &iwm->status); out: mutex_unlock(&iwm->mutex); @@ -200,7 +201,7 @@ static void iwm_watchdog(unsigned long data) IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n"); if (modparam_reset) - schedule_work(&iwm->reset_worker); + iwm_resetting(iwm); } int iwm_priv_init(struct iwm_priv *iwm) @@ -284,7 +285,11 @@ void iwm_reset(struct iwm_priv *iwm) if (test_bit(IWM_STATUS_READY, &iwm->status)) iwm_target_reset(iwm); - iwm->status = 0; + if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) { + iwm->status = 0; + set_bit(IWM_STATUS_RESETTING, &iwm->status); + } else + iwm->status = 0; iwm->scan_id = 1; list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { @@ -300,6 +305,13 @@ void iwm_reset(struct iwm_priv *iwm) iwm_link_off(iwm); } +void iwm_resetting(struct iwm_priv *iwm) +{ + set_bit(IWM_STATUS_RESETTING, &iwm->status); + + schedule_work(&iwm->reset_worker); +} + /* * Notification code: * |