util.c 46.9 KB
Newer Older
Johannes Berg's avatar
Johannes Berg committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright 2002-2005, Instant802 Networks, Inc.
 * Copyright 2005-2006, Devicescape Software, Inc.
 * Copyright 2006-2007	Jiri Benc <jbenc@suse.cz>
 * Copyright 2007	Johannes Berg <johannes@sipsolutions.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.
 *
 * utilities for mac80211
 */

#include <net/mac80211.h>
#include <linux/netdevice.h>
16
#include <linux/export.h>
Johannes Berg's avatar
Johannes Berg committed
17
18
19
20
21
22
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/bitmap.h>
23
#include <linux/crc32.h>
24
#include <net/net_namespace.h>
Johannes Berg's avatar
Johannes Berg committed
25
#include <net/cfg80211.h>
26
#include <net/rtnetlink.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
#include "rate.h"
31
#include "mesh.h"
Johannes Berg's avatar
Johannes Berg committed
32
#include "wme.h"
33
#include "led.h"
Johannes Berg's avatar
Johannes Berg committed
34
#include "wep.h"
Johannes Berg's avatar
Johannes Berg committed
35
36
37
38

/* privid for wiphys to determine whether they belong to us or not */
void *mac80211_wiphy_privid = &mac80211_wiphy_privid;

39
40
41
42
43
44
45
46
47
struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
{
	struct ieee80211_local *local;
	BUG_ON(!wiphy);

	local = wiphy_priv(wiphy);
	return &local->hw;
}
EXPORT_SYMBOL(wiphy_to_ieee80211_hw);
Johannes Berg's avatar
Johannes Berg committed
48

49
u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
50
			enum nl80211_iftype type)
Johannes Berg's avatar
Johannes Berg committed
51
{
52
	__le16 fc = hdr->frame_control;
Johannes Berg's avatar
Johannes Berg committed
53

54
55
	 /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
	if (len < 16)
Johannes Berg's avatar
Johannes Berg committed
56
57
		return NULL;

58
	if (ieee80211_is_data(fc)) {
59
60
		if (len < 24) /* drop incorrect hdr len (data) */
			return NULL;
61
62

		if (ieee80211_has_a4(fc))
Johannes Berg's avatar
Johannes Berg committed
63
			return NULL;
64
65
66
		if (ieee80211_has_tods(fc))
			return hdr->addr1;
		if (ieee80211_has_fromds(fc))
Johannes Berg's avatar
Johannes Berg committed
67
			return hdr->addr2;
68
69
70
71
72

		return hdr->addr3;
	}

	if (ieee80211_is_mgmt(fc)) {
73
74
		if (len < 24) /* drop incorrect hdr len (mgmt) */
			return NULL;
Johannes Berg's avatar
Johannes Berg committed
75
		return hdr->addr3;
76
77
78
79
	}

	if (ieee80211_is_ctl(fc)) {
		if(ieee80211_is_pspoll(fc))
Johannes Berg's avatar
Johannes Berg committed
80
			return hdr->addr1;
81
82

		if (ieee80211_is_back_req(fc)) {
83
			switch (type) {
84
			case NL80211_IFTYPE_STATION:
85
				return hdr->addr2;
86
87
			case NL80211_IFTYPE_AP:
			case NL80211_IFTYPE_AP_VLAN:
88
89
				return hdr->addr1;
			default:
90
				break; /* fall through to the return */
91
92
			}
		}
Johannes Berg's avatar
Johannes Berg committed
93
94
95
96
97
	}

	return NULL;
}

98
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
Johannes Berg's avatar
Johannes Berg committed
99
{
100
	struct sk_buff *skb;
101
102
	struct ieee80211_hdr *hdr;

103
	skb_queue_walk(&tx->skbs, skb) {
104
105
		hdr = (struct ieee80211_hdr *) skb->data;
		hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
106
	}
Johannes Berg's avatar
Johannes Berg committed
107
108
}

