mlme.c 68.9 KB
Newer Older
1
2
/*
 * BSS client mode implementation
3
 * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
4
5
6
7
8
9
10
11
12
13
 * Copyright 2004, Instant802 Networks, Inc.
 * Copyright 2005, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

14
#include <linux/delay.h>
15
16
17
18
#include <linux/if_ether.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
19
#include <linux/rtnetlink.h>
20
#include <linux/pm_qos_params.h>
21
#include <linux/crc32.h>
22
#include <net/mac80211.h>
23
#include <asm/unaligned.h>
Johannes Berg's avatar
Johannes Berg committed
24

25
#include "ieee80211_i.h"
26
#include "driver-ops.h"
Johannes Berg's avatar
Johannes Berg committed
27
28
#include "rate.h"
#include "led.h"
29
30
31
32
33

#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_MAX_TRIES 3
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_MAX_TRIES 3
34
#define IEEE80211_MAX_PROBE_TRIES 5
35
36
37
38
39
40
41
42
43
44

/*
 * beacon loss detection timeout
 * XXX: should depend on beacon interval
 */
#define IEEE80211_BEACON_LOSS_TIME	(2 * HZ)
/*
 * Time the connection can be idle before we probe
 * it to see if we can still talk to the AP.
 */
45
#define IEEE80211_CONNECTION_IDLE_TIME	(30 * HZ)
46
47
48
49
50
/*
 * Time we wait for a probe response after sending
 * a probe request because of beacon loss or for
 * checking the connection still works.
 */
51
#define IEEE80211_PROBE_WAIT		(HZ / 2)
52

53
54
55
#define TMR_RUNNING_TIMER	0
#define TMR_RUNNING_CHANSW	1

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 * All cfg80211 functions have to be called outside a locked
 * section so that they can acquire a lock themselves... This
 * is much simpler than queuing up things in cfg80211, but we
 * do need some indirection for that here.
 */
enum rx_mgmt_action {
	/* no action required */
	RX_MGMT_NONE,

	/* caller must call cfg80211_send_rx_auth() */
	RX_MGMT_CFG80211_AUTH,

	/* caller must call cfg80211_send_rx_assoc() */
	RX_MGMT_CFG80211_ASSOC,

	/* caller must call cfg80211_send_deauth() */
	RX_MGMT_CFG80211_DEAUTH,

	/* caller must call cfg80211_send_disassoc() */
	RX_MGMT_CFG80211_DISASSOC,

	/* caller must call cfg80211_auth_timeout() & free work */
	RX_MGMT_CFG80211_AUTH_TO,

	/* caller must call cfg80211_assoc_timeout() & free work */
	RX_MGMT_CFG80211_ASSOC_TO,
};

85
/* utils */
86
87
88
89
90
static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
{
	WARN_ON(!mutex_is_locked(&ifmgd->mtx));
}

Johannes Berg's avatar
Johannes Berg committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
 * We can have multiple work items (and connection probing)
 * scheduling this timer, but we need to take care to only
 * reschedule it when it should fire _earlier_ than it was
 * asked for before, or if it's not pending right now. This
 * function ensures that. Note that it then is required to
 * run this function for all timeouts after the first one
 * has happened -- the work that runs from this timer will
 * do that.
 */
static void run_again(struct ieee80211_if_managed *ifmgd,
			     unsigned long timeout)
{
	ASSERT_MGD_MTX(ifmgd);

	if (!timer_pending(&ifmgd->timer) ||
	    time_before(timeout, ifmgd->timer.expires))
		mod_timer(&ifmgd->timer, timeout);
}

111
112
113
114
115
116
117
118
119
static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
{
	if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
		return;

	mod_timer(&sdata->u.mgd.bcn_mon_timer,
		  round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
}

120
static int ecw2cw(int ecw)
Johannes Berg's avatar
Johannes Berg committed
121
{
122
	return (1 << ecw) - 1;
Johannes Berg's avatar
Johannes Berg committed
123
124
}

125
static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
126
				      struct ieee80211_supported_band *sband,
127
				      u32 *rates)
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{
	int i, j, count;
	*rates = 0;
	count = 0;
	for (i = 0; i < bss->supp_rates_len; i++) {
		int rate = (bss->supp_rates[i] & 0x7F) * 5;

		for (j = 0; j < sband->n_bitrates; j++)
			if (sband->bitrates[j].bitrate == rate) {
				*rates |= BIT(j);
				count++;
				break;
			}
	}

	return count;
}

