cfg.c 41.5 KB
Newer Older
1
2
3
/*
 * mac80211 configuration hooks for cfg80211
 *
4
 * Copyright 2006-2010	Johannes Berg <johannes@sipsolutions.net>
5
6
7
8
 *
 * This file is GPLv2 as found in COPYING.
 */

9
#include <linux/ieee80211.h>
10
11
#include <linux/nl80211.h>
#include <linux/rtnetlink.h>
12
#include <linux/slab.h>
13
#include <net/net_namespace.h>
14
#include <linux/rcupdate.h>
15
16
#include <net/cfg80211.h>
#include "ieee80211_i.h"
17
#include "driver-ops.h"
18
#include "cfg.h"
Johannes Berg's avatar
Johannes Berg committed
19
#include "rate.h"
20
21
#include "mesh.h"

22
static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
23
24
			       enum nl80211_iftype type, u32 *flags,
			       struct vif_params *params)
25
26
{
	struct ieee80211_local *local = wiphy_priv(wiphy);
27
28
29
	struct net_device *dev;
	struct ieee80211_sub_if_data *sdata;
	int err;
30

31
32
	err = ieee80211_if_add(local, name, &dev, type, params);
	if (err || type != NL80211_IFTYPE_MONITOR || !flags)
33
34
35
36
37
		return err;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
	sdata->u.mntr_flags = *flags;
	return 0;
38
39
}

40
static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
41
{
42
	ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev));
43

44
	return 0;
45
46
}

47
48
static int ieee80211_change_iface(struct wiphy *wiphy,
				  struct net_device *dev,
49
50
				  enum nl80211_iftype type, u32 *flags,
				  struct vif_params *params)
51
{
52
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
53
	int ret;
54

55
	ret = ieee80211_if_change_type(sdata, type);
56
57
	if (ret)
		return ret;
58

Johannes Berg's avatar
Johannes Berg committed
59
	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
60
61
62
		ieee80211_sdata_set_mesh_id(sdata,
					    params->mesh_id_len,
					    params->mesh_id);
63

64
65
66
67
68
69
70
	if (type == NL80211_IFTYPE_AP_VLAN &&
	    params && params->use_4addr == 0)
		rcu_assign_pointer(sdata->u.vlan.sta, NULL);
	else if (type == NL80211_IFTYPE_STATION &&
		 params && params->use_4addr >= 0)
		sdata->u.mgd.use_4addr = params->use_4addr;

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
	if (sdata->vif.type == NL80211_IFTYPE_MONITOR && flags) {
		struct ieee80211_local *local = sdata->local;

		if (ieee80211_sdata_running(sdata)) {
			/*
			 * Prohibit MONITOR_FLAG_COOK_FRAMES to be
			 * changed while the interface is up.
			 * Else we would need to add a lot of cruft
			 * to update everything:
			 *	cooked_mntrs, monitor and all fif_* counters
			 *	reconfigure hardware
			 */
			if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
			    (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
				return -EBUSY;

			ieee80211_adjust_monitor_flags(sdata, -1);
			sdata->u.mntr_flags = *flags;
			ieee80211_adjust_monitor_flags(sdata, 1);

			ieee80211_configure_filter(local);
		} else {
			/*
			 * Because the interface is down, ieee80211_do_stop
			 * and ieee80211_do_open take care of "everything"
			 * mentioned in the comment above.
			 */
			sdata->u.mntr_flags = *flags;
		}
	}
101

102
103
104
	return 0;
}

105
static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
106
			     u8 key_idx, bool pairwise, const u8 *mac_addr,
107
108
			     struct key_params *params)
{
109
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
110
	struct sta_info *sta = NULL;
111
	struct ieee80211_key *key;
112
	int err;
113

114
	if (!ieee80211_sdata_running(sdata))
Johannes Berg's avatar
Johannes Berg committed
115
116
		return -ENETDOWN;

117
	/* reject WEP and TKIP keys if WEP failed to initialize */
118
119
120
	switch (params->cipher) {
	case WLAN_CIPHER_SUITE_WEP40:
	case WLAN_CIPHER_SUITE_TKIP:
121
122
123
	case WLAN_CIPHER_SUITE_WEP104:
		if (IS_ERR(sdata->local->wep_tx_tfm))
			return -EINVAL;
124
		break;
125
	default:
126
		break;
127
128
	}

129
130
	key = ieee80211_key_alloc(params->cipher, key_idx, params->key_len,
				  params->key, params->seq_len, params->seq);
131
132
	if (IS_ERR(key))
		return PTR_ERR(key);
133

134
135
136
	if (pairwise)
		key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;

Johannes Berg's avatar
Johannes Berg committed
137
	mutex_lock(&sdata->local->sta_mtx);
138

139
	if (mac_addr) {
140
		sta = sta_info_get_bss(sdata, mac_addr);
141
		if (!sta) {
142
			ieee80211_key_free(sdata->local, key);
143
144
			err = -ENOENT;
			goto out_unlock;
145
		}
146
147
	}

148
149
150
	err = ieee80211_key_link(key, sdata, sta);
	if (err)
		ieee80211_key_free(sdata->local, key);
151

152
 out_unlock:
Johannes Berg's avatar
Johannes Berg committed
153
	mutex_unlock(&sdata->local->sta_mtx);
154
155