109
int ieee80211_frame_duration(enum ieee80211_band band, size_t len,
Johannes Berg's avatar
Johannes Berg committed
110
111
112
113
114
115
116
117
118
119
120
121
122
			     int rate, int erp, int short_preamble)
{
	int dur;

	/* calculate duration (in microseconds, rounded up to next higher
	 * integer if it includes a fractional microsecond) to send frame of
	 * len bytes (does not include FCS) at the given rate. Duration will
	 * also include SIFS.
	 *
	 * rate is in 100 kbps, so divident is multiplied by 10 in the
	 * DIV_ROUND_UP() operations.
	 */

123
	if (band == IEEE80211_BAND_5GHZ || erp) {
Johannes Berg's avatar
Johannes Berg committed
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
		/*
		 * OFDM:
		 *
		 * N_DBPS = DATARATE x 4
		 * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
		 *	(16 = SIGNAL time, 6 = tail bits)
		 * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
		 *
		 * T_SYM = 4 usec
		 * 802.11a - 17.5.2: aSIFSTime = 16 usec
		 * 802.11g - 19.8.4: aSIFSTime = 10 usec +
		 *	signal ext = 6 usec
		 */
		dur = 16; /* SIFS + signal ext */
		dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */
		dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */
		dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
					4 * rate); /* T_SYM x N_SYM */
	} else {
		/*
		 * 802.11b or 802.11g with 802.11b compatibility:
		 * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
		 * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.
		 *
		 * 802.11 (DS): 15.3.3, 802.11b: 18.3.4
		 * aSIFSTime = 10 usec
		 * aPreambleLength = 144 usec or 72 usec with short preamble
		 * aPLCPHeaderLength = 48 usec or 24 usec with short preamble
		 */
		dur = 10; /* aSIFSTime = 10 usec */
		dur += short_preamble ? (72 + 24) : (144 + 48);

		dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
	}

	return dur;
}

/* Exported duration function for driver use */
163
164
__le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
					struct ieee80211_vif *vif,
165
					enum ieee80211_band band,
166
167
					size_t frame_len,
					struct ieee80211_rate *rate)
Johannes Berg's avatar
Johannes Berg committed
168
{
169
	struct ieee80211_sub_if_data *sdata;
Johannes Berg's avatar
Johannes Berg committed
170
171
	u16 dur;
	int erp;
172
	bool short_preamble = false;
Johannes Berg's avatar
Johannes Berg committed
173

174
	erp = 0;
175
176
	if (vif) {
		sdata = vif_to_sdata(vif);
177
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
178
179
180
		if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}
181

182
	dur = ieee80211_frame_duration(band, frame_len, rate->bitrate, erp,
183
				       short_preamble);
Johannes Berg's avatar
Johannes Berg committed
184
185
186
187
188

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_generic_frame_duration);

189
190
__le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
			      struct ieee80211_vif *vif, size_t frame_len,
191
			      const struct ieee80211_tx_info *frame_txctl)
Johannes Berg's avatar
Johannes Berg committed
192
193
194
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_rate *rate;
195
	struct ieee80211_sub_if_data *sdata;
196
	bool short_preamble;
Johannes Berg's avatar
Johannes Berg committed
197
198
	int erp;
	u16 dur;
199
200
	struct ieee80211_supported_band *sband;

201
	sband = local->hw.wiphy->bands[frame_txctl->band];
Johannes Berg's avatar
Johannes Berg committed
202

203
	short_preamble = false;
204

205
	rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
206
207

	erp = 0;
208
209
	if (vif) {
		sdata = vif_to_sdata(vif);
210
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
211
212
213
		if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}
Johannes Berg's avatar
Johannes Berg committed
214
215

	/* CTS duration */
216
	dur = ieee80211_frame_duration(sband->band, 10, rate->bitrate,
Johannes Berg's avatar
Johannes Berg committed
217
218
				       erp, short_preamble);
	/* Data frame duration */
219
	dur += ieee80211_frame_duration(sband->band, frame_len, rate->bitrate,
Johannes Berg's avatar
Johannes Berg committed
220
221
					erp, short_preamble);
	/* ACK duration */
222
	dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate,
Johannes Berg's avatar
Johannes Berg committed
223
224
225
226
227
228
					erp, short_preamble);

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_rts_duration);

229
230
__le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
				    struct ieee80211_vif *vif,
Johannes Berg's avatar
Johannes Berg committed
231
				    size_t frame_len,
