mlme.c 100 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/moduleparam.h>
20
#include <linux/rtnetlink.h>
21
#include <linux/pm_qos.h>
22
#include <linux/crc32.h>
23
#include <linux/slab.h>
24
#include <linux/export.h>
25
#include <net/mac80211.h>
26
#include <asm/unaligned.h>
Johannes Berg's avatar
Johannes Berg committed
27

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

Johannes Berg's avatar
Johannes Berg committed
33
34
35
36
37
38
#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
#define IEEE80211_AUTH_MAX_TRIES 3
#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
#define IEEE80211_ASSOC_MAX_TRIES 3

39
40
41
42
43
44
45
46
47
static int max_nullfunc_tries = 2;
module_param(max_nullfunc_tries, int, 0644);
MODULE_PARM_DESC(max_nullfunc_tries,
		 "Maximum nullfunc tx tries before disconnecting (reason 4).");

static int max_probe_tries = 5;
module_param(max_probe_tries, int, 0644);
MODULE_PARM_DESC(max_probe_tries,
		 "Maximum probe tries before disconnecting (reason 4).");
48
49

/*
50
51
52
53
54
55
 * Beacon loss timeout is calculated as N frames times the
 * advertised beacon interval.  This may need to be somewhat
 * higher than what hardware might detect to account for
 * delays in the host processing frames. But since we also
 * probe on beacon miss before declaring the connection lost
 * default to what we want.
56
 */
57
58
#define IEEE80211_BEACON_LOSS_COUNT	7

59
60
61
62
/*
 * Time the connection can be idle before we probe
 * it to see if we can still talk to the AP.
 */
63
#define IEEE80211_CONNECTION_IDLE_TIME	(30 * HZ)
64
65
66
67
68
/*
 * Time we wait for a probe response after sending
 * a probe request because of beacon loss or for
 * checking the connection still works.
 */
69
70
71
72
73
static int probe_wait_ms = 500;
module_param(probe_wait_ms, int, 0644);
MODULE_PARM_DESC(probe_wait_ms,
		 "Maximum time(ms) to wait for probe response"
		 " before disconnecting (reason 4).");
74

75
76
77
78
79
80
81
/*
 * Weight given to the latest Beacon frame when calculating average signal
 * strength for Beacon frames received in the current BSS. This must be
 * between 1 and 15.
 */
#define IEEE80211_SIGNAL_AVE_WEIGHT	3

82
83
84
85
86
87
/*
 * How many Beacon frames need to have been used in average signal strength
 * before starting to indicate signal change events.
 */
#define IEEE80211_SIGNAL_AVE_MIN_COUNT	4

88
89
90
#define TMR_RUNNING_TIMER	0
#define TMR_RUNNING_CHANSW	1

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
 * 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_deauth() */
	RX_MGMT_CFG80211_DEAUTH,

	/* caller must call cfg80211_send_disassoc() */
	RX_MGMT_CFG80211_DISASSOC,
Johannes Berg's avatar
Johannes Berg committed
106
107
108
109
110
111
112
113
114

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

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

	/* caller must call cfg80211_send_assoc_timeout() */
	RX_MGMT_CFG80211_ASSOC_TIMEOUT,
115
116
};

117
/* utils */
118
119
static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
{
120
	lockdep_assert_held(&ifmgd->mtx);
121
122
}

Johannes Berg's avatar
Johannes Berg committed
123
124
125
126
127
128
129
130
131
132
/*
 * 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.
 */
