mac80211: backport brcmfmac firmware & clm_blob loading rework
[oweals/openwrt.git] / package / kernel / mac80211 / patches / 327-v4.17-0007-brcmfmac-pass-struct-in-brcmf_fw_get_firmwares.patch
1 From d09ae51a4b676151edaf572bcd5f272b5532639f Mon Sep 17 00:00:00 2001
2 From: Arend Van Spriel <arend.vanspriel@broadcom.com>
3 Date: Thu, 22 Mar 2018 21:28:26 +0100
4 Subject: [PATCH] brcmfmac: pass struct in brcmf_fw_get_firmwares()
5
6 Make the function brcmf_fw_get_firmwares() a bit more easy to extend
7 using a structure to pass the request parameters.
8
9 Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
10 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
11 Reviewed-by: Franky Lin <franky.lin@broadcom.com>
12 Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
13 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
14 ---
15  .../broadcom/brcm80211/brcmfmac/firmware.c         | 175 ++++++++++++++-------
16  .../broadcom/brcm80211/brcmfmac/firmware.h         |  43 +++--
17  .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    |  38 ++++-
18  .../wireless/broadcom/brcm80211/brcmfmac/sdio.c    |  32 +++-
19  .../net/wireless/broadcom/brcm80211/brcmfmac/usb.c |  43 ++++-
20  5 files changed, 245 insertions(+), 86 deletions(-)
21
22 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
23 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
24 @@ -438,18 +438,31 @@ void brcmf_fw_nvram_free(void *nvram)
25  
26  struct brcmf_fw {
27         struct device *dev;
28 -       u16 flags;
29 -       const struct firmware *code;
30 -       const char *nvram_name;
31 -       u16 domain_nr;
32 -       u16 bus_nr;
33 -       void (*done)(struct device *dev, int err, const struct firmware *fw,
34 -                    void *nvram_image, u32 nvram_len);
35 +       struct brcmf_fw_request *req;
36 +       u32 curpos;
37 +       void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
38  };
39  
40 +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
41 +
42 +static void brcmf_fw_free_request(struct brcmf_fw_request *req)
43 +{
44 +       struct brcmf_fw_item *item;
45 +       int i;
46 +
47 +       for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) {
48 +               if (item->type == BRCMF_FW_TYPE_BINARY)
49 +                       release_firmware(item->binary);
50 +               else if (item->type == BRCMF_FW_TYPE_NVRAM)
51 +                       brcmf_fw_nvram_free(item->nv_data.data);
52 +       }
53 +       kfree(req);
54 +}
55 +
56  static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
57  {
58         struct brcmf_fw *fwctx = ctx;
59 +       struct brcmf_fw_item *cur;
60         u32 nvram_length = 0;
61         void *nvram = NULL;
62         u8 *data = NULL;
63 @@ -457,83 +470,150 @@ static void brcmf_fw_request_nvram_done(
64         bool raw_nvram;
65  
66         brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
67 +
68 +       cur = &fwctx->req->items[fwctx->curpos];
69 +
70         if (fw && fw->data) {
71                 data = (u8 *)fw->data;
72                 data_len = fw->size;
73                 raw_nvram = false;
74         } else {
75                 data = bcm47xx_nvram_get_contents(&data_len);
76 -               if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
77 +               if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
78                         goto fail;
79                 raw_nvram = true;
80         }
81  
82         if (data)
83                 nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
84 -                                            fwctx->domain_nr, fwctx->bus_nr);
85 +                                            fwctx->req->domain_nr,
86 +                                            fwctx->req->bus_nr);
87  
88         if (raw_nvram)
89                 bcm47xx_nvram_release_contents(data);
90         release_firmware(fw);
91 -       if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
92 +       if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
93                 goto fail;
94  
95 -       fwctx->done(fwctx->dev, 0, fwctx->code, nvram, nvram_length);
96 -       kfree(fwctx);
97 +       brcmf_dbg(TRACE, "nvram %p len %d\n", nvram, nvram_length);
98 +       cur->nv_data.data = nvram;
99 +       cur->nv_data.len = nvram_length;
100         return;
101  
102  fail:
103         brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
104 -       release_firmware(fwctx->code);
105 -       fwctx->done(fwctx->dev, -ENOENT, NULL, NULL, 0);
106 +       fwctx->done(fwctx->dev, -ENOENT, NULL);
107 +       brcmf_fw_free_request(fwctx->req);
108         kfree(fwctx);
109  }
110  
111 -static void brcmf_fw_request_code_done(const struct firmware *fw, void *ctx)
112 +static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
113 +{
114 +       struct brcmf_fw_item *cur;
115 +       const struct firmware *fw = NULL;
116 +       int ret;
117 +
118 +       cur = &fwctx->req->items[fwctx->curpos];
119 +
120 +       brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
121 +                 cur->path);
122 +
123 +       if (async)
124 +               ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
125 +                                             fwctx->dev, GFP_KERNEL, fwctx,
126 +                                             brcmf_fw_request_done);
127 +       else
128 +               ret = request_firmware(&fw, cur->path, fwctx->dev);
129 +
130 +       if (ret < 0) {
131 +               brcmf_fw_request_done(NULL, fwctx);
132 +       } else if (!async && fw) {
133 +               brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path,
134 +                         fw ? "" : "not ");
135 +               if (cur->type == BRCMF_FW_TYPE_BINARY)
136 +                       cur->binary = fw;
137 +               else if (cur->type == BRCMF_FW_TYPE_NVRAM)
138 +                       brcmf_fw_request_nvram_done(fw, fwctx);
139 +               else
140 +                       release_firmware(fw);
141 +
142 +               return -EAGAIN;
143 +       }
144 +       return 0;
145 +}
146 +
147 +static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
148  {
149         struct brcmf_fw *fwctx = ctx;
150 +       struct brcmf_fw_item *cur;
151         int ret = 0;
152  
153 -       brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
154 -       if (!fw) {
155 +       cur = &fwctx->req->items[fwctx->curpos];
156 +
157 +       brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
158 +                 fw ? "" : "not ");
159 +
160 +       if (fw) {
161 +               if (cur->type == BRCMF_FW_TYPE_BINARY)
162 +                       cur->binary = fw;
163 +               else if (cur->type == BRCMF_FW_TYPE_NVRAM)
164 +                       brcmf_fw_request_nvram_done(fw, fwctx);
165 +               else
166 +                       release_firmware(fw);
167 +       } else if (cur->type == BRCMF_FW_TYPE_NVRAM) {
168 +               brcmf_fw_request_nvram_done(NULL, fwctx);
169 +       } else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL)) {
170                 ret = -ENOENT;
171                 goto fail;
172         }
173 -       /* only requested code so done here */
174 -       if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM))
175 -               goto done;
176 -
177 -       fwctx->code = fw;
178 -       ret = request_firmware_nowait(THIS_MODULE, true, fwctx->nvram_name,
179 -                                     fwctx->dev, GFP_KERNEL, fwctx,
180 -                                     brcmf_fw_request_nvram_done);
181  
182 -       /* pass NULL to nvram callback for bcm47xx fallback */
183 -       if (ret)
184 -               brcmf_fw_request_nvram_done(NULL, fwctx);
185 +       do {
186 +               if (++fwctx->curpos == fwctx->req->n_items) {
187 +                       ret = 0;
188 +                       goto done;
189 +               }
190 +
191 +               ret = brcmf_fw_request_next_item(fwctx, false);
192 +       } while (ret == -EAGAIN);
193 +
194         return;
195  
196  fail:
197 -       brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
198 +       brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
199 +                 dev_name(fwctx->dev), cur->path);
200 +       brcmf_fw_free_request(fwctx->req);
201 +       fwctx->req = NULL;
202  done:
203 -       fwctx->done(fwctx->dev, ret, fw, NULL, 0);
204 +       fwctx->done(fwctx->dev, ret, fwctx->req);
205         kfree(fwctx);
206  }
207  
208 -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
209 -                               const char *code, const char *nvram,
210 -                               void (*fw_cb)(struct device *dev, int err,
211 -                                             const struct firmware *fw,
212 -                                             void *nvram_image, u32 nvram_len),
213 -                               u16 domain_nr, u16 bus_nr)
214 +static bool brcmf_fw_request_is_valid(struct brcmf_fw_request *req)
215 +{
216 +       struct brcmf_fw_item *item;
217 +       int i;
218 +
219 +       if (!req->n_items)
220 +               return false;
221 +
222 +       for (i = 0, item = &req->items[0]; i < req->n_items; i++, item++) {
223 +               if (!item->path)
224 +                       return false;
225 +       }
226 +       return true;
227 +}
228 +
229 +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
230 +                          void (*fw_cb)(struct device *dev, int err,
231 +                                        struct brcmf_fw_request *req))
232  {
233         struct brcmf_fw *fwctx;
234  
235         brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
236 -       if (!fw_cb || !code)
237 +       if (!fw_cb)
238                 return -EINVAL;
239  
240 -       if ((flags & BRCMF_FW_REQUEST_NVRAM) && !nvram)
241 +       if (!brcmf_fw_request_is_valid(req))
242                 return -EINVAL;
243  
244         fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL);
245 @@ -541,26 +621,11 @@ int brcmf_fw_get_firmwares_pcie(struct d
246                 return -ENOMEM;
247  
248         fwctx->dev = dev;
249 -       fwctx->flags = flags;
250 +       fwctx->req = req;
251         fwctx->done = fw_cb;
252 -       if (flags & BRCMF_FW_REQUEST_NVRAM)
253 -               fwctx->nvram_name = nvram;
254 -       fwctx->domain_nr = domain_nr;
255 -       fwctx->bus_nr = bus_nr;
256 -
257 -       return request_firmware_nowait(THIS_MODULE, true, code, dev,
258 -                                      GFP_KERNEL, fwctx,
259 -                                      brcmf_fw_request_code_done);
260 -}
261  
262 -int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
263 -                          const char *code, const char *nvram,
264 -                          void (*fw_cb)(struct device *dev, int err,
265 -                                        const struct firmware *fw,
266 -                                        void *nvram_image, u32 nvram_len))
267 -{
268 -       return brcmf_fw_get_firmwares_pcie(dev, flags, code, nvram, fw_cb, 0,
269 -                                          0);
270 +       brcmf_fw_request_next_item(fwctx, true);
271 +       return 0;
272  }
273  
274  static void brcmf_fw_get_full_name(char fw_name[BRCMF_FW_NAME_LEN],
275 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
276 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
277 @@ -16,10 +16,7 @@
278  #ifndef BRCMFMAC_FIRMWARE_H
279  #define BRCMFMAC_FIRMWARE_H
280  
281 -#define BRCMF_FW_REQUEST               0x000F
282 -#define  BRCMF_FW_REQUEST_NVRAM                0x0001
283 -#define BRCMF_FW_REQ_FLAGS             0x00F0
284 -#define  BRCMF_FW_REQ_NV_OPTIONAL      0x0010
285 +#define BRCMF_FW_REQF_OPTIONAL         0x0001
286  
287  #define        BRCMF_FW_NAME_LEN               320
288  
289 @@ -54,21 +51,39 @@ int brcmf_fw_map_chip_to_name(u32 chip,
290                               u32 table_size, char fw_name[BRCMF_FW_NAME_LEN],
291                               char nvram_name[BRCMF_FW_NAME_LEN]);
292  void brcmf_fw_nvram_free(void *nvram);
293 +
294 +enum brcmf_fw_type {
295 +       BRCMF_FW_TYPE_BINARY,
296 +       BRCMF_FW_TYPE_NVRAM
297 +};
298 +
299 +struct brcmf_fw_item {
300 +       const char *path;
301 +       enum brcmf_fw_type type;
302 +       u16 flags;
303 +       union {
304 +               const struct firmware *binary;
305 +               struct {
306 +                       void *data;
307 +                       u32 len;
308 +               } nv_data;
309 +       };
310 +};
311 +
312 +struct brcmf_fw_request {
313 +       u16 domain_nr;
314 +       u16 bus_nr;
315 +       u32 n_items;
316 +       struct brcmf_fw_item items[0];
317 +};
318 +
319  /*
320   * Request firmware(s) asynchronously. When the asynchronous request
321   * fails it will not use the callback, but call device_release_driver()
322   * instead which will call the driver .remove() callback.
323   */
324 -int brcmf_fw_get_firmwares_pcie(struct device *dev, u16 flags,
325 -                               const char *code, const char *nvram,
326 -                               void (*fw_cb)(struct device *dev, int err,
327 -                                             const struct firmware *fw,
328 -                                             void *nvram_image, u32 nvram_len),
329 -                               u16 domain_nr, u16 bus_nr);
330 -int brcmf_fw_get_firmwares(struct device *dev, u16 flags,
331 -                          const char *code, const char *nvram,
332 +int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req,
333                            void (*fw_cb)(struct device *dev, int err,
334 -                                        const struct firmware *fw,
335 -                                        void *nvram_image, u32 nvram_len));
336 +                                        struct brcmf_fw_request *req));
337  
338  #endif /* BRCMFMAC_FIRMWARE_H */
339 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
340 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
341 @@ -1651,15 +1651,19 @@ static const struct brcmf_buscore_ops br
342         .write32 = brcmf_pcie_buscore_write32,
343  };
344  
345 +#define BRCMF_PCIE_FW_CODE     0
346 +#define BRCMF_PCIE_FW_NVRAM    1
347 +
348  static void brcmf_pcie_setup(struct device *dev, int ret,
349 -                            const struct firmware *fw,
350 -                            void *nvram, u32 nvram_len)
351 +                            struct brcmf_fw_request *fwreq)
352  {
353 +       const struct firmware *fw;
354 +       void *nvram;
355         struct brcmf_bus *bus;
356         struct brcmf_pciedev *pcie_bus_dev;
357         struct brcmf_pciedev_info *devinfo;
358         struct brcmf_commonring **flowrings;
359 -       u32 i;
360 +       u32 i, nvram_len;
361  
362         /* check firmware loading result */
363         if (ret)
364 @@ -1670,6 +1674,11 @@ static void brcmf_pcie_setup(struct devi
365         devinfo = pcie_bus_dev->devinfo;
366         brcmf_pcie_attach(devinfo);
367  
368 +       fw = fwreq->items[BRCMF_PCIE_FW_CODE].binary;
369 +       nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data;
370 +       nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len;
371 +       kfree(fwreq);
372 +
373         /* Some of the firmwares have the size of the memory of the device
374          * defined inside the firmware. This is because part of the memory in
375          * the device is shared and the devision is determined by FW. Parse
376 @@ -1730,6 +1739,7 @@ static int
377  brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
378  {
379         int ret;
380 +       struct brcmf_fw_request *fwreq;
381         struct brcmf_pciedev_info *devinfo;
382         struct brcmf_pciedev *pcie_bus_dev;
383         struct brcmf_bus *bus;
384 @@ -1800,12 +1810,26 @@ brcmf_pcie_probe(struct pci_dev *pdev, c
385         if (ret)
386                 goto fail_bus;
387  
388 -       ret = brcmf_fw_get_firmwares_pcie(bus->dev, BRCMF_FW_REQUEST_NVRAM |
389 -                                                   BRCMF_FW_REQ_NV_OPTIONAL,
390 -                                         devinfo->fw_name, devinfo->nvram_name,
391 -                                         brcmf_pcie_setup, domain_nr, bus_nr);
392 +       fwreq = kzalloc(sizeof(*fwreq) + 2 * sizeof(struct brcmf_fw_item),
393 +                       GFP_KERNEL);
394 +       if (!fwreq) {
395 +               ret = -ENOMEM;
396 +               goto fail_bus;
397 +       }
398 +
399 +       fwreq->items[BRCMF_PCIE_FW_CODE].path = devinfo->fw_name;
400 +       fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
401 +       fwreq->items[BRCMF_PCIE_FW_NVRAM].path = devinfo->nvram_name;
402 +       fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
403 +       fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
404 +       fwreq->n_items = 2;
405 +       fwreq->domain_nr = domain_nr;
406 +       fwreq->bus_nr = bus_nr;
407 +       ret = brcmf_fw_get_firmwares(bus->dev, fwreq, brcmf_pcie_setup);
408         if (ret == 0)
409                 return 0;
410 +
411 +       kfree(fwreq);
412  fail_bus:
413         kfree(bus->msgbuf);
414         kfree(bus);
415 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
416 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
417 @@ -4031,14 +4031,19 @@ static const struct brcmf_bus_ops brcmf_
418         .get_fwname = brcmf_sdio_get_fwname,
419  };
420  
421 +#define BRCMF_SDIO_FW_CODE     0
422 +#define BRCMF_SDIO_FW_NVRAM    1
423 +
424  static void brcmf_sdio_firmware_callback(struct device *dev, int err,
425 -                                        const struct firmware *code,
426 -                                        void *nvram, u32 nvram_len)
427 +                                        struct brcmf_fw_request *fwreq)
428  {
429         struct brcmf_bus *bus_if = dev_get_drvdata(dev);
430         struct brcmf_sdio_dev *sdiod = bus_if->bus_priv.sdio;
431         struct brcmf_sdio *bus = sdiod->bus;
432         struct brcmf_core *core = bus->sdio_core;
433 +       const struct firmware *code;
434 +       void *nvram;
435 +       u32 nvram_len;
436         u8 saveclk;
437  
438         brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
439 @@ -4046,6 +4051,11 @@ static void brcmf_sdio_firmware_callback
440         if (err)
441                 goto fail;
442  
443 +       code = fwreq->items[BRCMF_SDIO_FW_CODE].binary;
444 +       nvram = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.data;
445 +       nvram_len = fwreq->items[BRCMF_SDIO_FW_NVRAM].nv_data.len;
446 +       kfree(fwreq);
447 +
448         /* try to download image and nvram to the dongle */
449         bus->alp_only = true;
450         err = brcmf_sdio_download_firmware(bus, code, nvram, nvram_len);
451 @@ -4150,6 +4160,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
452         int ret;
453         struct brcmf_sdio *bus;
454         struct workqueue_struct *wq;
455 +       struct brcmf_fw_request *fwreq;
456  
457         brcmf_dbg(TRACE, "Enter\n");
458  
459 @@ -4240,11 +4251,24 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
460         if (ret)
461                 goto fail;
462  
463 -       ret = brcmf_fw_get_firmwares(sdiodev->dev, BRCMF_FW_REQUEST_NVRAM,
464 -                                    sdiodev->fw_name, sdiodev->nvram_name,
465 +       fwreq = kzalloc(sizeof(fwreq) + 2 * sizeof(struct brcmf_fw_item),
466 +                       GFP_KERNEL);
467 +       if (!fwreq) {
468 +               ret = -ENOMEM;
469 +               goto fail;
470 +       }
471 +
472 +       fwreq->items[BRCMF_SDIO_FW_CODE].path = sdiodev->fw_name;
473 +       fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
474 +       fwreq->items[BRCMF_SDIO_FW_NVRAM].path = sdiodev->nvram_name;
475 +       fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
476 +       fwreq->n_items = 2;
477 +
478 +       ret = brcmf_fw_get_firmwares(sdiodev->dev, fwreq,
479                                      brcmf_sdio_firmware_callback);
480         if (ret != 0) {
481                 brcmf_err("async firmware request failed: %d\n", ret);
482 +               kfree(fwreq);
483                 goto fail;
484         }
485  
486 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
487 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
488 @@ -1155,18 +1155,23 @@ static const struct brcmf_bus_ops brcmf_
489         .get_fwname = brcmf_usb_get_fwname,
490  };
491  
492 +#define BRCMF_USB_FW_CODE      0
493 +
494  static void brcmf_usb_probe_phase2(struct device *dev, int ret,
495 -                                  const struct firmware *fw,
496 -                                  void *nvram, u32 nvlen)
497 +                                  struct brcmf_fw_request *fwreq)
498  {
499         struct brcmf_bus *bus = dev_get_drvdata(dev);
500         struct brcmf_usbdev_info *devinfo = bus->bus_priv.usb->devinfo;
501 +       const struct firmware *fw;
502  
503         if (ret)
504                 goto error;
505  
506         brcmf_dbg(USB, "Start fw downloading\n");
507  
508 +       fw = fwreq->items[BRCMF_USB_FW_CODE].binary;
509 +       kfree(fwreq);
510 +
511         ret = check_file(fw->data);
512         if (ret < 0) {
513                 brcmf_err("invalid firmware\n");
514 @@ -1200,6 +1205,7 @@ static int brcmf_usb_probe_cb(struct brc
515         struct brcmf_bus *bus = NULL;
516         struct brcmf_usbdev *bus_pub = NULL;
517         struct device *dev = devinfo->dev;
518 +       struct brcmf_fw_request *fwreq;
519         int ret;
520  
521         brcmf_dbg(USB, "Enter\n");
522 @@ -1250,11 +1256,22 @@ static int brcmf_usb_probe_cb(struct brc
523         if (ret)
524                 goto fail;
525  
526 +       fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
527 +                       GFP_KERNEL);
528 +       if (!fwreq) {
529 +               ret = -ENOMEM;
530 +               goto fail;
531 +       }
532 +
533 +       fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
534 +       fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
535 +       fwreq->n_items = 1;
536 +
537         /* request firmware here */
538 -       ret = brcmf_fw_get_firmwares(dev, 0, devinfo->fw_name, NULL,
539 -                                    brcmf_usb_probe_phase2);
540 +       ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
541         if (ret) {
542                 brcmf_err("firmware request failed: %d\n", ret);
543 +               kfree(fwreq);
544                 goto fail;
545         }
546  
547 @@ -1447,11 +1464,25 @@ static int brcmf_usb_reset_resume(struct
548  {
549         struct usb_device *usb = interface_to_usbdev(intf);
550         struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
551 +       struct brcmf_fw_request *fwreq;
552 +       int ret;
553  
554         brcmf_dbg(USB, "Enter\n");
555  
556 -       return brcmf_fw_get_firmwares(&usb->dev, 0, devinfo->fw_name, NULL,
557 -                                     brcmf_usb_probe_phase2);
558 +       fwreq = kzalloc(sizeof(*fwreq) + sizeof(struct brcmf_fw_item),
559 +                       GFP_KERNEL);
560 +       if (!fwreq)
561 +               return -ENOMEM;
562 +
563 +       fwreq->items[BRCMF_USB_FW_CODE].path = devinfo->fw_name;
564 +       fwreq->items[BRCMF_USB_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
565 +       fwreq->n_items = 1;
566 +
567 +       ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
568 +       if (ret < 0)
569 +               kfree(fwreq);
570 +
571 +       return ret;
572  }
573  
574  #define BRCMF_USB_DEVICE(dev_id)       \