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