Johannes Berg's avatar
Johannes Berg committed
133
static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
Johannes Berg's avatar
Johannes Berg committed
134
135
136
137
138
139
140
141
{
	ASSERT_MGD_MTX(ifmgd);

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

142
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
143
{
144
	if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
145
146
		return;

147
148
149
	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
		return;

150
	mod_timer(&sdata->u.mgd.bcn_mon_timer,
151
		  round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
152
153
}

154
155
void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
{
156
157
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;

158
159
160
	if (unlikely(!sdata->u.mgd.associated))
		return;

161
162
163
164
165
	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
		return;

	mod_timer(&sdata->u.mgd.conn_mon_timer,
		  round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
166
167

	ifmgd->probe_send_count = 0;
168
169
}

170
static int ecw2cw(int ecw)
Johannes Berg's avatar
Johannes Berg committed
171
{
172
	return (1 << ecw) - 1;
Johannes Berg's avatar
Johannes Berg committed
173
174
}

175
176
177
static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
				  struct ieee80211_ht_operation *ht_oper,
				  const u8 *bssid, bool reconfig)
178
179
180
181
182
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_supported_band *sband;
	struct sta_info *sta;
	u32 changed = 0;
183
	u16 ht_opmode;
184
	bool disable_40 = false;
185

186
	sband = local->hw.wiphy->bands[local->oper_channel->band];
187

188
189
	switch (sdata->vif.bss_conf.channel_type) {
	case NL80211_CHAN_HT40PLUS:
190
		if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
191
192
193
			disable_40 = true;
		break;
	case NL80211_CHAN_HT40MINUS:
194
		if (local->oper_channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
195
196
197
198
199
			disable_40 = true;
		break;
	default:
		break;
	}
200

201
202
	/* This can change during the lifetime of the BSS */
	if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
203
204
205
206
		disable_40 = true;

	mutex_lock(&local->sta_mtx);
	sta = sta_info_get(sdata, bssid);
207

208
209
210
211
212
213
	WARN_ON_ONCE(!sta);

	if (sta && !sta->supports_40mhz)
		disable_40 = true;

	if (sta && (!reconfig ||
214
		    (disable_40 != !(sta->sta.ht_cap.cap &
215
					IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
216

217
218
219
220
		if (disable_40)
			sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		else
			sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
221

222
		rate_control_rate_update(local, sband, sta,
223
					 IEEE80211_RC_BW_CHANGED);
224
	}
225
	mutex_unlock(&local->sta_mtx);
226

227
	ht_opmode = le16_to_cpu(ht_oper->operation_mode);
228
229

	/* if bss configuration changed store the new one */
230
	if (!reconfig || (sdata->vif.bss_conf.ht_operation_mode != ht_opmode)) {
231
		changed |= BSS_CHANGED_HT;
232
		sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
233
234
235
236
237
	}

	return changed;
}

238
239
/* frame sending functions */

Johannes Berg's avatar
Johannes Berg committed
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len,
				      struct ieee80211_supported_band *sband,
				      u32 *rates)
{
	int i, j, count;
	*rates = 0;
	count = 0;
	for (i = 0; i < supp_rates_len; i++) {
		int rate = (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;
}

static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
262
				struct sk_buff *skb, u8 ap_ht_param,
Johannes Berg's avatar
Johannes Berg committed
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
				struct ieee80211_supported_band *sband,
				struct ieee80211_channel *channel,
				enum ieee80211_smps_mode smps)
{
	u8 *pos;
	u32 flags = channel->flags;
	u16 cap;
	struct ieee80211_sta_ht_cap ht_cap;

	BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));

	memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
	ieee80211_apply_htcap_overrides(sdata, &ht_cap);

	/* determine capability flags */
	cap = ht_cap.cap;

280
	switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
Johannes Berg's avatar
Johannes Berg committed
281
282
283
284
285
286
287
288
289
290
291
292
293
294
	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
		if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			cap &= ~IEEE80211_HT_CAP_SGI_40;
		}
		break;
	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
		if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
			cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
			cap &= ~IEEE80211_HT_CAP_SGI_40;
		}
		break;
	}

295
296
297
298
299
300
301
302
303
304
	/*
	 * If 40 MHz was disabled associate as though we weren't
	 * capable of 40 MHz -- some broken APs will never fall
	 * back to trying to transmit in 20 MHz.
	 */
	if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_40MHZ) {
		cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
		cap &= ~IEEE80211_HT_CAP_SGI_40;
	}

