Message ID | 1562835912-1404-3-git-send-email-arend.vanspriel@broadcom.com (mailing list archive) |
---|---|
State | Accepted |
Commit | 14fcfd1cc0c05ea58f47dd693fdd13f25dfe995e |
Delegated to: | Kalle Valo |
Headers | show |
Series | brcmfmac: rework probe/attach sequence | expand |
On 11.07.2019 11:05, Arend van Spriel wrote: > When brcmf_detach() from the bus layer upon rmmod we can no longer > communicate. Hence we will set the bus state to DOWN and cleanup > the event and protocol layer. The network interfaces need to be > deleted before brcmf_cfg80211_detach() because the latter does the > wiphy_unregister() which issues a warning if there are still network > devices linked to the wiphy instance. > > Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> > Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> > Reviewed-by: Franky Lin <franky.lin@broadcom.com> > Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> This fixes a rmmod crash in brcmf_txfinalize() that I reported in the: brcmfmac: NULL pointer dereference during brcmf_detach() after firmware crash <b519e746-ddfd-421f-d897-7620d229e4b2@gmail.com> https://www.spinics.net/lists/linux-wireless/msg182913.html Tested-by: Rafał Miłecki <rafal@milecki.pl>
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index fda6044..80d54d2 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -1307,25 +1307,26 @@ void brcmf_detach(struct device *dev) unregister_inet6addr_notifier(&drvr->inet6addr_notifier); #endif - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); - if (drvr->config) - brcmf_p2p_detach(&drvr->config->p2p); - brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); - - /* make sure primary interface removed last */ - for (i = BRCMF_MAX_IFS-1; i > -1; i--) - brcmf_remove_interface(drvr->iflist[i], false); - - brcmf_cfg80211_detach(drvr->config); - drvr->config = NULL; - brcmf_bus_stop(drvr->bus_if); + brcmf_fweh_detach(drvr); brcmf_proto_detach(drvr); + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { + if (drvr->iflist[i]) + brcmf_del_if(drvr, drvr->iflist[i]->bsscfgidx, false); + } + + if (drvr->config) { + brcmf_p2p_detach(&drvr->config->p2p); + brcmf_cfg80211_detach(drvr->config); + drvr->config = NULL; + } + bus_if->drvr = NULL; + wiphy_free(drvr->wiphy); }