aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2019-04-18 12:37:10 +0200
committerRafał Miłecki <rafal@milecki.pl>2019-04-18 13:44:02 +0200
commitd3bab051cfd1f2f5791e4352309c51f5e29b678f (patch)
tree9e7c45913d95f1725a77bc0f909e970c88f8c412
parenteaef74279c8f392d9656e616a9e958b31333fd4f (diff)
downloadupstream-d3bab051cfd1f2f5791e4352309c51f5e29b678f.tar.gz
upstream-d3bab051cfd1f2f5791e4352309c51f5e29b678f.tar.bz2
upstream-d3bab051cfd1f2f5791e4352309c51f5e29b678f.zip
mac80211: brcmfmac: really add early fw crash recovery
Previous commit backported USB fixes instead of firmware crash recovery patches. Fixes: eaef74279c8f ("mac80211: brcmfmac: early work on FullMAC firmware crash recovery") Signed-off-by: Rafał Miłecki <rafal@milecki.pl> (cherry picked from commit 2d2e615dee0421e126af9d4ebd49a720e341e3af)
-rw-r--r--package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch32
-rw-r--r--package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch79
-rw-r--r--package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch160
-rw-r--r--package/kernel/mac80211/patches/342-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch (renamed from package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch)0
-rw-r--r--package/kernel/mac80211/patches/342-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch (renamed from package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch)0
-rw-r--r--package/kernel/mac80211/patches/342-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch (renamed from package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch)0
6 files changed, 271 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch b/package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch
new file mode 100644
index 0000000000..ef251721c2
--- /dev/null
+++ b/package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch
@@ -0,0 +1,32 @@
+From c9692820710f57c826b2e43a6fb1e4cd307508b0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 26 Feb 2019 14:11:16 +0100
+Subject: [PATCH] brcmfmac: support repeated brcmf_fw_alloc_request() calls
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+During a normal brcmfmac lifetime brcmf_fw_alloc_request() is called
+once only during the probe. It's safe to assume provided array is clear.
+
+Further brcmfmac improvements may require calling it multiple times
+though. This patch allows it by fixing invalid firmware paths like:
+brcm/brcmfmac4366c-pcie.binbrcm/brcmfmac4366c-pcie.bin
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+@@ -582,6 +582,7 @@ int brcmf_fw_map_chip_to_name(u32 chip,
+ return -ENODEV;
+ }
+
++ fw_name[0] = '\0';
+ /* check if firmware path is provided by module parameter */
+ if (brcmf_mp_global.firmware_path[0] != '\0') {
+ strlcpy(fw_name, brcmf_mp_global.firmware_path,
diff --git a/package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch b/package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch
new file mode 100644
index 0000000000..227fda077d
--- /dev/null
+++ b/package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch
@@ -0,0 +1,79 @@
+From a2ec87ddbf1637f854ffcfff9d12d392fa30758b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 26 Feb 2019 14:11:18 +0100
+Subject: [PATCH] brcmfmac: add a function designated for handling firmware
+ fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This improves handling PCIe firmware halts by printing a clear error
+message and replaces a similar code in the SDIO bus support.
+
+It will also allow further improvements like trying to recover from a
+firmware crash.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 2 ++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 ++++++++++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +-
+ .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++--
+ 4 files changed, 15 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+@@ -233,6 +233,8 @@ void brcmf_dev_reset(struct device *dev)
+ void brcmf_txflowblock(struct device *dev, bool state);
+ /* Request from bus module to initiate a coredump */
+ void brcmf_dev_coredump(struct device *dev);
++/* Indication that firmware has halted or crashed */
++void brcmf_fw_crashed(struct device *dev);
+
+ /* Notify the bus has transferred the tx packet to firmware */
+ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1274,6 +1274,16 @@ void brcmf_dev_coredump(struct device *d
+ brcmf_dbg(TRACE, "failed to create coredump\n");
+ }
+
++void brcmf_fw_crashed(struct device *dev)
++{
++ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
++ struct brcmf_pub *drvr = bus_if->drvr;
++
++ bphy_err(drvr, "Firmware has halted or crashed\n");
++
++ brcmf_dev_coredump(dev);
++}
++
+ void brcmf_detach(struct device *dev)
+ {
+ s32 i;
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -728,7 +728,7 @@ static void brcmf_pcie_handle_mb_data(st
+ }
+ if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) {
+ brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n");
+- brcmf_dev_coredump(&devinfo->pdev->dev);
++ brcmf_fw_crashed(&devinfo->pdev->dev);
+ }
+ }
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -1097,8 +1097,8 @@ static u32 brcmf_sdio_hostmail(struct br
+
+ /* dongle indicates the firmware has halted/crashed */
+ if (hmb_data & HMB_DATA_FWHALT) {
+- brcmf_err("mailbox indicates firmware halted\n");
+- brcmf_dev_coredump(&sdiod->func[1]->dev);
++ brcmf_dbg(SDIO, "mailbox indicates firmware halted\n");
++ brcmf_fw_crashed(&sdiod->func[1]->dev);
+ }
+
+ /* Dongle recomposed rx frames, accept them again */
diff --git a/package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch b/package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch
new file mode 100644
index 0000000000..96692c99e5
--- /dev/null
+++ b/package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch
@@ -0,0 +1,160 @@
+From 4684997d9eea29380000e062755aa6d368d789a3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 26 Feb 2019 14:11:19 +0100
+Subject: [PATCH] brcmfmac: reset PCIe bus on a firmware crash
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This includes bus reset & reloading a firmware. It should be sufficient
+for a user space to (setup and) use a wireless device again.
+
+Support for reset on USB & SDIO can be added later.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/bus.h | 10 ++++++
+ .../broadcom/brcm80211/brcmfmac/core.c | 12 +++++++
+ .../broadcom/brcm80211/brcmfmac/core.h | 2 ++
+ .../broadcom/brcm80211/brcmfmac/pcie.c | 35 +++++++++++++++++++
+ 4 files changed, 59 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+@@ -87,6 +87,7 @@ 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 (*reset)(struct device *dev);
+ };
+
+
+@@ -214,6 +215,15 @@ int brcmf_bus_get_memdump(struct brcmf_b
+ return bus->ops->get_memdump(bus->dev, data, len);
+ }
+
++static inline
++int brcmf_bus_reset(struct brcmf_bus *bus)
++{
++ if (!bus->ops->reset)
++ return -EOPNOTSUPP;
++
++ return bus->ops->reset(bus->dev);
++}
++
+ /*
+ * interface functions from common layer
+ */
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1080,6 +1080,14 @@ static int brcmf_revinfo_read(struct seq
+ return 0;
+ }
+
++static void brcmf_core_bus_reset(struct work_struct *work)
++{
++ struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
++ bus_reset);
++
++ brcmf_bus_reset(drvr->bus_if);
++}
++
+ int brcmf_bus_started(struct device *dev)
+ {
+ int ret = -1;
+@@ -1161,6 +1169,8 @@ int brcmf_bus_started(struct device *dev
+ #endif
+ #endif /* CONFIG_INET */
+
++ INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset);
++
+ return 0;
+
+ fail:
+@@ -1282,6 +1292,8 @@ void brcmf_fw_crashed(struct device *dev
+ bphy_err(drvr, "Firmware has halted or crashed\n");
+
+ brcmf_dev_coredump(dev);
++
++ schedule_work(&drvr->bus_reset);
+ }
+
+ void brcmf_detach(struct device *dev)
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+@@ -146,6 +146,8 @@ struct brcmf_pub {
+ struct notifier_block inet6addr_notifier;
+ struct brcmf_mp_device *settings;
+
++ struct work_struct bus_reset;
++
+ /* Pointer needed by OpenWrt due to backporting some fixes */
+ void *cfg80211_ops;
+ };
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -343,6 +343,8 @@ static const u32 brcmf_ring_itemsize[BRC
+ BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE
+ };
+
++static void brcmf_pcie_setup(struct device *dev, const struct firmware *fw,
++ void *nvram, u32 nvram_len);
+
+ static u32
+ brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset)
+@@ -1382,6 +1384,45 @@ static int brcmf_pcie_get_memdump(struct
+ }
+
+
++static int brcmf_pcie_reset(struct device *dev)
++{
++ 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;
++ u16 domain_nr;
++ u16 bus_nr;
++ int err;
++
++ brcmf_detach(dev);
++
++ brcmf_pcie_release_irq(devinfo);
++ brcmf_pcie_release_scratchbuffers(devinfo);
++ brcmf_pcie_release_ringbuffers(devinfo);
++ brcmf_pcie_reset_device(devinfo);
++
++ err = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
++ brcmf_pcie_fwnames,
++ ARRAY_SIZE(brcmf_pcie_fwnames),
++ devinfo->fw_name, devinfo->nvram_name);
++ if (err) {
++ dev_err(dev, "Failed to prepare FW request\n");
++ return err;
++ }
++
++ domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
++ bus_nr = devinfo->pdev->bus->number;
++ err = brcmf_fw_get_firmwares_pcie(bus_if->dev, BRCMF_FW_REQUEST_NVRAM |
++ BRCMF_FW_REQ_NV_OPTIONAL,
++ devinfo->fw_name, devinfo->nvram_name,
++ brcmf_pcie_setup, domain_nr, bus_nr);
++ if (err) {
++ dev_err(dev, "Failed to prepare FW request\n");
++ return err;
++ }
++
++ return err;
++}
++
+ static const struct brcmf_bus_ops brcmf_pcie_bus_ops = {
+ .txdata = brcmf_pcie_tx,
+ .stop = brcmf_pcie_down,
+@@ -1390,6 +1431,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,
++ .reset = brcmf_pcie_reset,
+ };
+
+
diff --git a/package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch b/package/kernel/mac80211/patches/342-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch
index a6d5c34007..a6d5c34007 100644
--- a/package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch
+++ b/package/kernel/mac80211/patches/342-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch
diff --git a/package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch b/package/kernel/mac80211/patches/342-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch
index 80ad31ece6..80ad31ece6 100644
--- a/package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch
+++ b/package/kernel/mac80211/patches/342-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch
diff --git a/package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch b/package/kernel/mac80211/patches/342-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch
index 4c8d073914..4c8d073914 100644
--- a/package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch
+++ b/package/kernel/mac80211/patches/342-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch