static void housekeeping_enable(struct zd_mac *mac) { dev_dbg_f(zd_mac_dev(mac), "\n"); queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, 0); }
static void bssinfo_change(struct net_device *netdev, u32 changes) { struct zd_mac *mac = zd_netdev_mac(netdev); struct ieee80211softmac_device *softmac = ieee80211_priv(netdev); struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo; int need_set_rts_cts = 0; int need_set_rates = 0; u16 basic_rates; unsigned long flags; dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) { spin_lock_irqsave(&mac->lock, flags); mac->short_preamble = bssinfo->short_preamble; spin_unlock_irqrestore(&mac->lock, flags); need_set_rts_cts = 1; } if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) { /* Set RTS rate to highest available basic rate */ u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac, &bssinfo->supported_rates, 1); hi_rate = rate_to_zd_rate(hi_rate); spin_lock_irqsave(&mac->lock, flags); if (hi_rate != mac->rts_rate) { mac->rts_rate = hi_rate; need_set_rts_cts = 1; } spin_unlock_irqrestore(&mac->lock, flags); /* Set basic rates */ need_set_rates = 1; if (bssinfo->supported_rates.count == 0) { /* Allow the device to be flexible */ basic_rates = CR_RATES_80211B | CR_RATES_80211G; } else { int i = 0; basic_rates = 0; for (i = 0; i < bssinfo->supported_rates.count; i++) { u16 rate = bssinfo->supported_rates.rates[i]; if ((rate & IEEE80211_BASIC_RATE_MASK) == 0) continue; rate &= ~IEEE80211_BASIC_RATE_MASK; basic_rates |= rate_to_cr_rate(rate); } } spin_lock_irqsave(&mac->lock, flags); mac->basic_rates = basic_rates; spin_unlock_irqrestore(&mac->lock, flags); } /* Schedule any changes we made above */ spin_lock_irqsave(&mac->lock, flags); if (need_set_rts_cts && !mac->updating_rts_rate) { mac->updating_rts_rate = 1; netif_stop_queue(mac->netdev); queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); } if (need_set_rates && !mac->updating_basic_rates) { mac->updating_basic_rates = 1; netif_stop_queue(mac->netdev); queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, 0); } spin_unlock_irqrestore(&mac->lock, flags); }
int zd_usb_enable_int(struct zd_usb *usb) { int r; struct usb_device *udev = zd_usb_to_usbdev(usb); struct zd_usb_interrupt *intr = &usb->intr; struct urb *urb; dev_dbg_f(zd_usb_dev(usb), "\n"); urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { r = -ENOMEM; goto out; } ZD_ASSERT(!irqs_disabled()); spin_lock_irq(&intr->lock); if (intr->urb) { spin_unlock_irq(&intr->lock); r = 0; goto error_free_urb; } intr->urb = urb; spin_unlock_irq(&intr->lock); r = -ENOMEM; intr->buffer = usb_alloc_coherent(udev, USB_MAX_EP_INT_BUFFER, GFP_KERNEL, &intr->buffer_dma); if (!intr->buffer) { dev_dbg_f(zd_usb_dev(usb), "couldn't allocate transfer_buffer\n"); goto error_set_urb_null; } usb_fill_int_urb(urb, udev, usb_rcvintpipe(udev, EP_INT_IN), intr->buffer, USB_MAX_EP_INT_BUFFER, int_urb_complete, usb, intr->interval); urb->transfer_dma = intr->buffer_dma; urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; dev_dbg_f(zd_usb_dev(usb), "submit urb %p\n", intr->urb); r = usb_submit_urb(urb, GFP_KERNEL); if (r) { dev_dbg_f(zd_usb_dev(usb), "Couldn't submit urb. Error number %d\n", r); goto error; } return 0; error: usb_free_coherent(udev, USB_MAX_EP_INT_BUFFER, intr->buffer, intr->buffer_dma); error_set_urb_null: spin_lock_irq(&intr->lock); intr->urb = NULL; spin_unlock_irq(&intr->lock); error_free_urb: usb_free_urb(urb); out: return r; }
static void rx_urb_complete(struct urb *urb) { int r; struct zd_usb *usb; struct zd_usb_rx *rx; const u8 *buffer; unsigned int length; switch (urb->status) { case 0: break; case -ESHUTDOWN: case -EINVAL: case -ENODEV: case -ENOENT: case -ECONNRESET: case -EPIPE: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); return; default: dev_dbg_f(urb_dev(urb), "urb %p error %d\n", urb, urb->status); goto resubmit; } buffer = urb->transfer_buffer; length = urb->actual_length; usb = urb->context; rx = &usb->rx; tasklet_schedule(&rx->reset_timer_tasklet); if (length%rx->usb_packet_size > rx->usb_packet_size-4) { /* If there is an old first fragment, we don't care. */ dev_dbg_f(urb_dev(urb), "*** first fragment ***\n"); ZD_ASSERT(length <= ARRAY_SIZE(rx->fragment)); spin_lock(&rx->lock); memcpy(rx->fragment, buffer, length); rx->fragment_length = length; spin_unlock(&rx->lock); goto resubmit; } spin_lock(&rx->lock); if (rx->fragment_length > 0) { /* We are on a second fragment, we believe */ ZD_ASSERT(length + rx->fragment_length <= ARRAY_SIZE(rx->fragment)); dev_dbg_f(urb_dev(urb), "*** second fragment ***\n"); memcpy(rx->fragment+rx->fragment_length, buffer, length); handle_rx_packet(usb, rx->fragment, rx->fragment_length + length); rx->fragment_length = 0; spin_unlock(&rx->lock); } else { spin_unlock(&rx->lock); handle_rx_packet(usb, buffer, length); } resubmit: r = usb_submit_urb(urb, GFP_ATOMIC); if (r) dev_dbg_f(urb_dev(urb), "urb %p resubmit error %d\n", urb, r); }
static int upload_code(struct usb_device *udev, const u8 *data, size_t size, u16 code_offset, int flags) { u8 *p; int r; /* USB request blocks need "kmalloced" buffers. */ p = kmalloc(MAX_TRANSFER_SIZE, GFP_KERNEL); if (!p) { dev_err(&udev->dev, "out of memory\n"); r = -ENOMEM; goto error; } size &= ~1; while (size > 0) { size_t transfer_size = size <= MAX_TRANSFER_SIZE ? size : MAX_TRANSFER_SIZE; dev_dbg_f(&udev->dev, "transfer size %zu\n", transfer_size); memcpy(p, data, transfer_size); r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), USB_REQ_FIRMWARE_DOWNLOAD, USB_DIR_OUT | USB_TYPE_VENDOR, code_offset, 0, p, transfer_size, 1000 /* ms */); if (r < 0) { dev_err(&udev->dev, "USB control request for firmware upload" " failed. Error number %d\n", r); goto error; } transfer_size = r & ~1; size -= transfer_size; data += transfer_size; code_offset += transfer_size/sizeof(u16); } if (flags & REBOOT) { u8 ret; /* Use "DMA-aware" buffer. */ r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), USB_REQ_FIRMWARE_CONFIRM, USB_DIR_IN | USB_TYPE_VENDOR, 0, 0, p, sizeof(ret), 5000 /* ms */); if (r != sizeof(ret)) { dev_err(&udev->dev, "control request firmeware confirmation failed." " Return value %d\n", r); if (r >= 0) r = -ENODEV; goto error; } ret = p[0]; if (ret & 0x80) { dev_err(&udev->dev, "Internal error while downloading." " Firmware confirm return value %#04x\n", (unsigned int)ret); r = -ENODEV; goto error; } dev_dbg_f(&udev->dev, "firmware confirm return value %#04x\n", (unsigned int)ret); } r = 0; error: kfree(p); return r; }