PKG_NAME:=mac80211
PKG_VERSION:=2017-01-31
-PKG_RELEASE:=6
+PKG_RELEASE:=7
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
PKG_BACKPORT_VERSION:=
PKG_HASH:=75e6d39e34cf156212a2509172a4a62b673b69eb4a1d9aaa565f7fa719fa2317
--- /dev/null
+From f1ac3aa212af6dd0a36dc07a63f95f91be6f4935 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 24 Feb 2017 17:32:46 +0100
+Subject: [PATCH] brcmfmac: always print error when PSM's watchdog fires
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+So far we were attaching BRCMF_E_PSM_WATCHDOG event listener in
+brcmf_debug_attach which gets compiled only with CONFIG_BRCMDBG. This
+event means something went wrong and firmware / hardware usually can't
+be expected to work (reliably).
+
+Such a problem is significant for user experience so I believe we should
+print an error unconditionally (even with debugging disabled). What can
+be indeed optional is dumping bus memory as this is clearly part of
+debugging process.
+
+In the future we may also try to extend this listener by trying to
+recover from the error or at least signal it to the cfg80211.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/core.c | 22 ++++++++++++++++++
+ .../wireless/broadcom/brcm80211/brcmfmac/debug.c | 26 +++-------------------
+ .../wireless/broadcom/brcm80211/brcmfmac/debug.h | 9 ++++++++
+ 3 files changed, 34 insertions(+), 23 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -748,6 +748,24 @@ void brcmf_remove_interface(struct brcmf
+ brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked);
+ }
+
++static int brcmf_psm_watchdog_notify(struct brcmf_if *ifp,
++ const struct brcmf_event_msg *evtmsg,
++ void *data)
++{
++ int err;
++
++ brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
++
++ brcmf_err("PSM's watchdog has fired!\n");
++
++ err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
++ evtmsg->datalen);
++ if (err)
++ brcmf_err("Failed to get memory dump, %d\n", err);
++
++ return err;
++}
++
+ #ifdef CONFIG_INET
+ #define ARPOL_MAX_ENTRIES 8
+ static int brcmf_inetaddr_changed(struct notifier_block *nb,
+@@ -927,6 +945,10 @@ int brcmf_attach(struct device *dev, str
+ goto fail;
+ }
+
++ /* Attach to events important for core code */
++ brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
++ brcmf_psm_watchdog_notify);
++
+ /* attach firmware event handler */
+ brcmf_fweh_attach(drvr);
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.c
+@@ -27,8 +27,8 @@
+
+ static struct dentry *root_folder;
+
+-static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
+- size_t len)
++int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
++ size_t len)
+ {
+ void *dump;
+ size_t ramsize;
+@@ -54,24 +54,6 @@ static int brcmf_debug_create_memdump(st
+ return 0;
+ }
+
+-static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
+- const struct brcmf_event_msg *evtmsg,
+- void *data)
+-{
+- int err;
+-
+- brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx);
+-
+- brcmf_err("PSM's watchdog has fired!\n");
+-
+- err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
+- evtmsg->datalen);
+- if (err)
+- brcmf_err("Failed to get memory dump, %d\n", err);
+-
+- return err;
+-}
+-
+ void brcmf_debugfs_init(void)
+ {
+ root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
+@@ -99,9 +81,7 @@ int brcmf_debug_attach(struct brcmf_pub
+ if (IS_ERR(drvr->dbgfs_dir))
+ return PTR_ERR(drvr->dbgfs_dir);
+
+-
+- return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
+- brcmf_debug_psm_watchdog_notify);
++ return 0;
+ }
+
+ void brcmf_debug_detach(struct brcmf_pub *drvr)
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+@@ -99,6 +99,7 @@ do { \
+
+ extern int brcmf_msg_level;
+
++struct brcmf_bus;
+ struct brcmf_pub;
+ #ifdef DEBUG
+ void brcmf_debugfs_init(void);
+@@ -108,6 +109,8 @@ void brcmf_debug_detach(struct brcmf_pub
+ struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
+ int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
+ int (*read_fn)(struct seq_file *seq, void *data));
++int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
++ size_t len);
+ #else
+ static inline void brcmf_debugfs_init(void)
+ {
+@@ -128,6 +131,12 @@ int brcmf_debugfs_add_entry(struct brcmf
+ {
+ return 0;
+ }
++static inline
++int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
++ size_t len)
++{
++ return 0;
++}
+ #endif
+
+ #endif /* BRCMFMAC_DEBUG_H */
--- /dev/null
+From d79fe4cb70d8deab7b8dc1de547ed4b915574414 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 8 Mar 2017 14:50:15 +0100
+Subject: [PATCH] brcmfmac: Do not print the firmware version as an error
+
+Using pr_err for things which are not errors is a bad idea. E.g. it
+will cause the plymouth bootsplash screen to drop back to the text
+console so that the user can see the error, which is not what we
+normally want to happen.
+
+Instead add a new brcmf_info macro and use that.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 9 +++++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -161,7 +161,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
+ strsep(&ptr, "\n");
+
+ /* Print fw version info */
+- brcmf_err("Firmware version = %s\n", buf);
++ brcmf_info("Firmware version = %s\n", buf);
+
+ /* locate firmware version number for ethtool */
+ ptr = strrchr(buf, ' ') + 1;
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+@@ -59,6 +59,10 @@ void __brcmf_err(const char *func, const
+ } while (0)
+
+ #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
++
++/* For debug/tracing purposes treat info messages as errors */
++#define brcmf_info brcmf_err
++
+ __printf(3, 4)
+ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...);
+ #define brcmf_dbg(level, fmt, ...) \
+@@ -77,6 +81,11 @@ do { \
+
+ #else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
+
++#define brcmf_info(fmt, ...) \
++ do { \
++ pr_info("%s: " fmt, __func__, ##__VA_ARGS__); \
++ } while (0)
++
+ #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
+
+ #define BRCMF_DATA_ON() 0
--- /dev/null
+From 26e537884a8ef451f5c60f6949b1615069931ffa Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 8 Mar 2017 14:50:16 +0100
+Subject: [PATCH] brcmfmac: Do not complain about country code "00"
+
+The country code gets set to "00" by default at boot, ignore this
+rather then logging an error about it.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -6736,6 +6736,10 @@ static void brcmf_cfg80211_reg_notifier(
+ s32 err;
+ int i;
+
++ /* The country code gets set to "00" by default at boot, ignore */
++ if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
++ return;
++
+ /* ignore non-ISO3166 country codes */
+ for (i = 0; i < sizeof(req->alpha2); i++)
+ if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
--- /dev/null
+From b9472a2e3e452c414634b3ccb1ef6c4098878686 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Wed, 8 Mar 2017 14:50:17 +0100
+Subject: [PATCH] brcmfmac: Handle status == BRCMF_E_STATUS_ABORT in
+ cfg80211_escan_handler
+
+If a scan gets aborted BRCMF_SCAN_STATUS_BUSY gets cleared in
+cfg->scan_status and when we receive an abort event from the firmware
+the BRCMF_SCAN_STATUS_BUSY check in the cfg80211_escan_handler will
+trigger resulting in multiple errors getting logged.
+
+Check for a status of BRCMF_E_STATUS_ABORT and in this case simply
+cleanly exit the cfg80211_escan_handler. This also avoids a
+BRCMF_E_STATUS_ABORT event arriving after a new scan has been started
+causing the new scan to complete prematurely without any data.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3097,6 +3097,9 @@ brcmf_cfg80211_escan_handler(struct brcm
+
+ status = e->status;
+
++ if (status == BRCMF_E_STATUS_ABORT)
++ goto exit;
++
+ if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
+ return -EPERM;
--- /dev/null
+From 49fe9b59f0e9b750f173fbe44637c436ba1030d2 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Tue, 28 Mar 2017 11:43:27 +0100
+Subject: [PATCH] brcmfmac: restore bus state when enter_D3 fails
+
+In brcmf_pcie_suspend() we inform the firmware on the device that
+it will enter in D3 state. Before this is done we already bring down
+the bus state. However, When entering D3 fails we abort the suspend
+and the bus state need to be restored.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1877,6 +1877,7 @@ static int brcmf_pcie_pm_enter_D3(struct
+ BRCMF_PCIE_MBDATA_TIMEOUT);
+ if (!devinfo->mbdata_completed) {
+ brcmf_err("Timeout on response for entering D3 substate\n");
++ brcmf_bus_change_state(bus, BRCMF_BUS_UP);
+ return -EIO;
+ }
+
--- /dev/null
+From 6e84ab604bdedaa16239bd1c6e5fcb5660309f02 Mon Sep 17 00:00:00 2001
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Wed, 5 Apr 2017 20:33:26 +0200
+Subject: [PATCH] brcmfmac: properly align buffers on certain platforms with 64
+ bit DMA
+
+Systems with 64 bit DMA at least partially require buffers to be used
+for DMA to be 8-byte-aligned. One example is Amlogic Meson GX.
+Switching the MMC/SDIO driver for this platform to SG DMA mode
+resulted in problems due to unaligned buffers.
+
+Fortunately the brcmfmac driver has a global define for the alignment.
+Changing it to 8 fixed the issues with Meson GX.
+
+Suggested-by: Helmut Klein <hgkr.klein@gmail.com>
+Tested-by: Helmut Klein <hgkr.klein@gmail.com>
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -539,7 +539,11 @@ static int qcount[NUMPRIO];
+ /* Limit on rounding up frames */
+ static const uint max_roundup = 512;
+
++#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
++#define ALIGNMENT 8
++#else
+ #define ALIGNMENT 4
++#endif
+
+ enum brcmf_sdio_frmtype {
+ BRCMF_SDIO_FT_NORMAL,
--- /dev/null
+From 4835f37e3bafc138f8bfa3cbed2920dd56fed283 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 6 Apr 2017 13:14:40 +0100
+Subject: [PATCH] brcmfmac: add length checks in scheduled scan result handler
+
+Assure the event data buffer is long enough to hold the array
+of netinfo items and that SSID length does not exceed the maximum
+of 32 characters as per 802.11 spec.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3300,6 +3300,7 @@ brcmf_notify_sched_scan_results(struct b
+ struct brcmf_pno_scanresults_le *pfn_result;
+ u32 result_count;
+ u32 status;
++ u32 datalen;
+
+ brcmf_dbg(SCAN, "Enter\n");
+
+@@ -3326,6 +3327,14 @@ brcmf_notify_sched_scan_results(struct b
+ brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
+ goto out_err;
+ }
++
++ netinfo_start = brcmf_get_netinfo_array(pfn_result);
++ datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
++ if (datalen < result_count * sizeof(*netinfo)) {
++ brcmf_err("insufficient event data\n");
++ goto out_err;
++ }
++
+ request = brcmf_alloc_internal_escan_request(wiphy,
+ result_count);
+ if (!request) {
+@@ -3333,8 +3342,6 @@ brcmf_notify_sched_scan_results(struct b
+ goto out_err;
+ }
+
+- netinfo_start = brcmf_get_netinfo_array(pfn_result);
+-
+ for (i = 0; i < result_count; i++) {
+ netinfo = &netinfo_start[i];
+ if (!netinfo) {
+@@ -3344,6 +3351,8 @@ brcmf_notify_sched_scan_results(struct b
+ goto out_err;
+ }
+
++ if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
++ netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
+ brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
+ netinfo->SSID, netinfo->channel);
+ err = brcmf_internal_escan_add_info(request,
--- /dev/null
+From 6594e1e8343645fe849a2ad42fcab94e2cf5b2c0 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 6 Apr 2017 13:14:41 +0100
+Subject: [PATCH] brcmfmac: remove bogus check in scheduled scan result handler
+
+Checking whether the address of an array element is null is bogus
+so removing it.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3344,12 +3344,6 @@ brcmf_notify_sched_scan_results(struct b
+
+ for (i = 0; i < result_count; i++) {
+ netinfo = &netinfo_start[i];
+- if (!netinfo) {
+- brcmf_err("Invalid netinfo ptr. index: %d\n",
+- i);
+- err = -EINVAL;
+- goto out_err;
+- }
+
+ if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
+ netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
--- /dev/null
+From 6ea51fc708aedcf411f355de65a704ecda501bc4 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 6 Apr 2017 13:14:42 +0100
+Subject: [PATCH] brcmfmac: only add channels and ssids once in scan request
+
+When receiving pno results there may be duplicate channels and/or
+ssids. Assure each is added only once when preparing the internal
+escan request.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3216,7 +3216,7 @@ static int brcmf_internal_escan_add_info
+ {
+ struct ieee80211_channel *chan;
+ enum nl80211_band band;
+- int freq;
++ int freq, i;
+
+ if (channel <= CH_MAX_2G_CHANNEL)
+ band = NL80211_BAND_2GHZ;
+@@ -3231,10 +3231,22 @@ static int brcmf_internal_escan_add_info
+ if (!chan)
+ return -EINVAL;
+
+- req->channels[req->n_channels++] = chan;
+- memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
+- req->ssids[req->n_ssids++].ssid_len = ssid_len;
+-
++ for (i = 0; i < req->n_channels; i++) {
++ if (req->channels[i] == chan)
++ break;
++ }
++ if (i == req->n_channels)
++ req->channels[req->n_channels++] = chan;
++
++ for (i = 0; i < req->n_ssids; i++) {
++ if (req->ssids[i].ssid_len == ssid_len &&
++ !memcmp(req->ssids[i].ssid, ssid, ssid_len))
++ break;
++ }
++ if (i == req->n_ssids) {
++ memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
++ req->ssids[req->n_ssids++].ssid_len = ssid_len;
++ }
+ return 0;
+ }
+
--- /dev/null
+From 455a1eb4654c24560eb9dfc634f29cba3d87601e Mon Sep 17 00:00:00 2001
+From: James Hughes <james.hughes@raspberrypi.org>
+Date: Mon, 24 Apr 2017 12:40:50 +0100
+Subject: [PATCH] brcmfmac: Ensure pointer correctly set if skb data location
+ changes
+
+The incoming skb header may be resized if header space is
+insufficient, which might change the data adddress in the skb.
+Ensure that a cached pointer to that data is correctly set by
+moving assignment to after any possible changes.
+
+Signed-off-by: James Hughes <james.hughes@raspberrypi.org>
+
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -198,7 +198,7 @@ static netdev_tx_t brcmf_netdev_start_xm
+ int ret;
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_pub *drvr = ifp->drvr;
+- struct ethhdr *eh = (struct ethhdr *)(skb->data);
++ struct ethhdr *eh;
+
+ brcmf_dbg(DATA, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
+
+@@ -236,6 +236,8 @@ static netdev_tx_t brcmf_netdev_start_xm
+ goto done;
+ }
+
++ eh = (struct ethhdr *)(skb->data);
++
+ if (eh->h_proto == htons(ETH_P_PAE))
+ atomic_inc(&ifp->pend_8021x_cnt);
+
--- /dev/null
+From 9cc4b7cb86cbcc6330a3faa8cd65268cd2d3c227 Mon Sep 17 00:00:00 2001
+From: James Hughes <james.hughes@raspberrypi.org>
+Date: Tue, 25 Apr 2017 10:15:06 +0100
+Subject: [PATCH] brcmfmac: Make skb header writable before use
+
+The driver was making changes to the skb_header without
+ensuring it was writable (i.e. uncloned).
+This patch also removes some boiler plate header size
+checking/adjustment code as that is also handled by the
+skb_cow_header function used to make header writable.
+
+Signed-off-by: James Hughes <james.hughes@raspberrypi.org>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -211,22 +211,13 @@ static netdev_tx_t brcmf_netdev_start_xm
+ goto done;
+ }
+
+- /* Make sure there's enough room for any header */
+- if (skb_headroom(skb) < drvr->hdrlen) {
+- struct sk_buff *skb2;
+-
+- brcmf_dbg(INFO, "%s: insufficient headroom\n",
++ /* Make sure there's enough writable headroom*/
++ ret = skb_cow_head(skb, drvr->hdrlen);
++ if (ret < 0) {
++ brcmf_err("%s: skb_cow_head failed\n",
+ brcmf_ifname(ifp));
+- drvr->bus_if->tx_realloc++;
+- skb2 = skb_realloc_headroom(skb, drvr->hdrlen);
+ dev_kfree_skb(skb);
+- skb = skb2;
+- if (skb == NULL) {
+- brcmf_err("%s: skb_realloc_headroom failed\n",
+- brcmf_ifname(ifp));
+- ret = -ENOMEM;
+- goto done;
+- }
++ goto done;
+ }
+
+ /* validate length for ether packet */
--- /dev/null
+From 1dbf647f31751a4e94fa0435c34f0f5ad5ce0adc Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Fri, 26 May 2017 13:02:55 +0200
+Subject: [PATCH] brcmfmac: fix alignment configuration on host using 64-bit
+ DMA
+
+For SDIO the alignment requirement for transfers from device to host
+is configured in firmware. This configuration is limited to minimum
+of 4-byte alignment. However, this is not correct for platforms using
+64-bit DMA when the minimum alignment should be 8 bytes. This issue
+appeared when the ALIGNMENT definition was set according the DMA
+configuration. The configuration in firmware was not using that macro
+defintion, but a hardcoded value of 4. Hence the driver reported
+alignment failures for data coming from the device and causing
+transfers to fail.
+
+Fixes: 6e84ab604bde ("brcmfmac: properly align buffers on certain platforms
+Reported-by: Hans de Goede <hdegoede@redhat.com>
+Tested-by: Hans de Goede <hdegoede@redhat.com>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3420,7 +3420,7 @@ static int brcmf_sdio_bus_preinit(struct
+ /* otherwise, set txglomalign */
+ value = sdiodev->settings->bus.sdio.sd_sgentry_align;
+ /* SDIO ADMA requires at least 32 bit alignment */
+- value = max_t(u32, value, 4);
++ value = max_t(u32, value, ALIGNMENT);
+ err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
+ sizeof(u32));
+ }
+ goto done;
+ }
+
- /* Make sure there's enough room for any header */
- if (skb_headroom(skb) < drvr->hdrlen) {
- struct sk_buff *skb2;
-@@ -295,6 +343,15 @@ void brcmf_txflowblock(struct device *de
+ /* Make sure there's enough writable headroom*/
+ ret = skb_cow_head(skb, drvr->hdrlen);
+ if (ret < 0) {
+@@ -288,6 +336,15 @@ void brcmf_txflowblock(struct device *de
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb)
{