aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2012-05-15 10:08:54 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-05 10:16:08 -0400
commit6b8bf5bc5e99f52334bec1b06b14d28dc595c95a (patch)
treedce70af33853e584eed256952b7dbbcc55098eef /drivers/net
parent6e066921b3970232d5faadcdf33a92f43ec84334 (diff)
wlcore: fixes for connection_loss_work
We can't use cancel_delayed_work_sync() from functions that take the wl->mutex, since connection_loss_work also takes the mutex. This might result in a deadlock. Restructure the code so the work is synchronously canceled before taking the mutex. Avoid a bug where we would indefinitely delay the connection loss indication by re-queuing the connection loss work on consecutive beacon loss events. Cc: bartosz.markowski <bartosz.markowski@tieto.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ti/wlcore/event.c15
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c10
2 files changed, 19 insertions, 6 deletions
diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c
index 28e2a633c3be..4ed835799178 100644
--- a/drivers/net/wireless/ti/wlcore/event.c
+++ b/drivers/net/wireless/ti/wlcore/event.c
@@ -148,15 +148,24 @@ static int wl1271_event_process(struct wl1271 *wl)
148 int delay = wl->conf.conn.synch_fail_thold * 148 int delay = wl->conf.conn.synch_fail_thold *
149 wl->conf.conn.bss_lose_timeout; 149 wl->conf.conn.bss_lose_timeout;
150 wl1271_info("Beacon loss detected."); 150 wl1271_info("Beacon loss detected.");
151 cancel_delayed_work_sync(&wl->connection_loss_work); 151
152 /*
153 * if the work is already queued, it should take place. We
154 * don't want to delay the connection loss indication
155 * any more.
156 */
152 ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work, 157 ieee80211_queue_delayed_work(wl->hw, &wl->connection_loss_work,
153 msecs_to_jiffies(delay)); 158 msecs_to_jiffies(delay));
154 } 159 }
155 160
156 if (vector & REGAINED_BSS_EVENT_ID) { 161 if (vector & REGAINED_BSS_EVENT_ID) {
157 /* TODO: check for multi-role */ 162 /* TODO: check for multi-role */
158 wl1271_info("Beacon regained."); 163 wl1271_info("Beacon regained.");
159 cancel_delayed_work_sync(&wl->connection_loss_work); 164 cancel_delayed_work(&wl->connection_loss_work);
165
166 /* sanity check - we can't lose and gain the beacon together */
167 WARN(vector & BSS_LOSE_EVENT_ID,
168 "Concurrent beacon loss and gain from FW");
160 } 169 }
161 170
162 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { 171 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index af00dabf96b7..4be62c93808b 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -3712,9 +3712,6 @@ sta_not_found:
3712 do_join = true; 3712 do_join = true;
3713 set_assoc = true; 3713 set_assoc = true;
3714 3714
3715 /* Cancel connection_loss_work */
3716 cancel_delayed_work_sync(&wl->connection_loss_work);
3717
3718 /* 3715 /*
3719 * use basic rates from AP, and determine lowest rate 3716 * use basic rates from AP, and determine lowest rate
3720 * to use with control frames. 3717 * to use with control frames.
@@ -3964,6 +3961,13 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
3964 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x", 3961 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed 0x%x",
3965 (int)changed); 3962 (int)changed);
3966 3963
3964 /*
3965 * make sure to cancel pending disconnections if our association
3966 * state changed
3967 */
3968 if (!is_ap && (changed & BSS_CHANGED_ASSOC))
3969 cancel_delayed_work_sync(&wl->connection_loss_work);
3970
3967 mutex_lock(&wl->mutex); 3971 mutex_lock(&wl->mutex);
3968 3972
3969 if (unlikely(wl->state == WL1271_STATE_OFF)) 3973 if (unlikely(wl->state == WL1271_STATE_OFF))