146
147
148
149
150
151
152
/*
 * ieee80211_enable_ht should be called only after the operating band
 * has been determined as ht configuration depends on the hw's
 * HT abilities for a specific band.
 */
static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
			       struct ieee80211_ht_info *hti,
153
			       const u8 *bssid, u16 ap_ht_cap_flags)
154
155
156
157
158
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	struct sta_info *sta;
	u32 changed = 0;
159
	u16 ht_opmode;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	bool enable_ht = true, ht_changed;
	enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;

	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

	/* HT is not supported */
	if (!sband->ht_cap.ht_supported)
		enable_ht = false;

	/* check that channel matches the right operating channel */
	if (local->hw.conf.channel->center_freq !=
	    ieee80211_channel_to_frequency(hti->control_chan))
		enable_ht = false;

	if (enable_ht) {
		channel_type = NL80211_CHAN_HT20;

		if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
		    (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
		    (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
			switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
			case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
182
183
184
				if (!(local->hw.conf.channel->flags &
				    IEEE80211_CHAN_NO_HT40PLUS))
					channel_type = NL80211_CHAN_HT40PLUS;
185
186
				break;
			case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
187
188
189
				if (!(local->hw.conf.channel->flags &
				    IEEE80211_CHAN_NO_HT40MINUS))
					channel_type = NL80211_CHAN_HT40MINUS;
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
				break;
			}
		}
	}

	ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
		     channel_type != local->hw.conf.channel_type;

	local->oper_channel_type = channel_type;

	if (ht_changed) {
                /* channel_type change automatically detected */
		ieee80211_hw_config(local, 0);

		rcu_read_lock();
205
		sta = sta_info_get(local, bssid);
206
207
208
209
210
211
212
213
214
215
		if (sta)
			rate_control_rate_update(local, sband, sta,
						 IEEE80211_RC_HT_CHANGED);
		rcu_read_unlock();
        }

	/* disable HT */
	if (!enable_ht)
		return 0;

216
	ht_opmode = le16_to_cpu(hti->operation_mode);
217
218

	/* if bss configuration changed store the new one */
219
220
	if (!sdata->ht_opmode_valid ||
	    sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
221
		changed |= BSS_CHANGED_HT;
222
		sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
223
		sdata->ht_opmode_valid = true;
224
225
226
227
228
	}

	return changed;
}

229
230
/* frame sending functions */

231
232
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
				 struct ieee80211_mgd_work *wk)
233
{
234
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
235
236
237
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
238
239
	u8 *pos;
	const u8 *ies, *ht_ie;
240
241
242
243
	int i, len, count, rates_len, supp_rates_len;
	u16 capab;
	int wmm = 0;
	struct ieee80211_supported_band *sband;
244
	u32 rates = 0;
245
246

	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
247
248
			    sizeof(*mgmt) + 200 + wk->ie_len +
			    wk->ssid_len);
249
250
251
252
253
254
255
256
257
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
		       "frame\n", sdata->dev->name);
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];

258
	capab = ifmgd->capab;
259
260
261
262
263
264
265
266

	if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) {
		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE))
			capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
		if (!(local->hw.flags & IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE))
			capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
	}

267
268
269
270
	if (wk->bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
		capab |= WLAN_CAPABILITY_PRIVACY;
	if (wk->bss->wmm_used)
		wmm = 1;
271

272
273
274
275
276
	/* get all rates supported by the device and the AP as
	 * some APs don't like getting a superset of their rates
	 * in the association request (e.g. D-Link DAP 1353 in
	 * b-only mode) */
	rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates);
277

278
279
280
	if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
	    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
281
282
283

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
284
	memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN);
285
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
286
	memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN);
287

288
	if (!is_zero_ether_addr(wk->prev_bssid)) {
289
290
291
292
293
294
		skb_put(skb, 10);
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_REASSOC_REQ);
		mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
		mgmt->u.reassoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
295
		memcpy(mgmt->u.reassoc_req.current_ap, wk->prev_bssid,
296
297
298
299
300
301
		       ETH_ALEN);
	} else {
		skb_put(skb, 4);
		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
						  IEEE80211_STYPE_ASSOC_REQ);
		mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
302
		mgmt->u.assoc_req.listen_interval =
303
304
305
306
				cpu_to_le16(local->hw.conf.listen_interval);
	}

	/* SSID */
