diff options
author | Arend van Spriel <arend@broadcom.com> | 2014-05-27 06:56:23 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-05-29 13:10:23 -0400 |
commit | 5b8045d484d0ef77d6aa9444023220c5671fa3fe (patch) | |
tree | 30c506a845f0a6bde6084c6500180e83a6084eec /drivers/net/wireless/brcm80211/brcmfmac/usb.c | |
parent | bd0e1b1d380efe713a612c91417b948e7ebea58d (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/usb.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/usb.c | 98 |
1 files changed, 68 insertions, 30 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 8d679403518f..21335e2ca0e6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <dhd_bus.h> | 25 | #include <dhd_bus.h> |
26 | #include <dhd_dbg.h> | 26 | #include <dhd_dbg.h> |
27 | 27 | ||
28 | #include "firmware.h" | ||
28 | #include "usb_rdl.h" | 29 | #include "usb_rdl.h" |
29 | #include "usb.h" | 30 | #include "usb.h" |
30 | 31 | ||
@@ -87,7 +88,7 @@ struct brcmf_usbdev_info { | |||
87 | struct brcmf_usbreq *tx_reqs; | 88 | struct brcmf_usbreq *tx_reqs; |
88 | struct brcmf_usbreq *rx_reqs; | 89 | struct brcmf_usbreq *rx_reqs; |
89 | 90 | ||
90 | u8 *image; /* buffer for combine fw and nvram */ | 91 | const u8 *image; /* buffer for combine fw and nvram */ |
91 | int image_len; | 92 | int image_len; |
92 | 93 | ||
93 | struct usb_device *usbdev; | 94 | struct usb_device *usbdev; |
@@ -1021,7 +1022,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | |||
1021 | } | 1022 | } |
1022 | 1023 | ||
1023 | err = brcmf_usb_dlstart(devinfo, | 1024 | err = brcmf_usb_dlstart(devinfo, |
1024 | devinfo->image, devinfo->image_len); | 1025 | (u8 *)devinfo->image, devinfo->image_len); |
1025 | if (err == 0) | 1026 | if (err == 0) |
1026 | err = brcmf_usb_dlrun(devinfo); | 1027 | err = brcmf_usb_dlrun(devinfo); |
1027 | return err; | 1028 | return err; |
@@ -1080,7 +1081,22 @@ static int check_file(const u8 *headers) | |||
1080 | return -1; | 1081 | return -1; |
1081 | } | 1082 | } |
1082 | 1083 | ||
1083 | static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | 1084 | static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo) |
1085 | { | ||
1086 | switch (devinfo->bus_pub.devid) { | ||
1087 | case 43143: | ||
1088 | return BRCMF_USB_43143_FW_NAME; | ||
1089 | case 43235: | ||
1090 | case 43236: | ||
1091 | case 43238: | ||
1092 | return BRCMF_USB_43236_FW_NAME; | ||
1093 | case 43242: | ||
1094 | return BRCMF_USB_43242_FW_NAME; | ||
1095 | default: | ||
1096 | return NULL; | ||
1097 | } | ||
1098 | } | ||
1099 | static __used int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | ||
1084 | { | 1100 | { |
1085 | s8 *fwname; | 1101 | s8 *fwname; |
1086 | const struct firmware *fw; | 1102 | const struct firmware *fw; |
@@ -1202,16 +1218,6 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, | |||
1202 | goto error; | 1218 | goto error; |
1203 | } | 1219 | } |
1204 | 1220 | ||
1205 | if (!brcmf_usb_dlneeded(devinfo)) | ||
1206 | return &devinfo->bus_pub; | ||
1207 | |||
1208 | brcmf_dbg(USB, "Start fw downloading\n"); | ||
1209 | if (brcmf_usb_get_fw(devinfo)) | ||
1210 | goto error; | ||
1211 | |||
1212 | if (brcmf_usb_fw_download(devinfo)) | ||
1213 | goto error; | ||
1214 | |||
1215 | return &devinfo->bus_pub; | 1221 | return &devinfo->bus_pub; |
1216 | 1222 | ||
1217 | error: | 1223 | error: |
@@ -1252,12 +1258,47 @@ fail: | |||
1252 | return ret; | 1258 | return ret; |
1253 | } | 1259 | } |
1254 | 1260 | ||
1261 | static void brcmf_usb_probe_phase2(struct device *dev, | ||
1262 | const struct firmware *fw, | ||
1263 | void *nvram, u32 nvlen) | ||
1264 | { | ||
1265 | struct brcmf_bus *bus = dev_get_drvdata(dev); | ||
1266 | struct brcmf_usbdev_info *devinfo; | ||
1267 | int ret; | ||
1268 | |||
1269 | brcmf_dbg(USB, "Start fw downloading\n"); | ||
1270 | ret = check_file(fw->data); | ||
1271 | if (ret < 0) { | ||
1272 | brcmf_err("invalid firmware\n"); | ||
1273 | release_firmware(fw); | ||
1274 | goto error; | ||
1275 | } | ||
1276 | |||
1277 | devinfo = bus->bus_priv.usb->devinfo; | ||
1278 | devinfo->image = fw->data; | ||
1279 | devinfo->image_len = fw->size; | ||
1280 | |||
1281 | ret = brcmf_usb_fw_download(devinfo); | ||
1282 | release_firmware(fw); | ||
1283 | if (ret) | ||
1284 | goto error; | ||
1285 | |||
1286 | ret = brcmf_usb_bus_setup(devinfo); | ||
1287 | if (ret) | ||
1288 | goto error; | ||
1289 | |||
1290 | return; | ||
1291 | error: | ||
1292 | brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); | ||
1293 | device_release_driver(dev); | ||
1294 | } | ||
1295 | |||
1255 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) | 1296 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) |
1256 | { | 1297 | { |
1257 | struct brcmf_bus *bus = NULL; | 1298 | struct brcmf_bus *bus = NULL; |
1258 | struct brcmf_usbdev *bus_pub = NULL; | 1299 | struct brcmf_usbdev *bus_pub = NULL; |
1259 | int ret; | ||
1260 | struct device *dev = devinfo->dev; | 1300 | struct device *dev = devinfo->dev; |
1301 | int ret; | ||
1261 | 1302 | ||
1262 | brcmf_dbg(USB, "Enter\n"); | 1303 | brcmf_dbg(USB, "Enter\n"); |
1263 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); | 1304 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); |
@@ -1280,13 +1321,16 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) | |||
1280 | bus->proto_type = BRCMF_PROTO_BCDC; | 1321 | bus->proto_type = BRCMF_PROTO_BCDC; |
1281 | bus->always_use_fws_queue = true; | 1322 | bus->always_use_fws_queue = true; |
1282 | 1323 | ||
1283 | ret = brcmf_usb_bus_setup(devinfo); | 1324 | if (!brcmf_usb_dlneeded(devinfo)) { |
1284 | if (ret) { | 1325 | ret = brcmf_usb_bus_setup(devinfo); |
1285 | brcmf_err("dongle is not responding\n"); | 1326 | if (ret) |
1286 | goto fail; | 1327 | goto fail; |
1287 | } | 1328 | } |
1288 | 1329 | /* request firmware here */ | |
1330 | brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL, | ||
1331 | brcmf_usb_probe_phase2); | ||
1289 | return 0; | 1332 | return 0; |
1333 | |||
1290 | fail: | 1334 | fail: |
1291 | /* Release resources in reverse order */ | 1335 | /* Release resources in reverse order */ |
1292 | kfree(bus); | 1336 | kfree(bus); |
@@ -1409,12 +1453,8 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1409 | } | 1453 | } |
1410 | 1454 | ||
1411 | /* Allocate interrupt URB and data buffer */ | 1455 | /* Allocate interrupt URB and data buffer */ |
1412 | /* RNDIS says 8-byte intr, our old drivers used 4-byte */ | 1456 | devinfo->intr_size = |
1413 | if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) | 1457 | le16_to_cpu(IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize); |
1414 | devinfo->intr_size = 8; | ||
1415 | else | ||
1416 | devinfo->intr_size = 4; | ||
1417 | |||
1418 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; | 1458 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; |
1419 | 1459 | ||
1420 | if (usb->speed == USB_SPEED_SUPER) | 1460 | if (usb->speed == USB_SPEED_SUPER) |
@@ -1481,13 +1521,11 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) | |||
1481 | { | 1521 | { |
1482 | struct usb_device *usb = interface_to_usbdev(intf); | 1522 | struct usb_device *usb = interface_to_usbdev(intf); |
1483 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1523 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1484 | |||
1485 | brcmf_dbg(USB, "Enter\n"); | 1524 | brcmf_dbg(USB, "Enter\n"); |
1486 | 1525 | ||
1487 | if (!brcmf_usb_fw_download(devinfo)) | 1526 | return brcmf_fw_get_firmwares(&usb->dev, 0, |
1488 | return brcmf_usb_bus_setup(devinfo); | 1527 | brcmf_usb_get_fwname(devinfo), NULL, |
1489 | 1528 | brcmf_usb_probe_phase2); | |
1490 | return -EIO; | ||
1491 | } | 1529 | } |
1492 | 1530 | ||
1493 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c | 1531 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c |