Johannes Berg's avatar
Johannes Berg committed
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
	/* set SM PS mode properly */
	cap &= ~IEEE80211_HT_CAP_SM_PS;
	switch (smps) {
	case IEEE80211_SMPS_AUTOMATIC:
	case IEEE80211_SMPS_NUM_MODES:
		WARN_ON(1);
	case IEEE80211_SMPS_OFF:
		cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	case IEEE80211_SMPS_STATIC:
		cap |= WLAN_HT_CAP_SM_PS_STATIC <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	case IEEE80211_SMPS_DYNAMIC:
		cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
			IEEE80211_HT_CAP_SM_PS_SHIFT;
		break;
	}

	/* reserve and fill IE */
	pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
	ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
}

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
				 struct sk_buff *skb,
				 struct ieee80211_supported_band *sband)
{
	u8 *pos;
	u32 cap;
	struct ieee80211_sta_vht_cap vht_cap;

	BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));

	memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));

	/* determine capability flags */
	cap = vht_cap.cap;

	/* reserve and fill IE */
	pos = skb_put(skb, sizeof(struct ieee80211_vht_capabilities) + 2);
	ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
}

Johannes Berg's avatar
Johannes Berg committed
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
	u8 *pos, qos_info;
	size_t offset = 0, noffset;
	int i, count, rates_len, supp_rates_len;
	u16 capab;
	struct ieee80211_supported_band *sband;
	u32 rates = 0;

	lockdep_assert_held(&ifmgd->mtx);

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

	if (assoc_data->supp_rates_len) {
		/*
		 * 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(assoc_data->supp_rates,
						       assoc_data->supp_rates_len,
						       sband, &rates);
	} else {
		/*
		 * In case AP not provide any supported rates information
		 * before association, we send information element(s) with
		 * all rates that we support.
		 */
		rates = ~0;
		rates_len = sband->n_bitrates;
	}

	skb = alloc_skb(local->hw.extra_tx_headroom +
			sizeof(*mgmt) + /* bit too much but doesn't matter */
			2 + assoc_data->ssid_len + /* SSID */
			4 + rates_len + /* (extended) rates */
			4 + /* power capability */
			2 + 2 * sband->n_channels + /* supported channels */
			2 + sizeof(struct ieee80211_ht_cap) + /* HT */
395
			2 + sizeof(struct ieee80211_vht_capabilities) + /* VHT */
Johannes Berg's avatar
Johannes Berg committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
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
			assoc_data->ie_len + /* extra IEs */
			9, /* WMM */
			GFP_KERNEL);
	if (!skb)
		return;

	skb_reserve(skb, local->hw.extra_tx_headroom);

	capab = WLAN_CAPABILITY_ESS;

	if (sband->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;
	}

	if (assoc_data->capability & WLAN_CAPABILITY_PRIVACY)
		capab |= WLAN_CAPABILITY_PRIVACY;

	if ((assoc_data->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
	    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
	memset(mgmt, 0, 24);
	memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(mgmt->bssid, assoc_data->bss->bssid, ETH_ALEN);

	if (!is_zero_ether_addr(assoc_data->prev_bssid)) {
		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);
		memcpy(mgmt->u.reassoc_req.current_ap, assoc_data->prev_bssid,
		       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);
		mgmt->u.assoc_req.listen_interval =
				cpu_to_le16(local->hw.conf.listen_interval);
	}

	/* SSID */
	pos = skb_put(skb, 2 + assoc_data->ssid_len);
	*pos++ = WLAN_EID_SSID;
	*pos++ = assoc_data->ssid_len;
	memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);

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

	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->oper_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*/
		}
	}

	/* if present, add any custom IEs that go before HT */
	if (assoc_data->ie_len && assoc_data->ie) {
		static const u8 before_ht[] = {
			WLAN_EID_SSID,
			WLAN_EID_SUPP_RATES,
			WLAN_EID_EXT_SUPP_RATES,
			WLAN_EID_PWR_CAPABILITY,
			WLAN_EID_SUPPORTED_CHANNELS,
			WLAN_EID_RSN,
			WLAN_EID_QOS_CAPA,
			WLAN_EID_RRM_ENABLED_CAPABILITIES,
			WLAN_EID_MOBILITY_DOMAIN,
			WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
		};
		noffset = ieee80211_ie_split(assoc_data->ie, assoc_data->ie_len,
					     before_ht, ARRAY_SIZE(before_ht),
					     offset);
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

Johannes Berg's avatar
Johannes Berg committed
524
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
525
		ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
Johannes Berg's avatar
Johannes Berg committed
526
527
				    sband, local->oper_channel, ifmgd->ap_smps);

