cfg.c revision 3b53fde8ac40c4321389def14d7f4a9e14092fd3
1/*
2 * mac80211 configuration hooks for cfg80211
3 *
4 * Copyright 2006, 2007	Johannes Berg <johannes@sipsolutions.net>
5 *
6 * This file is GPLv2 as found in COPYING.
7 */
8
9#include <linux/ieee80211.h>
10#include <linux/nl80211.h>
11#include <linux/rtnetlink.h>
12#include <net/net_namespace.h>
13#include <linux/rcupdate.h>
14#include <net/cfg80211.h>
15#include "ieee80211_i.h"
16#include "driver-ops.h"
17#include "cfg.h"
18#include "rate.h"
19#include "mesh.h"
20
21static bool nl80211_type_check(enum nl80211_iftype type)
22{
23	switch (type) {
24	case NL80211_IFTYPE_ADHOC:
25	case NL80211_IFTYPE_STATION:
26	case NL80211_IFTYPE_MONITOR:
27#ifdef CONFIG_MAC80211_MESH
28	case NL80211_IFTYPE_MESH_POINT:
29#endif
30	case NL80211_IFTYPE_AP:
31	case NL80211_IFTYPE_AP_VLAN:
32	case NL80211_IFTYPE_WDS:
33		return true;
34	default:
35		return false;
36	}
37}
38
39static bool nl80211_params_check(enum nl80211_iftype type,
40				 struct vif_params *params)
41{
42	if (!nl80211_type_check(type))
43		return false;
44
45	if (params->use_4addr > 0) {
46		switch(type) {
47		case NL80211_IFTYPE_AP_VLAN:
48		case NL80211_IFTYPE_STATION:
49			break;
50		default:
51			return false;
52		}
53	}
54	return true;
55}
56
57static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
58			       enum nl80211_iftype type, u32 *flags,
59			       struct vif_params *params)
60{
61	struct ieee80211_local *local = wiphy_priv(wiphy);
62	struct net_device *dev;
63	struct ieee80211_sub_if_data *sdata;
64	int err;
65
66	if (!nl80211_params_check(type, params))
67		return -EINVAL;
68
69	err = ieee80211_if_add(local, name, &dev, type, params);
70	if (err || type != NL80211_IFTYPE_MONITOR || !flags)
71		return err;
72
73	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
74	sdata->u.mntr_flags = *flags;
75	return 0;
76}
77
78static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
79{
80	ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev));
81
82	return 0;
83}
84
85static int ieee80211_change_iface(struct wiphy *wiphy,
86				  struct net_device *dev,
87				  enum nl80211_iftype type, u32 *flags,
88				  struct vif_params *params)
89{
90	struct ieee80211_sub_if_data *sdata;
91	int ret;
92
93	if (netif_running(dev))
94		return -EBUSY;
95
96	if (!nl80211_params_check(type, params))
97		return -EINVAL;
98
99	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
100
101	ret = ieee80211_if_change_type(sdata, type);
102	if (ret)
103		return ret;
104
105	if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
106		ieee80211_sdata_set_mesh_id(sdata,
107					    params->mesh_id_len,
108					    params->mesh_id);
109
110	if (params->use_4addr >= 0)
111		sdata->use_4addr = !!params->use_4addr;
112
113	if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
114		return 0;
115
116	sdata->u.mntr_flags = *flags;
117	return 0;
118}
119
120static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
121			     u8 key_idx, const u8 *mac_addr,
122			     struct key_params *params)
123{
124	struct ieee80211_sub_if_data *sdata;
125	struct sta_info *sta = NULL;
126	enum ieee80211_key_alg alg;
127	struct ieee80211_key *key;
128	int err;
129
130	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
131
132	switch (params->cipher) {
133	case WLAN_CIPHER_SUITE_WEP40:
134	case WLAN_CIPHER_SUITE_WEP104:
135		alg = ALG_WEP;
136		break;
137	case WLAN_CIPHER_SUITE_TKIP:
138		alg = ALG_TKIP;
139		break;
140	case WLAN_CIPHER_SUITE_CCMP:
141		alg = ALG_CCMP;
142		break;
143	case WLAN_CIPHER_SUITE_AES_CMAC:
144		alg = ALG_AES_CMAC;
145		break;
146	default:
147		return -EINVAL;
148	}
149
150	key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
151				  params->seq_len, params->seq);
152	if (!key)
153		return -ENOMEM;
154
155	rcu_read_lock();
156
157	if (mac_addr) {
158		sta = sta_info_get(sdata->local, mac_addr);
159		if (!sta) {
160			ieee80211_key_free(key);
161			err = -ENOENT;
162			goto out_unlock;
163		}
164	}
165
166	ieee80211_key_link(key, sdata, sta);
167
168	err = 0;
169 out_unlock:
170	rcu_read_unlock();
171
172	return err;
173}
174
175static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
176			     u8 key_idx, const u8 *mac_addr)
177{
178	struct ieee80211_sub_if_data *sdata;
179	struct sta_info *sta;
180	int ret;
181
182	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
183
184	rcu_read_lock();
185
186	if (mac_addr) {
187		ret = -ENOENT;
188
189		sta = sta_info_get(sdata->local, mac_addr);
190		if (!sta)
191			goto out_unlock;
192
193		if (sta->key) {
194			ieee80211_key_free(sta->key);
195			WARN_ON(sta->key);
196			ret = 0;
197		}
198
199		goto out_unlock;
200	}
201
202	if (!sdata->keys[key_idx]) {
203		ret = -ENOENT;
204		goto out_unlock;
205	}
206
207	ieee80211_key_free(sdata->keys[key_idx]);
208	WARN_ON(sdata->keys[key_idx]);
209
210	ret = 0;
211 out_unlock:
212	rcu_read_unlock();
213
214	return ret;
215}
216
217static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
218			     u8 key_idx, const u8 *mac_addr, void *cookie,
219			     void (*callback)(void *cookie,
220					      struct key_params *params))
221{
222	struct ieee80211_sub_if_data *sdata;
223	struct sta_info *sta = NULL;
224	u8 seq[6] = {0};
225	struct key_params params;
226	struct ieee80211_key *key;
227	u32 iv32;
228	u16 iv16;
229	int err = -ENOENT;
230
231	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
232
233	rcu_read_lock();
234
235	if (mac_addr) {
236		sta = sta_info_get(sdata->local, mac_addr);
237		if (!sta)
238			goto out;
239
240		key = sta->key;
241	} else
242		key = sdata->keys[key_idx];
243
244	if (!key)
245		goto out;
246
247	memset(&params, 0, sizeof(params));
248
249	switch (key->conf.alg) {
250	case ALG_TKIP:
251		params.cipher = WLAN_CIPHER_SUITE_TKIP;
252
253		iv32 = key->u.tkip.tx.iv32;
254		iv16 = key->u.tkip.tx.iv16;
255
256		if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
257			drv_get_tkip_seq(sdata->local,
258					 key->conf.hw_key_idx,
259					 &iv32, &iv16);
260
261		seq[0] = iv16 & 0xff;
262		seq[1] = (iv16 >> 8) & 0xff;
263		seq[2] = iv32 & 0xff;
264		seq[3] = (iv32 >> 8) & 0xff;
265		seq[4] = (iv32 >> 16) & 0xff;
266		seq[5] = (iv32 >> 24) & 0xff;
267		params.seq = seq;
268		params.seq_len = 6;
269		break;
270	case ALG_CCMP:
271		params.cipher = WLAN_CIPHER_SUITE_CCMP;
272		seq[0] = key->u.ccmp.tx_pn[5];
273		seq[1] = key->u.ccmp.tx_pn[4];
274		seq[2] = key->u.ccmp.tx_pn[3];
275		seq[3] = key->u.ccmp.tx_pn[2];
276		seq[4] = key->u.ccmp.tx_pn[1];
277		seq[5] = key->u.ccmp.tx_pn[0];
278		params.seq = seq;
279		params.seq_len = 6;
280		break;
281	case ALG_WEP:
282		if (key->conf.keylen == 5)
283			params.cipher = WLAN_CIPHER_SUITE_WEP40;
284		else
285			params.cipher = WLAN_CIPHER_SUITE_WEP104;
286		break;
287	case ALG_AES_CMAC:
288		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
289		seq[0] = key->u.aes_cmac.tx_pn[5];
290		seq[1] = key->u.aes_cmac.tx_pn[4];
291		seq[2] = key->u.aes_cmac.tx_pn[3];
292		seq[3] = key->u.aes_cmac.tx_pn[2];
293		seq[4] = key->u.aes_cmac.tx_pn[1];
294		seq[5] = key->u.aes_cmac.tx_pn[0];
295		params.seq = seq;
296		params.seq_len = 6;
297		break;
298	}
299
300	params.key = key->conf.key;
301	params.key_len = key->conf.keylen;
302
303	callback(cookie, &params);
304	err = 0;
305
306 out:
307	rcu_read_unlock();
308	return err;
309}
310
311static int ieee80211_config_default_key(struct wiphy *wiphy,
312					struct net_device *dev,
313					u8 key_idx)
314{
315	struct ieee80211_sub_if_data *sdata;
316
317	rcu_read_lock();
318
319	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
320	ieee80211_set_default_key(sdata, key_idx);
321
322	rcu_read_unlock();
323
324	return 0;
325}
326
327static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
328					     struct net_device *dev,
329					     u8 key_idx)
330{
331	struct ieee80211_sub_if_data *sdata;
332
333	rcu_read_lock();
334
335	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
336	ieee80211_set_default_mgmt_key(sdata, key_idx);
337
338	rcu_read_unlock();
339
340	return 0;
341}
342
343static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
344{
345	struct ieee80211_sub_if_data *sdata = sta->sdata;
346
347	sinfo->generation = sdata->local->sta_generation;
348
349	sinfo->filled = STATION_INFO_INACTIVE_TIME |
350			STATION_INFO_RX_BYTES |
351			STATION_INFO_TX_BYTES |
352			STATION_INFO_RX_PACKETS |
353			STATION_INFO_TX_PACKETS |
354			STATION_INFO_TX_BITRATE;
355
356	sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
357	sinfo->rx_bytes = sta->rx_bytes;
358	sinfo->tx_bytes = sta->tx_bytes;
359	sinfo->rx_packets = sta->rx_packets;
360	sinfo->tx_packets = sta->tx_packets;
361
362	if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) {
363		sinfo->filled |= STATION_INFO_SIGNAL;
364		sinfo->signal = (s8)sta->last_signal;
365	}
366
367	sinfo->txrate.flags = 0;
368	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)
369		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
370	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
371		sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
372	if (sta->last_tx_rate.flags & IEEE80211_TX_RC_SHORT_GI)
373		sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
374
375	if (!(sta->last_tx_rate.flags & IEEE80211_TX_RC_MCS)) {
376		struct ieee80211_supported_band *sband;
377		sband = sta->local->hw.wiphy->bands[
378				sta->local->hw.conf.channel->band];
379		sinfo->txrate.legacy =
380			sband->bitrates[sta->last_tx_rate.idx].bitrate;
381	} else
382		sinfo->txrate.mcs = sta->last_tx_rate.idx;
383
384	if (ieee80211_vif_is_mesh(&sdata->vif)) {
385#ifdef CONFIG_MAC80211_MESH
386		sinfo->filled |= STATION_INFO_LLID |
387				 STATION_INFO_PLID |
388				 STATION_INFO_PLINK_STATE;
389
390		sinfo->llid = le16_to_cpu(sta->llid);
391		sinfo->plid = le16_to_cpu(sta->plid);
392		sinfo->plink_state = sta->plink_state;
393#endif
394	}
395}
396
397
398static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
399				 int idx, u8 *mac, struct station_info *sinfo)
400{
401	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
402	struct sta_info *sta;
403	int ret = -ENOENT;
404
405	rcu_read_lock();
406
407	sta = sta_info_get_by_idx(sdata, idx);
408	if (sta) {
409		ret = 0;
410		memcpy(mac, sta->sta.addr, ETH_ALEN);
411		sta_set_sinfo(sta, sinfo);
412	}
413
414	rcu_read_unlock();
415
416	return ret;
417}
418
419static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
420				 u8 *mac, struct station_info *sinfo)
421{
422	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
423	struct sta_info *sta;
424	int ret = -ENOENT;
425
426	rcu_read_lock();
427
428	/* XXX: verify sta->dev == dev */
429
430	sta = sta_info_get(local, mac);
431	if (sta) {
432		ret = 0;
433		sta_set_sinfo(sta, sinfo);
434	}
435
436	rcu_read_unlock();
437
438	return ret;
439}
440
441/*
442 * This handles both adding a beacon and setting new beacon info
443 */
444static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
445				   struct beacon_parameters *params)
446{
447	struct beacon_data *new, *old;
448	int new_head_len, new_tail_len;
449	int size;
450	int err = -EINVAL;
451
452	old = sdata->u.ap.beacon;
453
454	/* head must not be zero-length */
455	if (params->head && !params->head_len)
456		return -EINVAL;
457
458	/*
459	 * This is a kludge. beacon interval should really be part
460	 * of the beacon information.
461	 */
462	if (params->interval &&
463	    (sdata->vif.bss_conf.beacon_int != params->interval)) {
464		sdata->vif.bss_conf.beacon_int = params->interval;
465		ieee80211_bss_info_change_notify(sdata,
466						 BSS_CHANGED_BEACON_INT);
467	}
468
469	/* Need to have a beacon head if we don't have one yet */
470	if (!params->head && !old)
471		return err;
472
473	/* sorry, no way to start beaconing without dtim period */
474	if (!params->dtim_period && !old)
475		return err;
476
477	/* new or old head? */
478	if (params->head)
479		new_head_len = params->head_len;
480	else
481		new_head_len = old->head_len;
482
483	/* new or old tail? */
484	if (params->tail || !old)
485		/* params->tail_len will be zero for !params->tail */
486		new_tail_len = params->tail_len;
487	else
488		new_tail_len = old->tail_len;
489
490	size = sizeof(*new) + new_head_len + new_tail_len;
491
492	new = kzalloc(size, GFP_KERNEL);
493	if (!new)
494		return -ENOMEM;
495
496	/* start filling the new info now */
497
498	/* new or old dtim period? */
499	if (params->dtim_period)
500		new->dtim_period = params->dtim_period;
501	else
502		new->dtim_period = old->dtim_period;
503
504	/*
505	 * pointers go into the block we allocated,
506	 * memory is | beacon_data | head | tail |
507	 */
508	new->head = ((u8 *) new) + sizeof(*new);
509	new->tail = new->head + new_head_len;
510	new->head_len = new_head_len;
511	new->tail_len = new_tail_len;
512
513	/* copy in head */
514	if (params->head)
515		memcpy(new->head, params->head, new_head_len);
516	else
517		memcpy(new->head, old->head, new_head_len);
518
519	/* copy in optional tail */
520	if (params->tail)
521		memcpy(new->tail, params->tail, new_tail_len);
522	else
523		if (old)
524			memcpy(new->tail, old->tail, new_tail_len);
525
526	rcu_assign_pointer(sdata->u.ap.beacon, new);
527
528	synchronize_rcu();
529
530	kfree(old);
531
532	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
533						BSS_CHANGED_BEACON);
534	return 0;
535}
536
537static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
538				struct beacon_parameters *params)
539{
540	struct ieee80211_sub_if_data *sdata;
541	struct beacon_data *old;
542
543	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
544
545	old = sdata->u.ap.beacon;
546
547	if (old)
548		return -EALREADY;
549
550	return ieee80211_config_beacon(sdata, params);
551}
552
553static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
554				struct beacon_parameters *params)
555{
556	struct ieee80211_sub_if_data *sdata;
557	struct beacon_data *old;
558
559	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
560
561	old = sdata->u.ap.beacon;
562
563	if (!old)
564		return -ENOENT;
565
566	return ieee80211_config_beacon(sdata, params);
567}
568
569static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
570{
571	struct ieee80211_sub_if_data *sdata;
572	struct beacon_data *old;
573
574	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
575
576	old = sdata->u.ap.beacon;
577
578	if (!old)
579		return -ENOENT;
580
581	rcu_assign_pointer(sdata->u.ap.beacon, NULL);
582	synchronize_rcu();
583	kfree(old);
584
585	ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
586	return 0;
587}
588
589/* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
590struct iapp_layer2_update {
591	u8 da[ETH_ALEN];	/* broadcast */
592	u8 sa[ETH_ALEN];	/* STA addr */
593	__be16 len;		/* 6 */
594	u8 dsap;		/* 0 */
595	u8 ssap;		/* 0 */
596	u8 control;
597	u8 xid_info[3];
598} __attribute__ ((packed));
599
600static void ieee80211_send_layer2_update(struct sta_info *sta)
601{
602	struct iapp_layer2_update *msg;
603	struct sk_buff *skb;
604
605	/* Send Level 2 Update Frame to update forwarding tables in layer 2
606	 * bridge devices */
607
608	skb = dev_alloc_skb(sizeof(*msg));
609	if (!skb)
610		return;
611	msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
612
613	/* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
614	 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
615
616	memset(msg->da, 0xff, ETH_ALEN);
617	memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
618	msg->len = htons(6);
619	msg->dsap = 0;
620	msg->ssap = 0x01;	/* NULL LSAP, CR Bit: Response */
621	msg->control = 0xaf;	/* XID response lsb.1111F101.
622				 * F=0 (no poll command; unsolicited frame) */
623	msg->xid_info[0] = 0x81;	/* XID format identifier */
624	msg->xid_info[1] = 1;	/* LLC types/classes: Type 1 LLC */
625	msg->xid_info[2] = 0;	/* XID sender's receive window size (RW) */
626
627	skb->dev = sta->sdata->dev;
628	skb->protocol = eth_type_trans(skb, sta->sdata->dev);
629	memset(skb->cb, 0, sizeof(skb->cb));
630	netif_rx(skb);
631}
632
633static void sta_apply_parameters(struct ieee80211_local *local,
634				 struct sta_info *sta,
635				 struct station_parameters *params)
636{
637	u32 rates;
638	int i, j;
639	struct ieee80211_supported_band *sband;
640	struct ieee80211_sub_if_data *sdata = sta->sdata;
641	u32 mask, set;
642
643	sband = local->hw.wiphy->bands[local->oper_channel->band];
644
645	spin_lock_bh(&sta->lock);
646	mask = params->sta_flags_mask;
647	set = params->sta_flags_set;
648
649	if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
650		sta->flags &= ~WLAN_STA_AUTHORIZED;
651		if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
652			sta->flags |= WLAN_STA_AUTHORIZED;
653	}
654
655	if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
656		sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
657		if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
658			sta->flags |= WLAN_STA_SHORT_PREAMBLE;
659	}
660
661	if (mask & BIT(NL80211_STA_FLAG_WME)) {
662		sta->flags &= ~WLAN_STA_WME;
663		if (set & BIT(NL80211_STA_FLAG_WME))
664			sta->flags |= WLAN_STA_WME;
665	}
666
667	if (mask & BIT(NL80211_STA_FLAG_MFP)) {
668		sta->flags &= ~WLAN_STA_MFP;
669		if (set & BIT(NL80211_STA_FLAG_MFP))
670			sta->flags |= WLAN_STA_MFP;
671	}
672	spin_unlock_bh(&sta->lock);
673
674	/*
675	 * cfg80211 validates this (1-2007) and allows setting the AID
676	 * only when creating a new station entry
677	 */
678	if (params->aid)
679		sta->sta.aid = params->aid;
680
681	/*
682	 * FIXME: updating the following information is racy when this
683	 *	  function is called from ieee80211_change_station().
684	 *	  However, all this information should be static so
685	 *	  maybe we should just reject attemps to change it.
686	 */
687
688	if (params->listen_interval >= 0)
689		sta->listen_interval = params->listen_interval;
690
691	if (params->supported_rates) {
692		rates = 0;
693
694		for (i = 0; i < params->supported_rates_len; i++) {
695			int rate = (params->supported_rates[i] & 0x7f) * 5;
696			for (j = 0; j < sband->n_bitrates; j++) {
697				if (sband->bitrates[j].bitrate == rate)
698					rates |= BIT(j);
699			}
700		}
701		sta->sta.supp_rates[local->oper_channel->band] = rates;
702	}
703
704	if (params->ht_capa)
705		ieee80211_ht_cap_ie_to_sta_ht_cap(sband,
706						  params->ht_capa,
707						  &sta->sta.ht_cap);
708
709	if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
710		switch (params->plink_action) {
711		case PLINK_ACTION_OPEN:
712			mesh_plink_open(sta);
713			break;
714		case PLINK_ACTION_BLOCK:
715			mesh_plink_block(sta);
716			break;
717		}
718	}
719}
720
721static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
722				 u8 *mac, struct station_parameters *params)
723{
724	struct ieee80211_local *local = wiphy_priv(wiphy);
725	struct sta_info *sta;
726	struct ieee80211_sub_if_data *sdata;
727	int err;
728	int layer2_update;
729
730	if (params->vlan) {
731		sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
732
733		if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
734		    sdata->vif.type != NL80211_IFTYPE_AP)
735			return -EINVAL;
736	} else
737		sdata = IEEE80211_DEV_TO_SUB_IF(dev);
738
739	if (compare_ether_addr(mac, dev->dev_addr) == 0)
740		return -EINVAL;
741
742	if (is_multicast_ether_addr(mac))
743		return -EINVAL;
744
745	sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
746	if (!sta)
747		return -ENOMEM;
748
749	sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
750
751	sta_apply_parameters(local, sta, params);
752
753	rate_control_rate_init(sta);
754
755	layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
756		sdata->vif.type == NL80211_IFTYPE_AP;
757
758	rcu_read_lock();
759
760	err = sta_info_insert(sta);
761	if (err) {
762		rcu_read_unlock();
763		return err;
764	}
765
766	if (layer2_update)
767		ieee80211_send_layer2_update(sta);
768
769	rcu_read_unlock();
770
771	return 0;
772}
773
774static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
775				 u8 *mac)
776{
777	struct ieee80211_local *local = wiphy_priv(wiphy);
778	struct ieee80211_sub_if_data *sdata;
779	struct sta_info *sta;
780
781	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
782
783	if (mac) {
784		rcu_read_lock();
785
786		/* XXX: get sta belonging to dev */
787		sta = sta_info_get(local, mac);
788		if (!sta) {
789			rcu_read_unlock();
790			return -ENOENT;
791		}
792
793		sta_info_unlink(&sta);
794		rcu_read_unlock();
795
796		sta_info_destroy(sta);
797	} else
798		sta_info_flush(local, sdata);
799
800	return 0;
801}
802
803static int ieee80211_change_station(struct wiphy *wiphy,
804				    struct net_device *dev,
805				    u8 *mac,
806				    struct station_parameters *params)
807{
808	struct ieee80211_local *local = wiphy_priv(wiphy);
809	struct sta_info *sta;
810	struct ieee80211_sub_if_data *vlansdata;
811
812	rcu_read_lock();
813
814	/* XXX: get sta belonging to dev */
815	sta = sta_info_get(local, mac);
816	if (!sta) {
817		rcu_read_unlock();
818		return -ENOENT;
819	}
820
821	if (params->vlan && params->vlan != sta->sdata->dev) {
822		vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
823
824		if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
825		    vlansdata->vif.type != NL80211_IFTYPE_AP) {
826			rcu_read_unlock();
827			return -EINVAL;
828		}
829
830		if (vlansdata->use_4addr) {
831			if (vlansdata->u.vlan.sta)
832				return -EBUSY;
833
834			rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
835		}
836
837		sta->sdata = vlansdata;
838		ieee80211_send_layer2_update(sta);
839	}
840
841	sta_apply_parameters(local, sta, params);
842
843	rcu_read_unlock();
844
845	return 0;
846}
847
848#ifdef CONFIG_MAC80211_MESH
849static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
850				 u8 *dst, u8 *next_hop)
851{
852	struct ieee80211_local *local = wiphy_priv(wiphy);
853	struct ieee80211_sub_if_data *sdata;
854	struct mesh_path *mpath;
855	struct sta_info *sta;
856	int err;
857
858	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
859
860	rcu_read_lock();
861	sta = sta_info_get(local, next_hop);
862	if (!sta) {
863		rcu_read_unlock();
864		return -ENOENT;
865	}
866
867	err = mesh_path_add(dst, sdata);
868	if (err) {
869		rcu_read_unlock();
870		return err;
871	}
872
873	mpath = mesh_path_lookup(dst, sdata);
874	if (!mpath) {
875		rcu_read_unlock();
876		return -ENXIO;
877	}
878	mesh_path_fix_nexthop(mpath, sta);
879
880	rcu_read_unlock();
881	return 0;
882}
883
884static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
885				 u8 *dst)
886{
887	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
888
889	if (dst)
890		return mesh_path_del(dst, sdata);
891
892	mesh_path_flush(sdata);
893	return 0;
894}
895
896static int ieee80211_change_mpath(struct wiphy *wiphy,
897				    struct net_device *dev,
898				    u8 *dst, u8 *next_hop)
899{
900	struct ieee80211_local *local = wiphy_priv(wiphy);
901	struct ieee80211_sub_if_data *sdata;
902	struct mesh_path *mpath;
903	struct sta_info *sta;
904
905	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
906
907	rcu_read_lock();
908
909	sta = sta_info_get(local, next_hop);
910	if (!sta) {
911		rcu_read_unlock();
912		return -ENOENT;
913	}
914
915	mpath = mesh_path_lookup(dst, sdata);
916	if (!mpath) {
917		rcu_read_unlock();
918		return -ENOENT;
919	}
920
921	mesh_path_fix_nexthop(mpath, sta);
922
923	rcu_read_unlock();
924	return 0;
925}
926
927static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
928			    struct mpath_info *pinfo)
929{
930	if (mpath->next_hop)
931		memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
932	else
933		memset(next_hop, 0, ETH_ALEN);
934
935	pinfo->generation = mesh_paths_generation;
936
937	pinfo->filled = MPATH_INFO_FRAME_QLEN |
938			MPATH_INFO_SN |
939			MPATH_INFO_METRIC |
940			MPATH_INFO_EXPTIME |
941			MPATH_INFO_DISCOVERY_TIMEOUT |
942			MPATH_INFO_DISCOVERY_RETRIES |
943			MPATH_INFO_FLAGS;
944
945	pinfo->frame_qlen = mpath->frame_queue.qlen;
946	pinfo->sn = mpath->sn;
947	pinfo->metric = mpath->metric;
948	if (time_before(jiffies, mpath->exp_time))
949		pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
950	pinfo->discovery_timeout =
951			jiffies_to_msecs(mpath->discovery_timeout);
952	pinfo->discovery_retries = mpath->discovery_retries;
953	pinfo->flags = 0;
954	if (mpath->flags & MESH_PATH_ACTIVE)
955		pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
956	if (mpath->flags & MESH_PATH_RESOLVING)
957		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
958	if (mpath->flags & MESH_PATH_SN_VALID)
959		pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
960	if (mpath->flags & MESH_PATH_FIXED)
961		pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
962	if (mpath->flags & MESH_PATH_RESOLVING)
963		pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
964
965	pinfo->flags = mpath->flags;
966}
967
968static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
969			       u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
970
971{
972	struct ieee80211_sub_if_data *sdata;
973	struct mesh_path *mpath;
974
975	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
976
977	rcu_read_lock();
978	mpath = mesh_path_lookup(dst, sdata);
979	if (!mpath) {
980		rcu_read_unlock();
981		return -ENOENT;
982	}
983	memcpy(dst, mpath->dst, ETH_ALEN);
984	mpath_set_pinfo(mpath, next_hop, pinfo);
985	rcu_read_unlock();
986	return 0;
987}
988
989static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
990				 int idx, u8 *dst, u8 *next_hop,
991				 struct mpath_info *pinfo)
992{
993	struct ieee80211_sub_if_data *sdata;
994	struct mesh_path *mpath;
995
996	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
997
998	rcu_read_lock();
999	mpath = mesh_path_lookup_by_idx(idx, sdata);
1000	if (!mpath) {
1001		rcu_read_unlock();
1002		return -ENOENT;
1003	}
1004	memcpy(dst, mpath->dst, ETH_ALEN);
1005	mpath_set_pinfo(mpath, next_hop, pinfo);
1006	rcu_read_unlock();
1007	return 0;
1008}
1009
1010static int ieee80211_get_mesh_params(struct wiphy *wiphy,
1011				struct net_device *dev,
1012				struct mesh_config *conf)
1013{
1014	struct ieee80211_sub_if_data *sdata;
1015	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1016
1017	memcpy(conf, &(sdata->u.mesh.mshcfg), sizeof(struct mesh_config));
1018	return 0;
1019}
1020
1021static inline bool _chg_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
1022{
1023	return (mask >> (parm-1)) & 0x1;
1024}
1025
1026static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1027				struct net_device *dev,
1028				const struct mesh_config *nconf, u32 mask)
1029{
1030	struct mesh_config *conf;
1031	struct ieee80211_sub_if_data *sdata;
1032	struct ieee80211_if_mesh *ifmsh;
1033
1034	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1035	ifmsh = &sdata->u.mesh;
1036
1037	/* Set the config options which we are interested in setting */
1038	conf = &(sdata->u.mesh.mshcfg);
1039	if (_chg_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask))
1040		conf->dot11MeshRetryTimeout = nconf->dot11MeshRetryTimeout;
1041	if (_chg_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask))
1042		conf->dot11MeshConfirmTimeout = nconf->dot11MeshConfirmTimeout;
1043	if (_chg_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask))
1044		conf->dot11MeshHoldingTimeout = nconf->dot11MeshHoldingTimeout;
1045	if (_chg_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask))
1046		conf->dot11MeshMaxPeerLinks = nconf->dot11MeshMaxPeerLinks;
1047	if (_chg_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask))
1048		conf->dot11MeshMaxRetries = nconf->dot11MeshMaxRetries;
1049	if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask))
1050		conf->dot11MeshTTL = nconf->dot11MeshTTL;
1051	if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask))
1052		conf->auto_open_plinks = nconf->auto_open_plinks;
1053	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
1054		conf->dot11MeshHWMPmaxPREQretries =
1055			nconf->dot11MeshHWMPmaxPREQretries;
1056	if (_chg_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
1057		conf->path_refresh_time = nconf->path_refresh_time;
1058	if (_chg_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
1059		conf->min_discovery_timeout = nconf->min_discovery_timeout;
1060	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
1061		conf->dot11MeshHWMPactivePathTimeout =
1062			nconf->dot11MeshHWMPactivePathTimeout;
1063	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
1064		conf->dot11MeshHWMPpreqMinInterval =
1065			nconf->dot11MeshHWMPpreqMinInterval;
1066	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
1067			   mask))
1068		conf->dot11MeshHWMPnetDiameterTraversalTime =
1069			nconf->dot11MeshHWMPnetDiameterTraversalTime;
1070	if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
1071		conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1072		ieee80211_mesh_root_setup(ifmsh);
1073	}
1074	return 0;
1075}
1076
1077#endif
1078
1079static int ieee80211_change_bss(struct wiphy *wiphy,
1080				struct net_device *dev,
1081				struct bss_parameters *params)
1082{
1083	struct ieee80211_sub_if_data *sdata;
1084	u32 changed = 0;
1085
1086	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1087
1088	if (params->use_cts_prot >= 0) {
1089		sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
1090		changed |= BSS_CHANGED_ERP_CTS_PROT;
1091	}
1092	if (params->use_short_preamble >= 0) {
1093		sdata->vif.bss_conf.use_short_preamble =
1094			params->use_short_preamble;
1095		changed |= BSS_CHANGED_ERP_PREAMBLE;
1096	}
1097	if (params->use_short_slot_time >= 0) {
1098		sdata->vif.bss_conf.use_short_slot =
1099			params->use_short_slot_time;
1100		changed |= BSS_CHANGED_ERP_SLOT;
1101	}
1102
1103	if (params->basic_rates) {
1104		int i, j;
1105		u32 rates = 0;
1106		struct ieee80211_local *local = wiphy_priv(wiphy);
1107		struct ieee80211_supported_band *sband =
1108			wiphy->bands[local->oper_channel->band];
1109
1110		for (i = 0; i < params->basic_rates_len; i++) {
1111			int rate = (params->basic_rates[i] & 0x7f) * 5;
1112			for (j = 0; j < sband->n_bitrates; j++) {
1113				if (sband->bitrates[j].bitrate == rate)
1114					rates |= BIT(j);
1115			}
1116		}
1117		sdata->vif.bss_conf.basic_rates = rates;
1118		changed |= BSS_CHANGED_BASIC_RATES;
1119	}
1120
1121	ieee80211_bss_info_change_notify(sdata, changed);
1122
1123	return 0;
1124}
1125
1126static int ieee80211_set_txq_params(struct wiphy *wiphy,
1127				    struct ieee80211_txq_params *params)
1128{
1129	struct ieee80211_local *local = wiphy_priv(wiphy);
1130	struct ieee80211_tx_queue_params p;
1131
1132	if (!local->ops->conf_tx)
1133		return -EOPNOTSUPP;
1134
1135	memset(&p, 0, sizeof(p));
1136	p.aifs = params->aifs;
1137	p.cw_max = params->cwmax;
1138	p.cw_min = params->cwmin;
1139	p.txop = params->txop;
1140	if (drv_conf_tx(local, params->queue, &p)) {
1141		printk(KERN_DEBUG "%s: failed to set TX queue "
1142		       "parameters for queue %d\n",
1143		       wiphy_name(local->hw.wiphy), params->queue);
1144		return -EINVAL;
1145	}
1146
1147	return 0;
1148}
1149
1150static int ieee80211_set_channel(struct wiphy *wiphy,
1151				 struct ieee80211_channel *chan,
1152				 enum nl80211_channel_type channel_type)
1153{
1154	struct ieee80211_local *local = wiphy_priv(wiphy);
1155
1156	local->oper_channel = chan;
1157	local->oper_channel_type = channel_type;
1158
1159	return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
1160}
1161
1162#ifdef CONFIG_PM
1163static int ieee80211_suspend(struct wiphy *wiphy)
1164{
1165	return __ieee80211_suspend(wiphy_priv(wiphy));
1166}
1167
1168static int ieee80211_resume(struct wiphy *wiphy)
1169{
1170	return __ieee80211_resume(wiphy_priv(wiphy));
1171}
1172#else
1173#define ieee80211_suspend NULL
1174#define ieee80211_resume NULL
1175#endif
1176
1177static int ieee80211_scan(struct wiphy *wiphy,
1178			  struct net_device *dev,
1179			  struct cfg80211_scan_request *req)
1180{
1181	struct ieee80211_sub_if_data *sdata;
1182
1183	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1184
1185	if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1186	    sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1187	    sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
1188	    (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
1189		return -EOPNOTSUPP;
1190
1191	return ieee80211_request_scan(sdata, req);
1192}
1193
1194static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1195			  struct cfg80211_auth_request *req)
1196{
1197	return ieee80211_mgd_auth(IEEE80211_DEV_TO_SUB_IF(dev), req);
1198}
1199
1200static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
1201			   struct cfg80211_assoc_request *req)
1202{
1203	return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req);
1204}
1205
1206static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
1207			    struct cfg80211_deauth_request *req,
1208			    void *cookie)
1209{
1210	return ieee80211_mgd_deauth(IEEE80211_DEV_TO_SUB_IF(dev),
1211				    req, cookie);
1212}
1213
1214static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
1215			      struct cfg80211_disassoc_request *req,
1216			      void *cookie)
1217{
1218	return ieee80211_mgd_disassoc(IEEE80211_DEV_TO_SUB_IF(dev),
1219				      req, cookie);
1220}
1221
1222static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1223			       struct cfg80211_ibss_params *params)
1224{
1225	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1226
1227	return ieee80211_ibss_join(sdata, params);
1228}
1229
1230static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1231{
1232	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1233
1234	return ieee80211_ibss_leave(sdata);
1235}
1236
1237static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1238{
1239	struct ieee80211_local *local = wiphy_priv(wiphy);
1240	int err;
1241
1242	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1243		err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1244
1245		if (err)
1246			return err;
1247	}
1248
1249	if (changed & WIPHY_PARAM_RETRY_SHORT)
1250		local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
1251	if (changed & WIPHY_PARAM_RETRY_LONG)
1252		local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
1253	if (changed &
1254	    (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
1255		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
1256
1257	return 0;
1258}
1259
1260static int ieee80211_set_tx_power(struct wiphy *wiphy,
1261				  enum tx_power_setting type, int dbm)
1262{
1263	struct ieee80211_local *local = wiphy_priv(wiphy);
1264	struct ieee80211_channel *chan = local->hw.conf.channel;
1265	u32 changes = 0;
1266
1267	switch (type) {
1268	case TX_POWER_AUTOMATIC:
1269		local->user_power_level = -1;
1270		break;
1271	case TX_POWER_LIMITED:
1272		if (dbm < 0)
1273			return -EINVAL;
1274		local->user_power_level = dbm;
1275		break;
1276	case TX_POWER_FIXED:
1277		if (dbm < 0)
1278			return -EINVAL;
1279		/* TODO: move to cfg80211 when it knows the channel */
1280		if (dbm > chan->max_power)
1281			return -EINVAL;
1282		local->user_power_level = dbm;
1283		break;
1284	}
1285
1286	ieee80211_hw_config(local, changes);
1287
1288	return 0;
1289}
1290
1291static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
1292{
1293	struct ieee80211_local *local = wiphy_priv(wiphy);
1294
1295	*dbm = local->hw.conf.power_level;
1296
1297	return 0;
1298}
1299
1300static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
1301				  u8 *addr)
1302{
1303	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1304
1305	memcpy(&sdata->u.wds.remote_addr, addr, ETH_ALEN);
1306
1307	return 0;
1308}
1309
1310static void ieee80211_rfkill_poll(struct wiphy *wiphy)
1311{
1312	struct ieee80211_local *local = wiphy_priv(wiphy);
1313
1314	drv_rfkill_poll(local);
1315}
1316
1317#ifdef CONFIG_NL80211_TESTMODE
1318static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1319{
1320	struct ieee80211_local *local = wiphy_priv(wiphy);
1321
1322	if (!local->ops->testmode_cmd)
1323		return -EOPNOTSUPP;
1324
1325	return local->ops->testmode_cmd(&local->hw, data, len);
1326}
1327#endif
1328
1329static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1330				    bool enabled, int timeout)
1331{
1332	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1333	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1334	struct ieee80211_conf *conf = &local->hw.conf;
1335
1336	if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
1337		return -EOPNOTSUPP;
1338
1339	if (enabled == sdata->u.mgd.powersave &&
1340	    timeout == conf->dynamic_ps_timeout)
1341		return 0;
1342
1343	sdata->u.mgd.powersave = enabled;
1344	conf->dynamic_ps_timeout = timeout;
1345
1346	if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1347		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
1348
1349	ieee80211_recalc_ps(local, -1);
1350
1351	return 0;
1352}
1353
1354static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1355				      struct net_device *dev,
1356				      const u8 *addr,
1357				      const struct cfg80211_bitrate_mask *mask)
1358{
1359	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1360	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1361	int i, err = -EINVAL;
1362	u32 target_rate;
1363	struct ieee80211_supported_band *sband;
1364
1365	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1366
1367	/* target_rate = -1, rate->fixed = 0 means auto only, so use all rates
1368	 * target_rate = X, rate->fixed = 1 means only rate X
1369	 * target_rate = X, rate->fixed = 0 means all rates <= X */
1370	sdata->max_ratectrl_rateidx = -1;
1371	sdata->force_unicast_rateidx = -1;
1372
1373	if (mask->fixed)
1374		target_rate = mask->fixed / 100;
1375	else if (mask->maxrate)
1376		target_rate = mask->maxrate / 100;
1377	else
1378		return 0;
1379
1380	for (i=0; i< sband->n_bitrates; i++) {
1381		struct ieee80211_rate *brate = &sband->bitrates[i];
1382		int this_rate = brate->bitrate;
1383
1384		if (target_rate == this_rate) {
1385			sdata->max_ratectrl_rateidx = i;
1386			if (mask->fixed)
1387				sdata->force_unicast_rateidx = i;
1388			err = 0;
1389			break;
1390		}
1391	}
1392
1393	return err;
1394}
1395
1396struct cfg80211_ops mac80211_config_ops = {
1397	.add_virtual_intf = ieee80211_add_iface,
1398	.del_virtual_intf = ieee80211_del_iface,
1399	.change_virtual_intf = ieee80211_change_iface,
1400	.add_key = ieee80211_add_key,
1401	.del_key = ieee80211_del_key,
1402	.get_key = ieee80211_get_key,
1403	.set_default_key = ieee80211_config_default_key,
1404	.set_default_mgmt_key = ieee80211_config_default_mgmt_key,
1405	.add_beacon = ieee80211_add_beacon,
1406	.set_beacon = ieee80211_set_beacon,
1407	.del_beacon = ieee80211_del_beacon,
1408	.add_station = ieee80211_add_station,
1409	.del_station = ieee80211_del_station,
1410	.change_station = ieee80211_change_station,
1411	.get_station = ieee80211_get_station,
1412	.dump_station = ieee80211_dump_station,
1413#ifdef CONFIG_MAC80211_MESH
1414	.add_mpath = ieee80211_add_mpath,
1415	.del_mpath = ieee80211_del_mpath,
1416	.change_mpath = ieee80211_change_mpath,
1417	.get_mpath = ieee80211_get_mpath,
1418	.dump_mpath = ieee80211_dump_mpath,
1419	.set_mesh_params = ieee80211_set_mesh_params,
1420	.get_mesh_params = ieee80211_get_mesh_params,
1421#endif
1422	.change_bss = ieee80211_change_bss,
1423	.set_txq_params = ieee80211_set_txq_params,
1424	.set_channel = ieee80211_set_channel,
1425	.suspend = ieee80211_suspend,
1426	.resume = ieee80211_resume,
1427	.scan = ieee80211_scan,
1428	.auth = ieee80211_auth,
1429	.assoc = ieee80211_assoc,
1430	.deauth = ieee80211_deauth,
1431	.disassoc = ieee80211_disassoc,
1432	.join_ibss = ieee80211_join_ibss,
1433	.leave_ibss = ieee80211_leave_ibss,
1434	.set_wiphy_params = ieee80211_set_wiphy_params,
1435	.set_tx_power = ieee80211_set_tx_power,
1436	.get_tx_power = ieee80211_get_tx_power,
1437	.set_wds_peer = ieee80211_set_wds_peer,
1438	.rfkill_poll = ieee80211_rfkill_poll,
1439	CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
1440	.set_power_mgmt = ieee80211_set_power_mgmt,
1441	.set_bitrate_mask = ieee80211_set_bitrate_mask,
1442};
1443