kernel: bump 4.14 to 4.14.72
[openwrt/staging/chunkeey.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) \