aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-29 04:20:02 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-30 15:08:31 -0500
commite76aadc572288a158ae18ae1c10fe395c7bca066 (patch)
tree82c3e5a961039826c31b944d1f27f488743f9d8b /net/mac80211
parent742c29fd5bcd73f14facd6c7f3912c5ab66739ed (diff)
mac80211: revert on-channel work optimisations
The on-channel work optimisations have caused a number of issues, and the code is unfortunately very complex and almost impossible to follow. Instead of attempting to put in more workarounds let's just remove those optimisations, we can work on them again later, after we change the whole auth/assoc design. This should fix rate_control_send_low() warnings, see RH bug 731365. Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/main.c41
-rw-r--r--net/mac80211/offchannel.c9
-rw-r--r--net/mac80211/scan.c4
-rw-r--r--net/mac80211/work.c99
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);
1220void ieee80211_sched_scan_stopped_work(struct work_struct *work); 1220void ieee80211_sched_scan_stopped_work(struct work_struct *work);
1221 1221
1222/* off-channel helpers */ 1222/* off-channel helpers */
1223bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local);
1224void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local, 1223void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,
1225 bool tell_ap); 1224 bool tell_ap);
1226void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, 1225void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local,
1227 bool offchannel_ps_enable); 1226 bool offchannel_ps_enable);
1228void ieee80211_offchannel_return(struct ieee80211_local *local, 1227void ieee80211_offchannel_return(struct ieee80211_local *local,
1229 bool enable_beaconing,
1230 bool offchannel_ps_disable); 1228 bool offchannel_ps_disable);
1231void ieee80211_hw_roc_setup(struct ieee80211_local *local); 1229void 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 */
101bool 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
136int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 95int 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
158void ieee80211_offchannel_return(struct ieee80211_local *local, 158void 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
865static 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
883static enum nl80211_channel_type
884ieee80211_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
903static void ieee80211_work_timer(unsigned long data) 865static 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);