aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch')
-rw-r--r--package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch75
1 files changed, 75 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch b/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch
new file mode 100644
index 0000000000..6dd0c03e3d
--- /dev/null
+++ b/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch
@@ -0,0 +1,75 @@
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
+Date: Wed, 29 Jun 2016 21:54:26 +0200
+Subject: [PATCH] brcmfmac: delete interface directly in code that sent fw
+ request
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far when receiving event about in-firmware-interface removal our
+event worker was notifying listener and afterwards it was removing Linux
+interface.
+
+First of all it was resulting in slightly unexpected order. The listener
+(del_virtual_intf callback) was (usually) returning with success before
+we even called unregister_netdev(ice).
+
+Please note this couldn't be simply fixed by changing order of calls in
+brcmf_fweh_handle_if_event as unregistering interface earlier could free
+struct brcmf_if.
+
+Another problem of current implementation are possible lockups. Focus on
+the time slot between calling event handler and removing Linux
+interface. During that time original caller may leave (unlocking rtnl
+semaphore) *and* another call to the same code may be done (locking it
+again). If that happens our event handler will stuck at removing Linux
+interface, it won't handle another event and will block process holding
+rtnl lock.
+
+This can be simply solved by unregistering interface in a proper
+callback, right after receiving confirmation event from firmware. This
+only required modifying worker to don't unregister on its own if there
+is someone waiting for the event.
+
+Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
+@@ -18,6 +18,7 @@
+ #include "brcmu_wifi.h"
+ #include "brcmu_utils.h"
+
++#include "cfg80211.h"
+ #include "core.h"
+ #include "debug.h"
+ #include "tracepoint.h"
+@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s
+
+ err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
+
+- if (ifp && ifevent->action == BRCMF_E_IF_DEL)
+- brcmf_remove_interface(ifp, false);
++ if (ifp && ifevent->action == BRCMF_E_IF_DEL) {
++ bool armed = brcmf_cfg80211_vif_event_armed(drvr->config);
++
++ /* Default handling in case no-one waits for this event */
++ if (!armed)
++ brcmf_remove_interface(ifp, false);
++ }
+ }
+
+ /**
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ else
+ err = 0;
+ }
+- if (err)
+- brcmf_remove_interface(vif->ifp, true);
++ brcmf_remove_interface(vif->ifp, true);
+
+ brcmf_cfg80211_arm_vif_event(cfg, NULL);
+ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)