	return err;
156
157
158
}

static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
159
			     u8 key_idx, bool pairwise, const u8 *mac_addr)
160
161
162
163
164
165
166
{
	struct ieee80211_sub_if_data *sdata;
	struct sta_info *sta;
	int ret;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

Johannes Berg's avatar
Johannes Berg committed
167
	mutex_lock(&sdata->local->sta_mtx);
168

169
	if (mac_addr) {
170
171
		ret = -ENOENT;

172
		sta = sta_info_get_bss(sdata, mac_addr);
173
		if (!sta)
174
			goto out_unlock;
175

176
177
178
179
180
181
182
183
184
185
186
		if (pairwise) {
			if (sta->ptk) {
				ieee80211_key_free(sdata->local, sta->ptk);
				ret = 0;
			}
		} else {
			if (sta->gtk[key_idx]) {
				ieee80211_key_free(sdata->local,
						   sta->gtk[key_idx]);
				ret = 0;
			}
187
		}
188

189
		goto out_unlock;
190
191
	}

192
193
194
195
	if (!sdata->keys[key_idx]) {
		ret = -ENOENT;
		goto out_unlock;
	}
196

197
	ieee80211_key_free(sdata->local, sdata->keys[key_idx]);
198
	WARN_ON(sdata->keys[key_idx]);
199

200
201
	ret = 0;
 out_unlock:
Johannes Berg's avatar
Johannes Berg committed
202
	mutex_unlock(&sdata->local->sta_mtx);
203
204

	return ret;
205
206
}

207
static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
208
209
			     u8 key_idx, bool pairwise, const u8 *mac_addr,
			     void *cookie,
210
211
212
			     void (*callback)(void *cookie,
					      struct key_params *params))
{
213
	struct ieee80211_sub_if_data *sdata;
214
215
216
	struct sta_info *sta = NULL;
	u8 seq[6] = {0};
	struct key_params params;
217
	struct ieee80211_key *key = NULL;
218
219
220
221
	u32 iv32;
	u16 iv16;
	int err = -ENOENT;

222
223
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

224
225
	rcu_read_lock();

226
	if (mac_addr) {
227
		sta = sta_info_get_bss(sdata, mac_addr);
228
229
230
		if (!sta)
			goto out;

231
232
233
234
		if (pairwise)
			key = sta->ptk;
		else if (key_idx < NUM_DEFAULT_KEYS)
			key = sta->gtk[key_idx];
235
236
237
238
239
240
241
242
	} else
		key = sdata->keys[key_idx];

	if (!key)
		goto out;

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

243
	params.cipher = key->conf.cipher;
244

245
246
	switch (key->conf.cipher) {
	case WLAN_CIPHER_SUITE_TKIP:
247
248
		iv32 = key->u.tkip.tx.iv32;
		iv16 = key->u.tkip.tx.iv16;
249

250
251
252
253
		if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
			drv_get_tkip_seq(sdata->local,
					 key->conf.hw_key_idx,
					 &iv32, &iv16);
254
255
256
257
258
259
260
261
262
263

		seq[0] = iv16 & 0xff;
		seq[1] = (iv16 >> 8) & 0xff;
		seq[2] = iv32 & 0xff;
		seq[3] = (iv32 >> 8) & 0xff;
		seq[4] = (iv32 >> 16) & 0xff;
		seq[5] = (iv32 >> 24) & 0xff;
		params.seq = seq;
		params.seq_len = 6;
		break;
264
	case WLAN_CIPHER_SUITE_CCMP:
265
266
267
268
269
270
271
272
273
		seq[0] = key->u.ccmp.tx_pn[5];
		seq[1] = key->u.ccmp.tx_pn[4];
		seq[2] = key->u.ccmp.tx_pn[3];
		seq[3] = key->u.ccmp.tx_pn[2];
		seq[4] = key->u.ccmp.tx_pn[1];
		seq[5] = key->u.ccmp.tx_pn[0];
		params.seq = seq;
		params.seq_len = 6;
		break;
274
	case WLAN_CIPHER_SUITE_AES_CMAC:
275
276
277
278
279
280
281
282
283
		seq[0] = key->u.aes_cmac.tx_pn[5];
		seq[1] = key->u.aes_cmac.tx_pn[4];
		seq[2] = key->u.aes_cmac.tx_pn[3];
		seq[3] = key->u.aes_cmac.tx_pn[2];
		seq[4] = key->u.aes_cmac.tx_pn[1];
		seq[5] = key->u.aes_cmac.tx_pn[0];
		params.seq = seq;
		params.seq_len = 6;
		break;
284
285
286
287
288
289
290
291
292
	}

