aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi/main.c
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2009-09-01 09:14:02 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-09-01 12:48:27 -0400
commitc7436273889e0ce511b317041f35344e92344885 (patch)
tree6b18a0a3d5308226afac15e1a545ef30119c925a /drivers/net/wireless/iwmc3200wifi/main.c
parentde15fd31fcabb4b81a556736dd67ec4f71462f07 (diff)
iwmc3200wifi: add disconnect work
When the driver receives "connection terminated" event from device, it could be caused by 2 reasons: the firmware is roaming or the connection is lost (AP disappears). For the former, an association complete event is supposed to come within 3 seconds. For the latter, the driver won't receive any event except the connection terminated. So we kick a delayed work (5*HZ) when we receive the connection terminated event. It will be canceled if it turns out to be a roaming event later. Otherwise we notify SME and userspace the disconnection. Signed-off-by: Zhu Yi <yi.zhu@intel.com> 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.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index cf2574442b57..c41fa8c5fa11 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -108,6 +108,26 @@ static void iwm_statistics_request(struct work_struct *work)
108 iwm_send_umac_stats_req(iwm, 0); 108 iwm_send_umac_stats_req(iwm, 0);
109} 109}
110 110
111static void iwm_disconnect_work(struct work_struct *work)
112{
113 struct iwm_priv *iwm =
114 container_of(work, struct iwm_priv, disconnect.work);
115
116 if (iwm->umac_profile_active)
117 iwm_invalidate_mlme_profile(iwm);
118
119 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
120 iwm->umac_profile_active = 0;
121 memset(iwm->bssid, 0, ETH_ALEN);
122 iwm->channel = 0;
123
124 iwm_link_off(iwm);
125
126 wake_up_interruptible(&iwm->mlme_queue);
127
128 cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
129}
130
111int __iwm_up(struct iwm_priv *iwm); 131int __iwm_up(struct iwm_priv *iwm);
112int __iwm_down(struct iwm_priv *iwm); 132int __iwm_down(struct iwm_priv *iwm);
113 133
@@ -198,6 +218,7 @@ int iwm_priv_init(struct iwm_priv *iwm)
198 spin_lock_init(&iwm->cmd_lock); 218 spin_lock_init(&iwm->cmd_lock);
199 iwm->scan_id = 1; 219 iwm->scan_id = 1;
200 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request); 220 INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
221 INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
201 INIT_WORK(&iwm->reset_worker, iwm_reset_worker); 222 INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
202 INIT_LIST_HEAD(&iwm->bss_list); 223 INIT_LIST_HEAD(&iwm->bss_list);
203 224