aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-07-09 20:39:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:10 -0400
commitca386f3137eb68621fadba546d9eb35ac2f82de3 (patch)
treebfdb1ecabe0ca942fadec255a7c92ecac405f153 /net/mac80211
parent01a7e08436929271c6173b5daf3e193ef5b3561a (diff)
mac80211: fix multi-use timer
We have, sometimes, multiple things that want to run but don't have their own timer. Introduce a new function to mac80211's mlme run_again() that makes sure that the timer will run again at the _first_ needed time, use that function and also properly reprogram the timer once it fired. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mlme.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8e4a60497bba..c1114bb8095b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -72,6 +72,26 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
72 WARN_ON(!mutex_is_locked(&ifmgd->mtx)); 72 WARN_ON(!mutex_is_locked(&ifmgd->mtx));
73} 73}
74 74
75/*
76 * We can have multiple work items (and connection probing)
77 * scheduling this timer, but we need to take care to only
78 * reschedule it when it should fire _earlier_ than it was
79 * asked for before, or if it's not pending right now. This
80 * function ensures that. Note that it then is required to
81 * run this function for all timeouts after the first one
82 * has happened -- the work that runs from this timer will
83 * do that.
84 */
85static void run_again(struct ieee80211_if_managed *ifmgd,
86 unsigned long timeout)
87{
88 ASSERT_MGD_MTX(ifmgd);
89
90 if (!timer_pending(&ifmgd->timer) ||
91 time_before(timeout, ifmgd->timer.expires))
92 mod_timer(&ifmgd->timer, timeout);
93}
94
75static int ecw2cw(int ecw) 95static int ecw2cw(int ecw)
76{ 96{
77 return (1 << ecw) - 1; 97 return (1 << ecw) - 1;
@@ -916,7 +936,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
916 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0); 936 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);
917 937
918 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 938 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
919 mod_timer(&ifmgd->timer, wk->timeout); 939 run_again(ifmgd, wk->timeout);
920 940
921 return RX_MGMT_NONE; 941 return RX_MGMT_NONE;
922} 942}
@@ -958,7 +978,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
958 wk->auth_transaction = 2; 978 wk->auth_transaction = 2;
959 979
960 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 980 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
961 mod_timer(&ifmgd->timer, wk->timeout); 981 run_again(ifmgd, wk->timeout);
962 982
963 return RX_MGMT_NONE; 983 return RX_MGMT_NONE;
964} 984}
@@ -1079,7 +1099,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1079 ieee80211_send_assoc(sdata, wk); 1099 ieee80211_send_assoc(sdata, wk);
1080 1100
1081 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 1101 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
1082 mod_timer(&ifmgd->timer, wk->timeout); 1102 run_again(ifmgd, wk->timeout);
1083 1103
1084 return RX_MGMT_NONE; 1104 return RX_MGMT_NONE;
1085} 1105}
@@ -1140,7 +1160,7 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1140 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 1160 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1141 ssid + 2, ssid[1], NULL, 0); 1161 ssid + 2, ssid[1], NULL, 0);
1142 1162
1143 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); 1163 run_again(ifmgd, jiffies + IEEE80211_PROBE_WAIT);
1144 out: 1164 out:
1145 mutex_unlock(&ifmgd->mtx); 1165 mutex_unlock(&ifmgd->mtx);
1146} 1166}
@@ -1350,8 +1370,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1350 sdata->dev->name, tu, ms); 1370 sdata->dev->name, tu, ms);
1351 wk->timeout = jiffies + msecs_to_jiffies(ms); 1371 wk->timeout = jiffies + msecs_to_jiffies(ms);
1352 if (ms > IEEE80211_ASSOC_TIMEOUT) 1372 if (ms > IEEE80211_ASSOC_TIMEOUT)
1353 mod_timer(&ifmgd->timer, 1373 run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
1354 jiffies + msecs_to_jiffies(ms));
1355 return RX_MGMT_NONE; 1374 return RX_MGMT_NONE;
1356 } 1375 }
1357 1376
@@ -1981,8 +2000,15 @@ static void ieee80211_sta_work(struct work_struct *work)
1981 } 2000 }
1982 2001
1983 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) { 2002 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
1984 if (time_before(jiffies, wk->timeout)) 2003 if (time_is_after_jiffies(wk->timeout)) {
2004 /*
2005 * This work item isn't supposed to be worked on
2006 * right now, but take care to adjust the timer
2007 * properly.
2008 */
2009 run_again(ifmgd, wk->timeout);
1985 continue; 2010 continue;
2011 }
1986 2012
1987 switch (wk->state) { 2013 switch (wk->state) {
1988 default: 2014 default: