c9757db976d777246ce3a549f61b561e89dab56a
[oweals/openwrt.git] /
1 From 4ab2cf03da91785f2c34d79a302e53da06928bc1 Mon Sep 17 00:00:00 2001
2 From: Arend van Spriel <arend.vanspriel@broadcom.com>
3 Date: Thu, 14 Feb 2019 13:43:51 +0100
4 Subject: [PATCH] brcmfmac: check and dump trap info during sdio probe
5
6 When the firmware crashes during the probe sequence we provide little
7 information on what really failed. This patch checks the sdpcm shared
8 location and show the trap information if a firmware trap has happened.
9
10 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
11 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
12 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
13 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
14 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
15 ---
16  .../broadcom/brcm80211/brcmfmac/sdio.c        | 59 +++++++++++++------
17  1 file changed, 40 insertions(+), 19 deletions(-)
18
19 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
20 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
21 @@ -3010,21 +3010,35 @@ static int brcmf_sdio_trap_info(struct s
22         if (error < 0)
23                 return error;
24  
25 -       seq_printf(seq,
26 -                  "dongle trap info: type 0x%x @ epc 0x%08x\n"
27 -                  "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
28 -                  "  lr   0x%08x pc   0x%08x offset 0x%x\n"
29 -                  "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
30 -                  "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
31 -                  le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
32 -                  le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
33 -                  le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
34 -                  le32_to_cpu(tr.pc), sh->trap_addr,
35 -                  le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
36 -                  le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
37 -                  le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
38 -                  le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
39 -
40 +       if (seq)
41 +               seq_printf(seq,
42 +                          "dongle trap info: type 0x%x @ epc 0x%08x\n"
43 +                          "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
44 +                          "  lr   0x%08x pc   0x%08x offset 0x%x\n"
45 +                          "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
46 +                          "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
47 +                          le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
48 +                          le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
49 +                          le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
50 +                          le32_to_cpu(tr.pc), sh->trap_addr,
51 +                          le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
52 +                          le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
53 +                          le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
54 +                          le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
55 +       else
56 +               pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n"
57 +                        "  cpsr 0x%08x spsr 0x%08x sp 0x%08x\n"
58 +                        "  lr   0x%08x pc   0x%08x offset 0x%x\n"
59 +                        "  r0   0x%08x r1   0x%08x r2 0x%08x r3 0x%08x\n"
60 +                        "  r4   0x%08x r5   0x%08x r6 0x%08x r7 0x%08x\n",
61 +                        le32_to_cpu(tr.type), le32_to_cpu(tr.epc),
62 +                        le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr),
63 +                        le32_to_cpu(tr.r13), le32_to_cpu(tr.r14),
64 +                        le32_to_cpu(tr.pc), sh->trap_addr,
65 +                        le32_to_cpu(tr.r0), le32_to_cpu(tr.r1),
66 +                        le32_to_cpu(tr.r2), le32_to_cpu(tr.r3),
67 +                        le32_to_cpu(tr.r4), le32_to_cpu(tr.r5),
68 +                        le32_to_cpu(tr.r6), le32_to_cpu(tr.r7));
69         return 0;
70  }
71  
72 @@ -3078,8 +3092,10 @@ static int brcmf_sdio_checkdied(struct b
73         else if (sh.flags & SDPCM_SHARED_ASSERT)
74                 brcmf_err("assertion in dongle\n");
75  
76 -       if (sh.flags & SDPCM_SHARED_TRAP)
77 +       if (sh.flags & SDPCM_SHARED_TRAP) {
78                 brcmf_err("firmware trap in dongle\n");
79 +               brcmf_sdio_trap_info(NULL, bus, &sh);
80 +       }
81  
82         return 0;
83  }
84 @@ -4210,7 +4226,7 @@ static void brcmf_sdio_firmware_callback
85         } else {
86                 /* Disable F2 again */
87                 sdio_disable_func(sdiod->func2);
88 -               goto release;
89 +               goto checkdied;
90         }
91  
92         if (brcmf_chip_sr_capable(bus->ci)) {
93 @@ -4231,8 +4247,10 @@ static void brcmf_sdio_firmware_callback
94         }
95  
96         /* If we didn't come up, turn off backplane clock */
97 -       if (err != 0)
98 +       if (err != 0) {
99                 brcmf_sdio_clkctl(bus, CLK_NONE, false);
100 +               goto checkdied;
101 +       }
102  
103         sdio_release_host(sdiod->func1);
104  
105 @@ -4246,12 +4264,15 @@ static void brcmf_sdio_firmware_callback
106         err = brcmf_attach(sdiod->dev, sdiod->settings);
107         if (err != 0) {
108                 brcmf_err("brcmf_attach failed\n");
109 -               goto fail;
110 +               sdio_claim_host(sdiod->func1);
111 +               goto checkdied;
112         }
113  
114         /* ready */
115         return;
116  
117 +checkdied:
118 +       brcmf_sdio_checkdied(bus);
119  release:
120         sdio_release_host(sdiod->func1);
121  fail: