mac80211: backport more brcmfmac changes queued for the 5.1
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / brcm / 349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch
diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch
new file mode 100644 (file)
index 0000000..dce4331
--- /dev/null
@@ -0,0 +1,121 @@
+From 4ab2cf03da91785f2c34d79a302e53da06928bc1 Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 14 Feb 2019 13:43:51 +0100
+Subject: [PATCH] brcmfmac: check and dump trap info during sdio probe
+
+When the firmware crashes during the probe sequence we provide little
+information on what really failed. This patch checks the sdpcm shared
+location and show the trap information if a firmware trap has happened.
+
+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>
+---
+ .../broadcom/brcm80211/brcmfmac/sdio.c        | 59 +++++++++++++------
+ 1 file changed, 40 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -2999,21 +2999,35 @@ static int brcmf_sdio_trap_info(struct s
+       if (error < 0)
+               return error;
+-      seq_printf(seq,
+-                 "dongle trap info: type 0x%x @ epc 0x%08x\n"
+-                 "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
+-                 "  lr   0x%08x pc   0x%08x offset 0x%x\n"
+-                 "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
+-                 "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
+-                 le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
+-                 le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
+-                 le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
+-                 le32_to_cpu(tr.pc), sh->trap_addr,
+-                 le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
+-                 le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
+-                 le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
+-                 le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
+-
++      if (seq)
++              seq_printf(seq,
++                         "dongle trap info: type 0x%x @ epc 0x%08x\n"
++                         "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
++                         "  lr   0x%08x pc   0x%08x offset 0x%x\n"
++                         "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
++                         "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
++                         le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
++                         le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
++                         le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
++                         le32_to_cpu(tr.pc), sh->trap_addr,
++                         le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
++                         le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
++                         le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
++                         le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
++      else
++              pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n"
++                       "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
++                       "  lr   0x%08x pc   0x%08x offset 0x%x\n"
++                       "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
++                       "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
++                       le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
++                       le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
++                       le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
++                       le32_to_cpu(tr.pc), sh->trap_addr,
++                       le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
++                       le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
++                       le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
++                       le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
+       return 0;
+ }
+@@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct b
+       else if (sh.flags & SDPCM_SHARED_ASSERT)
+               brcmf_err("assertion in dongle\n");
+-      if (sh.flags & SDPCM_SHARED_TRAP)
++      if (sh.flags & SDPCM_SHARED_TRAP) {
+               brcmf_err("firmware trap in dongle\n");
++              brcmf_sdio_trap_info(NULL, bus, &sh);
++      }
+       return 0;
+ }
+@@ -4199,7 +4215,7 @@ static void brcmf_sdio_firmware_callback
+       } else {
+               /* Disable F2 again */
+               sdio_disable_func(sdiod->func2);
+-              goto release;
++              goto checkdied;
+       }
+       if (brcmf_chip_sr_capable(bus->ci)) {
+@@ -4220,8 +4236,10 @@ static void brcmf_sdio_firmware_callback
+       }
+       /* If we didn't come up, turn off backplane clock */
+-      if (err != 0)
++      if (err != 0) {
+               brcmf_sdio_clkctl(bus, CLK_NONE, false);
++              goto checkdied;
++      }
+       sdio_release_host(sdiod->func1);
+@@ -4235,12 +4253,15 @@ static void brcmf_sdio_firmware_callback
+       err = brcmf_attach(sdiod->dev, sdiod->settings);
+       if (err != 0) {
+               brcmf_err("brcmf_attach failed\n");
+-              goto fail;
++              sdio_claim_host(sdiod->func1);
++              goto checkdied;
+       }
+       /* ready */
+       return;
++checkdied:
++      brcmf_sdio_checkdied(bus);
+ release:
+       sdio_release_host(sdiod->func1);
+ fail: