diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 165 |
1 files changed, 74 insertions, 91 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 5ca62ea15079..b80bc80e46cf 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
27 | 27 | ||
28 | #include "ieee80211_i.h" | 28 | #include "ieee80211_i.h" |
29 | #include "driver-ops.h" | ||
29 | #include "rate.h" | 30 | #include "rate.h" |
30 | #include "mesh.h" | 31 | #include "mesh.h" |
31 | #include "wep.h" | 32 | #include "wep.h" |
@@ -81,10 +82,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local) | |||
81 | /* be a bit nasty */ | 82 | /* be a bit nasty */ |
82 | new_flags |= (1<<31); | 83 | new_flags |= (1<<31); |
83 | 84 | ||
84 | local->ops->configure_filter(local_to_hw(local), | 85 | drv_configure_filter(local, changed_flags, &new_flags, |
85 | changed_flags, &new_flags, | 86 | local->mdev->mc_count, |
86 | local->mdev->mc_count, | 87 | local->mdev->mc_list); |
87 | local->mdev->mc_list); | ||
88 | 88 | ||
89 | WARN_ON(new_flags & (1<<31)); | 89 | WARN_ON(new_flags & (1<<31)); |
90 | 90 | ||
@@ -152,82 +152,6 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev) | |||
152 | ieee80211_configure_filter(local); | 152 | ieee80211_configure_filter(local); |
153 | } | 153 | } |
154 | 154 | ||
155 | /* everything else */ | ||
156 | |||
157 | int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) | ||
158 | { | ||
159 | struct ieee80211_local *local = sdata->local; | ||
160 | struct ieee80211_if_conf conf; | ||
161 | |||
162 | if (WARN_ON(!netif_running(sdata->dev))) | ||
163 | return 0; | ||
164 | |||
165 | memset(&conf, 0, sizeof(conf)); | ||
166 | |||
167 | if (sdata->vif.type == NL80211_IFTYPE_STATION) | ||
168 | conf.bssid = sdata->u.mgd.bssid; | ||
169 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
170 | conf.bssid = sdata->u.ibss.bssid; | ||
171 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
172 | conf.bssid = sdata->dev->dev_addr; | ||
173 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
174 | static const u8 zero[ETH_ALEN] = { 0 }; | ||
175 | conf.bssid = zero; | ||
176 | } else { | ||
177 | WARN_ON(1); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | |||
181 | if (!local->ops->config_interface) | ||
182 | return 0; | ||
183 | |||
184 | switch (sdata->vif.type) { | ||
185 | case NL80211_IFTYPE_AP: | ||
186 | case NL80211_IFTYPE_ADHOC: | ||
187 | case NL80211_IFTYPE_MESH_POINT: | ||
188 | break; | ||
189 | default: | ||
190 | /* do not warn to simplify caller in scan.c */ | ||
191 | changed &= ~IEEE80211_IFCC_BEACON_ENABLED; | ||
192 | if (WARN_ON(changed & IEEE80211_IFCC_BEACON)) | ||
193 | return -EINVAL; | ||
194 | changed &= ~IEEE80211_IFCC_BEACON; | ||
195 | break; | ||
196 | } | ||
197 | |||
198 | if (changed & IEEE80211_IFCC_BEACON_ENABLED) { | ||
199 | if (local->sw_scanning) { | ||
200 | conf.enable_beacon = false; | ||
201 | } else { | ||
202 | /* | ||
203 | * Beacon should be enabled, but AP mode must | ||
204 | * check whether there is a beacon configured. | ||
205 | */ | ||
206 | switch (sdata->vif.type) { | ||
207 | case NL80211_IFTYPE_AP: | ||
208 | conf.enable_beacon = | ||
209 | !!rcu_dereference(sdata->u.ap.beacon); | ||
210 | break; | ||
211 | case NL80211_IFTYPE_ADHOC: | ||
212 | conf.enable_beacon = !!sdata->u.ibss.presp; | ||
213 | break; | ||
214 | case NL80211_IFTYPE_MESH_POINT: | ||
215 | conf.enable_beacon = true; | ||
216 | break; | ||
217 | default: | ||
218 | /* not reached */ | ||
219 | WARN_ON(1); | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | conf.changed = changed; | ||
226 | |||
227 | return local->ops->config_interface(local_to_hw(local), | ||
228 | &sdata->vif, &conf); | ||
229 | } | ||
230 | |||
231 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | 155 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) |
232 | { | 156 | { |
233 | struct ieee80211_channel *chan; | 157 | struct ieee80211_channel *chan; |
@@ -268,7 +192,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
268 | } | 192 | } |
269 | 193 | ||
270 | if (changed && local->open_count) { | 194 | if (changed && local->open_count) { |
271 | ret = local->ops->config(local_to_hw(local), changed); | 195 | ret = drv_config(local, changed); |
272 | /* | 196 | /* |
273 | * Goal: | 197 | * Goal: |
274 | * HW reconfiguration should never fail, the driver has told | 198 | * HW reconfiguration should never fail, the driver has told |
@@ -294,17 +218,77 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
294 | { | 218 | { |
295 | struct ieee80211_local *local = sdata->local; | 219 | struct ieee80211_local *local = sdata->local; |
296 | 220 | ||
297 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | 221 | if (!changed) |
298 | return; | 222 | return; |
299 | 223 | ||
300 | if (!changed) | 224 | if (sdata->vif.type == NL80211_IFTYPE_STATION) |
225 | sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid; | ||
226 | else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | ||
227 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | ||
228 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | ||
229 | sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; | ||
230 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | ||
231 | static const u8 zero[ETH_ALEN] = { 0 }; | ||
232 | sdata->vif.bss_conf.bssid = zero; | ||
233 | } else { | ||
234 | WARN_ON(1); | ||
301 | return; | 235 | return; |
236 | } | ||
237 | |||
238 | switch (sdata->vif.type) { | ||
239 | case NL80211_IFTYPE_AP: | ||
240 | case NL80211_IFTYPE_ADHOC: | ||
241 | case NL80211_IFTYPE_MESH_POINT: | ||
242 | break; | ||
243 | default: | ||
244 | /* do not warn to simplify caller in scan.c */ | ||
245 | changed &= ~BSS_CHANGED_BEACON_ENABLED; | ||
246 | if (WARN_ON(changed & BSS_CHANGED_BEACON)) | ||
247 | return; | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | ||
252 | if (local->sw_scanning) { | ||
253 | sdata->vif.bss_conf.enable_beacon = false; | ||
254 | } else { | ||
255 | /* | ||
256 | * Beacon should be enabled, but AP mode must | ||
257 | * check whether there is a beacon configured. | ||
258 | */ | ||
259 | switch (sdata->vif.type) { | ||
260 | case NL80211_IFTYPE_AP: | ||
261 | sdata->vif.bss_conf.enable_beacon = | ||
262 | !!rcu_dereference(sdata->u.ap.beacon); | ||
263 | break; | ||
264 | case NL80211_IFTYPE_ADHOC: | ||
265 | sdata->vif.bss_conf.enable_beacon = | ||
266 | !!rcu_dereference(sdata->u.ibss.presp); | ||
267 | break; | ||
268 | case NL80211_IFTYPE_MESH_POINT: | ||
269 | sdata->vif.bss_conf.enable_beacon = true; | ||
270 | break; | ||
271 | default: | ||
272 | /* not reached */ | ||
273 | WARN_ON(1); | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | } | ||
302 | 278 | ||
303 | if (local->ops->bss_info_changed) | 279 | drv_bss_info_changed(local, &sdata->vif, |
304 | local->ops->bss_info_changed(local_to_hw(local), | 280 | &sdata->vif.bss_conf, changed); |
305 | &sdata->vif, | 281 | |
306 | &sdata->vif.bss_conf, | 282 | /* |
307 | changed); | 283 | * DEPRECATED |
284 | * | ||
285 | * ~changed is just there to not do this at resume time | ||
286 | */ | ||
287 | if (changed & BSS_CHANGED_BEACON_INT && ~changed) { | ||
288 | local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int; | ||
289 | ieee80211_hw_config(local, | ||
290 | _IEEE80211_CONF_CHANGE_BEACON_INTERVAL); | ||
291 | } | ||
308 | } | 292 | } |
309 | 293 | ||
310 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 294 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
@@ -783,6 +767,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
783 | 767 | ||
784 | INIT_LIST_HEAD(&local->interfaces); | 768 | INIT_LIST_HEAD(&local->interfaces); |
785 | mutex_init(&local->iflist_mtx); | 769 | mutex_init(&local->iflist_mtx); |
770 | mutex_init(&local->scan_mtx); | ||
786 | 771 | ||
787 | spin_lock_init(&local->key_lock); | 772 | spin_lock_init(&local->key_lock); |
788 | 773 | ||
@@ -970,9 +955,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
970 | 955 | ||
971 | debugfs_hw_add(local); | 956 | debugfs_hw_add(local); |
972 | 957 | ||
973 | if (local->hw.conf.beacon_int < 10) | ||
974 | local->hw.conf.beacon_int = 100; | ||
975 | |||
976 | if (local->hw.max_listen_interval == 0) | 958 | if (local->hw.max_listen_interval == 0) |
977 | local->hw.max_listen_interval = 1; | 959 | local->hw.max_listen_interval = 1; |
978 | 960 | ||
@@ -1126,6 +1108,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw) | |||
1126 | struct ieee80211_local *local = hw_to_local(hw); | 1108 | struct ieee80211_local *local = hw_to_local(hw); |
1127 | 1109 | ||
1128 | mutex_destroy(&local->iflist_mtx); | 1110 | mutex_destroy(&local->iflist_mtx); |
1111 | mutex_destroy(&local->scan_mtx); | ||
1129 | 1112 | ||
1130 | wiphy_free(local->hw.wiphy); | 1113 | wiphy_free(local->hw.wiphy); |
1131 | } | 1114 | } |