aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ibss.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r--net/mac80211/ibss.c184
1 files changed, 153 insertions, 31 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index ea7b9c2c7e66..e08387cdc8fd 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -30,6 +30,7 @@
30 30
31#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) 31#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
32#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) 32#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
33#define IEEE80211_IBSS_RSN_INACTIVITY_LIMIT (10 * HZ)
33 34
34#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 35#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
35 36
@@ -43,16 +44,18 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
43{ 44{
44 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 45 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
45 struct ieee80211_local *local = sdata->local; 46 struct ieee80211_local *local = sdata->local;
46 int rates, i; 47 int rates_n = 0, i, ri;
47 struct ieee80211_mgmt *mgmt; 48 struct ieee80211_mgmt *mgmt;
48 u8 *pos; 49 u8 *pos;
49 struct ieee80211_supported_band *sband; 50 struct ieee80211_supported_band *sband;
50 struct cfg80211_bss *bss; 51 struct cfg80211_bss *bss;
51 u32 bss_change; 52 u32 bss_change, rate_flags, rates = 0, rates_added = 0;
52 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
53 struct cfg80211_chan_def chandef; 53 struct cfg80211_chan_def chandef;
54 enum nl80211_bss_scan_width scan_width;
55 bool have_higher_than_11mbit = false;
54 struct beacon_data *presp; 56 struct beacon_data *presp;
55 int frame_len; 57 int frame_len;
58 int shift;
56 59
57 sdata_assert_lock(sdata); 60 sdata_assert_lock(sdata);
58 61
@@ -83,6 +86,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
83 86
84 chandef = ifibss->chandef; 87 chandef = ifibss->chandef;
85 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { 88 if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
89 if (chandef.width == NL80211_CHAN_WIDTH_5 ||
90 chandef.width == NL80211_CHAN_WIDTH_10 ||
91 chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
92 chandef.width == NL80211_CHAN_WIDTH_20) {
93 sdata_info(sdata,
94 "Failed to join IBSS, beacons forbidden\n");
95 return;
96 }
86 chandef.width = NL80211_CHAN_WIDTH_20; 97 chandef.width = NL80211_CHAN_WIDTH_20;
87 chandef.center_freq1 = chan->center_freq; 98 chandef.center_freq1 = chan->center_freq;
88 } 99 }
@@ -99,6 +110,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 110 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 111
101 sband = local->hw.wiphy->bands[chan->band]; 112 sband = local->hw.wiphy->bands[chan->band];
113 shift = ieee80211_vif_get_shift(&sdata->vif);
102 114
103 /* Build IBSS probe response */ 115 /* Build IBSS probe response */
104 frame_len = sizeof(struct ieee80211_hdr_3addr) + 116 frame_len = sizeof(struct ieee80211_hdr_3addr) +
@@ -134,15 +146,33 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
134 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 146 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
135 pos += ifibss->ssid_len; 147 pos += ifibss->ssid_len;
136 148
137 rates = min_t(int, 8, sband->n_bitrates); 149 rate_flags = ieee80211_chandef_rate_flags(&chandef);
150 for (i = 0; i < sband->n_bitrates; i++) {
151 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
152 continue;
153 if (sband->bitrates[i].bitrate > 110)
154 have_higher_than_11mbit = true;
155
156 rates |= BIT(i);
157 rates_n++;
158 }
159
138 *pos++ = WLAN_EID_SUPP_RATES; 160 *pos++ = WLAN_EID_SUPP_RATES;
139 *pos++ = rates; 161 *pos++ = min_t(int, 8, rates_n);
140 for (i = 0; i < rates; i++) { 162 for (ri = 0; ri < sband->n_bitrates; ri++) {
141 int rate = sband->bitrates[i].bitrate; 163 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
164 5 * (1 << shift));
142 u8 basic = 0; 165 u8 basic = 0;
143 if (basic_rates & BIT(i)) 166 if (!(rates & BIT(ri)))
167 continue;
168
169 if (basic_rates & BIT(ri))
144 basic = 0x80; 170 basic = 0x80;
145 *pos++ = basic | (u8) (rate / 5); 171 *pos++ = basic | (u8) rate;
172 if (++rates_added == 8) {
173 ri++; /* continue at next rate for EXT_SUPP_RATES */
174 break;
175 }
146 } 176 }
147 177
148 if (sband->band == IEEE80211_BAND_2GHZ) { 178 if (sband->band == IEEE80211_BAND_2GHZ) {
@@ -157,15 +187,20 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
157 *pos++ = 0; 187 *pos++ = 0;
158 *pos++ = 0; 188 *pos++ = 0;
159 189
160 if (sband->n_bitrates > 8) { 190 /* put the remaining rates in WLAN_EID_EXT_SUPP_RATES */
191 if (rates_n > 8) {
161 *pos++ = WLAN_EID_EXT_SUPP_RATES; 192 *pos++ = WLAN_EID_EXT_SUPP_RATES;
162 *pos++ = sband->n_bitrates - 8; 193 *pos++ = rates_n - 8;
163 for (i = 8; i < sband->n_bitrates; i++) { 194 for (; ri < sband->n_bitrates; ri++) {
164 int rate = sband->bitrates[i].bitrate; 195 int rate = DIV_ROUND_UP(sband->bitrates[ri].bitrate,
196 5 * (1 << shift));
165 u8 basic = 0; 197 u8 basic = 0;
166 if (basic_rates & BIT(i)) 198 if (!(rates & BIT(ri)))
199 continue;
200
201 if (basic_rates & BIT(ri))
167 basic = 0x80; 202 basic = 0x80;
168 *pos++ = basic | (u8) (rate / 5); 203 *pos++ = basic | (u8) rate;
169 } 204 }
170 } 205 }
171 206
@@ -179,8 +214,12 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
179 chandef.width != NL80211_CHAN_WIDTH_5 && 214 chandef.width != NL80211_CHAN_WIDTH_5 &&
180 chandef.width != NL80211_CHAN_WIDTH_10 && 215 chandef.width != NL80211_CHAN_WIDTH_10 &&
181 sband->ht_cap.ht_supported) { 216 sband->ht_cap.ht_supported) {
182 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 217 struct ieee80211_sta_ht_cap ht_cap;
183 sband->ht_cap.cap); 218
219 memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
220 ieee80211_apply_htcap_overrides(sdata, &ht_cap);
221
222 pos = ieee80211_ie_build_ht_cap(pos, &ht_cap, ht_cap.cap);
184 /* 223 /*
185 * Note: According to 802.11n-2009 9.13.3.1, HT Protection 224 * Note: According to 802.11n-2009 9.13.3.1, HT Protection
186 * field and RIFS Mode are reserved in IBSS mode, therefore 225 * field and RIFS Mode are reserved in IBSS mode, therefore
@@ -236,18 +275,26 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
236 sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ; 275 sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ;
237 bss_change |= BSS_CHANGED_ERP_SLOT; 276 bss_change |= BSS_CHANGED_ERP_SLOT;
238 277
278 /* cf. IEEE 802.11 9.2.12 */
279 if (chan->band == IEEE80211_BAND_2GHZ && have_higher_than_11mbit)
280 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
281 else
282 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
283
239 sdata->vif.bss_conf.ibss_joined = true; 284 sdata->vif.bss_conf.ibss_joined = true;
240 sdata->vif.bss_conf.ibss_creator = creator; 285 sdata->vif.bss_conf.ibss_creator = creator;
241 ieee80211_bss_info_change_notify(sdata, bss_change); 286 ieee80211_bss_info_change_notify(sdata, bss_change);
242 287
243 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); 288 ieee80211_set_wmm_default(sdata, true);
244 289
245 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 290 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
246 mod_timer(&ifibss->timer, 291 mod_timer(&ifibss->timer,
247 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 292 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
248 293
249 bss = cfg80211_inform_bss_frame(local->hw.wiphy, chan, 294 scan_width = cfg80211_chandef_to_scan_width(&chandef);
250 mgmt, presp->head_len, 0, GFP_KERNEL); 295 bss = cfg80211_inform_bss_width_frame(local->hw.wiphy, chan,
296 scan_width, mgmt,
297 presp->head_len, 0, GFP_KERNEL);
251 cfg80211_put_bss(local->hw.wiphy, bss); 298 cfg80211_put_bss(local->hw.wiphy, bss);
252 netif_carrier_on(sdata->dev); 299 netif_carrier_on(sdata->dev);
253 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL); 300 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
@@ -264,6 +311,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
264 u16 beacon_int = cbss->beacon_interval; 311 u16 beacon_int = cbss->beacon_interval;
265 const struct cfg80211_bss_ies *ies; 312 const struct cfg80211_bss_ies *ies;
266 u64 tsf; 313 u64 tsf;
314 u32 rate_flags;
315 int shift;
267 316
268 sdata_assert_lock(sdata); 317 sdata_assert_lock(sdata);
269 318
@@ -271,15 +320,24 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
271 beacon_int = 10; 320 beacon_int = 10;
272 321
273 sband = sdata->local->hw.wiphy->bands[cbss->channel->band]; 322 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
323 rate_flags = ieee80211_chandef_rate_flags(&sdata->u.ibss.chandef);
324 shift = ieee80211_vif_get_shift(&sdata->vif);
274 325
275 basic_rates = 0; 326 basic_rates = 0;
276 327
277 for (i = 0; i < bss->supp_rates_len; i++) { 328 for (i = 0; i < bss->supp_rates_len; i++) {
278 int rate = (bss->supp_rates[i] & 0x7f) * 5; 329 int rate = bss->supp_rates[i] & 0x7f;
279 bool is_basic = !!(bss->supp_rates[i] & 0x80); 330 bool is_basic = !!(bss->supp_rates[i] & 0x80);
280 331
281 for (j = 0; j < sband->n_bitrates; j++) { 332 for (j = 0; j < sband->n_bitrates; j++) {
282 if (sband->bitrates[j].bitrate == rate) { 333 int brate;
334 if ((rate_flags & sband->bitrates[j].flags)
335 != rate_flags)
336 continue;
337
338 brate = DIV_ROUND_UP(sband->bitrates[j].bitrate,
339 5 * (1 << shift));
340 if (brate == rate) {
283 if (is_basic) 341 if (is_basic)
284 basic_rates |= BIT(j); 342 basic_rates |= BIT(j);
285 break; 343 break;
@@ -335,6 +393,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
335 struct sta_info *sta; 393 struct sta_info *sta;
336 struct ieee80211_chanctx_conf *chanctx_conf; 394 struct ieee80211_chanctx_conf *chanctx_conf;
337 struct ieee80211_supported_band *sband; 395 struct ieee80211_supported_band *sband;
396 enum nl80211_bss_scan_width scan_width;
338 int band; 397 int band;
339 398
340 /* 399 /*
@@ -363,6 +422,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
363 if (WARN_ON_ONCE(!chanctx_conf)) 422 if (WARN_ON_ONCE(!chanctx_conf))
364 return NULL; 423 return NULL;
365 band = chanctx_conf->def.chan->band; 424 band = chanctx_conf->def.chan->band;
425 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
366 rcu_read_unlock(); 426 rcu_read_unlock();
367 427
368 sta = sta_info_alloc(sdata, addr, GFP_KERNEL); 428 sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -376,7 +436,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
376 /* make sure mandatory rates are always added */ 436 /* make sure mandatory rates are always added */
377 sband = local->hw.wiphy->bands[band]; 437 sband = local->hw.wiphy->bands[band];
378 sta->sta.supp_rates[band] = supp_rates | 438 sta->sta.supp_rates[band] = supp_rates |
379 ieee80211_mandatory_rates(sband); 439 ieee80211_mandatory_rates(sband, scan_width);
380 440
381 return ieee80211_ibss_finish_sta(sta); 441 return ieee80211_ibss_finish_sta(sta);
382} 442}
@@ -440,6 +500,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
440 u64 beacon_timestamp, rx_timestamp; 500 u64 beacon_timestamp, rx_timestamp;
441 u32 supp_rates = 0; 501 u32 supp_rates = 0;
442 enum ieee80211_band band = rx_status->band; 502 enum ieee80211_band band = rx_status->band;
503 enum nl80211_bss_scan_width scan_width;
443 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band]; 504 struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
444 bool rates_updated = false; 505 bool rates_updated = false;
445 506
@@ -461,16 +522,22 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
461 sta = sta_info_get(sdata, mgmt->sa); 522 sta = sta_info_get(sdata, mgmt->sa);
462 523
463 if (elems->supp_rates) { 524 if (elems->supp_rates) {
464 supp_rates = ieee80211_sta_get_rates(local, elems, 525 supp_rates = ieee80211_sta_get_rates(sdata, elems,
465 band, NULL); 526 band, NULL);
466 if (sta) { 527 if (sta) {
467 u32 prev_rates; 528 u32 prev_rates;
468 529
469 prev_rates = sta->sta.supp_rates[band]; 530 prev_rates = sta->sta.supp_rates[band];
470 /* make sure mandatory rates are always added */ 531 /* make sure mandatory rates are always added */
471 sta->sta.supp_rates[band] = supp_rates | 532 scan_width = NL80211_BSS_CHAN_WIDTH_20;
472 ieee80211_mandatory_rates(sband); 533 if (rx_status->flag & RX_FLAG_5MHZ)
534 scan_width = NL80211_BSS_CHAN_WIDTH_5;
535 if (rx_status->flag & RX_FLAG_10MHZ)
536 scan_width = NL80211_BSS_CHAN_WIDTH_10;
473 537
538 sta->sta.supp_rates[band] = supp_rates |
539 ieee80211_mandatory_rates(sband,
540 scan_width);
474 if (sta->sta.supp_rates[band] != prev_rates) { 541 if (sta->sta.supp_rates[band] != prev_rates) {
475 ibss_dbg(sdata, 542 ibss_dbg(sdata,
476 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", 543 "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n",
@@ -585,7 +652,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
585 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", 652 "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n",
586 mgmt->bssid); 653 mgmt->bssid);
587 ieee80211_sta_join_ibss(sdata, bss); 654 ieee80211_sta_join_ibss(sdata, bss);
588 supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); 655 supp_rates = ieee80211_sta_get_rates(sdata, elems, band, NULL);
589 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 656 ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
590 supp_rates); 657 supp_rates);
591 rcu_read_unlock(); 658 rcu_read_unlock();
@@ -604,6 +671,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
604 struct sta_info *sta; 671 struct sta_info *sta;
605 struct ieee80211_chanctx_conf *chanctx_conf; 672 struct ieee80211_chanctx_conf *chanctx_conf;
606 struct ieee80211_supported_band *sband; 673 struct ieee80211_supported_band *sband;
674 enum nl80211_bss_scan_width scan_width;
607 int band; 675 int band;
608 676
609 /* 677 /*
@@ -629,6 +697,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
629 return; 697 return;
630 } 698 }
631 band = chanctx_conf->def.chan->band; 699 band = chanctx_conf->def.chan->band;
700 scan_width = cfg80211_chandef_to_scan_width(&chanctx_conf->def);
632 rcu_read_unlock(); 701 rcu_read_unlock();
633 702
634 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); 703 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -640,7 +709,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
640 /* make sure mandatory rates are always added */ 709 /* make sure mandatory rates are always added */
641 sband = local->hw.wiphy->bands[band]; 710 sband = local->hw.wiphy->bands[band];
642 sta->sta.supp_rates[band] = supp_rates | 711 sta->sta.supp_rates[band] = supp_rates |
643 ieee80211_mandatory_rates(sband); 712 ieee80211_mandatory_rates(sband, scan_width);
644 713
645 spin_lock(&ifibss->incomplete_lock); 714 spin_lock(&ifibss->incomplete_lock);
646 list_add(&sta->list, &ifibss->incomplete_stations); 715 list_add(&sta->list, &ifibss->incomplete_stations);
@@ -672,6 +741,33 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
672 return active; 741 return active;
673} 742}
674 743
744static void ieee80211_ibss_sta_expire(struct ieee80211_sub_if_data *sdata)
745{
746 struct ieee80211_local *local = sdata->local;
747 struct sta_info *sta, *tmp;
748 unsigned long exp_time = IEEE80211_IBSS_INACTIVITY_LIMIT;
749 unsigned long exp_rsn_time = IEEE80211_IBSS_RSN_INACTIVITY_LIMIT;
750
751 mutex_lock(&local->sta_mtx);
752
753 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
754 if (sdata != sta->sdata)
755 continue;
756
757 if (time_after(jiffies, sta->last_rx + exp_time) ||
758 (time_after(jiffies, sta->last_rx + exp_rsn_time) &&
759 sta->sta_state != IEEE80211_STA_AUTHORIZED)) {
760 sta_dbg(sta->sdata, "expiring inactive %sSTA %pM\n",
761 sta->sta_state != IEEE80211_STA_AUTHORIZED ?
762 "not authorized " : "", sta->sta.addr);
763
764 WARN_ON(__sta_info_destroy(sta));
765 }
766 }
767
768 mutex_unlock(&local->sta_mtx);
769}
770
675/* 771/*
676 * This function is called with state == IEEE80211_IBSS_MLME_JOINED 772 * This function is called with state == IEEE80211_IBSS_MLME_JOINED
677 */ 773 */
@@ -679,13 +775,14 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
679static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) 775static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
680{ 776{
681 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 777 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
778 enum nl80211_bss_scan_width scan_width;
682 779
683 sdata_assert_lock(sdata); 780 sdata_assert_lock(sdata);
684 781
685 mod_timer(&ifibss->timer, 782 mod_timer(&ifibss->timer,
686 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); 783 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
687 784
688 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); 785 ieee80211_ibss_sta_expire(sdata);
689 786
690 if (time_before(jiffies, ifibss->last_scan_completed + 787 if (time_before(jiffies, ifibss->last_scan_completed +
691 IEEE80211_IBSS_MERGE_INTERVAL)) 788 IEEE80211_IBSS_MERGE_INTERVAL))
@@ -700,8 +797,9 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
700 sdata_info(sdata, 797 sdata_info(sdata,
701 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); 798 "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n");
702 799
800 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
703 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, 801 ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len,
704 NULL); 802 NULL, scan_width);
705} 803}
706 804
707static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 805static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
@@ -751,6 +849,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
751 struct cfg80211_bss *cbss; 849 struct cfg80211_bss *cbss;
752 struct ieee80211_channel *chan = NULL; 850 struct ieee80211_channel *chan = NULL;
753 const u8 *bssid = NULL; 851 const u8 *bssid = NULL;
852 enum nl80211_bss_scan_width scan_width;
754 int active_ibss; 853 int active_ibss;
755 u16 capability; 854 u16 capability;
756 855
@@ -799,8 +898,10 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
799 IEEE80211_SCAN_INTERVAL)) { 898 IEEE80211_SCAN_INTERVAL)) {
800 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); 899 sdata_info(sdata, "Trigger new scan to find an IBSS to join\n");
801 900
901 scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef);
802 ieee80211_request_ibss_scan(sdata, ifibss->ssid, 902 ieee80211_request_ibss_scan(sdata, ifibss->ssid,
803 ifibss->ssid_len, chan); 903 ifibss->ssid_len, chan,
904 scan_width);
804 } else { 905 } else {
805 int interval = IEEE80211_SCAN_INTERVAL; 906 int interval = IEEE80211_SCAN_INTERVAL;
806 907
@@ -1020,6 +1121,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1020 struct cfg80211_ibss_params *params) 1121 struct cfg80211_ibss_params *params)
1021{ 1122{
1022 u32 changed = 0; 1123 u32 changed = 0;
1124 u32 rate_flags;
1125 struct ieee80211_supported_band *sband;
1126 int i;
1023 1127
1024 if (params->bssid) { 1128 if (params->bssid) {
1025 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); 1129 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
@@ -1030,6 +1134,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1030 sdata->u.ibss.privacy = params->privacy; 1134 sdata->u.ibss.privacy = params->privacy;
1031 sdata->u.ibss.control_port = params->control_port; 1135 sdata->u.ibss.control_port = params->control_port;
1032 sdata->u.ibss.basic_rates = params->basic_rates; 1136 sdata->u.ibss.basic_rates = params->basic_rates;
1137
1138 /* fix basic_rates if channel does not support these rates */
1139 rate_flags = ieee80211_chandef_rate_flags(&params->chandef);
1140 sband = sdata->local->hw.wiphy->bands[params->chandef.chan->band];
1141 for (i = 0; i < sband->n_bitrates; i++) {
1142 if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
1143 sdata->u.ibss.basic_rates &= ~BIT(i);
1144 }
1033 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate, 1145 memcpy(sdata->vif.bss_conf.mcast_rate, params->mcast_rate,
1034 sizeof(params->mcast_rate)); 1146 sizeof(params->mcast_rate));
1035 1147
@@ -1051,6 +1163,11 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1051 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); 1163 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
1052 sdata->u.ibss.ssid_len = params->ssid_len; 1164 sdata->u.ibss.ssid_len = params->ssid_len;
1053 1165
1166 memcpy(&sdata->u.ibss.ht_capa, &params->ht_capa,
1167 sizeof(sdata->u.ibss.ht_capa));
1168 memcpy(&sdata->u.ibss.ht_capa_mask, &params->ht_capa_mask,
1169 sizeof(sdata->u.ibss.ht_capa_mask));
1170
1054 /* 1171 /*
1055 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is 1172 * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
1056 * reserved, but an HT STA shall protect HT transmissions as though 1173 * reserved, but an HT STA shall protect HT transmissions as though
@@ -1131,6 +1248,11 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
1131 presp = rcu_dereference_protected(ifibss->presp, 1248 presp = rcu_dereference_protected(ifibss->presp,
1132 lockdep_is_held(&sdata->wdev.mtx)); 1249 lockdep_is_held(&sdata->wdev.mtx));
1133 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); 1250 RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
1251
1252 /* on the next join, re-program HT parameters */
1253 memset(&ifibss->ht_capa, 0, sizeof(ifibss->ht_capa));
1254 memset(&ifibss->ht_capa_mask, 0, sizeof(ifibss->ht_capa_mask));
1255
1134 sdata->vif.bss_conf.ibss_joined = false; 1256 sdata->vif.bss_conf.ibss_joined = false;
1135 sdata->vif.bss_conf.ibss_creator = false; 1257 sdata->vif.bss_conf.ibss_creator = false;
1136 sdata->vif.bss_conf.enable_beacon = false; 1258 sdata->vif.bss_conf.enable_beacon = false;