232
				    const struct ieee80211_tx_info *frame_txctl)
Johannes Berg's avatar
Johannes Berg committed
233
234
235
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_rate *rate;
236
	struct ieee80211_sub_if_data *sdata;
237
	bool short_preamble;
Johannes Berg's avatar
Johannes Berg committed
238
239
	int erp;
	u16 dur;
240
241
	struct ieee80211_supported_band *sband;

242
	sband = local->hw.wiphy->bands[frame_txctl->band];
Johannes Berg's avatar
Johannes Berg committed
243

244
	short_preamble = false;
245

246
	rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
247
	erp = 0;
248
249
	if (vif) {
		sdata = vif_to_sdata(vif);
250
		short_preamble = sdata->vif.bss_conf.use_short_preamble;
251
252
253
		if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
			erp = rate->flags & IEEE80211_RATE_ERP_G;
	}
Johannes Berg's avatar
Johannes Berg committed
254
255

	/* Data frame duration */
256
	dur = ieee80211_frame_duration(sband->band, frame_len, rate->bitrate,
Johannes Berg's avatar
Johannes Berg committed
257
				       erp, short_preamble);
258
	if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
Johannes Berg's avatar
Johannes Berg committed
259
		/* ACK duration */
260
		dur += ieee80211_frame_duration(sband->band, 10, rate->bitrate,
Johannes Berg's avatar
Johannes Berg committed
261
262
263
264
265
266
267
						erp, short_preamble);
	}

	return cpu_to_le16(dur);
}
EXPORT_SYMBOL(ieee80211_ctstoself_duration);

268
269
270
void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue)
{
	struct ieee80211_sub_if_data *sdata;
271
272
273
274
	int n_acs = IEEE80211_NUM_ACS;

	if (local->hw.queues < IEEE80211_NUM_ACS)
		n_acs = 1;
275
276
277
278
279
280
281
282
283
284
285

	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
		int ac;

		if (test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
			continue;

		if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE &&
		    local->queue_stop_reasons[sdata->vif.cab_queue] != 0)
			continue;

286
		for (ac = 0; ac < n_acs; ac++) {
287
288
289
290
291
292
293
294
295
296
297
			int ac_queue = sdata->vif.hw_queue[ac];

			if (ac_queue == queue ||
			    (sdata->vif.cab_queue == queue &&
			     local->queue_stop_reasons[ac_queue] == 0 &&
			     skb_queue_empty(&local->pending[ac_queue])))
				netif_wake_subqueue(sdata->dev, ac);
		}
	}
}

298
299
static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason)
Johannes Berg's avatar
Johannes Berg committed
300
301
302
{
	struct ieee80211_local *local = hw_to_local(hw);

Johannes Berg's avatar
Johannes Berg committed
303
304
	trace_wake_queue(local, queue, reason);

305
306
	if (WARN_ON(queue >= hw->queues))
		return;
307

308
309
310
	if (!test_bit(reason, &local->queue_stop_reasons[queue]))
		return;

311
312
313
314
315
316
	__clear_bit(reason, &local->queue_stop_reasons[queue]);

	if (local->queue_stop_reasons[queue] != 0)
		/* someone still has this queue stopped */
		return;

317
318
	if (skb_queue_empty(&local->pending[queue])) {
		rcu_read_lock();
319
		ieee80211_propagate_queue_wake(local, queue);
320
321
		rcu_read_unlock();
	} else
Johannes Berg's avatar
Johannes Berg committed
322
		tasklet_schedule(&local->tx_pending_tasklet);
Johannes Berg's avatar
Johannes Berg committed
323
}
324

325
326
void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason)
327
328
329
330
331
332
333
334
335
336
337
338
339
340
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_wake_queue(hw, queue, reason);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
{
	ieee80211_wake_queue_by_reason(hw, queue,
				       IEEE80211_QUEUE_STOP_REASON_DRIVER);
}
Johannes Berg's avatar
Johannes Berg committed
341
342
EXPORT_SYMBOL(ieee80211_wake_queue);

343
344
static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
				   enum queue_stop_reason reason)