307
	ies = pos = skb_put(skb, 2 + wk->ssid_len);
308
	*pos++ = WLAN_EID_SSID;
309
310
	*pos++ = wk->ssid_len;
	memcpy(pos, wk->ssid, wk->ssid_len);
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

	/* add all rates which were marked to be used above */
	supp_rates_len = rates_len;
	if (supp_rates_len > 8)
		supp_rates_len = 8;

	len = sband->n_bitrates;
	pos = skb_put(skb, supp_rates_len + 2);
	*pos++ = WLAN_EID_SUPP_RATES;
	*pos++ = supp_rates_len;

	count = 0;
	for (i = 0; i < sband->n_bitrates; i++) {
		if (BIT(i) & rates) {
			int rate = sband->bitrates[i].bitrate;
			*pos++ = (u8) (rate / 5);
			if (++count == 8)
				break;
		}
	}

	if (rates_len > count) {
		pos = skb_put(skb, rates_len - count + 2);
		*pos++ = WLAN_EID_EXT_SUPP_RATES;
		*pos++ = rates_len - count;

		for (i++; i < sband->n_bitrates; i++) {
			if (BIT(i) & rates) {
				int rate = sband->bitrates[i].bitrate;
				*pos++ = (u8) (rate / 5);
			}
		}
	}

	if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) {
		/* 1. power capabilities */
		pos = skb_put(skb, 4);
		*pos++ = WLAN_EID_PWR_CAPABILITY;
		*pos++ = 2;
		*pos++ = 0; /* min tx power */
		*pos++ = local->hw.conf.channel->max_power; /* max tx power */

		/* 2. supported channels */
		/* TODO: get this in reg domain format */
		pos = skb_put(skb, 2 * sband->n_channels + 2);
		*pos++ = WLAN_EID_SUPPORTED_CHANNELS;
		*pos++ = 2 * sband->n_channels;
		for (i = 0; i < sband->n_channels; i++) {
			*pos++ = ieee80211_frequency_to_channel(
					sband->channels[i].center_freq);
			*pos++ = 1; /* one channel in the subband*/
		}
	}

365
366
367
	if (wk->ie_len && wk->ie) {
		pos = skb_put(skb, wk->ie_len);
		memcpy(pos, wk->ie, wk->ie_len);
368
369
	}

370
	if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED)) {
371
372
373
374
375
376
377
378
379
380
381
382
383
		pos = skb_put(skb, 9);
		*pos++ = WLAN_EID_VENDOR_SPECIFIC;
		*pos++ = 7; /* len */
		*pos++ = 0x00; /* Microsoft OUI 00:50:F2 */
		*pos++ = 0x50;
		*pos++ = 0xf2;
		*pos++ = 2; /* WME */
		*pos++ = 0; /* WME info */
		*pos++ = 1; /* WME ver */
		*pos++ = 0;
	}

	/* wmm support is a must to HT */
384
385
386
387
388
389
	/*
	 * IEEE802.11n does not allow TKIP/WEP as pairwise
	 * ciphers in HT mode. We still associate in non-ht
	 * mode (11a/b/g) if any one of these ciphers is
	 * configured as pairwise.
	 */
390
	if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
391
	    sband->ht_cap.ht_supported &&
392
	    (ht_ie = ieee80211_bss_get_ie(&wk->bss->cbss, WLAN_EID_HT_INFORMATION)) &&
393
	    ht_ie[1] >= sizeof(struct ieee80211_ht_info) &&
394
	    (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) {
395
396
397
		struct ieee80211_ht_info *ht_info =
			(struct ieee80211_ht_info *)(ht_ie + 2);
		u16 cap = sband->ht_cap.cap;
398
399
400
		__le16 tmp;
		u32 flags = local->hw.conf.channel->flags;

401
402
		switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
		case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
403
			if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
404
				cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
405
406
407
				cap &= ~IEEE80211_HT_CAP_SGI_40;
			}
			break;
408
		case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
409
			if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
410
				cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
411
412
413
414
415
416
417
418
419
420
421
422
423
				cap &= ~IEEE80211_HT_CAP_SGI_40;
			}
			break;
		}

		tmp = cpu_to_le16(cap);
		pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2);
		*pos++ = WLAN_EID_HT_CAPABILITY;
		*pos++ = sizeof(struct ieee80211_ht_cap);
		memset(pos, 0, sizeof(struct ieee80211_ht_cap));
		memcpy(pos, &tmp, sizeof(u16));
		pos += sizeof(u16);
		/* TODO: needs a define here for << 2 */
