diff options
Diffstat (limited to 'net/mac80211/work.c')
-rw-r--r-- | net/mac80211/work.c | 59 |
1 files changed, 50 insertions, 9 deletions
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6bf787a5b38a..204f0a4db969 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -126,12 +126,6 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
126 | 126 | ||
127 | /* determine capability flags */ | 127 | /* determine capability flags */ |
128 | 128 | ||
129 | if (ieee80211_disable_40mhz_24ghz && | ||
130 | sband->band == IEEE80211_BAND_2GHZ) { | ||
131 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
132 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
133 | } | ||
134 | |||
135 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 129 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
136 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 130 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
137 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { | 131 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { |
@@ -874,6 +868,44 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
874 | kfree_skb(skb); | 868 | kfree_skb(skb); |
875 | } | 869 | } |
876 | 870 | ||
871 | static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct, | ||
872 | enum nl80211_channel_type oper_ct) | ||
873 | { | ||
874 | switch (wk_ct) { | ||
875 | case NL80211_CHAN_NO_HT: | ||
876 | return true; | ||
877 | case NL80211_CHAN_HT20: | ||
878 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
879 | return true; | ||
880 | return false; | ||
881 | case NL80211_CHAN_HT40MINUS: | ||
882 | case NL80211_CHAN_HT40PLUS: | ||
883 | return (wk_ct == oper_ct); | ||
884 | } | ||
885 | WARN_ON(1); /* shouldn't get here */ | ||
886 | return false; | ||
887 | } | ||
888 | |||
889 | static enum nl80211_channel_type | ||
890 | ieee80211_calc_ct(enum nl80211_channel_type wk_ct, | ||
891 | enum nl80211_channel_type oper_ct) | ||
892 | { | ||
893 | switch (wk_ct) { | ||
894 | case NL80211_CHAN_NO_HT: | ||
895 | return oper_ct; | ||
896 | case NL80211_CHAN_HT20: | ||
897 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
898 | return oper_ct; | ||
899 | return wk_ct; | ||
900 | case NL80211_CHAN_HT40MINUS: | ||
901 | case NL80211_CHAN_HT40PLUS: | ||
902 | return wk_ct; | ||
903 | } | ||
904 | WARN_ON(1); /* shouldn't get here */ | ||
905 | return wk_ct; | ||
906 | } | ||
907 | |||
908 | |||
877 | static void ieee80211_work_timer(unsigned long data) | 909 | static void ieee80211_work_timer(unsigned long data) |
878 | { | 910 | { |
879 | struct ieee80211_local *local = (void *) data; | 911 | struct ieee80211_local *local = (void *) data; |
@@ -927,14 +959,22 @@ static void ieee80211_work_work(struct work_struct *work) | |||
927 | bool on_oper_chan; | 959 | bool on_oper_chan; |
928 | bool tmp_chan_changed = false; | 960 | bool tmp_chan_changed = false; |
929 | bool on_oper_chan2; | 961 | bool on_oper_chan2; |
962 | enum nl80211_channel_type wk_ct; | ||
930 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 963 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
964 | |||
965 | /* Work with existing channel type if possible. */ | ||
966 | wk_ct = wk->chan_type; | ||
967 | if (wk->chan == local->hw.conf.channel) | ||
968 | wk_ct = ieee80211_calc_ct(wk->chan_type, | ||
969 | local->hw.conf.channel_type); | ||
970 | |||
931 | if (local->tmp_channel) | 971 | if (local->tmp_channel) |
932 | if ((local->tmp_channel != wk->chan) || | 972 | if ((local->tmp_channel != wk->chan) || |
933 | (local->tmp_channel_type != wk->chan_type)) | 973 | (local->tmp_channel_type != wk_ct)) |
934 | tmp_chan_changed = true; | 974 | tmp_chan_changed = true; |
935 | 975 | ||
936 | local->tmp_channel = wk->chan; | 976 | local->tmp_channel = wk->chan; |
937 | local->tmp_channel_type = wk->chan_type; | 977 | local->tmp_channel_type = wk_ct; |
938 | /* | 978 | /* |
939 | * Leave the station vifs in awake mode if they | 979 | * Leave the station vifs in awake mode if they |
940 | * happen to be on the same channel as | 980 | * happen to be on the same channel as |
@@ -1031,7 +1071,8 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1031 | continue; | 1071 | continue; |
1032 | if (wk->chan != local->tmp_channel) | 1072 | if (wk->chan != local->tmp_channel) |
1033 | continue; | 1073 | continue; |
1034 | if (wk->chan_type != local->tmp_channel_type) | 1074 | if (ieee80211_work_ct_coexists(wk->chan_type, |
1075 | local->tmp_channel_type)) | ||
1035 | continue; | 1076 | continue; |
1036 | remain_off_channel = true; | 1077 | remain_off_channel = true; |
1037 | } | 1078 | } |