diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/Makefile | 3 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 58 | ||||
-rw-r--r-- | net/mac80211/chan.c | 127 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 5 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 16 | ||||
-rw-r--r-- | net/mac80211/main.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 44 | ||||
-rw-r--r-- | net/mac80211/tx.c | 5 | ||||
-rw-r--r-- | net/mac80211/util.c | 25 |
9 files changed, 249 insertions, 36 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 04420291e7ad..84b48ba8a77e 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -23,7 +23,8 @@ mac80211-y := \ | |||
23 | key.o \ | 23 | key.o \ |
24 | util.o \ | 24 | util.o \ |
25 | wme.o \ | 25 | wme.o \ |
26 | event.o | 26 | event.o \ |
27 | chan.o | ||
27 | 28 | ||
28 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o | 29 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o |
29 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ | 30 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ae37270a0633..c7000a6ca379 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1162,15 +1162,39 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | static int ieee80211_set_channel(struct wiphy *wiphy, | 1164 | static int ieee80211_set_channel(struct wiphy *wiphy, |
1165 | struct net_device *netdev, | ||
1165 | struct ieee80211_channel *chan, | 1166 | struct ieee80211_channel *chan, |
1166 | enum nl80211_channel_type channel_type) | 1167 | enum nl80211_channel_type channel_type) |
1167 | { | 1168 | { |
1168 | struct ieee80211_local *local = wiphy_priv(wiphy); | 1169 | struct ieee80211_local *local = wiphy_priv(wiphy); |
1170 | struct ieee80211_sub_if_data *sdata = NULL; | ||
1171 | |||
1172 | if (netdev) | ||
1173 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
1174 | |||
1175 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
1176 | case CHAN_MODE_HOPPING: | ||
1177 | return -EBUSY; | ||
1178 | case CHAN_MODE_FIXED: | ||
1179 | if (local->oper_channel != chan) | ||
1180 | return -EBUSY; | ||
1181 | if (!sdata && local->_oper_channel_type == channel_type) | ||
1182 | return 0; | ||
1183 | break; | ||
1184 | case CHAN_MODE_UNDEFINED: | ||
1185 | break; | ||
1186 | } | ||
1169 | 1187 | ||
1170 | local->oper_channel = chan; | 1188 | local->oper_channel = chan; |
1171 | local->oper_channel_type = channel_type; | ||
1172 | 1189 | ||
1173 | return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 1190 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) |
1191 | return -EBUSY; | ||
1192 | |||
1193 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
1194 | if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR) | ||
1195 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | ||
1196 | |||
1197 | return 0; | ||
1174 | } | 1198 | } |
1175 | 1199 | ||
1176 | #ifdef CONFIG_PM | 1200 | #ifdef CONFIG_PM |
@@ -1214,6 +1238,20 @@ static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, | |||
1214 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, | 1238 | static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev, |
1215 | struct cfg80211_assoc_request *req) | 1239 | struct cfg80211_assoc_request *req) |
1216 | { | 1240 | { |
1241 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1242 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
1243 | |||
1244 | switch (ieee80211_get_channel_mode(local, sdata)) { | ||
1245 | case CHAN_MODE_HOPPING: | ||
1246 | return -EBUSY; | ||
1247 | case CHAN_MODE_FIXED: | ||
1248 | if (local->oper_channel == req->bss->channel) | ||
1249 | break; | ||
1250 | return -EBUSY; | ||
1251 | case CHAN_MODE_UNDEFINED: | ||
1252 | break; | ||
1253 | } | ||
1254 | |||
1217 | return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); | 1255 | return ieee80211_mgd_assoc(IEEE80211_DEV_TO_SUB_IF(dev), req); |
1218 | } | 1256 | } |
1219 | 1257 | ||
@@ -1236,8 +1274,22 @@ static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev, | |||
1236 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | 1274 | static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, |
1237 | struct cfg80211_ibss_params *params) | 1275 | struct cfg80211_ibss_params *params) |
1238 | { | 1276 | { |
1277 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1239 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1278 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1240 | 1279 | ||
1280 | switch (ieee80211_get_channel_mode(local, sdata)) { | ||
1281 | case CHAN_MODE_HOPPING: | ||
1282 | return -EBUSY; | ||
1283 | case CHAN_MODE_FIXED: | ||
1284 | if (!params->channel_fixed) | ||
1285 | return -EBUSY; | ||
1286 | if (local->oper_channel == params->channel) | ||
1287 | break; | ||
1288 | return -EBUSY; | ||
1289 | case CHAN_MODE_UNDEFINED: | ||
1290 | break; | ||
1291 | } | ||
1292 | |||
1241 | return ieee80211_ibss_join(sdata, params); | 1293 | return ieee80211_ibss_join(sdata, params); |
1242 | } | 1294 | } |
1243 | 1295 | ||
@@ -1366,7 +1418,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | |||
1366 | * association, there's no need to send an action frame. | 1418 | * association, there's no need to send an action frame. |
1367 | */ | 1419 | */ |
1368 | if (!sdata->u.mgd.associated || | 1420 | if (!sdata->u.mgd.associated || |
1369 | sdata->local->oper_channel_type == NL80211_CHAN_NO_HT) { | 1421 | sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT) { |
1370 | mutex_lock(&sdata->local->iflist_mtx); | 1422 | mutex_lock(&sdata->local->iflist_mtx); |
1371 | ieee80211_recalc_smps(sdata->local, sdata); | 1423 | ieee80211_recalc_smps(sdata->local, sdata); |
1372 | mutex_unlock(&sdata->local->iflist_mtx); | 1424 | mutex_unlock(&sdata->local->iflist_mtx); |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c new file mode 100644 index 000000000000..5d218c530a4e --- /dev/null +++ b/net/mac80211/chan.c | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * mac80211 - channel management | ||
3 | */ | ||
4 | |||
5 | #include <linux/nl80211.h> | ||
6 | #include "ieee80211_i.h" | ||
7 | |||
8 | enum ieee80211_chan_mode | ||
9 | __ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
10 | struct ieee80211_sub_if_data *ignore) | ||
11 | { | ||
12 | struct ieee80211_sub_if_data *sdata; | ||
13 | |||
14 | WARN_ON(!mutex_is_locked(&local->iflist_mtx)); | ||
15 | |||
16 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
17 | if (sdata == ignore) | ||
18 | continue; | ||
19 | |||
20 | if (!ieee80211_sdata_running(sdata)) | ||
21 | continue; | ||
22 | |||
23 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | ||
24 | continue; | ||
25 | |||
26 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
27 | !sdata->u.mgd.associated) | ||
28 | continue; | ||
29 | |||
30 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
31 | if (!sdata->u.ibss.ssid_len) | ||
32 | continue; | ||
33 | if (!sdata->u.ibss.fixed_channel) | ||
34 | return CHAN_MODE_HOPPING; | ||
35 | } | ||
36 | |||
37 | if (sdata->vif.type == NL80211_IFTYPE_AP && | ||
38 | !sdata->u.ap.beacon) | ||
39 | continue; | ||
40 | |||
41 | return CHAN_MODE_FIXED; | ||
42 | } | ||
43 | |||
44 | return CHAN_MODE_UNDEFINED; | ||
45 | } | ||
46 | |||
47 | enum ieee80211_chan_mode | ||
48 | ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
49 | struct ieee80211_sub_if_data *ignore) | ||
50 | { | ||
51 | enum ieee80211_chan_mode mode; | ||
52 | |||
53 | mutex_lock(&local->iflist_mtx); | ||
54 | mode = __ieee80211_get_channel_mode(local, ignore); | ||
55 | mutex_unlock(&local->iflist_mtx); | ||
56 | |||
57 | return mode; | ||
58 | } | ||
59 | |||
60 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | ||
61 | struct ieee80211_sub_if_data *sdata, | ||
62 | enum nl80211_channel_type chantype) | ||
63 | { | ||
64 | struct ieee80211_sub_if_data *tmp; | ||
65 | enum nl80211_channel_type superchan = NL80211_CHAN_NO_HT; | ||
66 | bool result; | ||
67 | |||
68 | mutex_lock(&local->iflist_mtx); | ||
69 | |||
70 | list_for_each_entry(tmp, &local->interfaces, list) { | ||
71 | if (tmp == sdata) | ||
72 | continue; | ||
73 | |||
74 | if (!ieee80211_sdata_running(tmp)) | ||
75 | continue; | ||
76 | |||
77 | switch (tmp->vif.bss_conf.channel_type) { | ||
78 | case NL80211_CHAN_NO_HT: | ||
79 | case NL80211_CHAN_HT20: | ||
80 | superchan = tmp->vif.bss_conf.channel_type; | ||
81 | break; | ||
82 | case NL80211_CHAN_HT40PLUS: | ||
83 | WARN_ON(superchan == NL80211_CHAN_HT40MINUS); | ||
84 | superchan = NL80211_CHAN_HT40PLUS; | ||
85 | break; | ||
86 | case NL80211_CHAN_HT40MINUS: | ||
87 | WARN_ON(superchan == NL80211_CHAN_HT40PLUS); | ||
88 | superchan = NL80211_CHAN_HT40MINUS; | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | switch (superchan) { | ||
94 | case NL80211_CHAN_NO_HT: | ||
95 | case NL80211_CHAN_HT20: | ||
96 | /* | ||
97 | * allow any change that doesn't go to no-HT | ||
98 | * (if it already is no-HT no change is needed) | ||
99 | */ | ||
100 | if (chantype == NL80211_CHAN_NO_HT) | ||
101 | break; | ||
102 | superchan = chantype; | ||
103 | break; | ||
104 | case NL80211_CHAN_HT40PLUS: | ||
105 | case NL80211_CHAN_HT40MINUS: | ||
106 | /* allow smaller bandwidth and same */ | ||
107 | if (chantype == NL80211_CHAN_NO_HT) | ||
108 | break; | ||
109 | if (chantype == NL80211_CHAN_HT20) | ||
110 | break; | ||
111 | if (superchan == chantype) | ||
112 | break; | ||
113 | result = false; | ||
114 | goto out; | ||
115 | } | ||
116 | |||
117 | local->_oper_channel_type = superchan; | ||
118 | |||
119 | if (sdata) | ||
120 | sdata->vif.bss_conf.channel_type = chantype; | ||
121 | |||
122 | result = true; | ||
123 | out: | ||
124 | mutex_unlock(&local->iflist_mtx); | ||
125 | |||
126 | return result; | ||
127 | } | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index b72ee6435fa3..b2cc1fda6cfd 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -103,7 +103,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
103 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; | 103 | sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0; |
104 | 104 | ||
105 | local->oper_channel = chan; | 105 | local->oper_channel = chan; |
106 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 106 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); |
107 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 107 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
108 | 108 | ||
109 | sband = local->hw.wiphy->bands[chan->band]; | 109 | sband = local->hw.wiphy->bands[chan->band]; |
@@ -911,7 +911,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
911 | /* fix ourselves to that channel now already */ | 911 | /* fix ourselves to that channel now already */ |
912 | if (params->channel_fixed) { | 912 | if (params->channel_fixed) { |
913 | sdata->local->oper_channel = params->channel; | 913 | sdata->local->oper_channel = params->channel; |
914 | sdata->local->oper_channel_type = NL80211_CHAN_NO_HT; | 914 | WARN_ON(!ieee80211_set_channel_type(sdata->local, sdata, |
915 | NL80211_CHAN_NO_HT)); | ||
915 | } | 916 | } |
916 | 917 | ||
917 | if (params->ie) { | 918 | if (params->ie) { |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index cbaf4981e110..7ef7798d04cd 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -767,7 +767,7 @@ struct ieee80211_local { | |||
767 | enum mac80211_scan_state next_scan_state; | 767 | enum mac80211_scan_state next_scan_state; |
768 | struct delayed_work scan_work; | 768 | struct delayed_work scan_work; |
769 | struct ieee80211_sub_if_data *scan_sdata; | 769 | struct ieee80211_sub_if_data *scan_sdata; |
770 | enum nl80211_channel_type oper_channel_type; | 770 | enum nl80211_channel_type _oper_channel_type; |
771 | struct ieee80211_channel *oper_channel, *csa_channel; | 771 | struct ieee80211_channel *oper_channel, *csa_channel; |
772 | 772 | ||
773 | /* Temporary remain-on-channel for off-channel operations */ | 773 | /* Temporary remain-on-channel for off-channel operations */ |
@@ -1228,6 +1228,20 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, | |||
1228 | int ieee80211_wk_cancel_remain_on_channel( | 1228 | int ieee80211_wk_cancel_remain_on_channel( |
1229 | struct ieee80211_sub_if_data *sdata, u64 cookie); | 1229 | struct ieee80211_sub_if_data *sdata, u64 cookie); |
1230 | 1230 | ||
1231 | /* channel management */ | ||
1232 | enum ieee80211_chan_mode { | ||
1233 | CHAN_MODE_UNDEFINED, | ||
1234 | CHAN_MODE_HOPPING, | ||
1235 | CHAN_MODE_FIXED, | ||
1236 | }; | ||
1237 | |||
1238 | enum ieee80211_chan_mode | ||
1239 | ieee80211_get_channel_mode(struct ieee80211_local *local, | ||
1240 | struct ieee80211_sub_if_data *ignore); | ||
1241 | bool ieee80211_set_channel_type(struct ieee80211_local *local, | ||
1242 | struct ieee80211_sub_if_data *sdata, | ||
1243 | enum nl80211_channel_type chantype); | ||
1244 | |||
1231 | #ifdef CONFIG_MAC80211_NOINLINE | 1245 | #ifdef CONFIG_MAC80211_NOINLINE |
1232 | #define debug_noinline noinline | 1246 | #define debug_noinline noinline |
1233 | #else | 1247 | #else |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index bd632e1ee2c5..22a384dfab65 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -111,7 +111,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
111 | channel_type = local->tmp_channel_type; | 111 | channel_type = local->tmp_channel_type; |
112 | } else { | 112 | } else { |
113 | chan = local->oper_channel; | 113 | chan = local->oper_channel; |
114 | channel_type = local->oper_channel_type; | 114 | channel_type = local->_oper_channel_type; |
115 | } | 115 | } |
116 | 116 | ||
117 | if (chan != local->hw.conf.channel || | 117 | if (chan != local->hw.conf.channel || |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 358226f63b81..11783192a625 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -137,11 +137,14 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
137 | struct sta_info *sta; | 137 | struct sta_info *sta; |
138 | u32 changed = 0; | 138 | u32 changed = 0; |
139 | u16 ht_opmode; | 139 | u16 ht_opmode; |
140 | bool enable_ht = true, ht_changed; | 140 | bool enable_ht = true; |
141 | enum nl80211_channel_type prev_chantype; | ||
141 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; | 142 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; |
142 | 143 | ||
143 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 144 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
144 | 145 | ||
146 | prev_chantype = sdata->vif.bss_conf.channel_type; | ||
147 | |||
145 | /* HT is not supported */ | 148 | /* HT is not supported */ |
146 | if (!sband->ht_cap.ht_supported) | 149 | if (!sband->ht_cap.ht_supported) |
147 | enable_ht = false; | 150 | enable_ht = false; |
@@ -172,38 +175,37 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
172 | } | 175 | } |
173 | } | 176 | } |
174 | 177 | ||
175 | ht_changed = conf_is_ht(&local->hw.conf) != enable_ht || | ||
176 | channel_type != local->hw.conf.channel_type; | ||
177 | |||
178 | if (local->tmp_channel) | 178 | if (local->tmp_channel) |
179 | local->tmp_channel_type = channel_type; | 179 | local->tmp_channel_type = channel_type; |
180 | local->oper_channel_type = channel_type; | ||
181 | 180 | ||
182 | if (ht_changed) { | 181 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { |
183 | /* channel_type change automatically detected */ | 182 | /* can only fail due to HT40+/- mismatch */ |
184 | ieee80211_hw_config(local, 0); | 183 | channel_type = NL80211_CHAN_HT20; |
184 | WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); | ||
185 | } | ||
185 | 186 | ||
187 | /* channel_type change automatically detected */ | ||
188 | ieee80211_hw_config(local, 0); | ||
189 | |||
190 | if (prev_chantype != channel_type) { | ||
186 | rcu_read_lock(); | 191 | rcu_read_lock(); |
187 | sta = sta_info_get(sdata, bssid); | 192 | sta = sta_info_get(sdata, bssid); |
188 | if (sta) | 193 | if (sta) |
189 | rate_control_rate_update(local, sband, sta, | 194 | rate_control_rate_update(local, sband, sta, |
190 | IEEE80211_RC_HT_CHANGED, | 195 | IEEE80211_RC_HT_CHANGED, |
191 | local->oper_channel_type); | 196 | channel_type); |
192 | rcu_read_unlock(); | 197 | rcu_read_unlock(); |
193 | } | 198 | } |
194 | |||
195 | /* disable HT */ | ||
196 | if (!enable_ht) | ||
197 | return 0; | ||
198 | 199 | ||
199 | ht_opmode = le16_to_cpu(hti->operation_mode); | 200 | ht_opmode = le16_to_cpu(hti->operation_mode); |
200 | 201 | ||
201 | /* if bss configuration changed store the new one */ | 202 | /* if bss configuration changed store the new one */ |
202 | if (!sdata->ht_opmode_valid || | 203 | if (sdata->ht_opmode_valid != enable_ht || |
203 | sdata->vif.bss_conf.ht_operation_mode != ht_opmode) { | 204 | sdata->vif.bss_conf.ht_operation_mode != ht_opmode || |
205 | prev_chantype != channel_type) { | ||
204 | changed |= BSS_CHANGED_HT; | 206 | changed |= BSS_CHANGED_HT; |
205 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; | 207 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; |
206 | sdata->ht_opmode_valid = true; | 208 | sdata->ht_opmode_valid = enable_ht; |
207 | } | 209 | } |
208 | 210 | ||
209 | return changed; | 211 | return changed; |
@@ -866,7 +868,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
866 | ieee80211_set_wmm_default(sdata); | 868 | ieee80211_set_wmm_default(sdata); |
867 | 869 | ||
868 | /* channel(_type) changes are handled by ieee80211_hw_config */ | 870 | /* channel(_type) changes are handled by ieee80211_hw_config */ |
869 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 871 | WARN_ON(!ieee80211_set_channel_type(local, sdata, NL80211_CHAN_NO_HT)); |
870 | 872 | ||
871 | /* on the next assoc, re-program HT parameters */ | 873 | /* on the next assoc, re-program HT parameters */ |
872 | sdata->ht_opmode_valid = false; | 874 | sdata->ht_opmode_valid = false; |
@@ -883,8 +885,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
883 | 885 | ||
884 | ieee80211_hw_config(local, config_changed); | 886 | ieee80211_hw_config(local, config_changed); |
885 | 887 | ||
886 | /* And the BSSID changed -- not very interesting here */ | 888 | /* The BSSID (not really interesting) and HT changed */ |
887 | changed |= BSS_CHANGED_BSSID; | 889 | changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT; |
888 | ieee80211_bss_info_change_notify(sdata, changed); | 890 | ieee80211_bss_info_change_notify(sdata, changed); |
889 | 891 | ||
890 | if (remove_sta) | 892 | if (remove_sta) |
@@ -2266,7 +2268,7 @@ int ieee80211_mgd_action(struct ieee80211_sub_if_data *sdata, | |||
2266 | if ((chan != local->tmp_channel || | 2268 | if ((chan != local->tmp_channel || |
2267 | channel_type != local->tmp_channel_type) && | 2269 | channel_type != local->tmp_channel_type) && |
2268 | (chan != local->oper_channel || | 2270 | (chan != local->oper_channel || |
2269 | channel_type != local->oper_channel_type)) | 2271 | channel_type != local->_oper_channel_type)) |
2270 | return -EBUSY; | 2272 | return -EBUSY; |
2271 | 2273 | ||
2272 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); | 2274 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index f3841f43249e..680bcb7093db 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2251,8 +2251,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2251 | 2251 | ||
2252 | info->control.vif = vif; | 2252 | info->control.vif = vif; |
2253 | 2253 | ||
2254 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | 2254 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT | |
2255 | info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; | 2255 | IEEE80211_TX_CTL_ASSIGN_SEQ | |
2256 | IEEE80211_TX_CTL_FIRST_FRAGMENT; | ||
2256 | out: | 2257 | out: |
2257 | rcu_read_unlock(); | 2258 | rcu_read_unlock(); |
2258 | return skb; | 2259 | return skb; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 2b75b4fb68f4..5b79d552780a 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1160,18 +1160,33 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1160 | 1160 | ||
1161 | /* Finally also reconfigure all the BSS information */ | 1161 | /* Finally also reconfigure all the BSS information */ |
1162 | list_for_each_entry(sdata, &local->interfaces, list) { | 1162 | list_for_each_entry(sdata, &local->interfaces, list) { |
1163 | u32 changed = ~0; | 1163 | u32 changed; |
1164 | |||
1164 | if (!ieee80211_sdata_running(sdata)) | 1165 | if (!ieee80211_sdata_running(sdata)) |
1165 | continue; | 1166 | continue; |
1167 | |||
1168 | /* common change flags for all interface types */ | ||
1169 | changed = BSS_CHANGED_ERP_CTS_PROT | | ||
1170 | BSS_CHANGED_ERP_PREAMBLE | | ||
1171 | BSS_CHANGED_ERP_SLOT | | ||
1172 | BSS_CHANGED_HT | | ||
1173 | BSS_CHANGED_BASIC_RATES | | ||
1174 | BSS_CHANGED_BEACON_INT | | ||
1175 | BSS_CHANGED_BSSID | | ||
1176 | BSS_CHANGED_CQM; | ||
1177 | |||
1166 | switch (sdata->vif.type) { | 1178 | switch (sdata->vif.type) { |
1167 | case NL80211_IFTYPE_STATION: | 1179 | case NL80211_IFTYPE_STATION: |
1168 | /* disable beacon change bits */ | 1180 | changed |= BSS_CHANGED_ASSOC; |
1169 | changed &= ~(BSS_CHANGED_BEACON | | 1181 | ieee80211_bss_info_change_notify(sdata, changed); |
1170 | BSS_CHANGED_BEACON_ENABLED); | 1182 | break; |
1171 | /* fall through */ | ||
1172 | case NL80211_IFTYPE_ADHOC: | 1183 | case NL80211_IFTYPE_ADHOC: |
1184 | changed |= BSS_CHANGED_IBSS; | ||
1185 | /* fall through */ | ||
1173 | case NL80211_IFTYPE_AP: | 1186 | case NL80211_IFTYPE_AP: |
1174 | case NL80211_IFTYPE_MESH_POINT: | 1187 | case NL80211_IFTYPE_MESH_POINT: |
1188 | changed |= BSS_CHANGED_BEACON | | ||
1189 | BSS_CHANGED_BEACON_ENABLED; | ||
1175 | ieee80211_bss_info_change_notify(sdata, changed); | 1190 | ieee80211_bss_info_change_notify(sdata, changed); |
1176 | break; | 1191 | break; |
1177 | case NL80211_IFTYPE_WDS: | 1192 | case NL80211_IFTYPE_WDS: |