diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 41 | ||||
-rw-r--r-- | net/mac80211/offchannel.c | 9 | ||||
-rw-r--r-- | net/mac80211/scan.c | 4 | ||||
-rw-r--r-- | net/mac80211/work.c | 99 |
5 files changed, 13 insertions, 142 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a785d61defe1..bdefa6ba3f4c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1220,13 +1220,11 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata); | |||
1220 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); | 1220 | void ieee80211_sched_scan_stopped_work(struct work_struct *work); |
1221 | 1221 | ||
1222 | /* off-channel helpers */ | 1222 | /* off-channel helpers */ |
1223 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local); | ||
1224 | void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, | 1223 | void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, |
1225 | bool tell_ap); | 1224 | bool tell_ap); |
1226 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | 1225 | void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, |
1227 | bool offchannel_ps_enable); | 1226 | bool offchannel_ps_enable); |
1228 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 1227 | void ieee80211_offchannel_return(struct ieee80211_local *local, |
1229 | bool enable_beaconing, | ||
1230 | bool offchannel_ps_disable); | 1228 | bool offchannel_ps_disable); |
1231 | void ieee80211_hw_roc_setup(struct ieee80211_local *local); | 1229 | void ieee80211_hw_roc_setup(struct ieee80211_local *local); |
1232 | 1230 | ||
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index dddedfad5404..944bed35d923 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -92,47 +92,6 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
92 | ieee80211_configure_filter(local); | 92 | ieee80211_configure_filter(local); |
93 | } | 93 | } |
94 | 94 | ||
95 | /* | ||
96 | * Returns true if we are logically configured to be on | ||
97 | * the operating channel AND the hardware-conf is currently | ||
98 | * configured on the operating channel. Compares channel-type | ||
99 | * as well. | ||
100 | */ | ||
101 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | ||
102 | { | ||
103 | struct ieee80211_channel *chan; | ||
104 | enum nl80211_channel_type channel_type; | ||
105 | |||
106 | /* This logic needs to match logic in ieee80211_hw_config */ | ||
107 | if (local->scan_channel) { | ||
108 | chan = local->scan_channel; | ||
109 | /* If scanning on oper channel, use whatever channel-type | ||
110 | * is currently in use. | ||
111 | */ | ||
112 | if (chan == local->oper_channel) | ||
113 | channel_type = local->_oper_channel_type; | ||
114 | else | ||
115 | channel_type = NL80211_CHAN_NO_HT; | ||
116 | } else if (local->tmp_channel) { | ||
117 | chan = local->tmp_channel; | ||
118 | channel_type = local->tmp_channel_type; | ||
119 | } else { | ||
120 | chan = local->oper_channel; | ||
121 | channel_type = local->_oper_channel_type; | ||
122 | } | ||
123 | |||
124 | if (chan != local->oper_channel || | ||
125 | channel_type != local->_oper_channel_type) | ||
126 | return false; | ||
127 | |||
128 | /* Check current hardware-config against oper_channel. */ | ||
129 | if (local->oper_channel != local->hw.conf.channel || | ||
130 | local->_oper_channel_type != local->hw.conf.channel_type) | ||
131 | return false; | ||
132 | |||
133 | return true; | ||
134 | } | ||
135 | |||
136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 95 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
137 | { | 96 | { |
138 | struct ieee80211_channel *chan; | 97 | struct ieee80211_channel *chan; |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index ebd8cccac8f2..e4330d843575 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -156,7 +156,6 @@ void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, | |||
156 | } | 156 | } |
157 | 157 | ||
158 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 158 | void ieee80211_offchannel_return(struct ieee80211_local *local, |
159 | bool enable_beaconing, | ||
160 | bool offchannel_ps_disable) | 159 | bool offchannel_ps_disable) |
161 | { | 160 | { |
162 | struct ieee80211_sub_if_data *sdata; | 161 | struct ieee80211_sub_if_data *sdata; |
@@ -188,11 +187,9 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
188 | netif_tx_wake_all_queues(sdata->dev); | 187 | netif_tx_wake_all_queues(sdata->dev); |
189 | } | 188 | } |
190 | 189 | ||
191 | /* Check to see if we should re-enable beaconing */ | 190 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
192 | if (enable_beaconing && | 191 | sdata->vif.type == NL80211_IFTYPE_ADHOC || |
193 | (sdata->vif.type == NL80211_IFTYPE_AP || | 192 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT) |
194 | sdata->vif.type == NL80211_IFTYPE_ADHOC || | ||
195 | sdata->vif.type == NL80211_IFTYPE_MESH_POINT)) | ||
196 | ieee80211_bss_info_change_notify( | 193 | ieee80211_bss_info_change_notify( |
197 | sdata, BSS_CHANGED_BEACON_ENABLED); | 194 | sdata, BSS_CHANGED_BEACON_ENABLED); |
198 | } | 195 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 81863031e0a3..2c5041cc71f8 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -297,7 +297,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
297 | if (!was_hw_scan) { | 297 | if (!was_hw_scan) { |
298 | ieee80211_configure_filter(local); | 298 | ieee80211_configure_filter(local); |
299 | drv_sw_scan_complete(local); | 299 | drv_sw_scan_complete(local); |
300 | ieee80211_offchannel_return(local, true, true); | 300 | ieee80211_offchannel_return(local, true); |
301 | } | 301 | } |
302 | 302 | ||
303 | ieee80211_recalc_idle(local); | 303 | ieee80211_recalc_idle(local); |
@@ -602,7 +602,7 @@ static void ieee80211_scan_state_suspend(struct ieee80211_local *local, | |||
602 | * in off-channel state..will put that back | 602 | * in off-channel state..will put that back |
603 | * on-channel at the end of scanning. | 603 | * on-channel at the end of scanning. |
604 | */ | 604 | */ |
605 | ieee80211_offchannel_return(local, true, false); | 605 | ieee80211_offchannel_return(local, false); |
606 | 606 | ||
607 | *next_delay = HZ / 5; | 607 | *next_delay = HZ / 5; |
608 | /* afterwards, resume scan & go to next channel */ | 608 | /* afterwards, resume scan & go to next channel */ |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6884a2d986dc..c6dd01a05291 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -862,44 +862,6 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
862 | kfree_skb(skb); | 862 | kfree_skb(skb); |
863 | } | 863 | } |
864 | 864 | ||
865 | static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct, | ||
866 | enum nl80211_channel_type oper_ct) | ||
867 | { | ||
868 | switch (wk_ct) { | ||
869 | case NL80211_CHAN_NO_HT: | ||
870 | return true; | ||
871 | case NL80211_CHAN_HT20: | ||
872 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
873 | return true; | ||
874 | return false; | ||
875 | case NL80211_CHAN_HT40MINUS: | ||
876 | case NL80211_CHAN_HT40PLUS: | ||
877 | return (wk_ct == oper_ct); | ||
878 | } | ||
879 | WARN_ON(1); /* shouldn't get here */ | ||
880 | return false; | ||
881 | } | ||
882 | |||
883 | static enum nl80211_channel_type | ||
884 | ieee80211_calc_ct(enum nl80211_channel_type wk_ct, | ||
885 | enum nl80211_channel_type oper_ct) | ||
886 | { | ||
887 | switch (wk_ct) { | ||
888 | case NL80211_CHAN_NO_HT: | ||
889 | return oper_ct; | ||
890 | case NL80211_CHAN_HT20: | ||
891 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
892 | return oper_ct; | ||
893 | return wk_ct; | ||
894 | case NL80211_CHAN_HT40MINUS: | ||
895 | case NL80211_CHAN_HT40PLUS: | ||
896 | return wk_ct; | ||
897 | } | ||
898 | WARN_ON(1); /* shouldn't get here */ | ||
899 | return wk_ct; | ||
900 | } | ||
901 | |||
902 | |||
903 | static void ieee80211_work_timer(unsigned long data) | 865 | static void ieee80211_work_timer(unsigned long data) |
904 | { | 866 | { |
905 | struct ieee80211_local *local = (void *) data; | 867 | struct ieee80211_local *local = (void *) data; |
@@ -950,40 +912,12 @@ static void ieee80211_work_work(struct work_struct *work) | |||
950 | } | 912 | } |
951 | 913 | ||
952 | if (!started && !local->tmp_channel) { | 914 | if (!started && !local->tmp_channel) { |
953 | bool on_oper_chan, on_oper_chan2; | 915 | ieee80211_offchannel_stop_vifs(local, true); |
954 | enum nl80211_channel_type wk_ct; | ||
955 | |||
956 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | ||
957 | |||
958 | /* Work with existing channel type if possible. */ | ||
959 | wk_ct = wk->chan_type; | ||
960 | if (wk->chan == local->hw.conf.channel) | ||
961 | wk_ct = ieee80211_calc_ct(wk->chan_type, | ||
962 | local->hw.conf.channel_type); | ||
963 | 916 | ||
964 | local->tmp_channel = wk->chan; | 917 | local->tmp_channel = wk->chan; |
965 | local->tmp_channel_type = wk_ct; | 918 | local->tmp_channel_type = wk->chan_type; |
966 | /* | 919 | |
967 | * Leave the station vifs in awake mode if they | 920 | ieee80211_hw_config(local, 0); |
968 | * happen to be on the same channel as | ||
969 | * the requested channel. | ||
970 | */ | ||
971 | on_oper_chan2 = ieee80211_cfg_on_oper_channel(local); | ||
972 | if (on_oper_chan != on_oper_chan2) { | ||
973 | if (on_oper_chan2) { | ||
974 | /* going off oper channel, PS too */ | ||
975 | ieee80211_offchannel_stop_vifs(local, | ||
976 | true); | ||
977 | ieee80211_hw_config(local, 0); | ||
978 | } else { | ||
979 | /* going on channel, but leave PS | ||
980 | * off-channel. */ | ||
981 | ieee80211_hw_config(local, 0); | ||
982 | ieee80211_offchannel_return(local, | ||
983 | true, | ||
984 | false); | ||
985 | } | ||
986 | } | ||
987 | 921 | ||
988 | started = true; | 922 | started = true; |
989 | wk->timeout = jiffies; | 923 | wk->timeout = jiffies; |
@@ -1052,34 +986,17 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1052 | list_for_each_entry(wk, &local->work_list, list) { | 986 | list_for_each_entry(wk, &local->work_list, list) { |
1053 | if (!wk->started) | 987 | if (!wk->started) |
1054 | continue; | 988 | continue; |
1055 | if (wk->chan != local->tmp_channel) | 989 | if (wk->chan != local->tmp_channel || |
1056 | continue; | 990 | wk->chan_type != local->tmp_channel_type) |
1057 | if (!ieee80211_work_ct_coexists(wk->chan_type, | ||
1058 | local->tmp_channel_type)) | ||
1059 | continue; | 991 | continue; |
1060 | remain_off_channel = true; | 992 | remain_off_channel = true; |
1061 | } | 993 | } |
1062 | 994 | ||
1063 | if (!remain_off_channel && local->tmp_channel) { | 995 | if (!remain_off_channel && local->tmp_channel) { |
1064 | local->tmp_channel = NULL; | 996 | local->tmp_channel = NULL; |
1065 | /* If tmp_channel wasn't operating channel, then | 997 | ieee80211_hw_config(local, 0); |
1066 | * we need to go back on-channel. | ||
1067 | * NOTE: If we can ever be here while scannning, | ||
1068 | * or if the hw_config() channel config logic changes, | ||
1069 | * then we may need to do a more thorough check to see if | ||
1070 | * we still need to do a hardware config. Currently, | ||
1071 | * we cannot be here while scanning, however. | ||
1072 | */ | ||
1073 | if (!ieee80211_cfg_on_oper_channel(local)) | ||
1074 | ieee80211_hw_config(local, 0); | ||
1075 | 998 | ||
1076 | /* At the least, we need to disable offchannel_ps, | 999 | ieee80211_offchannel_return(local, true); |
1077 | * so just go ahead and run the entire offchannel | ||
1078 | * return logic here. We *could* skip enabling | ||
1079 | * beaconing if we were already on-oper-channel | ||
1080 | * as a future optimization. | ||
1081 | */ | ||
1082 | ieee80211_offchannel_return(local, true, true); | ||
1083 | 1000 | ||
1084 | /* give connection some time to breathe */ | 1001 | /* give connection some time to breathe */ |
1085 | run_again(local, jiffies + HZ/2); | 1002 | run_again(local, jiffies + HZ/2); |