327-v4.17-0008-brcmfmac-introduce-brcmf_fw_alloc_request-function.patch 10.0 KB

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