mac80211: backport brcmfmac firmware & clm_blob loading rework
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch
1 From 2baa3aaee27f137b8db9a9224d0fe9b281d28e34 Mon Sep 17 00:00:00 2001
2 From: Arend Van Spriel <arend.vanspriel@broadcom.com>
3 Date: Thu, 22 Mar 2018 21:28:27 +0100
4 Subject: [PATCH] brcmfmac: introduce brcmf_fw_alloc_request() function
5
6 The function brcmf_fw_alloc_request() takes a list of required files
7 and allocated the struct brcmf_fw_request instance accordingly. The
8 request can be modified by the caller before being passed to the
9 brcmf_fw_request_firmwares() function.
10
11 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
13 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
16 ---
17  .../broadcom/brcm80211/brcmfmac/firmware.c         | 58 ++++++++++++++++++++++
18  .../broadcom/brcm80211/brcmfmac/firmware.h         | 11 ++++
19  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 58 ++++++++++++----------
20  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    | 38 ++++++++------
21  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 42 +++++++++-------
22  5 files changed, 147 insertions(+), 60 deletions(-)
23
24 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
25 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
26 @@ -688,3 +688,61 @@ int brcmf_fw_map_chip_to_name(u32 chip,
27         return 0;
28  }
29  
30 +struct brcmf_fw_request *
31 +brcmf_fw_alloc_request(u32 chip, u32 chiprev,
32 +                      struct brcmf_firmware_mapping mapping_table[],
33 +                      u32 table_size, struct brcmf_fw_name *fwnames,
34 +                      u32 n_fwnames)
35 +{
36 +       struct brcmf_fw_request *fwreq;
37 +       char chipname[12];
38 +       const char *mp_path;
39 +       u32 i, j;
40 +       char end;
41 +       size_t reqsz;
42 +
43 +       for (i = 0; i < table_size; i++) {
44 +               if (mapping_table[i].chipid == chip &&
45 +                   mapping_table[i].revmask & BIT(chiprev))
46 +                       break;
47 +       }
48 +
49 +       if (i == table_size) {
50 +               brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev);
51 +               return NULL;
52 +       }
53 +
54 +       reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item);
55 +       fwreq = kzalloc(reqsz, GFP_KERNEL);
56 +       if (!fwreq)
57 +               return NULL;
58 +
59 +       brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname));
60 +
61 +       brcmf_info("using %s for chip %s\n",
62 +                  mapping_table[i].fw_base, chipname);
63 +
64 +       mp_path = brcmf_mp_global.firmware_path;
65 +       end = mp_path[strlen(mp_path) - 1];
66 +       fwreq->n_items = n_fwnames;
67 +
68 +       for (j = 0; j < n_fwnames; j++) {
69 +               fwreq->items[j].path = fwnames[j].path;
70 +               /* check if firmware path is provided by module parameter */
71 +               if (brcmf_mp_global.firmware_path[0] != '\0') {
72 +                       strlcpy(fwnames[j].path, mp_path,
73 +                               BRCMF_FW_NAME_LEN);
74 +
75 +                       if (end != '/') {
76 +                               strlcat(fwnames[j].path, "/",
77 +                                       BRCMF_FW_NAME_LEN);
78 +                       }
79 +               }
80 +               brcmf_fw_get_full_name(fwnames[j].path,
81 +                                      mapping_table[i].fw_base,
82 +                                      fwnames[j].extension);
83 +               fwreq->items[j].path = fwnames[j].path;
84 +       }
85 +
86 +       return fwreq;
87 +}
88 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
89 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
90 @@ -77,6 +77,17 @@ struct brcmf_fw_request {
91         struct brcmf_fw_item items[0];
92  };
93  
94 +struct brcmf_fw_name {
95 +       const char *extension;
96 +       char *path;
97 +};
98 +
99 +struct brcmf_fw_request *
100 +brcmf_fw_alloc_request(u32 chip, u32 chiprev,
101 +                      struct brcmf_firmware_mapping mapping_table[],
102 +                      u32 table_size, struct brcmf_fw_name *fwnames,
103 +                      u32 n_fwnames);
104 +
105  /*
106   * Request firmware(s) asynchronously. When the asynchronous request
107   * fails it will not use the callback, but call device_release_driver()
108 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
109 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
110 @@ -1735,6 +1735,31 @@ fail:
111         device_release_driver(dev);
112  }
113  
114 +static struct brcmf_fw_request *
115 +brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo)
116 +{
117 +       struct brcmf_fw_request *fwreq;
118 +       struct brcmf_fw_name fwnames[] = {
119 +               { ".bin", devinfo->fw_name },
120 +               { ".txt", devinfo->nvram_name },
121 +       };
122 +
123 +       fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev,
124 +                                      brcmf_pcie_fwnames,
125 +                                      ARRAY_SIZE(brcmf_pcie_fwnames),
126 +                                      fwnames, ARRAY_SIZE(fwnames));
127 +       if (!fwreq)
128 +               return NULL;
129 +
130 +       fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
131 +       fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
132 +       fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
133 +       fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus);
134 +       fwreq->bus_nr = devinfo->pdev->bus->number;
135 +
136 +       return fwreq;
137 +}
138 +
139  static int
140  brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
141  {
142 @@ -1743,13 +1768,8 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
143         struct brcmf_pciedev_info *devinfo;
144         struct brcmf_pciedev *pcie_bus_dev;
145         struct brcmf_bus *bus;
146 -       u16 domain_nr;
147 -       u16 bus_nr;
148  
149 -       domain_nr = pci_domain_nr(pdev->bus) + 1;
150 -       bus_nr = pdev->bus->number;
151 -       brcmf_dbg(PCIE, "Enter %x:%x (%d/%d)\n", pdev->vendor, pdev->device,
152 -                 domain_nr, bus_nr);
153 +       brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device);
154  
155         ret = -ENOMEM;
156         devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL);
157 @@ -1803,33 +1823,19 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
158         bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot);
159         dev_set_drvdata(&pdev->dev, bus);
160  
161 -       ret = brcmf_fw_map_chip_to_name(devinfo->ci->chip, devinfo->ci->chiprev,
162 -                                       brcmf_pcie_fwnames,
163 -                                       ARRAY_SIZE(brcmf_pcie_fwnames),
164 -                                       devinfo->fw_name, devinfo->nvram_name);
165 -       if (ret)
166 -               goto fail_bus;
167 -
168 -       fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
169 -                       GFP_KERNEL);
170 +       fwreq = brcmf_pcie_prepare_fw_request(devinfo);
171         if (!fwreq) {
172                 ret = -ENOMEM;
173                 goto fail_bus;
174         }
175  
176 -       fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name;
177 -       fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
178 -       fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name;
179 -       fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
180 -       fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
181 -       fwreq->n_items = 2;
182 -       fwreq->domain_nr = domain_nr;
183 -       fwreq->bus_nr = bus_nr;
184         ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup);
185 -       if (ret == 0)
186 -               return 0;
187 +       if (ret < 0) {
188 +               kfree(fwreq);
189 +               goto fail_bus;
190 +       }
191 +       return 0;
192  
193 -       kfree(fwreq);
194  fail_bus:
195         kfree(bus->msgbuf);
196         kfree(bus);
197 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
198 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
199 @@ -4155,6 +4155,28 @@ fail:
200         device_release_driver(dev);
201  }
202  
203 +static struct brcmf_fw_request *
204 +brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus)
205 +{
206 +       struct brcmf_fw_request *fwreq;
207 +       struct brcmf_fw_name fwnames[] = {
208 +               { ".bin", bus->sdiodev->fw_name },
209 +               { ".txt", bus->sdiodev->nvram_name },
210 +       };
211 +
212 +       fwreq = brcmf_fw_alloc_request(bus->ci->chip, bus->ci->chiprev,
213 +                                      brcmf_sdio_fwnames,
214 +                                      ARRAY_SIZE(brcmf_sdio_fwnames),
215 +                                      fwnames, ARRAY_SIZE(fwnames));
216 +       if (!fwreq)
217 +               return NULL;
218 +
219 +       fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
220 +       fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
221 +
222 +       return fwreq;
223 +}
224 +
225  struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
226  {
227         int ret;
228 @@ -4244,26 +4266,12 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
229  
230         brcmf_dbg(INFO, "completed!!\n");
231  
232 -       ret = brcmf_fw_map_chip_to_name(bus->ci->chip, bus->ci->chiprev,
233 -                                       brcmf_sdio_fwnames,
234 -                                       ARRAY_SIZE(brcmf_sdio_fwnames),
235 -                                       sdiodev->fw_name, sdiodev->nvram_name);
236 -       if (ret)
237 -               goto fail;
238 -
239 -       fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
240 -                       GFP_KERNEL);
241 +       fwreq = brcmf_sdio_prepare_fw_request(bus);
242         if (!fwreq) {
243                 ret = -ENOMEM;
244                 goto fail;
245         }
246  
247 -       fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name;
248 -       fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
249 -       fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name;
250 -       fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
251 -       fwreq->n_items = 2;
252 -
253         ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
254                                      brcmf_sdio_firmware_callback);
255         if (ret != 0) {
256 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
257 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
258 @@ -1200,6 +1200,27 @@ error:
259         device_release_driver(dev);
260  }
261  
262 +static struct brcmf_fw_request *
263 +brcmf_usb_prepare_fw_request(struct brcmf_usbdev_info *devinfo)
264 +{
265 +       struct brcmf_fw_request *fwreq;
266 +       struct brcmf_fw_name fwnames[] = {
267 +               { ".bin", devinfo->fw_name },
268 +       };
269 +
270 +       fwreq = brcmf_fw_alloc_request(devinfo->bus_pub.devid,
271 +                                      devinfo->bus_pub.chiprev,
272 +                                      brcmf_usb_fwnames,
273 +                                      ARRAY_SIZE(brcmf_usb_fwnames),
274 +                                      fwnames, ARRAY_SIZE(fwnames));
275 +       if (!fwreq)
276 +               return NULL;
277 +
278 +       fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
279 +
280 +       return fwreq;
281 +}
282 +
283  static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
284  {
285         struct brcmf_bus *bus = NULL;
286 @@ -1249,24 +1270,12 @@ static int brcmf_usb_probe_cb(struct brc
287         bus->chip = bus_pub->devid;
288         bus->chiprev = bus_pub->chiprev;
289  
290 -       ret = brcmf_fw_map_chip_to_name(bus_pub->devid, bus_pub->chiprev,
291 -                                       brcmf_usb_fwnames,
292 -                                       ARRAY_SIZE(brcmf_usb_fwnames),
293 -                                       devinfo->fw_name, NULL);
294 -       if (ret)
295 -               goto fail;
296 -
297 -       fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
298 -                       GFP_KERNEL);
299 +       fwreq = brcmf_usb_prepare_fw_request(devinfo);
300         if (!fwreq) {
301                 ret = -ENOMEM;
302                 goto fail;
303         }
304  
305 -       fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
306 -       fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
307 -       fwreq->n_items = 1;
308 -
309         /* request firmware here */
310         ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
311         if (ret) {
312 @@ -1469,15 +1478,10 @@ static int brcmf_usb_reset_resume(struct
313  
314         brcmf_dbg(USB, "Enter\n");
315  
316 -       fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
317 -                       GFP_KERNEL);
318 +       fwreq = brcmf_usb_prepare_fw_request(devinfo);
319         if (!fwreq)
320                 return -ENOMEM;
321  
322 -       fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
323 -       fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
324 -       fwreq->n_items = 1;
325 -
326         ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
327         if (ret < 0)
328                 kfree(fwreq);