mac80211: Update to version 5.15.58-1
[openwrt/staging/dangole.git] / package / kernel / mac80211 / patches / brcm / 865-brcmfmac-Read-alternative-firmware-names-from-DT.patch
1 From 4e32024cbb14230af3048e249e84f8c2b25ce45a Mon Sep 17 00:00:00 2001
2 From: Phil Elwell <phil@raspberrypi.com>
3 Date: Thu, 28 Oct 2021 15:03:16 +0100
4 Subject: [PATCH] brcmfmac: Read alternative firmware names from DT
5
6 Add the ability to load the names of alternative firmwares from the
7 Device Tree node. This permits separate firmwares for 43436s and 43438
8 and allows downstream firmwares to coexist with upstream.
9
10 Signed-off-by: Phil Elwell <phil@raspberrypi.com>
11 ---
12 .../wireless/broadcom/brcm80211/brcmfmac/of.c | 36 ++++++++++++++
13 .../wireless/broadcom/brcm80211/brcmfmac/of.h | 7 +++
14 .../broadcom/brcm80211/brcmfmac/sdio.c | 47 +++++++++++++++++--
15 3 files changed, 87 insertions(+), 3 deletions(-)
16
17 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
18 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
19 @@ -11,6 +11,7 @@
20 #include "debug.h"
21 #include "core.h"
22 #include "common.h"
23 +#include "firmware.h"
24 #include "of.h"
25
26 static int brcmf_of_get_country_codes(struct device *dev,
27 @@ -153,3 +154,38 @@ void brcmf_of_probe(struct device *dev,
28 sdio->oob_irq_nr = irq;
29 sdio->oob_irq_flags = irqf;
30 }
31 +
32 +struct brcmf_firmware_mapping *
33 +brcmf_of_fwnames(struct device *dev, u32 *fwname_count)
34 +{
35 + struct device_node *np = dev->of_node;
36 + struct brcmf_firmware_mapping *fwnames;
37 + struct device_node *map_np, *fw_np;
38 + int of_count;
39 + int count = 0;
40 +
41 + map_np = of_get_child_by_name(np, "firmwares");
42 + of_count = of_get_child_count(map_np);
43 + if (!of_count)
44 + return NULL;
45 +
46 + fwnames = devm_kcalloc(dev, of_count,
47 + sizeof(struct brcmf_firmware_mapping),
48 + GFP_KERNEL);
49 +
50 + for_each_child_of_node(map_np, fw_np)
51 + {
52 + struct brcmf_firmware_mapping *cur = &fwnames[count];
53 +
54 + if (of_property_read_u32(fw_np, "chipid", &cur->chipid) ||
55 + of_property_read_u32(fw_np, "revmask", &cur->revmask))
56 + continue;
57 + cur->fw_base = of_get_property(fw_np, "fw_base", NULL);
58 + if (cur->fw_base)
59 + count++;
60 + }
61 +
62 + *fwname_count = count;
63 +
64 + return count ? fwnames : NULL;
65 +}
66 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
67 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h
68 @@ -5,9 +5,16 @@
69 #ifdef CONFIG_OF
70 void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
71 struct brcmf_mp_device *settings);
72 +struct brcmf_firmware_mapping *
73 +brcmf_of_fwnames(struct device *dev, u32 *map_count);
74 #else
75 static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
76 struct brcmf_mp_device *settings)
77 {
78 }
79 +static struct brcmf_firmware_mapping *
80 +brcmf_of_fwnames(struct device *dev, u32 *map_count)
81 +{
82 + return NULL;
83 +}
84 #endif /* CONFIG_OF */
85 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
86 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
87 @@ -35,6 +35,7 @@
88 #include "core.h"
89 #include "common.h"
90 #include "bcdc.h"
91 +#include "of.h"
92
93 #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500)
94 #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500)
95 @@ -633,7 +634,7 @@ MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "b
96 /* per-board firmware binaries */
97 MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-sdio.*.bin");
98
99 -static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
100 +static const struct brcmf_firmware_mapping sdio_fwnames[] = {
101 BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
102 BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x0000001F, 43241B0),
103 BRCMF_FW_ENTRY(BRCM_CC_43241_CHIP_ID, 0x00000020, 43241B4),
104 @@ -659,6 +660,9 @@ static const struct brcmf_firmware_mappi
105 BRCMF_FW_ENTRY(CY_CC_43752_CHIP_ID, 0xFFFFFFFF, 43752)
106 };
107
108 +static const struct brcmf_firmware_mapping *brcmf_sdio_fwnames = sdio_fwnames;
109 +static u32 brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames);
110 +
111 #define TXCTL_CREDITS 2
112
113 static void pkt_align(struct sk_buff *p, int len, int align)
114 @@ -4140,7 +4144,7 @@ int brcmf_sdio_get_fwname(struct device
115
116 fwreq = brcmf_fw_alloc_request(bus_if->chip, bus_if->chiprev,
117 brcmf_sdio_fwnames,
118 - ARRAY_SIZE(brcmf_sdio_fwnames),
119 + brcmf_sdio_fwnames_count,
120 fwnames, ARRAY_SIZE(fwnames));
121 if (!fwreq)
122 return -ENOMEM;
123 @@ -4196,6 +4200,9 @@ static const struct brcmf_bus_ops brcmf_
124 #define BRCMF_SDIO_FW_CODE 0
125 #define BRCMF_SDIO_FW_NVRAM 1
126
127 +static struct brcmf_fw_request *
128 +brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus);
129 +
130 static void brcmf_sdio_firmware_callback(struct device *dev, int err,
131 struct brcmf_fw_request *fwreq)
132 {
133 @@ -4211,6 +4218,22 @@ static void brcmf_sdio_firmware_callback
134
135 brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
136
137 + if (err && brcmf_sdio_fwnames != sdio_fwnames) {
138 + /* Try again with the standard firmware names */
139 + brcmf_sdio_fwnames = sdio_fwnames;
140 + brcmf_sdio_fwnames_count = ARRAY_SIZE(sdio_fwnames);
141 + kfree(fwreq);
142 + fwreq = brcmf_sdio_prepare_fw_request(bus);
143 + if (!fwreq) {
144 + err = -ENOMEM;
145 + goto fail;
146 + }
147 + err = brcmf_fw_get_firmwares(dev, fwreq,
148 + brcmf_sdio_firmware_callback);
149 + if (!err)
150 + return;
151 + }
152 +
153 if (err)
154 goto fail;
155
156 @@ -4419,7 +4442,7 @@ brcmf_sdio_prepare_fw_request(struct brc
157
158 fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
159 brcmf_sdio_fwnames,
160 - ARRAY_SIZE(brcmf_sdio_fwnames),
161 + brcmf_sdio_fwnames_count,
162 fwnames, ARRAY_SIZE(fwnames));
163 if (!fwreq)
164 return NULL;
165 @@ -4437,6 +4460,9 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
166 struct brcmf_sdio *bus;
167 struct workqueue_struct *wq;
168 struct brcmf_fw_request *fwreq;
169 + struct brcmf_firmware_mapping *of_fwnames, *fwnames = NULL;
170 + const int fwname_size = sizeof(struct brcmf_firmware_mapping);
171 + u32 of_fw_count;
172
173 brcmf_dbg(TRACE, "Enter\n");
174
175 @@ -4519,6 +4545,21 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
176
177 brcmf_dbg(INFO, "completed!!\n");
178
179 + of_fwnames = brcmf_of_fwnames(sdiodev->dev, &of_fw_count);
180 + if (of_fwnames)
181 + fwnames = devm_kcalloc(sdiodev->dev,
182 + of_fw_count + brcmf_sdio_fwnames_count,
183 + fwname_size, GFP_KERNEL);
184 +
185 + if (fwnames) {
186 + /* The array is scanned in order, so overrides come first */
187 + memcpy(fwnames, of_fwnames, of_fw_count * fwname_size);
188 + memcpy(fwnames + of_fw_count, sdio_fwnames,
189 + brcmf_sdio_fwnames_count * fwname_size);
190 + brcmf_sdio_fwnames = fwnames;
191 + brcmf_sdio_fwnames_count += of_fw_count;
192 + }
193 +
194 fwreq = brcmf_sdio_prepare_fw_request(bus);
195 if (!fwreq) {
196 ret = -ENOMEM;