static
struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
				      int nrxq, int ntxq)
{
	brcmf_dbg(USB, "Enter\n");

	devinfo->bus_pub.nrxq = nrxq;
	devinfo->rx_low_watermark = nrxq / 2;
	devinfo->bus_pub.devinfo = devinfo;
	devinfo->bus_pub.ntxq = ntxq;
	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN;

	/* flow control when too many tx urbs posted */
	devinfo->tx_low_watermark = ntxq / 4;
	devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
	devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;

	/* Initialize other structure content */
	init_waitqueue_head(&devinfo->ioctl_resp_wait);

	/* Initialize the spinlocks */
	spin_lock_init(&devinfo->qlock);
	spin_lock_init(&devinfo->tx_flowblock_lock);

	INIT_LIST_HEAD(&devinfo->rx_freeq);
	INIT_LIST_HEAD(&devinfo->rx_postq);

	INIT_LIST_HEAD(&devinfo->tx_freeq);
	INIT_LIST_HEAD(&devinfo->tx_postq);

	devinfo->tx_flowblock = false;

	devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
	if (!devinfo->rx_reqs)
		goto error;

	devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
	if (!devinfo->tx_reqs)
		goto error;
	devinfo->tx_freecount = ntxq;

	devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!devinfo->ctl_urb) {
		brcmf_err("usb_alloc_urb (ctl) failed\n");
		goto error;
	}
	devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!devinfo->bulk_urb) {
		brcmf_err("usb_alloc_urb (bulk) failed\n");
		goto error;
	}

	return &devinfo->bus_pub;

error:
	brcmf_err("failed!\n");
	brcmf_usb_detach(devinfo);
	return NULL;
}
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
{
	struct brcmf_bus *bus = NULL;
	struct brcmf_usbdev *bus_pub = NULL;
	struct device *dev = devinfo->dev;
	int ret;

	brcmf_dbg(USB, "Enter\n");
	bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
	if (!bus_pub)
		return -ENODEV;

	bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
	if (!bus) {
		ret = -ENOMEM;
		goto fail;
	}

	bus->dev = dev;
	bus_pub->bus = bus;
	bus->bus_priv.usb = bus_pub;
	dev_set_drvdata(dev, bus);
	bus->ops = &brcmf_usb_bus_ops;
	bus->proto_type = BRCMF_PROTO_BCDC;
	bus->always_use_fws_queue = true;
#ifdef CONFIG_PM
	bus->wowl_supported = true;
#endif

	if (!brcmf_usb_dlneeded(devinfo)) {
		ret = brcmf_usb_bus_setup(devinfo);
		if (ret)
			goto fail;
		/* we are done */
		mutex_unlock(&devinfo->dev_init_lock);
		return 0;
	}
	bus->chip = bus_pub->devid;
	bus->chiprev = bus_pub->chiprev;

	/* request firmware here */
	ret = brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo),
				     NULL, brcmf_usb_probe_phase2);
	if (ret) {
		brcmf_err("firmware request failed: %d\n", ret);
		goto fail;
	}

	return 0;