	params.key = key->conf.key;
	params.key_len = key->conf.keylen;

	callback(cookie, &params);
	err = 0;

 out:
293
	rcu_read_unlock();
294
295
296
	return err;
}

297
298
299
300
static int ieee80211_config_default_key(struct wiphy *wiphy,
					struct net_device *dev,
					u8 key_idx)
{
Johannes Berg's avatar
Johannes Berg committed
301
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
302

303
304
305
306
307
	ieee80211_set_default_key(sdata, key_idx);

	return 0;
}

308
309
310
311
static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
					     struct net_device *dev,
					     u8 key_idx)
{
312
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
313
314
315
316
317
318

	ieee80211_set_default_mgmt_key(sdata, key_idx);

	return 0;
}

319
320
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
{
321
	struct ieee80211_sub_if_data *sdata = sta->sdata;
322

323
324
	sinfo->generation = sdata->local->sta_generation;

325
326
	sinfo->filled = STATION_INFO_INACTIVE_TIME |
			STATION_INFO_RX_BYTES |
327
			STATION_INFO_TX_BYTES |
328
329
			STATION_INFO_RX_PACKETS |
			STATION_INFO_TX_PACKETS |
330
331
			STATION_INFO_TX_RETRIES |
			STATION_INFO_TX_FAILED |
332
			STATION_INFO_TX_BITRATE;
333
334
335
336

	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
	sinfo->rx_bytes = sta->rx_bytes;
	sinfo->tx_bytes = sta->tx_bytes;
337
338
	sinfo->rx_packets = sta->rx_packets;
	sinfo->tx_packets = sta->tx_packets;
339
340
	sinfo->tx_retries = sta->tx_retry_count;
	sinfo->tx_failed = sta->tx_retry_failed;
341

342
343
	if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
	    (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
		sinfo->filled |= STATION_INFO_SIGNAL;
		sinfo->signal = (s8)sta->last_signal;
	}

	sinfo->txrate.flags = 0;
	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
		sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
		sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;

	if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
		struct ieee80211_supported_band *sband;
		sband = sta->local->hw.wiphy->bands[
				sta->local->hw.conf.channel->band];
		sinfo->txrate.legacy =
			sband->bitrates[sta->last_tx_rate.idx].bitrate;
	} else
		sinfo->txrate.mcs = sta->last_tx_rate.idx;

Johannes Berg's avatar
Johannes Berg committed
365
	if (ieee80211_vif_is_mesh(&sdata->vif)) {
366
367
368
369
370
371
372
373
374
#ifdef CONFIG_MAC80211_MESH
		sinfo->filled |= STATION_INFO_LLID |
				 STATION_INFO_PLID |
				 STATION_INFO_PLINK_STATE;

		sinfo->llid = le16_to_cpu(sta->llid);
		sinfo->plid = le16_to_cpu(sta->plid);
		sinfo->plink_state = sta->plink_state;
#endif
Johannes Berg's avatar
Johannes Berg committed
375
	}
376
377
378
379
380
381
}


static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
				 int idx, u8 *mac, struct station_info *sinfo)
{
382
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
383
	struct sta_info *sta;
384
385
386
	int ret = -ENOENT;

	rcu_read_lock();
387

388
	sta = sta_info_get_by_idx(sdata, idx);
389
390
	if (sta) {
		ret = 0;
391
		memcpy(mac, sta->sta.addr, ETH_ALEN);
392
393
		sta_set_sinfo(sta, sinfo);
	}
394

395
	rcu_read_unlock();
396

397
	return ret;
398
399
}

400
401
402
403
404
405
406
407
static int ieee80211_dump_survey(struct wiphy *wiphy, struct net_device *dev,
				 int idx, struct survey_info *survey)
{
	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);

	return drv_get_survey(local, idx, survey);
}

408
static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
409
				 u8 *mac, struct station_info *sinfo)
410
{
411
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
412
	struct sta_info *sta;
413
	int ret = -ENOENT;
414

415
	rcu_read_lock();
416

417
	sta = sta_info_get_bss(sdata, mac);
418
419
420
421
422
423
424
425
	if (sta) {
		ret = 0;
		sta_set_sinfo(sta, sinfo);
	}

	rcu_read_unlock();

	return ret;
426
427
}

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
/*
 * This handles both adding a beacon and setting new beacon info
 */