Johannes Berg's avatar
Johannes Berg committed
345
346
{
	struct ieee80211_local *local = hw_to_local(hw);
347
	struct ieee80211_sub_if_data *sdata;
348
	int n_acs = IEEE80211_NUM_ACS;
Johannes Berg's avatar
Johannes Berg committed
349

Johannes Berg's avatar
Johannes Berg committed
350
351
	trace_stop_queue(local, queue, reason);

352
353
	if (WARN_ON(queue >= hw->queues))
		return;
354

355
356
357
	if (test_bit(reason, &local->queue_stop_reasons[queue]))
		return;

358
	__set_bit(reason, &local->queue_stop_reasons[queue]);
359

360
361
362
	if (local->hw.queues < IEEE80211_NUM_ACS)
		n_acs = 1;

363
	rcu_read_lock();
364
365
366
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
		int ac;

367
		for (ac = 0; ac < n_acs; ac++) {
368
369
370
371
372
			if (sdata->vif.hw_queue[ac] == queue ||
			    sdata->vif.cab_queue == queue)
				netif_stop_subqueue(sdata->dev, ac);
		}
	}
373
	rcu_read_unlock();
Johannes Berg's avatar
Johannes Berg committed
374
}
375

376
377
void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
				    enum queue_stop_reason reason)
378
379
380
381
382
383
384
385
386
387
388
389
390
391
{
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_stop_queue(hw, queue, reason);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
{
	ieee80211_stop_queue_by_reason(hw, queue,
				       IEEE80211_QUEUE_STOP_REASON_DRIVER);
}
Johannes Berg's avatar
Johannes Berg committed
392
393
EXPORT_SYMBOL(ieee80211_stop_queue);

394
395
396
397
398
void ieee80211_add_pending_skb(struct ieee80211_local *local,
			       struct sk_buff *skb)
{
	struct ieee80211_hw *hw = &local->hw;
	unsigned long flags;
399
	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
400
	int queue = info->hw_queue;
401
402

	if (WARN_ON(!info->control.vif)) {
403
		kfree_skb(skb);
404
405
		return;
	}
406
407
408

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	__ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
Johannes Berg's avatar
Johannes Berg committed
409
	__skb_queue_tail(&local->pending[queue], skb);
410
411
412
413
	__ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

414
415
416
void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
				   struct sk_buff_head *skbs,
				   void (*fn)(void *data), void *data)
417
418
419
420
{
	struct ieee80211_hw *hw = &local->hw;
	struct sk_buff *skb;
	unsigned long flags;
421
	int queue, i;
422
423
424

	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	while ((skb = skb_dequeue(skbs))) {
425
426
427
		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

		if (WARN_ON(!info->control.vif)) {
428
			kfree_skb(skb);
429
430
431
			continue;
		}

432
		queue = info->hw_queue;
433
434
435
436

		__ieee80211_stop_queue(hw, queue,
				IEEE80211_QUEUE_STOP_REASON_SKB_ADD);

Johannes Berg's avatar
Johannes Berg committed
437
		__skb_queue_tail(&local->pending[queue], skb);
438
439
	}

440
441
442
	if (fn)
		fn(data);

Johannes Berg's avatar
Johannes Berg committed
443
	for (i = 0; i < hw->queues; i++)
444
445
446
447
448
		__ieee80211_wake_queue(hw, i,
			IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

449
450
void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
				    enum queue_stop_reason reason)
Johannes Berg's avatar
Johannes Berg committed
451
{
452
453
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;
Johannes Berg's avatar
Johannes Berg committed
454
455
	int i;

456
457
	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);

458
	for (i = 0; i < hw->queues; i++)
459
460
461
462
463
464
465
466
467
		__ieee80211_stop_queue(hw, i, reason);

	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_stop_queues(struct ieee80211_hw *hw)
{
	ieee80211_stop_queues_by_reason(hw,
					IEEE80211_QUEUE_STOP_REASON_DRIVER);
Johannes Berg's avatar
Johannes Berg committed
468
469
470
}
EXPORT_SYMBOL(ieee80211_stop_queues);

471
472
473
int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
{
	struct ieee80211_local *local = hw_to_local(hw);
Johannes Berg's avatar
Johannes Berg committed
474
475
	unsigned long flags;
	int ret;
476

477
478
	if (WARN_ON(queue >= hw->queues))
		return true;
479

Johannes Berg's avatar
Johannes Berg committed
480
481
482
483
	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
	ret = !!local->queue_stop_reasons[queue];
	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
	return ret;
484
485
486
}
EXPORT_SYMBOL(ieee80211_queue_stopped);

487
488
void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
				     enum queue_stop_reason reason)
Johannes Berg's avatar
Johannes Berg committed
489
{
490
491
	struct ieee80211_local *local = hw_to_local(hw);
	unsigned long flags;
Johannes Berg's avatar
Johannes Berg committed
492
493
	int i;

494
495
	spin_lock_irqsave(&local->queue_stop_reason_lock, flags);

496
	for (i = 0; i < hw->queues; i++)
497
498
499
500
501
502
503
504
		__ieee80211_wake_queue(hw, i, reason);

	spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
}

void ieee80211_wake_queues(struct ieee80211_hw *hw)
{
	ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
Johannes Berg's avatar
Johannes Berg committed
505
506
}
EXPORT_SYMBOL(ieee80211_wake_queues);
507

508
509
510
511
512
void ieee80211_iterate_active_interfaces(
	struct ieee80211_hw *hw,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
513
514
515
516
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_sub_if_data *sdata;

517
	mutex_lock(&local->iflist_mtx);
518
519
520

	list_for_each_entry(sdata, &local->interfaces, list) {
		switch (sdata->vif.type) {
521
522
		case NL80211_IFTYPE_MONITOR:
		case NL80211_IFTYPE_AP_VLAN:
523
			continue;
524
		default:
525
526
			break;
		}
527
		if (ieee80211_sdata_running(sdata))
528
			iterator(data, sdata->vif.addr,
529
530
531
				 &sdata->vif);
	}

532
533
534
535
536
	sdata = rcu_dereference_protected(local->monitor_sdata,
					  lockdep_is_held(&local->iflist_mtx));
	if (sdata)
		iterator(data, sdata->vif.addr, &sdata->vif);

537
	mutex_unlock(&local->iflist_mtx);
538
539
540
541
542
543
544
545
546
547
548
549
}
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);

