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.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 7b5131bd6fa1..6dc3579c0ac5 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -36,6 +36,15 @@ static bool nl80211_type_check(enum nl80211_iftype type)
36 } 36 }
37} 37}
38 38
39static bool nl80211_params_check(enum nl80211_iftype type,
40 struct vif_params *params)
41{
42 if (!nl80211_type_check(type))
43 return false;
44
45 return true;
46}
47
39static int ieee80211_add_iface(struct wiphy *wiphy, char *name, 48static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
40 enum nl80211_iftype type, u32 *flags, 49 enum nl80211_iftype type, u32 *flags,
41 struct vif_params *params) 50 struct vif_params *params)
@@ -45,7 +54,7 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
45 struct ieee80211_sub_if_data *sdata; 54 struct ieee80211_sub_if_data *sdata;
46 int err; 55 int err;
47 56
48 if (!nl80211_type_check(type)) 57 if (!nl80211_params_check(type, params))
49 return -EINVAL; 58 return -EINVAL;
50 59
51 err = ieee80211_if_add(local, name, &dev, type, params); 60 err = ieee80211_if_add(local, name, &dev, type, params);
@@ -75,7 +84,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
75 if (netif_running(dev)) 84 if (netif_running(dev))
76 return -EBUSY; 85 return -EBUSY;
77 86
78 if (!nl80211_type_check(type)) 87 if (!nl80211_params_check(type, params))
79 return -EINVAL; 88 return -EINVAL;
80 89
81 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 90 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -92,6 +101,13 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
92 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags) 101 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
93 return 0; 102 return 0;
94 103
104 if (type == NL80211_IFTYPE_AP_VLAN &&
105 params && params->use_4addr == 0)
106 rcu_assign_pointer(sdata->u.vlan.sta, NULL);
107 else if (type == NL80211_IFTYPE_STATION &&
108 params && params->use_4addr >= 0)
109 sdata->u.mgd.use_4addr = params->use_4addr;
110
95 sdata->u.mntr_flags = *flags; 111 sdata->u.mntr_flags = *flags;
96 return 0; 112 return 0;
97} 113}
@@ -338,7 +354,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
338 sinfo->rx_packets = sta->rx_packets; 354 sinfo->rx_packets = sta->rx_packets;
339 sinfo->tx_packets = sta->tx_packets; 355 sinfo->tx_packets = sta->tx_packets;
340 356
341 if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { 357 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
358 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
342 sinfo->filled |= STATION_INFO_SIGNAL; 359 sinfo->filled |= STATION_INFO_SIGNAL;
343 sinfo->signal = (s8)sta->last_signal; 360 sinfo->signal = (s8)sta->last_signal;
344 } 361 }
@@ -377,13 +394,13 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
377static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, 394static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
378 int idx, u8 *mac, struct station_info *sinfo) 395 int idx, u8 *mac, struct station_info *sinfo)
379{ 396{
380 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 397 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
381 struct sta_info *sta; 398 struct sta_info *sta;
382 int ret = -ENOENT; 399 int ret = -ENOENT;
383 400
384 rcu_read_lock(); 401 rcu_read_lock();
385 402
386 sta = sta_info_get_by_idx(local, idx, dev); 403 sta = sta_info_get_by_idx(sdata, idx);
387 if (sta) { 404 if (sta) {
388 ret = 0; 405 ret = 0;
389 memcpy(mac, sta->sta.addr, ETH_ALEN); 406 memcpy(mac, sta->sta.addr, ETH_ALEN);
@@ -738,13 +755,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
738 755
739 err = sta_info_insert(sta); 756 err = sta_info_insert(sta);
740 if (err) { 757 if (err) {
741 /* STA has been freed */
742 if (err == -EEXIST && layer2_update) {
743 /* Need to update layer 2 devices on reassociation */
744 sta = sta_info_get(local, mac);
745 if (sta)
746 ieee80211_send_layer2_update(sta);
747 }
748 rcu_read_unlock(); 758 rcu_read_unlock();
749 return err; 759 return err;
750 } 760 }
@@ -813,6 +823,15 @@ static int ieee80211_change_station(struct wiphy *wiphy,
813 return -EINVAL; 823 return -EINVAL;
814 } 824 }
815 825
826 if (params->vlan->ieee80211_ptr->use_4addr) {
827 if (vlansdata->u.vlan.sta) {
828 rcu_read_unlock();
829 return -EBUSY;
830 }
831
832 rcu_assign_pointer(vlansdata->u.vlan.sta, sta);
833 }
834
816 sta->sdata = vlansdata; 835 sta->sdata = vlansdata;
817 ieee80211_send_layer2_update(sta); 836 ieee80211_send_layer2_update(sta);
818 } 837 }
@@ -914,7 +933,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
914 pinfo->generation = mesh_paths_generation; 933 pinfo->generation = mesh_paths_generation;
915 934
916 pinfo->filled = MPATH_INFO_FRAME_QLEN | 935 pinfo->filled = MPATH_INFO_FRAME_QLEN |
917 MPATH_INFO_DSN | 936 MPATH_INFO_SN |
918 MPATH_INFO_METRIC | 937 MPATH_INFO_METRIC |
919 MPATH_INFO_EXPTIME | 938 MPATH_INFO_EXPTIME |
920 MPATH_INFO_DISCOVERY_TIMEOUT | 939 MPATH_INFO_DISCOVERY_TIMEOUT |
@@ -922,7 +941,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
922 MPATH_INFO_FLAGS; 941 MPATH_INFO_FLAGS;
923 942
924 pinfo->frame_qlen = mpath->frame_queue.qlen; 943 pinfo->frame_qlen = mpath->frame_queue.qlen;
925 pinfo->dsn = mpath->dsn; 944 pinfo->sn = mpath->sn;
926 pinfo->metric = mpath->metric; 945 pinfo->metric = mpath->metric;
927 if (time_before(jiffies, mpath->exp_time)) 946 if (time_before(jiffies, mpath->exp_time))
928 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies); 947 pinfo->exptime = jiffies_to_msecs(mpath->exp_time - jiffies);
@@ -934,8 +953,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
934 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE; 953 pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
935 if (mpath->flags & MESH_PATH_RESOLVING) 954 if (mpath->flags & MESH_PATH_RESOLVING)
936 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING; 955 pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
937 if (mpath->flags & MESH_PATH_DSN_VALID) 956 if (mpath->flags & MESH_PATH_SN_VALID)
938 pinfo->flags |= NL80211_MPATH_FLAG_DSN_VALID; 957 pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
939 if (mpath->flags & MESH_PATH_FIXED) 958 if (mpath->flags & MESH_PATH_FIXED)
940 pinfo->flags |= NL80211_MPATH_FLAG_FIXED; 959 pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
941 if (mpath->flags & MESH_PATH_RESOLVING) 960 if (mpath->flags & MESH_PATH_RESOLVING)
@@ -1008,7 +1027,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1008{ 1027{
1009 struct mesh_config *conf; 1028 struct mesh_config *conf;
1010 struct ieee80211_sub_if_data *sdata; 1029 struct ieee80211_sub_if_data *sdata;
1030 struct ieee80211_if_mesh *ifmsh;
1031
1011 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1032 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1033 ifmsh = &sdata->u.mesh;
1012 1034
1013 /* Set the config options which we are interested in setting */ 1035 /* Set the config options which we are interested in setting */
1014 conf = &(sdata->u.mesh.mshcfg); 1036 conf = &(sdata->u.mesh.mshcfg);
@@ -1043,6 +1065,10 @@ static int ieee80211_set_mesh_params(struct wiphy *wiphy,
1043 mask)) 1065 mask))
1044 conf->dot11MeshHWMPnetDiameterTraversalTime = 1066 conf->dot11MeshHWMPnetDiameterTraversalTime =
1045 nconf->dot11MeshHWMPnetDiameterTraversalTime; 1067 nconf->dot11MeshHWMPnetDiameterTraversalTime;
1068 if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask)) {
1069 conf->dot11MeshHWMPRootMode = nconf->dot11MeshHWMPRootMode;
1070 ieee80211_mesh_root_setup(ifmsh);
1071 }
1046 return 0; 1072 return 0;
1047} 1073}
1048 1074