cfg80211: Add new wireless regulatory infrastructure
[linux-2.6.git] / net / mac80211 / cfg.c
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 "cfg.h"
17 #include "rate.h"
18 #include "mesh.h"
19
20 struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
21 {
22         struct ieee80211_local *local = wiphy_priv(wiphy);
23         return &local->hw;
24 }
25 EXPORT_SYMBOL(wiphy_to_hw);
26
27 static enum ieee80211_if_types
28 nl80211_type_to_mac80211_type(enum nl80211_iftype type)
29 {
30         switch (type) {
31         case NL80211_IFTYPE_UNSPECIFIED:
32                 return IEEE80211_IF_TYPE_STA;
33         case NL80211_IFTYPE_ADHOC:
34                 return IEEE80211_IF_TYPE_IBSS;
35         case NL80211_IFTYPE_STATION:
36                 return IEEE80211_IF_TYPE_STA;
37         case NL80211_IFTYPE_MONITOR:
38                 return IEEE80211_IF_TYPE_MNTR;
39 #ifdef CONFIG_MAC80211_MESH
40         case NL80211_IFTYPE_MESH_POINT:
41                 return IEEE80211_IF_TYPE_MESH_POINT;
42 #endif
43         case NL80211_IFTYPE_WDS:
44                 return IEEE80211_IF_TYPE_WDS;
45         default:
46                 return IEEE80211_IF_TYPE_INVALID;
47         }
48 }
49
50 static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
51                                enum nl80211_iftype type, u32 *flags,
52                                struct vif_params *params)
53 {
54         struct ieee80211_local *local = wiphy_priv(wiphy);
55         enum ieee80211_if_types itype;
56         struct net_device *dev;
57         struct ieee80211_sub_if_data *sdata;
58         int err;
59
60         itype = nl80211_type_to_mac80211_type(type);
61         if (itype == IEEE80211_IF_TYPE_INVALID)
62                 return -EINVAL;
63
64         err = ieee80211_if_add(local, name, &dev, itype, params);
65         if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags)
66                 return err;
67
68         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
69         sdata->u.mntr_flags = *flags;
70         return 0;
71 }
72
73 static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
74 {
75         struct net_device *dev;
76         struct ieee80211_sub_if_data *sdata;
77
78         /* we're under RTNL */
79         dev = __dev_get_by_index(&init_net, ifindex);
80         if (!dev)
81                 return -ENODEV;
82
83         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
84
85         ieee80211_if_remove(sdata);
86
87         return 0;
88 }
89
90 static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
91                                   enum nl80211_iftype type, u32 *flags,
92                                   struct vif_params *params)
93 {
94         struct ieee80211_local *local = wiphy_priv(wiphy);
95         struct net_device *dev;
96         enum ieee80211_if_types itype;
97         struct ieee80211_sub_if_data *sdata;
98         int ret;
99
100         /* we're under RTNL */
101         dev = __dev_get_by_index(&init_net, ifindex);
102         if (!dev)
103                 return -ENODEV;
104
105         itype = nl80211_type_to_mac80211_type(type);
106         if (itype == IEEE80211_IF_TYPE_INVALID)
107                 return -EINVAL;
108
109         if (dev == local->mdev)
110                 return -EOPNOTSUPP;
111
112         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
113
114         ret = ieee80211_if_change_type(sdata, itype);
115         if (ret)
116                 return ret;
117
118         if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
119                 ieee80211_if_sta_set_mesh_id(&sdata->u.sta,
120                                              params->mesh_id_len,
121                                              params->mesh_id);
122
123         if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags)
124                 return 0;
125
126         sdata->u.mntr_flags = *flags;
127         return 0;
128 }
129
130 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
131                              u8 key_idx, u8 *mac_addr,
132                              struct key_params *params)
133 {
134         struct ieee80211_local *local = wiphy_priv(wiphy);
135         struct ieee80211_sub_if_data *sdata;
136         struct sta_info *sta = NULL;
137         enum ieee80211_key_alg alg;
138         struct ieee80211_key *key;
139         int err;
140
141         if (dev == local->mdev)
142                 return -EOPNOTSUPP;
143
144         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
145
146         switch (params->cipher) {
147         case WLAN_CIPHER_SUITE_WEP40:
148         case WLAN_CIPHER_SUITE_WEP104:
149                 alg = ALG_WEP;
150                 break;
151         case WLAN_CIPHER_SUITE_TKIP:
152                 alg = ALG_TKIP;
153                 break;
154         case WLAN_CIPHER_SUITE_CCMP:
155                 alg = ALG_CCMP;
156                 break;
157         default:
158                 return -EINVAL;
159         }
160
161         key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
162         if (!key)
163                 return -ENOMEM;
164
165         rcu_read_lock();
166
167         if (mac_addr) {
168                 sta = sta_info_get(sdata->local, mac_addr);
169                 if (!sta) {
170                         ieee80211_key_free(key);
171                         err = -ENOENT;
172                         goto out_unlock;
173                 }
174         }
175
176         ieee80211_key_link(key, sdata, sta);
177
178         err = 0;
179  out_unlock:
180         rcu_read_unlock();
181
182         return err;
183 }
184
185 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
186                              u8 key_idx, u8 *mac_addr)
187 {
188         struct ieee80211_local *local = wiphy_priv(wiphy);
189         struct ieee80211_sub_if_data *sdata;
190         struct sta_info *sta;
191         int ret;
192
193         if (dev == local->mdev)
194                 return -EOPNOTSUPP;
195
196         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
197
198         rcu_read_lock();
199
200         if (mac_addr) {
201                 ret = -ENOENT;
202
203                 sta = sta_info_get(sdata->local, mac_addr);
204                 if (!sta)
205                         goto out_unlock;
206
207                 if (sta->key) {
208                         ieee80211_key_free(sta->key);
209                         WARN_ON(sta->key);
210                         ret = 0;
211                 }
212
213                 goto out_unlock;
214         }
215
216         if (!sdata->keys[key_idx]) {
217                 ret = -ENOENT;
218                 goto out_unlock;
219         }
220
221         ieee80211_key_free(sdata->keys[key_idx]);
222         WARN_ON(sdata->keys[key_idx]);
223
224         ret = 0;
225  out_unlock:
226         rcu_read_unlock();
227
228         return ret;
229 }
230
231 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
232                              u8 key_idx, u8 *mac_addr, void *cookie,
233                              void (*callback)(void *cookie,
234                                               struct key_params *params))
235 {
236         struct ieee80211_local *local = wiphy_priv(wiphy);
237         struct ieee80211_sub_if_data *sdata;
238         struct sta_info *sta = NULL;
239         u8 seq[6] = {0};
240         struct key_params params;
241         struct ieee80211_key *key;
242         u32 iv32;
243         u16 iv16;
244         int err = -ENOENT;
245
246         if (dev == local->mdev)
247                 return -EOPNOTSUPP;
248
249         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
250
251         rcu_read_lock();
252
253         if (mac_addr) {
254                 sta = sta_info_get(sdata->local, mac_addr);
255                 if (!sta)
256                         goto out;
257
258                 key = sta->key;
259         } else
260                 key = sdata->keys[key_idx];
261
262         if (!key)
263                 goto out;
264
265         memset(&params, 0, sizeof(params));
266
267         switch (key->conf.alg) {
268         case ALG_TKIP:
269                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
270
271                 iv32 = key->u.tkip.tx.iv32;
272                 iv16 = key->u.tkip.tx.iv16;
273
274                 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
275                     sdata->local->ops->get_tkip_seq)
276                         sdata->local->ops->get_tkip_seq(
277                                 local_to_hw(sdata->local),
278                                 key->conf.hw_key_idx,
279                                 &iv32, &iv16);
280
281                 seq[0] = iv16 & 0xff;
282                 seq[1] = (iv16 >> 8) & 0xff;
283                 seq[2] = iv32 & 0xff;
284                 seq[3] = (iv32 >> 8) & 0xff;
285                 seq[4] = (iv32 >> 16) & 0xff;
286                 seq[5] = (iv32 >> 24) & 0xff;
287                 params.seq = seq;
288                 params.seq_len = 6;
289                 break;
290         case ALG_CCMP:
291                 params.cipher = WLAN_CIPHER_SUITE_CCMP;
292                 seq[0] = key->u.ccmp.tx_pn[5];
293                 seq[1] = key->u.ccmp.tx_pn[4];
294                 seq[2] = key->u.ccmp.tx_pn[3];
295                 seq[3] = key->u.ccmp.tx_pn[2];
296                 seq[4] = key->u.ccmp.tx_pn[1];
297                 seq[5] = key->u.ccmp.tx_pn[0];
298                 params.seq = seq;
299                 params.seq_len = 6;
300                 break;
301         case ALG_WEP:
302                 if (key->conf.keylen == 5)
303                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
304                 else
305                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
306                 break;
307         }
308
309         params.key = key->conf.key;
310         params.key_len = key->conf.keylen;
311
312         callback(cookie, &params);
313         err = 0;
314
315  out:
316         rcu_read_unlock();
317         return err;
318 }
319
320 static int ieee80211_config_default_key(struct wiphy *wiphy,
321                                         struct net_device *dev,
322                                         u8 key_idx)
323 {
324         struct ieee80211_local *local = wiphy_priv(wiphy);
325         struct ieee80211_sub_if_data *sdata;
326
327         if (dev == local->mdev)
328                 return -EOPNOTSUPP;
329
330         rcu_read_lock();
331
332         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
333         ieee80211_set_default_key(sdata, key_idx);
334
335         rcu_read_unlock();
336
337         return 0;
338 }
339
340 static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
341 {
342         struct ieee80211_sub_if_data *sdata = sta->sdata;
343
344         sinfo->filled = STATION_INFO_INACTIVE_TIME |
345                         STATION_INFO_RX_BYTES |
346                         STATION_INFO_TX_BYTES;
347
348         sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
349         sinfo->rx_bytes = sta->rx_bytes;
350         sinfo->tx_bytes = sta->tx_bytes;
351
352         if (ieee80211_vif_is_mesh(&sdata->vif)) {
353 #ifdef CONFIG_MAC80211_MESH
354                 sinfo->filled |= STATION_INFO_LLID |
355                                  STATION_INFO_PLID |
356                                  STATION_INFO_PLINK_STATE;
357
358                 sinfo->llid = le16_to_cpu(sta->llid);
359                 sinfo->plid = le16_to_cpu(sta->plid);
360                 sinfo->plink_state = sta->plink_state;
361 #endif
362         }
363 }
364
365
366 static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
367                                  int idx, u8 *mac, struct station_info *sinfo)
368 {
369         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
370         struct sta_info *sta;
371         int ret = -ENOENT;
372
373         rcu_read_lock();
374
375         sta = sta_info_get_by_idx(local, idx, dev);
376         if (sta) {
377                 ret = 0;
378                 memcpy(mac, sta->addr, ETH_ALEN);
379                 sta_set_sinfo(sta, sinfo);
380         }
381
382         rcu_read_unlock();
383
384         return ret;
385 }
386
387 static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
388                                  u8 *mac, struct station_info *sinfo)
389 {
390         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
391         struct sta_info *sta;
392         int ret = -ENOENT;
393
394         rcu_read_lock();
395
396         /* XXX: verify sta->dev == dev */
397
398         sta = sta_info_get(local, mac);
399         if (sta) {
400                 ret = 0;
401                 sta_set_sinfo(sta, sinfo);
402         }
403
404         rcu_read_unlock();
405
406         return ret;
407 }
408
409 /*
410  * This handles both adding a beacon and setting new beacon info
411  */
412 static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
413                                    struct beacon_parameters *params)
414 {
415         struct beacon_data *new, *old;
416         int new_head_len, new_tail_len;
417         int size;
418         int err = -EINVAL;
419
420         old = sdata->u.ap.beacon;
421
422         /* head must not be zero-length */
423         if (params->head && !params->head_len)
424                 return -EINVAL;
425
426         /*
427          * This is a kludge. beacon interval should really be part
428          * of the beacon information.
429          */
430         if (params->interval) {
431                 sdata->local->hw.conf.beacon_int = params->interval;
432                 if (ieee80211_hw_config(sdata->local))
433                         return -EINVAL;
434                 /*
435                  * We updated some parameter so if below bails out
436                  * it's not an error.
437                  */
438                 err = 0;
439         }
440
441         /* Need to have a beacon head if we don't have one yet */
442         if (!params->head && !old)
443                 return err;
444
445         /* sorry, no way to start beaconing without dtim period */
446         if (!params->dtim_period && !old)
447                 return err;
448
449         /* new or old head? */
450         if (params->head)
451                 new_head_len = params->head_len;
452         else
453                 new_head_len = old->head_len;
454
455         /* new or old tail? */
456         if (params->tail || !old)
457                 /* params->tail_len will be zero for !params->tail */
458                 new_tail_len = params->tail_len;
459         else
460                 new_tail_len = old->tail_len;
461
462         size = sizeof(*new) + new_head_len + new_tail_len;
463
464         new = kzalloc(size, GFP_KERNEL);
465         if (!new)
466                 return -ENOMEM;
467
468         /* start filling the new info now */
469
470         /* new or old dtim period? */
471         if (params->dtim_period)
472                 new->dtim_period = params->dtim_period;
473         else
474                 new->dtim_period = old->dtim_period;
475
476         /*
477          * pointers go into the block we allocated,
478          * memory is | beacon_data | head | tail |
479          */
480         new->head = ((u8 *) new) + sizeof(*new);
481         new->tail = new->head + new_head_len;
482         new->head_len = new_head_len;
483         new->tail_len = new_tail_len;
484
485         /* copy in head */
486         if (params->head)
487                 memcpy(new->head, params->head, new_head_len);
488         else
489                 memcpy(new->head, old->head, new_head_len);
490
491         /* copy in optional tail */
492         if (params->tail)
493                 memcpy(new->tail, params->tail, new_tail_len);
494         else
495                 if (old)
496                         memcpy(new->tail, old->tail, new_tail_len);
497
498         rcu_assign_pointer(sdata->u.ap.beacon, new);
499
500         synchronize_rcu();
501
502         kfree(old);
503
504         return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
505 }
506
507 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
508                                 struct beacon_parameters *params)
509 {
510         struct ieee80211_local *local = wiphy_priv(wiphy);
511         struct ieee80211_sub_if_data *sdata;
512         struct beacon_data *old;
513
514         if (dev == local->mdev)
515                 return -EOPNOTSUPP;
516
517         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
518
519         if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
520                 return -EINVAL;
521
522         old = sdata->u.ap.beacon;
523
524         if (old)
525                 return -EALREADY;
526
527         return ieee80211_config_beacon(sdata, params);
528 }
529
530 static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
531                                 struct beacon_parameters *params)
532 {
533         struct ieee80211_local *local = wiphy_priv(wiphy);
534         struct ieee80211_sub_if_data *sdata;
535         struct beacon_data *old;
536
537         if (dev == local->mdev)
538                 return -EOPNOTSUPP;
539
540         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
541
542         if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
543                 return -EINVAL;
544
545         old = sdata->u.ap.beacon;
546
547         if (!old)
548                 return -ENOENT;
549
550         return ieee80211_config_beacon(sdata, params);
551 }
552
553 static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
554 {
555         struct ieee80211_local *local = wiphy_priv(wiphy);
556         struct ieee80211_sub_if_data *sdata;
557         struct beacon_data *old;
558
559         if (dev == local->mdev)
560                 return -EOPNOTSUPP;
561
562         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
563
564         if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
565                 return -EINVAL;
566
567         old = sdata->u.ap.beacon;
568
569         if (!old)
570                 return -ENOENT;
571
572         rcu_assign_pointer(sdata->u.ap.beacon, NULL);
573         synchronize_rcu();
574         kfree(old);
575
576         return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
577 }
578
579 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
580 struct iapp_layer2_update {
581         u8 da[ETH_ALEN];        /* broadcast */
582         u8 sa[ETH_ALEN];        /* STA addr */
583         __be16 len;             /* 6 */
584         u8 dsap;                /* 0 */
585         u8 ssap;                /* 0 */
586         u8 control;
587         u8 xid_info[3];
588 } __attribute__ ((packed));
589
590 static void ieee80211_send_layer2_update(struct sta_info *sta)
591 {
592         struct iapp_layer2_update *msg;
593         struct sk_buff *skb;
594
595         /* Send Level 2 Update Frame to update forwarding tables in layer 2
596          * bridge devices */
597
598         skb = dev_alloc_skb(sizeof(*msg));
599         if (!skb)
600                 return;
601         msg = (struct iapp_layer2_update *)skb_put(skb, sizeof(*msg));
602
603         /* 802.2 Type 1 Logical Link Control (LLC) Exchange Identifier (XID)
604          * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
605
606         memset(msg->da, 0xff, ETH_ALEN);
607         memcpy(msg->sa, sta->addr, ETH_ALEN);
608         msg->len = htons(6);
609         msg->dsap = 0;
610         msg->ssap = 0x01;       /* NULL LSAP, CR Bit: Response */
611         msg->control = 0xaf;    /* XID response lsb.1111F101.
612                                  * F=0 (no poll command; unsolicited frame) */
613         msg->xid_info[0] = 0x81;        /* XID format identifier */
614         msg->xid_info[1] = 1;   /* LLC types/classes: Type 1 LLC */
615         msg->xid_info[2] = 0;   /* XID sender's receive window size (RW) */
616
617         skb->dev = sta->sdata->dev;
618         skb->protocol = eth_type_trans(skb, sta->sdata->dev);
619         memset(skb->cb, 0, sizeof(skb->cb));
620         netif_rx(skb);
621 }
622
623 static void sta_apply_parameters(struct ieee80211_local *local,
624                                  struct sta_info *sta,
625                                  struct station_parameters *params)
626 {
627         u32 rates;
628         int i, j;
629         struct ieee80211_supported_band *sband;
630         struct ieee80211_sub_if_data *sdata = sta->sdata;
631
632         /*
633          * FIXME: updating the flags is racy when this function is
634          *        called from ieee80211_change_station(), this will
635          *        be resolved in a future patch.
636          */
637
638         if (params->station_flags & STATION_FLAG_CHANGED) {
639                 spin_lock_bh(&sta->lock);
640                 sta->flags &= ~WLAN_STA_AUTHORIZED;
641                 if (params->station_flags & STATION_FLAG_AUTHORIZED)
642                         sta->flags |= WLAN_STA_AUTHORIZED;
643
644                 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
645                 if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
646                         sta->flags |= WLAN_STA_SHORT_PREAMBLE;
647
648                 sta->flags &= ~WLAN_STA_WME;
649                 if (params->station_flags & STATION_FLAG_WME)
650                         sta->flags |= WLAN_STA_WME;
651                 spin_unlock_bh(&sta->lock);
652         }
653
654         /*
655          * FIXME: updating the following information is racy when this
656          *        function is called from ieee80211_change_station().
657          *        However, all this information should be static so
658          *        maybe we should just reject attemps to change it.
659          */
660
661         if (params->aid) {
662                 sta->aid = params->aid;
663                 if (sta->aid > IEEE80211_MAX_AID)
664                         sta->aid = 0; /* XXX: should this be an error? */
665         }
666
667         if (params->listen_interval >= 0)
668                 sta->listen_interval = params->listen_interval;
669
670         if (params->supported_rates) {
671                 rates = 0;
672                 sband = local->hw.wiphy->bands[local->oper_channel->band];
673
674                 for (i = 0; i < params->supported_rates_len; i++) {
675                         int rate = (params->supported_rates[i] & 0x7f) * 5;
676                         for (j = 0; j < sband->n_bitrates; j++) {
677                                 if (sband->bitrates[j].bitrate == rate)
678                                         rates |= BIT(j);
679                         }
680                 }
681                 sta->supp_rates[local->oper_channel->band] = rates;
682         }
683
684         if (params->ht_capa) {
685                 ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
686                                                &sta->ht_info);
687         }
688
689         if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
690                 switch (params->plink_action) {
691                 case PLINK_ACTION_OPEN:
692                         mesh_plink_open(sta);
693                         break;
694                 case PLINK_ACTION_BLOCK:
695                         mesh_plink_block(sta);
696                         break;
697                 }
698         }
699 }
700
701 static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
702                                  u8 *mac, struct station_parameters *params)
703 {
704         struct ieee80211_local *local = wiphy_priv(wiphy);
705         struct sta_info *sta;
706         struct ieee80211_sub_if_data *sdata;
707         int err;
708
709         if (dev == local->mdev || params->vlan == local->mdev)
710                 return -EOPNOTSUPP;
711
712         /* Prevent a race with changing the rate control algorithm */
713         if (!netif_running(dev))
714                 return -ENETDOWN;
715
716         if (params->vlan) {
717                 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
718
719                 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN &&
720                     sdata->vif.type != IEEE80211_IF_TYPE_AP)
721                         return -EINVAL;
722         } else
723                 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
724
725         if (compare_ether_addr(mac, dev->dev_addr) == 0)
726                 return -EINVAL;
727
728         if (is_multicast_ether_addr(mac))
729                 return -EINVAL;
730
731         sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
732         if (!sta)
733                 return -ENOMEM;
734
735         sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
736
737         sta_apply_parameters(local, sta, params);
738
739         rate_control_rate_init(sta, local);
740
741         rcu_read_lock();
742
743         err = sta_info_insert(sta);
744         if (err) {
745                 /* STA has been freed */
746                 rcu_read_unlock();
747                 return err;
748         }
749
750         if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
751             sdata->vif.type == IEEE80211_IF_TYPE_AP)
752                 ieee80211_send_layer2_update(sta);
753
754         rcu_read_unlock();
755
756         return 0;
757 }
758
759 static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
760                                  u8 *mac)
761 {
762         struct ieee80211_local *local = wiphy_priv(wiphy);
763         struct ieee80211_sub_if_data *sdata;
764         struct sta_info *sta;
765
766         if (dev == local->mdev)
767                 return -EOPNOTSUPP;
768
769         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
770
771         if (mac) {
772                 rcu_read_lock();
773
774                 /* XXX: get sta belonging to dev */
775                 sta = sta_info_get(local, mac);
776                 if (!sta) {
777                         rcu_read_unlock();
778                         return -ENOENT;
779                 }
780
781                 sta_info_unlink(&sta);
782                 rcu_read_unlock();
783
784                 sta_info_destroy(sta);
785         } else
786                 sta_info_flush(local, sdata);
787
788         return 0;
789 }
790
791 static int ieee80211_change_station(struct wiphy *wiphy,
792                                     struct net_device *dev,
793                                     u8 *mac,
794                                     struct station_parameters *params)
795 {
796         struct ieee80211_local *local = wiphy_priv(wiphy);
797         struct sta_info *sta;
798         struct ieee80211_sub_if_data *vlansdata;
799
800         if (dev == local->mdev || params->vlan == local->mdev)
801                 return -EOPNOTSUPP;
802
803         rcu_read_lock();
804
805         /* XXX: get sta belonging to dev */
806         sta = sta_info_get(local, mac);
807         if (!sta) {
808                 rcu_read_unlock();
809                 return -ENOENT;
810         }
811
812         if (params->vlan && params->vlan != sta->sdata->dev) {
813                 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
814
815                 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN &&
816                     vlansdata->vif.type != IEEE80211_IF_TYPE_AP) {
817                         rcu_read_unlock();
818                         return -EINVAL;
819                 }
820
821                 sta->sdata = vlansdata;
822                 ieee80211_send_layer2_update(sta);
823         }
824
825         sta_apply_parameters(local, sta, params);
826
827         rcu_read_unlock();
828
829         return 0;
830 }
831
832 #ifdef CONFIG_MAC80211_MESH
833 static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
834                                  u8 *dst, u8 *next_hop)
835 {
836         struct ieee80211_local *local = wiphy_priv(wiphy);
837         struct ieee80211_sub_if_data *sdata;
838         struct mesh_path *mpath;
839         struct sta_info *sta;
840         int err;
841
842         if (dev == local->mdev)
843                 return -EOPNOTSUPP;
844
845         if (!netif_running(dev))
846                 return -ENETDOWN;
847
848         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
849
850         if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
851                 return -ENOTSUPP;
852
853         rcu_read_lock();
854         sta = sta_info_get(local, next_hop);
855         if (!sta) {
856                 rcu_read_unlock();
857                 return -ENOENT;
858         }
859
860         err = mesh_path_add(dst, sdata);
861         if (err) {
862                 rcu_read_unlock();
863                 return err;
864         }
865
866         mpath = mesh_path_lookup(dst, sdata);
867         if (!mpath) {
868                 rcu_read_unlock();
869                 return -ENXIO;
870         }
871         mesh_path_fix_nexthop(mpath, sta);
872
873         rcu_read_unlock();
874         return 0;
875 }
876
877 static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
878                                  u8 *dst)
879 {
880         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
881
882         if (dst)
883                 return mesh_path_del(dst, sdata);
884
885         mesh_path_flush(sdata);
886         return 0;
887 }
888
889 static int ieee80211_change_mpath(struct wiphy *wiphy,
890                                     struct net_device *dev,
891                                     u8 *dst, u8 *next_hop)
892 {
893         struct ieee80211_local *local = wiphy_priv(wiphy);
894         struct ieee80211_sub_if_data *sdata;
895         struct mesh_path *mpath;
896         struct sta_info *sta;
897
898         if (dev == local->mdev)
899                 return -EOPNOTSUPP;
900
901         if (!netif_running(dev))
902                 return -ENETDOWN;
903
904         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
905
906         if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
907                 return -ENOTSUPP;
908
909         rcu_read_lock();
910
911         sta = sta_info_get(local, next_hop);
912         if (!sta) {
913                 rcu_read_unlock();
914                 return -ENOENT;
915         }
916
917         mpath = mesh_path_lookup(dst, sdata);
918         if (!mpath) {
919                 rcu_read_unlock();
920                 return -ENOENT;
921         }
922
923         mesh_path_fix_nexthop(mpath, sta);
924
925         rcu_read_unlock();
926         return 0;
927 }
928
929 static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
930                             struct mpath_info *pinfo)
931 {
932         if (mpath->next_hop)
933                 memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN);
934         else
935                 memset(next_hop, 0, ETH_ALEN);
936
937         pinfo->filled = MPATH_INFO_FRAME_QLEN |
938                         MPATH_INFO_DSN |
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->dsn = mpath->dsn;
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_DSN_VALID)
959                 pinfo->flags |= NL80211_MPATH_FLAG_DSN_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
968 static 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_local *local = wiphy_priv(wiphy);
973         struct ieee80211_sub_if_data *sdata;
974         struct mesh_path *mpath;
975
976         if (dev == local->mdev)
977                 return -EOPNOTSUPP;
978
979         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
980
981         if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
982                 return -ENOTSUPP;
983
984         rcu_read_lock();
985         mpath = mesh_path_lookup(dst, sdata);
986         if (!mpath) {
987                 rcu_read_unlock();
988                 return -ENOENT;
989         }
990         memcpy(dst, mpath->dst, ETH_ALEN);
991         mpath_set_pinfo(mpath, next_hop, pinfo);
992         rcu_read_unlock();
993         return 0;
994 }
995
996 static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
997                                  int idx, u8 *dst, u8 *next_hop,
998                                  struct mpath_info *pinfo)
999 {
1000         struct ieee80211_local *local = wiphy_priv(wiphy);
1001         struct ieee80211_sub_if_data *sdata;
1002         struct mesh_path *mpath;
1003
1004         if (dev == local->mdev)
1005                 return -EOPNOTSUPP;
1006
1007         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1008
1009         if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
1010                 return -ENOTSUPP;
1011
1012         rcu_read_lock();
1013         mpath = mesh_path_lookup_by_idx(idx, sdata);
1014         if (!mpath) {
1015                 rcu_read_unlock();
1016                 return -ENOENT;
1017         }
1018         memcpy(dst, mpath->dst, ETH_ALEN);
1019         mpath_set_pinfo(mpath, next_hop, pinfo);
1020         rcu_read_unlock();
1021         return 0;
1022 }
1023 #endif
1024
1025 static int ieee80211_change_bss(struct wiphy *wiphy,
1026                                 struct net_device *dev,
1027                                 struct bss_parameters *params)
1028 {
1029         struct ieee80211_local *local = wiphy_priv(wiphy);
1030         struct ieee80211_sub_if_data *sdata;
1031         u32 changed = 0;
1032
1033         if (dev == local->mdev)
1034                 return -EOPNOTSUPP;
1035
1036         sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1037
1038         if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
1039                 return -EINVAL;
1040
1041         if (params->use_cts_prot >= 0) {
1042                 sdata->bss_conf.use_cts_prot = params->use_cts_prot;
1043                 changed |= BSS_CHANGED_ERP_CTS_PROT;
1044         }
1045         if (params->use_short_preamble >= 0) {
1046                 sdata->bss_conf.use_short_preamble =
1047                         params->use_short_preamble;
1048                 changed |= BSS_CHANGED_ERP_PREAMBLE;
1049         }
1050         if (params->use_short_slot_time >= 0) {
1051                 sdata->bss_conf.use_short_slot =
1052                         params->use_short_slot_time;
1053                 changed |= BSS_CHANGED_ERP_SLOT;
1054         }
1055
1056         ieee80211_bss_info_change_notify(sdata, changed);
1057
1058         return 0;
1059 }
1060
1061 struct cfg80211_ops mac80211_config_ops = {
1062         .add_virtual_intf = ieee80211_add_iface,
1063         .del_virtual_intf = ieee80211_del_iface,
1064         .change_virtual_intf = ieee80211_change_iface,
1065         .add_key = ieee80211_add_key,
1066         .del_key = ieee80211_del_key,
1067         .get_key = ieee80211_get_key,
1068         .set_default_key = ieee80211_config_default_key,
1069         .add_beacon = ieee80211_add_beacon,
1070         .set_beacon = ieee80211_set_beacon,
1071         .del_beacon = ieee80211_del_beacon,
1072         .add_station = ieee80211_add_station,
1073         .del_station = ieee80211_del_station,
1074         .change_station = ieee80211_change_station,
1075         .get_station = ieee80211_get_station,
1076         .dump_station = ieee80211_dump_station,
1077 #ifdef CONFIG_MAC80211_MESH
1078         .add_mpath = ieee80211_add_mpath,
1079         .del_mpath = ieee80211_del_mpath,
1080         .change_mpath = ieee80211_change_mpath,
1081         .get_mpath = ieee80211_get_mpath,
1082         .dump_mpath = ieee80211_dump_mpath,
1083 #endif
1084         .change_bss = ieee80211_change_bss,
1085 };