diff options
Diffstat (limited to 'package/kernel/mac80211/patches')
4 files changed, 161 insertions, 2 deletions
diff --git a/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch b/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch new file mode 100644 index 0000000..12d7eb4 --- /dev/null +++ b/package/kernel/mac80211/patches/319-0005-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) diff --git a/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch new file mode 100644 index 0000000..2f7165e --- /dev/null +++ b/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch @@ -0,0 +1,84 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> +Date: Wed, 29 Jun 2016 21:54:27 +0200 +Subject: [PATCH] brcmfmac: support removing AP interfaces with + "interface_remove" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove" +for removing interfaces. Try to use this method on cfg80211 request. In +case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this +will just result in firmware rejecting command and this won't change any +behavior. + +Signed-off-by: Rafał Miłecki <zajec5@gmail.com> +Signed-off-by: Kalle Valo <kvalo@codeaurora.org> +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -785,12 +785,48 @@ s32 brcmf_notify_escan_complete(struct b + return err; + } + ++static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, ++ struct wireless_dev *wdev) ++{ ++ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); ++ struct net_device *ndev = wdev->netdev; ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ int ret; ++ int err; ++ ++ brcmf_cfg80211_arm_vif_event(cfg, ifp->vif); ++ ++ err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0); ++ if (err) { ++ brcmf_err("interface_remove failed %d\n", err); ++ goto err_unarm; ++ } ++ ++ /* wait for firmware event */ ++ ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, ++ BRCMF_VIF_EVENT_TIMEOUT); ++ if (!ret) { ++ brcmf_err("timeout occurred\n"); ++ err = -EIO; ++ goto err_unarm; ++ } ++ ++ brcmf_remove_interface(ifp, true); ++ ++err_unarm: ++ brcmf_cfg80211_arm_vif_event(cfg, NULL); ++ return err; ++} ++ + static + int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) + { + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); + struct net_device *ndev = wdev->netdev; + ++ if (ndev && ndev == cfg_to_ndev(cfg)) ++ return -ENOTSUPP; ++ + /* vif event pending in firmware */ + if (brcmf_cfg80211_vif_event_armed(cfg)) + return -EBUSY; +@@ -807,12 +843,13 @@ int brcmf_cfg80211_del_iface(struct wiph + switch (wdev->iftype) { + case NL80211_IFTYPE_ADHOC: + case NL80211_IFTYPE_STATION: +- case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: + case NL80211_IFTYPE_WDS: + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_MESH_POINT: + return -EOPNOTSUPP; ++ case NL80211_IFTYPE_AP: ++ return brcmf_cfg80211_del_ap_iface(wiphy, wdev); + case NL80211_IFTYPE_P2P_CLIENT: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_P2P_DEVICE: diff --git a/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch index 0bfaae6..ae571c9 100644 --- a/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1208,6 +1208,7 @@ int __init brcmf_core_init(void) +@@ -1213,6 +1213,7 @@ int __init brcmf_core_init(void) { if (!schedule_work(&brcmf_driver_work)) return -EBUSY; diff --git a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch index 104438a..f301fe1 100644 --- a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch +++ b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2746,6 +2746,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip +@@ -2783,6 +2783,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip * preference in cfg struct to apply this to * FW later while initializing the dongle */ |