Ejemplo n.º 1
0
static int brcmf_usb_up(struct device *dev)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

	brcmf_dbg(USB, "Enter\n");
	if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)
		return 0;

	/* Success, indicate devinfo is fully up */
	brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);

	if (devinfo->ctl_urb) {
		devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
		devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);

		/* CTL Write */
		devinfo->ctl_write.bRequestType =
			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
		devinfo->ctl_write.bRequest = 0;
		devinfo->ctl_write.wValue = cpu_to_le16(0);
		devinfo->ctl_write.wIndex = cpu_to_le16(devinfo->ifnum);

		/* CTL Read */
		devinfo->ctl_read.bRequestType =
			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
		devinfo->ctl_read.bRequest = 1;
		devinfo->ctl_read.wValue = cpu_to_le16(0);
		devinfo->ctl_read.wIndex = cpu_to_le16(devinfo->ifnum);
	}
	brcmf_usb_rx_fill_all(devinfo);
	return 0;
}
Ejemplo n.º 2
0
static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{
	int err = 0;
	int timeout = 0;
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

	brcmf_dbg(USB, "Enter\n");
	if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP)
		return -EIO;

	if (test_and_set_bit(0, &devinfo->ctl_op))
		return -EIO;

	devinfo->ctl_completed = false;
	err = brcmf_usb_recv_ctl(devinfo, buf, len);
	if (err) {
		brcmf_err("fail %d bytes: %d\n", err, len);
		clear_bit(0, &devinfo->ctl_op);
		return err;
	}
	timeout = brcmf_usb_ioctl_resp_wait(devinfo);
	err = devinfo->ctl_urb_status;
	clear_bit(0, &devinfo->ctl_op);
	if (!timeout) {
		brcmf_err("rxctl wait timed out\n");
		err = -EIO;
	}
	if (!err)
		return devinfo->ctl_urb_actual_length;
	else
		return err;
}
Ejemplo n.º 3
0
static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
{
    int err = 0;
    int timeout = 0;
    bool pending;
    struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

    if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
        /* TODO: handle suspend/resume */
        return -EIO;
    }
    if (test_and_set_bit(0, &devinfo->ctl_op))
        return -EIO;

    err = brcmf_usb_recv_ctl(devinfo, buf, len);
    if (err) {
        brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
        return err;
    }
    devinfo->ctl_completed = false;
    timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
                                        &pending);
    err = devinfo->ctl_urb_status;
    clear_bit(0, &devinfo->ctl_op);
    if (!timeout) {
        brcmf_dbg(ERROR, "rxctl wait timed out\n");
        err = -EIO;
    }
    if (!err)
        return devinfo->ctl_urb_actual_length;
    else
        return err;
}
Ejemplo n.º 4
0
static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
	struct brcmf_usbreq  *req;
	int ret;

	if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
		/* TODO: handle suspend/resume */
		return -EIO;
	}

	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
	if (!req) {
		brcmu_pkt_buf_free_skb(skb);
		brcmf_dbg(ERROR, "no req to send\n");
		return -ENOMEM;
	}

	req->skb = skb;
	req->devinfo = devinfo;
	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
			  skb->data, skb->len, brcmf_usb_tx_complete, req);
	req->urb->transfer_flags |= URB_ZERO_PACKET;
	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
	if (ret) {
		brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
		brcmf_usb_del_fromq(devinfo, req);
		brcmu_pkt_buf_free_skb(req->skb);
		req->skb = NULL;
		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
	}

	return ret;
}
Ejemplo n.º 5
0
/*
 *	mark suspend state active and crank up the bus.
 */
static int brcmf_usb_resume(struct usb_interface *intf)
{
    struct usb_device *usb = interface_to_usbdev(intf);
    struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

    brcmf_dbg(TRACE, "enter\n");
    devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
    brcmf_bus_start(&usb->dev);
    return 0;
}
Ejemplo n.º 6
0
/*
 *	only need to signal the bus being down and update the suspend state.
 */
static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
{
    struct usb_device *usb = interface_to_usbdev(intf);
    struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

    brcmf_dbg(TRACE, "enter\n");
    devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
    devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
    return 0;
}
Ejemplo n.º 7
0
static int brcmf_usb_reset_resume(struct usb_interface *intf)
{
	struct usb_device *usb = interface_to_usbdev(intf);
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

	brcmf_dbg(USB, "Enter\n");

	return brcmf_fw_get_firmwares(&usb->dev, 0,
				      brcmf_usb_get_fwname(devinfo), NULL,
				      brcmf_usb_probe_phase2);
}
Ejemplo n.º 8
0
static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

	brcmf_dbg(USB, "Configuring WOWL, enabled=%d\n", enabled);
	devinfo->wowl_enabled = enabled;
	if (enabled)
		device_set_wakeup_enable(devinfo->dev, true);
	else
		device_set_wakeup_enable(devinfo->dev, false);
}
Ejemplo n.º 9
0
/*
 * (re-) start the bus.
 */
static int brcmf_usb_resume(struct usb_interface *intf)
{
	struct usb_device *usb = interface_to_usbdev(intf);
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

	brcmf_dbg(USB, "Enter\n");
	if (!devinfo->wowl_enabled)
		return brcmf_usb_bus_setup(devinfo);

	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP;
	brcmf_usb_rx_fill_all(devinfo);
	return 0;
}
Ejemplo n.º 10
0
/*
 * only need to signal the bus being down and update the state.
 */