static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
				   struct beacon_parameters *params)
{
	struct beacon_data *new, *old;
	int new_head_len, new_tail_len;
	int size;
	int err = -EINVAL;

	old = sdata->u.ap.beacon;

	/* head must not be zero-length */
	if (params->head && !params->head_len)
		return -EINVAL;

	/*
	 * This is a kludge. beacon interval should really be part
	 * of the beacon information.
	 */
449
450
451
452
453
	if (params->interval &&
	    (sdata->vif.bss_conf.beacon_int != params->interval)) {
		sdata->vif.bss_conf.beacon_int = params->interval;
		ieee80211_bss_info_change_notify(sdata,
						 BSS_CHANGED_BEACON_INT);
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
	}

	/* Need to have a beacon head if we don't have one yet */
	if (!params->head && !old)
		return err;

	/* sorry, no way to start beaconing without dtim period */
	if (!params->dtim_period && !old)
		return err;

	/* new or old head? */
	if (params->head)
		new_head_len = params->head_len;
	else
		new_head_len = old->head_len;

	/* new or old tail? */
	if (params->tail || !old)
		/* params->tail_len will be zero for !params->tail */
		new_tail_len = params->tail_len;
	else
		new_tail_len = old->tail_len;

	size = sizeof(*new) + new_head_len + new_tail_len;

	new = kzalloc(size, GFP_KERNEL);
	if (!new)
		return -ENOMEM;

	/* start filling the new info now */

	/* new or old dtim period? */
	if (params->dtim_period)
		new->dtim_period = params->dtim_period;
	else
		new->dtim_period = old->dtim_period;

	/*
	 * pointers go into the block we allocated,
	 * memory is | beacon_data | head | tail |
	 */
	new->head = ((u8 *) new) + sizeof(*new);
	new->tail = new->head + new_head_len;
	new->head_len = new_head_len;
	new->tail_len = new_tail_len;

	/* copy in head */
	if (params->head)
		memcpy(new->head, params->head, new_head_len);
	else
		memcpy(new->head, old->head, new_head_len);

	/* copy in optional tail */
	if (params->tail)
		memcpy(new->tail, params->tail, new_tail_len);
	else
		if (old)
			memcpy(new->tail, old->tail, new_tail_len);

513
514
	sdata->vif.bss_conf.dtim_period = new->dtim_period;

515
516
517
518
519
520
	rcu_assign_pointer(sdata->u.ap.beacon, new);

	synchronize_rcu();

	kfree(old);

521
522
523
	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
						BSS_CHANGED_BEACON);
	return 0;
524
525
526
527
528
}

static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
				struct beacon_parameters *params)
{
529
	struct ieee80211_sub_if_data *sdata;
530
531
	struct beacon_data *old;

532
533
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

534
535
536
537
538
539
540
541
542
543
544
	old = sdata->u.ap.beacon;

	if (old)
		return -EALREADY;

	return ieee80211_config_beacon(sdata, params);
}

static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
				struct beacon_parameters *params)
{
545
	struct ieee80211_sub_if_data *sdata;
546
547
	struct beacon_data *old;

548
549
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

550
551
552
553
554
555
556
557
558
559
	old = sdata->u.ap.beacon;

	if (!old)
		return -ENOENT;

	return ieee80211_config_beacon(sdata, params);
}

static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
{
560
	struct ieee80211_sub_if_data *sdata;
561
562
	struct beacon_data *old;

563
564
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

565
566
567
568
569
570
571
572
573
	old = sdata->u.ap.beacon;

	if (!old)
		return -ENOENT;

	rcu_assign_pointer(sdata->u.ap.beacon, NULL);
	synchronize_rcu();
	kfree(old);

574
575
	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
	return 0;
576
577
}

578
579
580
581
582
583
584
585
586
/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
struct iapp_layer2_update {
	u8 da[ETH_ALEN];	/* broadcast */
	u8 sa[ETH_ALEN];	/* STA addr */
	__be16 len;		/* 6 */
	u8 dsap;		/* 0 */
	u8 ssap;		/* 0 */
	u8 control;
	u8 xid_info[3];
Eric Dumazet's avatar
Eric Dumazet committed
587
} __packed;
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605

static void ieee80211_send_layer2_update(struct sta_info *sta)
{
	struct iapp_layer2_update *msg;
	struct sk_buff *skb;

	/* Send Level 2 Update Frame to update forwarding tables in layer 2
	 * bridge devices */

	skb = dev_alloc_skb(sizeof(*msg));
	if (!skb)
		return;
	msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));

	/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
	 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */

	memset(msg->da, 0xff, ETH_ALEN);
606
	memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
