From d3bab051cfd1f2f5791e4352309c51f5e29b678f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 18 Apr 2019 12:37:10 +0200 Subject: [PATCH] mac80211: brcmfmac: really add early fw crash recovery MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 2d2e615dee0421e126af9d4ebd49a720e341e3af) --- ...-repeated-brcmf_fw_alloc_request-cal.patch | 32 ++++ ...unction-designated-for-handling-firm.patch | 79 +++++++++ ...c-reset-PCIe-bus-on-a-firmware-crash.patch | 160 ++++++++++++++++++ ...-during-disconnect-when-USB-complet.patch} | 0 ...ending-parameter-from-brcmf_usb_fre.patch} | 0 ...nused-variable-i-from-brcmf_usb_fre.patch} | 0 6 files changed, 271 insertions(+) create mode 100644 package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch create mode 100644 package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch create mode 100644 package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch rename package/kernel/mac80211/patches/{340-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch => 342-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch} (100%) rename package/kernel/mac80211/patches/{340-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch => 342-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch} (100%) rename package/kernel/mac80211/patches/{340-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch => 342-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch} (100%) 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?= +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 +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + 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?= +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 +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + 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?= +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 +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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 similarity index 100% rename from package/kernel/mac80211/patches/340-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch rename to 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 similarity index 100% rename from package/kernel/mac80211/patches/340-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch rename to 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 similarity index 100% rename from package/kernel/mac80211/patches/340-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch rename to package/kernel/mac80211/patches/342-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch -- 2.30.2