528
529
530
	if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
		ieee80211_add_vht_ie(sdata, skb, sband);

Johannes Berg's avatar
Johannes Berg committed
531
532
533
534
535
536
537
538
539
540
	/* if present, add any custom non-vendor IEs that go after HT */
	if (assoc_data->ie_len && assoc_data->ie) {
		noffset = ieee80211_ie_split_vendor(assoc_data->ie,
						    assoc_data->ie_len,
						    offset);
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
		offset = noffset;
	}

541
542
	if (assoc_data->wmm) {
		if (assoc_data->uapsd) {
543
544
			qos_info = ifmgd->uapsd_queues;
			qos_info |= (ifmgd->uapsd_max_sp_len <<
Johannes Berg's avatar
Johannes Berg committed
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
				     IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
		} else {
			qos_info = 0;
		}

		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++ = qos_info;
	}

	/* add any remaining custom (i.e. vendor specific here) IEs */
	if (assoc_data->ie_len && assoc_data->ie) {
		noffset = assoc_data->ie_len;
		pos = skb_put(skb, noffset - offset);
		memcpy(pos, assoc_data->ie + offset, noffset - offset);
	}

Johannes Berg's avatar
Johannes Berg committed
569
570
	drv_mgd_prepare_tx(local, sdata);

Johannes Berg's avatar
Johannes Berg committed
571
572
573
574
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
}

575
576
577
578
579
580
void ieee80211_send_pspoll(struct ieee80211_local *local,
			   struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_pspoll *pspoll;
	struct sk_buff *skb;

581
582
	skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
	if (!skb)
583
584
		return;

585
586
	pspoll = (struct ieee80211_pspoll *) skb->data;
	pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
587

588
589
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
590
591
}

592
593
594
595
596
void ieee80211_send_nullfunc(struct ieee80211_local *local,
			     struct ieee80211_sub_if_data *sdata,
			     int powersave)
{
	struct sk_buff *skb;
597
	struct ieee80211_hdr_3addr *nullfunc;
598
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
599

600
601
	skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
	if (!skb)
602
603
		return;

604
	nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
605
	if (powersave)
606
		nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
607

608
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
609
610
611
612
	if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
			    IEEE80211_STA_CONNECTION_POLL))
		IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;

613
	ieee80211_tx_skb(sdata, skb);
614
615
}

616
617
618
619
620
621
622
623
624
625
626
static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
					  struct ieee80211_sub_if_data *sdata)
{
	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 + 30);
627
	if (!skb)
628
		return;
629

630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
	skb_reserve(skb, local->hw.extra_tx_headroom);

	nullfunc = (struct ieee80211_hdr *) skb_put(skb, 30);
	memset(nullfunc, 0, 30);
	fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
			 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
	nullfunc->frame_control = fc;
	memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
	memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
	memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
	memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);

	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
}

646
647
648
649
650
651
652
/* 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;

653
	if (!ieee80211_sdata_running(sdata))
654
655
		return;

656
657
658
	mutex_lock(&ifmgd->mtx);
	if (!ifmgd->associated)
		goto out;
659
660

	sdata->local->oper_channel = sdata->local->csa_channel;
661
662
663
664
	if (!sdata->local->ops->channel_switch) {
		/* call "hw_config" only if doing sw channel switch */
		ieee80211_hw_config(sdata->local,
			IEEE80211_CONF_CHANGE_CHANNEL);
665
666
667
	} else {
		/* update the device channel directly */
		sdata->local->hw.conf.channel = sdata->local->oper_channel;
668
	}
669

670
	/* XXX: shouldn't really modify cfg80211-owned data! */
671
	ifmgd->associated->channel = sdata->local->oper_channel;
672

673
	/* XXX: wait for a beacon first? */
674
675
	ieee80211_wake_queues_by_reason(&sdata->local->hw,
					IEEE80211_QUEUE_STOP_REASON_CSA);
676
677
678
 out:
	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
	mutex_unlock(&ifmgd->mtx);
679
680
}

681
682
683
684
685
686
687
688
689
690
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
{
	struct ieee80211_sub_if_data *sdata;
	struct ieee80211_if_managed *ifmgd;

	sdata = vif_to_sdata(vif);
	ifmgd = &sdata->u.mgd;

	trace_api_chswitch_done(sdata, success);
	if (!success) {
691
692
693
694
695
696
		sdata_info(sdata,
			   "driver channel switch failed, disconnecting\n");
		ieee80211_queue_work(&sdata->local->hw,
				     &ifmgd->csa_connection_drop_work);
	} else {
		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
697
698
699
700
	}
}
EXPORT_SYMBOL(ieee80211_chswitch_done);

701
702
703
704
705
706
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;

707
708
709
710
711
	if (sdata->local->quiescing) {
		set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
		return;
	}

712
	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
713
714
715
716
}

void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
				      struct ieee80211_channel_sw_ie *sw_elem,
717
718
				      struct ieee80211_bss *bss,
				      u64 timestamp)
719
{
720
721
	struct cfg80211_bss *cbss =
		container_of((void *)bss, struct cfg80211_bss, priv);
722
723
	struct ieee80211_channel *new_ch;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
724
725
	int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
						      cbss->channel->band);
726

727
728
729
	ASSERT_MGD_MTX(ifmgd);

	if (!ifmgd->associated)
730
731
		return;

732
	if (sdata->local->scanning)
733
734
735
736
737
738
739
740
741
		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);
742
743
744
745
746
747
	if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED) {
		sdata_info(sdata,
			   "AP %pM switches to unsupported channel (%d MHz), disconnecting\n",
			   ifmgd->associated->bssid, new_freq);
		ieee80211_queue_work(&sdata->local->hw,
				     &ifmgd->csa_connection_drop_work);
748
		return;
749
	}
750
751
752

	sdata->local->csa_channel = new_ch;

753
754
755
756
757
758
	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;

	if (sw_elem->mode)
		ieee80211_stop_queues_by_reason(&sdata->local->hw,
				IEEE80211_QUEUE_STOP_REASON_CSA);

759
760
	if (sdata->local->ops->channel_switch) {
		/* use driver's channel switch callback */
761
762
763
764
765
766
767
		struct ieee80211_channel_switch ch_switch = {
			.timestamp = timestamp,
			.block_tx = sw_elem->mode,
			.channel = new_ch,
			.count = sw_elem->count,
		};

768
769
770
771
772
		drv_channel_switch(sdata->local, &ch_switch);
		return;
	}

	/* channel switch handled in software */
773
	if (sw_elem->count <= 1)
774
		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
775
	else
776
		mod_timer(&ifmgd->chswitch_timer,
777
778
			  TU_TO_EXP_TIME(sw_elem->count *
					 cbss->beacon_interval));
779
780
781
}

static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
782
783
784
					struct ieee80211_channel *channel,
					const u8 *country_ie, u8 country_ie_len,
					const u8 *pwr_constr_elem)
785
{
786
787
788
789
	struct ieee80211_country_ie_triplet *triplet;
	int chan = ieee80211_frequency_to_channel(channel->center_freq);
	int i, chan_pwr, chan_increment, new_ap_level;
	bool have_chan_pwr = false;
790

791
792
	/* Invalid IE */
	if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
793
794
		return;

795
796
797
798
799
800
801
802
803
804
805
806
807
808
	triplet = (void *)(country_ie + 3);
	country_ie_len -= 3;

	switch (channel->band) {
	default:
		WARN_ON_ONCE(1);
		/* fall through */
	case IEEE80211_BAND_2GHZ:
	case IEEE80211_BAND_60GHZ:
		chan_increment = 1;
		break;
	case IEEE80211_BAND_5GHZ:
		chan_increment = 4;
		break;
809
	}
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846

	/* find channel */
	while (country_ie_len >= 3) {
		u8 first_channel = triplet->chans.first_channel;

		if (first_channel >= IEEE80211_COUNTRY_EXTENSION_ID)
			goto next;

		for (i = 0; i < triplet->chans.num_channels; i++) {
			if (first_channel + i * chan_increment == chan) {
				have_chan_pwr = true;
				chan_pwr = triplet->chans.max_power;
				break;
			}
		}
		if (have_chan_pwr)
			break;

 next:
		triplet++;
		country_ie_len -= 3;
	}

	if (!have_chan_pwr)
		return;

	new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);

	if (sdata->local->ap_power_level == new_ap_level)
		return;

	sdata_info(sdata,
		   "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
		   new_ap_level, chan_pwr, *pwr_constr_elem,
		   sdata->u.mgd.bssid);
	sdata->local->ap_power_level = new_ap_level;
	ieee80211_hw_config(sdata->local, 0);
