aboutsummaryrefslogtreecommitdiff
path: root/net/mac80211/ieee80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211.c')
-rw-r--r--net/mac80211/ieee80211.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index ccf84634f15..52638194e45 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -265,7 +265,6 @@ void ieee80211_if_mgmt_setup(struct net_device *dev)
dev->open = ieee80211_mgmt_open;
dev->stop = ieee80211_mgmt_stop;
dev->type = ARPHRD_IEEE80211_PRISM;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -551,7 +550,6 @@ void ieee80211_if_setup(struct net_device *dev)
dev->change_mtu = ieee80211_change_mtu;
dev->open = ieee80211_open;
dev->stop = ieee80211_stop;
- dev->uninit = ieee80211_if_reinit;
dev->destructor = ieee80211_if_free;
}
@@ -1242,6 +1240,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
goto fail_dev;
ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
+ ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
result = ieee80211_init_rate_ctrl_alg(local, NULL);
if (result < 0) {
@@ -1346,8 +1345,22 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
* because the driver cannot be handing us frames any
* more and the tasklet is killed.
*/
- list_for_each_entry_safe(sdata, tmp, &local->interfaces, list)
+
+ /*
+ * First, we remove all non-master interfaces. Do this because they
+ * may have bss pointer dependency on the master, and when we free
+ * the master these would be freed as well, breaking our list
+ * iteration completely.
+ */
+ list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
+ if (sdata->dev == local->mdev)
+ continue;
+ list_del(&sdata->list);
__ieee80211_if_del(local, sdata);
+ }
+
+ /* then, finally, remove the master interface */
+ __ieee80211_if_del(local, IEEE80211_DEV_TO_SUB_IF(local->mdev));
rtnl_unlock();