diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-07-09 20:39:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-07-24 15:05:10 -0400 |
commit | ca386f3137eb68621fadba546d9eb35ac2f82de3 (patch) | |
tree | bfdb1ecabe0ca942fadec255a7c92ecac405f153 /net/mac80211 | |
parent | 01a7e08436929271c6173b5daf3e193ef5b3561a (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.c | 40 |
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 | */ | ||
85 | static 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 | |||
75 | static int ecw2cw(int ecw) | 95 | static 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: |