diff options
Diffstat (limited to 'net/mac80211/work.c')
-rw-r--r-- | net/mac80211/work.c | 32 |
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 | ||
563 | static enum work_action __must_check | 564 | static enum work_action __must_check |
565 | ieee80211_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 | |||
583 | static enum work_action __must_check | ||
564 | ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) | 584 | ieee80211_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) { |