607
608
609
610
611
612
613
614
615
	msg->len = htons(6);
	msg->dsap = 0;
	msg->ssap = 0x01;	/* NULL LSAP, CR Bit: Response */
	msg->control = 0xaf;	/* XID response lsb.1111F101.
				 * F=0 (no poll command; unsolicited frame) */
	msg->xid_info[0] = 0x81;	/* XID format identifier */
	msg->xid_info[1] = 1;	/* LLC types/classes: Type 1 LLC */
	msg->xid_info[2] = 0;	/* XID sender's receive window size (RW) */

616
617
	skb->dev = sta->sdata->dev;
	skb->protocol = eth_type_trans(skb, sta->sdata->dev);
618
	memset(skb->cb, 0, sizeof(skb->cb));
619
	netif_rx_ni(skb);
620
621
622
623
624
625
}

static void sta_apply_parameters(struct ieee80211_local *local,
				 struct sta_info *sta,
				 struct station_parameters *params)
{
626
	unsigned long flags;
627
628
	u32 rates;
	int i, j;
629
	struct ieee80211_supported_band *sband;
630
	struct ieee80211_sub_if_data *sdata = sta->sdata;
631
	u32 mask, set;
632

Johannes Berg's avatar
Johannes Berg committed
633
634
	sband = local->hw.wiphy->bands[local->oper_channel->band];

635
	spin_lock_irqsave(&sta->flaglock, flags);
636
637
	mask = params->sta_flags_mask;
	set = params->sta_flags_set;
Johannes Berg's avatar
Johannes Berg committed
638

639
	if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
640
		sta->flags &= ~WLAN_STA_AUTHORIZED;
641
		if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
642
			sta->flags |= WLAN_STA_AUTHORIZED;
643
	}
644

645
	if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
646
		sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
647
		if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
648
			sta->flags |= WLAN_STA_SHORT_PREAMBLE;
649
	}
650

651
	if (mask & BIT(NL80211_STA_FLAG_WME)) {
652
		sta->flags &= ~WLAN_STA_WME;
653
		if (set & BIT(NL80211_STA_FLAG_WME))
654
			sta->flags |= WLAN_STA_WME;
655
	}
656

657
	if (mask & BIT(NL80211_STA_FLAG_MFP)) {
658
		sta->flags &= ~WLAN_STA_MFP;
659
		if (set & BIT(NL80211_STA_FLAG_MFP))
660
			sta->flags |= WLAN_STA_MFP;
661
	}
662
	spin_unlock_irqrestore(&sta->flaglock, flags);
663

664
665
666
667
668
669
670
	/*
	 * cfg80211 validates this (1-2007) and allows setting the AID
	 * only when creating a new station entry
	 */
	if (params->aid)
		sta->sta.aid = params->aid;

Johannes Berg's avatar
Johannes Berg committed
671
672
673
674
675
676
677
	/*
	 * FIXME: updating the following information is racy when this
	 *	  function is called from ieee80211_change_station().
	 *	  However, all this information should be static so
	 *	  maybe we should just reject attemps to change it.
	 */

678
679
680
681
682
	if (params->listen_interval >= 0)
		sta->listen_interval = params->listen_interval;

	if (params->supported_rates) {
		rates = 0;
683

684
685
		for (i = 0; i < params->supported_rates_len; i++) {
			int rate = (params->supported_rates[i] & 0x7f) * 5;
686
687
			for (j = 0; j < sband->n_bitrates; j++) {
				if (sband->bitrates[j].bitrate == rate)
688
689
690
					rates |= BIT(j);
			}
		}
691
		sta->sta.supp_rates[local->oper_channel->band] = rates;
692
	}
693

694
	if (params->ht_capa)
Johannes Berg's avatar
Johannes Berg committed
695
696
		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
						  params->ht_capa,
697
						  &sta->sta.ht_cap);
698

Johannes Berg's avatar
Johannes Berg committed
699
	if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
700
701
702
703
704
705
706
707
		switch (params->plink_action) {
		case PLINK_ACTION_OPEN:
			mesh_plink_open(sta);
			break;
		case PLINK_ACTION_BLOCK:
			mesh_plink_block(sta);
			break;
		}
Johannes Berg's avatar
Johannes Berg committed
708
	}
709
710
711
712
713
}

static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
				 u8 *mac, struct station_parameters *params)
{
714
	struct ieee80211_local *local = wiphy_priv(wiphy);
715
716
	struct sta_info *sta;
	struct ieee80211_sub_if_data *sdata;
Johannes Berg's avatar
Johannes Berg committed
717
	int err;
718
	int layer2_update;
719
720
721
722

	if (params->vlan) {
		sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);

723
724
		if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    sdata->vif.type != NL80211_IFTYPE_AP)
725
726
727
728
			return -EINVAL;
	} else
		sdata = IEEE80211_DEV_TO_SUB_IF(dev);