fail:
	/* Release resources in reverse order */
	kfree(bus);
	brcmf_usb_detach(devinfo);
	return ret;
}
static void
brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
{
	if (!devinfo)
		return;
	brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo);

	brcmf_detach(devinfo->dev);
	kfree(devinfo->bus_pub.bus);
	brcmf_usb_detach(devinfo);
}
Exemple #4
0
static void
brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
{
    if (!bus_pub)
        return;
    brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);

    brcmf_detach(bus_pub->devinfo->dev);
    kfree(bus_pub->bus);
    brcmf_usb_detach(bus_pub);

}
Exemple #5
0
static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
                              u32 bustype, u32 hdrlen)
{
    struct brcmf_bus *bus = NULL;
    struct brcmf_usbdev *bus_pub = NULL;
    int ret;


    bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
    if (!bus_pub) {
        ret = -ENODEV;
        goto fail;
    }

    bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
    if (!bus) {
        ret = -ENOMEM;
        goto fail;
    }

    bus_pub->bus = bus;
    bus->brcmf_bus_txdata = brcmf_usb_tx;
    bus->brcmf_bus_init = brcmf_usb_up;
    bus->brcmf_bus_stop = brcmf_usb_down;
    bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt;
    bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt;
    bus->type = bustype;
    bus->bus_priv.usb = bus_pub;
    dev_set_drvdata(dev, bus);

    /* Attach to the common driver interface */
    ret = brcmf_attach(hdrlen, dev);
    if (ret) {
        brcmf_dbg(ERROR, "dhd_attach failed\n");
        goto fail;
    }

    ret = brcmf_bus_start(dev);
    if (ret == -ENOLINK) {
        brcmf_dbg(ERROR, "dongle is not responding\n");
        brcmf_detach(dev);
        goto fail;
    }

    return 0;
fail:
    /* Release resources in reverse order */
    if (bus_pub)
        brcmf_usb_detach(bus_pub);
    kfree(bus);
    return ret;
}
Exemple #6
0
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
{
	struct brcmf_bus *bus = NULL;
	struct brcmf_usbdev *bus_pub = NULL;
	struct device *dev = devinfo->dev;
	struct brcmf_fw_request *fwreq;
	int ret;

	brcmf_dbg(USB, "Enter\n");
	bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
	if (!bus_pub)
		return -ENODEV;

	bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
	if (!bus) {
		ret = -ENOMEM;
		goto fail;
	}

	bus->dev = dev;
	bus_pub->bus = bus;
	bus->bus_priv.usb = bus_pub;
	dev_set_drvdata(dev, bus);
	bus->ops = &brcmf_usb_bus_ops;
	bus->proto_type = BRCMF_PROTO_BCDC;
	bus->always_use_fws_queue = true;
#ifdef CONFIG_PM
	bus->wowl_supported = true;
#endif

	devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB,
						   bus_pub->devid,
						   bus_pub->chiprev);
	if (!devinfo->settings) {
		ret = -ENOMEM;
		goto fail;
	}

	if (!brcmf_usb_dlneeded(devinfo)) {
		ret = brcmf_attach(devinfo->dev, devinfo->settings);
		if (ret)
			goto fail;
		/* we are done */
		complete(&devinfo->dev_init_done);
		return 0;
	}
	bus->chip = bus_pub->devid;
	bus->chiprev = bus_pub->chiprev;

	fwreq = brcmf_usb_prepare_fw_request(devinfo);
	if (!fwreq) {
		ret = -ENOMEM;
		goto fail;
	}

	/* request firmware here */
	ret = brcmf_fw_get_firmwares(dev, fwreq, brcmf_usb_probe_phase2);
	if (ret) {
		brcmf_err("firmware request failed: %d\n", ret);
		kfree(fwreq);
		goto fail;
	}

	return 0;

fail:
	/* Release resources in reverse order */
	kfree(bus);
	brcmf_usb_detach(devinfo);
	return ret;
}
Exemple #7
0
static
struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
{
    struct brcmf_usbdev_info *devinfo;

    devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
    if (devinfo == NULL)
        return NULL;

    devinfo->bus_pub.nrxq = nrxq;
    devinfo->rx_low_watermark = nrxq / 2;
    devinfo->bus_pub.devinfo = devinfo;
    devinfo->bus_pub.ntxq = ntxq;

    /* flow control when too many tx urbs posted */
    devinfo->tx_low_watermark = ntxq / 4;
    devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
    devinfo->dev = dev;
    devinfo->usbdev = usbdev_probe_info.usb;
    devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
    devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
    devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
    devinfo->intr_pipe = usbdev_probe_info.intr_pipe;

    devinfo->interval = usbdev_probe_info.interval;
    devinfo->intr_size = usbdev_probe_info.intr_size;

    memcpy(&devinfo->probe_info, &usbdev_probe_info,
           sizeof(struct brcmf_usb_probe_info));
    devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;

    /* Initialize other structure content */
    init_waitqueue_head(&devinfo->ioctl_resp_wait);

    /* Initialize the spinlocks */
    spin_lock_init(&devinfo->qlock);

    INIT_LIST_HEAD(&devinfo->rx_freeq);
    INIT_LIST_HEAD(&devinfo->rx_postq);

    INIT_LIST_HEAD(&devinfo->tx_freeq);
    INIT_LIST_HEAD(&devinfo->tx_postq);

    devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
    if (!devinfo->rx_reqs)
        goto error;

    devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
    if (!devinfo->tx_reqs)
        goto error;

    devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
    if (!devinfo->intr_urb) {
        brcmf_dbg(ERROR, "usb_alloc_urb (intr) failed\n");
        goto error;
    }
    devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
    if (!devinfo->ctl_urb) {
        brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
        goto error;
    }
    devinfo->rxctl_deferrespok = 0;

    devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
    if (!devinfo->bulk_urb) {
        brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
        goto error;
    }

    init_waitqueue_head(&devinfo->wait);
    if (!brcmf_usb_dlneeded(devinfo))
        return &devinfo->bus_pub;

    brcmf_dbg(TRACE, "start fw downloading\n");
    if (brcmf_usb_get_fw(devinfo))
        goto error;

    if (brcmf_usb_fw_download(devinfo))
        goto error;

    return &devinfo->bus_pub;

error:
    brcmf_dbg(ERROR, "failed!\n");
    brcmf_usb_detach(&devinfo->bus_pub);
    return NULL;
}