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;
 }
 
        dev->change_mtu = ieee80211_change_mtu;
        dev->open = ieee80211_open;
        dev->stop = ieee80211_stop;
-       dev->uninit = ieee80211_if_reinit;
        dev->destructor = ieee80211_if_free;
 }
 
                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) {
         * 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();
 
 
        if (ret)
                goto fail;
 
+       /*
+        * Called even when register_netdevice fails, it would
+        * oops if assigned before initialising the rest.
+        */
+       ndev->uninit = ieee80211_if_reinit;
+
        ieee80211_debugfs_add_netdev(nsdata);
 
        if (local->open_count > 0)
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        int oldtype = sdata->type;
 
-       dev->hard_start_xmit = ieee80211_subif_start_xmit;
-
+       /*
+        * We need to call this function on the master interface
+        * which already has a hard_start_xmit routine assigned
+        * which must not be changed.
+        */
+       if (!dev->hard_start_xmit)
+               dev->hard_start_xmit = ieee80211_subif_start_xmit;
+
+       /*
+        * Called even when register_netdevice fails, it would
+        * oops if assigned before initialising the rest.
+        */
+       dev->uninit = ieee80211_if_reinit;
+
+       /* most have no BSS pointer */
+       sdata->bss = NULL;
        sdata->type = type;
+
        switch (type) {
        case IEEE80211_IF_TYPE_WDS:
-               sdata->bss = NULL;
+               /* nothing special */
                break;
        case IEEE80211_IF_TYPE_VLAN:
                sdata->u.vlan.ap = NULL;
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct sta_info *sta;
+       struct sk_buff *skb;
 
        ASSERT_RTNL();
 
                kfree(sdata->u.ap.beacon_tail);
                kfree(sdata->u.ap.generic_elem);
 
-               if (dev != local->mdev) {
-                       struct sk_buff *skb;
-                       while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
-                               local->total_ps_buffered--;
-                               dev_kfree_skb(skb);
-                       }
+               while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
+                       local->total_ps_buffered--;
+                       dev_kfree_skb(skb);
                }
 
                break;