aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c201
1 files changed, 94 insertions, 107 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 297c257864c7..855126a3039d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -17,26 +17,26 @@
17#include "rate.h" 17#include "rate.h"
18#include "mesh.h" 18#include "mesh.h"
19 19
20static enum ieee80211_if_types 20struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
21nl80211_type_to_mac80211_type(enum nl80211_iftype type) 21{
22 struct ieee80211_local *local = wiphy_priv(wiphy);
23 return &local->hw;
24}
25EXPORT_SYMBOL(wiphy_to_hw);
26
27static bool nl80211_type_check(enum nl80211_iftype type)
22{ 28{
23 switch (type) { 29 switch (type) {
24 case NL80211_IFTYPE_UNSPECIFIED:
25 return IEEE80211_IF_TYPE_STA;
26 case NL80211_IFTYPE_ADHOC: 30 case NL80211_IFTYPE_ADHOC:
27 return IEEE80211_IF_TYPE_IBSS;
28 case NL80211_IFTYPE_STATION: 31 case NL80211_IFTYPE_STATION:
29 return IEEE80211_IF_TYPE_STA;
30 case NL80211_IFTYPE_MONITOR: 32 case NL80211_IFTYPE_MONITOR:
31 return IEEE80211_IF_TYPE_MNTR;
32#ifdef CONFIG_MAC80211_MESH 33#ifdef CONFIG_MAC80211_MESH
33 case NL80211_IFTYPE_MESH_POINT: 34 case NL80211_IFTYPE_MESH_POINT:
34 return IEEE80211_IF_TYPE_MESH_POINT;
35#endif 35#endif
36 case NL80211_IFTYPE_WDS: 36 case NL80211_IFTYPE_WDS:
37 return IEEE80211_IF_TYPE_WDS; 37 return true;
38 default: 38 default:
39 return IEEE80211_IF_TYPE_INVALID; 39 return false;
40 } 40 }
41} 41}
42 42
@@ -45,17 +45,15 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
45 struct vif_params *params) 45 struct vif_params *params)
46{ 46{
47 struct ieee80211_local *local = wiphy_priv(wiphy); 47 struct ieee80211_local *local = wiphy_priv(wiphy);
48 enum ieee80211_if_types itype;
49 struct net_device *dev; 48 struct net_device *dev;
50 struct ieee80211_sub_if_data *sdata; 49 struct ieee80211_sub_if_data *sdata;
51 int err; 50 int err;
52 51
53 itype = nl80211_type_to_mac80211_type(type); 52 if (!nl80211_type_check(type))
54 if (itype == IEEE80211_IF_TYPE_INVALID)
55 return -EINVAL; 53 return -EINVAL;
56 54
57 err = ieee80211_if_add(local, name, &dev, itype, params); 55 err = ieee80211_if_add(local, name, &dev, type, params);
58 if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) 56 if (err || type != NL80211_IFTYPE_MONITOR || !flags)
59 return err; 57 return err;
60 58
61 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 59 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -66,13 +64,16 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
66static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 64static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
67{ 65{
68 struct net_device *dev; 66 struct net_device *dev;
67 struct ieee80211_sub_if_data *sdata;
69 68
70 /* we're under RTNL */ 69 /* we're under RTNL */
71 dev = __dev_get_by_index(&init_net, ifindex); 70 dev = __dev_get_by_index(&init_net, ifindex);
72 if (!dev) 71 if (!dev)
73 return -ENODEV; 72 return -ENODEV;
74 73
75 ieee80211_if_remove(dev); 74 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
75
76 ieee80211_if_remove(sdata);
76 77
77 return 0; 78 return 0;
78} 79}
@@ -81,9 +82,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
81 enum nl80211_iftype type, u32 *flags, 82 enum nl80211_iftype type, u32 *flags,
82 struct vif_params *params) 83 struct vif_params *params)
83{ 84{
84 struct ieee80211_local *local = wiphy_priv(wiphy);
85 struct net_device *dev; 85 struct net_device *dev;
86 enum ieee80211_if_types itype;
87 struct ieee80211_sub_if_data *sdata; 86 struct ieee80211_sub_if_data *sdata;
88 int ret; 87 int ret;
89 88
@@ -92,25 +91,24 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
92 if (!dev) 91 if (!dev)
93 return -ENODEV; 92 return -ENODEV;
94 93
95 itype = nl80211_type_to_mac80211_type(type); 94 if (!nl80211_type_check(type))
96 if (itype == IEEE80211_IF_TYPE_INVALID)
97 return -EINVAL; 95 return -EINVAL;
98 96
99 if (dev == local->mdev)
100 return -EOPNOTSUPP;
101
102 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 97 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
103 98
104 ret = ieee80211_if_change_type(sdata, itype); 99 ret = ieee80211_if_change_type(sdata, type);
105 if (ret) 100 if (ret)
106 return ret; 101 return ret;
107 102
103 if (netif_running(sdata->dev))
104 return -EBUSY;
105
108 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) 106 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
109 ieee80211_if_sta_set_mesh_id(&sdata->u.sta, 107 ieee80211_sdata_set_mesh_id(sdata,
110 params->mesh_id_len, 108 params->mesh_id_len,
111 params->mesh_id); 109 params->mesh_id);
112 110
113 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) 111 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
114 return 0; 112 return 0;
115 113
116 sdata->u.mntr_flags = *flags; 114 sdata->u.mntr_flags = *flags;
@@ -121,16 +119,12 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
121 u8 key_idx, u8 *mac_addr, 119 u8 key_idx, u8 *mac_addr,
122 struct key_params *params) 120 struct key_params *params)
123{ 121{
124 struct ieee80211_local *local = wiphy_priv(wiphy);
125 struct ieee80211_sub_if_data *sdata; 122 struct ieee80211_sub_if_data *sdata;
126 struct sta_info *sta = NULL; 123 struct sta_info *sta = NULL;
127 enum ieee80211_key_alg alg; 124 enum ieee80211_key_alg alg;
128 struct ieee80211_key *key; 125 struct ieee80211_key *key;
129 int err; 126 int err;
130 127
131 if (dev == local->mdev)
132 return -EOPNOTSUPP;
133
134 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 128 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
135 129
136 switch (params->cipher) { 130 switch (params->cipher) {
@@ -175,14 +169,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
175static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 169static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
176 u8 key_idx, u8 *mac_addr) 170 u8 key_idx, u8 *mac_addr)
177{ 171{
178 struct ieee80211_local *local = wiphy_priv(wiphy);
179 struct ieee80211_sub_if_data *sdata; 172 struct ieee80211_sub_if_data *sdata;
180 struct sta_info *sta; 173 struct sta_info *sta;
181 int ret; 174 int ret;
182 175
183 if (dev == local->mdev)
184 return -EOPNOTSUPP;
185
186 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 176 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
187 177
188 rcu_read_lock(); 178 rcu_read_lock();
@@ -223,7 +213,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
223 void (*callback)(void *cookie, 213 void (*callback)(void *cookie,
224 struct key_params *params)) 214 struct key_params *params))
225{ 215{
226 struct ieee80211_local *local = wiphy_priv(wiphy);
227 struct ieee80211_sub_if_data *sdata; 216 struct ieee80211_sub_if_data *sdata;
228 struct sta_info *sta = NULL; 217 struct sta_info *sta = NULL;
229 u8 seq[6] = {0}; 218 u8 seq[6] = {0};
@@ -233,9 +222,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
233 u16 iv16; 222 u16 iv16;
234 int err = -ENOENT; 223 int err = -ENOENT;
235 224
236 if (dev == local->mdev)
237 return -EOPNOTSUPP;
238
239 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 225 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
240 226
241 rcu_read_lock(); 227 rcu_read_lock();
@@ -311,12 +297,8 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
311 struct net_device *dev, 297 struct net_device *dev,
312 u8 key_idx) 298 u8 key_idx)
313{ 299{
314 struct ieee80211_local *local = wiphy_priv(wiphy);
315 struct ieee80211_sub_if_data *sdata; 300 struct ieee80211_sub_if_data *sdata;
316 301
317 if (dev == local->mdev)
318 return -EOPNOTSUPP;
319
320 rcu_read_lock(); 302 rcu_read_lock();
321 303
322 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 304 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -365,7 +347,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
365 sta = sta_info_get_by_idx(local, idx, dev); 347 sta = sta_info_get_by_idx(local, idx, dev);
366 if (sta) { 348 if (sta) {
367 ret = 0; 349 ret = 0;
368 memcpy(mac, sta->addr, ETH_ALEN); 350 memcpy(mac, sta->sta.addr, ETH_ALEN);
369 sta_set_sinfo(sta, sinfo); 351 sta_set_sinfo(sta, sinfo);
370 } 352 }
371 353
@@ -497,16 +479,12 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
497static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 479static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
498 struct beacon_parameters *params) 480 struct beacon_parameters *params)
499{ 481{
500 struct ieee80211_local *local = wiphy_priv(wiphy);
501 struct ieee80211_sub_if_data *sdata; 482 struct ieee80211_sub_if_data *sdata;
502 struct beacon_data *old; 483 struct beacon_data *old;
503 484
504 if (dev == local->mdev)
505 return -EOPNOTSUPP;
506
507 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 485 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
508 486
509 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 487 if (sdata->vif.type != NL80211_IFTYPE_AP)
510 return -EINVAL; 488 return -EINVAL;
511 489
512 old = sdata->u.ap.beacon; 490 old = sdata->u.ap.beacon;
@@ -520,16 +498,12 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
520static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 498static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
521 struct beacon_parameters *params) 499 struct beacon_parameters *params)
522{ 500{
523 struct ieee80211_local *local = wiphy_priv(wiphy);
524 struct ieee80211_sub_if_data *sdata; 501 struct ieee80211_sub_if_data *sdata;
525 struct beacon_data *old; 502 struct beacon_data *old;
526 503
527 if (dev == local->mdev)
528 return -EOPNOTSUPP;
529
530 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 504 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
531 505
532 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 506 if (sdata->vif.type != NL80211_IFTYPE_AP)
533 return -EINVAL; 507 return -EINVAL;
534 508
535 old = sdata->u.ap.beacon; 509 old = sdata->u.ap.beacon;
@@ -542,16 +516,12 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
542 516
543static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 517static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
544{ 518{
545 struct ieee80211_local *local = wiphy_priv(wiphy);
546 struct ieee80211_sub_if_data *sdata; 519 struct ieee80211_sub_if_data *sdata;
547 struct beacon_data *old; 520 struct beacon_data *old;
548 521
549 if (dev == local->mdev)
550 return -EOPNOTSUPP;
551
552 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 522 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
553 523
554 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 524 if (sdata->vif.type != NL80211_IFTYPE_AP)
555 return -EINVAL; 525 return -EINVAL;
556 526
557 old = sdata->u.ap.beacon; 527 old = sdata->u.ap.beacon;
@@ -594,7 +564,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
594 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 564 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
595 565
596 memset(msg->da, 0xff, ETH_ALEN); 566 memset(msg->da, 0xff, ETH_ALEN);
597 memcpy(msg->sa, sta->addr, ETH_ALEN); 567 memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
598 msg->len = htons(6); 568 msg->len = htons(6);
599 msg->dsap = 0; 569 msg->dsap = 0;
600 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ 570 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
@@ -649,9 +619,9 @@ static void sta_apply_parameters(struct ieee80211_local *local,
649 */ 619 */
650 620
651 if (params->aid) { 621 if (params->aid) {
652 sta->aid = params->aid; 622 sta->sta.aid = params->aid;
653 if (sta->aid > IEEE80211_MAX_AID) 623 if (sta->sta.aid > IEEE80211_MAX_AID)
654 sta->aid = 0; /* XXX: should this be an error? */ 624 sta->sta.aid = 0; /* XXX: should this be an error? */
655 } 625 }
656 626
657 if (params->listen_interval >= 0) 627 if (params->listen_interval >= 0)
@@ -668,7 +638,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
668 rates |= BIT(j); 638 rates |= BIT(j);
669 } 639 }
670 } 640 }
671 sta->supp_rates[local->oper_channel->band] = rates; 641 sta->sta.supp_rates[local->oper_channel->band] = rates;
642 }
643
644 if (params->ht_capa) {
645 ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
646 &sta->sta.ht_info);
672 } 647 }
673 648
674 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 649 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
@@ -691,9 +666,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
691 struct ieee80211_sub_if_data *sdata; 666 struct ieee80211_sub_if_data *sdata;
692 int err; 667 int err;
693 668
694 if (dev == local->mdev || params->vlan == local->mdev)
695 return -EOPNOTSUPP;
696
697 /* Prevent a race with changing the rate control algorithm */ 669 /* Prevent a race with changing the rate control algorithm */
698 if (!netif_running(dev)) 670 if (!netif_running(dev))
699 return -ENETDOWN; 671 return -ENETDOWN;
@@ -701,8 +673,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
701 if (params->vlan) { 673 if (params->vlan) {
702 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 674 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
703 675
704 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN && 676 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
705 sdata->vif.type != IEEE80211_IF_TYPE_AP) 677 sdata->vif.type != NL80211_IFTYPE_AP)
706 return -EINVAL; 678 return -EINVAL;
707 } else 679 } else
708 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 680 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -721,7 +693,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
721 693
722 sta_apply_parameters(local, sta, params); 694 sta_apply_parameters(local, sta, params);
723 695
724 rate_control_rate_init(sta, local); 696 rate_control_rate_init(sta);
725 697
726 rcu_read_lock(); 698 rcu_read_lock();
727 699
@@ -732,8 +704,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
732 return err; 704 return err;
733 } 705 }
734 706
735 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || 707 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
736 sdata->vif.type == IEEE80211_IF_TYPE_AP) 708 sdata->vif.type == NL80211_IFTYPE_AP)
737 ieee80211_send_layer2_update(sta); 709 ieee80211_send_layer2_update(sta);
738 710
739 rcu_read_unlock(); 711 rcu_read_unlock();
@@ -748,9 +720,6 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
748 struct ieee80211_sub_if_data *sdata; 720 struct ieee80211_sub_if_data *sdata;
749 struct sta_info *sta; 721 struct sta_info *sta;
750 722
751 if (dev == local->mdev)
752 return -EOPNOTSUPP;
753
754 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 723 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
755 724
756 if (mac) { 725 if (mac) {
@@ -782,9 +751,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
782 struct sta_info *sta; 751 struct sta_info *sta;
783 struct ieee80211_sub_if_data *vlansdata; 752 struct ieee80211_sub_if_data *vlansdata;
784 753
785 if (dev == local->mdev || params->vlan == local->mdev)
786 return -EOPNOTSUPP;
787
788 rcu_read_lock(); 754 rcu_read_lock();
789 755
790 /* XXX: get sta belonging to dev */ 756 /* XXX: get sta belonging to dev */
@@ -797,8 +763,8 @@ static int ieee80211_change_station(struct wiphy *wiphy,
797 if (params->vlan && params->vlan != sta->sdata->dev) { 763 if (params->vlan && params->vlan != sta->sdata->dev) {
798 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 764 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
799 765
800 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN && 766 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
801 vlansdata->vif.type != IEEE80211_IF_TYPE_AP) { 767 vlansdata->vif.type != NL80211_IFTYPE_AP) {
802 rcu_read_unlock(); 768 rcu_read_unlock();
803 return -EINVAL; 769 return -EINVAL;
804 } 770 }
@@ -824,15 +790,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
824 struct sta_info *sta; 790 struct sta_info *sta;
825 int err; 791 int err;
826 792
827 if (dev == local->mdev)
828 return -EOPNOTSUPP;
829
830 if (!netif_running(dev)) 793 if (!netif_running(dev))
831 return -ENETDOWN; 794 return -ENETDOWN;
832 795
833 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 796 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
834 797
835 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 798 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
836 return -ENOTSUPP; 799 return -ENOTSUPP;
837 800
838 rcu_read_lock(); 801 rcu_read_lock();
@@ -842,13 +805,13 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
842 return -ENOENT; 805 return -ENOENT;
843 } 806 }
844 807
845 err = mesh_path_add(dst, dev); 808 err = mesh_path_add(dst, sdata);
846 if (err) { 809 if (err) {
847 rcu_read_unlock(); 810 rcu_read_unlock();
848 return err; 811 return err;
849 } 812 }
850 813
851 mpath = mesh_path_lookup(dst, dev); 814 mpath = mesh_path_lookup(dst, sdata);
852 if (!mpath) { 815 if (!mpath) {
853 rcu_read_unlock(); 816 rcu_read_unlock();
854 return -ENXIO; 817 return -ENXIO;
@@ -862,10 +825,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
862static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 825static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
863 u8 *dst) 826 u8 *dst)
864{ 827{
828 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
829
865 if (dst) 830 if (dst)
866 return mesh_path_del(dst, dev); 831 return mesh_path_del(dst, sdata);
867 832
868 mesh_path_flush(dev); 833 mesh_path_flush(sdata);
869 return 0; 834 return 0;
870} 835}
871 836
@@ -878,15 +843,12 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
878 struct mesh_path *mpath; 843 struct mesh_path *mpath;
879 struct sta_info *sta; 844 struct sta_info *sta;
880 845
881 if (dev == local->mdev)
882 return -EOPNOTSUPP;
883
884 if (!netif_running(dev)) 846 if (!netif_running(dev))
885 return -ENETDOWN; 847 return -ENETDOWN;
886 848
887 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 849 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
888 850
889 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 851 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
890 return -ENOTSUPP; 852 return -ENOTSUPP;
891 853
892 rcu_read_lock(); 854 rcu_read_lock();
@@ -897,7 +859,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
897 return -ENOENT; 859 return -ENOENT;
898 } 860 }
899 861
900 mpath = mesh_path_lookup(dst, dev); 862 mpath = mesh_path_lookup(dst, sdata);
901 if (!mpath) { 863 if (!mpath) {
902 rcu_read_unlock(); 864 rcu_read_unlock();
903 return -ENOENT; 865 return -ENOENT;
@@ -913,7 +875,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
913 struct mpath_info *pinfo) 875 struct mpath_info *pinfo)
914{ 876{
915 if (mpath->next_hop) 877 if (mpath->next_hop)
916 memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN); 878 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
917 else 879 else
918 memset(next_hop, 0, ETH_ALEN); 880 memset(next_hop, 0, ETH_ALEN);
919 881
@@ -952,20 +914,16 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
952 u8 *dst, u8 *next_hop, struct mpath_info *pinfo) 914 u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
953 915
954{ 916{
955 struct ieee80211_local *local = wiphy_priv(wiphy);
956 struct ieee80211_sub_if_data *sdata; 917 struct ieee80211_sub_if_data *sdata;
957 struct mesh_path *mpath; 918 struct mesh_path *mpath;
958 919
959 if (dev == local->mdev)
960 return -EOPNOTSUPP;
961
962 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 920 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
963 921
964 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 922 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
965 return -ENOTSUPP; 923 return -ENOTSUPP;
966 924
967 rcu_read_lock(); 925 rcu_read_lock();
968 mpath = mesh_path_lookup(dst, dev); 926 mpath = mesh_path_lookup(dst, sdata);
969 if (!mpath) { 927 if (!mpath) {
970 rcu_read_unlock(); 928 rcu_read_unlock();
971 return -ENOENT; 929 return -ENOENT;
@@ -980,20 +938,16 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
980 int idx, u8 *dst, u8 *next_hop, 938 int idx, u8 *dst, u8 *next_hop,
981 struct mpath_info *pinfo) 939 struct mpath_info *pinfo)
982{ 940{
983 struct ieee80211_local *local = wiphy_priv(wiphy);
984 struct ieee80211_sub_if_data *sdata; 941 struct ieee80211_sub_if_data *sdata;
985 struct mesh_path *mpath; 942 struct mesh_path *mpath;
986 943
987 if (dev == local->mdev)
988 return -EOPNOTSUPP;
989
990 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 944 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
991 945
992 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 946 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
993 return -ENOTSUPP; 947 return -ENOTSUPP;
994 948
995 rcu_read_lock(); 949 rcu_read_lock();
996 mpath = mesh_path_lookup_by_idx(idx, dev); 950 mpath = mesh_path_lookup_by_idx(idx, sdata);
997 if (!mpath) { 951 if (!mpath) {
998 rcu_read_unlock(); 952 rcu_read_unlock();
999 return -ENOENT; 953 return -ENOENT;
@@ -1005,6 +959,38 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1005} 959}
1006#endif 960#endif
1007 961
962static int ieee80211_change_bss(struct wiphy *wiphy,
963 struct net_device *dev,
964 struct bss_parameters *params)
965{
966 struct ieee80211_sub_if_data *sdata;
967 u32 changed = 0;
968
969 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
970
971 if (sdata->vif.type != NL80211_IFTYPE_AP)
972 return -EINVAL;
973
974 if (params->use_cts_prot >= 0) {
975 sdata->bss_conf.use_cts_prot = params->use_cts_prot;
976 changed |= BSS_CHANGED_ERP_CTS_PROT;
977 }
978 if (params->use_short_preamble >= 0) {
979 sdata->bss_conf.use_short_preamble =
980 params->use_short_preamble;
981 changed |= BSS_CHANGED_ERP_PREAMBLE;
982 }
983 if (params->use_short_slot_time >= 0) {
984 sdata->bss_conf.use_short_slot =
985 params->use_short_slot_time;
986 changed |= BSS_CHANGED_ERP_SLOT;
987 }
988
989 ieee80211_bss_info_change_notify(sdata, changed);
990
991 return 0;
992}
993
1008struct cfg80211_ops mac80211_config_ops = { 994struct cfg80211_ops mac80211_config_ops = {
1009 .add_virtual_intf = ieee80211_add_iface, 995 .add_virtual_intf = ieee80211_add_iface,
1010 .del_virtual_intf = ieee80211_del_iface, 996 .del_virtual_intf = ieee80211_del_iface,
@@ -1028,4 +1014,5 @@ struct cfg80211_ops mac80211_config_ops = {
1028 .get_mpath = ieee80211_get_mpath, 1014 .get_mpath = ieee80211_get_mpath,
1029 .dump_mpath = ieee80211_dump_mpath, 1015 .dump_mpath = ieee80211_dump_mpath,
1030#endif 1016#endif
1017 .change_bss = ieee80211_change_bss,
1031}; 1018};