aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/work.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/work.c')
-rw-r--r--net/mac80211/work.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index ae344d1ba056..36305e0d06ef 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -458,8 +458,9 @@ ieee80211_direct_probe(struct ieee80211_work *wk)
458 return WORK_ACT_TIMEOUT; 458 return WORK_ACT_TIMEOUT;
459 } 459 }
460 460
461 printk(KERN_DEBUG "%s: direct probe to %pM (try %d)\n", 461 printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n",
462 sdata->name, wk->filter_ta, wk->probe_auth.tries); 462 sdata->name, wk->filter_ta, wk->probe_auth.tries,
463 IEEE80211_AUTH_MAX_TRIES);
463 464
464 /* 465 /*
465 * Direct probe is sent to broadcast address as some APs 466 * Direct probe is sent to broadcast address as some APs
@@ -561,6 +562,25 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
561} 562}
562 563
563static enum work_action __must_check 564static enum work_action __must_check
565ieee80211_offchannel_tx(struct ieee80211_work *wk)
566{
567 if (!wk->started) {
568 wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait);
569
570 /*
571 * After this, offchan_tx.frame remains but now is no
572 * longer a valid pointer -- we still need it as the
573 * cookie for canceling this work.
574 */
575 ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame);
576
577 return WORK_ACT_NONE;
578 }
579
580 return WORK_ACT_TIMEOUT;
581}
582
583static enum work_action __must_check
564ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) 584ieee80211_assoc_beacon_wait(struct ieee80211_work *wk)
565{ 585{
566 if (wk->started) 586 if (wk->started)
@@ -955,6 +975,9 @@ static void ieee80211_work_work(struct work_struct *work)
955 case IEEE80211_WORK_REMAIN_ON_CHANNEL: 975 case IEEE80211_WORK_REMAIN_ON_CHANNEL:
956 rma = ieee80211_remain_on_channel_timeout(wk); 976 rma = ieee80211_remain_on_channel_timeout(wk);
957 break; 977 break;
978 case IEEE80211_WORK_OFFCHANNEL_TX:
979 rma = ieee80211_offchannel_tx(wk);
980 break;
958 case IEEE80211_WORK_ASSOC_BEACON_WAIT: 981 case IEEE80211_WORK_ASSOC_BEACON_WAIT:
959 rma = ieee80211_assoc_beacon_wait(wk); 982 rma = ieee80211_assoc_beacon_wait(wk);
960 break; 983 break;
@@ -1051,11 +1074,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1051{ 1074{
1052 struct ieee80211_local *local = sdata->local; 1075 struct ieee80211_local *local = sdata->local;
1053 struct ieee80211_work *wk; 1076 struct ieee80211_work *wk;
1077 bool cleanup = false;
1054 1078
1055 mutex_lock(&local->mtx); 1079 mutex_lock(&local->mtx);
1056 list_for_each_entry(wk, &local->work_list, list) { 1080 list_for_each_entry(wk, &local->work_list, list) {
1057 if (wk->sdata != sdata) 1081 if (wk->sdata != sdata)
1058 continue; 1082 continue;
1083 cleanup = true;
1059 wk->type = IEEE80211_WORK_ABORT; 1084 wk->type = IEEE80211_WORK_ABORT;
1060 wk->started = true; 1085 wk->started = true;
1061 wk->timeout = jiffies; 1086 wk->timeout = jiffies;
@@ -1063,7 +1088,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata)
1063 mutex_unlock(&local->mtx); 1088 mutex_unlock(&local->mtx);
1064 1089
1065 /* run cleanups etc. */ 1090 /* run cleanups etc. */
1066 ieee80211_work_work(&local->work_work); 1091 if (cleanup)
1092 ieee80211_work_work(&local->work_work);
1067 1093
1068 mutex_lock(&local->mtx); 1094 mutex_lock(&local->mtx);
1069 list_for_each_entry(wk, &local->work_list, list) { 1095 list_for_each_entry(wk, &local->work_list, list) {