424
425
426
		*pos++ = sband->ht_cap.ampdu_factor |
			 (sband->ht_cap.ampdu_density << 2);
		memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
427
428
	}

429
	ieee80211_tx_skb(sdata, skb, 0);
430
431
432
}


433
static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
Johannes Berg's avatar
Johannes Berg committed
434
435
					   const u8 *bssid, u16 stype, u16 reason,
					   void *cookie)
436
437
{
	struct ieee80211_local *local = sdata->local;
438
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
439
440
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
441

442
	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
443
	if (!skb) {
444
445
		printk(KERN_DEBUG "%s: failed to allocate buffer for "
		       "deauth/disassoc frame\n", sdata->dev->name);
446
447
448
449
450
451
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
452
	memcpy(mgmt->da, bssid, ETH_ALEN);
453
	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
454
	memcpy(mgmt->bssid, bssid, ETH_ALEN);
455
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
456
	skb_put(skb, 2);
457
	/* u.deauth.reason_code == u.disassoc.reason_code */
458
459
	mgmt->u.deauth.reason_code = cpu_to_le16(reason);

460
	if (stype == IEEE80211_STYPE_DEAUTH)
Johannes Berg's avatar
Johannes Berg committed
461
		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie);
462
	else
Johannes Berg's avatar
Johannes Berg committed
463
		cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie);
464
	ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
465
466
}

467
468
469
void ieee80211_send_pspoll(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
470
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
	struct ieee80211_pspoll *pspoll;
	struct sk_buff *skb;
	u16 fc;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for "
		       "pspoll frame\n", sdata->dev->name);
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll));
	memset(pspoll, 0, sizeof(*pspoll));
	fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM;
	pspoll->frame_control = cpu_to_le16(fc);
487
	pspoll->aid = cpu_to_le16(ifmgd->aid);
488
489
490
491

	/* aid in PS-Poll has its two MSBs each set to 1 */
	pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);

492
	memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN);
493
494
495
496
497
	memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN);

	ieee80211_tx_skb(sdata, skb, 0);
}

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
void ieee80211_send_nullfunc(struct ieee80211_local *local,
			     struct ieee80211_sub_if_data *sdata,
			     int powersave)
{
	struct sk_buff *skb;
	struct ieee80211_hdr *nullfunc;
	__le16 fc;

	if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
		return;

	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
	if (!skb) {
		printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
		       "frame\n", sdata->dev->name);
		return;
	}
	skb_reserve(skb, local->hw.extra_tx_headroom);

	nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
	memset(nullfunc, 0, 24);
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_TODS);
	if (powersave)
		fc |= cpu_to_le16(IEEE80211_FCTL_PM);
	nullfunc->frame_control = fc;
	memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
	memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
	memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);

	ieee80211_tx_skb(sdata, skb, 0);
}

531
532
533
534
535
536
537
538
539
540
/* spectrum management related things */
static void ieee80211_chswitch_work(struct work_struct *work)
{
	struct ieee80211_sub_if_data *sdata =
		container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

	if (!netif_running(sdata->dev))
		return;

541
542
543
	mutex_lock(&ifmgd->mtx);
	if (!ifmgd->associated)
		goto out;
544
545

	sdata->local->oper_channel = sdata->local->csa_channel;
546
547
	ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL);

548
	/* XXX: shouldn't really modify cfg80211-owned data! */
549
	ifmgd->associated->cbss.channel = sdata->local->oper_channel;
550
551
552

	ieee80211_wake_queues_by_reason(&sdata->local->hw,
					IEEE80211_QUEUE_STOP_REASON_CSA);
553
554
555
 out:
	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
	mutex_unlock(&ifmgd->mtx);
556
557
558
559
560
561
562
563
}

static void ieee80211_chswitch_timer(unsigned long data)
{
	struct ieee80211_sub_if_data *sdata =
		(struct ieee80211_sub_if_data *) data;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

564
565
566
567
568
	if (sdata->local->quiescing) {
		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
		return;
	}

569
	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
570
571
572
573
574
575
576
577
578
579
}

void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
				      struct ieee80211_channel_sw_ie *sw_elem,
				      struct ieee80211_bss *bss)
{
	struct ieee80211_channel *new_ch;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);

580
581
582
	ASSERT_MGD_MTX(ifmgd);

	if (!ifmgd->associated)
