aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/iface.c')
-rw-r--r--net/mac80211/iface.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 30d73552e9ab..12a6d4bb5d37 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -188,11 +188,22 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
188 if (!is_valid_ether_addr(sdata->u.wds.remote_addr)) 188 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
189 return -ENOLINK; 189 return -ENOLINK;
190 break; 190 break;
191 case NL80211_IFTYPE_AP_VLAN: 191 case NL80211_IFTYPE_AP_VLAN: {
192 struct ieee80211_sub_if_data *master;
193
192 if (!sdata->bss) 194 if (!sdata->bss)
193 return -ENOLINK; 195 return -ENOLINK;
196
194 list_add(&sdata->u.vlan.list, &sdata->bss->vlans); 197 list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
198
199 master = container_of(sdata->bss,
200 struct ieee80211_sub_if_data, u.ap);
201 sdata->control_port_protocol =
202 master->control_port_protocol;
203 sdata->control_port_no_encrypt =
204 master->control_port_no_encrypt;
195 break; 205 break;
206 }
196 case NL80211_IFTYPE_AP: 207 case NL80211_IFTYPE_AP:
197 sdata->bss = &sdata->u.ap; 208 sdata->bss = &sdata->u.ap;
198 break; 209 break;
@@ -265,7 +276,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
265 break; 276 break;
266 default: 277 default:
267 if (coming_up) { 278 if (coming_up) {
268 res = drv_add_interface(local, &sdata->vif); 279 res = drv_add_interface(local, sdata);
269 if (res) 280 if (res)
270 goto err_stop; 281 goto err_stop;
271 } 282 }
@@ -282,10 +293,18 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
282 changed |= ieee80211_reset_erp_info(sdata); 293 changed |= ieee80211_reset_erp_info(sdata);
283 ieee80211_bss_info_change_notify(sdata, changed); 294 ieee80211_bss_info_change_notify(sdata, changed);
284 295
285 if (sdata->vif.type == NL80211_IFTYPE_STATION) 296 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
297 sdata->vif.type == NL80211_IFTYPE_ADHOC)
286 netif_carrier_off(dev); 298 netif_carrier_off(dev);
287 else 299 else
288 netif_carrier_on(dev); 300 netif_carrier_on(dev);
301
302 /*
303 * set default queue parameters so drivers don't
304 * need to initialise the hardware if the hardware
305 * doesn't start up with sane defaults
306 */
307 ieee80211_set_wmm_default(sdata);
289 } 308 }
290 309
291 set_bit(SDATA_STATE_RUNNING, &sdata->state); 310 set_bit(SDATA_STATE_RUNNING, &sdata->state);
@@ -329,15 +348,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
329 if (coming_up) 348 if (coming_up)
330 local->open_count++; 349 local->open_count++;
331 350
332 if (hw_reconf_flags) { 351 if (hw_reconf_flags)
333 ieee80211_hw_config(local, hw_reconf_flags); 352 ieee80211_hw_config(local, hw_reconf_flags);
334 /*
335 * set default queue parameters so drivers don't
336 * need to initialise the hardware if the hardware
337 * doesn't start up with sane defaults
338 */
339 ieee80211_set_wmm_default(sdata);
340 }
341 353
342 ieee80211_recalc_ps(local, -1); 354 ieee80211_recalc_ps(local, -1);
343 355
@@ -345,7 +357,7 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
345 357
346 return 0; 358 return 0;
347 err_del_interface: 359 err_del_interface:
348 drv_remove_interface(local, &sdata->vif); 360 drv_remove_interface(local, sdata);
349 err_stop: 361 err_stop:
350 if (!local->open_count) 362 if (!local->open_count)
351 drv_stop(local); 363 drv_stop(local);
@@ -450,15 +462,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
450 struct ieee80211_sub_if_data *vlan, *tmpsdata; 462 struct ieee80211_sub_if_data *vlan, *tmpsdata;
451 struct beacon_data *old_beacon = 463 struct beacon_data *old_beacon =
452 rtnl_dereference(sdata->u.ap.beacon); 464 rtnl_dereference(sdata->u.ap.beacon);
465 struct sk_buff *old_probe_resp =
466 rtnl_dereference(sdata->u.ap.probe_resp);
453 467
454 /* sdata_running will return false, so this will disable */ 468 /* sdata_running will return false, so this will disable */
455 ieee80211_bss_info_change_notify(sdata, 469 ieee80211_bss_info_change_notify(sdata,
456 BSS_CHANGED_BEACON_ENABLED); 470 BSS_CHANGED_BEACON_ENABLED);
457 471
458 /* remove beacon */ 472 /* remove beacon and probe response */
459 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); 473 RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
474 RCU_INIT_POINTER(sdata->u.ap.probe_resp, NULL);
460 synchronize_rcu(); 475 synchronize_rcu();
461 kfree(old_beacon); 476 kfree(old_beacon);
477 kfree(old_probe_resp);
462 478
463 /* down all dependent devices, that is VLANs */ 479 /* down all dependent devices, that is VLANs */
464 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, 480 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
@@ -520,7 +536,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
520 ieee80211_free_keys(sdata); 536 ieee80211_free_keys(sdata);
521 537
522 if (going_down) 538 if (going_down)
523 drv_remove_interface(local, &sdata->vif); 539 drv_remove_interface(local, sdata);
524 } 540 }
525 541
526 sdata->bss = NULL; 542 sdata->bss = NULL;