847
848
}

849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_conf *conf = &local->hw.conf;

	WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
		!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
		(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));

	local->disable_dynamic_ps = false;
	conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
}
EXPORT_SYMBOL(ieee80211_enable_dyn_ps);

void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
{
	struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_conf *conf = &local->hw.conf;

	WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
		!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
		(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));

	local->disable_dynamic_ps = true;
	conf->dynamic_ps_timeout = 0;
	del_timer_sync(&local->dynamic_ps_timer);
	ieee80211_queue_work(&local->hw,
			     &local->dynamic_ps_enable_work);
}
EXPORT_SYMBOL(ieee80211_disable_dyn_ps);

882
883
884
885
886
887
/* 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
888
889
890
891
	/*
	 * If we are scanning right now then the parameters will
	 * take effect when scan finishes.
	 */
892
	if (local->scanning)
Johannes Berg's avatar
Johannes Berg committed
893
894
		return;

895
896
897
898
899
900
901
	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);
902

903
904
905
906
907
908
		if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
		    (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS))
			return;

		conf->flags |= IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
	}
}

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);
	}
}

926
927
928
929
static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
{
	struct ieee80211_if_managed *mgd = &sdata->u.mgd;
	struct sta_info *sta = NULL;
930
	bool authorized = false;
931
932
933
934

	if (!mgd->powersave)
		return false;

935
936
937
	if (mgd->broken_ap)
		return false;

938
939
940
941
942
943
944
945
946
947
	if (!mgd->associated)
		return false;

	if (mgd->flags & (IEEE80211_STA_BEACON_POLL |
			  IEEE80211_STA_CONNECTION_POLL))
		return false;

	rcu_read_lock();
	sta = sta_info_get(sdata, mgd->bssid);
	if (sta)
948
		authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
949
950
	rcu_read_unlock();

951
	return authorized;
952
953
}

954
/* need to hold RTNL or interface lock */
955
void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
956
957
958
{
	struct ieee80211_sub_if_data *sdata, *found = NULL;
	int count = 0;
959
	int timeout;
960
961
962
963
964
965
966

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

	list_for_each_entry(sdata, &local->interfaces, list) {
967
		if (!ieee80211_sdata_running(sdata))
968
			continue;
969
970
971
972
973
974
975
976
		if (sdata->vif.type == NL80211_IFTYPE_AP) {
			/* If an AP vif is found, then disable PS
			 * by setting the count to zero thereby setting
			 * ps_sdata to NULL.
			 */
			count = 0;
			break;
		}
977
978
979
980
981
982
		if (sdata->vif.type != NL80211_IFTYPE_STATION)
			continue;
		found = sdata;
		count++;
	}

983
	if (count == 1 && ieee80211_powersave_allowed(found)) {
984
		struct ieee80211_conf *conf = &local->hw.conf;
985
986
987
		s32 beaconint_us;

		if (latency < 0)
Mark Gross's avatar
Mark Gross committed
988
			latency = pm_qos_request(PM_QOS_NETWORK_LATENCY);
989
990
991
992

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

993
		timeout = local->dynamic_ps_forced_timeout;
994
995
		if (timeout < 0) {
			/*
996
997
			 * Go to full PSM if the user configures a very low
			 * latency requirement.
998
999
1000
			 * The 2000 second value is there for compatibility
			 * until the PM_QOS_NETWORK_LATENCY is configured
			 * with real values.
1001
			 */
1002
1003
			if (latency > (1900 * USEC_PER_MSEC) &&
			    latency != (2000 * USEC_PER_SEC))
1004
				timeout = 0;
1005
1006
			else
				timeout = 100;
1007
		}
1008
1009
1010
1011
		local->dynamic_ps_user_timeout = timeout;
		if (!local->disable_dynamic_ps)
			conf->dynamic_ps_timeout =
				local->dynamic_ps_user_timeout;
1012

1013
		if (beaconint_us > latency) {
1014
			local->ps_sdata = NULL;
1015
		} else {
1016
			struct ieee80211_bss *bss;
1017
			int maxslp = 1;
1018
			u8 dtimper;
1019

1020
1021
1022
1023
1024
1025
1026
			bss = (void *)found->u.mgd.associated->priv;
			dtimper = bss->dtim_period;

			/* If the TIM IE is invalid, pretend the value is 1 */
			if (!dtimper)
				dtimper = 1;
			else if (dtimper > 1)
1027
1028
1029
				maxslp = min_t(int, dtimper,
						    latency / beaconint_us);

1030
			local->hw.conf.max_sleep_period = maxslp;
1031
			local->hw.conf.ps_dtim_period = dtimper;
1032
			local->ps_sdata = found;
1033
		}
1034
	} else {
1035
		local->ps_sdata = NULL;
1036
	}
1037
1038
1039
1040

	ieee80211_change_ps(local);
}

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata)
{
	bool ps_allowed = ieee80211_powersave_allowed(sdata);

	if (sdata->vif.bss_conf.ps != ps_allowed) {
		sdata->vif.bss_conf.ps = ps_allowed;
		ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_PS);
	}
}

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
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;
1072
	struct ieee80211_if_managed *ifmgd;
