Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

brcmfmac: use asynchronous firmware request in USB

This patch adds use of asynchronous firmware request to
the driver USB layer.

Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Arend van Spriel and committed by
John W. Linville
5b8045d4 bd0e1b1d

+68 -30
+68 -30
drivers/net/wireless/brcm80211/brcmfmac/usb.c
··· 25 25 #include <dhd_bus.h> 26 26 #include <dhd_dbg.h> 27 27 28 + #include "firmware.h" 28 29 #include "usb_rdl.h" 29 30 #include "usb.h" 30 31 ··· 88 87 struct brcmf_usbreq *tx_reqs; 89 88 struct brcmf_usbreq *rx_reqs; 90 89 91 - u8 *image; /* buffer for combine fw and nvram */ 90 + const u8 *image; /* buffer for combine fw and nvram */ 92 91 int image_len; 93 92 94 93 struct usb_device *usbdev; ··· 1022 1021 } 1023 1022 1024 1023 err = brcmf_usb_dlstart(devinfo, 1025 - devinfo->image, devinfo->image_len); 1024 + (u8 *)devinfo->image, devinfo->image_len); 1026 1025 if (err == 0) 1027 1026 err = brcmf_usb_dlrun(devinfo); 1028 1027 return err; ··· 1081 1080 return -1; 1082 1081 } 1083 1082 1084 - static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) 1083 + static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo) 1084 + { 1085 + switch (devinfo->bus_pub.devid) { 1086 + case 43143: 1087 + return BRCMF_USB_43143_FW_NAME; 1088 + case 43235: 1089 + case 43236: 1090 + case 43238: 1091 + return BRCMF_USB_43236_FW_NAME; 1092 + case 43242: 1093 + return BRCMF_USB_43242_FW_NAME; 1094 + default: 1095 + return NULL; 1096 + } 1097 + } 1098 + static __used int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) 1085 1099 { 1086 1100 s8 *fwname; 1087 1101 const struct firmware *fw; ··· 1218 1202 goto error; 1219 1203 } 1220 1204 1221 - if (!brcmf_usb_dlneeded(devinfo)) 1222 - return &devinfo->bus_pub; 1223 - 1224 - brcmf_dbg(USB, "Start fw downloading\n"); 1225 - if (brcmf_usb_get_fw(devinfo)) 1226 - goto error; 1227 - 1228 - if (brcmf_usb_fw_download(devinfo)) 1229 - goto error; 1230 - 1231 1205 return &devinfo->bus_pub; 1232 1206 1233 1207 error: ··· 1258 1252 return ret; 1259 1253 } 1260 1254 1255 + static void brcmf_usb_probe_phase2(struct device *dev, 1256 + const struct firmware *fw, 1257 + void *nvram, u32 nvlen) 1258 + { 1259 + struct brcmf_bus *bus = dev_get_drvdata(dev); 1260 + struct brcmf_usbdev_info *devinfo; 1261 + int ret; 1262 + 1263 + brcmf_dbg(USB, "Start fw downloading\n"); 1264 + ret = check_file(fw->data); 1265 + if (ret < 0) { 1266 + brcmf_err("invalid firmware\n"); 1267 + release_firmware(fw); 1268 + goto error; 1269 + } 1270 + 1271 + devinfo = bus->bus_priv.usb->devinfo; 1272 + devinfo->image = fw->data; 1273 + devinfo->image_len = fw->size; 1274 + 1275 + ret = brcmf_usb_fw_download(devinfo); 1276 + release_firmware(fw); 1277 + if (ret) 1278 + goto error; 1279 + 1280 + ret = brcmf_usb_bus_setup(devinfo); 1281 + if (ret) 1282 + goto error; 1283 + 1284 + return; 1285 + error: 1286 + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); 1287 + device_release_driver(dev); 1288 + } 1289 + 1261 1290 static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) 1262 1291 { 1263 1292 struct brcmf_bus *bus = NULL; 1264 1293 struct brcmf_usbdev *bus_pub = NULL; 1265 - int ret; 1266 1294 struct device *dev = devinfo->dev; 1295 + int ret; 1267 1296 1268 1297 brcmf_dbg(USB, "Enter\n"); 1269 1298 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); ··· 1321 1280 bus->proto_type = BRCMF_PROTO_BCDC; 1322 1281 bus->always_use_fws_queue = true; 1323 1282 1324 - ret = brcmf_usb_bus_setup(devinfo); 1325 - if (ret) { 1326 - brcmf_err("dongle is not responding\n"); 1327 - goto fail; 1283 + if (!brcmf_usb_dlneeded(devinfo)) { 1284 + ret = brcmf_usb_bus_setup(devinfo); 1285 + if (ret) 1286 + goto fail; 1328 1287 } 1329 - 1288 + /* request firmware here */ 1289 + brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, 1290 + brcmf_usb_probe_phase2); 1330 1291 return 0; 1292 + 1331 1293 fail: 1332 1294 /* Release resources in reverse order */ 1333 1295 kfree(bus); ··· 1453 1409 } 1454 1410 1455 1411 /* Allocate interrupt URB and data buffer */ 1456 - /* RNDIS says 8-byte intr, our old drivers used 4-byte */ 1457 - if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) 1458 - devinfo->intr_size = 8; 1459 - else 1460 - devinfo->intr_size = 4; 1461 - 1412 + devinfo->intr_size = 1413 + le16_to_cpu(IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize); 1462 1414 devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; 1463 1415 1464 1416 if (usb->speed == USB_SPEED_SUPER) ··· 1521 1481 { 1522 1482 struct usb_device *usb = interface_to_usbdev(intf); 1523 1483 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); 1524 - 1525 1484 brcmf_dbg(USB, "Enter\n"); 1526 1485 1527 - if (!brcmf_usb_fw_download(devinfo)) 1528 - return brcmf_usb_bus_setup(devinfo); 1529 - 1530 - return -EIO; 1486 + return brcmf_fw_get_firmwares(&usb->dev, 0, 1487 + brcmf_usb_get_fwname(devinfo), NULL, 1488 + brcmf_usb_probe_phase2); 1531 1489 } 1532 1490 1533 1491 #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c