static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
{
	struct usb_device *usb = interface_to_usbdev(intf);
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

	brcmf_dbg(USB, "Enter\n");
	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
	if (devinfo->wowl_enabled)
		brcmf_cancel_all_urbs(devinfo);
	else
		brcmf_detach(&usb->dev);
	return 0;
}
Ejemplo n.º 11
0
static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
	struct brcmf_usbreq  *req;
	int ret;
	unsigned long flags;

	brcmf_dbg(USB, "Enter, skb=%p\n", skb);
	if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) {
		ret = -EIO;
		goto fail;
	}

	req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
					&devinfo->tx_freecount);
	if (!req) {
		brcmf_err("no req to send\n");
		ret = -ENOMEM;
		goto fail;
	}

	req->skb = skb;
	req->devinfo = devinfo;
	usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
			  skb->data, skb->len, brcmf_usb_tx_complete, req);
	req->urb->transfer_flags |= URB_ZERO_PACKET;
	brcmf_usb_enq(devinfo, &devinfo->tx_postq, req, NULL);
	ret = usb_submit_urb(req->urb, GFP_ATOMIC);
	if (ret) {
		brcmf_err("brcmf_usb_tx usb_submit_urb FAILED\n");
		brcmf_usb_del_fromq(devinfo, req);
		req->skb = NULL;
		brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
			      &devinfo->tx_freecount);
		goto fail;
	}

	spin_lock_irqsave(&devinfo->tx_flowblock_lock, flags);
	if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
	    !devinfo->tx_flowblock) {
		brcmf_txflowblock(dev, true);
		devinfo->tx_flowblock = true;
	}
	spin_unlock_irqrestore(&devinfo->tx_flowblock_lock, flags);
	return 0;

fail:
	return ret;
}
Ejemplo n.º 12
0
static void brcmf_usb_down(struct device *dev)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

	brcmf_dbg(USB, "Enter\n");
	if (devinfo == NULL)
		return;

	if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN)
		return;

	brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);

	brcmf_cancel_all_urbs(devinfo);
}
Ejemplo n.º 13
0
static int brcmf_usb_reset_resume(struct usb_interface *intf)
{
	struct usb_device *usb = interface_to_usbdev(intf);
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);
	struct brcmf_fw_request *fwreq;
	int ret;

	brcmf_dbg(USB, "Enter\n");

	fwreq = brcmf_usb_prepare_fw_request(devinfo);
	if (!fwreq)
		return -ENOMEM;

	ret = brcmf_fw_get_firmwares(&usb->dev, fwreq, brcmf_usb_probe_phase2);
	if (ret < 0)
		kfree(fwreq);

	return ret;
}
Ejemplo n.º 14
0
static void brcmf_usb_down(struct device *dev)
{
    struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

    if (devinfo == NULL)
        return;

    brcmf_dbg(TRACE, "enter\n");
    if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
        return;

    brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN);
    if (devinfo->intr_urb)
        usb_kill_urb(devinfo->intr_urb);

    if (devinfo->ctl_urb)
        usb_kill_urb(devinfo->ctl_urb);

    if (devinfo->bulk_urb)
        usb_kill_urb(devinfo->bulk_urb);
    brcmf_usb_free_q(&devinfo->tx_postq, true);

    brcmf_usb_free_q(&devinfo->rx_postq, true);
}
Ejemplo n.º 15
0
static int brcmf_usb_up(struct device *dev)
{
    struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
    u16 ifnum;

    if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
        return 0;

    /* If the USB/HSIC bus in sleep state, wake it up */
    if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) {
        if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) {
            brcmf_dbg(ERROR, "Could not Resume the bus!\n");
            return -EIO;
        }
    }
    devinfo->activity = true;

    /* Success, indicate devinfo is fully up */
    brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP);

    if (devinfo->intr_urb) {
        int ret;

        usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,
                         devinfo->intr_pipe,
                         &devinfo->intr,
                         devinfo->intr_size,
                         (usb_complete_t)brcmf_usb_intr_complete,
                         devinfo,
                         devinfo->interval);

        ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);
        if (ret) {
            brcmf_dbg(ERROR, "USB_SUBMIT_URB failed with status %d\n",
                      ret);
            return -EINVAL;
        }
    }

    if (devinfo->ctl_urb) {
        devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);
        devinfo->ctl_out_pipe = usb_sndctrlpipe(devinfo->usbdev, 0);

        ifnum = IFDESC(devinfo->usbdev, CONTROL_IF).bInterfaceNumber;

        /* CTL Write */
        devinfo->ctl_write.bRequestType =
            USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
        devinfo->ctl_write.bRequest = 0;
        devinfo->ctl_write.wValue = cpu_to_le16(0);
        devinfo->ctl_write.wIndex = cpu_to_le16p(&ifnum);

        /* CTL Read */
        devinfo->ctl_read.bRequestType =
            USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
        devinfo->ctl_read.bRequest = 1;
        devinfo->ctl_read.wValue = cpu_to_le16(0);
        devinfo->ctl_read.wIndex = cpu_to_le16p(&ifnum);
    }
    brcmf_usb_rx_fill_all(devinfo);
    return 0;
}