1073
1074
	unsigned long flags;
	int q;
1075
1076
1077
1078
1079

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

1080
1081
	ifmgd = &sdata->u.mgd;

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

1085
1086
1087
1088
	if (!local->disable_dynamic_ps &&
	    local->hw.conf.dynamic_ps_timeout > 0) {
		/* don't enter PS if TX frames are pending */
		if (drv_tx_frames_pending(local)) {
1089
1090
1091
1092
1093
			mod_timer(&local->dynamic_ps_timer, jiffies +
				  msecs_to_jiffies(
				  local->hw.conf.dynamic_ps_timeout));
			return;
		}
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111

		/*
		 * transmission can be stopped by others which leads to
		 * dynamic_ps_timer expiry. Postpone the ps timer if it
		 * is not the actual idle state.
		 */
		spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
		for (q = 0; q < local->hw.queues; q++) {
			if (local->queue_stop_reasons[q]) {
				spin_unlock_irqrestore(&local->queue_stop_reason_lock,
						       flags);
				mod_timer(&local->dynamic_ps_timer, jiffies +
					  msecs_to_jiffies(
					  local->hw.conf.dynamic_ps_timeout));
				return;
			}
		}
		spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1112
1113
	}

1114
	if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
1115
	    !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
1116
		netif_tx_stop_all_queues(sdata->dev);
1117

1118
1119
1120
1121
1122
1123
1124
1125
1126
		if (drv_tx_frames_pending(local))
			mod_timer(&local->dynamic_ps_timer, jiffies +
				  msecs_to_jiffies(
				  local->hw.conf.dynamic_ps_timeout));
		else {
			ieee80211_send_nullfunc(local, sdata, 1);
			/* Flush to get the tx status of nullfunc frame */
			drv_flush(local, false);
		}
1127
1128
	}

1129
1130
	if (!((local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) &&
	      (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) ||
1131
1132
1133
1134
1135
	    (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
		ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
		local->hw.conf.flags |= IEEE80211_CONF_PS;
		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
	}
1136

1137
1138
	if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
		netif_tx_wake_all_queues(sdata->dev);
1139
1140
1141
1142
1143
1144
}

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

1145
	if (local->quiescing || local->suspended)
1146
1147
		return;

1148
	ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
1149
1150
}

