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.c501
1 files changed, 270 insertions, 231 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3201e1f96365..0b30277eb366 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -22,6 +22,7 @@
22#include <asm/unaligned.h> 22#include <asm/unaligned.h>
23 23
24#include "ieee80211_i.h" 24#include "ieee80211_i.h"
25#include "driver-ops.h"
25#include "rate.h" 26#include "rate.h"
26 27
27#define IEEE80211_SCAN_INTERVAL (2 * HZ) 28#define IEEE80211_SCAN_INTERVAL (2 * HZ)
@@ -59,74 +60,65 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
59 sdata->u.ibss.bssid, 0); 60 sdata->u.ibss.bssid, 0);
60} 61}
61 62
62static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
63 const u8 *bssid, const int beacon_int, 64 const u8 *bssid, const int beacon_int,
64 const int freq, 65 struct ieee80211_channel *chan,
65 const size_t supp_rates_len, 66 const u32 basic_rates,
66 const u8 *supp_rates, 67 const u16 capability, u64 tsf)
67 const u16 capability, u64 tsf)
68{ 68{
69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 69 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
70 struct ieee80211_local *local = sdata->local; 70 struct ieee80211_local *local = sdata->local;
71 int res = 0, rates, i, j; 71 int rates, i;
72 struct sk_buff *skb; 72 struct sk_buff *skb;
73 struct ieee80211_mgmt *mgmt; 73 struct ieee80211_mgmt *mgmt;
74 u8 *pos; 74 u8 *pos;
75 struct ieee80211_supported_band *sband; 75 struct ieee80211_supported_band *sband;
76 union iwreq_data wrqu; 76 u32 bss_change;
77 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
77 78
78 if (local->ops->reset_tsf) { 79 /* Reset own TSF to allow time synchronization work. */
79 /* Reset own TSF to allow time synchronization work. */ 80 drv_reset_tsf(local);
80 local->ops->reset_tsf(local_to_hw(local));
81 }
82 81
83 if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) && 82 skb = ifibss->skb;
84 memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0) 83 rcu_assign_pointer(ifibss->presp, NULL);
85 return res; 84 synchronize_rcu();
85 skb->data = skb->head;
86 skb->len = 0;
87 skb_reset_tail_pointer(skb);
88 skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
86 89
87 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 90 if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
88 if (!skb) { 91 sta_info_flush(sdata->local, sdata);
89 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
90 "response\n", sdata->dev->name);
91 return -ENOMEM;
92 }
93
94 if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
95 /* Remove possible STA entries from other IBSS networks. */
96 sta_info_flush_delayed(sdata);
97 }
98 92
99 memcpy(ifibss->bssid, bssid, ETH_ALEN); 93 memcpy(ifibss->bssid, bssid, ETH_ALEN);
100 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
101 if (res)
102 return res;
103
104 local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
105 94
106 sdata->drop_unencrypted = capability & 95 sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
107 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
108 96
109 res = ieee80211_set_freq(sdata, freq); 97 local->oper_channel = chan;
98 local->oper_channel_type = NL80211_CHAN_NO_HT;
99 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
110 100
111 if (res) 101 sband = local->hw.wiphy->bands[chan->band];
112 return res;
113 102
114 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 103 /* build supported rates array */
104 pos = supp_rates;
105 for (i = 0; i < sband->n_bitrates; i++) {
106 int rate = sband->bitrates[i].bitrate;
107 u8 basic = 0;
108 if (basic_rates & BIT(i))
109 basic = 0x80;
110 *pos++ = basic | (u8) (rate / 5);
111 }
115 112
116 /* Build IBSS probe response */ 113 /* Build IBSS probe response */
117 114 mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
118 skb_reserve(skb, local->hw.extra_tx_headroom);
119
120 mgmt = (struct ieee80211_mgmt *)
121 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
122 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 115 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
123 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 116 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
124 IEEE80211_STYPE_PROBE_RESP); 117 IEEE80211_STYPE_PROBE_RESP);
125 memset(mgmt->da, 0xff, ETH_ALEN); 118 memset(mgmt->da, 0xff, ETH_ALEN);
126 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 119 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
127 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN); 120 memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
128 mgmt->u.beacon.beacon_int = 121 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
129 cpu_to_le16(local->hw.conf.beacon_int);
130 mgmt->u.beacon.timestamp = cpu_to_le64(tsf); 122 mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
131 mgmt->u.beacon.capab_info = cpu_to_le16(capability); 123 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
132 124
@@ -135,7 +127,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
135 *pos++ = ifibss->ssid_len; 127 *pos++ = ifibss->ssid_len;
136 memcpy(pos, ifibss->ssid, ifibss->ssid_len); 128 memcpy(pos, ifibss->ssid, ifibss->ssid_len);
137 129
138 rates = supp_rates_len; 130 rates = sband->n_bitrates;
139 if (rates > 8) 131 if (rates > 8)
140 rates = 8; 132 rates = 8;
141 pos = skb_put(skb, 2 + rates); 133 pos = skb_put(skb, 2 + rates);
@@ -147,7 +139,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
147 pos = skb_put(skb, 2 + 1); 139 pos = skb_put(skb, 2 + 1);
148 *pos++ = WLAN_EID_DS_PARAMS; 140 *pos++ = WLAN_EID_DS_PARAMS;
149 *pos++ = 1; 141 *pos++ = 1;
150 *pos++ = ieee80211_frequency_to_channel(freq); 142 *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
151 } 143 }
152 144
153 pos = skb_put(skb, 2 + 2); 145 pos = skb_put(skb, 2 + 2);
@@ -157,51 +149,73 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
157 *pos++ = 0; 149 *pos++ = 0;
158 *pos++ = 0; 150 *pos++ = 0;
159 151
160 if (supp_rates_len > 8) { 152 if (sband->n_bitrates > 8) {
161 rates = supp_rates_len - 8; 153 rates = sband->n_bitrates - 8;
162 pos = skb_put(skb, 2 + rates); 154 pos = skb_put(skb, 2 + rates);
163 *pos++ = WLAN_EID_EXT_SUPP_RATES; 155 *pos++ = WLAN_EID_EXT_SUPP_RATES;
164 *pos++ = rates; 156 *pos++ = rates;
165 memcpy(pos, &supp_rates[8], rates); 157 memcpy(pos, &supp_rates[8], rates);
166 } 158 }
167 159
168 ifibss->probe_resp = skb; 160 if (ifibss->ie_len)
161 memcpy(skb_put(skb, ifibss->ie_len),
162 ifibss->ie, ifibss->ie_len);
169 163
170 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON | 164 rcu_assign_pointer(ifibss->presp, skb);
171 IEEE80211_IFCC_BEACON_ENABLED);
172 165
166 sdata->vif.bss_conf.beacon_int = beacon_int;
167 bss_change = BSS_CHANGED_BEACON_INT;
168 bss_change |= ieee80211_reset_erp_info(sdata);
169 bss_change |= BSS_CHANGED_BSSID;
170 bss_change |= BSS_CHANGED_BEACON;
171 bss_change |= BSS_CHANGED_BEACON_ENABLED;
172 ieee80211_bss_info_change_notify(sdata, bss_change);
173 173
174 rates = 0; 174 ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
175 for (i = 0; i < supp_rates_len; i++) {
176 int bitrate = (supp_rates[i] & 0x7f) * 5;
177 for (j = 0; j < sband->n_bitrates; j++)
178 if (sband->bitrates[j].bitrate == bitrate)
179 rates |= BIT(j);
180 }
181 175
182 ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
183
184 ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
185 ifibss->state = IEEE80211_IBSS_MLME_JOINED; 176 ifibss->state = IEEE80211_IBSS_MLME_JOINED;
186 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 177 mod_timer(&ifibss->timer,
187 178 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
188 memset(&wrqu, 0, sizeof(wrqu));
189 memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
190 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
191 179
192 return res; 180 cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
181 mgmt, skb->len, 0, GFP_KERNEL);
182 cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
193} 183}
194 184
195static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 185static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
196 struct ieee80211_bss *bss) 186 struct ieee80211_bss *bss)
197{ 187{
198 return __ieee80211_sta_join_ibss(sdata, 188 struct ieee80211_supported_band *sband;
199 bss->cbss.bssid, 189 u32 basic_rates;
200 bss->cbss.beacon_interval, 190 int i, j;
201 bss->cbss.channel->center_freq, 191 u16 beacon_int = bss->cbss.beacon_interval;
202 bss->supp_rates_len, bss->supp_rates, 192
203 bss->cbss.capability, 193 if (beacon_int < 10)
204 bss->cbss.tsf); 194 beacon_int = 10;
195
196 sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
197
198 basic_rates = 0;
199
200 for (i = 0; i < bss->supp_rates_len; i++) {
201 int rate = (bss->supp_rates[i] & 0x7f) * 5;
202 bool is_basic = !!(bss->supp_rates[i] & 0x80);
203
204 for (j = 0; j < sband->n_bitrates; j++) {
205 if (sband->bitrates[j].bitrate == rate) {
206 if (is_basic)
207 basic_rates |= BIT(j);
208 break;
209 }
210 }
211 }
212
213 __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
214 beacon_int,
215 bss->cbss.channel,
216 basic_rates,
217 bss->cbss.capability,
218 bss->cbss.tsf);
205} 219}
206 220
207static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 221static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -277,7 +291,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
277 goto put_bss; 291 goto put_bss;
278 292
279 /* we use a fixed BSSID */ 293 /* we use a fixed BSSID */
280 if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET) 294 if (sdata->u.ibss.bssid)
281 goto put_bss; 295 goto put_bss;
282 296
283 /* not an IBSS */ 297 /* not an IBSS */
@@ -322,12 +336,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
322 bitrates[rx_status->rate_idx].bitrate; 336 bitrates[rx_status->rate_idx].bitrate;
323 337
324 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 338 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
325 } else if (local && local->ops && local->ops->get_tsf) 339 } else {
326 /* second best option: get current TSF */ 340 /*
327 rx_timestamp = local->ops->get_tsf(local_to_hw(local)); 341 * second best option: get current TSF
328 else 342 * (will return -1 if not supported)
329 /* can't merge without knowing the TSF */ 343 */
330 rx_timestamp = -1LLU; 344 rx_timestamp = drv_get_tsf(local);
345 }
331 346
332#ifdef CONFIG_MAC80211_IBSS_DEBUG 347#ifdef CONFIG_MAC80211_IBSS_DEBUG
333 printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" 348 printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
@@ -369,13 +384,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
369 struct sta_info *sta; 384 struct sta_info *sta;
370 int band = local->hw.conf.channel->band; 385 int band = local->hw.conf.channel->band;
371 386
372 /* TODO: Could consider removing the least recently used entry and 387 /*
373 * allow new one to be added. */ 388 * XXX: Consider removing the least recently used entry and
389 * allow new one to be added.
390 */
374 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { 391 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
375 if (net_ratelimit()) { 392 if (net_ratelimit())
376 printk(KERN_DEBUG "%s: No room for a new IBSS STA " 393 printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
377 "entry %pM\n", sdata->dev->name, addr); 394 sdata->dev->name, addr);
378 }
379 return NULL; 395 return NULL;
380 } 396 }
381 397
@@ -432,41 +448,33 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
432{ 448{
433 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 449 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
434 450
435 mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 451 mod_timer(&ifibss->timer,
452 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
436 453
437 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); 454 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
455
438 if (ieee80211_sta_active_ibss(sdata)) 456 if (ieee80211_sta_active_ibss(sdata))
439 return; 457 return;
440 458
441 if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) && 459 if (ifibss->fixed_channel)
442 (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
443 return; 460 return;
444 461
445 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 462 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
446 "IBSS networks with same SSID (merge)\n", sdata->dev->name); 463 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
447 464
448 /* XXX maybe racy? */ 465 ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
449 if (sdata->local->scan_req)
450 return;
451
452 memcpy(sdata->local->int_scan_req.ssids[0].ssid,
453 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
454 sdata->local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
455 ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
456} 466}
457 467
458static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) 468static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
459{ 469{
460 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 470 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
461 struct ieee80211_local *local = sdata->local; 471 struct ieee80211_local *local = sdata->local;
462 struct ieee80211_supported_band *sband; 472 struct ieee80211_supported_band *sband;
463 u8 *pos;
464 u8 bssid[ETH_ALEN]; 473 u8 bssid[ETH_ALEN];
465 u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
466 u16 capability; 474 u16 capability;
467 int i; 475 int i;
468 476
469 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) { 477 if (ifibss->fixed_bssid) {
470 memcpy(bssid, ifibss->bssid, ETH_ALEN); 478 memcpy(bssid, ifibss->bssid, ETH_ALEN);
471 } else { 479 } else {
472 /* Generate random, not broadcast, locally administered BSSID. Mix in 480 /* Generate random, not broadcast, locally administered BSSID. Mix in
@@ -482,10 +490,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
482 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", 490 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
483 sdata->dev->name, bssid); 491 sdata->dev->name, bssid);
484 492
485 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 493 sband = local->hw.wiphy->bands[ifibss->channel->band];
486
487 if (local->hw.conf.beacon_int == 0)
488 local->hw.conf.beacon_int = 100;
489 494
490 capability = WLAN_CAPABILITY_IBSS; 495 capability = WLAN_CAPABILITY_IBSS;
491 496
@@ -494,29 +499,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
494 else 499 else
495 sdata->drop_unencrypted = 0; 500 sdata->drop_unencrypted = 0;
496 501
497 pos = supp_rates; 502 __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
498 for (i = 0; i < sband->n_bitrates; i++) { 503 ifibss->channel, 3, /* first two are basic */
499 int rate = sband->bitrates[i].bitrate; 504 capability, 0);
500 *pos++ = (u8) (rate / 5);
501 }
502
503 return __ieee80211_sta_join_ibss(sdata,
504 bssid, local->hw.conf.beacon_int,
505 local->hw.conf.channel->center_freq,
506 sband->n_bitrates, supp_rates,
507 capability, 0);
508} 505}
509 506
510static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) 507static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
511{ 508{
512 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 509 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
513 struct ieee80211_local *local = sdata->local; 510 struct ieee80211_local *local = sdata->local;
514 struct ieee80211_bss *bss; 511 struct ieee80211_bss *bss;
512 struct ieee80211_channel *chan = NULL;
515 const u8 *bssid = NULL; 513 const u8 *bssid = NULL;
516 int active_ibss; 514 int active_ibss;
517 515 u16 capability;
518 if (ifibss->ssid_len == 0)
519 return -EINVAL;
520 516
521 active_ibss = ieee80211_sta_active_ibss(sdata); 517 active_ibss = ieee80211_sta_active_ibss(sdata);
522#ifdef CONFIG_MAC80211_IBSS_DEBUG 518#ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -525,14 +521,23 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
525#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 521#endif /* CONFIG_MAC80211_IBSS_DEBUG */
526 522
527 if (active_ibss) 523 if (active_ibss)
528 return 0; 524 return;
529 525
530 if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) 526 capability = WLAN_CAPABILITY_IBSS;
527 if (sdata->default_key)
528 capability |= WLAN_CAPABILITY_PRIVACY;
529
530 if (ifibss->fixed_bssid)
531 bssid = ifibss->bssid; 531 bssid = ifibss->bssid;
532 bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid, 532 if (ifibss->fixed_channel)
533 chan = ifibss->channel;
534 if (!is_zero_ether_addr(ifibss->bssid))
535 bssid = ifibss->bssid;
536 bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
533 ifibss->ssid, ifibss->ssid_len, 537 ifibss->ssid, ifibss->ssid_len,
534 WLAN_CAPABILITY_IBSS, 538 WLAN_CAPABILITY_IBSS |
535 WLAN_CAPABILITY_IBSS); 539 WLAN_CAPABILITY_PRIVACY,
540 capability);
536 541
537#ifdef CONFIG_MAC80211_IBSS_DEBUG 542#ifdef CONFIG_MAC80211_IBSS_DEBUG
538 if (bss) 543 if (bss)
@@ -540,18 +545,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
540 "%pM\n", bss->cbss.bssid, ifibss->bssid); 545 "%pM\n", bss->cbss.bssid, ifibss->bssid);
541#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 546#endif /* CONFIG_MAC80211_IBSS_DEBUG */
542 547
543 if (bss && 548 if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
544 (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
545 memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
546 int ret;
547
548 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" 549 printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
549 " based on configured SSID\n", 550 " based on configured SSID\n",
550 sdata->dev->name, bss->cbss.bssid); 551 sdata->dev->name, bss->cbss.bssid);
551 552
552 ret = ieee80211_sta_join_ibss(sdata, bss); 553 ieee80211_sta_join_ibss(sdata, bss);
553 ieee80211_rx_bss_put(local, bss); 554 ieee80211_rx_bss_put(local, bss);
554 return ret; 555 return;
555 } else if (bss) 556 } else if (bss)
556 ieee80211_rx_bss_put(local, bss); 557 ieee80211_rx_bss_put(local, bss);
557 558
@@ -562,29 +563,24 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
562 /* Selected IBSS not found in current scan results - try to scan */ 563 /* Selected IBSS not found in current scan results - try to scan */
563 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED && 564 if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
564 !ieee80211_sta_active_ibss(sdata)) { 565 !ieee80211_sta_active_ibss(sdata)) {
565 mod_timer(&ifibss->timer, jiffies + 566 mod_timer(&ifibss->timer,
566 IEEE80211_IBSS_MERGE_INTERVAL); 567 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
567 } else if (time_after(jiffies, local->last_scan_completed + 568 } else if (time_after(jiffies, ifibss->last_scan_completed +
568 IEEE80211_SCAN_INTERVAL)) { 569 IEEE80211_SCAN_INTERVAL)) {
569 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 570 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
570 "join\n", sdata->dev->name); 571 "join\n", sdata->dev->name);
571 572
572 /* XXX maybe racy? */ 573 ieee80211_request_internal_scan(sdata, ifibss->ssid,
573 if (local->scan_req) 574 ifibss->ssid_len);
574 return -EBUSY;
575
576 memcpy(local->int_scan_req.ssids[0].ssid,
577 ifibss->ssid, IEEE80211_MAX_SSID_LEN);
578 local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
579 return ieee80211_request_scan(sdata, &local->int_scan_req);
580 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) { 575 } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
581 int interval = IEEE80211_SCAN_INTERVAL; 576 int interval = IEEE80211_SCAN_INTERVAL;
582 577
583 if (time_after(jiffies, ifibss->ibss_join_req + 578 if (time_after(jiffies, ifibss->ibss_join_req +
584 IEEE80211_IBSS_JOIN_TIMEOUT)) { 579 IEEE80211_IBSS_JOIN_TIMEOUT)) {
585 if (!(local->oper_channel->flags & 580 if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
586 IEEE80211_CHAN_NO_IBSS)) 581 ieee80211_sta_create_ibss(sdata);
587 return ieee80211_sta_create_ibss(sdata); 582 return;
583 }
588 printk(KERN_DEBUG "%s: IBSS not allowed on" 584 printk(KERN_DEBUG "%s: IBSS not allowed on"
589 " %d MHz\n", sdata->dev->name, 585 " %d MHz\n", sdata->dev->name,
590 local->hw.conf.channel->center_freq); 586 local->hw.conf.channel->center_freq);
@@ -595,11 +591,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
595 } 591 }
596 592
597 ifibss->state = IEEE80211_IBSS_MLME_SEARCH; 593 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
598 mod_timer(&ifibss->timer, jiffies + interval); 594 mod_timer(&ifibss->timer,
599 return 0; 595 round_jiffies(jiffies + interval));
600 } 596 }
601
602 return 0;
603} 597}
604 598
605static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, 599static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -614,13 +608,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
614 u8 *pos, *end; 608 u8 *pos, *end;
615 609
616 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || 610 if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
617 len < 24 + 2 || !ifibss->probe_resp) 611 len < 24 + 2 || !ifibss->presp)
618 return; 612 return;
619 613
620 if (local->ops->tx_last_beacon) 614 tx_last_beacon = drv_tx_last_beacon(local);
621 tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
622 else
623 tx_last_beacon = 1;
624 615
625#ifdef CONFIG_MAC80211_IBSS_DEBUG 616#ifdef CONFIG_MAC80211_IBSS_DEBUG
626 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" 617 printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
@@ -649,13 +640,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
649 } 640 }
650 if (pos[1] != 0 && 641 if (pos[1] != 0 &&
651 (pos[1] != ifibss->ssid_len || 642 (pos[1] != ifibss->ssid_len ||
652 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) { 643 !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
653 /* Ignore ProbeReq for foreign SSID */ 644 /* Ignore ProbeReq for foreign SSID */
654 return; 645 return;
655 } 646 }
656 647
657 /* Reply with ProbeResp */ 648 /* Reply with ProbeResp */
658 skb = skb_copy(ifibss->probe_resp, GFP_KERNEL); 649 skb = skb_copy(ifibss->presp, GFP_KERNEL);
659 if (!skb) 650 if (!skb)
660 return; 651 return;
661 652
@@ -746,6 +737,9 @@ static void ieee80211_ibss_work(struct work_struct *work)
746 struct ieee80211_if_ibss *ifibss; 737 struct ieee80211_if_ibss *ifibss;
747 struct sk_buff *skb; 738 struct sk_buff *skb;
748 739
740 if (WARN_ON(local->suspended))
741 return;
742
749 if (!netif_running(sdata->dev)) 743 if (!netif_running(sdata->dev))
750 return; 744 return;
751 745
@@ -782,101 +776,63 @@ static void ieee80211_ibss_timer(unsigned long data)
782 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 776 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
783 struct ieee80211_local *local = sdata->local; 777 struct ieee80211_local *local = sdata->local;
784 778
779 if (local->quiescing) {
780 ifibss->timer_running = true;
781 return;
782 }
783
785 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); 784 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
786 queue_work(local->hw.workqueue, &ifibss->work); 785 queue_work(local->hw.workqueue, &ifibss->work);
787} 786}
788 787
789void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) 788#ifdef CONFIG_PM
789void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata)
790{ 790{
791 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 791 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
792 792
793 INIT_WORK(&ifibss->work, ieee80211_ibss_work); 793 cancel_work_sync(&ifibss->work);
794 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 794 if (del_timer_sync(&ifibss->timer))
795 (unsigned long) sdata); 795 ifibss->timer_running = true;
796 skb_queue_head_init(&ifibss->skb_queue);
797
798 ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
799 IEEE80211_IBSS_AUTO_CHANNEL_SEL;
800} 796}
801 797
802int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata) 798void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata)
803{ 799{
804 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 800 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
805 801
806 ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET; 802 if (ifibss->timer_running) {
807 803 add_timer(&ifibss->timer);
808 if (ifibss->ssid_len) 804 ifibss->timer_running = false;
809 ifibss->flags |= IEEE80211_IBSS_SSID_SET;
810 else
811 ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
812
813 ifibss->ibss_join_req = jiffies;
814 ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
815 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
816
817 return 0;
818}
819
820int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
821{
822 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
823
824 if (len > IEEE80211_MAX_SSID_LEN)
825 return -EINVAL;
826
827 if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
828 memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
829 memcpy(ifibss->ssid, ssid, len);
830 ifibss->ssid_len = len;
831 } 805 }
832
833 return ieee80211_ibss_commit(sdata);
834}
835
836int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
837{
838 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
839
840 memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
841 *len = ifibss->ssid_len;
842
843 return 0;
844} 806}
807#endif
845 808
846int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid) 809void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
847{ 810{
848 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 811 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
849 812
850 if (is_valid_ether_addr(bssid)) { 813 INIT_WORK(&ifibss->work, ieee80211_ibss_work);
851 memcpy(ifibss->bssid, bssid, ETH_ALEN); 814 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
852 ifibss->flags |= IEEE80211_IBSS_BSSID_SET; 815 (unsigned long) sdata);
853 } else { 816 skb_queue_head_init(&ifibss->skb_queue);
854 memset(ifibss->bssid, 0, ETH_ALEN);
855 ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
856 }
857
858 if (netif_running(sdata->dev)) {
859 if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
860 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
861 "the low-level driver\n", sdata->dev->name);
862 }
863 }
864
865 return ieee80211_ibss_commit(sdata);
866} 817}
867 818
868/* scan finished notification */ 819/* scan finished notification */
869void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local) 820void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
870{ 821{
871 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 822 struct ieee80211_sub_if_data *sdata;
872 struct ieee80211_if_ibss *ifibss; 823
873 824 mutex_lock(&local->iflist_mtx);
874 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) { 825 list_for_each_entry(sdata, &local->interfaces, list) {
875 ifibss = &sdata->u.ibss; 826 if (!netif_running(sdata->dev))
876 if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) || 827 continue;
877 !ieee80211_sta_active_ibss(sdata)) 828 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
878 ieee80211_sta_find_ibss(sdata); 829 continue;
830 if (!sdata->u.ibss.ssid_len)
831 continue;
832 sdata->u.ibss.last_scan_completed = jiffies;
833 ieee80211_sta_find_ibss(sdata);
879 } 834 }
835 mutex_unlock(&local->iflist_mtx);
880} 836}
881 837
882ieee80211_rx_result 838ieee80211_rx_result
@@ -906,3 +862,86 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
906 862
907 return RX_DROP_MONITOR; 863 return RX_DROP_MONITOR;
908} 864}
865
866int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
867 struct cfg80211_ibss_params *params)
868{
869 struct sk_buff *skb;
870
871 if (params->bssid) {
872 memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
873 sdata->u.ibss.fixed_bssid = true;
874 } else
875 sdata->u.ibss.fixed_bssid = false;
876
877 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
878
879 sdata->u.ibss.channel = params->channel;
880 sdata->u.ibss.fixed_channel = params->channel_fixed;
881
882 if (params->ie) {
883 sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
884 GFP_KERNEL);
885 if (sdata->u.ibss.ie)
886 sdata->u.ibss.ie_len = params->ie_len;
887 }
888
889 skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
890 36 /* bitrates */ +
891 34 /* SSID */ +
892 3 /* DS params */ +
893 4 /* IBSS params */ +
894 params->ie_len);
895 if (!skb)
896 return -ENOMEM;
897
898 sdata->u.ibss.skb = skb;
899 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
900 sdata->u.ibss.ibss_join_req = jiffies;
901
902 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
903
904 /*
905 * The ssid_len setting below is used to see whether
906 * we are active, and we need all other settings
907 * before that may get visible.
908 */
909 mb();
910
911 sdata->u.ibss.ssid_len = params->ssid_len;
912
913 ieee80211_recalc_idle(sdata->local);
914
915 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
916 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
917
918 return 0;
919}
920
921int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
922{
923 struct sk_buff *skb;
924
925 del_timer_sync(&sdata->u.ibss.timer);
926 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
927 cancel_work_sync(&sdata->u.ibss.work);
928 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
929
930 sta_info_flush(sdata->local, sdata);
931
932 /* remove beacon */
933 kfree(sdata->u.ibss.ie);
934 skb = sdata->u.ibss.presp;
935 rcu_assign_pointer(sdata->u.ibss.presp, NULL);
936 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
937 synchronize_rcu();
938 kfree_skb(skb);
939
940 skb_queue_purge(&sdata->u.ibss.skb_queue);
941 memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
942 sdata->u.ibss.ssid_len = 0;
943
944 ieee80211_recalc_idle(sdata->local);
945
946 return 0;
947}