[openwrt/openwrt] mac80211: brcmfmac: backport remaining changes from 4.15

LEDE Commits lede-commits at lists.infradead.org
Thu Mar 1 06:32:37 PST 2018


rmilecki pushed a commit to openwrt/openwrt.git, branch master:
https://git.lede-project.org/e52e8480add7607fe9643111d34ac3efdecad29a

commit e52e8480add7607fe9643111d34ac3efdecad29a
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Thu Mar 1 15:08:25 2018 +0100

    mac80211: brcmfmac: backport remaining changes from 4.15
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ...4-v4.15-brcmfmac-add-CLM-download-support.patch | 434 +++++++++++++++++++++
 ...ange-driver-unbind-order-of-the-sdio-func.patch |  37 ++
 ...-brcmfmac-Avoid-build-error-with-make-W-1.patch |  33 ++
 ...x-CLM-load-error-for-legacy-chips-when-us.patch |  40 ++
 ...mfmac-register-wiphy-s-during-module_init.patch |   2 +-
 ...ot-use-internal-roaming-engine-by-default.patch |   2 +-
 6 files changed, 546 insertions(+), 2 deletions(-)

diff --git a/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch b/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch
new file mode 100644
index 0000000..2cd5f73
--- /dev/null
+++ b/package/kernel/mac80211/patches/304-v4.15-brcmfmac-add-CLM-download-support.patch
@@ -0,0 +1,434 @@
+From fdd0bd88ceaecf729db103ac8836af5805dd2dc1 Mon Sep 17 00:00:00 2001
+From: Chung-Hsien Hsu <stanley.hsu at cypress.com>
+Date: Fri, 10 Nov 2017 17:27:15 +0800
+Subject: [PATCH] brcmfmac: add CLM download support
+
+The firmware for brcmfmac devices includes information regarding
+regulatory constraints. For certain devices this information is kept
+separately in a binary form that needs to be downloaded to the device.
+This patch adds support to download this so-called CLM blob file. It
+uses the same naming scheme as the other firmware files with extension
+of .clm_blob.
+
+The CLM blob file is optional. If the file does not exist, the download
+process will be bypassed. It will not affect the driver loading.
+
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Chung-Hsien Hsu <stanley.hsu at cypress.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  10 ++
+ .../wireless/broadcom/brcm80211/brcmfmac/common.c  | 157 +++++++++++++++++++++
+ .../wireless/broadcom/brcm80211/brcmfmac/core.c    |   2 +
+ .../wireless/broadcom/brcm80211/brcmfmac/core.h    |   2 +
+ .../broadcom/brcm80211/brcmfmac/fwil_types.h       |  31 ++++
+ .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  19 +++
+ .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  19 +++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  18 +++
+ 8 files changed, 258 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+@@ -71,6 +71,7 @@ struct brcmf_bus_dcmd {
+  * @wowl_config: specify if dongle is configured for wowl when going to suspend
+  * @get_ramsize: obtain size of device memory.
+  * @get_memdump: obtain device memory dump in provided buffer.
++ * @get_fwname: obtain firmware name.
+  *
+  * This structure provides an abstract interface towards the
+  * bus specific driver. For control messages to common driver
+@@ -87,6 +88,8 @@ struct brcmf_bus_ops {
+ 	void (*wowl_config)(struct device *dev, bool enabled);
+ 	size_t (*get_ramsize)(struct device *dev);
+ 	int (*get_memdump)(struct device *dev, void *data, size_t len);
++	int (*get_fwname)(struct device *dev, uint chip, uint chiprev,
++			  unsigned char *fw_name);
+ };
+ 
+ 
+@@ -224,6 +227,13 @@ int brcmf_bus_get_memdump(struct brcmf_b
+ 	return bus->ops->get_memdump(bus->dev, data, len);
+ }
+ 
++static inline
++int brcmf_bus_get_fwname(struct brcmf_bus *bus, uint chip, uint chiprev,
++			 unsigned char *fw_name)
++{
++	return bus->ops->get_fwname(bus->dev, chip, chiprev, fw_name);
++}
++
+ /*
+  * interface functions from common layer
+  */
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -18,6 +18,7 @@
+ #include <linux/string.h>
+ #include <linux/netdevice.h>
+ #include <linux/module.h>
++#include <linux/firmware.h>
+ #include <brcmu_wifi.h>
+ #include <brcmu_utils.h>
+ #include "core.h"
+@@ -28,6 +29,7 @@
+ #include "tracepoint.h"
+ #include "common.h"
+ #include "of.h"
++#include "firmware.h"
+ 
+ MODULE_AUTHOR("Broadcom Corporation");
+ MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
+@@ -104,12 +106,140 @@ void brcmf_c_set_joinpref_default(struct
+ 		brcmf_err("Set join_pref error (%d)\n", err);
+ }
+ 
++static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
++			    struct brcmf_dload_data_le *dload_buf,
++			    u32 len)
++{
++	s32 err;
++
++	flag |= (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT);
++	dload_buf->flag = cpu_to_le16(flag);
++	dload_buf->dload_type = cpu_to_le16(DL_TYPE_CLM);
++	dload_buf->len = cpu_to_le32(len);
++	dload_buf->crc = cpu_to_le32(0);
++	len = sizeof(*dload_buf) + len - 1;
++
++	err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, len);
++
++	return err;
++}
++
++static int brcmf_c_get_clm_name(struct brcmf_if *ifp, u8 *clm_name)
++{
++	struct brcmf_bus *bus = ifp->drvr->bus_if;
++	struct brcmf_rev_info *ri = &ifp->drvr->revinfo;
++	u8 fw_name[BRCMF_FW_NAME_LEN];
++	u8 *ptr;
++	size_t len;
++	s32 err;
++
++	memset(fw_name, 0, BRCMF_FW_NAME_LEN);
++	err = brcmf_bus_get_fwname(bus, ri->chipnum, ri->chiprev, fw_name);
++	if (err) {
++		brcmf_err("get firmware name failed (%d)\n", err);
++		goto done;
++	}
++
++	/* generate CLM blob file name */
++	ptr = strrchr(fw_name, '.');
++	if (!ptr) {
++		err = -ENOENT;
++		goto done;
++	}
++
++	len = ptr - fw_name + 1;
++	if (len + strlen(".clm_blob") > BRCMF_FW_NAME_LEN) {
++		err = -E2BIG;
++	} else {
++		strlcpy(clm_name, fw_name, len);
++		strlcat(clm_name, ".clm_blob", BRCMF_FW_NAME_LEN);
++	}
++done:
++	return err;
++}
++
++static int brcmf_c_process_clm_blob(struct brcmf_if *ifp)
++{
++	struct device *dev = ifp->drvr->bus_if->dev;
++	struct brcmf_dload_data_le *chunk_buf;
++	const struct firmware *clm = NULL;
++	u8 clm_name[BRCMF_FW_NAME_LEN];
++	u32 chunk_len;
++	u32 datalen;
++	u32 cumulative_len;
++	u16 dl_flag = DL_BEGIN;
++	u32 status;
++	s32 err;
++
++	brcmf_dbg(TRACE, "Enter\n");
++
++	memset(clm_name, 0, BRCMF_FW_NAME_LEN);
++	err = brcmf_c_get_clm_name(ifp, clm_name);
++	if (err) {
++		brcmf_err("get CLM blob file name failed (%d)\n", err);
++		return err;
++	}
++
++	err = request_firmware(&clm, clm_name, dev);
++	if (err) {
++		if (err == -ENOENT) {
++			brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n");
++			return 0;
++		}
++		brcmf_err("request CLM blob file failed (%d)\n", err);
++		return err;
++	}
++
++	chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
++	if (!chunk_buf) {
++		err = -ENOMEM;
++		goto done;
++	}
++
++	datalen = clm->size;
++	cumulative_len = 0;
++	do {
++		if (datalen > MAX_CHUNK_LEN) {
++			chunk_len = MAX_CHUNK_LEN;
++		} else {
++			chunk_len = datalen;
++			dl_flag |= DL_END;
++		}
++		memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len);
++
++		err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len);
++
++		dl_flag &= ~DL_BEGIN;
++
++		cumulative_len += chunk_len;
++		datalen -= chunk_len;
++	} while ((datalen > 0) && (err == 0));
++
++	if (err) {
++		brcmf_err("clmload (%zu byte file) failed (%d); ",
++			  clm->size, err);
++		/* Retrieve clmload_status and print */
++		err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status);
++		if (err)
++			brcmf_err("get clmload_status failed (%d)\n", err);
++		else
++			brcmf_dbg(INFO, "clmload_status=%d\n", status);
++		err = -EIO;
++	}
++
++	kfree(chunk_buf);
++done:
++	release_firmware(clm);
++	return err;
++}
++
+ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
+ {
+ 	s8 eventmask[BRCMF_EVENTING_MASK_LEN];
+ 	u8 buf[BRCMF_DCMD_SMLEN];
+ 	struct brcmf_rev_info_le revinfo;
+ 	struct brcmf_rev_info *ri;
++	char *clmver;
+ 	char *ptr;
+ 	s32 err;
+ 
+@@ -148,6 +278,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
+ 	}
+ 	ri->result = err;
+ 
++	/* Do any CLM downloading */
++	err = brcmf_c_process_clm_blob(ifp);
++	if (err < 0) {
++		brcmf_err("download CLM blob file failed, %d\n", err);
++		goto done;
++	}
++
+ 	/* query for 'ver' to get version info from firmware */
+ 	memset(buf, 0, sizeof(buf));
+ 	strcpy(buf, "ver");
+@@ -167,6 +304,26 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
+ 	ptr = strrchr(buf, ' ') + 1;
+ 	strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
+ 
++	/* Query for 'clmver' to get CLM version info from firmware */
++	memset(buf, 0, sizeof(buf));
++	err = brcmf_fil_iovar_data_get(ifp, "clmver", buf, sizeof(buf));
++	if (err) {
++		brcmf_dbg(TRACE, "retrieving clmver failed, %d\n", err);
++	} else {
++		clmver = (char *)buf;
++		/* store CLM version for adding it to revinfo debugfs file */
++		memcpy(ifp->drvr->clmver, clmver, sizeof(ifp->drvr->clmver));
++
++		/* Replace all newline/linefeed characters with space
++		 * character
++		 */
++		ptr = clmver;
++		while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL)
++			*ptr = ' ';
++
++		brcmf_dbg(INFO, "CLM version = %s\n", clmver);
++	}
++
+ 	/* set mpc */
+ 	err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
+ 	if (err) {
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1009,6 +1009,8 @@ static int brcmf_revinfo_read(struct seq
+ 	seq_printf(s, "anarev: %u\n", ri->anarev);
+ 	seq_printf(s, "nvramrev: %08x\n", ri->nvramrev);
+ 
++	seq_printf(s, "clmver: %s\n", bus_if->drvr->clmver);
++
+ 	return 0;
+ }
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+@@ -141,6 +141,8 @@ struct brcmf_pub {
+ 	struct notifier_block inetaddr_notifier;
+ 	struct notifier_block inet6addr_notifier;
+ 	struct brcmf_mp_device *settings;
++
++	u8 clmver[BRCMF_DCMD_SMLEN];
+ };
+ 
+ /* forward declarations */
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+@@ -155,6 +155,21 @@
+ #define BRCMF_MFP_CAPABLE		1
+ #define BRCMF_MFP_REQUIRED		2
+ 
++/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
++ * ioctl. It is relatively small because firmware has small maximum size input
++ * playload restriction for ioctls.
++ */
++#define MAX_CHUNK_LEN			1400
++
++#define DLOAD_HANDLER_VER		1	/* Downloader version */
++#define DLOAD_FLAG_VER_MASK		0xf000	/* Downloader version mask */
++#define DLOAD_FLAG_VER_SHIFT		12	/* Downloader version shift */
++
++#define DL_BEGIN			0x0002
++#define DL_END				0x0004
++
++#define DL_TYPE_CLM			2
++
+ /* join preference types for join_pref iovar */
+ enum brcmf_join_pref_types {
+ 	BRCMF_JOIN_PREF_RSSI = 1,
+@@ -827,6 +842,22 @@ struct brcmf_pno_macaddr_le {
+ };
+ 
+ /**
++ * struct brcmf_dload_data_le - data passing to firmware for downloading
++ * @flag: flags related to download data.
++ * @dload_type: type of download data.
++ * @len: length in bytes of download data.
++ * @crc: crc of download data.
++ * @data: download data.
++ */
++struct brcmf_dload_data_le {
++	__le16 flag;
++	__le16 dload_type;
++	__le32 len;
++	__le32 crc;
++	u8 data[1];
++};
++
++/**
+  * struct brcmf_pno_bssid_le - bssid configuration for PNO scan.
+  *
+  * @bssid: BSS network identifier.
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -1350,6 +1350,24 @@ static int brcmf_pcie_get_memdump(struct
+ 	return 0;
+ }
+ 
++static int brcmf_pcie_get_fwname(struct device *dev, u32 chip, u32 chiprev,
++				 u8 *fw_name)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
++	struct brcmf_pciedev_info *devinfo = buspub->devinfo;
++	int ret = 0;
++
++	if (devinfo->fw_name[0] != '\0')
++		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
++	else
++		ret = brcmf_fw_map_chip_to_name(chip, chiprev,
++						brcmf_pcie_fwnames,
++						ARRAY_SIZE(brcmf_pcie_fwnames),
++						fw_name, NULL);
++
++	return ret;
++}
+ 
+ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
+ 	.txdata = brcmf_pcie_tx,
+@@ -1359,6 +1377,7 @@ static const struct brcmf_bus_ops brcmf_
+ 	.wowl_config = brcmf_pcie_wowl_config,
+ 	.get_ramsize = brcmf_pcie_get_ramsize,
+ 	.get_memdump = brcmf_pcie_get_memdump,
++	.get_fwname = brcmf_pcie_get_fwname,
+ };
+ 
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3985,6 +3985,24 @@ brcmf_sdio_watchdog(unsigned long data)
+ 	}
+ }
+ 
++static int brcmf_sdio_get_fwname(struct device *dev, u32 chip, u32 chiprev,
++				 u8 *fw_name)
++{
++	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++	struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
++	int ret = 0;
++
++	if (sdiodev->fw_name[0] != '\0')
++		strlcpy(fw_name, sdiodev->fw_name, BRCMF_FW_NAME_LEN);
++	else
++		ret = brcmf_fw_map_chip_to_name(chip, chiprev,
++						brcmf_sdio_fwnames,
++						ARRAY_SIZE(brcmf_sdio_fwnames),
++						fw_name, NULL);
++
++	return ret;
++}
++
+ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = {
+ 	.stop = brcmf_sdio_bus_stop,
+ 	.preinit = brcmf_sdio_bus_preinit,
+@@ -3995,6 +4013,7 @@ static const struct brcmf_bus_ops brcmf_
+ 	.wowl_config = brcmf_sdio_wowl_config,
+ 	.get_ramsize = brcmf_sdio_bus_get_ramsize,
+ 	.get_memdump = brcmf_sdio_bus_get_memdump,
++	.get_fwname = brcmf_sdio_get_fwname,
+ };
+ 
+ static void brcmf_sdio_firmware_callback(struct device *dev, int err,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1128,12 +1128,30 @@ static void brcmf_usb_wowl_config(struct
+ 		device_set_wakeup_enable(devinfo->dev, false);
+ }
+ 
++static int brcmf_usb_get_fwname(struct device *dev, u32 chip, u32 chiprev,
++				u8 *fw_name)
++{
++	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
++	int ret = 0;
++
++	if (devinfo->fw_name[0] != '\0')
++		strlcpy(fw_name, devinfo->fw_name, BRCMF_FW_NAME_LEN);
++	else
++		ret = brcmf_fw_map_chip_to_name(chip, chiprev,
++						brcmf_usb_fwnames,
++						ARRAY_SIZE(brcmf_usb_fwnames),
++						fw_name, NULL);
++
++	return ret;
++}
++
+ static const struct brcmf_bus_ops brcmf_usb_bus_ops = {
+ 	.txdata = brcmf_usb_tx,
+ 	.stop = brcmf_usb_down,
+ 	.txctl = brcmf_usb_tx_ctlpkt,
+ 	.rxctl = brcmf_usb_rx_ctlpkt,
+ 	.wowl_config = brcmf_usb_wowl_config,
++	.get_fwname = brcmf_usb_get_fwname,
+ };
+ 
+ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
diff --git a/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch b/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch
new file mode 100644
index 0000000..3649bdd
--- /dev/null
+++ b/package/kernel/mac80211/patches/305-v4.15-brcmfmac-change-driver-unbind-order-of-the-sdio-func.patch
@@ -0,0 +1,37 @@
+From 5c3de777bdaf48bd0cfb43097c0d0fb85056cab7 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Sat, 25 Nov 2017 21:39:25 +0100
+Subject: [PATCH] brcmfmac: change driver unbind order of the sdio function
+ devices
+
+In the function brcmf_sdio_firmware_callback() the driver is
+unbound from the sdio function devices in the error path.
+However, the order in which it is done resulted in a use-after-free
+issue (see brcmf_ops_sdio_remove() in bcmsdh.c). Hence change
+the order and first unbind sdio function #2 device and then
+unbind sdio function #1 device.
+
+Cc: stable at vger.kernel.org # v4.12.x
+Fixes: 7a51461fc2da ("brcmfmac: unbind all devices upon failure in firmware callback")
+Reported-by: Stefan Wahren <stefan.wahren at i2se.com>
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at 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
+@@ -4121,8 +4121,8 @@ release:
+ 	sdio_release_host(sdiodev->func[1]);
+ fail:
+ 	brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), err);
+-	device_release_driver(dev);
+ 	device_release_driver(&sdiodev->func[2]->dev);
++	device_release_driver(dev);
+ }
+ 
+ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
diff --git a/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch b/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch
new file mode 100644
index 0000000..7344580
--- /dev/null
+++ b/package/kernel/mac80211/patches/306-v4.15-brcmfmac-Avoid-build-error-with-make-W-1.patch
@@ -0,0 +1,33 @@
+From 51ef7925e10688c57186d438e784532e063492e4 Mon Sep 17 00:00:00 2001
+From: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
+Date: Thu, 23 Nov 2017 17:57:04 +0200
+Subject: [PATCH] brcmfmac: Avoid build error with make W=1
+
+When I run make W=1 on gcc (Debian 7.2.0-16) 7.2.0 I got an error for
+the first run, all next ones are okay.
+
+  CC [M]  drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o
+drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2078: error: Cannot parse struct or union!
+scripts/Makefile.build:310: recipe for target 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o' failed
+
+Seems like something happened with W=1 and wrong kernel doc format.
+As a quick fix remove dubious /** in the code.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
+Acked-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at 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
+@@ -2070,7 +2070,7 @@ static int brcmf_sdio_txpkt_hdalign(stru
+ 	return head_pad;
+ }
+ 
+-/**
++/*
+  * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for
+  * bus layer usage.
+  */
diff --git a/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch b/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch
new file mode 100644
index 0000000..ead5e72
--- /dev/null
+++ b/package/kernel/mac80211/patches/307-v4.15-brcmfmac-fix-CLM-load-error-for-legacy-chips-when-us.patch
@@ -0,0 +1,40 @@
+From cc124d5cc8d81985c3511892d7a6d546552ff754 Mon Sep 17 00:00:00 2001
+From: Wright Feng <wright.feng at cypress.com>
+Date: Tue, 16 Jan 2018 17:26:50 +0800
+Subject: [PATCH] brcmfmac: fix CLM load error for legacy chips when user
+ helper is enabled
+
+For legacy chips without CLM blob files, kernel with user helper function
+returns -EAGAIN when we request_firmware(), and then driver got failed
+when bringing up legacy chips. We expect the CLM blob file for legacy chip
+is not existence in firmware path, but the -ENOENT error is transferred to
+-EAGAIN in firmware_class.c with user helper.
+Because of that, we continue with CLM data currently present in firmware
+if getting error from doing request_firmware().
+
+Cc: stable at vger.kernel.org # v4.15.y
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Wright Feng <wright.feng at cypress.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+@@ -182,12 +182,9 @@ static int brcmf_c_process_clm_blob(stru
+ 
+ 	err = request_firmware(&clm, clm_name, dev);
+ 	if (err) {
+-		if (err == -ENOENT) {
+-			brcmf_dbg(INFO, "continue with CLM data currently present in firmware\n");
+-			return 0;
+-		}
+-		brcmf_err("request CLM blob file failed (%d)\n", err);
+-		return err;
++		brcmf_info("no clm_blob available(err=%d), device may have limited channels available\n",
++			   err);
++		return 0;
+ 	}
+ 
+ 	chunk_buf = kzalloc(sizeof(*chunk_buf) + MAX_CHUNK_LEN - 1, GFP_KERNEL);
diff --git a/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch
index 599269d..0e98cb5 100644
--- a/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch
+++ b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch
@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1236,6 +1236,7 @@ int __init brcmf_core_init(void)
+@@ -1238,6 +1238,7 @@ int __init brcmf_core_init(void)
  {
  	if (!schedule_work(&brcmf_driver_work))
  		return -EBUSY;
diff --git a/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch
index 891c539..0ae012c 100644
--- a/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch
+++ b/package/kernel/mac80211/patches/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch
@@ -9,7 +9,7 @@ Signed-off-by: Phil Elwell <phil at raspberrypi.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
-@@ -69,7 +69,11 @@ static int brcmf_fcmode;
+@@ -71,7 +71,11 @@ static int brcmf_fcmode;
  module_param_named(fcmode, brcmf_fcmode, int, 0);
  MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
  



More information about the lede-commits mailing list