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; }
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; }
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; }
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; }
/* * 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; }
/* * 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; }
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); }
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); }
/* * (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; }
/* * 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; }
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; }
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); }
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; }
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); }
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; }