void ieee80211_iterate_active_interfaces_atomic(
	struct ieee80211_hw *hw,
	void (*iterator)(void *data, u8 *mac,
			 struct ieee80211_vif *vif),
	void *data)
{
	struct ieee80211_local *local = hw_to_local(hw);
	struct ieee80211_sub_if_data *sdata;

550
	rcu_read_lock();
551

552
	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
553
		switch (sdata->vif.type) {
554
555
		case NL80211_IFTYPE_MONITOR:
		case NL80211_IFTYPE_AP_VLAN:
556
			continue;
557
		default:
558
559
			break;
		}
560
		if (ieee80211_sdata_running(sdata))
561
			iterator(data, sdata->vif.addr,
562
				 &sdata->vif);
563
	}
564

565
566
567
568
	sdata = rcu_dereference(local->monitor_sdata);
	if (sdata)
		iterator(data, sdata->vif.addr, &sdata->vif);

569
	rcu_read_unlock();
570
}
571
EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
572

573
574
575
576
577
578
579
580
581
/*
 * Nothing should have been stuffed into the workqueue during
 * the suspend->resume cycle. If this WARN is seen then there
 * is a bug with either the driver suspend or something in
 * mac80211 stuffing into the workqueue which we haven't yet
 * cleared during mac80211's suspend cycle.
 */
static bool ieee80211_can_queue_work(struct ieee80211_local *local)
{
Johannes Berg's avatar
Johannes Berg committed
582
583
584
	if (WARN(local->suspended && !local->resuming,
		 "queueing ieee80211 work while going to suspend\n"))
		return false;
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612

	return true;
}

void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
{
	struct ieee80211_local *local = hw_to_local(hw);

	if (!ieee80211_can_queue_work(local))
		return;

	queue_work(local->workqueue, work);
}
EXPORT_SYMBOL(ieee80211_queue_work);