583
584
		return;

585
	if (sdata->local->scanning)
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
		return;

	/* Disregard subsequent beacons if we are already running a timer
	   processing a CSA */

	if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
		return;

	new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
	if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
		return;

	sdata->local->csa_channel = new_ch;

	if (sw_elem->count <= 1) {
601
		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
	} else {
		ieee80211_stop_queues_by_reason(&sdata->local->hw,
					IEEE80211_QUEUE_STOP_REASON_CSA);
		ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
		mod_timer(&ifmgd->chswitch_timer,
			  jiffies +
			  msecs_to_jiffies(sw_elem->count *
					   bss->cbss.beacon_interval));
	}
}

static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
					u16 capab_info, u8 *pwr_constr_elem,
					u8 pwr_constr_elem_len)
{
	struct ieee80211_conf *conf = &sdata->local->hw.conf;

	if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
		return;

	/* Power constraint IE length should be 1 octet */
	if (pwr_constr_elem_len != 1)
		return;

	if ((*pwr_constr_elem <= conf->channel->max_power) &&
	    (*pwr_constr_elem != sdata->local->power_constr_level)) {
		sdata->local->power_constr_level = *pwr_constr_elem;
		ieee80211_hw_config(sdata->local, 0);
	}
}

633
634
635
636
637
638
/* powersave */
static void ieee80211_enable_ps(struct ieee80211_local *local,
				struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_conf *conf = &local->hw.conf;

Johannes Berg's avatar
Johannes Berg committed
639
640
641
642
	/*
	 * If we are scanning right now then the parameters will
	 * take effect when scan finishes.
	 */
643
	if (local->scanning)
Johannes Berg's avatar
Johannes Berg committed
644
645
		return;

646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
	if (conf->dynamic_ps_timeout > 0 &&
	    !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
		mod_timer(&local->dynamic_ps_timer, jiffies +
			  msecs_to_jiffies(conf->dynamic_ps_timeout));
	} else {
		if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
			ieee80211_send_nullfunc(local, sdata, 1);
		conf->flags |= IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
	}
}

static void ieee80211_change_ps(struct ieee80211_local *local)
{
	struct ieee80211_conf *conf = &local->hw.conf;

	if (local->ps_sdata) {
		ieee80211_enable_ps(local, local->ps_sdata);
	} else if (conf->flags & IEEE80211_CONF_PS) {
		conf->flags &= ~IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
		del_timer_sync(&local->dynamic_ps_timer);
		cancel_work_sync(&local->dynamic_ps_enable_work);
	}
}

/* need to hold RTNL or interface lock */
673
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
{
	struct ieee80211_sub_if_data *sdata, *found = NULL;
	int count = 0;

	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
		local->ps_sdata = NULL;
		return;
	}

	list_for_each_entry(sdata, &local->interfaces, list) {
		if (!netif_running(sdata->dev))
			continue;
		if (sdata->vif.type != NL80211_IFTYPE_STATION)
			continue;
		found = sdata;
		count++;
	}

692
	if (count == 1 && found->u.mgd.powersave &&
693
	    found->u.mgd.associated && list_empty(&found->u.mgd.work_list) &&
694
695
	    !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
				    IEEE80211_STA_CONNECTION_POLL))) {
696
697
698
699
700
701
702
703
		s32 beaconint_us;

		if (latency < 0)
			latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);

		beaconint_us = ieee80211_tu_to_usec(
					found->vif.bss_conf.beacon_int);

704
		if (beaconint_us > latency) {
705
			local->ps_sdata = NULL;
706
707
708
709
710
711
712
713
		} else {
			u8 dtimper = found->vif.bss_conf.dtim_period;
			int maxslp = 1;

			if (dtimper > 1)
				maxslp = min_t(int, dtimper,
						    latency / beaconint_us);

714
			local->hw.conf.max_sleep_period = maxslp;
715
			local->ps_sdata = found;
716
		}
717
	} else {
718
		local->ps_sdata = NULL;
719
	}
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

	ieee80211_change_ps(local);
}

void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local,
			     dynamic_ps_disable_work);

	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
		local->hw.conf.flags &= ~IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
	}

	ieee80211_wake_queues_by_reason(&local->hw,
					IEEE80211_QUEUE_STOP_REASON_PS);
}

