diff options
author | Simon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de> | 2013-08-21 09:30:25 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-08-21 09:33:08 -0400 |
commit | 75a423f493ffdf741acae27bf179cd560f7813d7 (patch) | |
tree | 4981644ea18a1f4029e2626246b4bd81e8ca966f | |
parent | 2dfca312a91631311c1cf7c090246cc8103de038 (diff) |
mac80211: ibss: fix ignored channel parameter
my earlier patch "mac80211: change IBSS channel state to chandef"
created a regression by ignoring the channel parameter in
__ieee80211_sta_join_ibss, which breaks IBSS channel selection. This
patch fixes this situation by using the right channel and adopting the
selected bandwidth mode.
Cc: stable@vger.kernel.org
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/ibss.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 5e8bb3bee3c2..2d45643c964e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | 37 | static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, |
38 | const u8 *bssid, const int beacon_int, | 38 | const u8 *bssid, const int beacon_int, |
39 | struct ieee80211_channel *chan, | 39 | struct cfg80211_chan_def *req_chandef, |
40 | const u32 basic_rates, | 40 | const u32 basic_rates, |
41 | const u16 capability, u64 tsf, | 41 | const u16 capability, u64 tsf, |
42 | bool creator) | 42 | bool creator) |
@@ -51,6 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
51 | u32 bss_change; | 51 | u32 bss_change; |
52 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 52 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
53 | struct cfg80211_chan_def chandef; | 53 | struct cfg80211_chan_def chandef; |
54 | struct ieee80211_channel *chan; | ||
54 | struct beacon_data *presp; | 55 | struct beacon_data *presp; |
55 | int frame_len; | 56 | int frame_len; |
56 | 57 | ||
@@ -81,7 +82,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
81 | 82 | ||
82 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 83 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
83 | 84 | ||
84 | chandef = ifibss->chandef; | 85 | /* make a copy of the chandef, it could be modified below. */ |
86 | chandef = *req_chandef; | ||
87 | chan = chandef.chan; | ||
85 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { | 88 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { |
86 | chandef.width = NL80211_CHAN_WIDTH_20; | 89 | chandef.width = NL80211_CHAN_WIDTH_20; |
87 | chandef.center_freq1 = chan->center_freq; | 90 | chandef.center_freq1 = chan->center_freq; |
@@ -259,10 +262,12 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
259 | struct cfg80211_bss *cbss = | 262 | struct cfg80211_bss *cbss = |
260 | container_of((void *)bss, struct cfg80211_bss, priv); | 263 | container_of((void *)bss, struct cfg80211_bss, priv); |
261 | struct ieee80211_supported_band *sband; | 264 | struct ieee80211_supported_band *sband; |
265 | struct cfg80211_chan_def chandef; | ||
262 | u32 basic_rates; | 266 | u32 basic_rates; |
263 | int i, j; | 267 | int i, j; |
264 | u16 beacon_int = cbss->beacon_interval; | 268 | u16 beacon_int = cbss->beacon_interval; |
265 | const struct cfg80211_bss_ies *ies; | 269 | const struct cfg80211_bss_ies *ies; |
270 | enum nl80211_channel_type chan_type; | ||
266 | u64 tsf; | 271 | u64 tsf; |
267 | 272 | ||
268 | sdata_assert_lock(sdata); | 273 | sdata_assert_lock(sdata); |
@@ -270,6 +275,26 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
270 | if (beacon_int < 10) | 275 | if (beacon_int < 10) |
271 | beacon_int = 10; | 276 | beacon_int = 10; |
272 | 277 | ||
278 | switch (sdata->u.ibss.chandef.width) { | ||
279 | case NL80211_CHAN_WIDTH_20_NOHT: | ||
280 | case NL80211_CHAN_WIDTH_20: | ||
281 | case NL80211_CHAN_WIDTH_40: | ||
282 | chan_type = cfg80211_get_chandef_type(&sdata->u.ibss.chandef); | ||
283 | cfg80211_chandef_create(&chandef, cbss->channel, chan_type); | ||
284 | break; | ||
285 | case NL80211_CHAN_WIDTH_5: | ||
286 | case NL80211_CHAN_WIDTH_10: | ||
287 | cfg80211_chandef_create(&chandef, cbss->channel, | ||
288 | NL80211_CHAN_WIDTH_20_NOHT); | ||
289 | chandef.width = sdata->u.ibss.chandef.width; | ||
290 | break; | ||
291 | default: | ||
292 | /* fall back to 20 MHz for unsupported modes */ | ||
293 | cfg80211_chandef_create(&chandef, cbss->channel, | ||
294 | NL80211_CHAN_WIDTH_20_NOHT); | ||
295 | break; | ||
296 | } | ||
297 | |||
273 | sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; | 298 | sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; |
274 | 299 | ||
275 | basic_rates = 0; | 300 | basic_rates = 0; |
@@ -294,7 +319,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
294 | 319 | ||
295 | __ieee80211_sta_join_ibss(sdata, cbss->bssid, | 320 | __ieee80211_sta_join_ibss(sdata, cbss->bssid, |
296 | beacon_int, | 321 | beacon_int, |
297 | cbss->channel, | 322 | &chandef, |
298 | basic_rates, | 323 | basic_rates, |
299 | cbss->capability, | 324 | cbss->capability, |
300 | tsf, false); | 325 | tsf, false); |
@@ -736,7 +761,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
736 | sdata->drop_unencrypted = 0; | 761 | sdata->drop_unencrypted = 0; |
737 | 762 | ||
738 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 763 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
739 | ifibss->chandef.chan, ifibss->basic_rates, | 764 | &ifibss->chandef, ifibss->basic_rates, |
740 | capability, 0, true); | 765 | capability, 0, true); |
741 | } | 766 | } |
742 | 767 | ||