void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
				  struct delayed_work *dwork,
				  unsigned long delay)
{
	struct ieee80211_local *local = hw_to_local(hw);

	if (!ieee80211_can_queue_work(local))
		return;

	queue_delayed_work(local->workqueue, dwork, delay);
}
EXPORT_SYMBOL(ieee80211_queue_delayed_work);

613
614
615
616
617
618
619
u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
			       struct ieee802_11_elems *elems,
			       u64 filter, u32 crc)
{
	size_t left = len;
	u8 *pos = start;
	bool calc_crc = filter != 0;
620
	DECLARE_BITMAP(seen_elems, 256);
621

622
	bitmap_zero(seen_elems, 256);
623
624
625
626
627
628
	memset(elems, 0, sizeof(*elems));
	elems->ie_start = start;
	elems->total_len = len;

	while (left >= 2) {
		u8 id, elen;
629
		bool elem_parse_failed;
630
631
632
633
634

		id = *pos++;
		elen = *pos++;
		left -= 2;

635
636
		if (elen > left) {
			elems->parse_error = true;
637
			break;
638
639
640
641
642
643
644
645
646
647
		}

		if (id != WLAN_EID_VENDOR_SPECIFIC &&
		    id != WLAN_EID_QUIET &&
		    test_bit(id, seen_elems)) {
			elems->parse_error = true;
			left -= elen;
			pos += elen;
			continue;
		}
648
649
650
651

		if (calc_crc && id < 64 && (filter & (1ULL << id)))
			crc = crc32_be(crc, pos - 2, elen + 2);

652
653
		elem_parse_failed = false;

654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
		switch (id) {
		case WLAN_EID_SSID:
			elems->ssid = pos;
			elems->ssid_len = elen;
			break;
		case WLAN_EID_SUPP_RATES:
			elems->supp_rates = pos;
			elems->supp_rates_len = elen;
			break;
		case WLAN_EID_FH_PARAMS:
			elems->fh_params = pos;
			elems->fh_params_len = elen;
			break;
		case WLAN_EID_DS_PARAMS:
			elems->ds_params = pos;
			elems->ds_params_len = elen;
			break;
		case WLAN_EID_CF_PARAMS:
			elems->cf_params = pos;
			elems->cf_params_len = elen;
			break;
		case WLAN_EID_TIM:
			if (elen >= sizeof(struct ieee80211_tim_ie)) {
				elems->tim = (void *)pos;
				elems->tim_len = elen;
679
680
			} else
				elem_parse_failed = true;
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
			break;
		case WLAN_EID_IBSS_PARAMS:
			elems->ibss_params = pos;
			elems->ibss_params_len = elen;
			break;
		case WLAN_EID_CHALLENGE:
			elems->challenge = pos;
			elems->challenge_len = elen;
			break;
		case WLAN_EID_VENDOR_SPECIFIC:
			if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
			    pos[2] == 0xf2) {
				/* Microsoft OUI (00:50:F2) */

				if (calc_crc)
					crc = crc32_be(crc, pos - 2, elen + 2);

				if (pos[3] == 1) {
					/* OUI Type 1 - WPA IE */
					elems->wpa = pos;
					elems->wpa_len = elen;
				} else if (elen >= 5 && pos[3] == 2) {
					/* OUI Type 2 - WMM IE */
					if (pos[4] == 0) {
						elems->wmm_info = pos;
						elems->wmm_info_len = elen;
					} else if (pos[4] == 1) {
						elems->wmm_param = pos;
						elems->wmm_param_len = elen;
					}
				}
			}
			break;
		case WLAN_EID_RSN:
			elems->rsn = pos;
			elems->rsn_len = elen;
			break;
		case WLAN_EID_ERP_INFO:
			elems->erp_info = pos;
			elems->erp_info_len = elen;
			break;
		case WLAN_EID_EXT_SUPP_RATES:
			elems->ext_supp_rates = pos;
			elems->ext_supp_rates_len = elen;
			break;
		case WLAN_EID_HT_CAPABILITY:
			if (elen >= sizeof(struct ieee80211_ht_cap))
				elems->ht_cap_elem = (void *)pos;
729
730
			else
				elem_parse_failed = true;
731
			break;
732
733
734
		case WLAN_EID_HT_OPERATION:
			if (elen >= sizeof(struct ieee80211_ht_operation))
				elems->ht_operation = (void *)pos;
735
736
			else
				elem_parse_failed = true;
737
738
739
740
741
742
743
744
			break;
		case WLAN_EID_MESH_ID:
			elems->mesh_id = pos;
			elems->mesh_id_len = elen;
			break;
		case WLAN_EID_MESH_CONFIG:
			if (elen >= sizeof(struct ieee80211_meshconf_ie))
				elems->mesh_config = (void *)pos;
745
746
			else
				elem_parse_failed = true;
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
			break;
		case WLAN_EID_PEER_MGMT:
			elems->peering = pos;
			elems->peering_len = elen;
			break;
		case WLAN_EID_PREQ:
			elems->preq = pos;
			elems->preq_len = elen;
			break;
		case WLAN_EID_PREP:
			elems->prep = pos;
			elems->prep_len = elen;
			break;
		case WLAN_EID_PERR:
			elems->perr = pos;
			elems->perr_len = elen;
			break;
		case WLAN_EID_RANN:
			if (elen >= sizeof(struct ieee80211_rann_ie))
				elems->rann = (void *)pos;
767
768
			else
				elem_parse_failed = true;
769
770
			break;
		case WLAN_EID_CHANNEL_SWITCH:
771
772
773
774
775
			if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
				elem_parse_failed = true;
				break;
			}
			elems->ch_switch_ie = (void *)pos;
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
			break;
		case WLAN_EID_QUIET:
			if (!elems->quiet_elem) {
				elems->quiet_elem = pos;
				elems->quiet_elem_len = elen;
			}
			elems->num_of_quiet_elem++;
			break;
		case WLAN_EID_COUNTRY:
			elems->country_elem = pos;
			elems->country_elem_len = elen;
			break;
		case WLAN_EID_PWR_CONSTRAINT:
			elems->pwr_constr_elem = pos;
			elems->pwr_constr_elem_len = elen;
			break;
		case WLAN_EID_TIMEOUT_INTERVAL:
			elems->timeout_int = pos;
			elems->timeout_int_len = elen;
			break;
		default:
			break;
		}