Johannes Berg's avatar
Johannes Berg committed
1151
/* MLME */
1152
static bool ieee80211_sta_wmm_params(struct ieee80211_local *local,
1153
				     struct ieee80211_sub_if_data *sdata,
1154
1155
1156
				     u8 *wmm_param, size_t wmm_param_len)
{
	struct ieee80211_tx_queue_params params;
1157
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1158
1159
	size_t left;
	int count;
1160
	u8 *pos, uapsd_queues = 0;
1161

1162
	if (!local->ops->conf_tx)
1163
		return false;
1164

1165
	if (local->hw.queues < IEEE80211_NUM_ACS)
1166
		return false;
1167
1168

	if (!wmm_param)
1169
		return false;
1170

1171
	if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
1172
		return false;
1173
1174

	if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
1175
		uapsd_queues = ifmgd->uapsd_queues;
1176

1177
	count = wmm_param[6] & 0x0f;
1178
	if (count == ifmgd->wmm_last_param_set)
1179
		return false;
1180
	ifmgd->wmm_last_param_set = count;
1181
1182
1183
1184
1185
1186

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

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

1187
	sdata->wmm_acm = 0;
1188
1189
1190
	for (; left >= 4; left -= 4, pos += 4) {
		int aci = (pos[0] >> 5) & 0x03;
		int acm = (pos[0] >> 4) & 0x01;
1191
		bool uapsd = false;
1192
1193
1194
		int queue;

		switch (aci) {
1195
		case 1: /* AC_BK */
Johannes Berg's avatar
Johannes Berg committed
1196
			queue = 3;
Johannes Berg's avatar
Johannes Berg committed
1197
			if (acm)
1198
				sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
1199
1200
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
				uapsd = true;
1201
			break;
1202
		case 2: /* AC_VI */
Johannes Berg's avatar
Johannes Berg committed
1203
			queue = 1;
Johannes Berg's avatar
Johannes Berg committed
1204
			if (acm)
1205
				sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
1206
1207
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
				uapsd = true;
1208
			break;
1209
		case 3: /* AC_VO */
Johannes Berg's avatar
Johannes Berg committed
1210
			queue = 0;
Johannes Berg's avatar
Johannes Berg committed
1211
			if (acm)
1212
				sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
1213
1214
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
				uapsd = true;
1215
			break;
1216
		case 0: /* AC_BE */
1217
		default:
Johannes Berg's avatar
Johannes Berg committed
1218
			queue = 2;
Johannes Berg's avatar
Johannes Berg committed
1219
			if (acm)
1220
				sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
1221
1222
			if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
				uapsd = true;
1223
1224
1225
1226
1227
1228
			break;
		}

		params.aifs = pos[0] & 0x0f;
		params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
		params.cw_min = ecw2cw(pos[1] & 0x0f);
1229
		params.txop = get_unaligned_le16(pos + 2);
1230
1231
		params.uapsd = uapsd;

Johannes Berg's avatar
Johannes Berg committed
1232
1233
1234
1235
1236
		mlme_dbg(sdata,
			 "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
			 queue, aci, acm,
			 params.aifs, params.cw_min, params.cw_max,
			 params.txop, params.uapsd);
1237
1238
		sdata->tx_conf[queue] = params;
		if (drv_conf_tx(local, sdata, queue, &params))
Johannes Berg's avatar
Johannes Berg committed
1239
1240
1241
			sdata_err(sdata,
				  "failed to set TX queue parameters for queue %d\n",
				  queue);
1242
	}
1243
1244

	/* enable WMM or activate new settings */
1245
	sdata->vif.bss_conf.qos = true;
1246
	return true;
1247
1248
}

1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
{
	lockdep_assert_held(&sdata->local->mtx);

	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
				IEEE80211_STA_BEACON_POLL);
	ieee80211_run_deferred_scan(sdata->local);
}

static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
{
	mutex_lock(&sdata->local->mtx);
	__ieee80211_stop_poll(sdata);
	mutex_unlock(&sdata->local->mtx);
}

1265
1266
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
					   u16 capab, bool erp_valid, u8 erp)
1267
{
1268
	struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
1269
	u32 changed = 0;
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
	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);
1283
	if (sdata->local->oper_channel->band == IEEE80211_BAND_5GHZ)
1284
		use_short_slot = true;
1285

1286
1287
1288
	if (use_protection != bss_conf->use_cts_prot) {
		bss_conf->use_cts_prot = use_protection;
		changed |= BSS_CHANGED_ERP_CTS_PROT;
1289
	}
1290

1291
1292
	if (use_short_preamble != bss_conf->use_short_preamble)