aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wunderlich <simon.wunderlich@s2003.tu-chemnitz.de>2013-08-21 09:30:25 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-08-21 09:33:08 -0400
commit75a423f493ffdf741acae27bf179cd560f7813d7 (patch)
tree4981644ea18a1f4029e2626246b4bd81e8ca966f
parent2dfca312a91631311c1cf7c090246cc8103de038 (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.c33
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
37static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 37static 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