800
801
802
803
804
		if (elem_parse_failed)
			elems->parse_error = true;
		else
			set_bit(id, seen_elems);

805
806
807
808
		left -= elen;
		pos += elen;
	}

809
810
811
	if (left != 0)
		elems->parse_error = true;

812
813
814
	return crc;
}

815
816
void ieee802_11_parse_elems(u8 *start, size_t len,
			    struct ieee802_11_elems *elems)
817
818
819
820
{
	ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
}

821
822
void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata,
			       bool bss_notify)
823
824
825
{
	struct ieee80211_local *local = sdata->local;
	struct ieee80211_tx_queue_params qparam;
826
	int ac;
827
	bool use_11b, enable_qos;
828
	int aCWmin, aCWmax;
829
830
831
832

	if (!local->ops->conf_tx)
		return;

833
834
835
	if (local->hw.queues < IEEE80211_NUM_ACS)
		return;

836
837
	memset(&qparam, 0, sizeof(qparam));

838
	use_11b = (local->oper_channel->band == IEEE80211_BAND_2GHZ) &&
839
		 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
840

841
842
843
844
845
846
847
	/*
	 * By default disable QoS in STA mode for old access points, which do
	 * not support 802.11e. New APs will provide proper queue parameters,
	 * that we will configure later.
	 */
	enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION);

848
	for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
