提交 5b8045d4 编写于 作者: A Arend van Spriel 提交者: John W. Linville

brcmfmac: use asynchronous firmware request in USB

This patch adds use of asynchronous firmware request to
the driver USB layer.
Reviewed-by: NHante Meuleman <meuleman@broadcom.com>
Reviewed-by: NFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: NDaniel (Deognyoun) Kim <dekim@broadcom.com>
Reviewed-by: NPieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: NArend van Spriel <arend@broadcom.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 bd0e1b1d
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <dhd_bus.h> #include <dhd_bus.h>
#include <dhd_dbg.h> #include <dhd_dbg.h>
#include "firmware.h"
#include "usb_rdl.h" #include "usb_rdl.h"
#include "usb.h" #include "usb.h"
...@@ -87,7 +88,7 @@ struct brcmf_usbdev_info { ...@@ -87,7 +88,7 @@ struct brcmf_usbdev_info {
struct brcmf_usbreq *tx_reqs; struct brcmf_usbreq *tx_reqs;
struct brcmf_usbreq *rx_reqs; struct brcmf_usbreq *rx_reqs;
u8 *image; /* buffer for combine fw and nvram */ const u8 *image; /* buffer for combine fw and nvram */
int image_len; int image_len;
struct usb_device *usbdev; struct usb_device *usbdev;
...@@ -1021,7 +1022,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) ...@@ -1021,7 +1022,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
} }
err = brcmf_usb_dlstart(devinfo, err = brcmf_usb_dlstart(devinfo,
devinfo->image, devinfo->image_len); (u8 *)devinfo->image, devinfo->image_len);
if (err == 0) if (err == 0)
err = brcmf_usb_dlrun(devinfo); err = brcmf_usb_dlrun(devinfo);
return err; return err;
...@@ -1080,7 +1081,22 @@ static int check_file(const u8 *headers) ...@@ -1080,7 +1081,22 @@ static int check_file(const u8 *headers)
return -1; return -1;
} }
static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)
{
switch (devinfo->bus_pub.devid) {
case 43143:
return BRCMF_USB_43143_FW_NAME;
case 43235:
case 43236:
case 43238:
return BRCMF_USB_43236_FW_NAME;
case 43242:
return BRCMF_USB_43242_FW_NAME;
default:
return NULL;
}
}
static __used int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
{ {
s8 *fwname; s8 *fwname;
const struct firmware *fw; const struct firmware *fw;
...@@ -1202,16 +1218,6 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, ...@@ -1202,16 +1218,6 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
goto error; goto error;
} }
if (!brcmf_usb_dlneeded(devinfo))
return &devinfo->bus_pub;
brcmf_dbg(USB, "Start fw downloading\n");
if (brcmf_usb_get_fw(devinfo))
goto error;
if (brcmf_usb_fw_download(devinfo))
goto error;
return &devinfo->bus_pub; return &devinfo->bus_pub;
error: error:
...@@ -1252,12 +1258,47 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) ...@@ -1252,12 +1258,47 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
return ret; return ret;
} }
static void brcmf_usb_probe_phase2(struct device *dev,
const struct firmware *fw,
void *nvram, u32 nvlen)
{
struct brcmf_bus *bus = dev_get_drvdata(dev);
struct brcmf_usbdev_info *devinfo;
int ret;
brcmf_dbg(USB, "Start fw downloading\n");
ret = check_file(fw->data);
if (ret < 0) {
brcmf_err("invalid firmware\n");
release_firmware(fw);
goto error;
}
devinfo = bus->bus_priv.usb->devinfo;
devinfo->image = fw->data;
devinfo->image_len = fw->size;
ret = brcmf_usb_fw_download(devinfo);
release_firmware(fw);
if (ret)
goto error;
ret = brcmf_usb_bus_setup(devinfo);
if (ret)
goto error;
return;
error:
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
device_release_driver(dev);
}
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
{ {
struct brcmf_bus *bus = NULL; struct brcmf_bus *bus = NULL;
struct brcmf_usbdev *bus_pub = NULL; struct brcmf_usbdev *bus_pub = NULL;
int ret;
struct device *dev = devinfo->dev; struct device *dev = devinfo->dev;
int ret;
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); 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,13 +1321,16 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
bus->proto_type = BRCMF_PROTO_BCDC; bus->proto_type = BRCMF_PROTO_BCDC;
bus->always_use_fws_queue = true; bus->always_use_fws_queue = true;
if (!brcmf_usb_dlneeded(devinfo)) {
ret = brcmf_usb_bus_setup(devinfo); ret = brcmf_usb_bus_setup(devinfo);
if (ret) { if (ret)
brcmf_err("dongle is not responding\n");
goto fail; goto fail;
} }
/* request firmware here */
brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,
brcmf_usb_probe_phase2);
return 0; return 0;
fail: fail:
/* Release resources in reverse order */ /* Release resources in reverse order */
kfree(bus); kfree(bus);
...@@ -1409,12 +1453,8 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) ...@@ -1409,12 +1453,8 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
} }
/* Allocate interrupt URB and data buffer */ /* Allocate interrupt URB and data buffer */
/* RNDIS says 8-byte intr, our old drivers used 4-byte */ devinfo->intr_size =
if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) le16_to_cpu(IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize);
devinfo->intr_size = 8;
else
devinfo->intr_size = 4;
devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
if (usb->speed == USB_SPEED_SUPER) if (usb->speed == USB_SPEED_SUPER)
...@@ -1481,13 +1521,11 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf) ...@@ -1481,13 +1521,11 @@ static int brcmf_usb_reset_resume(struct usb_interface *intf)
{ {
struct usb_device *usb = interface_to_usbdev(intf); struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
if (!brcmf_usb_fw_download(devinfo)) return brcmf_fw_get_firmwares(&usb->dev, 0,
return brcmf_usb_bus_setup(devinfo); brcmf_usb_get_fwname(devinfo), NULL,
brcmf_usb_probe_phase2);
return -EIO;
} }
#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册