729
	if (compare_ether_addr(mac, sdata->vif.addr) == 0)
730
731
732
733
734
735
		return -EINVAL;

	if (is_multicast_ether_addr(mac))
		return -EINVAL;

	sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
Johannes Berg's avatar
Johannes Berg committed
736
737
	if (!sta)
		return -ENOMEM;
738
739
740
741
742

	sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;

	sta_apply_parameters(local, sta, params);

743
	rate_control_rate_init(sta);
744

745
746
747
	layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
		sdata->vif.type == NL80211_IFTYPE_AP;

748
	err = sta_info_insert_rcu(sta);
Johannes Berg's avatar
Johannes Berg committed
749
750
751
752
753
	if (err) {
		rcu_read_unlock();
		return err;
	}

754
	if (layer2_update)
Johannes Berg's avatar
Johannes Berg committed
755
756
757
758
		ieee80211_send_layer2_update(sta);

	rcu_read_unlock();

759
760
761
762
763
764
	return 0;
}

static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
				 u8 *mac)
{
765
766
	struct ieee80211_local *local = wiphy_priv(wiphy);
	struct ieee80211_sub_if_data *sdata;
767

768
769
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

770
771
	if (mac)
		return sta_info_destroy_addr_bss(sdata, mac);
772

773
	sta_info_flush(local, sdata);
774
775
776
777
778
779
780
781
	return 0;
}

static int ieee80211_change_station(struct wiphy *wiphy,
				    struct net_device *dev,
				    u8 *mac,
				    struct station_parameters *params)
{
782
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
783
	struct ieee80211_local *local = wiphy_priv(wiphy);
784
785
786
	struct sta_info *sta;
	struct ieee80211_sub_if_data *vlansdata;

Johannes Berg's avatar
Johannes Berg committed
787
788
	rcu_read_lock();

789
	sta = sta_info_get_bss(sdata, mac);
Johannes Berg's avatar
Johannes Berg committed
790
791
	if (!sta) {
		rcu_read_unlock();
792
		return -ENOENT;
Johannes Berg's avatar
Johannes Berg committed
793
	}
794

795
	if (params->vlan && params->vlan != sta->sdata->dev) {
796
797
		vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);

798
799
		if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
		    vlansdata->vif.type != NL80211_IFTYPE_AP) {
Johannes Berg's avatar
Johannes Berg committed
800
			rcu_read_unlock();
801
			return -EINVAL;
Johannes Berg's avatar
Johannes Berg committed
802
		}
803

804
		if (params->vlan->ieee80211_ptr->use_4addr) {
Johannes Berg's avatar
Johannes Berg committed
805
806
			if (vlansdata->u.vlan.sta) {
				rcu_read_unlock();
807
				return -EBUSY;
Johannes Berg's avatar
Johannes Berg committed
808
			}
809
810
811
812

			rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
		}

813
		sta->sdata = vlansdata;
814
815
816
817
818
		ieee80211_send_layer2_update(sta);
	}

	sta_apply_parameters(local, sta, params);

Johannes Berg's avatar
Johannes Berg committed
819
820
	rcu_read_unlock();

821
822
823
	return 0;
}

824
825
826
827
#ifdef CONFIG_MAC80211_MESH
static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
				 u8 *dst, u8 *next_hop)
{
828
	struct ieee80211_sub_if_data *sdata;
829
830
831
832
	struct mesh_path *mpath;
	struct sta_info *sta;
	int err;

833
834
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

835
	rcu_read_lock();
836
	sta = sta_info_get(sdata, next_hop);
837
838
	if (!sta) {
		rcu_read_unlock();
839
		return -ENOENT;
840
	}
841

842
	err = mesh_path_add(dst, sdata);
843
844
	if (err) {
		rcu_read_unlock();
845
		return err;
846
	}
847

848
	mpath = mesh_path_lookup(dst, sdata);
849
850
851
852
853
	if (!mpath) {
		rcu_read_unlock();
		return -ENXIO;
	}
	mesh_path_fix_nexthop(mpath, sta);
854

855
856
857
858
859
860
861
	rcu_read_unlock();
	return 0;
}

static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
				 u8 *dst)
{
862
863
	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);

864
	if (dst)
865
		return mesh_path_del(dst, sdata);
866

867
	mesh_path_flush(sdata);
868
869
870
871
872
873
874
	return 0;
}

