From 29fcc94c9acf1f789ad25fc460fb46aa740b68a0 Mon Sep 17 00:00:00 2001 From: Zoltan HERPAI Date: Thu, 29 Sep 2016 07:29:15 +0200 Subject: CC: openssl: update to 1.0.2j Security fixes: * (Severity: High) OCSP Status Request extension unbounded memory growth (CVE-2016-6304) * (Severity: Moderate) SSL_peek() hang on empty record (CVE-2016-6305) * (Severity: Moderate) Missing CRL sanity check (CVE-2016-7052) * 10 Low severity issues Security advisories: https://www.openssl.org/news/secadv/20160922.txt https://www.openssl.org/news/secadv/20160926.txt Signed-off-by: Zoltan HERPAI --- package/libs/openssl/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 3d13fe0a8b..ea68f167fb 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=openssl PKG_BASE:=1.0.2 -PKG_BUGFIX:=h +PKG_BUGFIX:=j PKG_VERSION:=$(PKG_BASE)$(PKG_BUGFIX) PKG_RELEASE:=1 PKG_USE_MIPS16:=0 @@ -21,7 +21,7 @@ PKG_SOURCE_URL:=http://www.openssl.org/source/ \ http://www.openssl.org/source/old/$(PKG_BASE)/ \ ftp://ftp.funet.fi/pub/crypt/mirrors/ftp.openssl.org/source \ ftp://ftp.sunet.se/pub/security/tools/net/openssl/source/ -PKG_MD5SUM:=9392e65072ce4b614c1392eefc1f23d0 +PKG_MD5SUM:=96322138f0b69e61b7212bc53d5e912b PKG_LICENSE:=OpenSSL PKG_LICENSE_FILES:=LICENSE -- cgit v1.2.3 From a047169f9d17b11b94df04fb019b718551c0d7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:19:44 +0200 Subject: mac80211: brcmfmac: fix lockup related to P2P interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...ac-include-required-headers-in-cfg80211.h.patch | 37 +++++ ...ightly-simplify-building-interface-combin.patch | 108 +++++++++++++++ ...x-lockup-when-removing-P2P-interface-afte.patch | 154 +++++++++++++++++++++ ...mfmac-register-wiphy-s-during-module_init.patch | 2 +- 4 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch create mode 100644 package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch create mode 100644 package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch diff --git a/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch b/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch new file mode 100644 index 0000000000..09547d8d3b --- /dev/null +++ b/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch @@ -0,0 +1,37 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 7 Jun 2016 08:20:21 +0200 +Subject: [PATCH] brcmfmac: include required headers in cfg80211.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Without this including cfg80211.h in a wrong order could result in: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:122:24: error: array type has incomplete element type + struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS]; + ^ +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:291:24: error: field ‘p2p’ has incomplete type + struct brcmf_p2p_info p2p; + ^ +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:297:27: error: field ‘pmk_list’ has incomplete type + struct brcmf_pmk_list_le pmk_list; + ^ +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:317:28: error: field ‘assoclist’ has incomplete type + struct brcmf_assoclist_le assoclist; + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -20,6 +20,9 @@ + /* for brcmu_d11inf */ + #include + ++#include "fwil_types.h" ++#include "p2p.h" ++ + #define WL_NUM_SCAN_MAX 10 + #define WL_TLV_INFO_MAX 1024 + #define WL_BSS_INFO_MAX 2048 diff --git a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch new file mode 100644 index 0000000000..972851633a --- /dev/null +++ b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch @@ -0,0 +1,108 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 7 Jun 2016 21:10:18 +0200 +Subject: [PATCH] brcmfmac: slightly simplify building interface combinations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This change reorders some operations in brcmf_setup_ifmodes in hope to +make it simpler: +1) It allocates arrays right before filling them. This way it's easier + to follow requested array length as it's immediately followed by + code filling it. It's easier to check e.g. why we need 4 entries for + P2P. Other than that it deduplicates some checks (e.g. for P2P). +2) It reorders code to first prepare limits and then define a new combo. + Previously this was mixed (e.g. we were setting num of channels + before preparing limits). +3) It modifies mbss code to use i variable just like other combos do. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6108,29 +6108,15 @@ static int brcmf_setup_ifmodes(struct wi + if (!combo) + goto err; + +- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); +- if (!c0_limits) +- goto err; +- +- if (p2p) { +- p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); +- if (!p2p_limits) +- goto err; +- } +- +- if (mbss) { +- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); +- if (!mbss_limits) +- goto err; +- } +- + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + + c = 0; + i = 0; +- combo[c].num_different_channels = 1; ++ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); ++ if (!c0_limits) ++ goto err; + c0_limits[i].max = 1; + c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); + if (p2p) { +@@ -6148,6 +6134,7 @@ static int brcmf_setup_ifmodes(struct wi + c0_limits[i].max = 1; + c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); + } ++ combo[c].num_different_channels = 1; + combo[c].max_interfaces = i; + combo[c].n_limits = i; + combo[c].limits = c0_limits; +@@ -6155,7 +6142,9 @@ static int brcmf_setup_ifmodes(struct wi + if (p2p) { + c++; + i = 0; +- combo[c].num_different_channels = 1; ++ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); ++ if (!p2p_limits) ++ goto err; + p2p_limits[i].max = 1; + p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); + p2p_limits[i].max = 1; +@@ -6164,6 +6153,7 @@ static int brcmf_setup_ifmodes(struct wi + p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); + p2p_limits[i].max = 1; + p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ combo[c].num_different_channels = 1; + combo[c].max_interfaces = i; + combo[c].n_limits = i; + combo[c].limits = p2p_limits; +@@ -6171,14 +6161,19 @@ static int brcmf_setup_ifmodes(struct wi + + if (mbss) { + c++; ++ i = 0; ++ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); ++ if (!mbss_limits) ++ goto err; ++ mbss_limits[i].max = 4; ++ mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP); + combo[c].beacon_int_infra_match = true; + combo[c].num_different_channels = 1; +- mbss_limits[0].max = 4; +- mbss_limits[0].types = BIT(NL80211_IFTYPE_AP); + combo[c].max_interfaces = 4; +- combo[c].n_limits = 1; ++ combo[c].n_limits = i; + combo[c].limits = mbss_limits; + } ++ + wiphy->n_iface_combinations = n_combos; + wiphy->iface_combinations = combo; + return 0; diff --git a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch new file mode 100644 index 0000000000..174d9a41db --- /dev/null +++ b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch @@ -0,0 +1,154 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 17 Jun 2016 12:29:21 +0200 +Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after event + timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Removing P2P interface is handled by sending a proper request to the +firmware. On success firmware triggers an event and driver's handler +removes a matching interface. + +However on event timeout we remove interface directly from the cfg80211 +callback. Current code doesn't handle this case correctly as it always +assumes rtnl to be unlocked. + +Fix it by adding an extra rtnl_locked parameter to functions and calling +unregister_netdevice when needed. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -705,12 +705,16 @@ fail: + return -EBADE; + } + +-static void brcmf_net_detach(struct net_device *ndev) ++static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked) + { +- if (ndev->reg_state == NETREG_REGISTERED) +- unregister_netdev(ndev); +- else ++ if (ndev->reg_state == NETREG_REGISTERED) { ++ if (rtnl_locked) ++ unregister_netdevice(ndev); ++ else ++ unregister_netdev(ndev); ++ } else { + brcmf_cfg80211_free_netdev(ndev); ++ } + } + + void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on) +@@ -808,7 +812,7 @@ struct brcmf_if *brcmf_add_if(struct brc + brcmf_err("ERROR: netdev:%s already exists\n", + ifp->ndev->name); + netif_stop_queue(ifp->ndev); +- brcmf_net_detach(ifp->ndev); ++ brcmf_net_detach(ifp->ndev, false); + drvr->iflist[bsscfgidx] = NULL; + } else { + brcmf_dbg(INFO, "netdev:%s ignore IF event\n", +@@ -856,7 +860,8 @@ struct brcmf_if *brcmf_add_if(struct brc + return ifp; + } + +-static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx) ++static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, ++ bool rtnl_locked) + { + struct brcmf_if *ifp; + +@@ -885,7 +890,7 @@ static void brcmf_del_if(struct brcmf_pu + cancel_work_sync(&ifp->setmacaddr_work); + cancel_work_sync(&ifp->multicast_work); + } +- brcmf_net_detach(ifp->ndev); ++ brcmf_net_detach(ifp->ndev, rtnl_locked); + } else { + /* Only p2p device interfaces which get dynamically created + * end up here. In this case the p2p module should be informed +@@ -899,14 +904,14 @@ static void brcmf_del_if(struct brcmf_pu + } + } + +-void brcmf_remove_interface(struct brcmf_if *ifp) ++void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) + { + if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp)) + return; + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx, + ifp->ifidx); + brcmf_fws_del_interface(ifp); +- brcmf_del_if(ifp->drvr, ifp->bsscfgidx); ++ brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked); + } + + #ifdef CONFIG_INET +@@ -1154,9 +1159,9 @@ fail: + brcmf_fws_deinit(drvr); + } + if (ifp) +- brcmf_net_detach(ifp->ndev); ++ brcmf_net_detach(ifp->ndev, false); + if (p2p_ifp) +- brcmf_net_detach(p2p_ifp->ndev); ++ brcmf_net_detach(p2p_ifp->ndev, false); + drvr->iflist[0] = NULL; + drvr->iflist[1] = NULL; + if (brcmf_ignoring_probe_fail(drvr)) +@@ -1222,7 +1227,7 @@ void brcmf_detach(struct device *dev) + + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS-1; i > -1; i--) +- brcmf_remove_interface(drvr->iflist[i]); ++ brcmf_remove_interface(drvr->iflist[i], false); + + brcmf_cfg80211_detach(drvr->config); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -213,7 +213,7 @@ struct brcmf_if *brcmf_get_ifp(struct br + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, + bool is_p2pdev, char *name, u8 *mac_addr); +-void brcmf_remove_interface(struct brcmf_if *ifp); ++void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -226,7 +226,7 @@ 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); ++ brcmf_remove_interface(ifp, false); + } + + /** +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2280,7 +2280,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph + err = 0; + } + if (err) +- brcmf_remove_interface(vif->ifp); ++ brcmf_remove_interface(vif->ifp, true); + + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) +@@ -2386,7 +2386,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i + if (vif != NULL) { + brcmf_p2p_cancel_remain_on_channel(vif->ifp); + brcmf_p2p_deinit_discovery(p2p); +- brcmf_remove_interface(vif->ifp); ++ brcmf_remove_interface(vif->ifp, false); + } + /* just set it all to zero */ + memset(p2p, 0, sizeof(*p2p)); diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch index 77c12741ef..a38e93ad6a 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1308,6 +1308,7 @@ static int __init brcmfmac_module_init(v +@@ -1313,6 +1313,7 @@ static int __init brcmfmac_module_init(v #endif if (!schedule_work(&brcmf_driver_work)) return -EBUSY; -- cgit v1.2.3 From 067545b37459056e9812c4a11c4a60aa9d04c891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:20:27 +0200 Subject: rpcd: iwinfo plugin fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Expose supported HT rate information in info call - Zero out ccode buffer when listing countries Signed-off-by: Jo-Philipp Wich Signed-off-by: Rafał Miłecki --- package/system/rpcd/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/system/rpcd/Makefile b/package/system/rpcd/Makefile index 86bd8c5686..80f131d0df 100644 --- a/package/system/rpcd/Makefile +++ b/package/system/rpcd/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=rpcd -PKG_VERSION:=2016-04-13 +PKG_VERSION:=2016-06-30 PKG_RELEASE=$(PKG_SOURCE_VERSION) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(OPENWRT_GIT)/project/rpcd.git PKG_SOURCE_SUBDIR:=$(PKG_NAME) -PKG_SOURCE_VERSION:=73aea9b8b621a1ce034bc6ee00c9d058a40c8a3d +PKG_SOURCE_VERSION:=23417e94d25570e6d62542bac46edd51e8e0243a PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz PKG_MAINTAINER:=Jo-Philipp Wich -- cgit v1.2.3 From e7d244374389586bfe6fa31be6403f656c2569a3 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 29 Sep 2016 14:21:21 +0200 Subject: CC: kernel: update kernel 3.18 to version 3.18.36 Signed-off-by: Hauke Mehrtens --- include/kernel-version.mk | 4 +- ...make-bootconsole-wait-for-both-THRE-and-T.patch | 49 --------------------- .../718-MIPS-ath79-add-EPG5000-support.patch | 6 +-- .../736-MIPS-ath79-add-MC-MAC1200R-support.patch | 6 +-- .../737-MIPS-ath79-add-om5p-an-support.patch | 4 +- ...8-MIPS-ath79-add-meraki-mr12-mr16-support.patch | 6 +-- .../799-MIPS-ath79-add-minibox-v1-support.patch | 6 +-- .../800-MIPS-ath79-add-RB922GS-support.patch | 6 +-- .../patches-3.18/902-unaligned_access_hacks.patch | 8 ++-- .../903-MIPS-ath79-ubnt-rocket-m-xw-support.patch | 2 +- ...04-MIPS-ath79-bitmain-antminer-s1-support.patch | 6 +-- ...05-MIPS-ath79-bitmain-antminer-s3-support.patch | 6 +-- .../906-MIPS-ath79-add-blackswift.patch | 6 +-- .../patches-3.18/907-MIPS-ath79-add-WPN824N.patch | 4 +- .../907-MIPS-ath79-add-tl-wa901nd-v4-support.patch | 40 ++++++++--------- .../150-pci-do-not-probe-too-early.patch | 2 +- ...t-EOF-mark-and-erase-all-remaining-blocks.patch | 2 +- ...-xhci-add-Broadcom-specific-fake-doorbell.patch | 4 +- ...ce-default-mouse-polling-interval-to-60Hz.patch | 2 +- ...-make-overcurrent-messages-more-prominent.patch | 2 +- ...around-unaligned-accesses-failing-on-bcm6.patch | 2 +- ..._freeing_init-new-hook-for-archs-before-m.patch | 10 ++--- .../generic/patches-3.18/204-module_strip.patch | 4 +- .../494-mtd-ubi-add-EOF-marker-support.patch | 2 +- .../811-pci_disable_usb_common_quirks.patch | 2 +- .../820-usb_add_usb_find_device_by_name.patch | 2 +- .../0001-MIPS-lantiq-add-pcie-driver.patch | 2 +- .../oxnas/patches-3.18/320-oxnas-irqchip.patch | 2 +- .../0052-i2c-MIPS-adds-ralink-I2C-driver.patch | 4 +- ...0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch | 4 +- .../0062-mt7621-add-ECHI-OCHI-XCHI-support.patch | 38 ++++++++-------- ...16-dt-sunxi-update-compats-for-tempcurves.patch | 51 ---------------------- 32 files changed, 97 insertions(+), 197 deletions(-) delete mode 100644 target/linux/ar71xx/patches-3.18/003-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch delete mode 100644 target/linux/sunxi/patches-3.18/116-dt-sunxi-update-compats-for-tempcurves.patch diff --git a/include/kernel-version.mk b/include/kernel-version.mk index f2744249d9..81cd12355e 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -2,9 +2,9 @@ LINUX_RELEASE?=1 -LINUX_VERSION-3.18 = .29 +LINUX_VERSION-3.18 = .36 -LINUX_KERNEL_MD5SUM-3.18.29 = b25737a0bc98e80d12200de93f239c28 +LINUX_KERNEL_MD5SUM-3.18.36 = 31b1699c1285aeeb81fb25750baa50d9 ifdef KERNEL_PATCHVER LINUX_VERSION:=$(KERNEL_PATCHVER)$(strip $(LINUX_VERSION-$(KERNEL_PATCHVER))) diff --git a/target/linux/ar71xx/patches-3.18/003-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch b/target/linux/ar71xx/patches-3.18/003-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch deleted file mode 100644 index 2eba263732..0000000000 --- a/target/linux/ar71xx/patches-3.18/003-MIPS-ath79-make-bootconsole-wait-for-both-THRE-and-T.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f1ba020af5076172c9d29006a747ccf40027fedc Mon Sep 17 00:00:00 2001 -Message-Id: -From: Matthias Schiffer -Date: Thu, 24 Mar 2016 15:34:05 +0100 -Subject: [PATCH] MIPS: ath79: make bootconsole wait for both THRE and TEMT - -This makes the ath79 bootconsole behave the same way as the generic 8250 -bootconsole. - -Also waiting for TEMT (transmit buffer is empty) instead of just THRE -(transmit buffer is not full) ensures that all characters have been -transmitted before the real serial driver starts reconfiguring the serial -controller (which would sometimes result in garbage being transmitted.) -This change does not cause a visible performance loss. - -In addition, this seems to fix a hang observed in certain configurations on -many AR7xxx/AR9xxx SoCs during autoconfig of the real serial driver. - -A more complete follow-up patch will disable 8250 autoconfig for ath79 -altogether (the serial controller is detected as a 16550A, which is not -fully compatible with the ath79 serial, and the autoconfig may lead to -undefined behavior on ath79.) - -Cc: -Signed-off-by: Matthias Schiffer ---- - arch/mips/ath79/early_printk.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - ---- a/arch/mips/ath79/early_printk.c -+++ b/arch/mips/ath79/early_printk.c -@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(voi - } while (1); - } - -+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -+ - static void prom_putchar_ar71xx(unsigned char ch) - { - void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); - -- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); -+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); - __raw_writel(ch, base + UART_TX * 4); -- prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE); -+ prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY); - } - - static void prom_putchar_ar933x(unsigned char ch) diff --git a/target/linux/ar71xx/patches-3.18/718-MIPS-ath79-add-EPG5000-support.patch b/target/linux/ar71xx/patches-3.18/718-MIPS-ath79-add-EPG5000-support.patch index a47e24d61b..d083c7bc3c 100644 --- a/target/linux/ar71xx/patches-3.18/718-MIPS-ath79-add-EPG5000-support.patch +++ b/target/linux/ar71xx/patches-3.18/718-MIPS-ath79-add-EPG5000-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -196,6 +196,17 @@ config ATH79_MACH_F9K1115V2 +@@ -205,6 +205,17 @@ config ATH79_MACH_F9K1115V2 select ATH79_DEV_USB select ATH79_DEV_WMAC @@ -20,7 +20,7 @@ select SOC_QCA955X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -72,6 +72,7 @@ obj-$(CONFIG_ATH79_MACH_EAP300V2) += mac +@@ -73,6 +73,7 @@ obj-$(CONFIG_ATH79_MACH_EAP300V2) += mac obj-$(CONFIG_ATH79_MACH_EAP7660D) += mach-eap7660d.o obj-$(CONFIG_ATH79_MACH_EL_M150) += mach-el-m150.o obj-$(CONFIG_ATH79_MACH_EL_MINI) += mach-el-mini.o @@ -30,7 +30,7 @@ obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -62,6 +62,7 @@ enum ath79_mach_type { +@@ -63,6 +63,7 @@ enum ath79_mach_type { ATH79_MACH_EL_M150, /* EasyLink EL-M150 */ ATH79_MACH_EL_MINI, /* EasyLink EL-MINI */ ATH79_MACH_ESR1750, /* EnGenius ESR1750 */ diff --git a/target/linux/ar71xx/patches-3.18/736-MIPS-ath79-add-MC-MAC1200R-support.patch b/target/linux/ar71xx/patches-3.18/736-MIPS-ath79-add-MC-MAC1200R-support.patch index cef612b300..b4d3ec100c 100644 --- a/target/linux/ar71xx/patches-3.18/736-MIPS-ath79-add-MC-MAC1200R-support.patch +++ b/target/linux/ar71xx/patches-3.18/736-MIPS-ath79-add-MC-MAC1200R-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -590,6 +590,16 @@ config ATH79_MACH_R6100 +@@ -599,6 +599,16 @@ config ATH79_MACH_R6100 select ATH79_DEV_USB select ATH79_DEV_WMAC @@ -19,7 +19,7 @@ select SOC_AR71XX --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -81,6 +81,7 @@ obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) + +@@ -82,6 +82,7 @@ obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) + obj-$(CONFIG_ATH79_MACH_JA76PF) += mach-ja76pf.o obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o @@ -29,7 +29,7 @@ obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -121,6 +121,7 @@ enum ath79_mach_type { +@@ -122,6 +122,7 @@ enum ath79_mach_type { ATH79_MACH_TEW_673GRU, /* TRENDnet TEW-673GRU */ ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */ ATH79_MACH_TEW_732BR, /* TRENDnet TEW-732BR */ diff --git a/target/linux/ar71xx/patches-3.18/737-MIPS-ath79-add-om5p-an-support.patch b/target/linux/ar71xx/patches-3.18/737-MIPS-ath79-add-om5p-an-support.patch index 3fbfba7024..137a09ab50 100644 --- a/target/linux/ar71xx/patches-3.18/737-MIPS-ath79-add-om5p-an-support.patch +++ b/target/linux/ar71xx/patches-3.18/737-MIPS-ath79-add-om5p-an-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -87,6 +87,7 @@ enum ath79_mach_type { +@@ -88,6 +88,7 @@ enum ath79_mach_type { ATH79_MACH_OM2P_LC, /* OpenMesh OM2P-LC */ ATH79_MACH_OM2Pv2, /* OpenMesh OM2Pv2 */ ATH79_MACH_OM2P, /* OpenMesh OM2P */ @@ -10,7 +10,7 @@ ATH79_MACH_PB42, /* Atheros PB42 */ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -743,6 +743,7 @@ config ATH79_MACH_OM2P +@@ -752,6 +752,7 @@ config ATH79_MACH_OM2P config ATH79_MACH_OM5P bool "OpenMesh OM5P board support" select SOC_AR934X diff --git a/target/linux/ar71xx/patches-3.18/738-MIPS-ath79-add-meraki-mr12-mr16-support.patch b/target/linux/ar71xx/patches-3.18/738-MIPS-ath79-add-meraki-mr12-mr16-support.patch index ceee0aa05c..84ae4003af 100644 --- a/target/linux/ar71xx/patches-3.18/738-MIPS-ath79-add-meraki-mr12-mr16-support.patch +++ b/target/linux/ar71xx/patches-3.18/738-MIPS-ath79-add-meraki-mr12-mr16-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -760,6 +760,26 @@ config ATH79_MACH_ONION_OMEGA +@@ -769,6 +769,26 @@ config ATH79_MACH_ONION_OMEGA select ATH79_DEV_USB select ATH79_DEV_WMAC @@ -29,7 +29,7 @@ select SOC_AR934X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -82,6 +82,8 @@ obj-$(CONFIG_ATH79_MACH_JA76PF) += mach +@@ -83,6 +83,8 @@ obj-$(CONFIG_ATH79_MACH_JA76PF) += mach obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o @@ -40,7 +40,7 @@ obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -71,6 +71,8 @@ enum ath79_mach_type { +@@ -72,6 +72,8 @@ enum ath79_mach_type { ATH79_MACH_JA76PF2, /* jjPlus JA76PF2 */ ATH79_MACH_JWAP003, /* jjPlus JWAP003 */ ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */ diff --git a/target/linux/ar71xx/patches-3.18/799-MIPS-ath79-add-minibox-v1-support.patch b/target/linux/ar71xx/patches-3.18/799-MIPS-ath79-add-minibox-v1-support.patch index dab82a3df3..e77d4ef41b 100644 --- a/target/linux/ar71xx/patches-3.18/799-MIPS-ath79-add-minibox-v1-support.patch +++ b/target/linux/ar71xx/patches-3.18/799-MIPS-ath79-add-minibox-v1-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -65,6 +65,7 @@ enum ath79_mach_type { +@@ -66,6 +66,7 @@ enum ath79_mach_type { ATH79_MACH_EPG5000, /* EnGenius EPG5000 */ ATH79_MACH_F9K1115V2, /* Belkin AC1750DB */ ATH79_MACH_GL_INET, /* GL-CONNECT GL-INET */ @@ -10,7 +10,7 @@ ATH79_MACH_JA76PF, /* jjPlus JA76PF */ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -522,6 +522,16 @@ config ATH79_MACH_EAP300V2 +@@ -531,6 +531,16 @@ config ATH79_MACH_EAP300V2 select ATH79_DEV_M25P80 select ATH79_DEV_WMAC @@ -29,7 +29,7 @@ select SOC_AR933X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -76,6 +76,7 @@ obj-$(CONFIG_ATH79_MACH_EPG5000) += mach +@@ -77,6 +77,7 @@ obj-$(CONFIG_ATH79_MACH_EPG5000) += mach obj-$(CONFIG_ATH79_MACH_ESR1750) += mach-esr1750.o obj-$(CONFIG_ATH79_MACH_F9K1115V2) += mach-f9k1115v2.o obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o diff --git a/target/linux/ar71xx/patches-3.18/800-MIPS-ath79-add-RB922GS-support.patch b/target/linux/ar71xx/patches-3.18/800-MIPS-ath79-add-RB922GS-support.patch index 6f1795f24d..a387bdd33b 100644 --- a/target/linux/ar71xx/patches-3.18/800-MIPS-ath79-add-RB922GS-support.patch +++ b/target/linux/ar71xx/patches-3.18/800-MIPS-ath79-add-RB922GS-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -635,6 +635,16 @@ config ATH79_MACH_RB91X +@@ -644,6 +644,16 @@ config ATH79_MACH_RB91X select ATH79_DEV_USB select ATH79_ROUTERBOOT @@ -19,7 +19,7 @@ select SOC_AR934X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -104,6 +104,7 @@ obj-$(CONFIG_ATH79_MACH_R6100) += mach- +@@ -105,6 +105,7 @@ obj-$(CONFIG_ATH79_MACH_R6100) += mach- obj-$(CONFIG_ATH79_MACH_RB4XX) += mach-rb4xx.o obj-$(CONFIG_ATH79_MACH_RB750) += mach-rb750.o obj-$(CONFIG_ATH79_MACH_RB91X) += mach-rb91x.o @@ -29,7 +29,7 @@ obj-$(CONFIG_ATH79_MACH_RBSXTLITE) += mach-rbsxtlite.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -111,6 +111,7 @@ enum ath79_mach_type { +@@ -112,6 +112,7 @@ enum ath79_mach_type { ATH79_MACH_RB_750G_R3, /* MikroTik RouterBOARD 750GL */ ATH79_MACH_RB_751, /* MikroTik RouterBOARD 751 */ ATH79_MACH_RB_751G, /* Mikrotik RouterBOARD 751G */ diff --git a/target/linux/ar71xx/patches-3.18/902-unaligned_access_hacks.patch b/target/linux/ar71xx/patches-3.18/902-unaligned_access_hacks.patch index d077b60bc8..dc0476919e 100644 --- a/target/linux/ar71xx/patches-3.18/902-unaligned_access_hacks.patch +++ b/target/linux/ar71xx/patches-3.18/902-unaligned_access_hacks.patch @@ -263,7 +263,7 @@ case IPV6_2292HOPOPTS: --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c -@@ -393,7 +393,7 @@ static void ip6gre_err(struct sk_buff *s +@@ -394,7 +394,7 @@ static void ip6gre_err(struct sk_buff *s t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr, flags & GRE_KEY ? @@ -272,7 +272,7 @@ p[1]); if (t == NULL) return; -@@ -475,11 +475,11 @@ static int ip6gre_rcv(struct sk_buff *sk +@@ -476,11 +476,11 @@ static int ip6gre_rcv(struct sk_buff *sk offset += 4; } if (flags&GRE_KEY) { @@ -286,7 +286,7 @@ offset += 4; } } -@@ -744,7 +744,7 @@ static netdev_tx_t ip6gre_xmit2(struct s +@@ -745,7 +745,7 @@ static netdev_tx_t ip6gre_xmit2(struct s if (tunnel->parms.o_flags&GRE_SEQ) { ++tunnel->o_seqno; @@ -295,7 +295,7 @@ ptr--; } if (tunnel->parms.o_flags&GRE_KEY) { -@@ -840,7 +840,7 @@ static inline int ip6gre_xmit_ipv6(struc +@@ -841,7 +841,7 @@ static inline int ip6gre_xmit_ipv6(struc dsfield = ipv6_get_dsfield(ipv6h); if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) diff --git a/target/linux/ar71xx/patches-3.18/903-MIPS-ath79-ubnt-rocket-m-xw-support.patch b/target/linux/ar71xx/patches-3.18/903-MIPS-ath79-ubnt-rocket-m-xw-support.patch index 96a16c28bc..7c187ce950 100644 --- a/target/linux/ar71xx/patches-3.18/903-MIPS-ath79-ubnt-rocket-m-xw-support.patch +++ b/target/linux/ar71xx/patches-3.18/903-MIPS-ath79-ubnt-rocket-m-xw-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -178,6 +178,7 @@ enum ath79_mach_type { +@@ -179,6 +179,7 @@ enum ath79_mach_type { ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ ATH79_MACH_UBNT_NANO_M_XW, /* Ubiquiti NanoStation M XW */ ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */ diff --git a/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-bitmain-antminer-s1-support.patch b/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-bitmain-antminer-s1-support.patch index c3ee5dc899..8cd4010bdc 100644 --- a/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-bitmain-antminer-s1-support.patch +++ b/target/linux/ar71xx/patches-3.18/904-MIPS-ath79-bitmain-antminer-s1-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -21,6 +21,7 @@ enum ath79_mach_type { +@@ -22,6 +22,7 @@ enum ath79_mach_type { ATH79_MACH_ALL0258N, /* Allnet ALL0258N */ ATH79_MACH_ALL0305, /* Allnet ALL0305 */ ATH79_MACH_ALL0315N, /* Allnet ALL0315N */ @@ -10,7 +10,7 @@ ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -56,6 +56,16 @@ config ATH79_MACH_ALL0315N +@@ -65,6 +65,16 @@ config ATH79_MACH_ALL0315N select ATH79_DEV_LEDS_GPIO select ATH79_DEV_M25P80 @@ -29,7 +29,7 @@ select SOC_AR724X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -42,6 +42,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += ma +@@ -43,6 +43,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += ma obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach-alfa-nx.o obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o diff --git a/target/linux/ar71xx/patches-3.18/905-MIPS-ath79-bitmain-antminer-s3-support.patch b/target/linux/ar71xx/patches-3.18/905-MIPS-ath79-bitmain-antminer-s3-support.patch index c1cb70e864..12a267d13f 100644 --- a/target/linux/ar71xx/patches-3.18/905-MIPS-ath79-bitmain-antminer-s3-support.patch +++ b/target/linux/ar71xx/patches-3.18/905-MIPS-ath79-bitmain-antminer-s3-support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -66,6 +66,16 @@ config ATH79_MACH_ANTMINER_S1 +@@ -75,6 +75,16 @@ config ATH79_MACH_ANTMINER_S1 select ATH79_DEV_USB select ATH79_DEV_WMAC @@ -19,7 +19,7 @@ select SOC_AR724X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -43,6 +43,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach +@@ -44,6 +44,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o obj-$(CONFIG_ATH79_MACH_ANTMINER_S1)+= mach-antminer-s1.o @@ -29,7 +29,7 @@ obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -22,6 +22,7 @@ enum ath79_mach_type { +@@ -23,6 +23,7 @@ enum ath79_mach_type { ATH79_MACH_ALL0305, /* Allnet ALL0305 */ ATH79_MACH_ALL0315N, /* Allnet ALL0315N */ ATH79_MACH_ANTMINER_S1, /* Antminer-S1 */ diff --git a/target/linux/ar71xx/patches-3.18/906-MIPS-ath79-add-blackswift.patch b/target/linux/ar71xx/patches-3.18/906-MIPS-ath79-add-blackswift.patch index 4d01a805a6..e12f22813e 100644 --- a/target/linux/ar71xx/patches-3.18/906-MIPS-ath79-add-blackswift.patch +++ b/target/linux/ar71xx/patches-3.18/906-MIPS-ath79-add-blackswift.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -887,6 +887,16 @@ config ATH79_MACH_EAP7660D +@@ -896,6 +896,16 @@ config ATH79_MACH_EAP7660D select ATH79_DEV_LEDS_GPIO select ATH79_DEV_M25P80 @@ -19,7 +19,7 @@ select SOC_QCA955X --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile -@@ -54,6 +54,7 @@ obj-$(CONFIG_ATH79_MACH_AP96) += mach-a +@@ -55,6 +55,7 @@ obj-$(CONFIG_ATH79_MACH_AP96) += mach-a obj-$(CONFIG_ATH79_MACH_ARCHER_C7) += mach-archer-c7.o obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A)+= mach-bhu-bxu2000n2-a.o @@ -29,7 +29,7 @@ obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -37,6 +37,7 @@ enum ath79_mach_type { +@@ -38,6 +38,7 @@ enum ath79_mach_type { ATH79_MACH_ARCHER_C7, /* TP-LINK Archer C7 board */ ATH79_MACH_AW_NR580, /* AzureWave AW-NR580 */ ATH79_MACH_BHU_BXU2000N2_A1, /* BHU BXU2000n-2 A1 */ diff --git a/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-WPN824N.patch b/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-WPN824N.patch index 2f0c964d38..d58a26fe5c 100644 --- a/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-WPN824N.patch +++ b/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-WPN824N.patch @@ -1,6 +1,6 @@ --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig -@@ -741,7 +741,7 @@ config ATH79_MACH_WNR2000 +@@ -750,7 +750,7 @@ config ATH79_MACH_WNR2000 select ATH79_DEV_WMAC config ATH79_MACH_WNR2000_V3 @@ -11,7 +11,7 @@ select ATH79_DEV_ETH --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h -@@ -204,6 +204,7 @@ enum ath79_mach_type { +@@ -206,6 +206,7 @@ enum ath79_mach_type { ATH79_MACH_WNR2200, /* NETGEAR WNR2200 */ ATH79_MACH_WNR612_V2, /* NETGEAR WNR612 v2 */ ATH79_MACH_WNR1000_V2, /* NETGEAR WNR1000 v2 */ diff --git a/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-tl-wa901nd-v4-support.patch b/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-tl-wa901nd-v4-support.patch index ebd9e52e19..37312adeb8 100644 --- a/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-tl-wa901nd-v4-support.patch +++ b/target/linux/ar71xx/patches-3.18/907-MIPS-ath79-add-tl-wa901nd-v4-support.patch @@ -1,19 +1,19 @@ ---- a/arch/mips/ath79/machtypes.h 2016-04-12 21:08:09.309541276 +0200 -+++ b/arch/mips/ath79/machtypes.h 2016-04-12 21:08:43.200013377 +0200 -@@ -152,6 +152,7 @@ - ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ - ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ - ATH79_MACH_TL_WA901ND_V3, /* TP-LINK TL-WA901ND v3 */ +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -152,6 +152,7 @@ enum ath79_mach_type { + ATH79_MACH_TL_WA901ND, /* TP-LINK TL-WA901ND */ + ATH79_MACH_TL_WA901ND_V2, /* TP-LINK TL-WA901ND v2 */ + ATH79_MACH_TL_WA901ND_V3, /* TP-LINK TL-WA901ND v3 */ + ATH79_MACH_TL_WA901ND_V4, /* TP-LINK TL-WA901ND v4 */ - ATH79_MACH_TL_WDR3500, /* TP-LINK TL-WDR3500 */ - ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */ - ATH79_MACH_TL_WDR4900_V2, /* TP-LINK TL-WDR4900 v2 */ ---- a/arch/mips/ath79/Kconfig 2016-04-12 21:00:07.267269819 +0200 -+++ b/arch/mips/ath79/Kconfig 2016-04-12 21:00:08.803199911 +0200 -@@ -1023,6 +1023,15 @@ - select ATH79_DEV_M25P80 - select ATH79_DEV_WMAC - + ATH79_MACH_TL_WDR3500, /* TP-LINK TL-WDR3500 */ + ATH79_MACH_TL_WDR4300, /* TP-LINK TL-WDR4300 */ + ATH79_MACH_TL_WDR4900_V2, /* TP-LINK TL-WDR4900 v2 */ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -1023,6 +1023,15 @@ config ATH79_MACH_TL_WA901ND_V2 + select ATH79_DEV_M25P80 + select ATH79_DEV_WMAC + +config ATH79_MACH_TL_WA901ND_V4 + bool "TP-LINK TL-WA901ND v4 support" + select SOC_QCA956X @@ -24,11 +24,11 @@ + select ATH79_DEV_WMAC + config ATH79_MACH_TL_WDR3500 - bool "TP-LINK TL-WDR3500 board support" - select SOC_AR934X ---- a/arch/mips/ath79/Makefile 2016-04-12 21:03:21.974455904 +0200 -+++ b/arch/mips/ath79/Makefile 2016-04-12 21:02:56.115621524 +0200 -@@ -128,6 +128,7 @@ + bool "TP-LINK TL-WDR3500 board support" + select SOC_AR934X +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -128,6 +128,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WA7210N_V2) + obj-$(CONFIG_ATH79_MACH_TL_WA830RE_V2) += mach-tl-wa830re-v2.o obj-$(CONFIG_ATH79_MACH_TL_WA901ND) += mach-tl-wa901nd.o obj-$(CONFIG_ATH79_MACH_TL_WA901ND_V2) += mach-tl-wa901nd-v2.o diff --git a/target/linux/bcm53xx/patches-3.18/150-pci-do-not-probe-too-early.patch b/target/linux/bcm53xx/patches-3.18/150-pci-do-not-probe-too-early.patch index 2964a26faa..236b3ee204 100644 --- a/target/linux/bcm53xx/patches-3.18/150-pci-do-not-probe-too-early.patch +++ b/target/linux/bcm53xx/patches-3.18/150-pci-do-not-probe-too-early.patch @@ -15,7 +15,7 @@ Signed-off-by: Hauke Mehrtens --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c -@@ -2100,7 +2100,10 @@ struct pci_bus *pci_scan_root_bus(struct +@@ -2132,7 +2132,10 @@ struct pci_bus *pci_scan_root_bus(struct if (!found) pci_bus_update_busn_res_end(b, max); diff --git a/target/linux/bcm53xx/patches-3.18/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch b/target/linux/bcm53xx/patches-3.18/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch index 08d4790e2f..64e60ce38f 100644 --- a/target/linux/bcm53xx/patches-3.18/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch +++ b/target/linux/bcm53xx/patches-3.18/500-UBI-Detect-EOF-mark-and-erase-all-remaining-blocks.patch @@ -49,7 +49,7 @@ Signed-off-by: Rafał Miłecki return UBI_IO_BAD_HDR_EBADMSG; --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h -@@ -743,6 +743,7 @@ extern struct mutex ubi_devices_mutex; +@@ -747,6 +747,7 @@ extern struct mutex ubi_devices_mutex; extern struct blocking_notifier_head ubi_notifiers; /* attach.c */ diff --git a/target/linux/bcm53xx/patches-3.18/820-xhci-add-Broadcom-specific-fake-doorbell.patch b/target/linux/bcm53xx/patches-3.18/820-xhci-add-Broadcom-specific-fake-doorbell.patch index 05835df0da..c60de181cc 100644 --- a/target/linux/bcm53xx/patches-3.18/820-xhci-add-Broadcom-specific-fake-doorbell.patch +++ b/target/linux/bcm53xx/patches-3.18/820-xhci-add-Broadcom-specific-fake-doorbell.patch @@ -90,5 +90,5 @@ Signed-off-by: Rafał Miłecki +#endif /* CONFIG_ARCH_BCM_5301X */ + if (!ret) - xhci->xhc_state &= ~(XHCI_STATE_HALTED | XHCI_STATE_DYING); - + /* clear state flags. Including dying, halted or removing */ + xhci->xhc_state = 0; diff --git a/target/linux/brcm2708/patches-3.18/0054-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch b/target/linux/brcm2708/patches-3.18/0054-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch index 1bf26e8db3..50326c7e98 100644 --- a/target/linux/brcm2708/patches-3.18/0054-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch +++ b/target/linux/brcm2708/patches-3.18/0054-hid-Reduce-default-mouse-polling-interval-to-60Hz.patch @@ -19,7 +19,7 @@ Reduces overhead when using X module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); -@@ -1079,8 +1079,12 @@ static int usbhid_start(struct hid_devic +@@ -1071,8 +1071,12 @@ static int usbhid_start(struct hid_devic } /* Change the polling interval of mice. */ diff --git a/target/linux/brcm2708/patches-3.18/0055-usb-core-make-overcurrent-messages-more-prominent.patch b/target/linux/brcm2708/patches-3.18/0055-usb-core-make-overcurrent-messages-more-prominent.patch index 82d36f84ef..1f4ad1bab9 100644 --- a/target/linux/brcm2708/patches-3.18/0055-usb-core-make-overcurrent-messages-more-prominent.patch +++ b/target/linux/brcm2708/patches-3.18/0055-usb-core-make-overcurrent-messages-more-prominent.patch @@ -10,7 +10,7 @@ Hub overcurrent messages are more serious than "debug". Increase loglevel. --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c -@@ -4928,7 +4928,7 @@ static void port_event(struct usb_hub *h +@@ -4934,7 +4934,7 @@ static void port_event(struct usb_hub *h if (portchange & USB_PORT_STAT_C_OVERCURRENT) { u16 status = 0, unused; diff --git a/target/linux/brcm63xx/patches-3.18/803-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch b/target/linux/brcm63xx/patches-3.18/803-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch index 8b603e8b66..7a3c2f01c2 100644 --- a/target/linux/brcm63xx/patches-3.18/803-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch +++ b/target/linux/brcm63xx/patches-3.18/803-jffs2-work-around-unaligned-accesses-failing-on-bcm6.patch @@ -15,7 +15,7 @@ Signed-off-by: Jonas Gorski --- a/fs/jffs2/nodelist.h +++ b/fs/jffs2/nodelist.h -@@ -255,7 +255,7 @@ struct jffs2_full_dirent +@@ -259,7 +259,7 @@ struct jffs2_full_dirent uint32_t ino; /* == zero for unlink */ unsigned int nhash; unsigned char type; diff --git a/target/linux/generic/patches-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch b/target/linux/generic/patches-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch index a6310c625c..2e66de29df 100644 --- a/target/linux/generic/patches-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch +++ b/target/linux/generic/patches-3.18/099-module_arch_freeing_init-new-hook-for-archs-before-m.patch @@ -145,7 +145,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi #endif --- a/kernel/module.c +++ b/kernel/module.c -@@ -1837,6 +1837,10 @@ void __weak module_arch_cleanup(struct m +@@ -1840,6 +1840,10 @@ void __weak module_arch_cleanup(struct m { } @@ -156,7 +156,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi /* Free a module, remove from lists, etc. */ static void free_module(struct module *mod) { -@@ -1869,6 +1873,7 @@ static void free_module(struct module *m +@@ -1872,6 +1876,7 @@ static void free_module(struct module *m /* This may be NULL, but that's OK */ unset_module_init_ro_nx(mod); @@ -164,7 +164,7 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi module_free(mod, mod->module_init); kfree(mod->args); percpu_modfree(mod); -@@ -2958,6 +2963,7 @@ static struct module *layout_and_allocat +@@ -2978,6 +2983,7 @@ static struct module *layout_and_allocat static void module_deallocate(struct module *mod, struct load_info *info) { percpu_modfree(mod); @@ -172,8 +172,8 @@ Origin: backport, https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.gi module_free(mod, mod->module_init); module_free(mod, mod->module_core); } -@@ -3081,6 +3087,7 @@ static int do_init_module(struct module - mod->strtab = mod->core_strtab; +@@ -3100,6 +3106,7 @@ static int do_init_module(struct module + rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms); #endif unset_module_init_ro_nx(mod); + module_arch_freeing_init(mod); diff --git a/target/linux/generic/patches-3.18/204-module_strip.patch b/target/linux/generic/patches-3.18/204-module_strip.patch index deef6b0c9a..f58e0e8c5c 100644 --- a/target/linux/generic/patches-3.18/204-module_strip.patch +++ b/target/linux/generic/patches-3.18/204-module_strip.patch @@ -109,7 +109,7 @@ Signed-off-by: Felix Fietkau config INIT_ALL_POSSIBLE --- a/kernel/module.c +++ b/kernel/module.c -@@ -2674,6 +2674,7 @@ static struct module *setup_load_info(st +@@ -2694,6 +2694,7 @@ static struct module *setup_load_info(st static int check_modinfo(struct module *mod, struct load_info *info, int flags) { @@ -117,7 +117,7 @@ Signed-off-by: Felix Fietkau const char *modmagic = get_modinfo(info, "vermagic"); int err; -@@ -2699,6 +2700,7 @@ static int check_modinfo(struct module * +@@ -2719,6 +2720,7 @@ static int check_modinfo(struct module * pr_warn("%s: module is from the staging directory, the quality " "is unknown, you have been warned.\n", mod->name); } diff --git a/target/linux/generic/patches-3.18/494-mtd-ubi-add-EOF-marker-support.patch b/target/linux/generic/patches-3.18/494-mtd-ubi-add-EOF-marker-support.patch index cd02c13e0c..4b5eb4568d 100644 --- a/target/linux/generic/patches-3.18/494-mtd-ubi-add-EOF-marker-support.patch +++ b/target/linux/generic/patches-3.18/494-mtd-ubi-add-EOF-marker-support.patch @@ -41,7 +41,7 @@ break; --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h -@@ -701,6 +701,7 @@ struct ubi_attach_info { +@@ -705,6 +705,7 @@ struct ubi_attach_info { int mean_ec; uint64_t ec_sum; int ec_count; diff --git a/target/linux/generic/patches-3.18/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/patches-3.18/811-pci_disable_usb_common_quirks.patch index b54d1509a5..a7bf0bb9fa 100644 --- a/target/linux/generic/patches-3.18/811-pci_disable_usb_common_quirks.patch +++ b/target/linux/generic/patches-3.18/811-pci_disable_usb_common_quirks.patch @@ -84,7 +84,7 @@ #endif /* __LINUX_USB_PCI_QUIRKS_H */ --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h -@@ -444,7 +444,14 @@ extern int usb_hcd_pci_probe(struct pci_ +@@ -445,7 +445,14 @@ extern int usb_hcd_pci_probe(struct pci_ extern void usb_hcd_pci_remove(struct pci_dev *dev); extern void usb_hcd_pci_shutdown(struct pci_dev *dev); diff --git a/target/linux/generic/patches-3.18/820-usb_add_usb_find_device_by_name.patch b/target/linux/generic/patches-3.18/820-usb_add_usb_find_device_by_name.patch index e381cc97be..bf19f5f783 100644 --- a/target/linux/generic/patches-3.18/820-usb_add_usb_find_device_by_name.patch +++ b/target/linux/generic/patches-3.18/820-usb_add_usb_find_device_by_name.patch @@ -74,7 +74,7 @@ * @dev: device the buffer will be used with --- a/include/linux/usb.h +++ b/include/linux/usb.h -@@ -721,6 +721,7 @@ static inline bool usb_device_no_sg_cons +@@ -720,6 +720,7 @@ static inline bool usb_device_no_sg_cons return udev && udev->bus && udev->bus->no_sg_constraint; } diff --git a/target/linux/lantiq/patches-3.18/0001-MIPS-lantiq-add-pcie-driver.patch b/target/linux/lantiq/patches-3.18/0001-MIPS-lantiq-add-pcie-driver.patch index 85311c21f2..4e0a51298e 100644 --- a/target/linux/lantiq/patches-3.18/0001-MIPS-lantiq-add-pcie-driver.patch +++ b/target/linux/lantiq/patches-3.18/0001-MIPS-lantiq-add-pcie-driver.patch @@ -5514,7 +5514,7 @@ Signed-off-by: John Crispin (transaction layer end-to-end CRC checking). --- a/include/linux/pci.h +++ b/include/linux/pci.h -@@ -1160,6 +1160,8 @@ void pci_walk_bus(struct pci_bus *top, i +@@ -1163,6 +1163,8 @@ void pci_walk_bus(struct pci_bus *top, i void *userdata); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); diff --git a/target/linux/oxnas/patches-3.18/320-oxnas-irqchip.patch b/target/linux/oxnas/patches-3.18/320-oxnas-irqchip.patch index 5e130bea81..c38d6bb045 100644 --- a/target/linux/oxnas/patches-3.18/320-oxnas-irqchip.patch +++ b/target/linux/oxnas/patches-3.18/320-oxnas-irqchip.patch @@ -24,7 +24,7 @@ obj-$(CONFIG_ARCH_VT8500) += irq-vt8500.o --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c -@@ -1044,6 +1044,7 @@ IRQCHIP_DECLARE(gic_400, "arm,gic-400", +@@ -1052,6 +1052,7 @@ IRQCHIP_DECLARE(gic_400, "arm,gic-400", IRQCHIP_DECLARE(cortex_a15_gic, "arm,cortex-a15-gic", gic_of_init); IRQCHIP_DECLARE(cortex_a9_gic, "arm,cortex-a9-gic", gic_of_init); IRQCHIP_DECLARE(cortex_a7_gic, "arm,cortex-a7-gic", gic_of_init); diff --git a/target/linux/ramips/patches-3.18/0052-i2c-MIPS-adds-ralink-I2C-driver.patch b/target/linux/ramips/patches-3.18/0052-i2c-MIPS-adds-ralink-I2C-driver.patch index 40c61072d1..b136b52b09 100644 --- a/target/linux/ramips/patches-3.18/0052-i2c-MIPS-adds-ralink-I2C-driver.patch +++ b/target/linux/ramips/patches-3.18/0052-i2c-MIPS-adds-ralink-I2C-driver.patch @@ -45,7 +45,7 @@ Signed-off-by: John Crispin +}; --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig -@@ -711,6 +711,10 @@ +@@ -711,6 +711,10 @@ config I2C_RK3X This driver can also be built as a module. If so, the module will be called i2c-rk3x. @@ -58,7 +58,7 @@ Signed-off-by: John Crispin help --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile -@@ -66,6 +66,7 @@ +@@ -66,6 +66,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o obj-$(CONFIG_I2C_PXA) += i2c-pxa.o obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o diff --git a/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch b/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch index d52cd2e09d..b00d36bdd9 100644 --- a/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch +++ b/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch @@ -1,6 +1,6 @@ --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig -@@ -439,6 +439,12 @@ +@@ -439,6 +439,12 @@ config SPI_RT2880 help This selects a driver for the Ralink RT288x/RT305x SPI Controller. @@ -15,7 +15,7 @@ depends on ARCH_S3C24XX --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile -@@ -46,6 +46,7 @@ +@@ -46,6 +46,7 @@ obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70l obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o diff --git a/target/linux/ramips/patches-3.18/0062-mt7621-add-ECHI-OCHI-XCHI-support.patch b/target/linux/ramips/patches-3.18/0062-mt7621-add-ECHI-OCHI-XCHI-support.patch index 4df5b3e7e5..3a8f47b104 100644 --- a/target/linux/ramips/patches-3.18/0062-mt7621-add-ECHI-OCHI-XCHI-support.patch +++ b/target/linux/ramips/patches-3.18/0062-mt7621-add-ECHI-OCHI-XCHI-support.patch @@ -1,6 +1,6 @@ --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c -@@ -214,8 +214,13 @@ int usb_hcd_pci_probe(struct pci_dev *de +@@ -223,8 +223,13 @@ int usb_hcd_pci_probe(struct pci_dev *de goto disable_pci; } @@ -5349,7 +5349,7 @@ /* TODO: copied from ehci-hcd.c - can this be refactored? */ /* * xhci_handshake - spin reading hc until handshake completes or fails -@@ -199,7 +221,7 @@ int xhci_reset(struct xhci_hcd *xhci) +@@ -200,7 +222,7 @@ int xhci_reset(struct xhci_hcd *xhci) return ret; } @@ -5358,7 +5358,7 @@ static int xhci_free_msi(struct xhci_hcd *xhci) { int i; -@@ -449,6 +471,11 @@ static void compliance_mode_recovery(uns +@@ -450,6 +472,11 @@ static void compliance_mode_recovery(uns "Attempting compliance mode recovery"); hcd = xhci->shared_hcd; @@ -5370,7 +5370,7 @@ if (hcd->state == HC_STATE_SUSPENDED) usb_hcd_resume_root_hub(hcd); -@@ -498,6 +525,9 @@ static bool xhci_compliance_mode_recover +@@ -499,6 +526,9 @@ static bool xhci_compliance_mode_recover { const char *dmi_product_name, *dmi_sys_vendor; @@ -5380,7 +5380,7 @@ dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); if (!dmi_product_name || !dmi_sys_vendor) -@@ -543,6 +573,10 @@ int xhci_init(struct usb_hcd *hcd) +@@ -544,6 +574,10 @@ int xhci_init(struct usb_hcd *hcd) xhci_dbg_trace(xhci, trace_xhci_dbg_init, "xHCI doesn't need link TRB QUIRK"); } @@ -5391,7 +5391,7 @@ retval = xhci_mem_init(xhci, GFP_KERNEL); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_init"); -@@ -627,7 +661,11 @@ int xhci_run(struct usb_hcd *hcd) +@@ -628,7 +662,11 @@ int xhci_run(struct usb_hcd *hcd) "// Set the interrupt modulation register"); temp = readl(&xhci->ir_set->irq_control); temp &= ~ER_IRQ_INTERVAL_MASK; @@ -5403,7 +5403,7 @@ writel(temp, &xhci->ir_set->irq_control); /* Set the HCD state before we enable the irqs */ -@@ -652,6 +690,9 @@ int xhci_run(struct usb_hcd *hcd) +@@ -653,6 +691,9 @@ int xhci_run(struct usb_hcd *hcd) xhci_queue_vendor_command(xhci, command, 0, 0, 0, TRB_TYPE(TRB_NEC_GET_FW)); } @@ -5413,7 +5413,7 @@ xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB2 roothub"); return 0; -@@ -1650,6 +1691,14 @@ int xhci_drop_endpoint(struct usb_hcd *h +@@ -1651,6 +1692,14 @@ int xhci_drop_endpoint(struct usb_hcd *h u32 drop_flag; u32 new_add_flags, new_drop_flags; int ret; @@ -5428,7 +5428,7 @@ ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); if (ret <= 0) -@@ -1697,6 +1746,40 @@ int xhci_drop_endpoint(struct usb_hcd *h +@@ -1698,6 +1747,40 @@ int xhci_drop_endpoint(struct usb_hcd *h xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); @@ -5469,7 +5469,7 @@ xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", (unsigned int) ep->desc.bEndpointAddress, udev->slot_id, -@@ -1729,6 +1812,19 @@ int xhci_add_endpoint(struct usb_hcd *hc +@@ -1730,6 +1813,19 @@ int xhci_add_endpoint(struct usb_hcd *hc u32 new_add_flags, new_drop_flags; struct xhci_virt_device *virt_dev; int ret = 0; @@ -5489,7 +5489,7 @@ ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); if (ret <= 0) { -@@ -1795,6 +1891,56 @@ int xhci_add_endpoint(struct usb_hcd *hc +@@ -1796,6 +1892,56 @@ int xhci_add_endpoint(struct usb_hcd *hc return -ENOMEM; } @@ -5546,7 +5546,7 @@ ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs); new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); -@@ -4465,8 +4611,14 @@ static u16 xhci_call_host_update_timeout +@@ -4467,8 +4613,14 @@ static u16 xhci_call_host_update_timeout u16 *timeout) { if (state == USB3_LPM_U1) @@ -5561,7 +5561,7 @@ return xhci_calculate_u2_timeout(xhci, udev, desc); return USB3_LPM_DISABLED; -@@ -4851,7 +5003,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, +@@ -4853,7 +5005,9 @@ int xhci_gen_setup(struct usb_hcd *hcd, hcd->self.no_sg_constraint = 1; /* XHCI controllers don't stop the ep queue on short packets :| */ @@ -5571,9 +5571,9 @@ if (usb_hcd_is_primary_hcd(hcd)) { xhci = kzalloc(sizeof(struct xhci_hcd), GFP_KERNEL); -@@ -4914,6 +5068,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, - goto error; - xhci_dbg(xhci, "Reset complete\n"); +@@ -4926,6 +5080,10 @@ int xhci_gen_setup(struct usb_hcd *hcd, + if (xhci->quirks & XHCI_NO_64BIT_SUPPORT) + xhci->hcc_params &= ~BIT(0); +#if defined (CONFIG_USB_MT7621_XHCI_PLATFORM) + setInitialReg(); @@ -5582,7 +5582,7 @@ /* Set dma_mask and coherent_dma_mask to 64-bits, * if xHC supports 64-bit addressing */ if (HCC_64BIT_ADDR(xhci->hcc_params) && -@@ -5008,8 +5166,57 @@ MODULE_DESCRIPTION(DRIVER_DESC); +@@ -5020,8 +5178,57 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_LICENSE("GPL"); @@ -5664,7 +5664,7 @@ /* xHCI PCI Configuration Registers */ #define XHCI_SBRN_OFFSET (0x60) -@@ -1588,8 +1603,12 @@ struct xhci_hcd { +@@ -1590,8 +1605,12 @@ struct xhci_hcd { /* Compliance Mode Recovery Data */ struct timer_list comp_mode_recovery_timer; u32 port_status_u0; @@ -5677,7 +5677,7 @@ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ -@@ -1737,6 +1756,26 @@ void xhci_urb_free_priv(struct xhci_hcd +@@ -1739,6 +1758,26 @@ void xhci_urb_free_priv(struct xhci_hcd void xhci_free_command(struct xhci_hcd *xhci, struct xhci_command *command); diff --git a/target/linux/sunxi/patches-3.18/116-dt-sunxi-update-compats-for-tempcurves.patch b/target/linux/sunxi/patches-3.18/116-dt-sunxi-update-compats-for-tempcurves.patch deleted file mode 100644 index fe8dcdbc0a..0000000000 --- a/target/linux/sunxi/patches-3.18/116-dt-sunxi-update-compats-for-tempcurves.patch +++ /dev/null @@ -1,51 +0,0 @@ -From ff774d842a2bf9136b9c7ddd7f5085a9062705ac Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 16 Jun 2014 20:06:43 +0200 -Subject: [PATCH] ARM: dts: sunxi: Adjust touchscreen compatible for sun5i and - later - -The touchscreen controller in the A13 and later has a different temperature -curve than the one in the original A10, change the compatible for the A13 and -later so that the kernel will use the correct curve. - -Reported-by: Tong Zhang -Signed-off-by: Hans de Goede ---- - arch/arm/boot/dts/sun5i-a10s.dtsi | 2 +- - arch/arm/boot/dts/sun5i-a13.dtsi | 2 +- - arch/arm/boot/dts/sun7i-a20.dtsi | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -533,7 +533,7 @@ - }; - - rtp: rtp@01c25000 { -- compatible = "allwinner,sun4i-a10-ts"; -+ compatible = "allwinner,sun5i-a13-ts"; - reg = <0x01c25000 0x100>; - interrupts = <29>; - }; ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -481,7 +481,7 @@ - }; - - rtp: rtp@01c25000 { -- compatible = "allwinner,sun4i-a10-ts"; -+ compatible = "allwinner,sun5i-a13-ts"; - reg = <0x01c25000 0x100>; - interrupts = <29>; - }; ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -924,7 +924,7 @@ - }; - - rtp: rtp@01c25000 { -- compatible = "allwinner,sun4i-a10-ts"; -+ compatible = "allwinner,sun5i-a13-ts"; - reg = <0x01c25000 0x100>; - interrupts = <0 29 4>; - }; -- cgit v1.2.3 From b0c59f5629f5378bbe9552e1459787cad6384fef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:21:52 +0200 Subject: mac80211: brcmfmac: fix interfaces management MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To work correctly hostapd requires wireless driver to allow interfaces removal. It was working with brcmfmac only partially. Firmware for BCM43602 got some special hack (feature?) that allowed removing all interfaces by disabling mbss mode. It wasn't working with BCM4366 firmware and remaining interfaces were preventing hostapd from starting again. Those patches add support for "interface_remove" firmware method which works with BCM4366 firmware and they make it finally possible to use BCM4366 & brcmfmac & multiple interfaces. Signed-off-by: Rafał Miłecki --- ...ange-function-name-for-brcmf_cfg80211_wai.patch | 99 ++++++++++++++++++++++ ...e-const-char-for-interface-name-in-brcmf_.patch | 39 +++++++++ ...-include-also-core.h-header-in-cfg80211.h.patch | 33 ++++++++ ...dd-missing-break-when-deleting-P2P_DEVICE.patch | 27 ++++++ ...lete-interface-directly-in-code-that-sent.patch | 75 ++++++++++++++++ ...pport-removing-AP-interfaces-with-interfa.patch | 84 ++++++++++++++++++ 6 files changed, 357 insertions(+) create mode 100644 package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch create mode 100644 package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch create mode 100644 package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch create mode 100644 package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch create mode 100644 package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch create mode 100644 package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch diff --git a/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch b/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch new file mode 100644 index 0000000000..e3427de732 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch @@ -0,0 +1,99 @@ +From: Arend van Spriel +Date: Wed, 17 Feb 2016 11:26:50 +0100 +Subject: [PATCH] brcmfmac: change function name for + brcmf_cfg80211_wait_vif_event_timeout() + +Dropping the '_timeout' from the function name as the fact that a timeout +value is passed makes it obvious a timeout is used. Also helps to keep code +lines a bit shorter and easier to stick to 80 char boundary. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -564,8 +564,8 @@ struct wireless_dev *brcmf_ap_add_vif(st + } + + /* wait for firmware event */ +- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, +- BRCMF_VIF_EVENT_TIMEOUT); ++ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD, ++ BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { + brcmf_err("timeout occurred\n"); +@@ -6395,8 +6395,9 @@ bool brcmf_cfg80211_vif_event_armed(stru + + return armed; + } +-int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, +- u8 action, ulong timeout) ++ ++int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg, ++ u8 action, ulong timeout) + { + struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -402,8 +402,8 @@ bool brcmf_get_vif_state_any(struct brcm + void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, + struct brcmf_cfg80211_vif *vif); + bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); +-int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, +- u8 action, ulong timeout); ++int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg, ++ u8 action, ulong timeout); + s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp, bool aborted, + bool fw_abort); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1988,8 +1988,8 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 + brcmf_cfg80211_arm_vif_event(cfg, NULL); + return err; + } +- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE, +- BRCMF_VIF_EVENT_TIMEOUT); ++ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_CHANGE, ++ BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { + brcmf_err("No BRCMF_E_IF_CHANGE event received\n"); +@@ -2090,8 +2090,8 @@ static struct wireless_dev *brcmf_p2p_cr + } + + /* wait for firmware event */ +- err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD, +- BRCMF_VIF_EVENT_TIMEOUT); ++ err = brcmf_cfg80211_wait_vif_event(p2p->cfg, BRCMF_E_IF_ADD, ++ BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); + brcmf_fweh_p2pdev_setup(pri_ifp, false); + if (!err) { +@@ -2180,8 +2180,8 @@ struct wireless_dev *brcmf_p2p_add_vif(s + } + + /* wait for firmware event */ +- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, +- BRCMF_VIF_EVENT_TIMEOUT); ++ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD, ++ BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { + brcmf_err("timeout occurred\n"); +@@ -2274,8 +2274,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph + } + if (!err) { + /* wait for firmware event */ +- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL, +- BRCMF_VIF_EVENT_TIMEOUT); ++ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, ++ BRCMF_VIF_EVENT_TIMEOUT); + if (!err) + err = -EIO; + else diff --git a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch new file mode 100644 index 0000000000..dd6bc37a49 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch @@ -0,0 +1,39 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 17 Jun 2016 12:48:44 +0200 +Subject: [PATCH] brcmfmac: use const char * for interface name in brcmf_add_if +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This function can work just fine with const pointer, it only calls +alloc_netdev which take const as well. Moreover it makes this function +more flexible as some cfg80211 callback may provide const char * as +well, e.g. add_virtual_intf. This will be needed for more advanced +interface management. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -795,7 +795,7 @@ fail: + } + + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, +- bool is_p2pdev, char *name, u8 *mac_addr) ++ bool is_p2pdev, const char *name, u8 *mac_addr) + { + struct brcmf_if *ifp; + struct net_device *ndev; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -212,7 +212,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) + struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); + int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); + struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, +- bool is_p2pdev, char *name, u8 *mac_addr); ++ bool is_p2pdev, const char *name, u8 *mac_addr); + void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); diff --git a/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch b/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch new file mode 100644 index 0000000000..ef35fab7d7 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch @@ -0,0 +1,33 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sat, 18 Jun 2016 18:49:38 +0200 +Subject: [PATCH] brcmfmac: include also core.h header in cfg80211.h +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This header provides two inline functions using struct brcmf_if so we +need core.h to avoid: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_prof’: +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: dereferencing pointer to incomplete type + return &ifp->vif->profile; + ^ +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_vif’: +drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: dereferencing pointer to incomplete type + return ifp->vif; + ^ + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -20,6 +20,7 @@ + /* for brcmu_d11inf */ + #include + ++#include "core.h" + #include "fwil_types.h" + #include "p2p.h" + diff --git a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch new file mode 100644 index 0000000000..4e01532228 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch @@ -0,0 +1,27 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Sun, 19 Jun 2016 01:55:57 +0200 +Subject: [PATCH] brcmfmac: add missing break when deleting P2P_DEVICE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +We obviously don't want to fall through in that switch. With this change +1) We wait for event (triggered by p2p_disc) as expected +2) We remove interface manually on timeout +3) We return 0 on success instead of -ENOTSUPP + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2254,6 +2254,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph + return 0; + brcmf_p2p_cancel_remain_on_channel(vif->ifp); + brcmf_p2p_deinit_discovery(p2p); ++ break; ++ + default: + return -ENOTSUPP; + } 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..f3f6cdb1d6 --- /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?= +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 +Signed-off-by: Kalle Valo +--- + +--- 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" +@@ -225,8 +226,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 +@@ -2281,8 +2281,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/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch new file mode 100644 index 0000000000..55989e60f5 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch @@ -0,0 +1,84 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -750,12 +750,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; +@@ -772,12 +808,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: -- cgit v1.2.3 From b5e7d8a212a4b2428ec681964fa7249a984caff1 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 29 Sep 2016 14:22:40 +0200 Subject: ramips: fix timing issues when using MT7621 spi Signed-off-by: John Crispin --- .../patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch b/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch index b00d36bdd9..4fe9f4c89e 100644 --- a/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch +++ b/target/linux/ramips/patches-3.18/0061-SPI-ralink-add-mt7621-SoC-spi-driver.patch @@ -25,7 +25,7 @@ obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o --- /dev/null +++ b/drivers/spi/spi-mt7621.c -@@ -0,0 +1,391 @@ +@@ -0,0 +1,394 @@ +/* + * spi-mt7621.c -- MediaTek MT7621 SPI controller driver + * @@ -225,6 +225,9 @@ + if (!buf) + continue; + ++ if (t->speed_hz < speed) ++ speed = t->speed_hz; ++ + if (WARN_ON(len + rlen > 36)) { + status = -EIO; + goto msg_done; -- cgit v1.2.3 From 84ea6e0315f93c3c24ba408b4a7015bd30394348 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 29 Sep 2016 14:23:08 +0200 Subject: ramips: fix usb phy initialisation this broke usb20 device detection. Signed-off-by: John Crispin --- .../0037-USB-phy-add-ralink-SoC-driver.patch | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/target/linux/ramips/patches-3.18/0037-USB-phy-add-ralink-SoC-driver.patch b/target/linux/ramips/patches-3.18/0037-USB-phy-add-ralink-SoC-driver.patch index 4dc5a7528b..d4afb42eff 100644 --- a/target/linux/ramips/patches-3.18/0037-USB-phy-add-ralink-SoC-driver.patch +++ b/target/linux/ramips/patches-3.18/0037-USB-phy-add-ralink-SoC-driver.patch @@ -58,19 +58,19 @@ +#define RT_SYSC_REG_CLKCFG1 0x030 +#define RT_SYSC_REG_USB_PHY_CFG 0x05c + -+#define OFS_U2_PHY_AC0 0x00 -+#define OFS_U2_PHY_AC1 0x04 -+#define OFS_U2_PHY_AC2 0x08 -+#define OFS_U2_PHY_ACR0 0x10 -+#define OFS_U2_PHY_ACR1 0x14 -+#define OFS_U2_PHY_ACR2 0x18 -+#define OFS_U2_PHY_ACR3 0x1C -+#define OFS_U2_PHY_ACR4 0x20 -+#define OFS_U2_PHY_AMON0 0x24 -+#define OFS_U2_PHY_DCR0 0x60 -+#define OFS_U2_PHY_DCR1 0x64 -+#define OFS_U2_PHY_DTM0 0x68 -+#define OFS_U2_PHY_DTM1 0x6C ++#define OFS_U2_PHY_AC0 0x800 ++#define OFS_U2_PHY_AC1 0x804 ++#define OFS_U2_PHY_AC2 0x808 ++#define OFS_U2_PHY_ACR0 0x810 ++#define OFS_U2_PHY_ACR1 0x814 ++#define OFS_U2_PHY_ACR2 0x818 ++#define OFS_U2_PHY_ACR3 0x81C ++#define OFS_U2_PHY_ACR4 0x820 ++#define OFS_U2_PHY_AMON0 0x824 ++#define OFS_U2_PHY_DCR0 0x860 ++#define OFS_U2_PHY_DCR1 0x864 ++#define OFS_U2_PHY_DTM0 0x868 ++#define OFS_U2_PHY_DTM1 0x86C + +#define RT_RSTCTRL_UDEV BIT(25) +#define RT_RSTCTRL_UHST BIT(22) -- cgit v1.2.3 From 718c539199c2be24ff92f7aa26c74048b4608eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:23:32 +0200 Subject: mac80211: brcmfmac: support hidden SSID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...mac-respect-hidden_ssid-for-AP-interfaces.patch | 43 ++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch diff --git a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch new file mode 100644 index 0000000000..10a99f5899 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch @@ -0,0 +1,43 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 6 Jul 2016 12:22:54 +0200 +Subject: [PATCH] brcmfmac: respect hidden_ssid for AP interfaces +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This was succesfully tested with 4366B1. A small workaround is needed +for the main interface otherwise it would stuck at the hidden state. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4508,6 +4508,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + brcmf_err("SET SSID error (%d)\n", err); + goto exit; + } ++ ++ if (settings->hidden_ssid) { ++ err = brcmf_fil_iovar_int_set(ifp, "closednet", 1); ++ if (err) { ++ brcmf_err("closednet error (%d)\n", err); ++ goto exit; ++ } ++ } ++ + brcmf_dbg(TRACE, "AP mode configuration complete\n"); + } else if (dev_role == NL80211_IFTYPE_P2P_GO) { + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); +@@ -4566,6 +4575,10 @@ static int brcmf_cfg80211_stop_ap(struct + return err; + } + ++ /* First BSS doesn't get a full reset */ ++ if (ifp->bsscfgidx == 0) ++ brcmf_fil_iovar_int_set(ifp, "closednet", 0); ++ + memset(&join_params, 0, sizeof(join_params)); + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, sizeof(join_params)); -- cgit v1.2.3 From 99ed5200c05be1d8535dae8903cd50a74b47ca37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:23:54 +0200 Subject: mac80211: brcmfmac: fix stopping netdev queue when bus clogs up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...store-stopping-netdev-queue-when-bus-clog.patch | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch diff --git a/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch b/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch new file mode 100644 index 0000000000..555186d626 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch @@ -0,0 +1,53 @@ +From: Arend Van Spriel +Date: Fri, 15 Jul 2016 12:16:12 +0200 +Subject: [PATCH] brcmfmac: restore stopping netdev queue when bus clogs up +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When the host-interface bus has hard time handling transmit packets +it informs higher layer about this and it would stop the netdev +queue when needed. However, since commit 9cd18359d31e ("brcmfmac: +Make FWS queueing configurable.") this was broken. With this patch +the behaviour is restored. + +Cc: stable@vger.kernel.org # v4.5, v4.6, v4.7 +Fixes: 9cd18359d31e ("brcmfmac: Make FWS queueing configurable.") +Tested-by: Per Förlin +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -2260,10 +2260,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw + void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked) + { + struct brcmf_fws_info *fws = drvr->fws; ++ struct brcmf_if *ifp; ++ int i; + +- fws->bus_flow_blocked = flow_blocked; +- if (!flow_blocked) +- brcmf_fws_schedule_deq(fws); +- else +- fws->stats.bus_flow_block++; ++ if (fws->avoid_queueing) { ++ for (i = 0; i < BRCMF_MAX_IFS; i++) { ++ ifp = drvr->iflist[i]; ++ if (!ifp || !ifp->ndev) ++ continue; ++ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, ++ flow_blocked); ++ } ++ } else { ++ fws->bus_flow_blocked = flow_blocked; ++ if (!flow_blocked) ++ brcmf_fws_schedule_deq(fws); ++ else ++ fws->stats.bus_flow_block++; ++ } + } -- cgit v1.2.3 From 3bf4b214e8a2f4f35b541a6180ac7d5cdd6786fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:24:14 +0200 Subject: mac80211: brcmfmac: backport patch simplifying brcmf_alloc_vif MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is quite trivial and will be required for VIF fixes in the future. Signed-off-by: Rafał Miłecki --- ...cmfmac-drop-unused-pm_block-vif-attribute.patch | 103 +++++++++++++++++++++ ...ightly-simplify-building-interface-combin.patch | 10 +- ...x-lockup-when-removing-P2P-interface-afte.patch | 4 +- ...dd-missing-break-when-deleting-P2P_DEVICE.patch | 2 +- ...lete-interface-directly-in-code-that-sent.patch | 2 +- 5 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch diff --git a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch new file mode 100644 index 0000000000..6cf8135346 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch @@ -0,0 +1,103 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 6 Jun 2016 23:03:55 +0200 +Subject: [PATCH] brcmfmac: drop unused pm_block vif attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This attribute was added 3 years ago by +commit 3eacf866559c ("brcmfmac: introduce brcmf_cfg80211_vif structure") +but it remains unused since then. It seems we can safely drop it. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -566,7 +566,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + + brcmf_dbg(INFO, "Adding vif \"%s\"\n", name); + +- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false); ++ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP); + if (IS_ERR(vif)) + return (struct wireless_dev *)vif; + +@@ -4995,8 +4995,7 @@ static struct cfg80211_ops wl_cfg80211_o + }; + + struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, +- enum nl80211_iftype type, +- bool pm_block) ++ enum nl80211_iftype type) + { + struct brcmf_cfg80211_vif *vif_walk; + struct brcmf_cfg80211_vif *vif; +@@ -5011,8 +5010,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v + vif->wdev.wiphy = cfg->wiphy; + vif->wdev.iftype = type; + +- vif->pm_block = pm_block; +- + brcmf_init_prof(&vif->profile); + + if (type == NL80211_IFTYPE_AP) { +@@ -6582,7 +6579,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + init_vif_event(&cfg->vif_event); + INIT_LIST_HEAD(&cfg->vif_list); + +- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false); ++ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION); + if (IS_ERR(vif)) + goto wiphy_out; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -165,7 +165,6 @@ struct vif_saved_ie { + * @wdev: wireless device. + * @profile: profile information. + * @sme_state: SME state using enum brcmf_vif_status bits. +- * @pm_block: power-management blocked. + * @list: linked list. + * @mgmt_rx_reg: registered rx mgmt frame types. + * @mbss: Multiple BSS type, set if not first AP (not relevant for P2P). +@@ -175,7 +174,6 @@ struct brcmf_cfg80211_vif { + struct wireless_dev wdev; + struct brcmf_cfg80211_profile profile; + unsigned long sme_state; +- bool pm_block; + struct vif_saved_ie saved_ie; + struct list_head list; + u16 mgmt_rx_reg; +@@ -386,8 +384,7 @@ s32 brcmf_cfg80211_down(struct net_devic + enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); + + struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, +- enum nl80211_iftype type, +- bool pm_block); ++ enum nl80211_iftype type); + void brcmf_free_vif(struct brcmf_cfg80211_vif *vif); + + s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2064,8 +2064,7 @@ static struct wireless_dev *brcmf_p2p_cr + if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif) + return ERR_PTR(-ENOSPC); + +- p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE, +- false); ++ p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE); + if (IS_ERR(p2p_vif)) { + brcmf_err("could not create discovery vif\n"); + return (struct wireless_dev *)p2p_vif; +@@ -2165,7 +2164,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + return ERR_PTR(-EOPNOTSUPP); + } + +- vif = brcmf_alloc_vif(cfg, type, false); ++ vif = brcmf_alloc_vif(cfg, type); + if (IS_ERR(vif)) + return (struct wireless_dev *)vif; + brcmf_cfg80211_arm_vif_event(cfg, vif); diff --git a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch index 972851633a..be6606d25a 100644 --- a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch +++ b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch @@ -23,7 +23,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6108,29 +6108,15 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6105,29 +6105,15 @@ static int brcmf_setup_ifmodes(struct wi if (!combo) goto err; @@ -56,7 +56,7 @@ Signed-off-by: Kalle Valo c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); if (p2p) { -@@ -6148,6 +6134,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6145,6 +6131,7 @@ static int brcmf_setup_ifmodes(struct wi c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); } @@ -64,7 +64,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = c0_limits; -@@ -6155,7 +6142,9 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6152,7 +6139,9 @@ static int brcmf_setup_ifmodes(struct wi if (p2p) { c++; i = 0; @@ -75,7 +75,7 @@ Signed-off-by: Kalle Valo p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); p2p_limits[i].max = 1; -@@ -6164,6 +6153,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6161,6 +6150,7 @@ static int brcmf_setup_ifmodes(struct wi p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); @@ -83,7 +83,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = p2p_limits; -@@ -6171,14 +6161,19 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6168,14 +6158,19 @@ static int brcmf_setup_ifmodes(struct wi if (mbss) { c++; diff --git a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch index 174d9a41db..0472290f6c 100644 --- a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch +++ b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch @@ -134,7 +134,7 @@ Signed-off-by: Kalle Valo /** --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2280,7 +2280,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2279,7 +2279,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph err = 0; } if (err) @@ -143,7 +143,7 @@ Signed-off-by: Kalle Valo brcmf_cfg80211_arm_vif_event(cfg, NULL); if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) -@@ -2386,7 +2386,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i +@@ -2385,7 +2385,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i if (vif != NULL) { brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); diff --git a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch index 4e01532228..1ed0fc14a2 100644 --- a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch +++ b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch @@ -16,7 +16,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2254,6 +2254,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2253,6 +2253,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph return 0; brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); 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 index f3f6cdb1d6..3268051aad 100644 --- 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 @@ -63,7 +63,7 @@ Signed-off-by: Kalle Valo /** --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2281,8 +2281,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2280,8 +2280,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph else err = 0; } -- cgit v1.2.3 From 1016f38a869a77a384b11aac7f6b947ce67726e1 Mon Sep 17 00:00:00 2001 From: Imre Kaloz Date: Thu, 29 Sep 2016 14:24:56 +0200 Subject: mwlwifi: upgrade to 10.3.0.18-20160804 adds support for the Linksys WRT1900ACSv2 and WRT1200ACv2 Signed-off-by: Imre Kaloz --- package/kernel/mwlwifi/Makefile | 4 +- .../kernel/mwlwifi/patches/100-drop_old_api.patch | 92 ---------------------- package/kernel/mwlwifi/patches/110-api_sync.patch | 19 ----- 3 files changed, 2 insertions(+), 113 deletions(-) delete mode 100644 package/kernel/mwlwifi/patches/100-drop_old_api.patch delete mode 100644 package/kernel/mwlwifi/patches/110-api_sync.patch diff --git a/package/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile index 091928df71..f59943d296 100644 --- a/package/kernel/mwlwifi/Makefile +++ b/package/kernel/mwlwifi/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mwlwifi -PKG_VERSION:=10.3.0.16-20160105 +PKG_VERSION:=10.3.0.18-20160804 PKG_RELEASE=1 PKG_LICENSE:=ISC @@ -17,7 +17,7 @@ PKG_LICENSE_FILES:= PKG_SOURCE_URL:=https://github.com/kaloz/mwlwifi PKG_SOURCE_PROTO:=git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=99d3879cc72f2a25d44fb4bee96fd84eca028b04 +PKG_SOURCE_VERSION:=d48847cc83954930fdcd98818bbf33e75707b8e1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz PKG_MAINTAINER:=Imre Kaloz diff --git a/package/kernel/mwlwifi/patches/100-drop_old_api.patch b/package/kernel/mwlwifi/patches/100-drop_old_api.patch deleted file mode 100644 index d2e149e9a2..0000000000 --- a/package/kernel/mwlwifi/patches/100-drop_old_api.patch +++ /dev/null @@ -1,92 +0,0 @@ ---- a/main.c -+++ b/main.c -@@ -418,11 +418,7 @@ static void mwl_set_ht_caps(struct mwl_p - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; - band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; - --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; --#else - ieee80211_hw_set(hw, AMPDU_AGGREGATION); --#endif - band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; - -@@ -524,29 +520,16 @@ static int mwl_wl_init(struct mwl_priv * - hw->queues = SYSADPT_TX_WMM_QUEUES; - - /* Set rssi values to dBm */ --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -- hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; --#else - ieee80211_hw_set(hw, SIGNAL_DBM); - ieee80211_hw_set(hw, HAS_RATE_CONTROL); --#endif - - /* Ask mac80211 not to trigger PS mode - * based on PM bit of incoming frames. - */ --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -- hw->flags |= IEEE80211_HW_AP_LINK_PS; --#else - ieee80211_hw_set(hw, AP_LINK_PS); --#endif - --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) -- hw->flags |= IEEE80211_HW_SUPPORTS_PER_STA_GTK | -- IEEE80211_HW_MFP_CAPABLE; --#else - ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK); - ieee80211_hw_set(hw, MFP_CAPABLE); --#endif - - hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; - ---- a/dev.h -+++ b/dev.h -@@ -484,10 +484,6 @@ static inline struct mwl_sta *mwl_dev_ge - return (struct mwl_sta *)&sta->drv_priv; - } - --#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) --#define ether_addr_copy(dst, src) memcpy(dst, src, ETH_ALEN) --#endif -- - /* Defined in mac80211.c. */ - extern const struct ieee80211_ops mwl_mac80211_ops; - ---- a/mac80211.c -+++ b/mac80211.c -@@ -572,19 +572,11 @@ static int mwl_mac80211_get_survey(struc - return 0; - } - --#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) --static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- enum ieee80211_ampdu_mlme_action action, -- struct ieee80211_sta *sta, -- u16 tid, u16 *ssn, u8 buf_size) --#else - static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, - u16 tid, u16 *ssn, u8 buf_size, bool amsdu) --#endif - { - int rc = 0; - struct mwl_priv *priv = hw->priv; ---- a/rx.c -+++ b/rx.c -@@ -232,10 +232,8 @@ static inline void mwl_rx_prepare_status - status->flag |= RX_FLAG_VHT; - if (bw == RX_RATE_INFO_HT40) - status->flag |= RX_FLAG_40MHZ; --#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0) - if (bw == RX_RATE_INFO_HT80) - status->vht_flag |= RX_VHT_FLAG_80MHZ; --#endif - if (gi == RX_RATE_INFO_SHORT_INTERVAL) - status->flag |= RX_FLAG_SHORT_GI; - status->vht_nss = (nss + 1); diff --git a/package/kernel/mwlwifi/patches/110-api_sync.patch b/package/kernel/mwlwifi/patches/110-api_sync.patch deleted file mode 100644 index ed3e06a1c1..0000000000 --- a/package/kernel/mwlwifi/patches/110-api_sync.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/mac80211.c -+++ b/mac80211.c -@@ -597,10 +597,13 @@ static int mwl_mac80211_get_survey(struc - - static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, -- enum ieee80211_ampdu_mlme_action action, -- struct ieee80211_sta *sta, -- u16 tid, u16 *ssn, u8 buf_size, bool amsdu) -+ struct ieee80211_ampdu_params *params) - { -+ enum ieee80211_ampdu_mlme_action action = params->action; -+ struct ieee80211_sta *sta = params->sta; -+ u16 tid = params->tid; -+ u16 *ssn = ¶ms->ssn; -+ u8 buf_size = params->buf_size; - int rc = 0; - struct mwl_priv *priv = hw->priv; - struct mwl_ampdu_stream *stream; -- cgit v1.2.3 From 396e838bd6a8e8df8ea2f0fdb8b70be449682b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:25:35 +0200 Subject: mac80211: brcmfmac: backport patches that were skipped previously #1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit They are necessary for further fixes and improvements otherwise recent patches don't apply. Signed-off-by: Rafał Miłecki --- ...-0002-brcmfmac-Limit-memory-allocs-to-64K.patch | 127 ++++ ...eck-for-wowl-support-before-enumerating-f.patch | 29 + ...nfigure-country-code-using-device-specifi.patch | 214 ++++++ ...fmac-Add-length-checks-on-firmware-events.patch | 283 ++++++++ ...d-neighbor-discovery-offload-ip-address-t.patch | 333 ++++++++++ ...mac-check-return-for-ARP-ip-setting-iovar.patch | 38 ++ ...44-0011-brcmfmac-remove-pcie-gen1-support.patch | 221 +++++++ ...12-brcmfmac-increase-timeout-for-tx-eapol.patch | 2 +- ...mfmac-move-module-init-and-exit-to-common.patch | 135 ++++ ...mac-add-wowl-gtk-rekeying-offload-support.patch | 260 ++++++++ ...ve-platform-data-retrieval-code-to-common.patch | 385 +++++++++++ ...ep-ARP-and-ND-offload-enabled-during-WOWL.patch | 69 ++ ...0017-brcmfmac-switch-to-new-platform-data.patch | 734 +++++++++++++++++++++ ...merge-platform-data-and-module-paramaters.patch | 607 +++++++++++++++++ ...-brcmfmac-integrate-add_keyext-in-add_key.patch | 227 +++++++ ...d-802.11w-management-frame-protection-sup.patch | 509 ++++++++++++++ ...ac-rework-function-picking-free-BSS-index.patch | 8 +- ...d-field-storing-control-channel-to-the-st.patch | 20 +- ...mac-support-get_channel-cfg80211-callback.patch | 4 +- ...-print-errors-if-creating-interface-fails.patch | 4 +- ...fix-setting-AP-channel-with-new-firmwares.patch | 12 +- ...n-t-remove-interface-on-link-down-firmwar.patch | 4 +- ...cmfmac-drop-unused-pm_block-vif-attribute.patch | 18 +- ...ightly-simplify-building-interface-combin.patch | 10 +- ...x-lockup-when-removing-P2P-interface-afte.patch | 52 +- ...e-const-char-for-interface-name-in-brcmf_.patch | 4 +- ...dd-missing-break-when-deleting-P2P_DEVICE.patch | 2 +- ...lete-interface-directly-in-code-that-sent.patch | 4 +- ...pport-removing-AP-interfaces-with-interfa.patch | 4 +- ...mac-respect-hidden_ssid-for-AP-interfaces.patch | 4 +- ...mfmac-register-wiphy-s-during-module_init.patch | 4 +- ...rkaround-bug-with-some-inconsistent-BSSes.patch | 2 +- 32 files changed, 4253 insertions(+), 76 deletions(-) create mode 100644 package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch create mode 100644 package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch create mode 100644 package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch create mode 100644 package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch create mode 100644 package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch create mode 100644 package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch create mode 100644 package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch create mode 100644 package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch create mode 100644 package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch create mode 100644 package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch create mode 100644 package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch create mode 100644 package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch create mode 100644 package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch create mode 100644 package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch create mode 100644 package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch diff --git a/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch b/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch new file mode 100644 index 0000000000..9c336f774f --- /dev/null +++ b/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch @@ -0,0 +1,127 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:26:51 +0100 +Subject: [PATCH] brcmfmac: Limit memory allocs to <64K + +Some systems have problems with allocating memory allocation larger +then 64K. Often on unload/load or suspend/resume a failure is +reported: Could not allocate wiphy device. This patch makes the +escan intermediate storage buf dynamically allocated, and smaller +than 64K. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1125,7 +1125,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy + + /* Arm scan timeout timer */ + mod_timer(&cfg->escan_timeout, jiffies + +- WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); ++ BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); + + return 0; + +@@ -3020,7 +3020,7 @@ brcmf_cfg80211_escan_handler(struct brcm + + list = (struct brcmf_scan_results *) + cfg->escan_info.escan_buf; +- if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) { ++ if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) { + brcmf_err("Buffer is too small: ignoring\n"); + goto exit; + } +@@ -3033,8 +3033,8 @@ brcmf_cfg80211_escan_handler(struct brcm + bss_info_le)) + goto exit; + } +- memcpy(&(cfg->escan_info.escan_buf[list->buflen]), +- bss_info_le, bi_length); ++ memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le, ++ bi_length); + list->version = le32_to_cpu(bss_info_le->version); + list->buflen += bi_length; + list->count++; +@@ -5402,14 +5402,14 @@ static void brcmf_deinit_priv_mem(struct + { + kfree(cfg->conf); + cfg->conf = NULL; +- kfree(cfg->escan_ioctl_buf); +- cfg->escan_ioctl_buf = NULL; + kfree(cfg->extra_buf); + cfg->extra_buf = NULL; + kfree(cfg->wowl.nd); + cfg->wowl.nd = NULL; + kfree(cfg->wowl.nd_info); + cfg->wowl.nd_info = NULL; ++ kfree(cfg->escan_info.escan_buf); ++ cfg->escan_info.escan_buf = NULL; + } + + static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) +@@ -5417,9 +5417,6 @@ static s32 brcmf_init_priv_mem(struct br + cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); + if (!cfg->conf) + goto init_priv_mem_out; +- cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); +- if (!cfg->escan_ioctl_buf) +- goto init_priv_mem_out; + cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); + if (!cfg->extra_buf) + goto init_priv_mem_out; +@@ -5431,6 +5428,9 @@ static s32 brcmf_init_priv_mem(struct br + GFP_KERNEL); + if (!cfg->wowl.nd_info) + goto init_priv_mem_out; ++ cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL); ++ if (!cfg->escan_info.escan_buf) ++ goto init_priv_mem_out; + + return 0; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -28,8 +28,11 @@ + #define WL_ROAM_TRIGGER_LEVEL -75 + #define WL_ROAM_DELTA 20 + +-#define WL_ESCAN_BUF_SIZE (1024 * 64) +-#define WL_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */ ++/* Keep BRCMF_ESCAN_BUF_SIZE below 64K (65536). Allocing over 64K can be ++ * problematic on some systems and should be avoided. ++ */ ++#define BRCMF_ESCAN_BUF_SIZE 65000 ++#define BRCMF_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */ + + #define WL_ESCAN_ACTION_START 1 + #define WL_ESCAN_ACTION_CONTINUE 2 +@@ -205,7 +208,7 @@ enum wl_escan_state { + + struct escan_info { + u32 escan_state; +- u8 escan_buf[WL_ESCAN_BUF_SIZE]; ++ u8 *escan_buf; + struct wiphy *wiphy; + struct brcmf_if *ifp; + s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, +@@ -278,7 +281,6 @@ struct brcmf_cfg80211_wowl { + * @escan_info: escan information. + * @escan_timeout: Timer for catch scan timeout. + * @escan_timeout_work: scan timeout worker. +- * @escan_ioctl_buf: dongle command buffer for escan commands. + * @vif_list: linked list of vif instances. + * @vif_cnt: number of vif instances. + * @vif_event: vif event signalling. +@@ -309,7 +311,6 @@ struct brcmf_cfg80211_info { + struct escan_info escan_info; + struct timer_list escan_timeout; + struct work_struct escan_timeout_work; +- u8 *escan_ioctl_buf; + struct list_head vif_list; + struct brcmf_cfg80211_vif_event vif_event; + struct completion vif_disabled; diff --git a/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch b/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch new file mode 100644 index 0000000000..ee3d9f37a8 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch @@ -0,0 +1,29 @@ +From: Franky Lin +Date: Wed, 17 Feb 2016 11:26:52 +0100 +Subject: [PATCH] brcmfmac: check for wowl support before enumerating feature + flag + +In some cases wiphy->wowlan could be NULL if firmware doesn't have the +support. Driver should check for support before walking down the feature +flags. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6594,7 +6594,8 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) { + wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; + #ifdef CONFIG_PM +- if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT) ++ if (wiphy->wowlan && ++ wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT) + wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR; + #endif + } diff --git a/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch b/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch new file mode 100644 index 0000000000..c52cac87b9 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch @@ -0,0 +1,214 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:26:53 +0100 +Subject: [PATCH] brcmfmac: Configure country code using device specific + settings + +Country code configuration in a device is a device specific +operation. For this the country code as specified by reg notifier +(iso3166 alpha2) needs to be translated to a device specific +country locale and revision number. This patch adds this +translation and puts a placeholder in the device specific settings +where the translation table can be stored. Additional patches will +be needed to read these tables from for example device platform +data. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6405,28 +6405,85 @@ int brcmf_cfg80211_wait_vif_event(struct + vif_event_equals(event, action), timeout); + } + ++static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], ++ struct brcmf_fil_country_le *ccreq) ++{ ++ struct cc_translate *country_codes; ++ struct cc_entry *cc; ++ s32 found_index; ++ int i; ++ ++ country_codes = drvr->settings->country_codes; ++ if (!country_codes) { ++ brcmf_dbg(TRACE, "No country codes configured for device\n"); ++ return -EINVAL; ++ } ++ ++ if ((alpha2[0] == ccreq->country_abbrev[0]) && ++ (alpha2[1] == ccreq->country_abbrev[1])) { ++ brcmf_dbg(TRACE, "Country code already set\n"); ++ return -EAGAIN; ++ } ++ ++ found_index = -1; ++ for (i = 0; i < country_codes->table_size; i++) { ++ cc = &country_codes->table[i]; ++ if ((cc->iso3166[0] == '\0') && (found_index == -1)) ++ found_index = i; ++ if ((cc->iso3166[0] == alpha2[0]) && ++ (cc->iso3166[1] == alpha2[1])) { ++ found_index = i; ++ break; ++ } ++ } ++ if (found_index == -1) { ++ brcmf_dbg(TRACE, "No country code match found\n"); ++ return -EINVAL; ++ } ++ memset(ccreq, 0, sizeof(*ccreq)); ++ ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev); ++ memcpy(ccreq->ccode, country_codes->table[found_index].cc, ++ BRCMF_COUNTRY_BUF_SZ); ++ ccreq->country_abbrev[0] = alpha2[0]; ++ ccreq->country_abbrev[1] = alpha2[1]; ++ ccreq->country_abbrev[2] = 0; ++ ++ return 0; ++} ++ + static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, + struct regulatory_request *req) + { + struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + struct brcmf_fil_country_le ccreq; ++ s32 err; + int i; + +- brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator, +- req->alpha2[0], req->alpha2[1]); +- + /* ignore non-ISO3166 country codes */ + for (i = 0; i < sizeof(req->alpha2); i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { +- brcmf_err("not a ISO3166 code\n"); ++ brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n", ++ req->alpha2[0], req->alpha2[1]); + return; + } +- memset(&ccreq, 0, sizeof(ccreq)); +- ccreq.rev = cpu_to_le32(-1); +- memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2)); +- if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) { +- brcmf_err("firmware rejected country setting\n"); ++ ++ brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator, ++ req->alpha2[0], req->alpha2[1]); ++ ++ err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); ++ if (err) { ++ brcmf_err("Country code iovar returned err = %d\n", err); ++ return; ++ } ++ ++ err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq); ++ if (err) ++ return; ++ ++ err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); ++ if (err) { ++ brcmf_err("Firmware rejected country setting\n"); + return; + } + brcmf_setup_wiphybands(wiphy); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -230,10 +230,8 @@ void brcmf_mp_attach(void) + int brcmf_mp_device_attach(struct brcmf_pub *drvr) + { + drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); +- if (!drvr->settings) { +- brcmf_err("Failed to alloca storage space for settings\n"); ++ if (!drvr->settings) + return -ENOMEM; +- } + + drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; + drvr->settings->p2p_enable = !!brcmf_p2p_enable; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -15,6 +15,8 @@ + #ifndef BRCMFMAC_COMMON_H + #define BRCMFMAC_COMMON_H + ++#include "fwil_types.h" ++ + extern const u8 ALLFFMAC[ETH_ALEN]; + + #define BRCMF_FW_ALTPATH_LEN 256 +@@ -39,6 +41,33 @@ struct brcmf_mp_global_t { + extern struct brcmf_mp_global_t brcmf_mp_global; + + /** ++ * struct cc_entry - Struct for translating user space country code (iso3166) to ++ * firmware country code and revision. ++ * ++ * @iso3166: iso3166 alpha 2 country code string. ++ * @cc: firmware country code string. ++ * @rev: firmware country code revision. ++ */ ++struct cc_entry { ++ char iso3166[BRCMF_COUNTRY_BUF_SZ]; ++ char cc[BRCMF_COUNTRY_BUF_SZ]; ++ s32 rev; ++}; ++ ++/** ++ * struct cc_translate - Struct for translating country codes as set by user ++ * space to a country code and rev which can be used by ++ * firmware. ++ * ++ * @table_size: number of entries in table (> 0) ++ * @table: dynamic array of 1 or more elements with translation information. ++ */ ++struct cc_translate { ++ int table_size; ++ struct cc_entry table[0]; ++}; ++ ++/** + * struct brcmf_mp_device - Device module paramaters. + * + * @sdiod_txglomsz: SDIO txglom size. +@@ -47,6 +76,7 @@ extern struct brcmf_mp_global_t brcmf_mp + * @feature_disable: Feature_disable bitmask. + * @fcmode: FWS flow control. + * @roamoff: Firmware roaming off? ++ * @country_codes: If available, pointer to struct for translating country codes + */ + struct brcmf_mp_device { + int sdiod_txglomsz; +@@ -56,6 +86,7 @@ struct brcmf_mp_device { + int fcmode; + bool roamoff; + bool ignore_probe_fail; ++ struct cc_translate *country_codes; + }; + + void brcmf_mp_attach(void); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -134,6 +134,8 @@ + #define BRCMF_PFN_MAC_OUI_ONLY BIT(0) + #define BRCMF_PFN_SET_MAC_UNASSOC BIT(1) + ++#define BRCMF_MCSSET_LEN 16 ++ + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, +@@ -279,7 +281,7 @@ struct brcmf_bss_info_le { + __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ + u8 flags; /* flags */ + u8 reserved[3]; /* Reserved for expansion of BSS properties */ +- u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ ++ u8 basic_mcs[BRCMF_MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + __le16 ie_offset; /* offset at which IEs start, from beginning */ + __le32 ie_length; /* byte length of Information Elements */ diff --git a/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch b/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch new file mode 100644 index 0000000000..3e2e3503b6 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch @@ -0,0 +1,283 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:26:54 +0100 +Subject: [PATCH] brcmfmac: Add length checks on firmware events + +Add additional length checks on firmware events to create more +robust code. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Lei Zhang +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3092,6 +3092,11 @@ brcmf_notify_sched_scan_results(struct b + + brcmf_dbg(SCAN, "Enter\n"); + ++ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { ++ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); ++ return 0; ++ } ++ + if (e->event_code == BRCMF_E_PFN_NET_LOST) { + brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n"); + return 0; +@@ -3415,6 +3420,11 @@ brcmf_wowl_nd_results(struct brcmf_if *i + + brcmf_dbg(SCAN, "Enter\n"); + ++ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { ++ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); ++ return 0; ++ } ++ + pfn_result = (struct brcmf_pno_scanresults_le *)data; + + if (e->event_code == BRCMF_E_PFN_NET_LOST) { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -26,50 +26,6 @@ + #include "fwil.h" + + /** +- * struct brcm_ethhdr - broadcom specific ether header. +- * +- * @subtype: subtype for this packet. +- * @length: TODO: length of appended data. +- * @version: version indication. +- * @oui: OUI of this packet. +- * @usr_subtype: subtype for this OUI. +- */ +-struct brcm_ethhdr { +- __be16 subtype; +- __be16 length; +- u8 version; +- u8 oui[3]; +- __be16 usr_subtype; +-} __packed; +- +-struct brcmf_event_msg_be { +- __be16 version; +- __be16 flags; +- __be32 event_type; +- __be32 status; +- __be32 reason; +- __be32 auth_type; +- __be32 datalen; +- u8 addr[ETH_ALEN]; +- char ifname[IFNAMSIZ]; +- u8 ifidx; +- u8 bsscfgidx; +-} __packed; +- +-/** +- * struct brcmf_event - contents of broadcom event packet. +- * +- * @eth: standard ether header. +- * @hdr: broadcom specific ether header. +- * @msg: common part of the actual event message. +- */ +-struct brcmf_event { +- struct ethhdr eth; +- struct brcm_ethhdr hdr; +- struct brcmf_event_msg_be msg; +-} __packed; +- +-/** + * struct brcmf_fweh_queue_item - event item on event queue. + * + * @q: list element for queuing. +@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item { + u8 ifidx; + u8 ifaddr[ETH_ALEN]; + struct brcmf_event_msg_be emsg; ++ u32 datalen; + u8 data[0]; + }; + +@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(stru + brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, + min_t(u32, emsg.datalen, 64), + "event payload, len=%d\n", emsg.datalen); ++ if (emsg.datalen > event->datalen) { ++ brcmf_err("event invalid length header=%d, msg=%d\n", ++ event->datalen, emsg.datalen); ++ goto event_free; ++ } + + /* special handling of interface event */ + if (event->code == BRCMF_E_IF) { +@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct br + * dispatch the event to a registered handler (using worker). + */ + void brcmf_fweh_process_event(struct brcmf_pub *drvr, +- struct brcmf_event *event_packet) ++ struct brcmf_event *event_packet, ++ u32 packet_len) + { + enum brcmf_fweh_event_code code; + struct brcmf_fweh_info *fweh = &drvr->fweh; +@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brc + if (code != BRCMF_E_IF && !fweh->evt_handler[code]) + return; + ++ if (datalen > BRCMF_DCMD_MAXLEN) ++ return; ++ + if (in_interrupt()) + alloc_flag = GFP_ATOMIC; + +@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brc + /* use memcpy to get aligned event message */ + memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); + memcpy(event->data, data, datalen); ++ event->datalen = datalen; + memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); + + brcmf_fweh_queue_event(fweh, event); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -27,7 +27,6 @@ + struct brcmf_pub; + struct brcmf_if; + struct brcmf_cfg80211_info; +-struct brcmf_event; + + /* list of firmware events */ + #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ +@@ -180,13 +179,55 @@ enum brcmf_fweh_event_code { + /** + * definitions for event packet validation. + */ +-#define BRCMF_EVENT_OUI_OFFSET 19 +-#define BRCM_OUI "\x00\x10\x18" +-#define DOT11_OUI_LEN 3 +-#define BCMILCP_BCM_SUBTYPE_EVENT 1 ++#define BRCM_OUI "\x00\x10\x18" ++#define BCMILCP_BCM_SUBTYPE_EVENT 1 + + + /** ++ * struct brcm_ethhdr - broadcom specific ether header. ++ * ++ * @subtype: subtype for this packet. ++ * @length: TODO: length of appended data. ++ * @version: version indication. ++ * @oui: OUI of this packet. ++ * @usr_subtype: subtype for this OUI. ++ */ ++struct brcm_ethhdr { ++ __be16 subtype; ++ __be16 length; ++ u8 version; ++ u8 oui[3]; ++ __be16 usr_subtype; ++} __packed; ++ ++struct brcmf_event_msg_be { ++ __be16 version; ++ __be16 flags; ++ __be32 event_type; ++ __be32 status; ++ __be32 reason; ++ __be32 auth_type; ++ __be32 datalen; ++ u8 addr[ETH_ALEN]; ++ char ifname[IFNAMSIZ]; ++ u8 ifidx; ++ u8 bsscfgidx; ++} __packed; ++ ++/** ++ * struct brcmf_event - contents of broadcom event packet. ++ * ++ * @eth: standard ether header. ++ * @hdr: broadcom specific ether header. ++ * @msg: common part of the actual event message. ++ */ ++struct brcmf_event { ++ struct ethhdr eth; ++ struct brcm_ethhdr hdr; ++ struct brcmf_event_msg_be msg; ++} __packed; ++ ++/** + * struct brcmf_event_msg - firmware event message. + * + * @version: version information. +@@ -256,34 +297,35 @@ void brcmf_fweh_unregister(struct brcmf_ + enum brcmf_fweh_event_code code); + int brcmf_fweh_activate_events(struct brcmf_if *ifp); + void brcmf_fweh_process_event(struct brcmf_pub *drvr, +- struct brcmf_event *event_packet); ++ struct brcmf_event *event_packet, ++ u32 packet_len); + void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); + + static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, + struct sk_buff *skb) + { + struct brcmf_event *event_packet; +- u8 *data; + u16 usr_stype; + + /* only process events when protocol matches */ + if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) + return; + ++ if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) ++ return; ++ + /* check for BRCM oui match */ + event_packet = (struct brcmf_event *)skb_mac_header(skb); +- data = (u8 *)event_packet; +- data += BRCMF_EVENT_OUI_OFFSET; +- if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) ++ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], ++ sizeof(event_packet->hdr.oui))) + return; + + /* final match on usr_subtype */ +- data += DOT11_OUI_LEN; +- usr_stype = get_unaligned_be16(data); ++ usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype); + if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) + return; + +- brcmf_fweh_process_event(drvr, event_packet); ++ brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN); + } + + #endif /* FWEH_H_ */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1361,6 +1361,11 @@ int brcmf_p2p_notify_action_frame_rx(str + u16 mgmt_type; + u8 action; + ++ if (e->datalen < sizeof(*rxframe)) { ++ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); ++ return 0; ++ } ++ + ch.chspec = be16_to_cpu(rxframe->chanspec); + cfg->d11inf.decchspec(&ch); + /* Check if wpa_supplicant has registered for this frame */ +@@ -1858,6 +1863,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere + brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, + e->reason); + ++ if (e->datalen < sizeof(*rxframe)) { ++ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); ++ return 0; ++ } ++ + ch.chspec = be16_to_cpu(rxframe->chanspec); + cfg->d11inf.decchspec(&ch); + diff --git a/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch b/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch new file mode 100644 index 0000000000..888ad5b050 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch @@ -0,0 +1,333 @@ +From: Franky Lin +Date: Wed, 17 Feb 2016 11:26:55 +0100 +Subject: [PATCH] brcmfmac: add neighbor discovery offload ip address table + configuration + +Configure ipv6 address for neighbor discovery offload ip table in +firmware obtained through ipv6 address notification callback. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -456,7 +456,7 @@ send_key_to_dongle(struct brcmf_if *ifp, + } + + static s32 +-brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) ++brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) + { + s32 err; + u32 mode; +@@ -484,6 +484,15 @@ brcmf_configure_arp_offload(struct brcmf + enable, mode); + } + ++ err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); ++ if (err) { ++ brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", ++ enable, err); ++ err = 0; ++ } else ++ brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", ++ enable, mode); ++ + return err; + } + +@@ -3543,7 +3552,7 @@ static s32 brcmf_cfg80211_resume(struct + brcmf_report_wowl_wakeind(wiphy, ifp); + brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); + brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); +- brcmf_configure_arp_offload(ifp, true); ++ brcmf_configure_arp_nd_offload(ifp, true); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, + cfg->wowl.pre_pmmode); + cfg->wowl.active = false; +@@ -3567,7 +3576,7 @@ static void brcmf_configure_wowl(struct + + brcmf_dbg(TRACE, "Suspend, wowl config.\n"); + +- brcmf_configure_arp_offload(ifp, false); ++ brcmf_configure_arp_nd_offload(ifp, false); + brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); + +@@ -4336,7 +4345,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + if (!mbss) { + brcmf_set_mpc(ifp, 0); +- brcmf_configure_arp_offload(ifp, false); ++ brcmf_configure_arp_nd_offload(ifp, false); + } + + /* find the RSN_IE */ +@@ -4482,7 +4491,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + exit: + if ((err) && (!mbss)) { + brcmf_set_mpc(ifp, 1); +- brcmf_configure_arp_offload(ifp, true); ++ brcmf_configure_arp_nd_offload(ifp, true); + } + return err; + } +@@ -4540,7 +4549,7 @@ static int brcmf_cfg80211_stop_ap(struct + brcmf_err("bss_enable config failed %d\n", err); + } + brcmf_set_mpc(ifp, 1); +- brcmf_configure_arp_offload(ifp, true); ++ brcmf_configure_arp_nd_offload(ifp, true); + clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); + brcmf_net_setcarrier(ifp, false); + +@@ -6287,7 +6296,7 @@ static s32 brcmf_config_dongle(struct br + if (err) + goto default_conf_out; + +- brcmf_configure_arp_offload(ifp, true); ++ brcmf_configure_arp_nd_offload(ifp, true); + + cfg->dongle_up = true; + default_conf_out: +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -20,6 +20,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + +@@ -172,6 +174,35 @@ _brcmf_set_mac_address(struct work_struc + } + } + ++#if IS_ENABLED(CONFIG_IPV6) ++static void _brcmf_update_ndtable(struct work_struct *work) ++{ ++ struct brcmf_if *ifp; ++ int i, ret; ++ ++ ifp = container_of(work, struct brcmf_if, ndoffload_work); ++ ++ /* clear the table in firmware */ ++ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0); ++ if (ret) { ++ brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret); ++ return; ++ } ++ ++ for (i = 0; i < ifp->ipv6addr_idx; i++) { ++ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip", ++ &ifp->ipv6_addr_tbl[i], ++ sizeof(struct in6_addr)); ++ if (ret) ++ brcmf_err("add nd ip err %d\n", ret); ++ } ++} ++#else ++static void _brcmf_update_ndtable(struct work_struct *work) ++{ ++} ++#endif ++ + static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) + { + struct brcmf_if *ifp = netdev_priv(ndev); +@@ -685,6 +716,7 @@ int brcmf_net_attach(struct brcmf_if *if + + INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); + INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); ++ INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable); + + if (rtnl_locked) + err = register_netdevice(ndev); +@@ -884,6 +916,7 @@ static void brcmf_del_if(struct brcmf_pu + if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { + cancel_work_sync(&ifp->setmacaddr_work); + cancel_work_sync(&ifp->multicast_work); ++ cancel_work_sync(&ifp->ndoffload_work); + } + brcmf_net_detach(ifp->ndev); + } else { +@@ -1025,6 +1058,56 @@ static int brcmf_inetaddr_changed(struct + } + #endif + ++#if IS_ENABLED(CONFIG_IPV6) ++static int brcmf_inet6addr_changed(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub, ++ inet6addr_notifier); ++ struct inet6_ifaddr *ifa = data; ++ struct brcmf_if *ifp; ++ int i; ++ struct in6_addr *table; ++ ++ /* Only handle primary interface */ ++ ifp = drvr->iflist[0]; ++ if (!ifp) ++ return NOTIFY_DONE; ++ if (ifp->ndev != ifa->idev->dev) ++ return NOTIFY_DONE; ++ ++ table = ifp->ipv6_addr_tbl; ++ for (i = 0; i < NDOL_MAX_ENTRIES; i++) ++ if (ipv6_addr_equal(&ifa->addr, &table[i])) ++ break; ++ ++ switch (action) { ++ case NETDEV_UP: ++ if (i == NDOL_MAX_ENTRIES) { ++ if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) { ++ table[ifp->ipv6addr_idx++] = ifa->addr; ++ } else { ++ for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++) ++ table[i] = table[i + 1]; ++ table[NDOL_MAX_ENTRIES - 1] = ifa->addr; ++ } ++ } ++ break; ++ case NETDEV_DOWN: ++ if (i < NDOL_MAX_ENTRIES) ++ for (; i < ifp->ipv6addr_idx; i++) ++ table[i] = table[i + 1]; ++ break; ++ default: ++ break; ++ } ++ ++ schedule_work(&ifp->ndoffload_work); ++ ++ return NOTIFY_OK; ++} ++#endif ++ + int brcmf_attach(struct device *dev) + { + struct brcmf_pub *drvr = NULL; +@@ -1164,30 +1247,41 @@ int brcmf_bus_start(struct device *dev) + #ifdef CONFIG_INET + drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; + ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); ++ if (ret) ++ goto fail; ++ ++#if IS_ENABLED(CONFIG_IPV6) ++ drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed; ++ ret = register_inet6addr_notifier(&drvr->inet6addr_notifier); ++ if (ret) { ++ unregister_inetaddr_notifier(&drvr->inetaddr_notifier); ++ goto fail; ++ } + #endif ++#endif /* CONFIG_INET */ ++ ++ return 0; + + fail: +- if (ret < 0) { +- brcmf_err("failed: %d\n", ret); +- if (drvr->config) { +- brcmf_cfg80211_detach(drvr->config); +- drvr->config = NULL; +- } +- if (drvr->fws) { +- brcmf_fws_del_interface(ifp); +- brcmf_fws_deinit(drvr); +- } +- if (ifp) +- brcmf_net_detach(ifp->ndev); +- if (p2p_ifp) +- brcmf_net_detach(p2p_ifp->ndev); +- drvr->iflist[0] = NULL; +- drvr->iflist[1] = NULL; +- if (brcmf_ignoring_probe_fail(drvr)) +- ret = 0; +- return ret; ++ brcmf_err("failed: %d\n", ret); ++ if (drvr->config) { ++ brcmf_cfg80211_detach(drvr->config); ++ drvr->config = NULL; ++ } ++ if (drvr->fws) { ++ brcmf_fws_del_interface(ifp); ++ brcmf_fws_deinit(drvr); + } +- return 0; ++ if (ifp) ++ brcmf_net_detach(ifp->ndev); ++ if (p2p_ifp) ++ brcmf_net_detach(p2p_ifp->ndev); ++ drvr->iflist[0] = NULL; ++ drvr->iflist[1] = NULL; ++ if (brcmf_ignoring_probe_fail(drvr)) ++ ret = 0; ++ ++ return ret; + } + + void brcmf_bus_add_txhdrlen(struct device *dev, uint len) +@@ -1237,6 +1331,10 @@ void brcmf_detach(struct device *dev) + unregister_inetaddr_notifier(&drvr->inetaddr_notifier); + #endif + ++#if IS_ENABLED(CONFIG_IPV6) ++ unregister_inet6addr_notifier(&drvr->inet6addr_notifier); ++#endif ++ + /* stop firmware event handling */ + brcmf_fweh_detach(drvr); + if (drvr->config) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -48,6 +48,8 @@ + */ + #define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 + ++#define NDOL_MAX_ENTRIES 8 ++ + /** + * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info + * +@@ -143,6 +145,7 @@ struct brcmf_pub { + #endif + + struct notifier_block inetaddr_notifier; ++ struct notifier_block inet6addr_notifier; + struct brcmf_mp_device *settings; + }; + +@@ -175,6 +178,7 @@ enum brcmf_netif_stop_reason { + * @stats: interface specific network statistics. + * @setmacaddr_work: worker object for setting mac address. + * @multicast_work: worker object for multicast provisioning. ++ * @ndoffload_work: worker object for neighbor discovery offload configuration. + * @fws_desc: interface specific firmware-signalling descriptor. + * @ifidx: interface index in device firmware. + * @bsscfgidx: index of bss associated with this interface. +@@ -191,6 +195,7 @@ struct brcmf_if { + struct net_device_stats stats; + struct work_struct setmacaddr_work; + struct work_struct multicast_work; ++ struct work_struct ndoffload_work; + struct brcmf_fws_mac_descriptor *fws_desc; + int ifidx; + s32 bsscfgidx; +@@ -199,6 +204,8 @@ struct brcmf_if { + spinlock_t netif_stop_lock; + atomic_t pend_8021x_cnt; + wait_queue_head_t pend_8021x_wait; ++ struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; ++ u8 ipv6addr_idx; + }; + + struct brcmf_skb_reorder_data { diff --git a/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch b/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch new file mode 100644 index 0000000000..68de8ed2a2 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch @@ -0,0 +1,38 @@ +From: Franky Lin +Date: Wed, 17 Feb 2016 11:26:56 +0100 +Subject: [PATCH] brcmfmac: check return for ARP ip setting iovar + +The return value of iovar set function should be saved and checked. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1039,14 +1039,14 @@ static int brcmf_inetaddr_changed(struct + return NOTIFY_OK; + } + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { +- if (addr_table[i] != 0) { +- brcmf_fil_iovar_data_set(ifp, +- "arp_hostip", &addr_table[i], +- sizeof(addr_table[i])); +- if (ret) +- brcmf_err("add arp ip err %d\n", +- ret); +- } ++ if (addr_table[i] == 0) ++ continue; ++ ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip", ++ &addr_table[i], ++ sizeof(addr_table[i])); ++ if (ret) ++ brcmf_err("add arp ip err %d\n", ++ ret); + } + } + break; diff --git a/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch b/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch new file mode 100644 index 0000000000..f99f6dbf07 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch @@ -0,0 +1,221 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:00 +0100 +Subject: [PATCH] brcmfmac: remove pcie gen1 support + +The PCIE bus driver supports older gen1 (v1) chips, but there is no +actual device which is using this older pcie core which is supported +by brcmfmac. Remove all gen1 related code. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -100,9 +100,6 @@ static struct brcmf_firmware_mapping brc + #define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 + #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140 + +-#define BRCMF_PCIE_GENREV1 1 +-#define BRCMF_PCIE_GENREV2 2 +- + #define BRCMF_PCIE2_INTA 0x01 + #define BRCMF_PCIE2_INTB 0x02 + +@@ -257,9 +254,7 @@ struct brcmf_pciedev_info { + u32 ram_size; + struct brcmf_chip *ci; + u32 coreid; +- u32 generic_corerev; + struct brcmf_pcie_shared_info shared; +- void (*ringbell)(struct brcmf_pciedev_info *devinfo); + wait_queue_head_t mbdata_resp_wait; + bool mbdata_completed; + bool irq_allocated; +@@ -746,68 +741,22 @@ static void brcmf_pcie_bus_console_read( + } + + +-static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo) +-{ +- u32 reg_value; +- +- brcmf_dbg(PCIE, "RING !\n"); +- reg_value = brcmf_pcie_read_reg32(devinfo, +- BRCMF_PCIE_PCIE2REG_MAILBOXINT); +- reg_value |= BRCMF_PCIE2_INTB; +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, +- reg_value); +-} +- +- +-static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo) +-{ +- brcmf_dbg(PCIE, "RING !\n"); +- /* Any arbitrary value will do, lets use 1 */ +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); +-} +- +- + static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo) + { +- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) +- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, +- 0); +- else +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, +- 0); ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0); + } + + + static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo) + { +- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) +- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, +- BRCMF_PCIE_INT_DEF); +- else +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, +- BRCMF_PCIE_MB_INT_D2H_DB | +- BRCMF_PCIE_MB_INT_FN0_0 | +- BRCMF_PCIE_MB_INT_FN0_1); ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, ++ BRCMF_PCIE_MB_INT_D2H_DB | ++ BRCMF_PCIE_MB_INT_FN0_0 | ++ BRCMF_PCIE_MB_INT_FN0_1); + } + + +-static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg) +-{ +- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; +- u32 status; +- +- status = 0; +- pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status); +- if (status) { +- brcmf_pcie_intr_disable(devinfo); +- brcmf_dbg(PCIE, "Enter\n"); +- return IRQ_WAKE_THREAD; +- } +- return IRQ_NONE; +-} +- +- +-static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg) ++static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) + { + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + +@@ -820,29 +769,7 @@ static irqreturn_t brcmf_pcie_quick_chec + } + + +-static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg) +-{ +- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; +- const struct pci_dev *pdev = devinfo->pdev; +- u32 status; +- +- devinfo->in_irq = true; +- status = 0; +- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); +- brcmf_dbg(PCIE, "Enter %x\n", status); +- if (status) { +- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); +- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) +- brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev); +- } +- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) +- brcmf_pcie_intr_enable(devinfo); +- devinfo->in_irq = false; +- return IRQ_HANDLED; +-} +- +- +-static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg) ++static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg) + { + struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; + u32 status; +@@ -879,28 +806,14 @@ static int brcmf_pcie_request_irq(struct + brcmf_pcie_intr_disable(devinfo); + + brcmf_dbg(PCIE, "Enter\n"); +- /* is it a v1 or v2 implementation */ ++ + pci_enable_msi(pdev); +- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { +- if (request_threaded_irq(pdev->irq, +- brcmf_pcie_quick_check_isr_v1, +- brcmf_pcie_isr_thread_v1, +- IRQF_SHARED, "brcmf_pcie_intr", +- devinfo)) { +- pci_disable_msi(pdev); +- brcmf_err("Failed to request IRQ %d\n", pdev->irq); +- return -EIO; +- } +- } else { +- if (request_threaded_irq(pdev->irq, +- brcmf_pcie_quick_check_isr_v2, +- brcmf_pcie_isr_thread_v2, +- IRQF_SHARED, "brcmf_pcie_intr", +- devinfo)) { +- pci_disable_msi(pdev); +- brcmf_err("Failed to request IRQ %d\n", pdev->irq); +- return -EIO; +- } ++ if (request_threaded_irq(pdev->irq, brcmf_pcie_quick_check_isr, ++ brcmf_pcie_isr_thread, IRQF_SHARED, ++ "brcmf_pcie_intr", devinfo)) { ++ pci_disable_msi(pdev); ++ brcmf_err("Failed to request IRQ %d\n", pdev->irq); ++ return -EIO; + } + devinfo->irq_allocated = true; + return 0; +@@ -931,16 +844,9 @@ static void brcmf_pcie_release_irq(struc + if (devinfo->in_irq) + brcmf_err("Still in IRQ (processing) !!!\n"); + +- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { +- status = 0; +- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); +- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); +- } else { +- status = brcmf_pcie_read_reg32(devinfo, +- BRCMF_PCIE_PCIE2REG_MAILBOXINT); +- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, +- status); +- } ++ status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); ++ + devinfo->irq_allocated = false; + } + +@@ -989,7 +895,9 @@ static int brcmf_pcie_ring_mb_ring_bell( + if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) + return -EIO; + +- devinfo->ringbell(devinfo); ++ brcmf_dbg(PCIE, "RING !\n"); ++ /* Any arbitrary value will do, lets use 1 */ ++ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); + + return 0; + } +@@ -1503,9 +1411,6 @@ static int brcmf_pcie_download_fw_nvram( + u32 address; + u32 resetintr; + +- devinfo->ringbell = brcmf_pcie_ringbell_v2; +- devinfo->generic_corerev = BRCMF_PCIE_GENREV2; +- + brcmf_dbg(PCIE, "Halt ARM.\n"); + err = brcmf_pcie_enter_download_state(devinfo); + if (err) diff --git a/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch b/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch index c529ff2c0e..4adfc2dc64 100644 --- a/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch +++ b/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch @@ -19,7 +19,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -40,7 +40,7 @@ MODULE_AUTHOR("Broadcom Corporation"); +@@ -42,7 +42,7 @@ MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); MODULE_LICENSE("Dual BSD/GPL"); diff --git a/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch b/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch new file mode 100644 index 0000000000..bd62781188 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch @@ -0,0 +1,135 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:02 +0100 +Subject: [PATCH] brcmfmac: move module init and exit to common + +In preparation of module parameters for all devices the module init +and exit routines are moved to the common file. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -28,6 +28,10 @@ + #include "tracepoint.h" + #include "common.h" + ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); ++MODULE_LICENSE("Dual BSD/GPL"); ++ + const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 +@@ -221,7 +225,7 @@ void __brcmf_dbg(u32 level, const char * + } + #endif + +-void brcmf_mp_attach(void) ++static void brcmf_mp_attach(void) + { + strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, + BRCMF_FW_ALTPATH_LEN); +@@ -249,3 +253,33 @@ void brcmf_mp_device_detach(struct brcmf + kfree(drvr->settings); + } + ++static int __init brcmfmac_module_init(void) ++{ ++ int err; ++ ++ /* Initialize debug system first */ ++ brcmf_debugfs_init(); ++ ++#ifdef CPTCFG_BRCMFMAC_SDIO ++ brcmf_sdio_init(); ++#endif ++ /* Initialize global module paramaters */ ++ brcmf_mp_attach(); ++ ++ /* Continue the initialization by registering the different busses */ ++ err = brcmf_core_init(); ++ if (err) ++ brcmf_debugfs_exit(); ++ ++ return err; ++} ++ ++static void __exit brcmfmac_module_exit(void) ++{ ++ brcmf_core_exit(); ++ brcmf_debugfs_exit(); ++} ++ ++module_init(brcmfmac_module_init); ++module_exit(brcmfmac_module_exit); ++ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -89,7 +89,6 @@ struct brcmf_mp_device { + struct cc_translate *country_codes; + }; + +-void brcmf_mp_attach(void); + int brcmf_mp_device_attach(struct brcmf_pub *drvr); + void brcmf_mp_device_detach(struct brcmf_pub *drvr); + #ifdef DEBUG +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -38,10 +38,6 @@ + #include "pcie.h" + #include "common.h" + +-MODULE_AUTHOR("Broadcom Corporation"); +-MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +-MODULE_LICENSE("Dual BSD/GPL"); +- + #define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) + + /* AMPDU rx reordering definitions */ +@@ -1422,19 +1418,15 @@ static void brcmf_driver_register(struct + } + static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); + +-static int __init brcmfmac_module_init(void) ++int __init brcmf_core_init(void) + { +- brcmf_debugfs_init(); +-#ifdef CPTCFG_BRCMFMAC_SDIO +- brcmf_sdio_init(); +-#endif + if (!schedule_work(&brcmf_driver_work)) + return -EBUSY; + + return 0; + } + +-static void __exit brcmfmac_module_exit(void) ++void __exit brcmf_core_exit(void) + { + cancel_work_sync(&brcmf_driver_work); + +@@ -1447,8 +1439,5 @@ static void __exit brcmfmac_module_exit( + #ifdef CPTCFG_BRCMFMAC_PCIE + brcmf_pcie_exit(); + #endif +- brcmf_debugfs_exit(); + } + +-module_init(brcmfmac_module_init); +-module_exit(brcmfmac_module_exit); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -227,5 +227,7 @@ void brcmf_txflowblock_if(struct brcmf_i + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); + void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); + void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); ++int __init brcmf_core_init(void); ++void __exit brcmf_core_exit(void); + + #endif /* BRCMFMAC_CORE_H */ diff --git a/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch b/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch new file mode 100644 index 0000000000..577ca8ed28 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch @@ -0,0 +1,260 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:03 +0100 +Subject: [PATCH] brcmfmac: add wowl gtk rekeying offload support + +This patch adds support for gtk rekeying offload and for gtk +rekeying failure during wowl mode. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3526,6 +3526,10 @@ static void brcmf_report_wowl_wakeind(st + else + wakeup_data.net_detect = cfg->wowl.nd_info; + } ++ if (wakeind & BRCMF_WOWL_GTK_FAILURE) { ++ brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n"); ++ wakeup_data.gtk_rekey_failure = true; ++ } + } else { + wakeup = NULL; + } +@@ -3607,6 +3611,8 @@ static void brcmf_configure_wowl(struct + brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, + brcmf_wowl_nd_results); + } ++ if (wowl->gtk_rekey_failure) ++ wowl_config |= BRCMF_WOWL_GTK_FAILURE; + if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) + wowl_config |= BRCMF_WOWL_UNASSOC; + +@@ -4874,7 +4880,32 @@ static int brcmf_cfg80211_tdls_oper(stru + return ret; + } + +-static struct cfg80211_ops wl_cfg80211_ops = { ++#ifdef CONFIG_PM ++static int ++brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev, ++ struct cfg80211_gtk_rekey_data *gtk) ++{ ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_gtk_keyinfo_le gtk_le; ++ int ret; ++ ++ brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx); ++ ++ memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck)); ++ memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek)); ++ memcpy(gtk_le.replay_counter, gtk->replay_ctr, ++ sizeof(gtk_le.replay_counter)); ++ ++ ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le, ++ sizeof(gtk_le)); ++ if (ret < 0) ++ brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret); ++ ++ return ret; ++} ++#endif ++ ++static struct cfg80211_ops brcmf_cfg80211_ops = { + .add_virtual_intf = brcmf_cfg80211_add_iface, + .del_virtual_intf = brcmf_cfg80211_del_iface, + .change_virtual_intf = brcmf_cfg80211_change_iface, +@@ -6139,19 +6170,18 @@ static void brcmf_wiphy_wowl_params(stru + { + #ifdef CONFIG_PM + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); +- s32 err; +- u32 wowl_cap; + + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { +- err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); +- if (!err) { +- if (wowl_cap & BRCMF_WOWL_PFN_FOUND) { +- brcmf_wowlan_support.flags |= +- WIPHY_WOWLAN_NET_DETECT; +- init_waitqueue_head(&cfg->wowl.nd_data_wait); +- } ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) { ++ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; ++ init_waitqueue_head(&cfg->wowl.nd_data_wait); + } + } ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) { ++ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; ++ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; ++ } ++ + wiphy->wowlan = &brcmf_wowlan_support; + #endif + } +@@ -6538,6 +6568,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; + struct brcmf_cfg80211_info *cfg; + struct wiphy *wiphy; ++ struct cfg80211_ops *ops; + struct brcmf_cfg80211_vif *vif; + struct brcmf_if *ifp; + s32 err = 0; +@@ -6549,8 +6580,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + return NULL; + } + ++ ops = kzalloc(sizeof(*ops), GFP_KERNEL); ++ if (!ops) ++ return NULL; ++ ++ memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops)); + ifp = netdev_priv(ndev); +- wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); ++#ifdef CONFIG_PM ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) ++ ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; ++#endif ++ wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); + if (!wiphy) { + brcmf_err("Could not allocate wiphy device\n"); + return NULL; +@@ -6560,6 +6600,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + + cfg = wiphy_priv(wiphy); + cfg->wiphy = wiphy; ++ cfg->ops = ops; + cfg->pub = drvr; + init_vif_event(&cfg->vif_event); + INIT_LIST_HEAD(&cfg->vif_list); +@@ -6686,6 +6727,7 @@ priv_out: + ifp->vif = NULL; + wiphy_out: + brcmf_free_wiphy(wiphy); ++ kfree(ops); + return NULL; + } + +@@ -6696,6 +6738,7 @@ void brcmf_cfg80211_detach(struct brcmf_ + + brcmf_btcoex_detach(cfg); + wiphy_unregister(cfg->wiphy); ++ kfree(cfg->ops); + wl_deinit_priv(cfg); + brcmf_free_wiphy(cfg->wiphy); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -256,6 +256,7 @@ struct brcmf_cfg80211_wowl { + * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface + * + * @wiphy: wiphy object for cfg80211 interface. ++ * @ops: pointer to copy of ops as registered with wiphy object. + * @conf: dongle configuration. + * @p2p: peer-to-peer specific information. + * @btcoex: Bluetooth coexistence information. +@@ -288,6 +289,7 @@ struct brcmf_cfg80211_wowl { + */ + struct brcmf_cfg80211_info { + struct wiphy *wiphy; ++ struct cfg80211_ops *ops; + struct brcmf_cfg80211_conf *conf; + struct brcmf_p2p_info p2p; + struct brcmf_btcoex_info *btcoex; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -136,6 +136,7 @@ void brcmf_feat_attach(struct brcmf_pub + { + struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + struct brcmf_pno_macaddr_le pfn_mac; ++ u32 wowl_cap; + s32 err; + + brcmf_feat_firmware_capabilities(ifp); +@@ -143,6 +144,17 @@ void brcmf_feat_attach(struct brcmf_pub + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); + if (drvr->bus_if->wowl_supported) + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) { ++ err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); ++ if (!err) { ++ if (wowl_cap & BRCMF_WOWL_PFN_FOUND) ++ ifp->drvr->feat_flags |= ++ BIT(BRCMF_FEAT_WOWL_ND); ++ if (wowl_cap & BRCMF_WOWL_GTK_FAILURE) ++ ifp->drvr->feat_flags |= ++ BIT(BRCMF_FEAT_WOWL_GTK); ++ } ++ } + /* MBSS does not work for 43362 */ + if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID) + ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -27,6 +27,8 @@ + * RSDB: Real Simultaneous Dual Band + * TDLS: Tunneled Direct Link Setup + * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan. ++ * WOWL_ND: WOWL net detect (PNO) ++ * WOWL_GTK: (WOWL) GTK rekeying offload + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -36,7 +38,9 @@ + BRCMF_FEAT_DEF(P2P) \ + BRCMF_FEAT_DEF(RSDB) \ + BRCMF_FEAT_DEF(TDLS) \ +- BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) ++ BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ ++ BRCMF_FEAT_DEF(WOWL_ND) \ ++ BRCMF_FEAT_DEF(WOWL_GTK) + + /* + * Quirks: +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -111,7 +111,9 @@ + /* Wakeup if received matched secured pattern: */ + #define BRCMF_WOWL_SECURE (1 << 25) + /* Wakeup on finding preferred network */ +-#define BRCMF_WOWL_PFN_FOUND (1 << 26) ++#define BRCMF_WOWL_PFN_FOUND (1 << 27) ++/* Wakeup on receiving pairwise key EAP packets: */ ++#define WIPHY_WOWL_EAP_PK (1 << 28) + /* Link Down indication in WoWL mode: */ + #define BRCMF_WOWL_LINKDOWN (1 << 31) + +@@ -136,6 +138,10 @@ + + #define BRCMF_MCSSET_LEN 16 + ++#define BRCMF_RSN_KCK_LENGTH 16 ++#define BRCMF_RSN_KEK_LENGTH 16 ++#define BRCMF_RSN_REPLAY_LEN 8 ++ + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, +@@ -789,4 +795,17 @@ struct brcmf_pktcnt_le { + __le32 rx_ocast_good_pkt; + }; + ++/** ++ * struct brcmf_gtk_keyinfo_le - GTP rekey data ++ * ++ * @kck: key confirmation key. ++ * @kek: key encryption key. ++ * @replay_counter: replay counter. ++ */ ++struct brcmf_gtk_keyinfo_le { ++ u8 kck[BRCMF_RSN_KCK_LENGTH]; ++ u8 kek[BRCMF_RSN_KEK_LENGTH]; ++ u8 replay_counter[BRCMF_RSN_REPLAY_LEN]; ++}; ++ + #endif /* FWIL_TYPES_H_ */ diff --git a/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch b/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch new file mode 100644 index 0000000000..2685238925 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch @@ -0,0 +1,385 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:04 +0100 +Subject: [PATCH] brcmfmac: move platform data retrieval code to common + +In preparation of module parameters for all devices the module +platform data retrieval is moved from sdio to common. It is still +only used for sdio devices. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -27,8 +27,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -46,7 +44,6 @@ + #include "bus.h" + #include "debug.h" + #include "sdio.h" +-#include "of.h" + #include "core.h" + #include "common.h" + +@@ -106,18 +103,18 @@ static void brcmf_sdiod_dummy_irqhandler + + int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) + { ++ struct brcmfmac_sdio_platform_data *pdata; + int ret = 0; + u8 data; + u32 addr, gpiocontrol; + unsigned long flags; + +- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { ++ pdata = sdiodev->pdata; ++ if ((pdata) && (pdata->oob_irq_supported)) { + brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", +- sdiodev->pdata->oob_irq_nr); +- ret = request_irq(sdiodev->pdata->oob_irq_nr, +- brcmf_sdiod_oob_irqhandler, +- sdiodev->pdata->oob_irq_flags, +- "brcmf_oob_intr", ++ pdata->oob_irq_nr); ++ ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, ++ pdata->oob_irq_flags, "brcmf_oob_intr", + &sdiodev->func[1]->dev); + if (ret != 0) { + brcmf_err("request_irq failed %d\n", ret); +@@ -129,7 +126,7 @@ int brcmf_sdiod_intr_register(struct brc + sdiodev->irq_en = true; + spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); + +- ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr); ++ ret = enable_irq_wake(pdata->oob_irq_nr); + if (ret != 0) { + brcmf_err("enable_irq_wake failed %d\n", ret); + return ret; +@@ -158,7 +155,7 @@ int brcmf_sdiod_intr_register(struct brc + + /* redirect, configure and enable io for interrupt signal */ + data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; +- if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) ++ if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) + data |= SDIO_SEPINT_ACT_HI; + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); + +@@ -176,9 +173,12 @@ int brcmf_sdiod_intr_register(struct brc + + int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) + { ++ struct brcmfmac_sdio_platform_data *pdata; ++ + brcmf_dbg(SDIO, "Entering\n"); + +- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { ++ pdata = sdiodev->pdata; ++ if ((pdata) && (pdata->oob_irq_supported)) { + sdio_claim_host(sdiodev->func[1]); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); +@@ -187,11 +187,10 @@ int brcmf_sdiod_intr_unregister(struct b + if (sdiodev->oob_irq_requested) { + sdiodev->oob_irq_requested = false; + if (sdiodev->irq_wake) { +- disable_irq_wake(sdiodev->pdata->oob_irq_nr); ++ disable_irq_wake(pdata->oob_irq_nr); + sdiodev->irq_wake = false; + } +- free_irq(sdiodev->pdata->oob_irq_nr, +- &sdiodev->func[1]->dev); ++ free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev); + sdiodev->irq_en = false; + } + } else { +@@ -1103,8 +1102,6 @@ static const struct sdio_device_id brcmf + }; + MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); + +-static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; +- + + static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev, + int val) +@@ -1167,10 +1164,7 @@ static int brcmf_ops_sdio_probe(struct s + dev_set_drvdata(&func->dev, bus_if); + dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); + sdiodev->dev = &sdiodev->func[1]->dev; +- sdiodev->pdata = brcmfmac_sdio_pdata; +- +- if (!sdiodev->pdata) +- brcmf_of_probe(sdiodev); ++ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev); + + #ifdef CONFIG_PM_SLEEP + /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ +@@ -1296,7 +1290,7 @@ static const struct dev_pm_ops brcmf_sdi + static struct sdio_driver brcmf_sdmmc_driver = { + .probe = brcmf_ops_sdio_probe, + .remove = brcmf_ops_sdio_remove, +- .name = BRCMFMAC_SDIO_PDATA_NAME, ++ .name = KBUILD_MODNAME, + .id_table = brcmf_sdmmc_ids, + .drv = { + .owner = THIS_MODULE, +@@ -1306,37 +1300,6 @@ static struct sdio_driver brcmf_sdmmc_dr + }, + }; + +-static int __init brcmf_sdio_pd_probe(struct platform_device *pdev) +-{ +- brcmf_dbg(SDIO, "Enter\n"); +- +- brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); +- +- if (brcmfmac_sdio_pdata->power_on) +- brcmfmac_sdio_pdata->power_on(); +- +- return 0; +-} +- +-static int brcmf_sdio_pd_remove(struct platform_device *pdev) +-{ +- brcmf_dbg(SDIO, "Enter\n"); +- +- if (brcmfmac_sdio_pdata->power_off) +- brcmfmac_sdio_pdata->power_off(); +- +- sdio_unregister_driver(&brcmf_sdmmc_driver); +- +- return 0; +-} +- +-static struct platform_driver brcmf_sdio_pd = { +- .remove = brcmf_sdio_pd_remove, +- .driver = { +- .name = BRCMFMAC_SDIO_PDATA_NAME, +- } +-}; +- + void brcmf_sdio_register(void) + { + int ret; +@@ -1350,19 +1313,6 @@ void brcmf_sdio_exit(void) + { + brcmf_dbg(SDIO, "Enter\n"); + +- if (brcmfmac_sdio_pdata) +- platform_driver_unregister(&brcmf_sdio_pd); +- else +- sdio_unregister_driver(&brcmf_sdmmc_driver); ++ sdio_unregister_driver(&brcmf_sdmmc_driver); + } + +-void __init brcmf_sdio_init(void) +-{ +- int ret; +- +- brcmf_dbg(SDIO, "Enter\n"); +- +- ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); +- if (ret == -ENODEV) +- brcmf_dbg(SDIO, "No platform data available.\n"); +-} +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -27,6 +27,7 @@ + #include "fwil_types.h" + #include "tracepoint.h" + #include "common.h" ++#include "of.h" + + MODULE_AUTHOR("Broadcom Corporation"); + MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); +@@ -79,6 +80,7 @@ module_param_named(ignore_probe_fail, br + MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); + #endif + ++static struct brcmfmac_sdio_platform_data *brcmfmac_pdata; + struct brcmf_mp_global_t brcmf_mp_global; + + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) +@@ -231,6 +233,13 @@ static void brcmf_mp_attach(void) + BRCMF_FW_ALTPATH_LEN); + } + ++struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev) ++{ ++ if (!brcmfmac_pdata) ++ brcmf_of_probe(dev, &brcmfmac_pdata); ++ return brcmfmac_pdata; ++} ++ + int brcmf_mp_device_attach(struct brcmf_pub *drvr) + { + drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); +@@ -253,6 +262,35 @@ void brcmf_mp_device_detach(struct brcmf + kfree(drvr->settings); + } + ++static int __init brcmf_common_pd_probe(struct platform_device *pdev) ++{ ++ brcmf_dbg(INFO, "Enter\n"); ++ ++ brcmfmac_pdata = dev_get_platdata(&pdev->dev); ++ ++ if (brcmfmac_pdata->power_on) ++ brcmfmac_pdata->power_on(); ++ ++ return 0; ++} ++ ++static int brcmf_common_pd_remove(struct platform_device *pdev) ++{ ++ brcmf_dbg(INFO, "Enter\n"); ++ ++ if (brcmfmac_pdata->power_off) ++ brcmfmac_pdata->power_off(); ++ ++ return 0; ++} ++ ++static struct platform_driver brcmf_pd = { ++ .remove = brcmf_common_pd_remove, ++ .driver = { ++ .name = BRCMFMAC_SDIO_PDATA_NAME, ++ } ++}; ++ + static int __init brcmfmac_module_init(void) + { + int err; +@@ -260,16 +298,21 @@ static int __init brcmfmac_module_init(v + /* Initialize debug system first */ + brcmf_debugfs_init(); + +-#ifdef CPTCFG_BRCMFMAC_SDIO +- brcmf_sdio_init(); +-#endif ++ /* Get the platform data (if available) for our devices */ ++ err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); ++ if (err == -ENODEV) ++ brcmf_dbg(INFO, "No platform data available.\n"); ++ + /* Initialize global module paramaters */ + brcmf_mp_attach(); + + /* Continue the initialization by registering the different busses */ + err = brcmf_core_init(); +- if (err) ++ if (err) { + brcmf_debugfs_exit(); ++ if (brcmfmac_pdata) ++ platform_driver_unregister(&brcmf_pd); ++ } + + return err; + } +@@ -277,6 +320,8 @@ static int __init brcmfmac_module_init(v + static void __exit brcmfmac_module_exit(void) + { + brcmf_core_exit(); ++ if (brcmfmac_pdata) ++ platform_driver_unregister(&brcmf_pd); + brcmf_debugfs_exit(); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -15,6 +15,8 @@ + #ifndef BRCMFMAC_COMMON_H + #define BRCMFMAC_COMMON_H + ++#include ++#include + #include "fwil_types.h" + + extern const u8 ALLFFMAC[ETH_ALEN]; +@@ -89,6 +91,7 @@ struct brcmf_mp_device { + struct cc_translate *country_codes; + }; + ++struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev); + int brcmf_mp_device_attach(struct brcmf_pub *drvr); + void brcmf_mp_device_detach(struct brcmf_pub *drvr); + #ifdef DEBUG +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -16,17 +16,16 @@ + #include + #include + #include +-#include +-#include +-#include + + #include + #include "debug.h" +-#include "sdio.h" ++#include "core.h" ++#include "common.h" ++#include "of.h" + +-void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) ++void ++brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio) + { +- struct device *dev = sdiodev->dev; + struct device_node *np = dev->of_node; + int irq; + u32 irqf; +@@ -35,12 +34,12 @@ void brcmf_of_probe(struct brcmf_sdio_de + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; + +- sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL); +- if (!sdiodev->pdata) ++ *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL); ++ if (!(*sdio)) + return; + + if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) +- sdiodev->pdata->drive_strength = val; ++ (*sdio)->drive_strength = val; + + /* make sure there are interrupts defined in the node */ + if (!of_find_property(np, "interrupts", NULL)) +@@ -53,7 +52,7 @@ void brcmf_of_probe(struct brcmf_sdio_de + } + irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); + +- sdiodev->pdata->oob_irq_supported = true; +- sdiodev->pdata->oob_irq_nr = irq; +- sdiodev->pdata->oob_irq_flags = irqf; ++ (*sdio)->oob_irq_supported = true; ++ (*sdio)->oob_irq_nr = irq; ++ (*sdio)->oob_irq_flags = irqf; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +@@ -14,9 +14,11 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #ifdef CONFIG_OF +-void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev); ++void ++brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio); + #else +-static void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) ++static void brcmf_of_probe(struct device *dev, ++ struct brcmfmac_sdio_platform_data **sdio) + { + } + #endif /* CONFIG_OF */ diff --git a/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch b/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch new file mode 100644 index 0000000000..4e789cfc5a --- /dev/null +++ b/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch @@ -0,0 +1,69 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:05 +0100 +Subject: [PATCH] brcmfmac: keep ARP and ND offload enabled during WOWL + +Currently ARP and ND (IPv6 Neigbor Discovery) offload get disabled +on entering suspend. However when firmwares support the wowl_cap +iovar then these offload routines can be kept enabled as they +will work during WOWL as well. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3556,7 +3556,8 @@ static s32 brcmf_cfg80211_resume(struct + brcmf_report_wowl_wakeind(wiphy, ifp); + brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); + brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); +- brcmf_configure_arp_nd_offload(ifp, true); ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND)) ++ brcmf_configure_arp_nd_offload(ifp, true); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, + cfg->wowl.pre_pmmode); + cfg->wowl.active = false; +@@ -3580,7 +3581,8 @@ static void brcmf_configure_wowl(struct + + brcmf_dbg(TRACE, "Suspend, wowl config.\n"); + +- brcmf_configure_arp_nd_offload(ifp, false); ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND)) ++ brcmf_configure_arp_nd_offload(ifp, false); + brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -147,6 +147,7 @@ void brcmf_feat_attach(struct brcmf_pub + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) { + err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); + if (!err) { ++ ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_WOWL_ARP_ND); + if (wowl_cap & BRCMF_WOWL_PFN_FOUND) + ifp->drvr->feat_flags |= + BIT(BRCMF_FEAT_WOWL_ND); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -29,6 +29,7 @@ + * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan. + * WOWL_ND: WOWL net detect (PNO) + * WOWL_GTK: (WOWL) GTK rekeying offload ++ * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL. + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -40,7 +41,8 @@ + BRCMF_FEAT_DEF(TDLS) \ + BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ + BRCMF_FEAT_DEF(WOWL_ND) \ +- BRCMF_FEAT_DEF(WOWL_GTK) ++ BRCMF_FEAT_DEF(WOWL_GTK) \ ++ BRCMF_FEAT_DEF(WOWL_ARP_ND) + + /* + * Quirks: diff --git a/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch b/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch new file mode 100644 index 0000000000..37b68552cc --- /dev/null +++ b/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch @@ -0,0 +1,734 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:07 +0100 +Subject: [PATCH] brcmfmac: switch to new platform data + +Platform data is only available for sdio. With this patch a new +platform data structure is being used which allows for platform +data for any device and configurable per device. This patch only +switches to the new structure and adds support for SDIO devices. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -103,7 +103,7 @@ static void brcmf_sdiod_dummy_irqhandler + + int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) + { +- struct brcmfmac_sdio_platform_data *pdata; ++ struct brcmfmac_sdio_pd *pdata; + int ret = 0; + u8 data; + u32 addr, gpiocontrol; +@@ -173,7 +173,7 @@ int brcmf_sdiod_intr_register(struct brc + + int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) + { +- struct brcmfmac_sdio_platform_data *pdata; ++ struct brcmfmac_sdio_pd *pdata; + + brcmf_dbg(SDIO, "Entering\n"); + +@@ -1164,17 +1164,6 @@ static int brcmf_ops_sdio_probe(struct s + dev_set_drvdata(&func->dev, bus_if); + dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); + sdiodev->dev = &sdiodev->func[1]->dev; +- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev); +- +-#ifdef CONFIG_PM_SLEEP +- /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ +- * is true or when platform data OOB irq is true). +- */ +- if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && +- ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || +- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) +- bus_if->wowl_supported = true; +-#endif + + brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6459,8 +6459,8 @@ int brcmf_cfg80211_wait_vif_event(struct + static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], + struct brcmf_fil_country_le *ccreq) + { +- struct cc_translate *country_codes; +- struct cc_entry *cc; ++ struct brcmfmac_pd_cc *country_codes; ++ struct brcmfmac_pd_cc_entry *cc; + s32 found_index; + int i; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -80,7 +80,7 @@ module_param_named(ignore_probe_fail, br + MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); + #endif + +-static struct brcmfmac_sdio_platform_data *brcmfmac_pdata; ++static struct brcmfmac_platform_data *brcmfmac_pdata; + struct brcmf_mp_global_t brcmf_mp_global; + + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) +@@ -229,15 +229,46 @@ void __brcmf_dbg(u32 level, const char * + + static void brcmf_mp_attach(void) + { ++ /* If module param firmware path is set then this will always be used, ++ * if not set then if available use the platform data version. To make ++ * sure it gets initialized at all, always copy the module param version ++ */ + strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, + BRCMF_FW_ALTPATH_LEN); ++ if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) && ++ (brcmf_mp_global.firmware_path[0] == '\0')) { ++ strlcpy(brcmf_mp_global.firmware_path, ++ brcmfmac_pdata->fw_alternative_path, ++ BRCMF_FW_ALTPATH_LEN); ++ } + } + +-struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev) +-{ +- if (!brcmfmac_pdata) +- brcmf_of_probe(dev, &brcmfmac_pdata); +- return brcmfmac_pdata; ++struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev) ++{ ++ struct brcmfmac_sdio_pd *pdata; ++ struct brcmfmac_pd_device *device_pd; ++ int i; ++ ++ if (brcmfmac_pdata) { ++ for (i = 0; i < brcmfmac_pdata->device_count; i++) { ++ device_pd = &brcmfmac_pdata->devices[i]; ++ if ((device_pd->bus_type == bus_type) && ++ (device_pd->id == chip) && ++ ((device_pd->rev == chiprev) || ++ (device_pd->rev == -1))) { ++ brcmf_dbg(INFO, "Platform data for device found\n"); ++ if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) ++ return &device_pd->bus.sdio; ++ break; ++ } ++ } ++ } ++ pdata = NULL; ++ brcmf_of_probe(dev, &pdata); ++ ++ return pdata; + } + + int brcmf_mp_device_attach(struct brcmf_pub *drvr) +@@ -287,7 +318,7 @@ static int brcmf_common_pd_remove(struct + static struct platform_driver brcmf_pd = { + .remove = brcmf_common_pd_remove, + .driver = { +- .name = BRCMFMAC_SDIO_PDATA_NAME, ++ .name = BRCMFMAC_PDATA_NAME, + } + }; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -16,7 +16,7 @@ + #define BRCMFMAC_COMMON_H + + #include +-#include ++#include + #include "fwil_types.h" + + extern const u8 ALLFFMAC[ETH_ALEN]; +@@ -43,33 +43,6 @@ struct brcmf_mp_global_t { + extern struct brcmf_mp_global_t brcmf_mp_global; + + /** +- * struct cc_entry - Struct for translating user space country code (iso3166) to +- * firmware country code and revision. +- * +- * @iso3166: iso3166 alpha 2 country code string. +- * @cc: firmware country code string. +- * @rev: firmware country code revision. +- */ +-struct cc_entry { +- char iso3166[BRCMF_COUNTRY_BUF_SZ]; +- char cc[BRCMF_COUNTRY_BUF_SZ]; +- s32 rev; +-}; +- +-/** +- * struct cc_translate - Struct for translating country codes as set by user +- * space to a country code and rev which can be used by +- * firmware. +- * +- * @table_size: number of entries in table (> 0) +- * @table: dynamic array of 1 or more elements with translation information. +- */ +-struct cc_translate { +- int table_size; +- struct cc_entry table[0]; +-}; +- +-/** + * struct brcmf_mp_device - Device module paramaters. + * + * @sdiod_txglomsz: SDIO txglom size. +@@ -88,10 +61,12 @@ struct brcmf_mp_device { + int fcmode; + bool roamoff; + bool ignore_probe_fail; +- struct cc_translate *country_codes; ++ struct brcmfmac_pd_cc *country_codes; + }; + +-struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev); ++struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev); + int brcmf_mp_device_attach(struct brcmf_pub *drvr); + void brcmf_mp_device_detach(struct brcmf_pub *drvr); + #ifdef DEBUG +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -23,8 +23,7 @@ + #include "common.h" + #include "of.h" + +-void +-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio) ++void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) + { + struct device_node *np = dev->of_node; + int irq; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +@@ -15,10 +15,9 @@ + */ + #ifdef CONFIG_OF + void +-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio); ++brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); + #else +-static void brcmf_of_probe(struct device *dev, +- struct brcmfmac_sdio_platform_data **sdio) ++static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) + { + } + #endif /* CONFIG_OF */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -33,8 +33,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -44,6 +42,8 @@ + #include "sdio.h" + #include "chip.h" + #include "firmware.h" ++#include "core.h" ++#include "common.h" + + #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) + #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) +@@ -3775,26 +3775,28 @@ static const struct brcmf_buscore_ops br + static bool + brcmf_sdio_probe_attach(struct brcmf_sdio *bus) + { ++ struct brcmf_sdio_dev *sdiodev; + u8 clkctl = 0; + int err = 0; + int reg_addr; + u32 reg_val; + u32 drivestrength; + +- sdio_claim_host(bus->sdiodev->func[1]); ++ sdiodev = bus->sdiodev; ++ sdio_claim_host(sdiodev->func[1]); + + pr_debug("F1 signature read @0x18000000=0x%4x\n", +- brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); ++ brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); + + /* + * Force PLL off until brcmf_chip_attach() + * programs PLL control regs + */ + +- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, ++ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, + BRCMF_INIT_CLKCTL1, &err); + if (!err) +- clkctl = brcmf_sdiod_regrb(bus->sdiodev, ++ clkctl = brcmf_sdiod_regrb(sdiodev, + SBSDIO_FUNC1_CHIPCLKCSR, &err); + + if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { +@@ -3803,50 +3805,77 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + goto fail; + } + +- bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); ++ bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops); + if (IS_ERR(bus->ci)) { + brcmf_err("brcmf_chip_attach failed!\n"); + bus->ci = NULL; + goto fail; + } ++ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, ++ BRCMF_BUSTYPE_SDIO, ++ bus->ci->chip, ++ bus->ci->chiprev); ++ /* platform specific configuration: ++ * alignments must be at least 4 bytes for ADMA ++ */ ++ bus->head_align = ALIGNMENT; ++ bus->sgentry_align = ALIGNMENT; ++ if (sdiodev->pdata) { ++ if (sdiodev->pdata->sd_head_align > ALIGNMENT) ++ bus->head_align = sdiodev->pdata->sd_head_align; ++ if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) ++ bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; ++ } ++ /* allocate scatter-gather table. sg support ++ * will be disabled upon allocation failure. ++ */ ++ brcmf_sdiod_sgtable_alloc(sdiodev); ++ ++#ifdef CONFIG_PM_SLEEP ++ /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ ++ * is true or when platform data OOB irq is true). ++ */ ++ if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && ++ ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || ++ (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) ++ sdiodev->bus_if->wowl_supported = true; ++#endif + + if (brcmf_sdio_kso_init(bus)) { + brcmf_err("error enabling KSO\n"); + goto fail; + } + +- if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) +- drivestrength = bus->sdiodev->pdata->drive_strength; ++ if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) ++ drivestrength = sdiodev->pdata->drive_strength; + else + drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; +- brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); ++ brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); + + /* Set card control so an SDIO card reset does a WLAN backplane reset */ +- reg_val = brcmf_sdiod_regrb(bus->sdiodev, +- SDIO_CCCR_BRCM_CARDCTRL, &err); ++ reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); + if (err) + goto fail; + + reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; + +- brcmf_sdiod_regwb(bus->sdiodev, +- SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); ++ brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); + if (err) + goto fail; + + /* set PMUControl so a backplane reset does PMU state reload */ + reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); +- reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); ++ reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); + if (err) + goto fail; + + reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); + +- brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err); ++ brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); + if (err) + goto fail; + +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(sdiodev->func[1]); + + brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); + +@@ -3867,7 +3896,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + return true; + + fail: +- sdio_release_host(bus->sdiodev->func[1]); ++ sdio_release_host(sdiodev->func[1]); + return false; + } + +@@ -4045,18 +4074,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->txminmax = BRCMF_TXMINMAX; + bus->tx_seq = SDPCM_SEQ_WRAP - 1; + +- /* platform specific configuration: +- * alignments must be at least 4 bytes for ADMA +- */ +- bus->head_align = ALIGNMENT; +- bus->sgentry_align = ALIGNMENT; +- if (sdiodev->pdata) { +- if (sdiodev->pdata->sd_head_align > ALIGNMENT) +- bus->head_align = sdiodev->pdata->sd_head_align; +- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) +- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; +- } +- + /* single-threaded workqueue */ + wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM, + dev_name(&sdiodev->func[1]->dev)); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -184,7 +184,7 @@ struct brcmf_sdio_dev { + struct brcmf_sdio *bus; + struct device *dev; + struct brcmf_bus *bus_if; +- struct brcmfmac_sdio_platform_data *pdata; ++ struct brcmfmac_sdio_pd *pdata; + bool oob_irq_requested; + bool irq_en; /* irq enable flags */ + spinlock_t irq_en_lock; +--- a/include/linux/platform_data/brcmfmac-sdio.h ++++ /dev/null +@@ -1,135 +0,0 @@ +-/* +- * Copyright (c) 2013 Broadcom Corporation +- * +- * Permission to use, copy, modify, and/or distribute this software for any +- * purpose with or without fee is hereby granted, provided that the above +- * copyright notice and this permission notice appear in all copies. +- * +- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +- */ +- +-#ifndef _LINUX_BRCMFMAC_PLATFORM_H +-#define _LINUX_BRCMFMAC_PLATFORM_H +- +-/* +- * Platform specific driver functions and data. Through the platform specific +- * device data functions can be provided to help the brcmfmac driver to +- * operate with the device in combination with the used platform. +- * +- * Use the platform data in the following (similar) way: +- * +- * +-#include +- +- +-static void brcmfmac_power_on(void) +-{ +-} +- +-static void brcmfmac_power_off(void) +-{ +-} +- +-static void brcmfmac_reset(void) +-{ +-} +- +-static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = { +- .power_on = brcmfmac_power_on, +- .power_off = brcmfmac_power_off, +- .reset = brcmfmac_reset +-}; +- +-static struct platform_device brcmfmac_device = { +- .name = BRCMFMAC_SDIO_PDATA_NAME, +- .id = PLATFORM_DEVID_NONE, +- .dev.platform_data = &brcmfmac_sdio_pdata +-}; +- +-void __init brcmfmac_init_pdata(void) +-{ +- brcmfmac_sdio_pdata.oob_irq_supported = true; +- brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB); +- brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ | +- IORESOURCE_IRQ_HIGHLEVEL; +- platform_device_register(&brcmfmac_device); +-} +- * +- * +- * Note: the brcmfmac can be loaded as module or be statically built-in into +- * the kernel. If built-in then do note that it uses module_init (and +- * module_exit) routines which equal device_initcall. So if you intend to +- * create a module with the platform specific data for the brcmfmac and have +- * it built-in to the kernel then use a higher initcall then device_initcall +- * (see init.h). If this is not done then brcmfmac will load without problems +- * but will not pickup the platform data. +- * +- * When the driver does not "detect" platform driver data then it will continue +- * without reporting anything and just assume there is no data needed. Which is +- * probably true for most platforms. +- * +- * Explanation of the platform_data fields: +- * +- * drive_strength: is the preferred drive_strength to be used for the SDIO +- * pins. If 0 then a default value will be used. This is the target drive +- * strength, the exact drive strength which will be used depends on the +- * capabilities of the device. +- * +- * oob_irq_supported: does the board have support for OOB interrupts. SDIO +- * in-band interrupts are relatively slow and for having less overhead on +- * interrupt processing an out of band interrupt can be used. If the HW +- * supports this then enable this by setting this field to true and configure +- * the oob related fields. +- * +- * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are +- * used for registering the irq using request_irq function. +- * +- * broken_sg_support: flag for broken sg list support of SDIO host controller. +- * Set this to true if the SDIO host controller has higher align requirement +- * than 32 bytes for each scatterlist item. +- * +- * sd_head_align: alignment requirement for start of data buffer +- * +- * sd_sgentry_align: length alignment requirement for each sg entry +- * +- * power_on: This function is called by the brcmfmac when the module gets +- * loaded. This can be particularly useful for low power devices. The platform +- * spcific routine may for example decide to power up the complete device. +- * If there is no use-case for this function then provide NULL. +- * +- * power_off: This function is called by the brcmfmac when the module gets +- * unloaded. At this point the device can be powered down or otherwise be reset. +- * So if an actual power_off is not supported but reset is then reset the device +- * when this function gets called. This can be particularly useful for low power +- * devices. If there is no use-case for this function (either power-down or +- * reset) then provide NULL. +- * +- * reset: This function can get called if the device communication broke down. +- * This functionality is particularly useful in case of SDIO type devices. It is +- * possible to reset a dongle via sdio data interface, but it requires that +- * this is fully functional. This function is chip/module specific and this +- * function should return only after the complete reset has completed. +- */ +- +-#define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio" +- +-struct brcmfmac_sdio_platform_data { +- unsigned int drive_strength; +- bool oob_irq_supported; +- unsigned int oob_irq_nr; +- unsigned long oob_irq_flags; +- bool broken_sg_support; +- unsigned short sd_head_align; +- unsigned short sd_sgentry_align; +- void (*power_on)(void); +- void (*power_off)(void); +- void (*reset)(void); +-}; +- +-#endif /* _LINUX_BRCMFMAC_PLATFORM_H */ +--- /dev/null ++++ b/include/linux/platform_data/brcmfmac.h +@@ -0,0 +1,185 @@ ++/* ++ * Copyright (c) 201 Broadcom Corporation ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef _LINUX_BRCMFMAC_PLATFORM_H ++#define _LINUX_BRCMFMAC_PLATFORM_H ++ ++ ++#define BRCMFMAC_PDATA_NAME "brcmfmac" ++ ++#define BRCMFMAC_COUNTRY_BUF_SZ 4 ++ ++ ++/* ++ * Platform specific driver functions and data. Through the platform specific ++ * device data functions and data can be provided to help the brcmfmac driver to ++ * operate with the device in combination with the used platform. ++ */ ++ ++ ++/** ++ * Note: the brcmfmac can be loaded as module or be statically built-in into ++ * the kernel. If built-in then do note that it uses module_init (and ++ * module_exit) routines which equal device_initcall. So if you intend to ++ * create a module with the platform specific data for the brcmfmac and have ++ * it built-in to the kernel then use a higher initcall then device_initcall ++ * (see init.h). If this is not done then brcmfmac will load without problems ++ * but will not pickup the platform data. ++ * ++ * When the driver does not "detect" platform driver data then it will continue ++ * without reporting anything and just assume there is no data needed. Which is ++ * probably true for most platforms. ++ */ ++ ++/** ++ * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are ++ * supported. ++ */ ++enum brcmf_bus_type { ++ BRCMF_BUSTYPE_SDIO, ++ BRCMF_BUSTYPE_USB, ++ BRCMF_BUSTYPE_PCIE ++}; ++ ++ ++/** ++ * struct brcmfmac_sdio_pd - SDIO Device specific platform data. ++ * ++ * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be ++ * used. ++ * @drive_strength: is the preferred drive_strength to be used for the SDIO ++ * pins. If 0 then a default value will be used. This is ++ * the target drive strength, the exact drive strength ++ * which will be used depends on the capabilities of the ++ * device. ++ * @oob_irq_supported: does the board have support for OOB interrupts. SDIO ++ * in-band interrupts are relatively slow and for having ++ * less overhead on interrupt processing an out of band ++ * interrupt can be used. If the HW supports this then ++ * enable this by setting this field to true and configure ++ * the oob related fields. ++ * @oob_irq_nr, ++ * @oob_irq_flags: the OOB interrupt information. The values are used for ++ * registering the irq using request_irq function. ++ * @broken_sg_support: flag for broken sg list support of SDIO host controller. ++ * Set this to true if the SDIO host controller has higher ++ * align requirement than 32 bytes for each scatterlist ++ * item. ++ * @sd_head_align: alignment requirement for start of data buffer. ++ * @sd_sgentry_align: length alignment requirement for each sg entry. ++ * @reset: This function can get called if the device communication ++ * broke down. This functionality is particularly useful in ++ * case of SDIO type devices. It is possible to reset a ++ * dongle via sdio data interface, but it requires that ++ * this is fully functional. This function is chip/module ++ * specific and this function should return only after the ++ * complete reset has completed. ++ */ ++struct brcmfmac_sdio_pd { ++ int txglomsz; ++ unsigned int drive_strength; ++ bool oob_irq_supported; ++ unsigned int oob_irq_nr; ++ unsigned long oob_irq_flags; ++ bool broken_sg_support; ++ unsigned short sd_head_align; ++ unsigned short sd_sgentry_align; ++ void (*reset)(void); ++}; ++ ++/** ++ * struct brcmfmac_pd_cc_entry - Struct for translating user space country code ++ * (iso3166) to firmware country code and ++ * revision. ++ * ++ * @iso3166: iso3166 alpha 2 country code string. ++ * @cc: firmware country code string. ++ * @rev: firmware country code revision. ++ */ ++struct brcmfmac_pd_cc_entry { ++ char iso3166[BRCMFMAC_COUNTRY_BUF_SZ]; ++ char cc[BRCMFMAC_COUNTRY_BUF_SZ]; ++ s32 rev; ++}; ++ ++/** ++ * struct brcmfmac_pd_cc - Struct for translating country codes as set by user ++ * space to a country code and rev which can be used by ++ * firmware. ++ * ++ * @table_size: number of entries in table (> 0) ++ * @table: array of 1 or more elements with translation information. ++ */ ++struct brcmfmac_pd_cc { ++ int table_size; ++ struct brcmfmac_pd_cc_entry table[0]; ++}; ++ ++/** ++ * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type) ++ * is the unique identifier of the device. ++ * ++ * @id: ID of the device for which this data is. In case of SDIO ++ * or PCIE this is the chipid as identified by chip.c In ++ * case of USB this is the chipid as identified by the ++ * device query. ++ * @rev: chip revision, see id. ++ * @bus_type: The type of bus. Some chipid/rev exist for different bus ++ * types. Each bus type has its own set of settings. ++ * @feature_disable: Bitmask of features to disable (override), See feature.c ++ * in brcmfmac for details. ++ * @country_codes: If available, pointer to struct for translating country ++ * codes. ++ * @bus: Bus specific (union) device settings. Currently only ++ * SDIO. ++ */ ++struct brcmfmac_pd_device { ++ unsigned int id; ++ unsigned int rev; ++ enum brcmf_bus_type bus_type; ++ unsigned int feature_disable; ++ struct brcmfmac_pd_cc *country_codes; ++ union { ++ struct brcmfmac_sdio_pd sdio; ++ } bus; ++}; ++ ++/** ++ * struct brcmfmac_platform_data - BRCMFMAC specific platform data. ++ * ++ * @power_on: This function is called by the brcmfmac driver when the module ++ * gets loaded. This can be particularly useful for low power ++ * devices. The platform spcific routine may for example decide to ++ * power up the complete device. If there is no use-case for this ++ * function then provide NULL. ++ * @power_off: This function is called by the brcmfmac when the module gets ++ * unloaded. At this point the devices can be powered down or ++ * otherwise be reset. So if an actual power_off is not supported ++ * but reset is supported by the devices then reset the devices ++ * when this function gets called. This can be particularly useful ++ * for low power devices. If there is no use-case for this ++ * function then provide NULL. ++ */ ++struct brcmfmac_platform_data { ++ void (*power_on)(void); ++ void (*power_off)(void); ++ char *fw_alternative_path; ++ int device_count; ++ struct brcmfmac_pd_device devices[0]; ++}; ++ ++ ++#endif /* _LINUX_BRCMFMAC_PLATFORM_H */ diff --git a/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch b/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch new file mode 100644 index 0000000000..34341d7f18 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch @@ -0,0 +1,607 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:08 +0100 +Subject: [PATCH] brcmfmac: merge platform data and module paramaters + +Merge module parameters and platform data in one struct. This is the +last step to move to the new platform data per device. Now parameters +of platform data will be merged with module parameters per device. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -109,8 +109,8 @@ int brcmf_sdiod_intr_register(struct brc + u32 addr, gpiocontrol; + unsigned long flags; + +- pdata = sdiodev->pdata; +- if ((pdata) && (pdata->oob_irq_supported)) { ++ pdata = &sdiodev->settings->bus.sdio; ++ if (pdata->oob_irq_supported) { + brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", + pdata->oob_irq_nr); + ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, +@@ -177,8 +177,8 @@ int brcmf_sdiod_intr_unregister(struct b + + brcmf_dbg(SDIO, "Entering\n"); + +- pdata = sdiodev->pdata; +- if ((pdata) && (pdata->oob_irq_supported)) { ++ pdata = &sdiodev->settings->bus.sdio; ++ if (pdata->oob_irq_supported) { + sdio_claim_host(sdiodev->func[1]); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); + brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); +@@ -522,7 +522,7 @@ static int brcmf_sdiod_sglist_rw(struct + target_list = pktlist; + /* for host with broken sg support, prepare a page aligned list */ + __skb_queue_head_init(&local_list); +- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { ++ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { + req_sz = 0; + skb_queue_walk(pktlist, pkt_next) + req_sz += pkt_next->len; +@@ -629,7 +629,7 @@ static int brcmf_sdiod_sglist_rw(struct + } + } + +- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { ++ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { + local_pkt_next = local_list.next; + orig_offset = 0; + skb_queue_walk(pktlist, pkt_next) { +@@ -900,7 +900,7 @@ void brcmf_sdiod_sgtable_alloc(struct br + return; + + nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, +- sdiodev->bus_if->drvr->settings->sdiod_txglomsz); ++ sdiodev->settings->bus.sdio.txglomsz); + nents += (nents >> 4) + 1; + + WARN_ON(nents > sdiodev->max_segment_count); +@@ -912,7 +912,7 @@ void brcmf_sdiod_sgtable_alloc(struct br + sdiodev->sg_support = false; + } + +- sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz; ++ sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz; + } + + #ifdef CONFIG_PM_SLEEP +@@ -1246,8 +1246,8 @@ static int brcmf_ops_sdio_suspend(struct + + sdio_flags = MMC_PM_KEEP_POWER; + if (sdiodev->wowl_enabled) { +- if (sdiodev->pdata->oob_irq_supported) +- enable_irq_wake(sdiodev->pdata->oob_irq_nr); ++ if (sdiodev->settings->bus.sdio.oob_irq_supported) ++ enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); + else + sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -43,6 +43,8 @@ enum brcmf_bus_protocol_type { + BRCMF_PROTO_MSGBUF + }; + ++struct brcmf_mp_device; ++ + struct brcmf_bus_dcmd { + char *name; + char *param; +@@ -217,7 +219,7 @@ bool brcmf_c_prec_enq(struct device *dev + void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); + + /* Indication from bus module regarding presence/insertion of dongle. */ +-int brcmf_attach(struct device *dev); ++int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); + /* Indication from bus module regarding removal/absence of dongle */ + void brcmf_detach(struct device *dev); + /* Indication from bus module that dongle should be reset */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -243,14 +243,35 @@ static void brcmf_mp_attach(void) + } + } + +-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, +- enum brcmf_bus_type bus_type, +- u32 chip, u32 chiprev) ++struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev) + { +- struct brcmfmac_sdio_pd *pdata; ++ struct brcmf_mp_device *settings; + struct brcmfmac_pd_device *device_pd; ++ bool found; + int i; + ++ brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip, ++ chiprev); ++ settings = kzalloc(sizeof(*settings), GFP_ATOMIC); ++ if (!settings) ++ return NULL; ++ ++ /* start by using the module paramaters */ ++ settings->p2p_enable = !!brcmf_p2p_enable; ++ settings->feature_disable = brcmf_feature_disable; ++ settings->fcmode = brcmf_fcmode; ++ settings->roamoff = !!brcmf_roamoff; ++#ifdef DEBUG ++ settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; ++#endif ++ ++ if (bus_type == BRCMF_BUSTYPE_SDIO) ++ settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; ++ ++ /* See if there is any device specific platform data configured */ ++ found = false; + if (brcmfmac_pdata) { + for (i = 0; i < brcmfmac_pdata->device_count; i++) { + device_pd = &brcmfmac_pdata->devices[i]; +@@ -259,38 +280,29 @@ struct brcmfmac_sdio_pd *brcmf_get_modul + ((device_pd->rev == chiprev) || + (device_pd->rev == -1))) { + brcmf_dbg(INFO, "Platform data for device found\n"); ++ settings->country_codes = ++ device_pd->country_codes; + if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) +- return &device_pd->bus.sdio; ++ memcpy(&settings->bus.sdio, ++ &device_pd->bus.sdio, ++ sizeof(settings->bus.sdio)); ++ found = true; + break; + } + } + } +- pdata = NULL; +- brcmf_of_probe(dev, &pdata); +- +- return pdata; +-} +- +-int brcmf_mp_device_attach(struct brcmf_pub *drvr) +-{ +- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); +- if (!drvr->settings) +- return -ENOMEM; +- +- drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; +- drvr->settings->p2p_enable = !!brcmf_p2p_enable; +- drvr->settings->feature_disable = brcmf_feature_disable; +- drvr->settings->fcmode = brcmf_fcmode; +- drvr->settings->roamoff = !!brcmf_roamoff; +-#ifdef DEBUG +- drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; +-#endif +- return 0; ++ if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) { ++ /* No platform data for this device. In case of SDIO try OF ++ * (Open Firwmare) Device Tree. ++ */ ++ brcmf_of_probe(dev, &settings->bus.sdio); ++ } ++ return settings; + } + +-void brcmf_mp_device_detach(struct brcmf_pub *drvr) ++void brcmf_release_module_param(struct brcmf_mp_device *module_param) + { +- kfree(drvr->settings); ++ kfree(module_param); + } + + static int __init brcmf_common_pd_probe(struct platform_device *pdev) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +@@ -45,41 +45,30 @@ extern struct brcmf_mp_global_t brcmf_mp + /** + * struct brcmf_mp_device - Device module paramaters. + * +- * @sdiod_txglomsz: SDIO txglom size. +- * @joinboost_5g_rssi: 5g rssi booost for preferred join selection. + * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). + * @feature_disable: Feature_disable bitmask. + * @fcmode: FWS flow control. + * @roamoff: Firmware roaming off? ++ * @ignore_probe_fail: Ignore probe failure. + * @country_codes: If available, pointer to struct for translating country codes ++ * @bus: Bus specific platform data. Only SDIO at the mmoment. + */ + struct brcmf_mp_device { +- int sdiod_txglomsz; +- int joinboost_5g_rssi; +- bool p2p_enable; +- int feature_disable; +- int fcmode; +- bool roamoff; +- bool ignore_probe_fail; ++ bool p2p_enable; ++ unsigned int feature_disable; ++ int fcmode; ++ bool roamoff; ++ bool ignore_probe_fail; + struct brcmfmac_pd_cc *country_codes; ++ union { ++ struct brcmfmac_sdio_pd sdio; ++ } bus; + }; + +-struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, +- enum brcmf_bus_type bus_type, +- u32 chip, u32 chiprev); +-int brcmf_mp_device_attach(struct brcmf_pub *drvr); +-void brcmf_mp_device_detach(struct brcmf_pub *drvr); +-#ifdef DEBUG +-static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) +-{ +- return drvr->settings->ignore_probe_fail; +-} +-#else +-static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) +-{ +- return false; +-} +-#endif ++struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, ++ enum brcmf_bus_type bus_type, ++ u32 chip, u32 chiprev); ++void brcmf_release_module_param(struct brcmf_mp_device *module_param); + + /* Sets dongle media info (drv_version, mac address). */ + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1104,7 +1104,7 @@ static int brcmf_inet6addr_changed(struc + } + #endif + +-int brcmf_attach(struct device *dev) ++int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) + { + struct brcmf_pub *drvr = NULL; + int ret = 0; +@@ -1126,10 +1126,7 @@ int brcmf_attach(struct device *dev) + drvr->hdrlen = 0; + drvr->bus_if = dev_get_drvdata(dev); + drvr->bus_if->drvr = drvr; +- +- /* Initialize device specific settings */ +- if (brcmf_mp_device_attach(drvr)) +- goto fail; ++ drvr->settings = settings; + + /* attach debug facilities */ + brcmf_debug_attach(drvr); +@@ -1274,7 +1271,7 @@ fail: + brcmf_net_detach(p2p_ifp->ndev); + drvr->iflist[0] = NULL; + drvr->iflist[1] = NULL; +- if (brcmf_ignoring_probe_fail(drvr)) ++ if (drvr->settings->ignore_probe_fail) + ret = 0; + + return ret; +@@ -1350,8 +1347,6 @@ void brcmf_detach(struct device *dev) + + brcmf_proto_detach(drvr); + +- brcmf_mp_device_detach(drvr); +- + brcmf_debug_detach(drvr); + bus_if->drvr = NULL; + kfree(drvr); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +@@ -23,7 +23,7 @@ + #include "common.h" + #include "of.h" + +-void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) ++void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) + { + struct device_node *np = dev->of_node; + int irq; +@@ -33,12 +33,8 @@ void brcmf_of_probe(struct device *dev, + if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + return; + +- *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL); +- if (!(*sdio)) +- return; +- + if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) +- (*sdio)->drive_strength = val; ++ sdio->drive_strength = val; + + /* make sure there are interrupts defined in the node */ + if (!of_find_property(np, "interrupts", NULL)) +@@ -51,7 +47,7 @@ void brcmf_of_probe(struct device *dev, + } + irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); + +- (*sdio)->oob_irq_supported = true; +- (*sdio)->oob_irq_nr = irq; +- (*sdio)->oob_irq_flags = irqf; ++ sdio->oob_irq_supported = true; ++ sdio->oob_irq_nr = irq; ++ sdio->oob_irq_flags = irqf; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +@@ -14,10 +14,9 @@ + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #ifdef CONFIG_OF +-void +-brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); ++void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio); + #else +-static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) ++static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) + { + } + #endif /* CONFIG_OF */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -37,6 +37,8 @@ + #include "pcie.h" + #include "firmware.h" + #include "chip.h" ++#include "core.h" ++#include "common.h" + + + enum brcmf_pcie_state { +@@ -266,6 +268,7 @@ struct brcmf_pciedev_info { + u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset); + void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset, + u16 value); ++ struct brcmf_mp_device *settings; + }; + + struct brcmf_pcie_ringbuf { +@@ -1525,16 +1528,16 @@ static void brcmf_pcie_release_resource( + } + + +-static int brcmf_pcie_attach_bus(struct device *dev) ++static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) + { + int ret; + + /* Attach to the common driver interface */ +- ret = brcmf_attach(dev); ++ ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings); + if (ret) { + brcmf_err("brcmf_attach failed\n"); + } else { +- ret = brcmf_bus_start(dev); ++ ret = brcmf_bus_start(&devinfo->pdev->dev); + if (ret) + brcmf_err("dongle is not responding\n"); + } +@@ -1672,7 +1675,7 @@ static void brcmf_pcie_setup(struct devi + init_waitqueue_head(&devinfo->mbdata_resp_wait); + + brcmf_pcie_intr_enable(devinfo); +- if (brcmf_pcie_attach_bus(bus->dev) == 0) ++ if (brcmf_pcie_attach_bus(devinfo) == 0) + return; + + brcmf_pcie_bus_console_read(devinfo); +@@ -1716,6 +1719,15 @@ brcmf_pcie_probe(struct pci_dev *pdev, c + goto fail; + } + ++ devinfo->settings = brcmf_get_module_param(&devinfo->pdev->dev, ++ BRCMF_BUSTYPE_PCIE, ++ devinfo->ci->chip, ++ devinfo->ci->chiprev); ++ if (!devinfo->settings) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ + bus = kzalloc(sizeof(*bus), GFP_KERNEL); + if (!bus) { + ret = -ENOMEM; +@@ -1760,6 +1772,8 @@ fail: + brcmf_pcie_release_resource(devinfo); + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + kfree(pcie_bus_dev); + kfree(devinfo); + return ret; +@@ -1799,6 +1813,8 @@ brcmf_pcie_remove(struct pci_dev *pdev) + + if (devinfo->ci) + brcmf_chip_detach(devinfo->ci); ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + + kfree(devinfo); + dev_set_drvdata(&pdev->dev, NULL); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -2442,15 +2442,17 @@ static void brcmf_sdio_bus_stop(struct d + + static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) + { ++ struct brcmf_sdio_dev *sdiodev; + unsigned long flags; + +- if (bus->sdiodev->oob_irq_requested) { +- spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); +- if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { +- enable_irq(bus->sdiodev->pdata->oob_irq_nr); +- bus->sdiodev->irq_en = true; ++ sdiodev = bus->sdiodev; ++ if (sdiodev->oob_irq_requested) { ++ spin_lock_irqsave(&sdiodev->irq_en_lock, flags); ++ if (!sdiodev->irq_en && !atomic_read(&bus->ipend)) { ++ enable_irq(sdiodev->settings->bus.sdio.oob_irq_nr); ++ sdiodev->irq_en = true; + } +- spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); ++ spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); + } + } + +@@ -3394,9 +3396,7 @@ static int brcmf_sdio_bus_preinit(struct + sizeof(u32)); + } else { + /* otherwise, set txglomalign */ +- value = 4; +- if (sdiodev->pdata) +- value = sdiodev->pdata->sd_sgentry_align; ++ value = sdiodev->settings->bus.sdio.sd_sgentry_align; + /* SDIO ADMA requires at least 32 bit alignment */ + value = max_t(u32, value, 4); + err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, +@@ -3811,21 +3811,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + bus->ci = NULL; + goto fail; + } +- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, ++ sdiodev->settings = brcmf_get_module_param(sdiodev->dev, + BRCMF_BUSTYPE_SDIO, + bus->ci->chip, + bus->ci->chiprev); ++ if (!sdiodev->settings) { ++ brcmf_err("Failed to get device parameters\n"); ++ goto fail; ++ } + /* platform specific configuration: + * alignments must be at least 4 bytes for ADMA + */ + bus->head_align = ALIGNMENT; + bus->sgentry_align = ALIGNMENT; +- if (sdiodev->pdata) { +- if (sdiodev->pdata->sd_head_align > ALIGNMENT) +- bus->head_align = sdiodev->pdata->sd_head_align; +- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) +- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; +- } ++ if (sdiodev->settings->bus.sdio.sd_head_align > ALIGNMENT) ++ bus->head_align = sdiodev->settings->bus.sdio.sd_head_align; ++ if (sdiodev->settings->bus.sdio.sd_sgentry_align > ALIGNMENT) ++ bus->sgentry_align = ++ sdiodev->settings->bus.sdio.sd_sgentry_align; ++ + /* allocate scatter-gather table. sg support + * will be disabled upon allocation failure. + */ +@@ -3837,7 +3841,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + */ + if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && + ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || +- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) ++ (sdiodev->settings->bus.sdio.oob_irq_supported))) + sdiodev->bus_if->wowl_supported = true; + #endif + +@@ -3846,8 +3850,8 @@ brcmf_sdio_probe_attach(struct brcmf_sdi + goto fail; + } + +- if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) +- drivestrength = sdiodev->pdata->drive_strength; ++ if (sdiodev->settings->bus.sdio.drive_strength) ++ drivestrength = sdiodev->settings->bus.sdio.drive_strength; + else + drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; + brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); +@@ -4124,7 +4128,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru + bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; + + /* Attach to the common layer, reserve hdr space */ +- ret = brcmf_attach(bus->sdiodev->dev); ++ ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings); + if (ret != 0) { + brcmf_err("brcmf_attach failed\n"); + goto fail; +@@ -4228,6 +4232,8 @@ void brcmf_sdio_remove(struct brcmf_sdio + } + brcmf_chip_detach(bus->ci); + } ++ if (bus->sdiodev->settings) ++ brcmf_release_module_param(bus->sdiodev->settings); + + kfree(bus->rxbuf); + kfree(bus->hdrbuf); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -184,7 +184,7 @@ struct brcmf_sdio_dev { + struct brcmf_sdio *bus; + struct device *dev; + struct brcmf_bus *bus_if; +- struct brcmfmac_sdio_pd *pdata; ++ struct brcmf_mp_device *settings; + bool oob_irq_requested; + bool irq_en; /* irq enable flags */ + spinlock_t irq_en_lock; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -27,6 +27,8 @@ + #include "debug.h" + #include "firmware.h" + #include "usb.h" ++#include "core.h" ++#include "common.h" + + + #define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000) +@@ -171,6 +173,7 @@ struct brcmf_usbdev_info { + struct urb *bulk_urb; /* used for FW download */ + + bool wowl_enabled; ++ struct brcmf_mp_device *settings; + }; + + static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, +@@ -1027,6 +1030,9 @@ static void brcmf_usb_detach(struct brcm + + kfree(devinfo->tx_reqs); + kfree(devinfo->rx_reqs); ++ ++ if (devinfo->settings) ++ brcmf_release_module_param(devinfo->settings); + } + + +@@ -1136,7 +1142,7 @@ static int brcmf_usb_bus_setup(struct br + int ret; + + /* Attach to the common driver interface */ +- ret = brcmf_attach(devinfo->dev); ++ ret = brcmf_attach(devinfo->dev, devinfo->settings); + if (ret) { + brcmf_err("brcmf_attach failed\n"); + return ret; +@@ -1223,6 +1229,14 @@ static int brcmf_usb_probe_cb(struct brc + bus->wowl_supported = true; + #endif + ++ devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB, ++ bus_pub->devid, ++ bus_pub->chiprev); ++ if (!devinfo->settings) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ + if (!brcmf_usb_dlneeded(devinfo)) { + ret = brcmf_usb_bus_setup(devinfo); + if (ret) diff --git a/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch b/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch new file mode 100644 index 0000000000..eb680fccfc --- /dev/null +++ b/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch @@ -0,0 +1,227 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:09 +0100 +Subject: [PATCH] brcmfmac: integrate add_keyext in add_key + +brcmf_add_keyext is called when a key is configured for a specific +mac address. This function is very similar to the calling function +brcmf_add_key. Integrate this function and also use existing del_key +function in case key is to be cleared. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2073,84 +2073,34 @@ done: + } + + static s32 +-brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, +- u8 key_idx, const u8 *mac_addr, struct key_params *params) ++brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, ++ u8 key_idx, bool pairwise, const u8 *mac_addr) + { + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_wsec_key key; + s32 err = 0; +- u8 keybuf[8]; ++ ++ brcmf_dbg(TRACE, "Enter\n"); ++ if (!check_vif_up(ifp->vif)) ++ return -EIO; ++ ++ if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { ++ /* we ignore this key index in this case */ ++ return -EINVAL; ++ } + + memset(&key, 0, sizeof(key)); +- key.index = (u32) key_idx; +- /* Instead of bcast for ea address for default wep keys, +- driver needs it to be Null */ +- if (!is_multicast_ether_addr(mac_addr)) +- memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); +- key.len = (u32) params->key_len; +- /* check for key index change */ +- if (key.len == 0) { +- /* key delete */ +- err = send_key_to_dongle(ifp, &key); +- if (err) +- brcmf_err("key delete error (%d)\n", err); +- } else { +- if (key.len > sizeof(key.data)) { +- brcmf_err("Invalid key length (%d)\n", key.len); +- return -EINVAL; +- } + +- brcmf_dbg(CONN, "Setting the key index %d\n", key.index); +- memcpy(key.data, params->key, key.len); ++ key.index = (u32)key_idx; ++ key.flags = BRCMF_PRIMARY_KEY; ++ key.algo = CRYPTO_ALGO_OFF; + +- if (!brcmf_is_apmode(ifp->vif) && +- (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { +- brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); +- memcpy(keybuf, &key.data[24], sizeof(keybuf)); +- memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); +- memcpy(&key.data[16], keybuf, sizeof(keybuf)); +- } ++ brcmf_dbg(CONN, "key index (%d)\n", key_idx); + +- /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ +- if (params->seq && params->seq_len == 6) { +- /* rx iv */ +- u8 *ivptr; +- ivptr = (u8 *) params->seq; +- key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | +- (ivptr[3] << 8) | ivptr[2]; +- key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; +- key.iv_initialized = true; +- } ++ /* Set the new key/index */ ++ err = send_key_to_dongle(ifp, &key); + +- switch (params->cipher) { +- case WLAN_CIPHER_SUITE_WEP40: +- key.algo = CRYPTO_ALGO_WEP1; +- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n"); +- break; +- case WLAN_CIPHER_SUITE_WEP104: +- key.algo = CRYPTO_ALGO_WEP128; +- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); +- break; +- case WLAN_CIPHER_SUITE_TKIP: +- key.algo = CRYPTO_ALGO_TKIP; +- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); +- break; +- case WLAN_CIPHER_SUITE_AES_CMAC: +- key.algo = CRYPTO_ALGO_AES_CCM; +- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); +- break; +- case WLAN_CIPHER_SUITE_CCMP: +- key.algo = CRYPTO_ALGO_AES_CCM; +- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); +- break; +- default: +- brcmf_err("Invalid cipher (0x%x)\n", params->cipher); +- return -EINVAL; +- } +- err = send_key_to_dongle(ifp, &key); +- if (err) +- brcmf_err("wsec_key error (%d)\n", err); +- } ++ brcmf_dbg(TRACE, "Exit\n"); + return err; + } + +@@ -2163,8 +2113,9 @@ brcmf_cfg80211_add_key(struct wiphy *wip + struct brcmf_wsec_key *key; + s32 val; + s32 wsec; +- s32 err = 0; ++ s32 err; + u8 keybuf[8]; ++ bool ext_key; + + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CONN, "key index (%d)\n", key_idx); +@@ -2177,27 +2128,32 @@ brcmf_cfg80211_add_key(struct wiphy *wip + return -EINVAL; + } + +- if (mac_addr && +- (params->cipher != WLAN_CIPHER_SUITE_WEP40) && +- (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { +- brcmf_dbg(TRACE, "Exit"); +- return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params); +- } +- +- key = &ifp->vif->profile.key[key_idx]; +- memset(key, 0, sizeof(*key)); ++ if (params->key_len == 0) ++ return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise, ++ mac_addr); + + if (params->key_len > sizeof(key->data)) { + brcmf_err("Too long key length (%u)\n", params->key_len); +- err = -EINVAL; +- goto done; ++ return -EINVAL; ++ } ++ ++ ext_key = false; ++ if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) && ++ (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { ++ brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr); ++ ext_key = true; + } ++ ++ key = &ifp->vif->profile.key[key_idx]; ++ memset(key, 0, sizeof(*key)); ++ if ((ext_key) && (!is_multicast_ether_addr(mac_addr))) ++ memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN); + key->len = params->key_len; + key->index = key_idx; +- + memcpy(key->data, params->key, key->len); ++ if (!ext_key) ++ key->flags = BRCMF_PRIMARY_KEY; + +- key->flags = BRCMF_PRIMARY_KEY; + switch (params->cipher) { + case WLAN_CIPHER_SUITE_WEP40: + key->algo = CRYPTO_ALGO_WEP1; +@@ -2237,7 +2193,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + } + + err = send_key_to_dongle(ifp, key); +- if (err) ++ if (ext_key || err) + goto done; + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); +@@ -2256,38 +2212,6 @@ done: + brcmf_dbg(TRACE, "Exit\n"); + return err; + } +- +-static s32 +-brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, +- u8 key_idx, bool pairwise, const u8 *mac_addr) +-{ +- struct brcmf_if *ifp = netdev_priv(ndev); +- struct brcmf_wsec_key key; +- s32 err = 0; +- +- brcmf_dbg(TRACE, "Enter\n"); +- if (!check_vif_up(ifp->vif)) +- return -EIO; +- +- if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { +- /* we ignore this key index in this case */ +- return -EINVAL; +- } +- +- memset(&key, 0, sizeof(key)); +- +- key.index = (u32) key_idx; +- key.flags = BRCMF_PRIMARY_KEY; +- key.algo = CRYPTO_ALGO_OFF; +- +- brcmf_dbg(CONN, "key index (%d)\n", key_idx); +- +- /* Set the new key/index */ +- err = send_key_to_dongle(ifp, &key); +- +- brcmf_dbg(TRACE, "Exit\n"); +- return err; +-} + + static s32 + brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, diff --git a/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch b/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch new file mode 100644 index 0000000000..c20d40c049 --- /dev/null +++ b/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch @@ -0,0 +1,509 @@ +From: Hante Meuleman +Date: Wed, 17 Feb 2016 11:27:10 +0100 +Subject: [PATCH] brcmfmac: add 802.11w management frame protection support + +Add full support for both AP and STA for management frame protection. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -72,8 +72,13 @@ + #define RSN_AKM_NONE 0 /* None (IBSS) */ + #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ + #define RSN_AKM_PSK 2 /* Pre-shared Key */ ++#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */ ++#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */ + #define RSN_CAP_LEN 2 /* Length of RSN capabilities */ +-#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C ++#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3)) ++#define RSN_CAP_MFPR_MASK BIT(6) ++#define RSN_CAP_MFPC_MASK BIT(7) ++#define RSN_PMKID_COUNT_LEN 2 + + #define VNDR_IE_CMD_LEN 4 /* length of the set command + * string :"add", "del" (+ NUL) +@@ -211,12 +216,19 @@ static const struct ieee80211_regdomain + REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } + }; + +-static const u32 __wl_cipher_suites[] = { ++/* Note: brcmf_cipher_suites is an array of int defining which cipher suites ++ * are supported. A pointer to this array and the number of entries is passed ++ * on to upper layers. AES_CMAC defines whether or not the driver supports MFP. ++ * So the cipher suite AES_CMAC has to be the last one in the array, and when ++ * device does not support MFP then the number of suites will be decreased by 1 ++ */ ++static const u32 brcmf_cipher_suites[] = { + WLAN_CIPHER_SUITE_WEP40, + WLAN_CIPHER_SUITE_WEP104, + WLAN_CIPHER_SUITE_TKIP, + WLAN_CIPHER_SUITE_CCMP, +- WLAN_CIPHER_SUITE_AES_CMAC, ++ /* Keep as last entry: */ ++ WLAN_CIPHER_SUITE_AES_CMAC + }; + + /* Vendor specific ie. id = 221, oui and type defines exact ie */ +@@ -1533,7 +1545,7 @@ static s32 brcmf_set_auth_type(struct ne + + static s32 + brcmf_set_wsec_mode(struct net_device *ndev, +- struct cfg80211_connect_params *sme, bool mfp) ++ struct cfg80211_connect_params *sme) + { + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; +@@ -1592,10 +1604,7 @@ brcmf_set_wsec_mode(struct net_device *n + sme->privacy) + pval = AES_ENABLED; + +- if (mfp) +- wsec = pval | gval | MFP_CAPABLE; +- else +- wsec = pval | gval; ++ wsec = pval | gval; + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec); + if (err) { + brcmf_err("error (%d)\n", err); +@@ -1612,56 +1621,100 @@ brcmf_set_wsec_mode(struct net_device *n + static s32 + brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + { +- struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); +- struct brcmf_cfg80211_security *sec; +- s32 val = 0; +- s32 err = 0; ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ s32 val; ++ s32 err; ++ const struct brcmf_tlv *rsn_ie; ++ const u8 *ie; ++ u32 ie_len; ++ u32 offset; ++ u16 rsn_cap; ++ u32 mfp; ++ u16 count; + +- if (sme->crypto.n_akm_suites) { +- err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), +- "wpa_auth", &val); +- if (err) { +- brcmf_err("could not get wpa_auth (%d)\n", err); +- return err; ++ if (!sme->crypto.n_akm_suites) ++ return 0; ++ ++ err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val); ++ if (err) { ++ brcmf_err("could not get wpa_auth (%d)\n", err); ++ return err; ++ } ++ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ val = WPA_AUTH_UNSPECIFIED; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ val = WPA_AUTH_PSK; ++ break; ++ default: ++ brcmf_err("invalid cipher group (%d)\n", ++ sme->crypto.cipher_group); ++ return -EINVAL; + } +- if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { +- switch (sme->crypto.akm_suites[0]) { +- case WLAN_AKM_SUITE_8021X: +- val = WPA_AUTH_UNSPECIFIED; +- break; +- case WLAN_AKM_SUITE_PSK: +- val = WPA_AUTH_PSK; +- break; +- default: +- brcmf_err("invalid cipher group (%d)\n", +- sme->crypto.cipher_group); +- return -EINVAL; +- } +- } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { +- switch (sme->crypto.akm_suites[0]) { +- case WLAN_AKM_SUITE_8021X: +- val = WPA2_AUTH_UNSPECIFIED; +- break; +- case WLAN_AKM_SUITE_PSK: +- val = WPA2_AUTH_PSK; +- break; +- default: +- brcmf_err("invalid cipher group (%d)\n", +- sme->crypto.cipher_group); +- return -EINVAL; +- } ++ } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { ++ switch (sme->crypto.akm_suites[0]) { ++ case WLAN_AKM_SUITE_8021X: ++ val = WPA2_AUTH_UNSPECIFIED; ++ break; ++ case WLAN_AKM_SUITE_8021X_SHA256: ++ val = WPA2_AUTH_1X_SHA256; ++ break; ++ case WLAN_AKM_SUITE_PSK_SHA256: ++ val = WPA2_AUTH_PSK_SHA256; ++ break; ++ case WLAN_AKM_SUITE_PSK: ++ val = WPA2_AUTH_PSK; ++ break; ++ default: ++ brcmf_err("invalid cipher group (%d)\n", ++ sme->crypto.cipher_group); ++ return -EINVAL; + } ++ } + +- brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); +- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), +- "wpa_auth", val); +- if (err) { +- brcmf_err("could not set wpa_auth (%d)\n", err); +- return err; +- } ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) ++ goto skip_mfp_config; ++ /* The MFP mode (1 or 2) needs to be determined, parse IEs. The ++ * IE will not be verified, just a quick search for MFP config ++ */ ++ rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len, ++ WLAN_EID_RSN); ++ if (!rsn_ie) ++ goto skip_mfp_config; ++ ie = (const u8 *)rsn_ie; ++ ie_len = rsn_ie->len + TLV_HDR_LEN; ++ /* Skip unicast suite */ ++ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN; ++ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len) ++ goto skip_mfp_config; ++ /* Skip multicast suite */ ++ count = ie[offset] + (ie[offset + 1] << 8); ++ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN); ++ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len) ++ goto skip_mfp_config; ++ /* Skip auth key management suite(s) */ ++ count = ie[offset] + (ie[offset + 1] << 8); ++ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN); ++ if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len) ++ goto skip_mfp_config; ++ /* Ready to read capabilities */ ++ mfp = BRCMF_MFP_NONE; ++ rsn_cap = ie[offset] + (ie[offset + 1] << 8); ++ if (rsn_cap & RSN_CAP_MFPR_MASK) ++ mfp = BRCMF_MFP_REQUIRED; ++ else if (rsn_cap & RSN_CAP_MFPC_MASK) ++ mfp = BRCMF_MFP_CAPABLE; ++ brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp); ++ ++skip_mfp_config: ++ brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); ++ err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val); ++ if (err) { ++ brcmf_err("could not set wpa_auth (%d)\n", err); ++ return err; + } +- sec = &profile->sec; +- sec->wpa_auth = sme->crypto.akm_suites[0]; + + return err; + } +@@ -1827,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + goto done; + } + +- err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED); ++ err = brcmf_set_wsec_mode(ndev, sme); + if (err) { + brcmf_err("wl_set_set_cipher failed (%d)\n", err); + goto done; +@@ -2077,10 +2130,12 @@ brcmf_cfg80211_del_key(struct wiphy *wip + u8 key_idx, bool pairwise, const u8 *mac_addr) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct brcmf_wsec_key key; +- s32 err = 0; ++ struct brcmf_wsec_key *key; ++ s32 err; + + brcmf_dbg(TRACE, "Enter\n"); ++ brcmf_dbg(CONN, "key index (%d)\n", key_idx); ++ + if (!check_vif_up(ifp->vif)) + return -EIO; + +@@ -2089,16 +2144,19 @@ brcmf_cfg80211_del_key(struct wiphy *wip + return -EINVAL; + } + +- memset(&key, 0, sizeof(key)); ++ key = &ifp->vif->profile.key[key_idx]; + +- key.index = (u32)key_idx; +- key.flags = BRCMF_PRIMARY_KEY; +- key.algo = CRYPTO_ALGO_OFF; ++ if (key->algo == CRYPTO_ALGO_OFF) { ++ brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n"); ++ return -EINVAL; ++ } + +- brcmf_dbg(CONN, "key index (%d)\n", key_idx); ++ memset(key, 0, sizeof(*key)); ++ key->index = (u32)key_idx; ++ key->flags = BRCMF_PRIMARY_KEY; + +- /* Set the new key/index */ +- err = send_key_to_dongle(ifp, &key); ++ /* Clear the key/index */ ++ err = send_key_to_dongle(ifp, key); + + brcmf_dbg(TRACE, "Exit\n"); + return err; +@@ -2106,8 +2164,8 @@ brcmf_cfg80211_del_key(struct wiphy *wip + + static s32 + brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, +- u8 key_idx, bool pairwise, const u8 *mac_addr, +- struct key_params *params) ++ u8 key_idx, bool pairwise, const u8 *mac_addr, ++ struct key_params *params) + { + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_wsec_key *key; +@@ -2214,9 +2272,10 @@ done: + } + + static s32 +-brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, +- u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, +- void (*callback) (void *cookie, struct key_params * params)) ++brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, ++ bool pairwise, const u8 *mac_addr, void *cookie, ++ void (*callback)(void *cookie, ++ struct key_params *params)) + { + struct key_params params; + struct brcmf_if *ifp = netdev_priv(ndev); +@@ -2268,8 +2327,15 @@ done: + + static s32 + brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, +- struct net_device *ndev, u8 key_idx) ++ struct net_device *ndev, u8 key_idx) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ ++ brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx); ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) ++ return 0; ++ + brcmf_dbg(INFO, "Not supported\n"); + + return -EOPNOTSUPP; +@@ -3769,7 +3835,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + u32 auth = 0; /* d11 open authentication */ + u16 count; + s32 err = 0; +- s32 len = 0; ++ s32 len; + u32 i; + u32 wsec; + u32 pval = 0; +@@ -3779,6 +3845,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + u8 *data; + u16 rsn_cap; + u32 wme_bss_disable; ++ u32 mfp; + + brcmf_dbg(TRACE, "Enter\n"); + if (wpa_ie == NULL) +@@ -3893,19 +3960,53 @@ brcmf_configure_wpaie(struct brcmf_if *i + is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) : + (wpa_auth |= WPA_AUTH_PSK); + break; ++ case RSN_AKM_SHA256_PSK: ++ brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n"); ++ wpa_auth |= WPA2_AUTH_PSK_SHA256; ++ break; ++ case RSN_AKM_SHA256_1X: ++ brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n"); ++ wpa_auth |= WPA2_AUTH_1X_SHA256; ++ break; + default: + brcmf_err("Ivalid key mgmt info\n"); + } + offset++; + } + ++ mfp = BRCMF_MFP_NONE; + if (is_rsn_ie) { + wme_bss_disable = 1; + if ((offset + RSN_CAP_LEN) <= len) { + rsn_cap = data[offset] + (data[offset + 1] << 8); + if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK) + wme_bss_disable = 0; ++ if (rsn_cap & RSN_CAP_MFPR_MASK) { ++ brcmf_dbg(TRACE, "MFP Required\n"); ++ mfp = BRCMF_MFP_REQUIRED; ++ /* Firmware only supports mfp required in ++ * combination with WPA2_AUTH_PSK_SHA256 or ++ * WPA2_AUTH_1X_SHA256. ++ */ ++ if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 | ++ WPA2_AUTH_1X_SHA256))) { ++ err = -EINVAL; ++ goto exit; ++ } ++ /* Firmware has requirement that WPA2_AUTH_PSK/ ++ * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI ++ * is to be included in the rsn ie. ++ */ ++ if (wpa_auth & WPA2_AUTH_PSK_SHA256) ++ wpa_auth |= WPA2_AUTH_PSK; ++ else if (wpa_auth & WPA2_AUTH_1X_SHA256) ++ wpa_auth |= WPA2_AUTH_UNSPECIFIED; ++ } else if (rsn_cap & RSN_CAP_MFPC_MASK) { ++ brcmf_dbg(TRACE, "MFP Capable\n"); ++ mfp = BRCMF_MFP_CAPABLE; ++ } + } ++ offset += RSN_CAP_LEN; + /* set wme_bss_disable to sync RSN Capabilities */ + err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", + wme_bss_disable); +@@ -3913,6 +4014,21 @@ brcmf_configure_wpaie(struct brcmf_if *i + brcmf_err("wme_bss_disable error %d\n", err); + goto exit; + } ++ ++ /* Skip PMKID cnt as it is know to be 0 for AP. */ ++ offset += RSN_PMKID_COUNT_LEN; ++ ++ /* See if there is BIP wpa suite left for MFP */ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) && ++ ((offset + WPA_IE_MIN_OUI_LEN) <= len)) { ++ err = brcmf_fil_bsscfg_data_set(ifp, "bip", ++ &data[offset], ++ WPA_IE_MIN_OUI_LEN); ++ if (err < 0) { ++ brcmf_err("bip error %d\n", err); ++ goto exit; ++ } ++ } + } + /* FOR WPS , set SES_OW_ENABLED */ + wsec = (pval | gval | SES_OW_ENABLED); +@@ -3929,6 +4045,16 @@ brcmf_configure_wpaie(struct brcmf_if *i + brcmf_err("wsec error %d\n", err); + goto exit; + } ++ /* Configure MFP, this needs to go after wsec otherwise the wsec command ++ * will overwrite the values set by MFP ++ */ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) { ++ err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp); ++ if (err < 0) { ++ brcmf_err("mfp error %d\n", err); ++ goto exit; ++ } ++ } + /* set upper-layer auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); + if (err < 0) { +@@ -6149,8 +6275,10 @@ static int brcmf_setup_wiphy(struct wiph + wiphy->n_addresses = i; + + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; +- wiphy->cipher_suites = __wl_cipher_suites; +- wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); ++ wiphy->cipher_suites = brcmf_cipher_suites; ++ wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites); ++ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) ++ wiphy->n_cipher_suites--; + wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | + WIPHY_FLAG_OFFCHAN_TX | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -72,7 +72,7 @@ + + #define BRCMF_VNDR_IE_P2PAF_SHIFT 12 + +-#define BRCMF_MAX_DEFAULT_KEYS 4 ++#define BRCMF_MAX_DEFAULT_KEYS 6 + + /* beacon loss timeout defaults */ + #define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2 +@@ -107,7 +107,6 @@ struct brcmf_cfg80211_security { + u32 auth_type; + u32 cipher_pairwise; + u32 cipher_group; +- u32 wpa_auth; + }; + + /** +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -161,6 +161,7 @@ void brcmf_feat_attach(struct brcmf_pub + ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode"); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable"); ++ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp"); + + pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; + err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -30,6 +30,7 @@ + * WOWL_ND: WOWL net detect (PNO) + * WOWL_GTK: (WOWL) GTK rekeying offload + * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL. ++ * MFP: 802.11w Management Frame Protection. + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -42,7 +43,8 @@ + BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ + BRCMF_FEAT_DEF(WOWL_ND) \ + BRCMF_FEAT_DEF(WOWL_GTK) \ +- BRCMF_FEAT_DEF(WOWL_ARP_ND) ++ BRCMF_FEAT_DEF(WOWL_ARP_ND) \ ++ BRCMF_FEAT_DEF(MFP) + + /* + * Quirks: +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +@@ -142,6 +142,10 @@ + #define BRCMF_RSN_KEK_LENGTH 16 + #define BRCMF_RSN_REPLAY_LEN 8 + ++#define BRCMF_MFP_NONE 0 ++#define BRCMF_MFP_CAPABLE 1 ++#define BRCMF_MFP_REQUIRED 2 ++ + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { + BRCMF_JOIN_PREF_RSSI = 1, +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h +@@ -236,6 +236,8 @@ static inline bool ac_bitmap_tst(u8 bitm + #define WPA2_AUTH_RESERVED3 0x0200 + #define WPA2_AUTH_RESERVED4 0x0400 + #define WPA2_AUTH_RESERVED5 0x0800 ++#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */ ++#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */ + + #define DOT11_DEFAULT_RTS_LEN 2347 + #define DOT11_DEFAULT_FRAG_LEN 2346 diff --git a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch b/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch index 6719f2ba51..f242748723 100644 --- a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch +++ b/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch @@ -43,7 +43,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -506,6 +506,21 @@ brcmf_cfg80211_update_proto_addr_mode(st +@@ -527,6 +527,21 @@ brcmf_cfg80211_update_proto_addr_mode(st ADDR_INDIRECT); } @@ -65,7 +65,7 @@ Signed-off-by: Kalle Valo static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) { struct brcmf_mbss_ssid_le mbss_ssid_le; -@@ -513,7 +528,7 @@ static int brcmf_cfg80211_request_ap_if( +@@ -534,7 +549,7 @@ static int brcmf_cfg80211_request_ap_if( int err; memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le)); @@ -76,7 +76,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -909,30 +909,6 @@ void brcmf_remove_interface(struct brcmf +@@ -938,30 +938,6 @@ void brcmf_remove_interface(struct brcmf brcmf_del_if(ifp->drvr, ifp->bsscfgidx); } @@ -109,7 +109,7 @@ Signed-off-by: Kalle Valo static int brcmf_inetaddr_changed(struct notifier_block *nb, --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -214,7 +214,6 @@ int brcmf_net_attach(struct brcmf_if *if +@@ -221,7 +221,6 @@ int brcmf_net_attach(struct brcmf_if *if struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); void brcmf_remove_interface(struct brcmf_if *ifp); diff --git a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch index a7074a2ef6..6f064d16ef 100644 --- a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch +++ b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch @@ -27,7 +27,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2690,7 +2690,7 @@ static s32 brcmf_inform_single_bss(struc +@@ -2689,7 +2689,7 @@ static s32 brcmf_inform_single_bss(struc if (!bi->ctl_ch) { ch.chspec = le16_to_cpu(bi->chanspec); cfg->d11inf.decchspec(&ch); @@ -36,7 +36,7 @@ Signed-off-by: Kalle Valo } channel = bi->ctl_ch; -@@ -2808,7 +2808,7 @@ static s32 brcmf_inform_ibss(struct brcm +@@ -2807,7 +2807,7 @@ static s32 brcmf_inform_ibss(struct brcm else band = wiphy->bands[IEEE80211_BAND_5GHZ]; @@ -45,7 +45,7 @@ Signed-off-by: Kalle Valo cfg->channel = freq; notify_channel = ieee80211_get_channel(wiphy, freq); -@@ -2818,7 +2818,7 @@ static s32 brcmf_inform_ibss(struct brcm +@@ -2817,7 +2817,7 @@ static s32 brcmf_inform_ibss(struct brcm notify_ielen = le32_to_cpu(bi->ie_length); notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; @@ -54,7 +54,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(CONN, "capability: %X\n", notify_capability); brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "signal: %d\n", notify_signal); -@@ -5132,7 +5132,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 +@@ -5234,7 +5234,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 else band = wiphy->bands[IEEE80211_BAND_5GHZ]; @@ -63,7 +63,7 @@ Signed-off-by: Kalle Valo notify_channel = ieee80211_get_channel(wiphy, freq); done: -@@ -5654,14 +5654,15 @@ static int brcmf_construct_chaninfo(stru +@@ -5756,14 +5756,15 @@ static int brcmf_construct_chaninfo(stru channel = band->channels; index = band->n_channels; for (j = 0; j < band->n_channels; j++) { @@ -82,7 +82,7 @@ Signed-off-by: Kalle Valo /* assuming the chanspecs order is HT20, * HT40 upper, HT40 lower, and VHT80. -@@ -5763,7 +5764,7 @@ static int brcmf_enable_bw40_2g(struct b +@@ -5865,7 +5866,7 @@ static int brcmf_enable_bw40_2g(struct b if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) continue; for (j = 0; j < band->n_channels; j++) { @@ -102,7 +102,7 @@ Signed-off-by: Kalle Valo } afx_hdl->peer_chan = bi->ctl_ch; brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", -@@ -1380,7 +1380,7 @@ int brcmf_p2p_notify_action_frame_rx(str +@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(str if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { @@ -111,7 +111,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", afx_hdl->peer_chan); complete(&afx_hdl->act_frm_scan); -@@ -1423,7 +1423,7 @@ int brcmf_p2p_notify_action_frame_rx(str +@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(str memcpy(&mgmt_frame->u, frame, mgmt_frame_len); mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); @@ -120,7 +120,7 @@ Signed-off-by: Kalle Valo ch.band == BRCMU_CHAN_BAND_2G ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ); -@@ -1863,7 +1863,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere +@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { @@ -129,7 +129,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", afx_hdl->peer_chan); complete(&afx_hdl->act_frm_scan); -@@ -1888,7 +1888,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere +@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere mgmt_frame = (u8 *)(rxframe + 1); mgmt_frame_len = e->datalen - sizeof(*rxframe); diff --git a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch b/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch index 3344e05af8..3e16c4bfc7 100644 --- a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch +++ b/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch @@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4769,6 +4769,68 @@ exit: +@@ -4846,6 +4846,68 @@ exit: return err; } @@ -84,7 +84,7 @@ Signed-off-by: Kalle Valo static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, struct wireless_dev *wdev, enum nl80211_crit_proto_id proto, -@@ -4906,6 +4968,7 @@ static struct cfg80211_ops wl_cfg80211_o +@@ -5008,6 +5070,7 @@ static struct cfg80211_ops brcmf_cfg8021 .mgmt_tx = brcmf_cfg80211_mgmt_tx, .remain_on_channel = brcmf_p2p_remain_on_channel, .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, diff --git a/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch b/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch index 460baa64bd..1b119b2c85 100644 --- a/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch +++ b/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch @@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -649,20 +649,24 @@ static struct wireless_dev *brcmf_cfg802 +@@ -670,20 +670,24 @@ static struct wireless_dev *brcmf_cfg802 return ERR_PTR(-EOPNOTSUPP); case NL80211_IFTYPE_AP: wdev = brcmf_ap_add_vif(wiphy, name, flags, params); @@ -48,7 +48,7 @@ Signed-off-by: Kalle Valo static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc) --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2020,8 +2020,6 @@ static int brcmf_p2p_request_p2p_if(stru +@@ -2030,8 +2030,6 @@ static int brcmf_p2p_request_p2p_if(stru err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request, sizeof(if_request)); diff --git a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch index 19f4ee1c18..bf06a767d4 100644 --- a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch +++ b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch @@ -32,7 +32,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4304,7 +4304,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4381,7 +4381,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi struct brcmf_join_params join_params; enum nl80211_iftype dev_role; struct brcmf_fil_bss_enable_le bss_enable; @@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo bool mbss; int is_11d; -@@ -4380,16 +4380,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4457,16 +4457,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); @@ -59,7 +59,7 @@ Signed-off-by: Kalle Valo if (is_11d != ifp->vif->is_11d) { err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, is_11d); -@@ -4437,6 +4429,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4514,6 +4506,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi err = -EINVAL; goto exit; } @@ -68,7 +68,7 @@ Signed-off-by: Kalle Valo if (dev_role == NL80211_IFTYPE_AP) { if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) brcmf_fil_iovar_int_set(ifp, "mbss", 1); -@@ -4446,6 +4440,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4523,6 +4517,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_err("setting AP mode failed %d\n", err); goto exit; } @@ -86,7 +86,7 @@ Signed-off-by: Kalle Valo err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); if (err < 0) { brcmf_err("BRCMF_C_UP error (%d)\n", err); -@@ -4467,7 +4472,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4544,7 +4549,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi goto exit; } brcmf_dbg(TRACE, "AP mode configuration complete\n"); @@ -101,7 +101,7 @@ Signed-off-by: Kalle Valo err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le, sizeof(ssid_le)); if (err < 0) { -@@ -4484,7 +4495,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4561,7 +4572,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi } brcmf_dbg(TRACE, "GO mode configuration complete\n"); diff --git a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch index df707a788f..6ef145338c 100644 --- a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch +++ b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch @@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -5269,7 +5269,6 @@ brcmf_notify_connect_status_ap(struct br +@@ -5371,7 +5371,6 @@ brcmf_notify_connect_status_ap(struct br struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { @@ -49,7 +49,7 @@ Signed-off-by: Kalle Valo static int generation; u32 event = e->event_code; u32 reason = e->reason; -@@ -5280,8 +5279,6 @@ brcmf_notify_connect_status_ap(struct br +@@ -5382,8 +5381,6 @@ brcmf_notify_connect_status_ap(struct br ndev != cfg_to_ndev(cfg)) { brcmf_dbg(CONN, "AP mode link down\n"); complete(&cfg->vif_disabled); diff --git a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch index 6cf8135346..dd1b490e1f 100644 --- a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch +++ b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch @@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -566,7 +566,7 @@ struct wireless_dev *brcmf_ap_add_vif(st +@@ -587,7 +587,7 @@ struct wireless_dev *brcmf_ap_add_vif(st brcmf_dbg(INFO, "Adding vif \"%s\"\n", name); @@ -24,7 +24,7 @@ Signed-off-by: Kalle Valo if (IS_ERR(vif)) return (struct wireless_dev *)vif; -@@ -4995,8 +4995,7 @@ static struct cfg80211_ops wl_cfg80211_o +@@ -5097,8 +5097,7 @@ static struct cfg80211_ops brcmf_cfg8021 }; struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, @@ -34,7 +34,7 @@ Signed-off-by: Kalle Valo { struct brcmf_cfg80211_vif *vif_walk; struct brcmf_cfg80211_vif *vif; -@@ -5011,8 +5010,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v +@@ -5113,8 +5112,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v vif->wdev.wiphy = cfg->wiphy; vif->wdev.iftype = type; @@ -43,7 +43,7 @@ Signed-off-by: Kalle Valo brcmf_init_prof(&vif->profile); if (type == NL80211_IFTYPE_AP) { -@@ -6582,7 +6579,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 +@@ -6753,7 +6750,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 init_vif_event(&cfg->vif_event); INIT_LIST_HEAD(&cfg->vif_list); @@ -54,7 +54,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -@@ -165,7 +165,6 @@ struct vif_saved_ie { +@@ -167,7 +167,6 @@ struct vif_saved_ie { * @wdev: wireless device. * @profile: profile information. * @sme_state: SME state using enum brcmf_vif_status bits. @@ -62,7 +62,7 @@ Signed-off-by: Kalle Valo * @list: linked list. * @mgmt_rx_reg: registered rx mgmt frame types. * @mbss: Multiple BSS type, set if not first AP (not relevant for P2P). -@@ -175,7 +174,6 @@ struct brcmf_cfg80211_vif { +@@ -177,7 +176,6 @@ struct brcmf_cfg80211_vif { struct wireless_dev wdev; struct brcmf_cfg80211_profile profile; unsigned long sme_state; @@ -70,7 +70,7 @@ Signed-off-by: Kalle Valo struct vif_saved_ie saved_ie; struct list_head list; u16 mgmt_rx_reg; -@@ -386,8 +384,7 @@ s32 brcmf_cfg80211_down(struct net_devic +@@ -388,8 +386,7 @@ s32 brcmf_cfg80211_down(struct net_devic enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, @@ -82,7 +82,7 @@ Signed-off-by: Kalle Valo s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2064,8 +2064,7 @@ static struct wireless_dev *brcmf_p2p_cr +@@ -2074,8 +2074,7 @@ static struct wireless_dev *brcmf_p2p_cr if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif) return ERR_PTR(-ENOSPC); @@ -92,7 +92,7 @@ Signed-off-by: Kalle Valo if (IS_ERR(p2p_vif)) { brcmf_err("could not create discovery vif\n"); return (struct wireless_dev *)p2p_vif; -@@ -2165,7 +2164,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s +@@ -2175,7 +2174,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s return ERR_PTR(-EOPNOTSUPP); } diff --git a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch index be6606d25a..e80ca8da0e 100644 --- a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch +++ b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch @@ -23,7 +23,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6105,29 +6105,15 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6207,29 +6207,15 @@ static int brcmf_setup_ifmodes(struct wi if (!combo) goto err; @@ -56,7 +56,7 @@ Signed-off-by: Kalle Valo c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); if (p2p) { -@@ -6145,6 +6131,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6247,6 +6233,7 @@ static int brcmf_setup_ifmodes(struct wi c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); } @@ -64,7 +64,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = c0_limits; -@@ -6152,7 +6139,9 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6254,7 +6241,9 @@ static int brcmf_setup_ifmodes(struct wi if (p2p) { c++; i = 0; @@ -75,7 +75,7 @@ Signed-off-by: Kalle Valo p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); p2p_limits[i].max = 1; -@@ -6161,6 +6150,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6263,6 +6252,7 @@ static int brcmf_setup_ifmodes(struct wi p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); @@ -83,7 +83,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = p2p_limits; -@@ -6168,14 +6158,19 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6270,14 +6260,19 @@ static int brcmf_setup_ifmodes(struct wi if (mbss) { c++; diff --git a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch index 0472290f6c..e870cc7572 100644 --- a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch +++ b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch @@ -1,3 +1,4 @@ +From b50ddfa8530e9b5f52e873fdd6ff04f327a88799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Fri, 17 Jun 2016 12:29:21 +0200 Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after event @@ -20,10 +21,15 @@ unregister_netdevice when needed. Signed-off-by: Rafał Miłecki Signed-off-by: Kalle Valo --- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 29 +++++++++++++--------- + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 +- + .../wireless/broadcom/brcm80211/brcmfmac/fweh.c | 2 +- + .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 4 +-- + 4 files changed, 21 insertions(+), 16 deletions(-) --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -705,12 +705,16 @@ fail: +@@ -733,12 +733,16 @@ fail: return -EBADE; } @@ -44,7 +50,7 @@ Signed-off-by: Kalle Valo } void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on) -@@ -808,7 +812,7 @@ struct brcmf_if *brcmf_add_if(struct brc +@@ -836,7 +840,7 @@ struct brcmf_if *brcmf_add_if(struct brc brcmf_err("ERROR: netdev:%s already exists\n", ifp->ndev->name); netif_stop_queue(ifp->ndev); @@ -53,7 +59,7 @@ Signed-off-by: Kalle Valo drvr->iflist[bsscfgidx] = NULL; } else { brcmf_dbg(INFO, "netdev:%s ignore IF event\n", -@@ -856,7 +860,8 @@ struct brcmf_if *brcmf_add_if(struct brc +@@ -884,7 +888,8 @@ struct brcmf_if *brcmf_add_if(struct brc return ifp; } @@ -63,16 +69,16 @@ Signed-off-by: Kalle Valo { struct brcmf_if *ifp; -@@ -885,7 +890,7 @@ static void brcmf_del_if(struct brcmf_pu - cancel_work_sync(&ifp->setmacaddr_work); +@@ -914,7 +919,7 @@ static void brcmf_del_if(struct brcmf_pu cancel_work_sync(&ifp->multicast_work); + cancel_work_sync(&ifp->ndoffload_work); } - brcmf_net_detach(ifp->ndev); + brcmf_net_detach(ifp->ndev, rtnl_locked); } else { /* Only p2p device interfaces which get dynamically created * end up here. In this case the p2p module should be informed -@@ -899,14 +904,14 @@ static void brcmf_del_if(struct brcmf_pu +@@ -928,14 +933,14 @@ static void brcmf_del_if(struct brcmf_pu } } @@ -89,19 +95,19 @@ Signed-off-by: Kalle Valo } #ifdef CONFIG_INET -@@ -1154,9 +1159,9 @@ fail: - brcmf_fws_deinit(drvr); - } - if (ifp) -- brcmf_net_detach(ifp->ndev); -+ brcmf_net_detach(ifp->ndev, false); - if (p2p_ifp) -- brcmf_net_detach(p2p_ifp->ndev); -+ brcmf_net_detach(p2p_ifp->ndev, false); - drvr->iflist[0] = NULL; - drvr->iflist[1] = NULL; - if (brcmf_ignoring_probe_fail(drvr)) -@@ -1222,7 +1227,7 @@ void brcmf_detach(struct device *dev) +@@ -1242,9 +1247,9 @@ fail: + brcmf_fws_deinit(drvr); + } + if (ifp) +- brcmf_net_detach(ifp->ndev); ++ brcmf_net_detach(ifp->ndev, false); + if (p2p_ifp) +- brcmf_net_detach(p2p_ifp->ndev); ++ brcmf_net_detach(p2p_ifp->ndev, false); + drvr->iflist[0] = NULL; + drvr->iflist[1] = NULL; + if (drvr->settings->ignore_probe_fail) +@@ -1313,7 +1318,7 @@ void brcmf_detach(struct device *dev) /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS-1; i > -1; i--) @@ -112,7 +118,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -213,7 +213,7 @@ struct brcmf_if *brcmf_get_ifp(struct br +@@ -220,7 +220,7 @@ struct brcmf_if *brcmf_get_ifp(struct br int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); @@ -123,7 +129,7 @@ Signed-off-by: Kalle Valo void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -@@ -226,7 +226,7 @@ static void brcmf_fweh_handle_if_event(s +@@ -183,7 +183,7 @@ 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) @@ -134,7 +140,7 @@ Signed-off-by: Kalle Valo /** --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2279,7 +2279,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2289,7 +2289,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph err = 0; } if (err) @@ -143,7 +149,7 @@ Signed-off-by: Kalle Valo brcmf_cfg80211_arm_vif_event(cfg, NULL); if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) -@@ -2385,7 +2385,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i +@@ -2395,7 +2395,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i if (vif != NULL) { brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); diff --git a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch index dd6bc37a49..75f9aae73a 100644 --- a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch +++ b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch @@ -17,7 +17,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -795,7 +795,7 @@ fail: +@@ -823,7 +823,7 @@ fail: } struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, @@ -28,7 +28,7 @@ Signed-off-by: Kalle Valo struct net_device *ndev; --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -212,7 +212,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) +@@ -219,7 +219,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, diff --git a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch index 1ed0fc14a2..ab9a634437 100644 --- a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch +++ b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch @@ -16,7 +16,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2253,6 +2253,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2263,6 +2263,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph return 0; brcmf_p2p_cancel_remain_on_channel(vif->ifp); brcmf_p2p_deinit_discovery(p2p); 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 index 3268051aad..6dd0c03e3d 100644 --- 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 @@ -45,7 +45,7 @@ Signed-off-by: Kalle Valo #include "core.h" #include "debug.h" #include "tracepoint.h" -@@ -225,8 +226,13 @@ static void brcmf_fweh_handle_if_event(s +@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); @@ -63,7 +63,7 @@ Signed-off-by: Kalle Valo /** --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -@@ -2280,8 +2280,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph +@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph else err = 0; } diff --git a/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch index 55989e60f5..1929f0b812 100644 --- a/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch +++ b/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch @@ -18,7 +18,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -750,12 +750,48 @@ s32 brcmf_notify_escan_complete(struct b +@@ -771,12 +771,48 @@ s32 brcmf_notify_escan_complete(struct b return err; } @@ -67,7 +67,7 @@ Signed-off-by: Kalle Valo /* vif event pending in firmware */ if (brcmf_cfg80211_vif_event_armed(cfg)) return -EBUSY; -@@ -772,12 +808,13 @@ int brcmf_cfg80211_del_iface(struct wiph +@@ -793,12 +829,13 @@ int brcmf_cfg80211_del_iface(struct wiph switch (wdev->iftype) { case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_STATION: diff --git a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch index 10a99f5899..6a18bafc80 100644 --- a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch +++ b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch @@ -14,7 +14,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4508,6 +4508,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4585,6 +4585,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_err("SET SSID error (%d)\n", err); goto exit; } @@ -30,7 +30,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(TRACE, "AP mode configuration complete\n"); } else if (dev_role == NL80211_IFTYPE_P2P_GO) { err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); -@@ -4566,6 +4575,10 @@ static int brcmf_cfg80211_stop_ap(struct +@@ -4643,6 +4652,10 @@ static int brcmf_cfg80211_stop_ap(struct return err; } diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch index a38e93ad6a..9850e2dad3 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,8 +13,8 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1313,6 +1313,7 @@ static int __init brcmfmac_module_init(v - #endif +@@ -1398,6 +1398,7 @@ int __init brcmf_core_init(void) + { if (!schedule_work(&brcmf_driver_work)) return -EBUSY; + flush_work(&brcmf_driver_work); diff --git a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch index 6e309e9fa1..1e440c02f3 100644 --- a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch +++ b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch @@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -630,9 +630,37 @@ static struct wireless_dev *brcmf_cfg802 +@@ -651,9 +651,37 @@ static struct wireless_dev *brcmf_cfg802 u32 *flags, struct vif_params *params) { -- cgit v1.2.3 From bc004132213820368cc3af1e54e18f5cdb760972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:58:53 +0200 Subject: mac80211: brcmfmac: backport patches that were skipped previously #2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...45-brcmfmac-Remove-waitqueue_active-check.patch | 54 ++ ...sert-default-boardrev-in-nvram-data-if-mi.patch | 114 ---- .../346-brcmfmac-uninitialized-ret-variable.patch | 21 + ...c-sdio-remove-unused-variable-retry_limit.patch | 24 + ...elete-unnecessary-variable-initialisation.patch | 26 + ...mac-clear-eventmask-array-before-using-it.patch | 27 + ...rcmfmac-fix-clearing-wowl-wake-indicators.patch | 27 + ...sert-default-boardrev-in-nvram-data-if-mi.patch | 114 ++++ ...fix-p2p-scan-abort-null-pointer-exception.patch | 29 + ...-brcmfmac-screening-firmware-event-packet.patch | 297 +++++++++++ ...cmfmac-cleanup-ampdu-rx-host-reorder-code.patch | 585 +++++++++++++++++++++ ...ac-revise-handling-events-in-receive-path.patch | 139 +++++ ...eate-common-function-for-handling-brcmf_p.patch | 88 ++++ ...ac-rework-function-picking-free-BSS-index.patch | 4 +- ...d-field-storing-control-channel-to-the-st.patch | 6 +- ...mac-support-get_channel-cfg80211-callback.patch | 4 +- ...fix-setting-AP-channel-with-new-firmwares.patch | 12 +- ...n-t-remove-interface-on-link-down-firmwar.patch | 4 +- ...cmfmac-drop-unused-pm_block-vif-attribute.patch | 6 +- ...ightly-simplify-building-interface-combin.patch | 10 +- ...x-lockup-when-removing-P2P-interface-afte.patch | 16 +- ...e-const-char-for-interface-name-in-brcmf_.patch | 4 +- ...mac-respect-hidden_ssid-for-AP-interfaces.patch | 4 +- ...store-stopping-netdev-queue-when-bus-clog.patch | 2 +- ...-brcmfmac-add-missing-eth_type_trans-call.patch | 26 + ...mfmac-register-wiphy-s-during-module_init.patch | 2 +- 26 files changed, 1494 insertions(+), 151 deletions(-) create mode 100644 package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch delete mode 100644 package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch create mode 100644 package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch create mode 100644 package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch create mode 100644 package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch create mode 100644 package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch create mode 100644 package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch create mode 100644 package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch create mode 100644 package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch create mode 100644 package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch create mode 100644 package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch create mode 100644 package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch create mode 100644 package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch create mode 100644 package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch diff --git a/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch b/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch new file mode 100644 index 0000000000..39f438321e --- /dev/null +++ b/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch @@ -0,0 +1,54 @@ +From: Hui Wang +Date: Wed, 9 Mar 2016 15:25:26 +0800 +Subject: [PATCH] brcmfmac: Remove waitqueue_active check + +We met a problem of pm_suspend when repeated closing/opening the lid +on a Lenovo laptop (1/20 reproduce rate), below is the log: + +[ 199.735876] PM: Entering mem sleep +[ 199.750516] e1000e: EEE TX LPI TIMER: 00000011 +[ 199.856638] Trying to free nonexistent resource <000000000000d000-000000000000d0ff> +[ 201.753566] brcmfmac: brcmf_pcie_suspend: Timeout on response for entering D3 substate +[ 201.753581] pci_legacy_suspend(): brcmf_pcie_suspend+0x0/0x1f0 [brcmfmac] returns -5 +[ 201.753585] dpm_run_callback(): pci_pm_suspend+0x0/0x160 returns -5 +[ 201.753589] PM: Device 0000:04:00.0 failed to suspend async: error -5 + +Through debugging, we found when problem happens, it is not the device +fails to enter D3, but the signal D3_ACK comes too early to pass the +waitqueue_active() check. + +Just like this: +brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D3_INFORM); +// signal is triggered here +wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, + BRCMF_PCIE_MBDATA_TIMEOUT); + +So far I think it is safe to remove waitqueue_active check since there +is only one place to trigger this signal (sending +BRCMF_H2D_HOST_D3_INFORM). And it is not a problem calling wake_up +event earlier than calling wait_event. + +Cc: Brett Rudley +Cc: Hante Meuleman +Cc: Franky (Zhenhui) Lin +Cc: Pieter-Paul Giesberts +Cc: Arend van Spriel +Signed-off-by: Hui Wang +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -677,10 +677,8 @@ static void brcmf_pcie_handle_mb_data(st + brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n"); + if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) { + brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n"); +- if (waitqueue_active(&devinfo->mbdata_resp_wait)) { +- devinfo->mbdata_completed = true; +- wake_up(&devinfo->mbdata_resp_wait); +- } ++ devinfo->mbdata_completed = true; ++ wake_up(&devinfo->mbdata_resp_wait); + } + } + diff --git a/package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch b/package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch deleted file mode 100644 index f293401ca8..0000000000 --- a/package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch +++ /dev/null @@ -1,114 +0,0 @@ -From: Hante Meuleman -Date: Mon, 11 Apr 2016 11:35:23 +0200 -Subject: [PATCH] brcmfmac: insert default boardrev in nvram data if - missing - -Some nvram files/stores come without the boardrev information, -but firmware requires this to be set. When not found in nvram then -add a default boardrev string to the nvram data. - -Reported-by: Rafal Milecki -Reviewed-by: Arend Van Spriel -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Hante Meuleman -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -@@ -29,6 +29,7 @@ - #define BRCMF_FW_MAX_NVRAM_SIZE 64000 - #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ - #define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */ -+#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff" - - enum nvram_parser_state { - IDLE, -@@ -51,6 +52,7 @@ enum nvram_parser_state { - * @entry: start position of key,value entry. - * @multi_dev_v1: detect pcie multi device v1 (compressed). - * @multi_dev_v2: detect pcie multi device v2. -+ * @boardrev_found: nvram contains boardrev information. - */ - struct nvram_parser { - enum nvram_parser_state state; -@@ -63,6 +65,7 @@ struct nvram_parser { - u32 entry; - bool multi_dev_v1; - bool multi_dev_v2; -+ bool boardrev_found; - }; - - /** -@@ -125,6 +128,8 @@ static enum nvram_parser_state brcmf_nvr - nvp->multi_dev_v1 = true; - if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) - nvp->multi_dev_v2 = true; -+ if (strncmp(&nvp->data[nvp->entry], "boardrev", 8) == 0) -+ nvp->boardrev_found = true; - } else if (!is_nvram_char(c) || c == ' ') { - brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", - nvp->line, nvp->column); -@@ -284,6 +289,8 @@ static void brcmf_fw_strip_multi_v1(stru - while (i < nvp->nvram_len) { - if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { - i += 2; -+ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) -+ nvp->boardrev_found = true; - while (nvp->nvram[i] != 0) { - nvram[j] = nvp->nvram[i]; - i++; -@@ -335,6 +342,8 @@ static void brcmf_fw_strip_multi_v2(stru - while (i < nvp->nvram_len - len) { - if (strncmp(&nvp->nvram[i], prefix, len) == 0) { - i += len; -+ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) -+ nvp->boardrev_found = true; - while (nvp->nvram[i] != 0) { - nvram[j] = nvp->nvram[i]; - i++; -@@ -356,6 +365,18 @@ fail: - nvp->nvram_len = 0; - } - -+static void brcmf_fw_add_defaults(struct nvram_parser *nvp) -+{ -+ if (nvp->boardrev_found) -+ return; -+ -+ memcpy(&nvp->nvram[nvp->nvram_len], &BRCMF_FW_DEFAULT_BOARDREV, -+ strlen(BRCMF_FW_DEFAULT_BOARDREV)); -+ nvp->nvram_len += strlen(BRCMF_FW_DEFAULT_BOARDREV); -+ nvp->nvram[nvp->nvram_len] = '\0'; -+ nvp->nvram_len++; -+} -+ - /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil - * and ending in a NUL. Removes carriage returns, empty lines, comment lines, - * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. -@@ -377,16 +398,21 @@ static void *brcmf_fw_nvram_strip(const - if (nvp.state == END) - break; - } -- if (nvp.multi_dev_v1) -+ if (nvp.multi_dev_v1) { -+ nvp.boardrev_found = false; - brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); -- else if (nvp.multi_dev_v2) -+ } else if (nvp.multi_dev_v2) { -+ nvp.boardrev_found = false; - brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); -+ } - - if (nvp.nvram_len == 0) { - kfree(nvp.nvram); - return NULL; - } - -+ brcmf_fw_add_defaults(&nvp); -+ - pad = nvp.nvram_len; - *new_length = roundup(nvp.nvram_len + 1, 4); - while (pad != *new_length) { diff --git a/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch b/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch new file mode 100644 index 0000000000..3c9ed425da --- /dev/null +++ b/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch @@ -0,0 +1,21 @@ +From: Dan Carpenter +Date: Tue, 15 Mar 2016 10:06:10 +0300 +Subject: [PATCH] brcmfmac: uninitialized "ret" variable + +There is an error path where "ret" isn't initialized. + +Signed-off-by: Dan Carpenter +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -250,7 +250,7 @@ static int brcmf_sdiod_request_data(stru + u32 addr, u8 regsz, void *data, bool write) + { + struct sdio_func *func; +- int ret; ++ int ret = -EINVAL; + + brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + write, fn, addr, regsz); diff --git a/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch b/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch new file mode 100644 index 0000000000..d1deb6ee5c --- /dev/null +++ b/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch @@ -0,0 +1,24 @@ +From: Colin Ian King +Date: Sun, 20 Mar 2016 17:34:52 +0000 +Subject: [PATCH] brcmfmac: sdio: remove unused variable retry_limit + +retry_limit has never been used during the life of this driver, so +we may as well remove it as it is redundant. + +Signed-off-by: Colin Ian King +Reviewed-by: Julian Calaby +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -535,9 +535,6 @@ static int qcount[NUMPRIO]; + + #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL) + +-/* Retry count for register access failures */ +-static const uint retry_limit = 2; +- + /* Limit on rounding up frames */ + static const uint max_roundup = 512; + diff --git a/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch b/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch new file mode 100644 index 0000000000..d399b264ea --- /dev/null +++ b/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch @@ -0,0 +1,26 @@ +From: Markus Elfring +Date: Fri, 18 Mar 2016 13:23:24 +1100 +Subject: [PATCH] brcmfmac: Delete unnecessary variable initialisation + +In brcmf_sdio_download_firmware(), bcmerror is set by the call to +brcmf_sdio_download_code_file(), before it's checked in the following +line. + +Signed-off-by: Markus Elfring +Acked-by: Arend van Spriel +[Rewrote commit message] +Signed-off-by: Julian Calaby +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3258,7 +3258,7 @@ static int brcmf_sdio_download_firmware( + const struct firmware *fw, + void *nvram, u32 nvlen) + { +- int bcmerror = -EFAULT; ++ int bcmerror; + u32 rstvec; + + sdio_claim_host(bus->sdiodev->func[1]); diff --git a/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch b/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch new file mode 100644 index 0000000000..0acb4faaf1 --- /dev/null +++ b/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch @@ -0,0 +1,27 @@ +From: Hante Meuleman +Date: Mon, 11 Apr 2016 11:35:21 +0200 +Subject: [PATCH] brcmfmac: clear eventmask array before using it + +When the event_msgs iovar is set an array is used to configure the +enabled events. This arrays needs to nulled before configuring +otherwise unhandled events will be enabled. This solves a problem +where in case of wowl the host got woken by an incorrectly enabled +event. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Arend Van Spriel +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -371,6 +371,7 @@ int brcmf_fweh_activate_events(struct br + int i, err; + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + ++ memset(eventmask, 0, sizeof(eventmask)); + for (i = 0; i < BRCMF_E_LAST; i++) { + if (ifp->drvr->fweh.evt_handler[i]) { + brcmf_dbg(EVENT, "enable event %s\n", diff --git a/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch b/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch new file mode 100644 index 0000000000..8d3067890c --- /dev/null +++ b/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch @@ -0,0 +1,27 @@ +From: Hante Meuleman +Date: Mon, 11 Apr 2016 11:35:22 +0200 +Subject: [PATCH] brcmfmac: fix clearing wowl wake indicators + +Newer firmwares require the usage of the wowl wakeind struct as size +for the iovar to clear the wake indicators. Older firmwares do not +care, so change the used size. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3608,7 +3608,8 @@ static void brcmf_configure_wowl(struct + if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) + wowl_config |= BRCMF_WOWL_UNASSOC; + +- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear")); ++ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", ++ sizeof(struct brcmf_wowl_wakeind_le)); + brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); + brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); + brcmf_bus_wowl_config(cfg->pub->bus_if, true); diff --git a/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch b/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch new file mode 100644 index 0000000000..f293401ca8 --- /dev/null +++ b/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch @@ -0,0 +1,114 @@ +From: Hante Meuleman +Date: Mon, 11 Apr 2016 11:35:23 +0200 +Subject: [PATCH] brcmfmac: insert default boardrev in nvram data if + missing + +Some nvram files/stores come without the boardrev information, +but firmware requires this to be set. When not found in nvram then +add a default boardrev string to the nvram data. + +Reported-by: Rafal Milecki +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -29,6 +29,7 @@ + #define BRCMF_FW_MAX_NVRAM_SIZE 64000 + #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ + #define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */ ++#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff" + + enum nvram_parser_state { + IDLE, +@@ -51,6 +52,7 @@ enum nvram_parser_state { + * @entry: start position of key,value entry. + * @multi_dev_v1: detect pcie multi device v1 (compressed). + * @multi_dev_v2: detect pcie multi device v2. ++ * @boardrev_found: nvram contains boardrev information. + */ + struct nvram_parser { + enum nvram_parser_state state; +@@ -63,6 +65,7 @@ struct nvram_parser { + u32 entry; + bool multi_dev_v1; + bool multi_dev_v2; ++ bool boardrev_found; + }; + + /** +@@ -125,6 +128,8 @@ static enum nvram_parser_state brcmf_nvr + nvp->multi_dev_v1 = true; + if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) + nvp->multi_dev_v2 = true; ++ if (strncmp(&nvp->data[nvp->entry], "boardrev", 8) == 0) ++ nvp->boardrev_found = true; + } else if (!is_nvram_char(c) || c == ' ') { + brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", + nvp->line, nvp->column); +@@ -284,6 +289,8 @@ static void brcmf_fw_strip_multi_v1(stru + while (i < nvp->nvram_len) { + if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { + i += 2; ++ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) ++ nvp->boardrev_found = true; + while (nvp->nvram[i] != 0) { + nvram[j] = nvp->nvram[i]; + i++; +@@ -335,6 +342,8 @@ static void brcmf_fw_strip_multi_v2(stru + while (i < nvp->nvram_len - len) { + if (strncmp(&nvp->nvram[i], prefix, len) == 0) { + i += len; ++ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) ++ nvp->boardrev_found = true; + while (nvp->nvram[i] != 0) { + nvram[j] = nvp->nvram[i]; + i++; +@@ -356,6 +365,18 @@ fail: + nvp->nvram_len = 0; + } + ++static void brcmf_fw_add_defaults(struct nvram_parser *nvp) ++{ ++ if (nvp->boardrev_found) ++ return; ++ ++ memcpy(&nvp->nvram[nvp->nvram_len], &BRCMF_FW_DEFAULT_BOARDREV, ++ strlen(BRCMF_FW_DEFAULT_BOARDREV)); ++ nvp->nvram_len += strlen(BRCMF_FW_DEFAULT_BOARDREV); ++ nvp->nvram[nvp->nvram_len] = '\0'; ++ nvp->nvram_len++; ++} ++ + /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil + * and ending in a NUL. Removes carriage returns, empty lines, comment lines, + * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. +@@ -377,16 +398,21 @@ static void *brcmf_fw_nvram_strip(const + if (nvp.state == END) + break; + } +- if (nvp.multi_dev_v1) ++ if (nvp.multi_dev_v1) { ++ nvp.boardrev_found = false; + brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); +- else if (nvp.multi_dev_v2) ++ } else if (nvp.multi_dev_v2) { ++ nvp.boardrev_found = false; + brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); ++ } + + if (nvp.nvram_len == 0) { + kfree(nvp.nvram); + return NULL; + } + ++ brcmf_fw_add_defaults(&nvp); ++ + pad = nvp.nvram_len; + *new_length = roundup(nvp.nvram_len + 1, 4); + while (pad != *new_length) { diff --git a/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch b/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch new file mode 100644 index 0000000000..ed0c83f9bb --- /dev/null +++ b/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch @@ -0,0 +1,29 @@ +From: Hante Meuleman +Date: Mon, 11 Apr 2016 11:35:24 +0200 +Subject: [PATCH] brcmfmac: fix p2p scan abort null pointer exception + +When p2p connection setup is performed without having ever done an +escan a null pointer exception can occur. This is because the ifp +to abort scanning is taken from escan struct while it was never +initialized. Fix this by using the primary ifp for scan abort. The +abort should still be performed and all scan related commands are +performed on primary ifp. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1266,7 +1266,7 @@ static void + brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg) + { + struct brcmf_p2p_info *p2p = &cfg->p2p; +- struct brcmf_if *ifp = cfg->escan_info.ifp; ++ struct brcmf_if *ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; + + if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) && + (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) || diff --git a/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch b/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch new file mode 100644 index 0000000000..4d26404f51 --- /dev/null +++ b/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch @@ -0,0 +1,297 @@ +From: Franky Lin +Date: Mon, 11 Apr 2016 11:35:25 +0200 +Subject: [PATCH] brcmfmac: screening firmware event packet + +Firmware uses asynchronized events as a communication method to the +host. The event packets are marked as ETH_P_LINK_CTL protocol type. For +SDIO and PCIe bus, this kind of packets are delivered through virtual +event channel not data channel. This patch adds a screening logic to +make sure the event handler only processes the events coming from the +correct channel. + +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -216,7 +216,9 @@ bool brcmf_c_prec_enq(struct device *dev + int prec); + + /* Receive frame for delivery to OS. Callee disposes of rxp. */ +-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); ++void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt); ++/* Receive async event packet from firmware. Callee disposes of rxp. */ ++void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); + + /* Indication from bus module regarding presence/insertion of dongle. */ + int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -311,16 +311,17 @@ void brcmf_txflowblock(struct device *de + brcmf_fws_bus_blocked(drvr, state); + } + +-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) ++void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, ++ bool handle_event) + { +- skb->dev = ifp->ndev; +- skb->protocol = eth_type_trans(skb, skb->dev); ++ skb->protocol = eth_type_trans(skb, ifp->ndev); + + if (skb->pkt_type == PACKET_MULTICAST) + ifp->stats.multicast++; + + /* Process special event packets */ +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ if (handle_event) ++ brcmf_fweh_process_skb(ifp->drvr, skb); + + if (!(ifp->ndev->flags & IFF_UP)) { + brcmu_pkt_buf_free_skb(skb); +@@ -381,7 +382,7 @@ static void brcmf_rxreorder_process_info + /* validate flags and flow id */ + if (flags == 0xFF) { + brcmf_err("invalid flags...so ignore this packet\n"); +- brcmf_netif_rx(ifp, pkt); ++ brcmf_netif_rx(ifp, pkt, false); + return; + } + +@@ -393,7 +394,7 @@ static void brcmf_rxreorder_process_info + if (rfi == NULL) { + brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", + flow_id); +- brcmf_netif_rx(ifp, pkt); ++ brcmf_netif_rx(ifp, pkt, false); + return; + } + +@@ -418,7 +419,7 @@ static void brcmf_rxreorder_process_info + rfi = kzalloc(buf_size, GFP_ATOMIC); + if (rfi == NULL) { + brcmf_err("failed to alloc buffer\n"); +- brcmf_netif_rx(ifp, pkt); ++ brcmf_netif_rx(ifp, pkt, false); + return; + } + +@@ -532,11 +533,11 @@ static void brcmf_rxreorder_process_info + netif_rx: + skb_queue_walk_safe(&reorder_list, pkt, pnext) { + __skb_unlink(pkt, &reorder_list); +- brcmf_netif_rx(ifp, pkt); ++ brcmf_netif_rx(ifp, pkt, false); + } + } + +-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb) ++void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) + { + struct brcmf_if *ifp; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); +@@ -560,7 +561,32 @@ void brcmf_rx_frame(struct device *dev, + if (rd->reorder) + brcmf_rxreorder_process_info(ifp, rd->reorder, skb); + else +- brcmf_netif_rx(ifp, skb); ++ brcmf_netif_rx(ifp, skb, handle_evnt); ++} ++ ++void brcmf_rx_event(struct device *dev, struct sk_buff *skb) ++{ ++ struct brcmf_if *ifp; ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ int ret; ++ ++ brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb); ++ ++ /* process and remove protocol-specific header */ ++ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); ++ ++ if (ret || !ifp || !ifp->ndev) { ++ if (ret != -ENODATA && ifp) ++ ifp->stats.rx_errors++; ++ brcmu_pkt_buf_free_skb(skb); ++ return; ++ } ++ ++ skb->protocol = eth_type_trans(skb, ifp->ndev); ++ ++ brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmu_pkt_buf_free_skb(skb); + } + + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -225,7 +225,8 @@ int brcmf_get_next_free_bsscfgidx(struct + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); +-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); ++void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, ++ bool handle_event); + void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); + int __init brcmf_core_init(void); + void __exit brcmf_core_exit(void); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -20,6 +20,7 @@ + + #include + #include ++#include + + #include + #include +@@ -1075,28 +1076,13 @@ static void brcmf_msgbuf_rxbuf_event_pos + } + + +-static void +-brcmf_msgbuf_rx_skb(struct brcmf_msgbuf *msgbuf, struct sk_buff *skb, +- u8 ifidx) +-{ +- struct brcmf_if *ifp; +- +- ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); +- if (!ifp || !ifp->ndev) { +- brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); +- brcmu_pkt_buf_free_skb(skb); +- return; +- } +- brcmf_netif_rx(ifp, skb); +-} +- +- + static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf) + { + struct msgbuf_rx_event *event; + u32 idx; + u16 buflen; + struct sk_buff *skb; ++ struct brcmf_if *ifp; + + event = (struct msgbuf_rx_event *)buf; + idx = le32_to_cpu(event->msg.request_id); +@@ -1116,7 +1102,19 @@ static void brcmf_msgbuf_process_event(s + + skb_trim(skb, buflen); + +- brcmf_msgbuf_rx_skb(msgbuf, skb, event->msg.ifidx); ++ ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx); ++ if (!ifp || !ifp->ndev) { ++ brcmf_err("Received pkt for invalid ifidx %d\n", ++ event->msg.ifidx); ++ goto exit; ++ } ++ ++ skb->protocol = eth_type_trans(skb, ifp->ndev); ++ ++ brcmf_fweh_process_skb(ifp->drvr, skb); ++ ++exit: ++ brcmu_pkt_buf_free_skb(skb); + } + + +@@ -1128,6 +1126,7 @@ brcmf_msgbuf_process_rx_complete(struct + u16 data_offset; + u16 buflen; + u32 idx; ++ struct brcmf_if *ifp; + + brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1); + +@@ -1148,7 +1147,14 @@ brcmf_msgbuf_process_rx_complete(struct + + skb_trim(skb, buflen); + +- brcmf_msgbuf_rx_skb(msgbuf, skb, rx_complete->msg.ifidx); ++ ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx); ++ if (!ifp || !ifp->ndev) { ++ brcmf_err("Received pkt for invalid ifidx %d\n", ++ rx_complete->msg.ifidx); ++ brcmu_pkt_buf_free_skb(skb); ++ return; ++ } ++ brcmf_netif_rx(ifp, skb, false); + } + + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1294,6 +1294,17 @@ static inline u8 brcmf_sdio_getdatoffset + return (u8)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT); + } + ++static inline bool brcmf_sdio_fromevntchan(u8 *swheader) ++{ ++ u32 hdrvalue; ++ u8 ret; ++ ++ hdrvalue = *(u32 *)swheader; ++ ret = (u8)((hdrvalue & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT); ++ ++ return (ret == SDPCM_EVENT_CHANNEL); ++} ++ + static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, + struct brcmf_sdio_hdrinfo *rd, + enum brcmf_sdio_frmtype type) +@@ -1641,7 +1652,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf + pfirst->len, pfirst->next, + pfirst->prev); + skb_unlink(pfirst, &bus->glom); +- brcmf_rx_frame(bus->sdiodev->dev, pfirst); ++ if (brcmf_sdio_fromevntchan(pfirst->data)) ++ brcmf_rx_event(bus->sdiodev->dev, pfirst); ++ else ++ brcmf_rx_frame(bus->sdiodev->dev, pfirst, ++ false); + bus->sdcnt.rxglompkts++; + } + +@@ -1967,18 +1982,19 @@ static uint brcmf_sdio_readframes(struct + __skb_trim(pkt, rd->len); + skb_pull(pkt, rd->dat_offset); + ++ if (pkt->len == 0) ++ brcmu_pkt_buf_free_skb(pkt); ++ else if (rd->channel == SDPCM_EVENT_CHANNEL) ++ brcmf_rx_event(bus->sdiodev->dev, pkt); ++ else ++ brcmf_rx_frame(bus->sdiodev->dev, pkt, ++ false); ++ + /* prepare the descriptor for the next read */ + rd->len = rd->len_nxtfrm << 4; + rd->len_nxtfrm = 0; + /* treat all packet as event if we don't know */ + rd->channel = SDPCM_EVENT_CHANNEL; +- +- if (pkt->len == 0) { +- brcmu_pkt_buf_free_skb(pkt); +- continue; +- } +- +- brcmf_rx_frame(bus->sdiodev->dev, pkt); + } + + rxcount = maxframes - rxleft; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -514,7 +514,7 @@ static void brcmf_usb_rx_complete(struct + + if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { + skb_put(skb, urb->actual_length); +- brcmf_rx_frame(devinfo->dev, skb); ++ brcmf_rx_frame(devinfo->dev, skb, true); + brcmf_usb_rx_refill(devinfo, req); + } else { + brcmu_pkt_buf_free_skb(skb); diff --git a/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch b/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch new file mode 100644 index 0000000000..33b263df3a --- /dev/null +++ b/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch @@ -0,0 +1,585 @@ +From: Arend van Spriel +Date: Mon, 11 Apr 2016 11:35:26 +0200 +Subject: [PATCH] brcmfmac: cleanup ampdu-rx host reorder code + +The code for ampdu-rx host reorder is related to the firmware signalling +supported in BCDC protocol. This change moves the code to fwsignal module. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -351,6 +351,12 @@ brcmf_proto_bcdc_add_tdls_peer(struct br + { + } + ++static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp, ++ struct sk_buff *skb) ++{ ++ brcmf_fws_rxreorder(ifp, skb); ++} ++ + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) + { + struct brcmf_bcdc *bcdc; +@@ -372,6 +378,7 @@ int brcmf_proto_bcdc_attach(struct brcmf + drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode; + drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer; + drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer; ++ drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder; + drvr->proto->pd = bcdc; + + drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -40,19 +40,6 @@ + + #define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) + +-/* AMPDU rx reordering definitions */ +-#define BRCMF_RXREORDER_FLOWID_OFFSET 0 +-#define BRCMF_RXREORDER_MAXIDX_OFFSET 2 +-#define BRCMF_RXREORDER_FLAGS_OFFSET 4 +-#define BRCMF_RXREORDER_CURIDX_OFFSET 6 +-#define BRCMF_RXREORDER_EXPIDX_OFFSET 8 +- +-#define BRCMF_RXREORDER_DEL_FLOW 0x01 +-#define BRCMF_RXREORDER_FLUSH_ALL 0x02 +-#define BRCMF_RXREORDER_CURIDX_VALID 0x04 +-#define BRCMF_RXREORDER_EXPIDX_VALID 0x08 +-#define BRCMF_RXREORDER_NEW_HOLE 0x10 +- + #define BRCMF_BSSIDX_INVALID -1 + + char *brcmf_ifname(struct brcmf_if *ifp) +@@ -342,207 +329,11 @@ void brcmf_netif_rx(struct brcmf_if *ifp + netif_rx_ni(skb); + } + +-static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi, +- u8 start, u8 end, +- struct sk_buff_head *skb_list) +-{ +- /* initialize return list */ +- __skb_queue_head_init(skb_list); +- +- if (rfi->pend_pkts == 0) { +- brcmf_dbg(INFO, "no packets in reorder queue\n"); +- return; +- } +- +- do { +- if (rfi->pktslots[start]) { +- __skb_queue_tail(skb_list, rfi->pktslots[start]); +- rfi->pktslots[start] = NULL; +- } +- start++; +- if (start > rfi->max_idx) +- start = 0; +- } while (start != end); +- rfi->pend_pkts -= skb_queue_len(skb_list); +-} +- +-static void brcmf_rxreorder_process_info(struct brcmf_if *ifp, u8 *reorder_data, +- struct sk_buff *pkt) +-{ +- u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; +- struct brcmf_ampdu_rx_reorder *rfi; +- struct sk_buff_head reorder_list; +- struct sk_buff *pnext; +- u8 flags; +- u32 buf_size; +- +- flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET]; +- flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET]; +- +- /* validate flags and flow id */ +- if (flags == 0xFF) { +- brcmf_err("invalid flags...so ignore this packet\n"); +- brcmf_netif_rx(ifp, pkt, false); +- return; +- } +- +- rfi = ifp->drvr->reorder_flows[flow_id]; +- if (flags & BRCMF_RXREORDER_DEL_FLOW) { +- brcmf_dbg(INFO, "flow-%d: delete\n", +- flow_id); +- +- if (rfi == NULL) { +- brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", +- flow_id); +- brcmf_netif_rx(ifp, pkt, false); +- return; +- } +- +- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx, +- &reorder_list); +- /* add the last packet */ +- __skb_queue_tail(&reorder_list, pkt); +- kfree(rfi); +- ifp->drvr->reorder_flows[flow_id] = NULL; +- goto netif_rx; +- } +- /* from here on we need a flow reorder instance */ +- if (rfi == NULL) { +- buf_size = sizeof(*rfi); +- max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; +- +- buf_size += (max_idx + 1) * sizeof(pkt); +- +- /* allocate space for flow reorder info */ +- brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", +- flow_id, max_idx); +- rfi = kzalloc(buf_size, GFP_ATOMIC); +- if (rfi == NULL) { +- brcmf_err("failed to alloc buffer\n"); +- brcmf_netif_rx(ifp, pkt, false); +- return; +- } +- +- ifp->drvr->reorder_flows[flow_id] = rfi; +- rfi->pktslots = (struct sk_buff **)(rfi+1); +- rfi->max_idx = max_idx; +- } +- if (flags & BRCMF_RXREORDER_NEW_HOLE) { +- if (rfi->pend_pkts) { +- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, +- rfi->exp_idx, +- &reorder_list); +- WARN_ON(rfi->pend_pkts); +- } else { +- __skb_queue_head_init(&reorder_list); +- } +- rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; +- rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; +- rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; +- rfi->pktslots[rfi->cur_idx] = pkt; +- rfi->pend_pkts++; +- brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n", +- flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts); +- } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) { +- cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; +- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; +- +- if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) { +- /* still in the current hole */ +- /* enqueue the current on the buffer chain */ +- if (rfi->pktslots[cur_idx] != NULL) { +- brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n"); +- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); +- rfi->pktslots[cur_idx] = NULL; +- } +- rfi->pktslots[cur_idx] = pkt; +- rfi->pend_pkts++; +- rfi->cur_idx = cur_idx; +- brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n", +- flow_id, cur_idx, exp_idx, rfi->pend_pkts); +- +- /* can return now as there is no reorder +- * list to process. +- */ +- return; +- } +- if (rfi->exp_idx == cur_idx) { +- if (rfi->pktslots[cur_idx] != NULL) { +- brcmf_dbg(INFO, "error buffer pending..free it\n"); +- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); +- rfi->pktslots[cur_idx] = NULL; +- } +- rfi->pktslots[cur_idx] = pkt; +- rfi->pend_pkts++; +- +- /* got the expected one. flush from current to expected +- * and update expected +- */ +- brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n", +- flow_id, cur_idx, exp_idx, rfi->pend_pkts); +- +- rfi->cur_idx = cur_idx; +- rfi->exp_idx = exp_idx; +- +- brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx, +- &reorder_list); +- brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n", +- flow_id, skb_queue_len(&reorder_list), +- rfi->pend_pkts); +- } else { +- u8 end_idx; +- +- brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n", +- flow_id, flags, rfi->cur_idx, rfi->exp_idx, +- cur_idx, exp_idx); +- if (flags & BRCMF_RXREORDER_FLUSH_ALL) +- end_idx = rfi->exp_idx; +- else +- end_idx = exp_idx; +- +- /* flush pkts first */ +- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, +- &reorder_list); +- +- if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) { +- __skb_queue_tail(&reorder_list, pkt); +- } else { +- rfi->pktslots[cur_idx] = pkt; +- rfi->pend_pkts++; +- } +- rfi->exp_idx = exp_idx; +- rfi->cur_idx = cur_idx; +- } +- } else { +- /* explicity window move updating the expected index */ +- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; +- +- brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n", +- flow_id, flags, rfi->exp_idx, exp_idx); +- if (flags & BRCMF_RXREORDER_FLUSH_ALL) +- end_idx = rfi->exp_idx; +- else +- end_idx = exp_idx; +- +- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, +- &reorder_list); +- __skb_queue_tail(&reorder_list, pkt); +- /* set the new expected idx */ +- rfi->exp_idx = exp_idx; +- } +-netif_rx: +- skb_queue_walk_safe(&reorder_list, pkt, pnext) { +- __skb_unlink(pkt, &reorder_list); +- brcmf_netif_rx(ifp, pkt, false); +- } +-} +- + void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) + { + struct brcmf_if *ifp; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; +- struct brcmf_skb_reorder_data *rd; + int ret; + + brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); +@@ -557,9 +348,8 @@ void brcmf_rx_frame(struct device *dev, + return; + } + +- rd = (struct brcmf_skb_reorder_data *)skb->cb; +- if (rd->reorder) +- brcmf_rxreorder_process_info(ifp, rd->reorder, skb); ++ if (brcmf_proto_is_reorder_skb(skb)) ++ brcmf_proto_rxreorder(ifp, skb); + else + brcmf_netif_rx(ifp, skb, handle_evnt); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -208,10 +208,6 @@ struct brcmf_if { + u8 ipv6addr_idx; + }; + +-struct brcmf_skb_reorder_data { +- u8 *reorder; +-}; +- + int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); + + /* Return pointer to interface name */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -92,6 +92,19 @@ enum brcmf_fws_tlv_len { + }; + #undef BRCMF_FWS_TLV_DEF + ++/* AMPDU rx reordering definitions */ ++#define BRCMF_RXREORDER_FLOWID_OFFSET 0 ++#define BRCMF_RXREORDER_MAXIDX_OFFSET 2 ++#define BRCMF_RXREORDER_FLAGS_OFFSET 4 ++#define BRCMF_RXREORDER_CURIDX_OFFSET 6 ++#define BRCMF_RXREORDER_EXPIDX_OFFSET 8 ++ ++#define BRCMF_RXREORDER_DEL_FLOW 0x01 ++#define BRCMF_RXREORDER_FLUSH_ALL 0x02 ++#define BRCMF_RXREORDER_CURIDX_VALID 0x04 ++#define BRCMF_RXREORDER_EXPIDX_VALID 0x08 ++#define BRCMF_RXREORDER_NEW_HOLE 0x10 ++ + #ifdef DEBUG + /* + * brcmf_fws_tlv_names - array of tlv names. +@@ -1614,6 +1627,202 @@ static int brcmf_fws_notify_bcmc_credit_ + return 0; + } + ++static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi, ++ u8 start, u8 end, ++ struct sk_buff_head *skb_list) ++{ ++ /* initialize return list */ ++ __skb_queue_head_init(skb_list); ++ ++ if (rfi->pend_pkts == 0) { ++ brcmf_dbg(INFO, "no packets in reorder queue\n"); ++ return; ++ } ++ ++ do { ++ if (rfi->pktslots[start]) { ++ __skb_queue_tail(skb_list, rfi->pktslots[start]); ++ rfi->pktslots[start] = NULL; ++ } ++ start++; ++ if (start > rfi->max_idx) ++ start = 0; ++ } while (start != end); ++ rfi->pend_pkts -= skb_queue_len(skb_list); ++} ++ ++void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) ++{ ++ u8 *reorder_data; ++ u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; ++ struct brcmf_ampdu_rx_reorder *rfi; ++ struct sk_buff_head reorder_list; ++ struct sk_buff *pnext; ++ u8 flags; ++ u32 buf_size; ++ ++ reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder; ++ flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET]; ++ flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET]; ++ ++ /* validate flags and flow id */ ++ if (flags == 0xFF) { ++ brcmf_err("invalid flags...so ignore this packet\n"); ++ brcmf_netif_rx(ifp, pkt, false); ++ return; ++ } ++ ++ rfi = ifp->drvr->reorder_flows[flow_id]; ++ if (flags & BRCMF_RXREORDER_DEL_FLOW) { ++ brcmf_dbg(INFO, "flow-%d: delete\n", ++ flow_id); ++ ++ if (rfi == NULL) { ++ brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", ++ flow_id); ++ brcmf_netif_rx(ifp, pkt, false); ++ return; ++ } ++ ++ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx, ++ &reorder_list); ++ /* add the last packet */ ++ __skb_queue_tail(&reorder_list, pkt); ++ kfree(rfi); ++ ifp->drvr->reorder_flows[flow_id] = NULL; ++ goto netif_rx; ++ } ++ /* from here on we need a flow reorder instance */ ++ if (rfi == NULL) { ++ buf_size = sizeof(*rfi); ++ max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; ++ ++ buf_size += (max_idx + 1) * sizeof(pkt); ++ ++ /* allocate space for flow reorder info */ ++ brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", ++ flow_id, max_idx); ++ rfi = kzalloc(buf_size, GFP_ATOMIC); ++ if (rfi == NULL) { ++ brcmf_err("failed to alloc buffer\n"); ++ brcmf_netif_rx(ifp, pkt, false); ++ return; ++ } ++ ++ ifp->drvr->reorder_flows[flow_id] = rfi; ++ rfi->pktslots = (struct sk_buff **)(rfi + 1); ++ rfi->max_idx = max_idx; ++ } ++ if (flags & BRCMF_RXREORDER_NEW_HOLE) { ++ if (rfi->pend_pkts) { ++ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, ++ rfi->exp_idx, ++ &reorder_list); ++ WARN_ON(rfi->pend_pkts); ++ } else { ++ __skb_queue_head_init(&reorder_list); ++ } ++ rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; ++ rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; ++ rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; ++ rfi->pktslots[rfi->cur_idx] = pkt; ++ rfi->pend_pkts++; ++ brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n", ++ flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts); ++ } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) { ++ cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; ++ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; ++ ++ if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) { ++ /* still in the current hole */ ++ /* enqueue the current on the buffer chain */ ++ if (rfi->pktslots[cur_idx] != NULL) { ++ brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n"); ++ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); ++ rfi->pktslots[cur_idx] = NULL; ++ } ++ rfi->pktslots[cur_idx] = pkt; ++ rfi->pend_pkts++; ++ rfi->cur_idx = cur_idx; ++ brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n", ++ flow_id, cur_idx, exp_idx, rfi->pend_pkts); ++ ++ /* can return now as there is no reorder ++ * list to process. ++ */ ++ return; ++ } ++ if (rfi->exp_idx == cur_idx) { ++ if (rfi->pktslots[cur_idx] != NULL) { ++ brcmf_dbg(INFO, "error buffer pending..free it\n"); ++ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); ++ rfi->pktslots[cur_idx] = NULL; ++ } ++ rfi->pktslots[cur_idx] = pkt; ++ rfi->pend_pkts++; ++ ++ /* got the expected one. flush from current to expected ++ * and update expected ++ */ ++ brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n", ++ flow_id, cur_idx, exp_idx, rfi->pend_pkts); ++ ++ rfi->cur_idx = cur_idx; ++ rfi->exp_idx = exp_idx; ++ ++ brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx, ++ &reorder_list); ++ brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n", ++ flow_id, skb_queue_len(&reorder_list), ++ rfi->pend_pkts); ++ } else { ++ u8 end_idx; ++ ++ brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n", ++ flow_id, flags, rfi->cur_idx, rfi->exp_idx, ++ cur_idx, exp_idx); ++ if (flags & BRCMF_RXREORDER_FLUSH_ALL) ++ end_idx = rfi->exp_idx; ++ else ++ end_idx = exp_idx; ++ ++ /* flush pkts first */ ++ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, ++ &reorder_list); ++ ++ if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) { ++ __skb_queue_tail(&reorder_list, pkt); ++ } else { ++ rfi->pktslots[cur_idx] = pkt; ++ rfi->pend_pkts++; ++ } ++ rfi->exp_idx = exp_idx; ++ rfi->cur_idx = cur_idx; ++ } ++ } else { ++ /* explicity window move updating the expected index */ ++ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; ++ ++ brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n", ++ flow_id, flags, rfi->exp_idx, exp_idx); ++ if (flags & BRCMF_RXREORDER_FLUSH_ALL) ++ end_idx = rfi->exp_idx; ++ else ++ end_idx = exp_idx; ++ ++ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, ++ &reorder_list); ++ __skb_queue_tail(&reorder_list, pkt); ++ /* set the new expected idx */ ++ rfi->exp_idx = exp_idx; ++ } ++netif_rx: ++ skb_queue_walk_safe(&reorder_list, pkt, pnext) { ++ __skb_unlink(pkt, &reorder_list); ++ brcmf_netif_rx(ifp, pkt, false); ++ } ++} ++ + void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) + { + struct brcmf_skb_reorder_data *rd; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +@@ -29,5 +29,6 @@ void brcmf_fws_add_interface(struct brcm + void brcmf_fws_del_interface(struct brcmf_if *ifp); + void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb); + void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked); ++void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb); + + #endif /* FWSIGNAL_H_ */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -527,6 +527,9 @@ static int brcmf_msgbuf_hdrpull(struct b + return -ENODEV; + } + ++static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) ++{ ++} + + static void + brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid) +@@ -1466,6 +1469,7 @@ int brcmf_proto_msgbuf_attach(struct brc + drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode; + drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; + drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; ++ drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; + drvr->proto->pd = msgbuf; + + init_waitqueue_head(&msgbuf->ioctl_resp_wait); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +@@ -22,6 +22,9 @@ enum proto_addr_mode { + ADDR_DIRECT + }; + ++struct brcmf_skb_reorder_data { ++ u8 *reorder; ++}; + + struct brcmf_proto { + int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, +@@ -38,6 +41,7 @@ struct brcmf_proto { + u8 peer[ETH_ALEN]); + void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx, + u8 peer[ETH_ALEN]); ++ void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb); + void *pd; + }; + +@@ -91,6 +95,18 @@ brcmf_proto_add_tdls_peer(struct brcmf_p + { + drvr->proto->add_tdls_peer(drvr, ifidx, peer); + } ++static inline bool brcmf_proto_is_reorder_skb(struct sk_buff *skb) ++{ ++ struct brcmf_skb_reorder_data *rd; ++ ++ rd = (struct brcmf_skb_reorder_data *)skb->cb; ++ return !!rd->reorder; ++} + ++static inline void ++brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) ++{ ++ ifp->drvr->proto->rxreorder(ifp, skb); ++} + + #endif /* BRCMFMAC_PROTO_H */ diff --git a/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch b/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch new file mode 100644 index 0000000000..a43feffe17 --- /dev/null +++ b/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch @@ -0,0 +1,139 @@ +From: Arend van Spriel +Date: Mon, 11 Apr 2016 11:35:27 +0200 +Subject: [PATCH] brcmfmac: revise handling events in receive path + +Move event handling out of brcmf_netif_rx() avoiding the need +to pass a flag. This flag is only ever true for USB hosts as +other interface use separate brcmf_rx_event() function. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -216,7 +216,7 @@ bool brcmf_c_prec_enq(struct device *dev + int prec); + + /* Receive frame for delivery to OS. Callee disposes of rxp. */ +-void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt); ++void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event); + /* Receive async event packet from firmware. Callee disposes of rxp. */ + void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -298,18 +298,11 @@ void brcmf_txflowblock(struct device *de + brcmf_fws_bus_blocked(drvr, state); + } + +-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, +- bool handle_event) ++void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) + { +- skb->protocol = eth_type_trans(skb, ifp->ndev); +- + if (skb->pkt_type == PACKET_MULTICAST) + ifp->stats.multicast++; + +- /* Process special event packets */ +- if (handle_event) +- brcmf_fweh_process_skb(ifp->drvr, skb); +- + if (!(ifp->ndev->flags & IFF_UP)) { + brcmu_pkt_buf_free_skb(skb); + return; +@@ -329,7 +322,7 @@ void brcmf_netif_rx(struct brcmf_if *ifp + netif_rx_ni(skb); + } + +-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) ++void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) + { + struct brcmf_if *ifp; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); +@@ -348,10 +341,17 @@ void brcmf_rx_frame(struct device *dev, + return; + } + +- if (brcmf_proto_is_reorder_skb(skb)) ++ skb->protocol = eth_type_trans(skb, ifp->ndev); ++ ++ if (brcmf_proto_is_reorder_skb(skb)) { + brcmf_proto_rxreorder(ifp, skb); +- else +- brcmf_netif_rx(ifp, skb, handle_evnt); ++ } else { ++ /* Process special event packets */ ++ if (handle_event) ++ brcmf_fweh_process_skb(ifp->drvr, skb); ++ ++ brcmf_netif_rx(ifp, skb); ++ } + } + + void brcmf_rx_event(struct device *dev, struct sk_buff *skb) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -221,8 +221,7 @@ int brcmf_get_next_free_bsscfgidx(struct + void brcmf_txflowblock_if(struct brcmf_if *ifp, + enum brcmf_netif_stop_reason reason, bool state); + void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); +-void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, +- bool handle_event); ++void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); + void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); + int __init brcmf_core_init(void); + void __exit brcmf_core_exit(void); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -1668,7 +1668,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + /* validate flags and flow id */ + if (flags == 0xFF) { + brcmf_err("invalid flags...so ignore this packet\n"); +- brcmf_netif_rx(ifp, pkt, false); ++ brcmf_netif_rx(ifp, pkt); + return; + } + +@@ -1680,7 +1680,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + if (rfi == NULL) { + brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", + flow_id); +- brcmf_netif_rx(ifp, pkt, false); ++ brcmf_netif_rx(ifp, pkt); + return; + } + +@@ -1705,7 +1705,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + rfi = kzalloc(buf_size, GFP_ATOMIC); + if (rfi == NULL) { + brcmf_err("failed to alloc buffer\n"); +- brcmf_netif_rx(ifp, pkt, false); ++ brcmf_netif_rx(ifp, pkt); + return; + } + +@@ -1819,7 +1819,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + netif_rx: + skb_queue_walk_safe(&reorder_list, pkt, pnext) { + __skb_unlink(pkt, &reorder_list); +- brcmf_netif_rx(ifp, pkt, false); ++ brcmf_netif_rx(ifp, pkt); + } + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1157,7 +1157,7 @@ brcmf_msgbuf_process_rx_complete(struct + brcmu_pkt_buf_free_skb(skb); + return; + } +- brcmf_netif_rx(ifp, skb, false); ++ brcmf_netif_rx(ifp, skb); + } + + diff --git a/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch b/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch new file mode 100644 index 0000000000..08ea235fdd --- /dev/null +++ b/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch @@ -0,0 +1,88 @@ +From: Arend van Spriel +Date: Mon, 11 Apr 2016 11:35:28 +0200 +Subject: [PATCH] brcmfmac: create common function for handling + brcmf_proto_hdrpull() + +In receive path brcmf_proto_hdrpull() needs to be called and handled +similar in brcmf_rx_frame() and brcmf_rx_event(). Move that duplicated +code in separate function. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -322,26 +322,35 @@ void brcmf_netif_rx(struct brcmf_if *ifp + netif_rx_ni(skb); + } + +-void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) ++static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb, ++ struct brcmf_if **ifp) + { +- struct brcmf_if *ifp; +- struct brcmf_bus *bus_if = dev_get_drvdata(dev); +- struct brcmf_pub *drvr = bus_if->drvr; + int ret; + +- brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); +- + /* process and remove protocol-specific header */ +- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); ++ ret = brcmf_proto_hdrpull(drvr, true, skb, ifp); + +- if (ret || !ifp || !ifp->ndev) { ++ if (ret || !(*ifp) || !(*ifp)->ndev) { + if (ret != -ENODATA && ifp) +- ifp->stats.rx_errors++; ++ (*ifp)->stats.rx_errors++; + brcmu_pkt_buf_free_skb(skb); +- return; ++ return -ENODATA; + } + +- skb->protocol = eth_type_trans(skb, ifp->ndev); ++ skb->protocol = eth_type_trans(skb, (*ifp)->ndev); ++ return 0; ++} ++ ++void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) ++{ ++ struct brcmf_if *ifp; ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ ++ brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); ++ ++ if (brcmf_rx_hdrpull(drvr, skb, &ifp)) ++ return; + + if (brcmf_proto_is_reorder_skb(skb)) { + brcmf_proto_rxreorder(ifp, skb); +@@ -359,21 +368,11 @@ void brcmf_rx_event(struct device *dev, + struct brcmf_if *ifp; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; +- int ret; + + brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb); + +- /* process and remove protocol-specific header */ +- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); +- +- if (ret || !ifp || !ifp->ndev) { +- if (ret != -ENODATA && ifp) +- ifp->stats.rx_errors++; +- brcmu_pkt_buf_free_skb(skb); ++ if (brcmf_rx_hdrpull(drvr, skb, &ifp)) + return; +- } +- +- skb->protocol = eth_type_trans(skb, ifp->ndev); + + brcmf_fweh_process_skb(ifp->drvr, skb); + brcmu_pkt_buf_free_skb(skb); diff --git a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch b/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch index f242748723..c602f2272a 100644 --- a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch +++ b/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch @@ -76,7 +76,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -938,30 +938,6 @@ void brcmf_remove_interface(struct brcmf +@@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf brcmf_del_if(ifp->drvr, ifp->bsscfgidx); } @@ -109,7 +109,7 @@ Signed-off-by: Kalle Valo static int brcmf_inetaddr_changed(struct notifier_block *nb, --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -221,7 +221,6 @@ int brcmf_net_attach(struct brcmf_if *if +@@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *if struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); void brcmf_remove_interface(struct brcmf_if *ifp); diff --git a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch index 6f064d16ef..a79c9a2e93 100644 --- a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch +++ b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch @@ -54,7 +54,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(CONN, "capability: %X\n", notify_capability); brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); brcmf_dbg(CONN, "signal: %d\n", notify_signal); -@@ -5234,7 +5234,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 +@@ -5235,7 +5235,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 else band = wiphy->bands[IEEE80211_BAND_5GHZ]; @@ -63,7 +63,7 @@ Signed-off-by: Kalle Valo notify_channel = ieee80211_get_channel(wiphy, freq); done: -@@ -5756,14 +5756,15 @@ static int brcmf_construct_chaninfo(stru +@@ -5757,14 +5757,15 @@ static int brcmf_construct_chaninfo(stru channel = band->channels; index = band->n_channels; for (j = 0; j < band->n_channels; j++) { @@ -82,7 +82,7 @@ Signed-off-by: Kalle Valo /* assuming the chanspecs order is HT20, * HT40 upper, HT40 lower, and VHT80. -@@ -5865,7 +5866,7 @@ static int brcmf_enable_bw40_2g(struct b +@@ -5866,7 +5867,7 @@ static int brcmf_enable_bw40_2g(struct b if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) continue; for (j = 0; j < band->n_channels; j++) { diff --git a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch b/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch index 3e16c4bfc7..2c536d178d 100644 --- a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch +++ b/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch @@ -15,7 +15,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4846,6 +4846,68 @@ exit: +@@ -4847,6 +4847,68 @@ exit: return err; } @@ -84,7 +84,7 @@ Signed-off-by: Kalle Valo static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, struct wireless_dev *wdev, enum nl80211_crit_proto_id proto, -@@ -5008,6 +5070,7 @@ static struct cfg80211_ops brcmf_cfg8021 +@@ -5009,6 +5071,7 @@ static struct cfg80211_ops brcmf_cfg8021 .mgmt_tx = brcmf_cfg80211_mgmt_tx, .remain_on_channel = brcmf_p2p_remain_on_channel, .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, diff --git a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch index bf06a767d4..a2e18a5fe9 100644 --- a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch +++ b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch @@ -32,7 +32,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4381,7 +4381,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4382,7 +4382,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi struct brcmf_join_params join_params; enum nl80211_iftype dev_role; struct brcmf_fil_bss_enable_le bss_enable; @@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo bool mbss; int is_11d; -@@ -4457,16 +4457,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4458,16 +4458,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); @@ -59,7 +59,7 @@ Signed-off-by: Kalle Valo if (is_11d != ifp->vif->is_11d) { err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, is_11d); -@@ -4514,6 +4506,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4515,6 +4507,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi err = -EINVAL; goto exit; } @@ -68,7 +68,7 @@ Signed-off-by: Kalle Valo if (dev_role == NL80211_IFTYPE_AP) { if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) brcmf_fil_iovar_int_set(ifp, "mbss", 1); -@@ -4523,6 +4517,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4524,6 +4518,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_err("setting AP mode failed %d\n", err); goto exit; } @@ -86,7 +86,7 @@ Signed-off-by: Kalle Valo err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); if (err < 0) { brcmf_err("BRCMF_C_UP error (%d)\n", err); -@@ -4544,7 +4549,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4545,7 +4550,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi goto exit; } brcmf_dbg(TRACE, "AP mode configuration complete\n"); @@ -101,7 +101,7 @@ Signed-off-by: Kalle Valo err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le, sizeof(ssid_le)); if (err < 0) { -@@ -4561,7 +4572,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4562,7 +4573,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi } brcmf_dbg(TRACE, "GO mode configuration complete\n"); diff --git a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch index 6ef145338c..167e4347d5 100644 --- a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch +++ b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch @@ -41,7 +41,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -5371,7 +5371,6 @@ brcmf_notify_connect_status_ap(struct br +@@ -5372,7 +5372,6 @@ brcmf_notify_connect_status_ap(struct br struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { @@ -49,7 +49,7 @@ Signed-off-by: Kalle Valo static int generation; u32 event = e->event_code; u32 reason = e->reason; -@@ -5382,8 +5381,6 @@ brcmf_notify_connect_status_ap(struct br +@@ -5383,8 +5382,6 @@ brcmf_notify_connect_status_ap(struct br ndev != cfg_to_ndev(cfg)) { brcmf_dbg(CONN, "AP mode link down\n"); complete(&cfg->vif_disabled); diff --git a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch index dd1b490e1f..28ef3a65fd 100644 --- a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch +++ b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch @@ -24,7 +24,7 @@ Signed-off-by: Kalle Valo if (IS_ERR(vif)) return (struct wireless_dev *)vif; -@@ -5097,8 +5097,7 @@ static struct cfg80211_ops brcmf_cfg8021 +@@ -5098,8 +5098,7 @@ static struct cfg80211_ops brcmf_cfg8021 }; struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, @@ -34,7 +34,7 @@ Signed-off-by: Kalle Valo { struct brcmf_cfg80211_vif *vif_walk; struct brcmf_cfg80211_vif *vif; -@@ -5113,8 +5112,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v +@@ -5114,8 +5113,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v vif->wdev.wiphy = cfg->wiphy; vif->wdev.iftype = type; @@ -43,7 +43,7 @@ Signed-off-by: Kalle Valo brcmf_init_prof(&vif->profile); if (type == NL80211_IFTYPE_AP) { -@@ -6753,7 +6750,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 +@@ -6754,7 +6751,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 init_vif_event(&cfg->vif_event); INIT_LIST_HEAD(&cfg->vif_list); diff --git a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch index e80ca8da0e..461e3dba53 100644 --- a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch +++ b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch @@ -23,7 +23,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6207,29 +6207,15 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6208,29 +6208,15 @@ static int brcmf_setup_ifmodes(struct wi if (!combo) goto err; @@ -56,7 +56,7 @@ Signed-off-by: Kalle Valo c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); if (p2p) { -@@ -6247,6 +6233,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6248,6 +6234,7 @@ static int brcmf_setup_ifmodes(struct wi c0_limits[i].max = 1; c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); } @@ -64,7 +64,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = c0_limits; -@@ -6254,7 +6241,9 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6255,7 +6242,9 @@ static int brcmf_setup_ifmodes(struct wi if (p2p) { c++; i = 0; @@ -75,7 +75,7 @@ Signed-off-by: Kalle Valo p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); p2p_limits[i].max = 1; -@@ -6263,6 +6252,7 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6264,6 +6253,7 @@ static int brcmf_setup_ifmodes(struct wi p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); p2p_limits[i].max = 1; p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); @@ -83,7 +83,7 @@ Signed-off-by: Kalle Valo combo[c].max_interfaces = i; combo[c].n_limits = i; combo[c].limits = p2p_limits; -@@ -6270,14 +6260,19 @@ static int brcmf_setup_ifmodes(struct wi +@@ -6271,14 +6261,19 @@ static int brcmf_setup_ifmodes(struct wi if (mbss) { c++; diff --git a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch index e870cc7572..e991f32327 100644 --- a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch +++ b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch @@ -29,7 +29,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -733,12 +733,16 @@ fail: +@@ -548,12 +548,16 @@ fail: return -EBADE; } @@ -50,7 +50,7 @@ Signed-off-by: Kalle Valo } void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on) -@@ -836,7 +840,7 @@ struct brcmf_if *brcmf_add_if(struct brc +@@ -651,7 +655,7 @@ struct brcmf_if *brcmf_add_if(struct brc brcmf_err("ERROR: netdev:%s already exists\n", ifp->ndev->name); netif_stop_queue(ifp->ndev); @@ -59,7 +59,7 @@ Signed-off-by: Kalle Valo drvr->iflist[bsscfgidx] = NULL; } else { brcmf_dbg(INFO, "netdev:%s ignore IF event\n", -@@ -884,7 +888,8 @@ struct brcmf_if *brcmf_add_if(struct brc +@@ -699,7 +703,8 @@ struct brcmf_if *brcmf_add_if(struct brc return ifp; } @@ -69,7 +69,7 @@ Signed-off-by: Kalle Valo { struct brcmf_if *ifp; -@@ -914,7 +919,7 @@ static void brcmf_del_if(struct brcmf_pu +@@ -729,7 +734,7 @@ static void brcmf_del_if(struct brcmf_pu cancel_work_sync(&ifp->multicast_work); cancel_work_sync(&ifp->ndoffload_work); } @@ -78,7 +78,7 @@ Signed-off-by: Kalle Valo } else { /* Only p2p device interfaces which get dynamically created * end up here. In this case the p2p module should be informed -@@ -928,14 +933,14 @@ static void brcmf_del_if(struct brcmf_pu +@@ -743,14 +748,14 @@ static void brcmf_del_if(struct brcmf_pu } } @@ -95,7 +95,7 @@ Signed-off-by: Kalle Valo } #ifdef CONFIG_INET -@@ -1242,9 +1247,9 @@ fail: +@@ -1057,9 +1062,9 @@ fail: brcmf_fws_deinit(drvr); } if (ifp) @@ -107,7 +107,7 @@ Signed-off-by: Kalle Valo drvr->iflist[0] = NULL; drvr->iflist[1] = NULL; if (drvr->settings->ignore_probe_fail) -@@ -1313,7 +1318,7 @@ void brcmf_detach(struct device *dev) +@@ -1128,7 +1133,7 @@ void brcmf_detach(struct device *dev) /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS-1; i > -1; i--) @@ -118,7 +118,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -220,7 +220,7 @@ struct brcmf_if *brcmf_get_ifp(struct br +@@ -216,7 +216,7 @@ struct brcmf_if *brcmf_get_ifp(struct br int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); diff --git a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch index 75f9aae73a..ed65f4dc88 100644 --- a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch +++ b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch @@ -17,7 +17,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -823,7 +823,7 @@ fail: +@@ -638,7 +638,7 @@ fail: } struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, @@ -28,7 +28,7 @@ Signed-off-by: Kalle Valo struct net_device *ndev; --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -219,7 +219,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) +@@ -215,7 +215,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, diff --git a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch index 6a18bafc80..ae458e7a02 100644 --- a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch +++ b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch @@ -14,7 +14,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4585,6 +4585,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi +@@ -4586,6 +4586,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi brcmf_err("SET SSID error (%d)\n", err); goto exit; } @@ -30,7 +30,7 @@ Signed-off-by: Kalle Valo brcmf_dbg(TRACE, "AP mode configuration complete\n"); } else if (dev_role == NL80211_IFTYPE_P2P_GO) { err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); -@@ -4643,6 +4652,10 @@ static int brcmf_cfg80211_stop_ap(struct +@@ -4644,6 +4653,10 @@ static int brcmf_cfg80211_stop_ap(struct return err; } diff --git a/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch b/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch index 555186d626..fcafa797ef 100644 --- a/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch +++ b/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch @@ -23,7 +23,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c -@@ -2260,10 +2260,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw +@@ -2469,10 +2469,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked) { struct brcmf_fws_info *fws = drvr->fws; diff --git a/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch b/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch new file mode 100644 index 0000000000..e2653542de --- /dev/null +++ b/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch @@ -0,0 +1,26 @@ +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Subject: [PATCH] brcmfmac: add missing eth_type_trans call +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are 2 protocols supported by brcmfmac and msgbuf one was missing a +proper skb setup before passing it to the netif. This was triggering +"NULL pointer dereference". + +Fixes: 9c349892ccc9 ("brcmfmac: revise handling events in receive path") +Signed-off-by: Rafał Miłecki +--- + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1157,6 +1157,9 @@ brcmf_msgbuf_process_rx_complete(struct + brcmu_pkt_buf_free_skb(skb); + return; + } ++ ++ skb->protocol = eth_type_trans(skb, ifp->ndev); ++ + brcmf_netif_rx(ifp, skb); + } + diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch index 9850e2dad3..ae571c99ab 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1398,6 +1398,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; -- cgit v1.2.3 From f9755e28776fdce0c2136492b43380d0eefe3c5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 29 Sep 2016 14:59:38 +0200 Subject: mac80211: brcmfmac: backport changes from 2016-09-27 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes memory leaks, some possible crashes and bug that could cause WARNING on every add_key/del_key call. It also replaces WARNING with a simple message. They may still occur e.g. on station going out of range and A-MPDU stall in the firmware. Signed-off-by: Rafał Miłecki --- ...rcmfmac-defer-DPC-processing-during-probe.patch | 42 +++++ ...x-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch | 32 ++++ ...s-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch | 34 ++++ ...eck-rtnl_lock-is-locked-when-removing-int.patch | 111 +++++++++++++ ...rcmfmac-Change-vif_event_lock-to-spinlock.patch | 175 +++++++++++++++++++++ ...-brcmfmac-add-missing-header-dependencies.patch | 29 ++++ ...mfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch | 51 ++++++ .../351-0035-brcmfmac-fix-pmksa-bssid-usage.patch | 51 ++++++ ...oid-potential-stack-overflow-in-brcmf_cfg.patch | 34 ++++ ...d-support-for-bcm4339-chip-with-modalias-.patch | 55 +++++++ ...io-shorten-retry-loop-in-brcmf_sdio_kso_c.patch | 56 +++++++ ...-brcmfmac-ignore-11d-configuration-errors.patch | 84 ++++++++++ ...work-pointer-trickery-in-brcmf_proto_bcdc.patch | 32 ++++ ...x-memory-leak-in-brcmf_flowring_add_tdls_.patch | 39 +++++ ...-initialize-variable-in-brcmf_sdiod_regrl.patch | 28 ++++ ...move-worker-from-.ndo_set_mac_address-cal.patch | 107 +++++++++++++ ...mac-remove-unnecessary-null-pointer-check.patch | 31 ++++ ...-brcmfmac-fix-clearing-entry-IPv6-address.patch | 37 +++++ ...x-out-of-bound-access-on-clearing-wowl-wa.patch | 44 ++++++ ...47-brcmfmac-simplify-mapping-of-auth-type.patch | 39 +++++ ...c-fix-memory-leak-in-brcmf_fill_bss_param.patch | 41 +++++ ...-drop-unused-fields-from-struct-brcmf_pub.patch | 60 +++++++ ...place-WARNING-on-timeout-with-a-simple-er.patch | 38 +++++ ...e-correct-skb-freeing-helper-when-deletin.patch | 58 +++++++ ...mfmac-register-wiphy-s-during-module_init.patch | 2 +- 25 files changed, 1309 insertions(+), 1 deletion(-) create mode 100644 package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch create mode 100644 package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch create mode 100644 package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch create mode 100644 package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch create mode 100644 package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch create mode 100644 package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch create mode 100644 package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch create mode 100644 package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch create mode 100644 package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch create mode 100644 package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch create mode 100644 package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch create mode 100644 package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch create mode 100644 package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch create mode 100644 package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch create mode 100644 package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch create mode 100644 package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch create mode 100644 package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch create mode 100644 package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch create mode 100644 package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch create mode 100644 package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch create mode 100644 package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch create mode 100644 package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch create mode 100644 package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch create mode 100644 package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch diff --git a/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch b/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch new file mode 100644 index 0000000000..a24c07f973 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch @@ -0,0 +1,42 @@ +From fd3ed33f51c2a586412d35b4f64803f019ab589f Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Fri, 15 Jul 2016 12:39:13 +0200 +Subject: [PATCH] brcmfmac: defer DPC processing during probe + +The sdio dpc starts processing when in SDIOD_STATE_DATA. This state was +entered right after firmware download. This patch moves that transition +just before enabling sdio interrupt handling thus avoiding watchdog +expiry which would put the bus to sleep while probing. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3304,10 +3304,6 @@ static int brcmf_sdio_download_firmware( + goto err; + } + +- /* Allow full data communication using DPC from now on. */ +- brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); +- bcmerror = 0; +- + err: + brcmf_sdio_clkctl(bus, CLK_SDONLY, false); + sdio_release_host(bus->sdiodev->func[1]); +@@ -4045,6 +4041,9 @@ static void brcmf_sdio_firmware_callback + } + + if (err == 0) { ++ /* Allow full data communication using DPC from now on. */ ++ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); ++ + err = brcmf_sdiod_intr_register(sdiodev); + if (err != 0) + brcmf_err("intr register failed:%d\n", err); diff --git a/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch b/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch new file mode 100644 index 0000000000..ba9a349f0f --- /dev/null +++ b/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch @@ -0,0 +1,32 @@ +From 3bdae810721b33061d2e541bd78a70f86ca42af3 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli +Date: Mon, 18 Jul 2016 16:24:34 -0700 +Subject: [PATCH] brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain + +In case brcmf_sdiod_recv_chain() cannot complete a succeful call to +brcmf_sdiod_buffrw, we would be leaking glom_skb and not free it as we +should, fix this. + +Reported-by: coverity (CID 1164856) +Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support") +Signed-off-by: Florian Fainelli +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -722,8 +722,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_ + return -ENOMEM; + err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, + glom_skb); +- if (err) ++ if (err) { ++ brcmu_pkt_buf_free_skb(glom_skb); + goto done; ++ } + + skb_queue_walk(pktq, skb) { + memcpy(skb->data, glom_skb->data, skb->len); diff --git a/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch b/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch new file mode 100644 index 0000000000..540b7f08bf --- /dev/null +++ b/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch @@ -0,0 +1,34 @@ +From 938f89e50a41c2d56710805fb019ad7618cef84b Mon Sep 17 00:00:00 2001 +From: Wolfram Sang +Date: Thu, 11 Aug 2016 23:05:31 +0200 +Subject: [PATCH] net: wireless: broadcom: brcm80211: brcmfmac: usb: don't + print error when allocating urb fails + +kmalloc will print enough information in case of failure. + +Signed-off-by: Wolfram Sang +Signed-off-by: David S. Miller +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1099,15 +1099,11 @@ struct brcmf_usbdev *brcmf_usb_attach(st + devinfo->tx_freecount = ntxq; + + devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC); +- if (!devinfo->ctl_urb) { +- brcmf_err("usb_alloc_urb (ctl) failed\n"); ++ if (!devinfo->ctl_urb) + goto error; +- } + devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); +- if (!devinfo->bulk_urb) { +- brcmf_err("usb_alloc_urb (bulk) failed\n"); ++ if (!devinfo->bulk_urb) + goto error; +- } + + return &devinfo->bus_pub; + diff --git a/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch b/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch new file mode 100644 index 0000000000..b98b68a88a --- /dev/null +++ b/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch @@ -0,0 +1,111 @@ +From 15dacf880e49ce3ecee05eb1a0c6b8e363dbacdc Mon Sep 17 00:00:00 2001 +From: "mhiramat@kernel.org" +Date: Mon, 15 Aug 2016 18:40:57 +0900 +Subject: [PATCH] brcmfmac: Check rtnl_lock is locked when removing interface +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check rtnl_lock is locked in brcmf_p2p_ifp_removed() by passing +rtnl_locked flag. Actually the caller brcmf_del_if() checks whether +the rtnl_lock is locked, but doesn't pass it to brcmf_p2p_ifp_removed(). + +Without this fix, wpa_supplicant goes softlockup with rtnl_lock +holding (this means all other process using netlink are locked up too) + +e.g. +[ 4495.876627] INFO: task wpa_supplicant:7307 blocked for more than 10 seconds. +[ 4495.876632] Tainted: G W 4.8.0-rc1+ #8 +[ 4495.876635] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 4495.876638] wpa_supplicant D ffff974c647b39a0 0 7307 1 0x00000000 +[ 4495.876644] ffff974c647b39a0 0000000000000000 ffff974c00000000 ffff974c7dc59c58 +[ 4495.876651] ffff974c6b7417c0 ffff974c645017c0 ffff974c647b4000 ffffffff86f16c08 +[ 4495.876657] ffff974c645017c0 0000000000000246 00000000ffffffff ffff974c647b39b8 +[ 4495.876664] Call Trace: +[ 4495.876671] [] schedule+0x3c/0x90 +[ 4495.876676] [] schedule_preempt_disabled+0x15/0x20 +[ 4495.876682] [] mutex_lock_nested+0x176/0x3b0 +[ 4495.876686] [] ? rtnl_lock+0x17/0x20 +[ 4495.876690] [] rtnl_lock+0x17/0x20 +[ 4495.876720] [] brcmf_p2p_ifp_removed+0x4d/0x70 [brcmfmac] +[ 4495.876741] [] brcmf_remove_interface+0x196/0x1b0 [brcmfmac] +[ 4495.876760] [] brcmf_p2p_del_vif+0x111/0x220 [brcmfmac] +[ 4495.876777] [] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac] +[ 4495.876820] [] nl80211_del_interface+0xfe/0x3a0 [cfg80211] +[ 4495.876825] [] genl_family_rcv_msg+0x1b5/0x370 +[ 4495.876832] [] ? trace_hardirqs_on+0xd/0x10 +[ 4495.876836] [] genl_rcv_msg+0x7d/0xb0 +[ 4495.876839] [] ? genl_family_rcv_msg+0x370/0x370 +[ 4495.876846] [] netlink_rcv_skb+0x97/0xb0 +[ 4495.876849] [] genl_rcv+0x28/0x40 +[ 4495.876854] [] netlink_unicast+0x1d3/0x2f0 +[ 4495.876860] [] ? netlink_unicast+0x14b/0x2f0 +[ 4495.876866] [] netlink_sendmsg+0x2eb/0x3a0 +[ 4495.876870] [] sock_sendmsg+0x38/0x50 +[ 4495.876874] [] ___sys_sendmsg+0x27f/0x290 +[ 4495.876882] [] ? mntput_no_expire+0x5/0x3f0 +[ 4495.876888] [] ? mntput_no_expire+0x8e/0x3f0 +[ 4495.876894] [] ? mntput_no_expire+0x5/0x3f0 +[ 4495.876899] [] ? mntput+0x24/0x40 +[ 4495.876904] [] ? __fput+0x190/0x200 +[ 4495.876909] [] __sys_sendmsg+0x45/0x80 +[ 4495.876914] [] SyS_sendmsg+0x12/0x20 +[ 4495.876918] [] entry_SYSCALL_64_fastpath+0x23/0xc1 +[ 4495.876924] [] ? trace_hardirqs_off_caller+0x1f/0xc0 + +Signed-off-by: Masami Hiramatsu +Acked-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 8 +++++--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 +- + 3 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -743,7 +743,7 @@ static void brcmf_del_if(struct brcmf_pu + * serious troublesome side effects. The p2p module will clean + * up the ifp if needed. + */ +- brcmf_p2p_ifp_removed(ifp); ++ brcmf_p2p_ifp_removed(ifp, rtnl_locked); + kfree(ifp); + } + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -2299,7 +2299,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph + return err; + } + +-void brcmf_p2p_ifp_removed(struct brcmf_if *ifp) ++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked) + { + struct brcmf_cfg80211_info *cfg; + struct brcmf_cfg80211_vif *vif; +@@ -2308,9 +2308,11 @@ void brcmf_p2p_ifp_removed(struct brcmf_ + vif = ifp->vif; + cfg = wdev_to_cfg(&vif->wdev); + cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; +- rtnl_lock(); ++ if (!rtnl_locked) ++ rtnl_lock(); + cfg80211_unregister_wdev(&vif->wdev); +- rtnl_unlock(); ++ if (!rtnl_locked) ++ rtnl_unlock(); + brcmf_free_vif(vif); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +@@ -155,7 +155,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); + int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg, + enum brcmf_fil_p2p_if_types if_type); +-void brcmf_p2p_ifp_removed(struct brcmf_if *ifp); ++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked); + int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev); + void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev); + int brcmf_p2p_scan_prep(struct wiphy *wiphy, diff --git a/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch b/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch new file mode 100644 index 0000000000..30ca25897d --- /dev/null +++ b/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch @@ -0,0 +1,175 @@ +From b64abcb7dae6060c67ab0e548da3ef923c49641d Mon Sep 17 00:00:00 2001 +From: "mhiramat@kernel.org" +Date: Mon, 15 Aug 2016 18:41:12 +0900 +Subject: [PATCH] brcmfmac: Change vif_event_lock to spinlock + +Change vif_event_lock to spinlock from mutex, since this lock is +used in wait_event_timeout() via vif_event_equals(). This caused +a warning report as below. + +As far as I can see, this lock protects regions where updating +structure members, not function calls. Also, since those +regions are not called from interrupt handlers (of course, it +was a mutex), spin_lock is used instead of spin_lock_irqsave. + +[ 186.678550] ------------[ cut here ]------------ +[ 186.678556] WARNING: CPU: 2 PID: 7140 at /home/mhiramat/ksrc/linux/kernel/sched/core.c:7545 __might_sleep+0x7c/0x80 +[ 186.678560] do not call blocking ops when !TASK_RUNNING; state=2 set at [] prepare_to_wait_event+0x60/0x100 +[ 186.678560] Modules linked in: brcmfmac xt_CHECKSUM rfcomm ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype br_netfilter xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_raw ip6table_security ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_filter ip6_tables iptable_raw iptable_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter ip_tables x_tables bnep nls_iso8859_1 i2c_designware_platform i2c_designware_core snd_hda_codec_hdmi snd_hda_codec_realtek dcdbas snd_hda_codec_generic snd_hda_intel snd_hda_codec intel_rapl snd_hda_core x86_pkg_temp_thermal intel_powerclamp coretemp +[ 186.678594] snd_pcm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 joydev glue_helper snd_hwdep lrw gf128mul uvcvideo ablk_helper snd_seq_midi cryptd snd_seq_midi_event snd_rawmidi videobuf2_vmalloc videobuf2_memops snd_seq input_leds videobuf2_v4l2 cfg80211 videobuf2_core snd_timer videodev serio_raw btusb snd_seq_device media btrtl rtsx_pci_ms snd mei_me memstick hid_multitouch mei soundcore brcmutil idma64 virt_dma intel_lpss_pci processor_thermal_device intel_soc_dts_iosf hci_uart btbcm btqca btintel bluetooth int3403_thermal dell_smo8800 intel_lpss_acpi intel_lpss int3402_thermal int340x_thermal_zone intel_hid mac_hid int3400_thermal shpchp sparse_keymap acpi_pad acpi_thermal_rel acpi_als kfifo_buf industrialio kvm_intel kvm irqbypass parport_pc ppdev lp parport autofs4 btrfs xor raid6_pq +[ 186.678631] usbhid nouveau ttm i915 rtsx_pci_sdmmc mxm_wmi i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops psmouse drm ahci rtsx_pci nvme nvme_core libahci i2c_hid hid pinctrl_sunrisepoint video wmi pinctrl_intel fjes [last unloaded: brcmfmac] +[ 186.678646] CPU: 2 PID: 7140 Comm: wpa_supplicant Not tainted 4.8.0-rc1+ #8 +[ 186.678647] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 01.02.00 04/07/2016 +[ 186.678648] 0000000000000000 ffff9d8c64b5b900 ffffffff98442f23 ffff9d8c64b5b950 +[ 186.678651] 0000000000000000 ffff9d8c64b5b940 ffffffff9808b22b 00001d790000000d +[ 186.678653] ffffffff98c75e78 000000000000026c 0000000000000000 ffff9d8c2706d058 +[ 186.678655] Call Trace: +[ 186.678659] [] dump_stack+0x85/0xc2 +[ 186.678666] [] __warn+0xcb/0xf0 +[ 186.678668] [] warn_slowpath_fmt+0x4f/0x60 +[ 186.678671] [] ? prepare_to_wait_event+0x60/0x100 +[ 186.678672] [] ? prepare_to_wait_event+0x60/0x100 +[ 186.678674] [] __might_sleep+0x7c/0x80 +[ 186.678680] [] mutex_lock_nested+0x33/0x3b0 +[ 186.678682] [] ? trace_hardirqs_on+0xd/0x10 +[ 186.678689] [] brcmf_cfg80211_wait_vif_event+0xcd/0x130 [brcmfmac] +[ 186.678691] [] ? wake_atomic_t_function+0x60/0x60 +[ 186.678697] [] brcmf_p2p_del_vif+0xf9/0x220 [brcmfmac] +[ 186.678702] [] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac] +[ 186.678716] [] nl80211_del_interface+0xfe/0x3a0 [cfg80211] +[ 186.678718] [] genl_family_rcv_msg+0x1b5/0x370 +[ 186.678720] [] ? trace_hardirqs_on+0xd/0x10 +[ 186.678721] [] genl_rcv_msg+0x7d/0xb0 +[ 186.678722] [] ? genl_family_rcv_msg+0x370/0x370 +[ 186.678724] [] netlink_rcv_skb+0x97/0xb0 +[ 186.678726] [] genl_rcv+0x28/0x40 +[ 186.678727] [] netlink_unicast+0x1d3/0x2f0 +[ 186.678729] [] ? netlink_unicast+0x14b/0x2f0 +[ 186.678731] [] netlink_sendmsg+0x2eb/0x3a0 +[ 186.678733] [] sock_sendmsg+0x38/0x50 +[ 186.678734] [] ___sys_sendmsg+0x27f/0x290 +[ 186.678737] [] ? mntput_no_expire+0x5/0x3f0 +[ 186.678739] [] ? mntput_no_expire+0x8e/0x3f0 +[ 186.678741] [] ? mntput_no_expire+0x5/0x3f0 +[ 186.678743] [] ? mntput+0x24/0x40 +[ 186.678744] [] ? __fput+0x190/0x200 +[ 186.678746] [] __sys_sendmsg+0x45/0x80 +[ 186.678748] [] SyS_sendmsg+0x12/0x20 +[ 186.678749] [] entry_SYSCALL_64_fastpath+0x23/0xc1 +[ 186.678751] [] ? trace_hardirqs_off_caller+0x1f/0xc0 +[ 186.678752] ---[ end trace e224d66c5d8408b5 ]--- + +Signed-off-by: Masami Hiramatsu +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++----------- + .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +- + 2 files changed, 14 insertions(+), 14 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5555,7 +5555,7 @@ static s32 brcmf_notify_vif_event(struct + ifevent->action, ifevent->flags, ifevent->ifidx, + ifevent->bsscfgidx); + +- mutex_lock(&event->vif_event_lock); ++ spin_lock(&event->vif_event_lock); + event->action = ifevent->action; + vif = event->vif; + +@@ -5563,7 +5563,7 @@ static s32 brcmf_notify_vif_event(struct + case BRCMF_E_IF_ADD: + /* waiting process may have timed out */ + if (!cfg->vif_event.vif) { +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + return -EBADF; + } + +@@ -5574,24 +5574,24 @@ static s32 brcmf_notify_vif_event(struct + ifp->ndev->ieee80211_ptr = &vif->wdev; + SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); + } +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + wake_up(&event->vif_wq); + return 0; + + case BRCMF_E_IF_DEL: +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + /* event may not be upon user request */ + if (brcmf_cfg80211_vif_event_armed(cfg)) + wake_up(&event->vif_wq); + return 0; + + case BRCMF_E_IF_CHANGE: +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + wake_up(&event->vif_wq); + return 0; + + default: +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + break; + } + return -EINVAL; +@@ -5712,7 +5712,7 @@ static void wl_deinit_priv(struct brcmf_ + static void init_vif_event(struct brcmf_cfg80211_vif_event *event) + { + init_waitqueue_head(&event->vif_wq); +- mutex_init(&event->vif_event_lock); ++ spin_lock_init(&event->vif_event_lock); + } + + static s32 brcmf_dongle_roam(struct brcmf_if *ifp) +@@ -6607,9 +6607,9 @@ static inline bool vif_event_equals(stru + { + u8 evt_action; + +- mutex_lock(&event->vif_event_lock); ++ spin_lock(&event->vif_event_lock); + evt_action = event->action; +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + return evt_action == action; + } + +@@ -6618,10 +6618,10 @@ void brcmf_cfg80211_arm_vif_event(struct + { + struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; + +- mutex_lock(&event->vif_event_lock); ++ spin_lock(&event->vif_event_lock); + event->vif = vif; + event->action = 0; +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + } + + bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg) +@@ -6629,9 +6629,9 @@ bool brcmf_cfg80211_vif_event_armed(stru + struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; + bool armed; + +- mutex_lock(&event->vif_event_lock); ++ spin_lock(&event->vif_event_lock); + armed = event->vif != NULL; +- mutex_unlock(&event->vif_event_lock); ++ spin_unlock(&event->vif_event_lock); + + return armed; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +@@ -227,7 +227,7 @@ struct escan_info { + */ + struct brcmf_cfg80211_vif_event { + wait_queue_head_t vif_wq; +- struct mutex vif_event_lock; ++ spinlock_t vif_event_lock; + u8 action; + struct brcmf_cfg80211_vif *vif; + }; diff --git a/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch b/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch new file mode 100644 index 0000000000..1a7947b39a --- /dev/null +++ b/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch @@ -0,0 +1,29 @@ +From 8af92af3f2d55db143417a5d401696f4b642009a Mon Sep 17 00:00:00 2001 +From: Baoyou Xie +Date: Mon, 29 Aug 2016 20:39:35 +0800 +Subject: [PATCH] brcmfmac: add missing header dependencies + +We get 1 warning when building kernel with W=1: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c:23:6: warning: no previous prototype for '__brcmf_err' [-Wmissing-prototypes] + +In fact, this function is declared in brcmfmac/debug.h, so this patch +adds missing header dependencies. + +Signed-off-by: Baoyou Xie +Acked-by: Arnd Bergmann +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c +@@ -19,6 +19,7 @@ + #ifndef __CHECKER__ + #define CREATE_TRACE_POINTS + #include "tracepoint.h" ++#include "debug.h" + + void __brcmf_err(const char *func, const char *fmt, ...) + { diff --git a/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch b/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch new file mode 100644 index 0000000000..24cd92a8be --- /dev/null +++ b/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch @@ -0,0 +1,51 @@ +From bccf3ffc8c6d8e0251a15541bb4d12b423c4f729 Mon Sep 17 00:00:00 2001 +From: Ismael Luceno +Date: Mon, 22 Aug 2016 19:40:07 -0300 +Subject: [PATCH] brcmfmac: Add USB ID for Cisco Linksys AE1200 + +The AE1200 comes with different revisions of the BCM43235 chipset, +but all have the same USB ID. Only revision 3 can be supported. + +Signed-off-by: Ismael Luceno +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 4 ++++ + drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++ + 2 files changed, 6 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -1456,11 +1456,15 @@ static int brcmf_usb_reset_resume(struct + #define BRCMF_USB_DEVICE(dev_id) \ + { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) } + ++#define LINKSYS_USB_DEVICE(dev_id) \ ++ { USB_DEVICE(BRCM_USB_VENDOR_ID_LINKSYS, dev_id) } ++ + static struct usb_device_id brcmf_usb_devid_table[] = { + BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID), + BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID), ++ LINKSYS_USB_DEVICE(BRCM_USB_43235_LINKSYS_DEVICE_ID), + { USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) }, + /* special entry for device with firmware loaded and running */ + BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID), +--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h ++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h +@@ -22,6 +22,7 @@ + + #define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c + #define BRCM_USB_VENDOR_ID_LG 0x043e ++#define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1 + #define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM + + /* Chipcommon Core Chip IDs */ +@@ -56,6 +57,7 @@ + + /* USB Device IDs */ + #define BRCM_USB_43143_DEVICE_ID 0xbd1e ++#define BRCM_USB_43235_LINKSYS_DEVICE_ID 0x0039 + #define BRCM_USB_43236_DEVICE_ID 0xbd17 + #define BRCM_USB_43242_DEVICE_ID 0xbd1f + #define BRCM_USB_43242_LG_DEVICE_ID 0x3101 diff --git a/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch b/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch new file mode 100644 index 0000000000..b58a266a25 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch @@ -0,0 +1,51 @@ +From 7703773ef1d85b40433902a8da20167331597e4a Mon Sep 17 00:00:00 2001 +From: Nicolas Iooss +Date: Tue, 23 Aug 2016 11:37:17 +0200 +Subject: [PATCH] brcmfmac: fix pmksa->bssid usage + +The struct cfg80211_pmksa defines its bssid field as: + + const u8 *bssid; + +contrary to struct brcmf_pmksa, which uses: + + u8 bssid[ETH_ALEN]; + +Therefore in brcmf_cfg80211_del_pmksa(), &pmksa->bssid takes the address +of this field (of type u8**), not the one of its content (which would be +u8*). Remove the & operator to make brcmf_dbg("%pM") and memcmp() +behave as expected. + +This bug have been found using a custom static checker (which checks the +usage of %p... attributes at build time). It has been introduced in +commit 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code"), +which replaced pmksa->bssid by &pmksa->bssid while refactoring the code, +without modifying struct cfg80211_pmksa definition. + +Replace &pmk[i].bssid with pmk[i].bssid too to make the code clearer, +this change does not affect the semantic. + +Fixes: 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code") +Cc: stable@vger.kernel.org +Signed-off-by: Nicolas Iooss +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3804,11 +3804,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w + if (!check_vif_up(ifp->vif)) + return -EIO; + +- brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid); ++ brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid); + + npmk = le32_to_cpu(cfg->pmk_list.npmk); + for (i = 0; i < npmk; i++) +- if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN)) ++ if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN)) + break; + + if ((npmk > 0) && (i < npmk)) { diff --git a/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch b/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch new file mode 100644 index 0000000000..760b6daf25 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch @@ -0,0 +1,34 @@ +From ded89912156b1a47d940a0c954c43afbabd0c42c Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 5 Sep 2016 10:45:47 +0100 +Subject: [PATCH] brcmfmac: avoid potential stack overflow in + brcmf_cfg80211_start_ap() + +User-space can choose to omit NL80211_ATTR_SSID and only provide raw +IE TLV data. When doing so it can provide SSID IE with length exceeding +the allowed size. The driver further processes this IE copying it +into a local variable without checking the length. Hence stack can be +corrupted and used as exploit. + +Cc: stable@vger.kernel.org # v4.7 +Reported-by: Daxing Guo +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4447,7 +4447,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + (u8 *)&settings->beacon.head[ie_offset], + settings->beacon.head_len - ie_offset, + WLAN_EID_SSID); +- if (!ssid_ie) ++ if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN) + return -EINVAL; + + memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len); diff --git a/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch b/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch new file mode 100644 index 0000000000..1285b30960 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch @@ -0,0 +1,55 @@ +From 634faf3686900ccdee87b77e2c56df8b2159912b Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 5 Sep 2016 11:42:12 +0100 +Subject: [PATCH] brcmfmac: add support for bcm4339 chip with modalias + sdio:c00v02D0d4339 + +The driver already supports the bcm4339 chipset but only for the variant +that shares the same modalias as the bcm4335, ie. sdio:c00v02D0d4335. +It turns out that there are also bcm4339 devices out there that have a +more distiguishable modalias sdio:c00v02D0d4339. + +Reported-by: Steve deRosier +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++- + include/linux/mmc/sdio_ids.h | 1 + + 3 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -1097,6 +1097,7 @@ static const struct sdio_device_id brcmf + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3756,7 +3756,8 @@ static u32 brcmf_sdio_buscore_read32(voi + u32 val, rev; + + val = brcmf_sdiod_regrl(sdiodev, addr, NULL); +- if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && ++ if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || ++ sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && + addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { + rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; + if (rev >= 2) { +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -32,6 +32,7 @@ + #define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c + #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d + #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 ++#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339 + #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 + #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 + #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 diff --git a/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch b/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch new file mode 100644 index 0000000000..1d5667ee6e --- /dev/null +++ b/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch @@ -0,0 +1,56 @@ +From 5251b6be8bb5c5675bdf12347c7b83937a5c91e5 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 5 Sep 2016 11:42:13 +0100 +Subject: [PATCH] brcmfmac: sdio: shorten retry loop in + brcmf_sdio_kso_control() + +In brcmf_sdio_kso_control() there is a retry loop as hardware may take +time to settle. However, when the call to brcmf_sdiod_regrb() returns +an error it is due to SDIO access failure and it makes no sense to wait +for hardware to settle. This patch aborts the loop after a number of +subsequent access errors. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -313,6 +313,7 @@ struct rte_console { + + #define KSO_WAIT_US 50 + #define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) ++#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5 + + /* + * Conversion of 802.1D priority to precedence level +@@ -675,6 +676,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio + { + u8 wr_val = 0, rd_val, cmp_val, bmask; + int err = 0; ++ int err_cnt = 0; + int try_cnt = 0; + + brcmf_dbg(TRACE, "Enter: on=%d\n", on); +@@ -710,9 +712,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio + */ + rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + &err); +- if (((rd_val & bmask) == cmp_val) && !err) ++ if (!err) { ++ if ((rd_val & bmask) == cmp_val) ++ break; ++ err_cnt = 0; ++ } ++ /* bail out upon subsequent access errors */ ++ if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) + break; +- + udelay(KSO_WAIT_US); + brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, + wr_val, &err); diff --git a/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch b/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch new file mode 100644 index 0000000000..1620e0022b --- /dev/null +++ b/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch @@ -0,0 +1,84 @@ +From b3589dfe02123a0d0ea82076a9f8ef84a46852c0 Mon Sep 17 00:00:00 2001 +From: Hante Meuleman +Date: Mon, 19 Sep 2016 12:09:51 +0100 +Subject: [PATCH] brcmfmac: ignore 11d configuration errors + +802.11d is not always supported by firmware anymore. Currently the +AP configuration of 11d will cause an abort if the ioctl set is +failing. This behavior is not correct and the error should be +ignored. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 27 ++++++++++++---------- + 1 file changed, 15 insertions(+), 12 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -4422,6 +4422,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef); + bool mbss; + int is_11d; ++ bool supports_11d; + + brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", + settings->chandef.chan->hw_value, +@@ -4434,11 +4435,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + mbss = ifp->vif->mbss; + + /* store current 11d setting */ +- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d); +- country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, +- settings->beacon.tail_len, +- WLAN_EID_COUNTRY); +- is_11d = country_ie ? 1 : 0; ++ if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, ++ &ifp->vif->is_11d)) { ++ supports_11d = false; ++ } else { ++ country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, ++ settings->beacon.tail_len, ++ WLAN_EID_COUNTRY); ++ is_11d = country_ie ? 1 : 0; ++ supports_11d = true; ++ } + + memset(&ssid_le, 0, sizeof(ssid_le)); + if (settings->ssid == NULL || settings->ssid_len == 0) { +@@ -4497,7 +4503,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + /* Parameters shared by all radio interfaces */ + if (!mbss) { +- if (is_11d != ifp->vif->is_11d) { ++ if ((supports_11d) && (is_11d != ifp->vif->is_11d)) { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, + is_11d); + if (err < 0) { +@@ -4539,7 +4545,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + brcmf_err("SET INFRA error %d\n", err); + goto exit; + } +- } else if (WARN_ON(is_11d != ifp->vif->is_11d)) { ++ } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) { + /* Multiple-BSS should use same 11d configuration */ + err = -EINVAL; + goto exit; +@@ -4673,11 +4679,8 @@ static int brcmf_cfg80211_stop_ap(struct + brcmf_err("setting INFRA mode failed %d\n", err); + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) + brcmf_fil_iovar_int_set(ifp, "mbss", 0); +- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, +- ifp->vif->is_11d); +- if (err < 0) +- brcmf_err("restoring REGULATORY setting failed %d\n", +- err); ++ brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, ++ ifp->vif->is_11d); + /* Bring device back up so it can be used again */ + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + if (err < 0) diff --git a/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch b/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch new file mode 100644 index 0000000000..9461164523 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch @@ -0,0 +1,32 @@ +From 704d1c6b56f4ee2ad6a5f012a72a278d17c1a223 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 19 Sep 2016 12:09:52 +0100 +Subject: [PATCH] brcmfmac: rework pointer trickery in + brcmf_proto_bcdc_query_dcmd() + +The variable info is assigned to point to bcdc->msg[1], which is the +same as pointing to bcdc->buf. As that is what we want to access +make it clear by fixing the assignment. This also avoid out-of-bounds +errors from static analyzers are bcdc->msg[1] is not in the structure +definition. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -194,7 +194,7 @@ retry: + } + + /* Check info buffer */ +- info = (void *)&msg[1]; ++ info = (void *)&bcdc->buf[0]; + + /* Copy info buffer */ + if (buf) { diff --git a/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch b/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch new file mode 100644 index 0000000000..2ececdf197 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch @@ -0,0 +1,39 @@ +From bc981641360183990de59da17f9f560f9150b801 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 19 Sep 2016 12:09:53 +0100 +Subject: [PATCH] brcmfmac: fix memory leak in brcmf_flowring_add_tdls_peer() + +In the error paths in brcmf_flowring_add_tdls_peer() the allocated +resource should be freed. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c +@@ -495,14 +495,18 @@ void brcmf_flowring_add_tdls_peer(struct + } else { + search = flow->tdls_entry; + if (memcmp(search->mac, peer, ETH_ALEN) == 0) +- return; ++ goto free_entry; + while (search->next) { + search = search->next; + if (memcmp(search->mac, peer, ETH_ALEN) == 0) +- return; ++ goto free_entry; + } + search->next = tdls_entry; + } + + flow->tdls_active = true; ++ return; ++ ++free_entry: ++ kfree(tdls_entry); + } diff --git a/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch b/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch new file mode 100644 index 0000000000..529cc8df02 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch @@ -0,0 +1,28 @@ +From 26305d3d7298d1ddf8fd4ce95a382aa90534f0a3 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 19 Sep 2016 12:09:54 +0100 +Subject: [PATCH] brcmfmac: initialize variable in brcmf_sdiod_regrl() + +In case of an error the variable returned is uninitialized. The caller +will probably check the error code before using it, but better assure +it is set to zero. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -416,7 +416,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d + + u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) + { +- u32 data; ++ u32 data = 0; + int retval; + + brcmf_dbg(SDIO, "addr:0x%08x\n", addr); diff --git a/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch b/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch new file mode 100644 index 0000000000..67af30e4fd --- /dev/null +++ b/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch @@ -0,0 +1,107 @@ +From 8fa5fdec09cd379c9ecb8972f344f8f308e0ccf3 Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Mon, 19 Sep 2016 12:09:55 +0100 +Subject: [PATCH] brcmfmac: remove worker from .ndo_set_mac_address() callback + +As it turns out there is no need to use a worker for the callback +because it is not called from atomic context. + +Reported-by: Dan Williams +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 39 ++++++++-------------- + .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 -- + 2 files changed, 13 insertions(+), 28 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -136,27 +136,6 @@ static void _brcmf_set_multicast_list(st + err); + } + +-static void +-_brcmf_set_mac_address(struct work_struct *work) +-{ +- struct brcmf_if *ifp; +- s32 err; +- +- ifp = container_of(work, struct brcmf_if, setmacaddr_work); +- +- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); +- +- err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, +- ETH_ALEN); +- if (err < 0) { +- brcmf_err("Setting cur_etheraddr failed, %d\n", err); +- } else { +- brcmf_dbg(TRACE, "MAC address updated to %pM\n", +- ifp->mac_addr); +- memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); +- } +-} +- + #if IS_ENABLED(CONFIG_IPV6) + static void _brcmf_update_ndtable(struct work_struct *work) + { +@@ -190,10 +169,20 @@ static int brcmf_netdev_set_mac_address( + { + struct brcmf_if *ifp = netdev_priv(ndev); + struct sockaddr *sa = (struct sockaddr *)addr; ++ int err; + +- memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); +- schedule_work(&ifp->setmacaddr_work); +- return 0; ++ brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); ++ ++ err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data, ++ ETH_ALEN); ++ if (err < 0) { ++ brcmf_err("Setting cur_etheraddr failed, %d\n", err); ++ } else { ++ brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data); ++ memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN); ++ memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); ++ } ++ return err; + } + + static void brcmf_netdev_set_multicast_list(struct net_device *ndev) +@@ -525,7 +514,6 @@ int brcmf_net_attach(struct brcmf_if *if + /* set the mac address */ + memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + +- INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); + INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); + INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable); + +@@ -730,7 +718,6 @@ static void brcmf_del_if(struct brcmf_pu + } + + if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { +- cancel_work_sync(&ifp->setmacaddr_work); + cancel_work_sync(&ifp->multicast_work); + cancel_work_sync(&ifp->ndoffload_work); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -176,7 +176,6 @@ enum brcmf_netif_stop_reason { + * @vif: points to cfg80211 specific interface information. + * @ndev: associated network device. + * @stats: interface specific network statistics. +- * @setmacaddr_work: worker object for setting mac address. + * @multicast_work: worker object for multicast provisioning. + * @ndoffload_work: worker object for neighbor discovery offload configuration. + * @fws_desc: interface specific firmware-signalling descriptor. +@@ -193,7 +192,6 @@ struct brcmf_if { + struct brcmf_cfg80211_vif *vif; + struct net_device *ndev; + struct net_device_stats stats; +- struct work_struct setmacaddr_work; + struct work_struct multicast_work; + struct work_struct ndoffload_work; + struct brcmf_fws_mac_descriptor *fws_desc; diff --git a/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch b/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch new file mode 100644 index 0000000000..5a08479329 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch @@ -0,0 +1,31 @@ +From 835680b82f029818c813324aed3073cdcf63241f Mon Sep 17 00:00:00 2001 +From: Hante Meuleman +Date: Mon, 19 Sep 2016 12:09:56 +0100 +Subject: [PATCH] brcmfmac: remove unnecessary null pointer check + +in the function brcmf_bus_start() in the exception handling a +check is made to dermine whether ifp is null, though this is not +possible. Removing the unnessary check. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1048,8 +1048,7 @@ fail: + brcmf_fws_del_interface(ifp); + brcmf_fws_deinit(drvr); + } +- if (ifp) +- brcmf_net_detach(ifp->ndev, false); ++ brcmf_net_detach(ifp->ndev, false); + if (p2p_ifp) + brcmf_net_detach(p2p_ifp->ndev, false); + drvr->iflist[0] = NULL; diff --git a/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch b/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch new file mode 100644 index 0000000000..0b3a23edc0 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch @@ -0,0 +1,37 @@ +From 2b7425f3629b38c438f890c20c5faeca64b144ff Mon Sep 17 00:00:00 2001 +From: Hante Meuleman +Date: Mon, 19 Sep 2016 12:09:57 +0100 +Subject: [PATCH] brcmfmac: fix clearing entry IPv6 address + +When IPv6 address is to be cleared there is a possible out of +bound access. But also the clearing of the last entry and the +adjustment of total number of stored IPv6 addresses is not +updated. This patch fixes that bug. Bug was found using coverity. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -873,9 +873,12 @@ static int brcmf_inet6addr_changed(struc + } + break; + case NETDEV_DOWN: +- if (i < NDOL_MAX_ENTRIES) +- for (; i < ifp->ipv6addr_idx; i++) ++ if (i < NDOL_MAX_ENTRIES) { ++ for (; i < ifp->ipv6addr_idx - 1; i++) + table[i] = table[i + 1]; ++ memset(&table[i], 0, sizeof(table[i])); ++ ifp->ipv6addr_idx--; ++ } + break; + default: + break; diff --git a/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch b/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch new file mode 100644 index 0000000000..a47cb3266f --- /dev/null +++ b/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch @@ -0,0 +1,44 @@ +From a7ed7828ecda0c2b5e0d7f55dedd4230afd4b583 Mon Sep 17 00:00:00 2001 +From: Hante Meuleman +Date: Mon, 19 Sep 2016 12:09:58 +0100 +Subject: [PATCH] brcmfmac: fix out of bound access on clearing wowl wake + indicator + +Clearing the wowl wakeindicator happens with a rather odd +construction where the string "clear" is used to set the iovar +wowl_wakeind. This was implemented incorrectly as it caused an +out of bound access. Use an intermediate variable of correct +length and copy string in that. Problem was found using coverity. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3623,6 +3623,7 @@ static void brcmf_configure_wowl(struct + struct cfg80211_wowlan *wowl) + { + u32 wowl_config; ++ struct brcmf_wowl_wakeind_le wowl_wakeind; + u32 i; + + brcmf_dbg(TRACE, "Suspend, wowl config.\n"); +@@ -3664,8 +3665,9 @@ static void brcmf_configure_wowl(struct + if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) + wowl_config |= BRCMF_WOWL_UNASSOC; + +- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", +- sizeof(struct brcmf_wowl_wakeind_le)); ++ memcpy(&wowl_wakeind, "clear", 6); ++ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind, ++ sizeof(wowl_wakeind)); + brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); + brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); + brcmf_bus_wowl_config(cfg->pub->bus_if, true); diff --git a/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch b/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch new file mode 100644 index 0000000000..a652ae60b8 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch @@ -0,0 +1,39 @@ +From 92c313604711a0976def79dabb9e8da3cc2cc780 Mon Sep 17 00:00:00 2001 +From: Hante Meuleman +Date: Mon, 19 Sep 2016 12:09:59 +0100 +Subject: [PATCH] brcmfmac: simplify mapping of auth type + +The 802.11 standard only has four valid auth type configurations of which +our firmware only supports two, ie. Open System and Shared Key. Simplify +the mapping falling back to automatic for other types specified by +user-space. + +Reviewed-by: Arend Van Spriel +Reviewed-by: Franky Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Hante Meuleman +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -1577,15 +1577,9 @@ static s32 brcmf_set_auth_type(struct ne + val = 1; + brcmf_dbg(CONN, "shared key\n"); + break; +- case NL80211_AUTHTYPE_AUTOMATIC: +- val = 2; +- brcmf_dbg(CONN, "automatic\n"); +- break; +- case NL80211_AUTHTYPE_NETWORK_EAP: +- brcmf_dbg(CONN, "network eap\n"); + default: + val = 2; +- brcmf_err("invalid auth type (%d)\n", sme->auth_type); ++ brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type); + break; + } + diff --git a/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch b/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch new file mode 100644 index 0000000000..a6fae37803 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch @@ -0,0 +1,41 @@ +From 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 21 Sep 2016 08:23:24 +0200 +Subject: [PATCH] brcmfmac: fix memory leak in brcmf_fill_bss_param +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This function is called from get_station callback which means that every +time user space was getting/dumping station(s) we were leaking 2 KiB. + +Signed-off-by: Rafał Miłecki +Fixes: 1f0dc59a6de ("brcmfmac: rework .get_station() callback") +Cc: stable@vger.kernel.org # 4.2+ +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -2463,7 +2463,7 @@ static void brcmf_fill_bss_param(struct + WL_BSS_INFO_MAX); + if (err) { + brcmf_err("Failed to get bss info (%d)\n", err); +- return; ++ goto out_kfree; + } + si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); + si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); +@@ -2475,6 +2475,9 @@ static void brcmf_fill_bss_param(struct + si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) + si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; ++ ++out_kfree: ++ kfree(buf); + } + + static s32 diff --git a/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch b/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch new file mode 100644 index 0000000000..47af73ad29 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch @@ -0,0 +1,60 @@ +From 2df86ad959c9d1cdbeb2f23a0801857731156692 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 23 Sep 2016 15:27:46 +0200 +Subject: [PATCH] brcmfmac: drop unused fields from struct brcmf_pub +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +They seem to be there from the first day. We calculate these values but +never use them. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 --- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 4 ---- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 -- + 3 files changed, 9 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -508,9 +508,6 @@ int brcmf_net_attach(struct brcmf_if *if + ndev->hard_header_len += drvr->hdrlen; + ndev->ethtool_ops = &brcmf_ethtool_ops; + +- drvr->rxsz = ndev->mtu + ndev->hard_header_len + +- drvr->hdrlen; +- + /* set the mac address */ + memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -112,15 +112,11 @@ struct brcmf_pub { + + /* Internal brcmf items */ + uint hdrlen; /* Total BRCMF header length (proto + bus) */ +- uint rxsz; /* Rx buffer size bus module should use */ + + /* Dongle media info */ + char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; + u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ + +- /* Multicast data packets sent to dongle */ +- unsigned long tx_multicast; +- + struct mac_address addresses[BRCMF_MAX_IFS]; + + struct brcmf_if *iflist[BRCMF_MAX_IFS]; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -2104,8 +2104,6 @@ int brcmf_fws_process_skb(struct brcmf_i + if (!skb->priority) + skb->priority = cfg80211_classify8021d(skb, NULL); + +- drvr->tx_multicast += !!multicast; +- + if (fws->avoid_queueing) { + rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); + if (rc < 0) diff --git a/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch b/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch new file mode 100644 index 0000000000..ca4863a195 --- /dev/null +++ b/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch @@ -0,0 +1,38 @@ +From 2f0e56fa37cce60a5ac5d451bcadec51cd711436 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 27 Sep 2016 12:12:24 +0200 +Subject: [PATCH] brcmfmac: replace WARNING on timeout with a simple error + message +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Even with timeout increased to 950 ms we get WARNINGs from time to time. +It mostly happens on A-MPDU stalls (e.g. when station goes out of +range). It may take up to 5-10 secods for the firmware to recover and +for that time it doesn't process packets. + +It's still useful to have a message on time out as it may indicate some +firmware problem and incorrect key update. Raising a WARNING however +wasn't really that necessary, it doesn't point to any driver bug anymore +and backtrace wasn't much useful. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1155,7 +1155,8 @@ int brcmf_netdev_wait_pend8021x(struct b + !brcmf_get_pend_8021x_cnt(ifp), + MAX_WAIT_FOR_8021X_TX); + +- WARN_ON(!err); ++ if (!err) ++ brcmf_err("Timed out waiting for no pending 802.1x packets\n"); + + return !err; + } diff --git a/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch b/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch new file mode 100644 index 0000000000..697635941b --- /dev/null +++ b/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch @@ -0,0 +1,58 @@ +From 7f00ee2bbc630900ba16fc2690473f3e2db0e264 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 27 Sep 2016 14:11:04 +0200 +Subject: [PATCH] brcmfmac: use correct skb freeing helper when deleting + flowring +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Flowrings contain skbs waiting for transmission that were passed to us +by netif. It means we checked every one of them looking for 802.1x +Ethernet type. When deleting flowring we have to use freeing function +that will check for 802.1x type as well. + +Freeing skbs without a proper check was leading to counter not being +properly decreased. This was triggering a WARNING every time +brcmf_netdev_wait_pend8021x was called. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Cc: stable@vger.kernel.org # 4.5+ +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c +@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct + + void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid) + { ++ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); + struct brcmf_flowring_ring *ring; ++ struct brcmf_if *ifp; + u16 hash_idx; ++ u8 ifidx; + struct sk_buff *skb; + + ring = flow->rings[flowid]; + if (!ring) + return; ++ ++ ifidx = brcmf_flowring_ifidx_get(flow, flowid); ++ ifp = brcmf_get_ifp(bus_if->drvr, ifidx); ++ + brcmf_flowring_block(flow, flowid, false); + hash_idx = ring->hash_id; + flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX; +@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_ + + skb = skb_dequeue(&ring->skblist); + while (skb) { +- brcmu_pkt_buf_free_skb(skb); ++ brcmf_txfinalize(ifp, skb, false); + skb = skb_dequeue(&ring->skblist); + } + diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch index ae571c99ab..f7f44f513f 100644 --- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1213,6 +1213,7 @@ int __init brcmf_core_init(void) +@@ -1200,6 +1200,7 @@ int __init brcmf_core_init(void) { if (!schedule_work(&brcmf_driver_work)) return -EBUSY; -- cgit v1.2.3