X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fmac80211%2Fiface.c;h=24ec86f6680a79affda7a7e818d91a0768861bcb;hb=45f2396c843a12ffab988071e725defba5c9703f;hp=30d73552e9ab0f89ef53707e564dd67aee47a3b8;hpb=ce0fda16084905d035e8ceb51cf42740ad781b15;p=pandora-kernel.git diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 30d73552e9ab..24ec86f6680a 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -382,10 +382,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, u32 hw_reconf_flags = 0; int i; enum nl80211_channel_type orig_ct; + bool cancel_scan; clear_bit(SDATA_STATE_RUNNING, &sdata->state); - if (local->scan_sdata == sdata) + cancel_scan = local->scan_sdata == sdata; + if (cancel_scan) ieee80211_scan_cancel(local); /* @@ -495,6 +497,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_configure_filter(local); break; default: + mutex_lock(&local->mtx); + if (local->hw_roc_dev == sdata->dev && + local->hw_roc_channel) { + /* ignore return value since this is racy */ + drv_cancel_remain_on_channel(local); + ieee80211_queue_work(&local->hw, &local->hw_roc_done); + } + mutex_unlock(&local->mtx); + + flush_work(&local->hw_roc_start); + flush_work(&local->hw_roc_done); + flush_work(&sdata->work); /* * When we get here, the interface is marked down. @@ -531,6 +545,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ieee80211_recalc_ps(local, -1); + if (cancel_scan) + flush_delayed_work(&local->scan_work); + if (local->open_count == 0) { if (local->ops->napi_poll) napi_disable(&local->napi); @@ -1230,6 +1247,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) ASSERT_RTNL(); + /* + * Close all AP_VLAN interfaces first, as otherwise they + * might be closed while the AP interface they belong to + * is closed, causing unregister_netdevice_many() to crash. + */ + list_for_each_entry(sdata, &local->interfaces, list) + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + dev_close(sdata->dev); + mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list);