diff options
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 201 |
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 | ||
20 | static enum ieee80211_if_types | 20 | struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy) |
21 | nl80211_type_to_mac80211_type(enum nl80211_iftype type) | 21 | { |
22 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
23 | return &local->hw; | ||
24 | } | ||
25 | EXPORT_SYMBOL(wiphy_to_hw); | ||
26 | |||
27 | static 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, | |||
66 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | 64 | static 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, | |||
175 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | 169 | static 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, | |||
497 | static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, | 479 | static 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, | |||
520 | static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, | 498 | static 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 | ||
543 | static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) | 517 | static 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, | |||
862 | static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, | 825 | static 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 | ||
962 | static 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 | |||
1008 | struct cfg80211_ops mac80211_config_ops = { | 994 | struct 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 | }; |