void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
{
	struct ieee80211_local *local =
		container_of(work, struct ieee80211_local,
			     dynamic_ps_enable_work);
	struct ieee80211_sub_if_data *sdata = local->ps_sdata;

	/* can only happen when PS was just disabled anyway */
	if (!sdata)
		return;

	if (local->hw.conf.flags & IEEE80211_CONF_PS)
		return;

	if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
		ieee80211_send_nullfunc(local, sdata, 1);

	local->hw.conf.flags |= IEEE80211_CONF_PS;
	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
}

void ieee80211_dynamic_ps_timer(unsigned long data)
{
	struct ieee80211_local *local = (void *) data;

764
	if (local->quiescing || local->suspended)
765
766
		return;

767
	ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
768
769
}

Johannes Berg's avatar
Johannes Berg committed
770
/* MLME */
771
static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
772
				     struct ieee80211_if_managed *ifmgd,
773
774
775
776
777
778
779
				     u8 *wmm_param, size_t wmm_param_len)
{
	struct ieee80211_tx_queue_params params;
	size_t left;
	int count;
	u8 *pos;

780
	if (!(ifmgd->flags & IEEE80211_STA_WMM_ENABLED))
781
782
783
784
785
		return;

	if (!wmm_param)
		return;

786
787
788
	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
		return;
	count = wmm_param[6] & 0x0f;
789
	if (count == ifmgd->wmm_last_param_set)
790
		return;
791
	ifmgd->wmm_last_param_set = count;
792
793
794
795
796
797
798
799
800
801
802
803
804

	pos = wmm_param + 8;
	left = wmm_param_len - 8;

	memset(&params, 0, sizeof(params));

	local->wmm_acm = 0;
	for (; left >= 4; left -= 4, pos += 4) {
		int aci = (pos[0] >> 5) & 0x03;
		int acm = (pos[0] >> 4) & 0x01;
		int queue;

		switch (aci) {
805
		case 1: /* AC_BK */
Johannes Berg's avatar
Johannes Berg committed
806
			queue = 3;
Johannes Berg's avatar
Johannes Berg committed
807
			if (acm)
808
				local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
809
			break;
810
		case 2: /* AC_VI */
Johannes Berg's avatar
Johannes Berg committed
811
			queue = 1;
Johannes Berg's avatar
Johannes Berg committed
812
			if (acm)
813
				local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
814
			break;
815
		case 3: /* AC_VO */
Johannes Berg's avatar
Johannes Berg committed
816
			queue = 0;
Johannes Berg's avatar
Johannes Berg committed
817
			if (acm)
818
				local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
819
			break;
820
		case 0: /* AC_BE */
821
		default:
Johannes Berg's avatar
Johannes Berg committed
822
			queue = 2;
Johannes Berg's avatar
Johannes Berg committed
823
			if (acm)
824
				local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
825
826
827
828
829
830
			break;
		}

		params.aifs = pos[0] & 0x0f;
		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
		params.cw_min = ecw2cw(pos[1] & 0x0f);
831
		params.txop = get_unaligned_le16(pos + 2);
832
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
833
		printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
834
		       "cWmin=%d cWmax=%d txop=%d\n",
835
836
		       wiphy_name(local->hw.wiphy), queue, aci, acm,
		       params.aifs, params.cw_min, params.cw_max, params.txop);
837
#endif
838
		if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
839
			printk(KERN_DEBUG "%s: failed to set TX queue "
840
841
			       "parameters for queue %d\n",
			       wiphy_name(local->hw.wiphy), queue);
842
843
844
	}
}

845
846
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
					   u16 capab, bool erp_valid, u8 erp)
847
{
848
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
849
	u32 changed = 0;
850
851
852
853
854
855
856
857
858
859
860
861
862
	bool use_protection;
	bool use_short_preamble;
	bool use_short_slot;

	if (erp_valid) {
		use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
		use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
	} else {
		use_protection = false;
		use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
	}

	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
863

864
865
866
	if (use_protection != bss_conf->use_cts_prot) {
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
867
	}
868

869
870
	if (use_short_preamble != bss_conf->use_short_preamble) {
		bss_conf->use_short_preamble = use_short_preamble;
871
		changed |= BSS_CHANGED_ERP_PREAMBLE;
872
	}
873

874
875
876
	if (use_short_slot != bss_conf->use_short_slot) {
		bss_conf->use_short_slot = use_short_slot;
		changed |= BSS_CHANGED_ERP_SLOT;
877
878
879
880
881
	}

	return changed;
}

