diff options
Diffstat (limited to 'net/mac80211/ibss.c')
-rw-r--r-- | net/mac80211/ibss.c | 190 |
1 files changed, 99 insertions, 91 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 5f3620f0bc0a..6b7644e818d8 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include "rate.h" | 26 | #include "rate.h" |
27 | 27 | ||
28 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) | 28 | #define IEEE80211_SCAN_INTERVAL (2 * HZ) |
29 | #define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) | ||
30 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) | 29 | #define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) |
31 | 30 | ||
32 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) | 31 | #define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) |
@@ -39,7 +38,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
39 | const u8 *bssid, const int beacon_int, | 38 | const u8 *bssid, const int beacon_int, |
40 | struct ieee80211_channel *chan, | 39 | struct ieee80211_channel *chan, |
41 | const u32 basic_rates, | 40 | const u32 basic_rates, |
42 | const u16 capability, u64 tsf) | 41 | const u16 capability, u64 tsf, |
42 | bool creator) | ||
43 | { | 43 | { |
44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 44 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
45 | struct ieee80211_local *local = sdata->local; | 45 | struct ieee80211_local *local = sdata->local; |
@@ -51,7 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
51 | struct cfg80211_bss *bss; | 51 | struct cfg80211_bss *bss; |
52 | u32 bss_change; | 52 | u32 bss_change; |
53 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 53 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
54 | enum nl80211_channel_type channel_type; | 54 | struct cfg80211_chan_def chandef; |
55 | 55 | ||
56 | lockdep_assert_held(&ifibss->mtx); | 56 | lockdep_assert_held(&ifibss->mtx); |
57 | 57 | ||
@@ -72,25 +72,29 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
72 | /* if merging, indicate to driver that we leave the old IBSS */ | 72 | /* if merging, indicate to driver that we leave the old IBSS */ |
73 | if (sdata->vif.bss_conf.ibss_joined) { | 73 | if (sdata->vif.bss_conf.ibss_joined) { |
74 | sdata->vif.bss_conf.ibss_joined = false; | 74 | sdata->vif.bss_conf.ibss_joined = false; |
75 | sdata->vif.bss_conf.ibss_creator = false; | ||
75 | netif_carrier_off(sdata->dev); | 76 | netif_carrier_off(sdata->dev); |
76 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); | 77 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IBSS); |
77 | } | 78 | } |
78 | 79 | ||
79 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
80 | |||
81 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 80 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
82 | 81 | ||
83 | local->oper_channel = chan; | 82 | cfg80211_chandef_create(&chandef, chan, ifibss->channel_type); |
84 | channel_type = ifibss->channel_type; | 83 | if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) { |
85 | if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) | 84 | chandef.width = NL80211_CHAN_WIDTH_20; |
86 | channel_type = NL80211_CHAN_HT20; | 85 | chandef.center_freq1 = chan->center_freq; |
87 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 86 | } |
88 | /* can only fail due to HT40+/- mismatch */ | 87 | |
89 | channel_type = NL80211_CHAN_HT20; | 88 | ieee80211_vif_release_channel(sdata); |
90 | WARN_ON(!ieee80211_set_channel_type(local, sdata, | 89 | if (ieee80211_vif_use_channel(sdata, &chandef, |
91 | NL80211_CHAN_HT20)); | 90 | ifibss->fixed_channel ? |
91 | IEEE80211_CHANCTX_SHARED : | ||
92 | IEEE80211_CHANCTX_EXCLUSIVE)) { | ||
93 | sdata_info(sdata, "Failed to join IBSS, no channel context\n"); | ||
94 | return; | ||
92 | } | 95 | } |
93 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 96 | |
97 | memcpy(ifibss->bssid, bssid, ETH_ALEN); | ||
94 | 98 | ||
95 | sband = local->hw.wiphy->bands[chan->band]; | 99 | sband = local->hw.wiphy->bands[chan->band]; |
96 | 100 | ||
@@ -156,7 +160,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
156 | ifibss->ie, ifibss->ie_len); | 160 | ifibss->ie, ifibss->ie_len); |
157 | 161 | ||
158 | /* add HT capability and information IEs */ | 162 | /* add HT capability and information IEs */ |
159 | if (channel_type && sband->ht_cap.ht_supported) { | 163 | if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
164 | sband->ht_cap.ht_supported) { | ||
160 | pos = skb_put(skb, 4 + | 165 | pos = skb_put(skb, 4 + |
161 | sizeof(struct ieee80211_ht_cap) + | 166 | sizeof(struct ieee80211_ht_cap) + |
162 | sizeof(struct ieee80211_ht_operation)); | 167 | sizeof(struct ieee80211_ht_operation)); |
@@ -168,7 +173,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
168 | * keep them at 0 | 173 | * keep them at 0 |
169 | */ | 174 | */ |
170 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, | 175 | pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap, |
171 | chan, channel_type, 0); | 176 | &chandef, 0); |
172 | } | 177 | } |
173 | 178 | ||
174 | if (local->hw.queues >= IEEE80211_NUM_ACS) { | 179 | if (local->hw.queues >= IEEE80211_NUM_ACS) { |
@@ -196,7 +201,22 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
196 | bss_change |= BSS_CHANGED_BASIC_RATES; | 201 | bss_change |= BSS_CHANGED_BASIC_RATES; |
197 | bss_change |= BSS_CHANGED_HT; | 202 | bss_change |= BSS_CHANGED_HT; |
198 | bss_change |= BSS_CHANGED_IBSS; | 203 | bss_change |= BSS_CHANGED_IBSS; |
204 | |||
205 | /* | ||
206 | * In 5 GHz/802.11a, we can always use short slot time. | ||
207 | * (IEEE 802.11-2012 18.3.8.7) | ||
208 | * | ||
209 | * In 2.4GHz, we must always use long slots in IBSS for compatibility | ||
210 | * reasons. | ||
211 | * (IEEE 802.11-2012 19.4.5) | ||
212 | * | ||
213 | * HT follows these specifications (IEEE 802.11-2012 20.3.18) | ||
214 | */ | ||
215 | sdata->vif.bss_conf.use_short_slot = chan->band == IEEE80211_BAND_5GHZ; | ||
216 | bss_change |= BSS_CHANGED_ERP_SLOT; | ||
217 | |||
199 | sdata->vif.bss_conf.ibss_joined = true; | 218 | sdata->vif.bss_conf.ibss_joined = true; |
219 | sdata->vif.bss_conf.ibss_creator = creator; | ||
200 | ieee80211_bss_info_change_notify(sdata, bss_change); | 220 | ieee80211_bss_info_change_notify(sdata, bss_change); |
201 | 221 | ||
202 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); | 222 | ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates); |
@@ -249,7 +269,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
249 | cbss->channel, | 269 | cbss->channel, |
250 | basic_rates, | 270 | basic_rates, |
251 | cbss->capability, | 271 | cbss->capability, |
252 | cbss->tsf); | 272 | cbss->tsf, |
273 | false); | ||
253 | } | 274 | } |
254 | 275 | ||
255 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | 276 | static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, |
@@ -279,7 +300,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
279 | ibss_dbg(sdata, | 300 | ibss_dbg(sdata, |
280 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", | 301 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", |
281 | sdata->vif.addr, addr, sdata->u.ibss.bssid); | 302 | sdata->vif.addr, addr, sdata->u.ibss.bssid); |
282 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 303 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, |
283 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 304 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
284 | } | 305 | } |
285 | return sta; | 306 | return sta; |
@@ -294,7 +315,8 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
294 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 315 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
295 | struct ieee80211_local *local = sdata->local; | 316 | struct ieee80211_local *local = sdata->local; |
296 | struct sta_info *sta; | 317 | struct sta_info *sta; |
297 | int band = local->oper_channel->band; | 318 | struct ieee80211_chanctx_conf *chanctx_conf; |
319 | int band; | ||
298 | 320 | ||
299 | /* | 321 | /* |
300 | * XXX: Consider removing the least recently used entry and | 322 | * XXX: Consider removing the least recently used entry and |
@@ -317,6 +339,13 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
317 | return NULL; | 339 | return NULL; |
318 | } | 340 | } |
319 | 341 | ||
342 | rcu_read_lock(); | ||
343 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
344 | if (WARN_ON_ONCE(!chanctx_conf)) | ||
345 | return NULL; | ||
346 | band = chanctx_conf->def.chan->band; | ||
347 | rcu_read_unlock(); | ||
348 | |||
320 | sta = sta_info_alloc(sdata, addr, GFP_KERNEL); | 349 | sta = sta_info_alloc(sdata, addr, GFP_KERNEL); |
321 | if (!sta) { | 350 | if (!sta) { |
322 | rcu_read_lock(); | 351 | rcu_read_lock(); |
@@ -362,11 +391,13 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
362 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 391 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
363 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 392 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
364 | 393 | ||
365 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | ||
366 | return; | ||
367 | ibss_dbg(sdata, | 394 | ibss_dbg(sdata, |
368 | "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", | 395 | "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", |
369 | mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); | 396 | mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); |
397 | |||
398 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | ||
399 | return; | ||
400 | |||
370 | sta_info_destroy_addr(sdata, mgmt->sa); | 401 | sta_info_destroy_addr(sdata, mgmt->sa); |
371 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | 402 | sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); |
372 | rcu_read_unlock(); | 403 | rcu_read_unlock(); |
@@ -389,7 +420,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
389 | * However, try to reply to authentication attempts if someone | 420 | * However, try to reply to authentication attempts if someone |
390 | * has actually implemented this. | 421 | * has actually implemented this. |
391 | */ | 422 | */ |
392 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, | 423 | ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, 0, NULL, 0, |
393 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); | 424 | mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); |
394 | } | 425 | } |
395 | 426 | ||
@@ -461,9 +492,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
461 | sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { | 492 | sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) { |
462 | /* we both use HT */ | 493 | /* we both use HT */ |
463 | struct ieee80211_sta_ht_cap sta_ht_cap_new; | 494 | struct ieee80211_sta_ht_cap sta_ht_cap_new; |
464 | enum nl80211_channel_type channel_type = | 495 | struct cfg80211_chan_def chandef; |
465 | ieee80211_ht_oper_to_channel_type( | 496 | |
466 | elems->ht_operation); | 497 | ieee80211_ht_oper_to_chandef(channel, |
498 | elems->ht_operation, | ||
499 | &chandef); | ||
467 | 500 | ||
468 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, | 501 | ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, |
469 | elems->ht_cap_elem, | 502 | elems->ht_cap_elem, |
@@ -473,9 +506,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
473 | * fall back to HT20 if we don't use or use | 506 | * fall back to HT20 if we don't use or use |
474 | * the other extension channel | 507 | * the other extension channel |
475 | */ | 508 | */ |
476 | if (!(channel_type == NL80211_CHAN_HT40MINUS || | 509 | if (chandef.width != NL80211_CHAN_WIDTH_40 || |
477 | channel_type == NL80211_CHAN_HT40PLUS) || | 510 | cfg80211_get_chandef_type(&chandef) != |
478 | channel_type != sdata->u.ibss.channel_type) | 511 | sdata->u.ibss.channel_type) |
479 | sta_ht_cap_new.cap &= | 512 | sta_ht_cap_new.cap &= |
480 | ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 513 | ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
481 | 514 | ||
@@ -517,7 +550,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
517 | goto put_bss; | 550 | goto put_bss; |
518 | 551 | ||
519 | /* different channel */ | 552 | /* different channel */ |
520 | if (cbss->channel != local->oper_channel) | 553 | if (sdata->u.ibss.fixed_channel && |
554 | sdata->u.ibss.channel != cbss->channel) | ||
521 | goto put_bss; | 555 | goto put_bss; |
522 | 556 | ||
523 | /* different SSID */ | 557 | /* different SSID */ |
@@ -530,30 +564,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
530 | if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) | 564 | if (ether_addr_equal(cbss->bssid, sdata->u.ibss.bssid)) |
531 | goto put_bss; | 565 | goto put_bss; |
532 | 566 | ||
533 | if (rx_status->flag & RX_FLAG_MACTIME_MPDU) { | 567 | if (ieee80211_have_rx_timestamp(rx_status)) { |
534 | /* | 568 | /* time when timestamp field was received */ |
535 | * For correct IBSS merging we need mactime; since mactime is | 569 | rx_timestamp = |
536 | * defined as the time the first data symbol of the frame hits | 570 | ieee80211_calculate_rx_timestamp(local, rx_status, |
537 | * the PHY, and the timestamp of the beacon is defined as "the | 571 | len + FCS_LEN, 24); |
538 | * time that the data symbol containing the first bit of the | ||
539 | * timestamp is transmitted to the PHY plus the transmitting | ||
540 | * STA's delays through its local PHY from the MAC-PHY | ||
541 | * interface to its interface with the WM" (802.11 11.1.2) | ||
542 | * - equals the time this bit arrives at the receiver - we have | ||
543 | * to take into account the offset between the two. | ||
544 | * | ||
545 | * E.g. at 1 MBit that means mactime is 192 usec earlier | ||
546 | * (=24 bytes * 8 usecs/byte) than the beacon timestamp. | ||
547 | */ | ||
548 | int rate; | ||
549 | |||
550 | if (rx_status->flag & RX_FLAG_HT) | ||
551 | rate = 65; /* TODO: HT rates */ | ||
552 | else | ||
553 | rate = local->hw.wiphy->bands[band]-> | ||
554 | bitrates[rx_status->rate_idx].bitrate; | ||
555 | |||
556 | rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); | ||
557 | } else { | 572 | } else { |
558 | /* | 573 | /* |
559 | * second best option: get current TSF | 574 | * second best option: get current TSF |
@@ -592,7 +607,8 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
592 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 607 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
593 | struct ieee80211_local *local = sdata->local; | 608 | struct ieee80211_local *local = sdata->local; |
594 | struct sta_info *sta; | 609 | struct sta_info *sta; |
595 | int band = local->oper_channel->band; | 610 | struct ieee80211_chanctx_conf *chanctx_conf; |
611 | int band; | ||
596 | 612 | ||
597 | /* | 613 | /* |
598 | * XXX: Consider removing the least recently used entry and | 614 | * XXX: Consider removing the least recently used entry and |
@@ -610,6 +626,15 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
610 | if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) | 626 | if (!ether_addr_equal(bssid, sdata->u.ibss.bssid)) |
611 | return; | 627 | return; |
612 | 628 | ||
629 | rcu_read_lock(); | ||
630 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | ||
631 | if (WARN_ON_ONCE(!chanctx_conf)) { | ||
632 | rcu_read_unlock(); | ||
633 | return; | ||
634 | } | ||
635 | band = chanctx_conf->def.chan->band; | ||
636 | rcu_read_unlock(); | ||
637 | |||
613 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 638 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
614 | if (!sta) | 639 | if (!sta) |
615 | return; | 640 | return; |
@@ -678,8 +703,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
678 | sdata_info(sdata, | 703 | sdata_info(sdata, |
679 | "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); | 704 | "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); |
680 | 705 | ||
681 | ieee80211_request_internal_scan(sdata, | 706 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, ifibss->ssid_len, |
682 | ifibss->ssid, ifibss->ssid_len, NULL); | 707 | NULL); |
683 | } | 708 | } |
684 | 709 | ||
685 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | 710 | static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) |
@@ -715,7 +740,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
715 | 740 | ||
716 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, | 741 | __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int, |
717 | ifibss->channel, ifibss->basic_rates, | 742 | ifibss->channel, ifibss->basic_rates, |
718 | capability, 0); | 743 | capability, 0, true); |
719 | } | 744 | } |
720 | 745 | ||
721 | /* | 746 | /* |
@@ -777,25 +802,14 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
777 | IEEE80211_SCAN_INTERVAL)) { | 802 | IEEE80211_SCAN_INTERVAL)) { |
778 | sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); | 803 | sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); |
779 | 804 | ||
780 | ieee80211_request_internal_scan(sdata, | 805 | ieee80211_request_ibss_scan(sdata, ifibss->ssid, |
781 | ifibss->ssid, ifibss->ssid_len, | 806 | ifibss->ssid_len, chan); |
782 | ifibss->fixed_channel ? ifibss->channel : NULL); | ||
783 | } else { | 807 | } else { |
784 | int interval = IEEE80211_SCAN_INTERVAL; | 808 | int interval = IEEE80211_SCAN_INTERVAL; |
785 | 809 | ||
786 | if (time_after(jiffies, ifibss->ibss_join_req + | 810 | if (time_after(jiffies, ifibss->ibss_join_req + |
787 | IEEE80211_IBSS_JOIN_TIMEOUT)) { | 811 | IEEE80211_IBSS_JOIN_TIMEOUT)) |
788 | if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) { | 812 | ieee80211_sta_create_ibss(sdata); |
789 | ieee80211_sta_create_ibss(sdata); | ||
790 | return; | ||
791 | } | ||
792 | sdata_info(sdata, "IBSS not allowed on %d MHz\n", | ||
793 | local->oper_channel->center_freq); | ||
794 | |||
795 | /* No IBSS found - decrease scan interval and continue | ||
796 | * scanning. */ | ||
797 | interval = IEEE80211_SCAN_INTERVAL_SLOW; | ||
798 | } | ||
799 | 813 | ||
800 | mod_timer(&ifibss->timer, | 814 | mod_timer(&ifibss->timer, |
801 | round_jiffies(jiffies + interval)); | 815 | round_jiffies(jiffies + interval)); |
@@ -1082,21 +1096,11 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1082 | 1096 | ||
1083 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; | 1097 | sdata->vif.bss_conf.beacon_int = params->beacon_interval; |
1084 | 1098 | ||
1085 | sdata->u.ibss.channel = params->channel; | 1099 | sdata->u.ibss.channel = params->chandef.chan; |
1086 | sdata->u.ibss.channel_type = params->channel_type; | 1100 | sdata->u.ibss.channel_type = |
1101 | cfg80211_get_chandef_type(¶ms->chandef); | ||
1087 | sdata->u.ibss.fixed_channel = params->channel_fixed; | 1102 | sdata->u.ibss.fixed_channel = params->channel_fixed; |
1088 | 1103 | ||
1089 | /* fix ourselves to that channel now already */ | ||
1090 | if (params->channel_fixed) { | ||
1091 | sdata->local->oper_channel = params->channel; | ||
1092 | if (!ieee80211_set_channel_type(sdata->local, sdata, | ||
1093 | params->channel_type)) { | ||
1094 | mutex_unlock(&sdata->u.ibss.mtx); | ||
1095 | kfree_skb(skb); | ||
1096 | return -EINVAL; | ||
1097 | } | ||
1098 | } | ||
1099 | |||
1100 | if (params->ie) { | 1104 | if (params->ie) { |
1101 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, | 1105 | sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len, |
1102 | GFP_KERNEL); | 1106 | GFP_KERNEL); |
@@ -1108,7 +1112,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1108 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | 1112 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; |
1109 | sdata->u.ibss.ibss_join_req = jiffies; | 1113 | sdata->u.ibss.ibss_join_req = jiffies; |
1110 | 1114 | ||
1111 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); | 1115 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); |
1112 | sdata->u.ibss.ssid_len = params->ssid_len; | 1116 | sdata->u.ibss.ssid_len = params->ssid_len; |
1113 | 1117 | ||
1114 | mutex_unlock(&sdata->u.ibss.mtx); | 1118 | mutex_unlock(&sdata->u.ibss.mtx); |
@@ -1134,6 +1138,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1134 | changed |= BSS_CHANGED_HT; | 1138 | changed |= BSS_CHANGED_HT; |
1135 | ieee80211_bss_info_change_notify(sdata, changed); | 1139 | ieee80211_bss_info_change_notify(sdata, changed); |
1136 | 1140 | ||
1141 | sdata->smps_mode = IEEE80211_SMPS_OFF; | ||
1142 | sdata->needed_rx_chains = sdata->local->rx_chains; | ||
1143 | |||
1137 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); | 1144 | ieee80211_queue_work(&sdata->local->hw, &sdata->work); |
1138 | 1145 | ||
1139 | return 0; | 1146 | return 0; |
@@ -1151,10 +1158,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1151 | 1158 | ||
1152 | mutex_lock(&sdata->u.ibss.mtx); | 1159 | mutex_lock(&sdata->u.ibss.mtx); |
1153 | 1160 | ||
1154 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | ||
1155 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | ||
1156 | sdata->u.ibss.ssid_len = 0; | ||
1157 | |||
1158 | active_ibss = ieee80211_sta_active_ibss(sdata); | 1161 | active_ibss = ieee80211_sta_active_ibss(sdata); |
1159 | 1162 | ||
1160 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { | 1163 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { |
@@ -1175,6 +1178,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1175 | } | 1178 | } |
1176 | } | 1179 | } |
1177 | 1180 | ||
1181 | ifibss->state = IEEE80211_IBSS_MLME_SEARCH; | ||
1182 | memset(ifibss->bssid, 0, ETH_ALEN); | ||
1183 | ifibss->ssid_len = 0; | ||
1184 | |||
1178 | sta_info_flush(sdata->local, sdata); | 1185 | sta_info_flush(sdata->local, sdata); |
1179 | 1186 | ||
1180 | spin_lock_bh(&ifibss->incomplete_lock); | 1187 | spin_lock_bh(&ifibss->incomplete_lock); |
@@ -1197,6 +1204,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1197 | lockdep_is_held(&sdata->u.ibss.mtx)); | 1204 | lockdep_is_held(&sdata->u.ibss.mtx)); |
1198 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); | 1205 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); |
1199 | sdata->vif.bss_conf.ibss_joined = false; | 1206 | sdata->vif.bss_conf.ibss_joined = false; |
1207 | sdata->vif.bss_conf.ibss_creator = false; | ||
1200 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | | 1208 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED | |
1201 | BSS_CHANGED_IBSS); | 1209 | BSS_CHANGED_IBSS); |
1202 | synchronize_rcu(); | 1210 | synchronize_rcu(); |