diff options
author | Ben Greear <greearb@candelatech.com> | 2011-02-04 14:54:17 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-04 16:30:32 -0500 |
commit | b23b025fe246f3acc2988eb6d400df34c27cb8ae (patch) | |
tree | e1c8cd163dc4dc7c603652a9e101f8381cf66fdc /net/mac80211/main.c | |
parent | cb8d61de2d7f074654057b2b924da1efbf625ad4 (diff) |
mac80211: Optimize scans on current operating channel.
This should decrease un-necessary flushes, on/off channel work,
and channel changes in cases where the only scanned channel is
the current operating channel.
* Removes SCAN_OFF_CHANNEL flag, uses SDATA_STATE_OFFCHANNEL
and is-scanning flags instead.
* Add helper method to determine if we are currently configured
for the operating channel.
* Do no blindly go off/on channel in work.c Instead, only call
appropriate on/off code when we really need to change channels.
Always enable offchannel-ps mode when starting work,
and disable it when we are done.
* Consolidate ieee80211_offchannel_stop_station and
ieee80211_offchannel_stop_beaconing, call it
ieee80211_offchannel_stop_vifs instead.
* Accept non-beacon frames when scanning on operating channel.
* Scan state machine optimized to minimize on/off channel
transitions. Also, when going on-channel, go ahead and
re-enable beaconing. We're going to be there for 200ms,
so seems like some useful beaconing could happen.
Always enable offchannel-ps mode when starting software
scan, and disable it when we are done.
* Grab local->mtx earlier in __ieee80211_scan_completed_finish
so that we are protected when calling hw_config(), etc.
* Pass probe-responses up the stack if scanning on local
channel, so that mlme can take a look.
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 09a27449f3fd..c155c0b69426 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -98,6 +98,41 @@ static void ieee80211_reconfig_filter(struct work_struct *work) | |||
98 | ieee80211_configure_filter(local); | 98 | ieee80211_configure_filter(local); |
99 | } | 99 | } |
100 | 100 | ||
101 | /* | ||
102 | * Returns true if we are logically configured to be on | ||
103 | * the operating channel AND the hardware-conf is currently | ||
104 | * configured on the operating channel. Compares channel-type | ||
105 | * as well. | ||
106 | */ | ||
107 | bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | ||
108 | { | ||
109 | struct ieee80211_channel *chan, *scan_chan; | ||
110 | enum nl80211_channel_type channel_type; | ||
111 | |||
112 | /* This logic needs to match logic in ieee80211_hw_config */ | ||
113 | if (local->scan_channel) { | ||
114 | chan = local->scan_channel; | ||
115 | channel_type = NL80211_CHAN_NO_HT; | ||
116 | } else if (local->tmp_channel) { | ||
117 | chan = scan_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 | |||
101 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 136 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
102 | { | 137 | { |
103 | struct ieee80211_channel *chan, *scan_chan; | 138 | struct ieee80211_channel *chan, *scan_chan; |
@@ -110,21 +145,27 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
110 | 145 | ||
111 | scan_chan = local->scan_channel; | 146 | scan_chan = local->scan_channel; |
112 | 147 | ||
148 | /* If this off-channel logic ever changes, ieee80211_on_oper_channel | ||
149 | * may need to change as well. | ||
150 | */ | ||
113 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 151 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
114 | if (scan_chan) { | 152 | if (scan_chan) { |
115 | chan = scan_chan; | 153 | chan = scan_chan; |
116 | channel_type = NL80211_CHAN_NO_HT; | 154 | channel_type = NL80211_CHAN_NO_HT; |
117 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | 155 | } else if (local->tmp_channel) { |
118 | } else if (local->tmp_channel && | ||
119 | local->oper_channel != local->tmp_channel) { | ||
120 | chan = scan_chan = local->tmp_channel; | 156 | chan = scan_chan = local->tmp_channel; |
121 | channel_type = local->tmp_channel_type; | 157 | channel_type = local->tmp_channel_type; |
122 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
123 | } else { | 158 | } else { |
124 | chan = local->oper_channel; | 159 | chan = local->oper_channel; |
125 | channel_type = local->_oper_channel_type; | 160 | channel_type = local->_oper_channel_type; |
126 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | ||
127 | } | 161 | } |
162 | |||
163 | if (chan != local->oper_channel || | ||
164 | channel_type != local->_oper_channel_type) | ||
165 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
166 | else | ||
167 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | ||
168 | |||
128 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 169 | offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
129 | 170 | ||
130 | if (offchannel_flag || chan != local->hw.conf.channel || | 171 | if (offchannel_flag || chan != local->hw.conf.channel || |
@@ -231,7 +272,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
231 | 272 | ||
232 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 273 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
233 | if (local->quiescing || !ieee80211_sdata_running(sdata) || | 274 | if (local->quiescing || !ieee80211_sdata_running(sdata) || |
234 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { | 275 | test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) { |
235 | sdata->vif.bss_conf.enable_beacon = false; | 276 | sdata->vif.bss_conf.enable_beacon = false; |
236 | } else { | 277 | } else { |
237 | /* | 278 | /* |