882
static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
883
				     struct ieee80211_mgd_work *wk,
Johannes Berg's avatar
Johannes Berg committed
884
				     u32 bss_info_changed)
885
{
886
	struct ieee80211_local *local = sdata->local;
887
	struct ieee80211_bss *bss = wk->bss;
888

Johannes Berg's avatar
Johannes Berg committed
889
	bss_info_changed |= BSS_CHANGED_ASSOC;
890
891
892
893
	/* set timing information */
	sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
	sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
	sdata->vif.bss_conf.dtim_period = bss->dtim_period;
894

895
896
897
	bss_info_changed |= BSS_CHANGED_BEACON_INT;
	bss_info_changed |= ieee80211_handle_bss_capability(sdata,
		bss->cbss.capability, bss->has_erp_value, bss->erp_value);
898

899
	sdata->u.mgd.associated = bss;
900
	sdata->u.mgd.old_associate_work = wk;
901
	memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
902

903
904
905
906
	/* just to be sure */
	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
				IEEE80211_STA_BEACON_POLL);

907
	ieee80211_led_assoc(local, 1);
908

909
	sdata->vif.bss_conf.assoc = 1;
910
911
912
913
914
	/*
	 * For now just always ask the driver to update the basic rateset
	 * when we have associated, we aren't checking whether it actually
	 * changed or not.
	 */
Johannes Berg's avatar
Johannes Berg committed
915
	bss_info_changed |= BSS_CHANGED_BASIC_RATES;
916
917
918
919

	/* And the BSSID changed - we're associated now */
	bss_info_changed |= BSS_CHANGED_BSSID;

Johannes Berg's avatar
Johannes Berg committed
920
	ieee80211_bss_info_change_notify(sdata, bss_info_changed);
921

Johannes Berg's avatar
Johannes Berg committed
922
923
924
	mutex_lock(&local->iflist_mtx);
	ieee80211_recalc_ps(local, -1);
	mutex_unlock(&local->iflist_mtx);
925

926
927
	netif_tx_start_all_queues(sdata->dev);
	netif_carrier_on(sdata->dev);
928
929
}

930
931
932
static enum rx_mgmt_action __must_check
ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
		       struct ieee80211_mgd_work *wk)
933
{
934
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
935
	struct ieee80211_local *local = sdata->local;
936

937
938
	wk->tries++;
	if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
939
		printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
940
		       sdata->dev->name, wk->bss->cbss.bssid);
941
942
943

		/*
		 * Most likely AP is not in the range so remove the
944
		 * bss struct for that AP.
945
		 */
946
		cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
947
948
949

		/*
		 * We might have a pending scan which had no chance to run yet
950
951
		 * due to work needing to be done. Hence, queue the STAs work
		 * again for that.
952
		 */
953
		ieee80211_queue_work(&local->hw, &ifmgd->work);
954
		return RX_MGMT_CFG80211_AUTH_TO;
955
956
	}

957
958
959
	printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n",
			sdata->dev->name, wk->bss->cbss.bssid,
			wk->tries);
960

961
962
	/*
	 * Direct probe is sent to broadcast address as some APs
963
964
	 * will not answer to direct packet in unassociated state.
	 */
965
966
967
	ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);

	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
Johannes Berg's avatar
Johannes Berg committed
968
	run_again(ifmgd, wk->timeout);
969

970
	return RX_MGMT_NONE;
Johannes Berg's avatar
Johannes Berg committed
971
}
972

973

974
975
976
static enum rx_mgmt_action __must_check
ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
		       struct ieee80211_mgd_work *wk)
977
{
978
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
979
	struct ieee80211_local *local = sdata->local;
980

981
982
	wk->tries++;
	if (wk->tries > IEEE80211_AUTH_MAX_TRIES) {
983
		printk(KERN_DEBUG "%s: authentication with AP %pM"
984
		       " timed out\n",
985
986
987
988
989
990
991
		       sdata->dev->name, wk->bss->cbss.bssid);

		/*
		 * Most likely AP is not in the range so remove the
		 * bss struct for that AP.
		 */
		cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss);
992
993
994

		/*
		 * We might have a pending scan which had no chance to run yet
995
996
		 * due to work needing to be done. Hence, queue the STAs work
		 * again for that.
997
		 */
998
		ieee80211_queue_work(&local->hw, &ifmgd->work);
999
		return RX_MGMT_CFG80211_AUTH_TO;
1000
1001
	}