static int ieee80211_change_mpath(struct wiphy *wiphy,
				    struct net_device *dev,
				    u8 *dst, u8 *next_hop)
{
875
	struct ieee80211_sub_if_data *sdata;
876
877
878
	struct mesh_path *mpath;
	struct sta_info *sta;

879
880
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

881
882
	rcu_read_lock();

883
	sta = sta_info_get(sdata, next_hop);
884
885
	if (!sta) {
		rcu_read_unlock();
886
		return -ENOENT;
887
	}
888

889
	mpath = mesh_path_lookup(dst, sdata);
890
891
892
893
894
895
	if (!mpath) {
		rcu_read_unlock();
		return -ENOENT;
	}

	mesh_path_fix_nexthop(mpath, sta);
896

897
898
899
900
901
902
903
904
	rcu_read_unlock();
	return 0;
}

static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
			    struct mpath_info *pinfo)
{
	if (mpath->next_hop)
905
		memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
906
907
908
	else
		memset(next_hop, 0, ETH_ALEN);

909
910
	pinfo->generation = mesh_paths_generation;

911
	pinfo->filled = MPATH_INFO_FRAME_QLEN |
912
			MPATH_INFO_SN |
913
914
915
916
917
918
919
			MPATH_INFO_METRIC |
			MPATH_INFO_EXPTIME |
			MPATH_INFO_DISCOVERY_TIMEOUT |
			MPATH_INFO_DISCOVERY_RETRIES |
			MPATH_INFO_FLAGS;

	pinfo->frame_qlen = mpath->frame_queue.qlen;
920
	pinfo->sn = mpath->sn;
921
922
923
924
925
926
927
928
929
930
931
	pinfo->metric = mpath->metric;
	if (time_before(jiffies, mpath->exp_time))
		pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
	pinfo->discovery_timeout =
			jiffies_to_msecs(mpath->discovery_timeout);
	pinfo->discovery_retries = mpath->discovery_retries;
	pinfo->flags = 0;
	if (mpath->flags & MESH_PATH_ACTIVE)
		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
	if (mpath->flags & MESH_PATH_RESOLVING)
		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
932
933
	if (mpath->flags & MESH_PATH_SN_VALID)
		pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
934
935
936
937
938
939
940
941
942
943
944
945
	if (mpath->flags & MESH_PATH_FIXED)
		pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
	if (mpath->flags & MESH_PATH_RESOLVING)
		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;

	pinfo->flags = mpath->flags;
}

static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
			       u8 *dst, u8 *next_hop, struct mpath_info *pinfo)

{
946
	struct ieee80211_sub_if_data *sdata;
947
948
	struct mesh_path *mpath;

949
950
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

951
	rcu_read_lock();
952
	mpath = mesh_path_lookup(dst, sdata);
953
954
955
956
957
958
959
960
961
962
963
964
965
966
	if (!mpath) {
		rcu_read_unlock();
		return -ENOENT;
	}
	memcpy(dst, mpath->dst, ETH_ALEN);
	mpath_set_pinfo(mpath, next_hop, pinfo);
	rcu_read_unlock();
	return 0;
}

static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
				 int idx, u8 *dst, u8 *next_hop,
				 struct mpath_info *pinfo)
{
967
	struct ieee80211_sub_if_data *sdata;
968
969
	struct mesh_path *mpath;

970
971
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

972
	rcu_read_lock();
973
	mpath = mesh_path_lookup_by_idx(idx, sdata);
974
975
976
977
978
979
980
981
982
	if (!mpath) {
		rcu_read_unlock();
		return -ENOENT;
	}
	memcpy(dst, mpath->dst, ETH_ALEN);
	mpath_set_pinfo(mpath, next_hop, pinfo);
	rcu_read_unlock();
	return 0;
}
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005

static int ieee80211_get_mesh_params(struct wiphy *wiphy,
				struct net_device *dev,
				struct mesh_config *conf)
{
	struct ieee80211_sub_if_data *sdata;
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
	return 0;
}

static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
{
	return (mask >> (parm-1)) & 0x1;
}

static int ieee80211_set_mesh_params(struct wiphy *wiphy,
				struct net_device *dev,
				const struct mesh_config *nconf, u32 mask)
{
	struct mesh_config *conf;
	struct ieee80211_sub_if_data *sdata;
1006
1007
	struct ieee80211_if_mesh *ifmsh;

1008
	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1009
	ifmsh = &sdata->u.mesh;
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043

	/* Set the config options which we are interested in setting */
	conf = &(sdata->u.mesh.mshcfg);
	if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
		conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
	if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
		conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
	if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
		conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
	if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
		conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
	if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
		conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
	if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
		conf->dot11MeshTTL = nconf->dot11MeshTTL;
	if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
		conf->auto_open_plinks = nconf->auto_open_plinks;
	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
		conf->dot11MeshHWMPmaxPREQretries =
			nconf->dot11MeshHWMPmaxPREQretries;
	if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
		conf->path_refresh_time = nconf->path_refresh_time;
	if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
		conf->min_discovery_timeout = nconf->min_discovery_timeout;
	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
		conf->dot11MeshHWMPactivePathTimeout =
			nconf->dot11MeshHWMPactivePathTimeout;
	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
		conf->dot11MeshHWMPpreqMinInterval =
			nconf->dot11MeshHWMPpreqMinInterval;
	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
			   mask))
		conf->dot11MeshHWMPnetDiameterTraversalTime =
			nconf->dot11MeshHWMPnetDiameterTraversalTime;