849
850
851
852
853
854
855
		/* Set defaults according to 802.11-2007 Table 7-37 */
		aCWmax = 1023;
		if (use_11b)
			aCWmin = 31;
		else
			aCWmin = 15;

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
882
883
884
885
886
887
888
889
890
891
892
		if (enable_qos) {
			switch (ac) {
			case IEEE80211_AC_BK:
				qparam.cw_max = aCWmax;
				qparam.cw_min = aCWmin;
				qparam.txop = 0;
				qparam.aifs = 7;
				break;
			/* never happens but let's not leave undefined */
			default:
			case IEEE80211_AC_BE:
				qparam.cw_max = aCWmax;
				qparam.cw_min = aCWmin;
				qparam.txop = 0;
				qparam.aifs = 3;
				break;
			case IEEE80211_AC_VI:
				qparam.cw_max = aCWmin;
				qparam.cw_min = (aCWmin + 1) / 2 - 1;
				if (use_11b)
					qparam.txop = 6016/32;
				else
					qparam.txop = 3008/32;
				qparam.aifs = 2;
				break;
			case IEEE80211_AC_VO:
				qparam.cw_max = (aCWmin + 1) / 2 - 1;
				qparam.cw_min = (aCWmin + 1) / 4 - 1;
				if (use_11b)
					qparam.txop = 3264/32;
				else
					qparam.txop = 1504/32;
				qparam.aifs = 2;
				break;
			}
		} else {
			/* Confiure old 802.11b/g medium access rules. */
893
894
			qparam.cw_max = aCWmax;
			qparam.cw_min = aCWmin;
895
896
897
			qparam.txop = 0;
			qparam.aifs = 2;
		}
898

899
900
		qparam.uapsd = false;

901
902
		sdata->tx_conf[ac] = qparam;
		drv_conf_tx(local, sdata, ac, &qparam);
903
	}
904

905
	if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {
906
		sdata->vif.bss_conf.qos = enable_qos;
907
908
909
		if (bss_notify)
			ieee80211_bss_info_change_notify(sdata,
							 BSS_CHANGED_QOS);
910
	}
911
}
912

913
914
915
916
917
918
919
920
921
922
923
924
void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
				  const size_t supp_rates_len,
				  const u8 *supp_rates)
{
	struct ieee80211_local *local = sdata->local;
	int i, have_higher_than_11mbit = 0;

	/* cf. IEEE 802.11 9.2.12 */
	for (i = 0; i < supp_rates_len; i++)
		if ((supp_rates[i] & 0x7f) * 5 > 110)
			have_higher_than_11mbit = 1;

925
	if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
926
927
928
929
930
	    have_higher_than_11mbit)
		sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
	else
		sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;

931
	ieee80211_set_wmm_default(sdata, true);
932
933
}

934
u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
935
936
937
938
			      enum ieee80211_band band)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_rate *bitrates;
939
	u32 mandatory_rates;
940
941
942
943
	enum ieee80211_rate_flags mandatory_flag;
	int i;

	sband = local->hw.wiphy->bands[band];
944
945
	if (WARN_ON(!sband))
		return 1;
946
947
948
949
950
951
952
953
954
955
956
957
958

	if (band == IEEE80211_BAND_2GHZ)
		mandatory_flag = IEEE80211_RATE_MANDATORY_B;
	else
		mandatory_flag = IEEE80211_RATE_MANDATORY_A;

	bitrates = sband->bitrates;
	mandatory_rates = 0;
	for (i = 0; i < sband->n_bitrates; i++)
		if (bitrates[i].flags & mandatory_flag)
			mandatory_rates |= BIT(i);
	return mandatory_rates;
}
959
960
961

void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
			 u16 transaction, u16 auth_alg,
962
963
			 u8 *extra, size_t extra_len, const u8 *da,
			 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx)
964
965
966
967
{
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_mgmt *mgmt;
Johannes Berg's avatar
Johannes Berg committed
968
	int err;
969
970

	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
971
			    sizeof(*mgmt) + 6 + extra_len);
972
	if (!skb)
973
		return;
974

975
976
977
978
979
980
	skb_reserve(skb, local->hw.extra_tx_headroom);

	mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
	memset(mgmt, 0, 24 + 6);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_AUTH);
981
	memcpy(mgmt->da, da, ETH_ALEN);
982
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
983
984
985
986
987
988
989
	memcpy(mgmt->bssid, bssid, ETH_ALEN);
	mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
	mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
	mgmt->u.auth.status_code = cpu_to_le16(0);
	if (extra)
		memcpy(skb_put(skb, extra_len), extra, extra_len);

Johannes Berg's avatar
Johannes Berg committed
990
991
992
993
994
995
	if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
		mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
		err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
		WARN_ON(err);
	}

996
997
	IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
	ieee80211_tx_skb(sdata, skb);
998
999
}

1000
int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
For faster browsing, not all history is shown. View entire blame