1002
1003
1004
1005
	printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n",
	       sdata->dev->name, wk->bss->cbss.bssid, wk->tries);

	ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
Johannes Berg's avatar
Johannes Berg committed
1006
			    wk->bss->cbss.bssid, NULL, 0, 0);
1007
	wk->auth_transaction = 2;
1008

1009
	wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
Johannes Berg's avatar
Johannes Berg committed
1010
	run_again(ifmgd, wk->timeout);
1011

1012
	return RX_MGMT_NONE;
1013
1014
}

1015
1016
static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
				   bool deauth)
1017
{
1018
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1019
1020
	struct ieee80211_local *local = sdata->local;
	struct sta_info *sta;
1021
	u32 changed = 0, config_changed = 0;
1022
	u8 bssid[ETH_ALEN];
1023

1024
1025
	ASSERT_MGD_MTX(ifmgd);

1026
1027
1028
1029
1030
	if (WARN_ON(!ifmgd->associated))
		return;

	memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);

1031
1032
1033
	ifmgd->associated = NULL;
	memset(ifmgd->bssid, 0, ETH_ALEN);

1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
	if (deauth) {
		kfree(ifmgd->old_associate_work);
		ifmgd->old_associate_work = NULL;
	} else {
		struct ieee80211_mgd_work *wk = ifmgd->old_associate_work;

		wk->state = IEEE80211_MGD_STATE_IDLE;
		list_add(&wk->list, &ifmgd->work_list);
	}

1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
	/*
	 * we need to commit the associated = NULL change because the
	 * scan code uses that to determine whether this iface should
	 * go to/wake up from powersave or not -- and could otherwise
	 * wake the queues erroneously.
	 */
	smp_mb();

	/*
	 * Thus, we can only afterwards stop the queues -- to account
	 * for the case where another CPU is finishing a scan at this
	 * time -- we don't want the scan code to enable queues.
	 */
1057

1058
	netif_tx_stop_all_queues(sdata->dev);
1059
1060
	netif_carrier_off(sdata->dev);

1061
	rcu_read_lock();
1062
	sta = sta_info_get(local, bssid);
1063
1064
1065
	if (sta)
		ieee80211_sta_tear_down_BA_sessions(sta);
	rcu_read_unlock();
1066

1067
1068
1069
	changed |= ieee80211_reset_erp_info(sdata);

	ieee80211_led_assoc(local, 0);
Johannes Berg's avatar
Johannes Berg committed
1070
1071
	changed |= BSS_CHANGED_ASSOC;
	sdata->vif.bss_conf.assoc = false;
1072

1073
1074
	ieee80211_set_wmm_default(sdata);

1075
1076
	ieee80211_recalc_idle(local);

1077
	/* channel(_type) changes are handled by ieee80211_hw_config */
Sujith's avatar
Sujith committed
1078
	local->oper_channel_type = NL80211_CHAN_NO_HT;
1079

1080
1081
1082
	/* on the next assoc, re-program HT parameters */
	sdata->ht_opmode_valid = false;

1083
1084
	local->power_constr_level = 0;

1085
1086
1087
	del_timer_sync(&local->dynamic_ps_timer);
	cancel_work_sync(&local->dynamic_ps_enable_work);

1088
1089
1090
1091
	if (local->hw.conf.flags & IEEE80211_CONF_PS) {
		local->hw.conf.flags &= ~IEEE80211_CONF_PS;
		config_changed |= IEEE80211_CONF_CHANGE_PS;
	}
Johannes Berg's avatar
Johannes Berg committed
1092

1093
	ieee80211_hw_config(local, config_changed);
1094
1095
1096

	/* And the BSSID changed -- not very interesting here */
	changed |= BSS_CHANGED_BSSID;
Johannes Berg's avatar
Johannes Berg committed
1097
	ieee80211_bss_info_change_notify(sdata, changed);
1098
1099
1100

	rcu_read_lock();

1101
	sta = sta_info_get(local, bssid);
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
	if (!sta) {
		rcu_read_unlock();
		return;
	}

	sta_info_unlink(&sta);

	rcu_read_unlock();

	sta_info_destroy(sta);
1112
}
1113

1114
1115
1116
static enum rx_mgmt_action __must_check
ieee80211_associate(struct ieee80211_sub_if_data *sdata,
		    struct ieee80211_mgd_work *wk)
1117
{
1118
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1119
	struct ieee80211_local *local = sdata->local;