diff options
Diffstat (limited to 'package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch')
-rw-r--r-- | package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch b/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch new file mode 100644 index 0000000..0651a2f --- /dev/null +++ b/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch @@ -0,0 +1,99 @@ +From: Arend van Spriel <arend@broadcom.com> +Date: Wed, 26 Aug 2015 22:15:04 +0200 +Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function + +In case of error during brcmf_bus_start() the network interfaces were +freed using free_netdev(). However, the interfaces may have additional +memory allocated which is not freed. The netdev has destructor set to +brcmf_cfg80211_free_netdev() which frees the additional memory if +allocated and call free_netdev(). The brcmf_net_detach() either calls +brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when +struct net_device::reg_state indicates the netdev was registered. + +Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com> +Reviewed-by: Hante Meuleman <meuleman@broadcom.com> +Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> +Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> +Signed-off-by: Arend van Spriel <arend@broadcom.com> +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -4747,7 +4747,8 @@ void brcmf_cfg80211_free_netdev(struct n + ifp = netdev_priv(ndev); + vif = ifp->vif; + +- brcmf_free_vif(vif); ++ if (vif) ++ brcmf_free_vif(vif); + free_netdev(ndev); + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c +@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if + } + + brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name); +- +- ndev->destructor = brcmf_cfg80211_free_netdev; + return 0; + + fail: +@@ -729,6 +727,14 @@ fail: + return -EBADE; + } + ++static void brcmf_net_detach(struct net_device *ndev) ++{ ++ if (ndev->reg_state == NETREG_REGISTERED) ++ unregister_netdev(ndev); ++ else ++ brcmf_cfg80211_free_netdev(ndev); ++} ++ + static int brcmf_net_p2p_open(struct net_device *ndev) + { + brcmf_dbg(TRACE, "Enter\n"); +@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc + ifp->ndev->name); + if (ifidx) { + netif_stop_queue(ifp->ndev); +- unregister_netdev(ifp->ndev); +- free_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + drvr->iflist[bssidx] = NULL; + } else { + brcmf_err("ignore IF event\n"); +@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc + if (!ndev) + return ERR_PTR(-ENOMEM); + ++ ndev->destructor = brcmf_cfg80211_free_netdev; + ifp = netdev_priv(ndev); + ifp->ndev = ndev; + /* store mapping ifidx to bssidx */ +@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu + cancel_work_sync(&ifp->setmacaddr_work); + cancel_work_sync(&ifp->multicast_work); + } +- /* unregister will take care of freeing it */ +- unregister_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + } + } + +@@ -1056,11 +1061,11 @@ fail: + brcmf_fws_deinit(drvr); + } + if (drvr->iflist[0]) { +- free_netdev(ifp->ndev); ++ brcmf_net_detach(ifp->ndev); + drvr->iflist[0] = NULL; + } + if (p2p_ifp) { +- free_netdev(p2p_ifp->ndev); ++ brcmf_net_detach(p2p_ifp->ndev); + drvr->iflist[1] = NULL; + } + return ret; |