1044
1045
1046
1047
	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
		conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
		ieee80211_mesh_root_setup(ifmsh);
	}
1048
1049
1050
	return 0;
}

1051
1052
#endif

1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
static int ieee80211_change_bss(struct wiphy *wiphy,
				struct net_device *dev,
				struct bss_parameters *params)
{
	struct ieee80211_sub_if_data *sdata;
	u32 changed = 0;

	sdata = IEEE80211_DEV_TO_SUB_IF(dev);

	if (params->use_cts_prot >= 0) {
1063
		sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
1064
1065
1066
		changed |= BSS_CHANGED_ERP_CTS_PROT;
	}
	if (params->use_short_preamble >= 0) {
1067
		sdata->vif.bss_conf.use_short_preamble =
1068
1069
1070
			params->use_short_preamble;
		changed |= BSS_CHANGED_ERP_PREAMBLE;
	}
1071
1072
1073
1074
1075
1076
1077

	if (!sdata->vif.bss_conf.use_short_slot &&
	    sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
		sdata->vif.bss_conf.use_short_slot = true;
		changed |= BSS_CHANGED_ERP_SLOT;
	}

1078
	if (params->use_short_slot_time >= 0) {
1079
		sdata->vif.bss_conf.use_short_slot =
1080
1081
1082
1083
			params->use_short_slot_time;
		changed |= BSS_CHANGED_ERP_SLOT;
	}

1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
	if (params->basic_rates) {
		int i, j;
		u32 rates = 0;
		struct ieee80211_local *local = wiphy_priv(wiphy);
		struct ieee80211_supported_band *sband =
			wiphy->bands[local->oper_channel->band];

		for (i = 0; i < params->basic_rates_len; i++) {
			int rate = (params->basic_rates[i] & 0x7f) * 5;
			for (j = 0; j < sband->n_bitrates; j++) {
				if (sband->bitrates[j].bitrate == rate)
					rates |= BIT(j);
			}
		}
		sdata->vif.bss_conf.basic_rates = rates;
		changed |= BSS_CHANGED_BASIC_RATES;
	}

1102
1103
1104
1105
1106
1107
1108
	if (params->ap_isolate >= 0) {
		if (params->ap_isolate)
			sdata->flags |= IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
		else
			sdata->flags &= ~IEEE80211_SDATA_DONT_BRIDGE_PACKETS;
	}

1109
1110
1111
1112
1113
	ieee80211_bss_info_change_notify(sdata, changed);

	return 0;
}

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
static int ieee80211_set_txq_params(struct wiphy *wiphy,
				    struct ieee80211_txq_params *params)
{
	struct ieee80211_local *local = wiphy_priv(wiphy);
	struct ieee80211_tx_queue_params p;

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

	memset(&p, 0, sizeof(p));
	p.aifs = params->aifs;
	p.cw_max = params->cwmax;
	p.cw_min = params->cwmin;
	p.txop = params->txop;
1128
1129
1130
1131
1132
1133
1134

	/*
	 * Setting tx queue params disables u-apsd because it's only
	 * called in master mode.
	 */
	p.uapsd = false;

1135
	if (drv_conf_tx(local, params->queue, &p)) {
Joe Perches's avatar
Joe Perches committed
1136
1137
1138
		wiphy_debug(local->hw.wiphy,
			    "failed to set TX queue parameters for queue %d\n",
			    params->queue);
1139
1140
1141
1142
1143
1144
		return -EINVAL;
	}

	return 0;
}

1145
static int ieee80211_set_channel(struct wiphy *wiphy,
1146
				 struct net_device *netdev,
1147
				 struct ieee80211_channel *chan,
Sujith's avatar
Sujith committed
1148
				 enum nl80211_channel_type channel_type)
1149
1150
{
	struct ieee80211_local *local = wiphy_priv(wiphy);
1151
1152
1153
1154
	struct ieee80211_sub_if_data *sdata = NULL;

	if (netdev)
		sdata = IEEE80211_DEV_TO_SUB_IF(netdev);
1155

1156
1157
1158
1159
	switch (ieee80211_get_channel_mode(local, NULL)) {
	case CHAN_MODE_HOPPING:
		return -EBUSY;
	case CHAN_MODE_FIXED:
1160
1161
1162
		if (local->oper_channel != chan)
			return -EBUSY;
		if (!sdata && local->_oper_channel_type == channel_type)
1163
			return 0;
1164
		break;