aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2015-08-26 22:10:14 +0000
committerRafał Miłecki <zajec5@gmail.com>2015-08-26 22:10:14 +0000
commite53ef786554097f42856e9ade31fd9f0845177c2 (patch)
tree78f49ecbea2439aa2978c2b2a57c22f775b42d70 /package/kernel/mac80211/patches/330-brcmfmac-introduce-brcmf_net_detach-function.patch
parent7d148608f341c5e53f7b000a58191389a0d2955e (diff)
downloadmaster-187ad058-e53ef786554097f42856e9ade31fd9f0845177c2.tar.gz
master-187ad058-e53ef786554097f42856e9ade31fd9f0845177c2.tar.bz2
master-187ad058-e53ef786554097f42856e9ade31fd9f0845177c2.zip
mac80211: add pending brcmfmac patches fixing multiple interfaces
So far support for multiple interface was somehow broken in brcmfmac. Driver couldn't correctly match firmware and system interfaces resulting in not working APs and WARNINGs. This pending patches fixes that :) Signed-off-by: Rafał Miłecki <zajec5@gmail.com> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@46734 3c298f89-4303-0410-b956-a3cf2f4a3e73
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.patch99
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 0000000000..0651a2f027
--- /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;