return -EBADE;
 }
 
-static void brcmf_net_detach(struct net_device *ndev)
+static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
 {
-       if (ndev->reg_state == NETREG_REGISTERED)
-               unregister_netdev(ndev);
-       else
+       if (ndev->reg_state == NETREG_REGISTERED) {
+               if (rtnl_locked)
+                       unregister_netdevice(ndev);
+               else
+                       unregister_netdev(ndev);
+       } else {
                brcmf_cfg80211_free_netdev(ndev);
+       }
 }
 
 void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
                        brcmf_err("ERROR: netdev:%s already exists\n",
                                  ifp->ndev->name);
                        netif_stop_queue(ifp->ndev);
-                       brcmf_net_detach(ifp->ndev);
+                       brcmf_net_detach(ifp->ndev, false);
                        drvr->iflist[bsscfgidx] = NULL;
                } else {
                        brcmf_dbg(INFO, "netdev:%s ignore IF event\n",
        return ifp;
 }
 
-static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx)
+static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx,
+                        bool rtnl_locked)
 {
        struct brcmf_if *ifp;
 
                        cancel_work_sync(&ifp->multicast_work);
                        cancel_work_sync(&ifp->ndoffload_work);
                }
-               brcmf_net_detach(ifp->ndev);
+               brcmf_net_detach(ifp->ndev, rtnl_locked);
        } else {
                /* Only p2p device interfaces which get dynamically created
                 * end up here. In this case the p2p module should be informed
        }
 }
 
-void brcmf_remove_interface(struct brcmf_if *ifp)
+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked)
 {
        if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp))
                return;
        brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx,
                  ifp->ifidx);
        brcmf_fws_del_interface(ifp);
-       brcmf_del_if(ifp->drvr, ifp->bsscfgidx);
+       brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
 }
 
 #ifdef CONFIG_INET
                brcmf_fws_deinit(drvr);
        }
        if (ifp)
-               brcmf_net_detach(ifp->ndev);
+               brcmf_net_detach(ifp->ndev, false);
        if (p2p_ifp)
-               brcmf_net_detach(p2p_ifp->ndev);
+               brcmf_net_detach(p2p_ifp->ndev, false);
        drvr->iflist[0] = NULL;
        drvr->iflist[1] = NULL;
        if (drvr->settings->ignore_probe_fail)
 
        /* make sure primary interface removed last */
        for (i = BRCMF_MAX_IFS-1; i > -1; i--)
-               brcmf_remove_interface(drvr->iflist[i]);
+               brcmf_remove_interface(drvr->iflist[i], false);
 
        brcmf_cfg80211_detach(drvr->config);
 
 
 int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
 struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx,
                              bool is_p2pdev, char *name, u8 *mac_addr);
-void brcmf_remove_interface(struct brcmf_if *ifp);
+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked);
 void brcmf_txflowblock_if(struct brcmf_if *ifp,
                          enum brcmf_netif_stop_reason reason, bool state);
 void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
 
                        err = 0;
        }
        if (err)
-               brcmf_remove_interface(vif->ifp);
+               brcmf_remove_interface(vif->ifp, true);
 
        brcmf_cfg80211_arm_vif_event(cfg, NULL);
        if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
        if (vif != NULL) {
                brcmf_p2p_cancel_remain_on_channel(vif->ifp);
                brcmf_p2p_deinit_discovery(p2p);
-               brcmf_remove_interface(vif->ifp);
+               brcmf_remove_interface(vif->ifp, false);
        }
        /* just set it all to zero */
        memset(p2p, 0, sizeof(*p2p));