Commit b63a2cb30405777033d58045c562a3b04d87d702

Authored by Christian Lamparter
Committed by John W. Linville
1 parent 6cb1935353

ar9170: ar9170: USB frontend driver

USB frontend driver code for Atheros' AR9170 modules.

Signed-off-by: Christian Lamparter <chunkeey@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 2 changed files with 821 additions and 0 deletions Side-by-side Diff

drivers/net/wireless/ar9170/usb.c
  1 +/*
  2 + * Atheros AR9170 driver
  3 + *
  4 + * USB - frontend
  5 + *
  6 + * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7 + * Copyright 2009, Christian Lamparter <chunkeey@web.de>
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation; either version 2 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program; see the file COPYING. If not, see
  21 + * http://www.gnu.org/licenses/.
  22 + *
  23 + * This file incorporates work covered by the following copyright and
  24 + * permission notice:
  25 + * Copyright (c) 2007-2008 Atheros Communications, Inc.
  26 + *
  27 + * Permission to use, copy, modify, and/or distribute this software for any
  28 + * purpose with or without fee is hereby granted, provided that the above
  29 + * copyright notice and this permission notice appear in all copies.
  30 + *
  31 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  32 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  33 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  34 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  35 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  36 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  37 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  38 + */
  39 +
  40 +#include <linux/module.h>
  41 +#include <linux/usb.h>
  42 +#include <linux/firmware.h>
  43 +#include <linux/etherdevice.h>
  44 +#include <net/mac80211.h>
  45 +#include "ar9170.h"
  46 +#include "cmd.h"
  47 +#include "hw.h"
  48 +#include "usb.h"
  49 +
  50 +MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
  51 +MODULE_LICENSE("GPL");
  52 +MODULE_DESCRIPTION("USB Driver for Atheros AR9170 based devices");
  53 +MODULE_FIRMWARE("ar9170-1.fw");
  54 +MODULE_FIRMWARE("ar9170-2.fw");
  55 +
  56 +static struct usb_device_id ar9170_usb_ids[] = {
  57 + /* Atheros 9170 */
  58 + { USB_DEVICE(0x0cf3, 0x9170) },
  59 + /* Atheros TG121N */
  60 + { USB_DEVICE(0x0cf3, 0x1001) },
  61 + /* D-Link DWA 160A */
  62 + { USB_DEVICE(0x07d1, 0x3c10) },
  63 + /* Netgear WNDA3100 */
  64 + { USB_DEVICE(0x0846, 0x9010) },
  65 + /* Netgear WN111 v2 */
  66 + { USB_DEVICE(0x0846, 0x9001) },
  67 + /* Zydas ZD1221 */
  68 + { USB_DEVICE(0x0ace, 0x1221) },
  69 + /* Z-Com UB81 BG */
  70 + { USB_DEVICE(0x0cde, 0x0023) },
  71 + /* Z-Com UB82 ABG */
  72 + { USB_DEVICE(0x0cde, 0x0026) },
  73 + /* Arcadyan WN7512 */
  74 + { USB_DEVICE(0x083a, 0xf522) },
  75 + /* Planex GWUS300 */
  76 + { USB_DEVICE(0x2019, 0x5304) },
  77 + /* IO-Data WNGDNUS2 */
  78 + { USB_DEVICE(0x04bb, 0x093f) },
  79 +
  80 + /* terminate */
  81 + {}
  82 +};
  83 +MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
  84 +
  85 +static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
  86 +{
  87 + struct sk_buff *skb = urb->context;
  88 + struct ar9170_usb *aru = (struct ar9170_usb *)
  89 + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
  90 +
  91 + if (!aru) {
  92 + dev_kfree_skb_irq(skb);
  93 + return ;
  94 + }
  95 +
  96 + ar9170_handle_tx_status(&aru->common, skb, false,
  97 + AR9170_TX_STATUS_COMPLETE);
  98 +}
  99 +
  100 +static void ar9170_usb_tx_urb_complete(struct urb *urb)
  101 +{
  102 +}
  103 +
  104 +static void ar9170_usb_irq_completed(struct urb *urb)
  105 +{
  106 + struct ar9170_usb *aru = urb->context;
  107 +
  108 + switch (urb->status) {
  109 + /* everything is fine */
  110 + case 0:
  111 + break;
  112 +
  113 + /* disconnect */
  114 + case -ENOENT:
  115 + case -ECONNRESET:
  116 + case -ENODEV:
  117 + case -ESHUTDOWN:
  118 + goto free;
  119 +
  120 + default:
  121 + goto resubmit;
  122 + }
  123 +
  124 + print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
  125 + urb->transfer_buffer, urb->actual_length);
  126 +
  127 +resubmit:
  128 + usb_anchor_urb(urb, &aru->rx_submitted);
  129 + if (usb_submit_urb(urb, GFP_ATOMIC)) {
  130 + usb_unanchor_urb(urb);
  131 + goto free;
  132 + }
  133 +
  134 + return;
  135 +
  136 +free:
  137 + usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
  138 +}
  139 +
  140 +static void ar9170_usb_rx_completed(struct urb *urb)
  141 +{
  142 + struct sk_buff *skb = urb->context;
  143 + struct ar9170_usb *aru = (struct ar9170_usb *)
  144 + usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
  145 + int err;
  146 +
  147 + if (!aru)
  148 + goto free;
  149 +
  150 + switch (urb->status) {
  151 + /* everything is fine */
  152 + case 0:
  153 + break;
  154 +
  155 + /* disconnect */
  156 + case -ENOENT:
  157 + case -ECONNRESET:
  158 + case -ENODEV:
  159 + case -ESHUTDOWN:
  160 + goto free;
  161 +
  162 + default:
  163 + goto resubmit;
  164 + }
  165 +
  166 + skb_put(skb, urb->actual_length);
  167 + ar9170_rx(&aru->common, skb);
  168 +
  169 +resubmit:
  170 + skb_reset_tail_pointer(skb);
  171 + skb_trim(skb, 0);
  172 +
  173 + usb_anchor_urb(urb, &aru->rx_submitted);
  174 + err = usb_submit_urb(urb, GFP_ATOMIC);
  175 + if (err) {
  176 + usb_unanchor_urb(urb);
  177 + dev_kfree_skb_irq(skb);
  178 + }
  179 +
  180 + return ;
  181 +
  182 +free:
  183 + dev_kfree_skb_irq(skb);
  184 + return;
  185 +}
  186 +
  187 +static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
  188 + struct urb *urb, gfp_t gfp)
  189 +{
  190 + struct sk_buff *skb;
  191 +
  192 + skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
  193 + if (!skb)
  194 + return -ENOMEM;
  195 +
  196 + /* reserve some space for mac80211's radiotap */
  197 + skb_reserve(skb, 32);
  198 +
  199 + usb_fill_bulk_urb(urb, aru->udev,
  200 + usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
  201 + skb->data, min(skb_tailroom(skb),
  202 + AR9170_MAX_RX_BUFFER_SIZE),
  203 + ar9170_usb_rx_completed, skb);
  204 +
  205 + return 0;
  206 +}
  207 +
  208 +static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
  209 +{
  210 + struct urb *urb = NULL;
  211 + void *ibuf;
  212 + int err = -ENOMEM;
  213 +
  214 + /* initialize interrupt endpoint */
  215 + urb = usb_alloc_urb(0, GFP_KERNEL);
  216 + if (!urb)
  217 + goto out;
  218 +
  219 + ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
  220 + if (!ibuf)
  221 + goto out;
  222 +
  223 + usb_fill_int_urb(urb, aru->udev,
  224 + usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
  225 + 64, ar9170_usb_irq_completed, aru, 1);
  226 + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  227 +
  228 + usb_anchor_urb(urb, &aru->rx_submitted);
  229 + err = usb_submit_urb(urb, GFP_KERNEL);
  230 + if (err) {
  231 + usb_unanchor_urb(urb);
  232 + usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
  233 + urb->transfer_dma);
  234 + }
  235 +
  236 +out:
  237 + usb_free_urb(urb);
  238 + return err;
  239 +}
  240 +
  241 +static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
  242 +{
  243 + struct urb *urb;
  244 + int i;
  245 + int err = -EINVAL;
  246 +
  247 + for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
  248 + err = -ENOMEM;
  249 + urb = usb_alloc_urb(0, GFP_KERNEL);
  250 + if (!urb)
  251 + goto err_out;
  252 +
  253 + err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
  254 + if (err) {
  255 + usb_free_urb(urb);
  256 + goto err_out;
  257 + }
  258 +
  259 + usb_anchor_urb(urb, &aru->rx_submitted);
  260 + err = usb_submit_urb(urb, GFP_KERNEL);
  261 + if (err) {
  262 + usb_unanchor_urb(urb);
  263 + dev_kfree_skb_any((void *) urb->transfer_buffer);
  264 + usb_free_urb(urb);
  265 + goto err_out;
  266 + }
  267 + usb_free_urb(urb);
  268 + }
  269 +
  270 + /* the device now waiting for a firmware. */
  271 + aru->common.state = AR9170_IDLE;
  272 + return 0;
  273 +
  274 +err_out:
  275 +
  276 + usb_kill_anchored_urbs(&aru->rx_submitted);
  277 + return err;
  278 +}
  279 +
  280 +static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
  281 +{
  282 + int ret;
  283 +
  284 + aru->common.state = AR9170_UNKNOWN_STATE;
  285 +
  286 + usb_unlink_anchored_urbs(&aru->tx_submitted);
  287 +
  288 + /* give the LED OFF command and the deauth frame a chance to air. */
  289 + ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
  290 + msecs_to_jiffies(100));
  291 + if (ret == 0)
  292 + dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
  293 + usb_poison_anchored_urbs(&aru->tx_submitted);
  294 +
  295 + usb_poison_anchored_urbs(&aru->rx_submitted);
  296 +}
  297 +
  298 +static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
  299 + unsigned int plen, void *payload,
  300 + unsigned int outlen, void *out)
  301 +{
  302 + struct ar9170_usb *aru = (void *) ar;
  303 + struct urb *urb = NULL;
  304 + unsigned long flags;
  305 + int err = -ENOMEM;
  306 +
  307 + if (unlikely(!IS_ACCEPTING_CMD(ar)))
  308 + return -EPERM;
  309 +
  310 + if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
  311 + return -EINVAL;
  312 +
  313 + urb = usb_alloc_urb(0, GFP_ATOMIC);
  314 + if (unlikely(!urb))
  315 + goto err_free;
  316 +
  317 + ar->cmdbuf[0] = cpu_to_le32(plen);
  318 + ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
  319 + /* writing multiple regs fills this buffer already */
  320 + if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
  321 + memcpy(&ar->cmdbuf[1], payload, plen);
  322 +
  323 + spin_lock_irqsave(&aru->common.cmdlock, flags);
  324 + aru->readbuf = (u8 *)out;
  325 + aru->readlen = outlen;
  326 + spin_unlock_irqrestore(&aru->common.cmdlock, flags);
  327 +
  328 + usb_fill_int_urb(urb, aru->udev,
  329 + usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
  330 + aru->common.cmdbuf, plen + 4,
  331 + ar9170_usb_tx_urb_complete, NULL, 1);
  332 +
  333 + usb_anchor_urb(urb, &aru->tx_submitted);
  334 + err = usb_submit_urb(urb, GFP_ATOMIC);
  335 + if (err) {
  336 + usb_unanchor_urb(urb);
  337 + usb_free_urb(urb);
  338 + goto err_unbuf;
  339 + }
  340 + usb_free_urb(urb);
  341 +
  342 + err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
  343 + if (err == 0) {
  344 + err = -ETIMEDOUT;
  345 + goto err_unbuf;
  346 + }
  347 +
  348 + if (outlen >= 0 && aru->readlen != outlen) {
  349 + err = -EMSGSIZE;
  350 + goto err_unbuf;
  351 + }
  352 +
  353 + return 0;
  354 +
  355 +err_unbuf:
  356 + /* Maybe the device was removed in the second we were waiting? */
  357 + if (IS_STARTED(ar)) {
  358 + dev_err(&aru->udev->dev, "no command feedback "
  359 + "received (%d).\n", err);
  360 +
  361 + /* provide some maybe useful debug information */
  362 + print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
  363 + aru->common.cmdbuf, plen + 4);
  364 + dump_stack();
  365 + }
  366 +
  367 + /* invalidate to avoid completing the next prematurely */
  368 + spin_lock_irqsave(&aru->common.cmdlock, flags);
  369 + aru->readbuf = NULL;
  370 + aru->readlen = 0;
  371 + spin_unlock_irqrestore(&aru->common.cmdlock, flags);
  372 +
  373 +err_free:
  374 +
  375 + return err;
  376 +}
  377 +
  378 +static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
  379 + bool txstatus_needed, unsigned int extra_len)
  380 +{
  381 + struct ar9170_usb *aru = (struct ar9170_usb *) ar;
  382 + struct urb *urb;
  383 + int err;
  384 +
  385 + if (unlikely(!IS_STARTED(ar))) {
  386 + /* Seriously, what were you drink... err... thinking!? */
  387 + return -EPERM;
  388 + }
  389 +
  390 + urb = usb_alloc_urb(0, GFP_ATOMIC);
  391 + if (unlikely(!urb))
  392 + return -ENOMEM;
  393 +
  394 + usb_fill_bulk_urb(urb, aru->udev,
  395 + usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
  396 + skb->data, skb->len + extra_len, (txstatus_needed ?
  397 + ar9170_usb_tx_urb_complete :
  398 + ar9170_usb_tx_urb_complete_free), skb);
  399 + urb->transfer_flags |= URB_ZERO_PACKET;
  400 +
  401 + usb_anchor_urb(urb, &aru->tx_submitted);
  402 + err = usb_submit_urb(urb, GFP_ATOMIC);
  403 + if (unlikely(err))
  404 + usb_unanchor_urb(urb);
  405 +
  406 + usb_free_urb(urb);
  407 + return err;
  408 +}
  409 +
  410 +static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
  411 +{
  412 + struct ar9170_usb *aru = (void *) ar;
  413 + unsigned long flags;
  414 + u32 in, out;
  415 +
  416 + if (!buffer)
  417 + return ;
  418 +
  419 + in = le32_to_cpup((__le32 *)buffer);
  420 + out = le32_to_cpu(ar->cmdbuf[0]);
  421 +
  422 + /* mask off length byte */
  423 + out &= ~0xFF;
  424 +
  425 + if (aru->readlen >= 0) {
  426 + /* add expected length */
  427 + out |= aru->readlen;
  428 + } else {
  429 + /* add obtained length */
  430 + out |= in & 0xFF;
  431 + }
  432 +
  433 + /*
  434 + * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
  435 + * length and we cannot predict the correct length in advance.
  436 + * So we only check if we provided enough space for the data.
  437 + */
  438 + if (unlikely(out < in)) {
  439 + dev_warn(&aru->udev->dev, "received invalid command response "
  440 + "got %d bytes, instead of %d bytes "
  441 + "and the resp length is %d bytes\n",
  442 + in, out, len);
  443 + print_hex_dump_bytes("ar9170 invalid resp: ",
  444 + DUMP_PREFIX_OFFSET, buffer, len);
  445 + /*
  446 + * Do not complete, then the command times out,
  447 + * and we get a stack trace from there.
  448 + */
  449 + return ;
  450 + }
  451 +
  452 + spin_lock_irqsave(&aru->common.cmdlock, flags);
  453 + if (aru->readbuf && len > 0) {
  454 + memcpy(aru->readbuf, buffer + 4, len - 4);
  455 + aru->readbuf = NULL;
  456 + }
  457 + complete(&aru->cmd_wait);
  458 + spin_unlock_irqrestore(&aru->common.cmdlock, flags);
  459 +}
  460 +
  461 +static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
  462 + size_t len, u32 addr, bool complete)
  463 +{
  464 + int transfer, err;
  465 + u8 *buf = kmalloc(4096, GFP_KERNEL);
  466 +
  467 + if (!buf)
  468 + return -ENOMEM;
  469 +
  470 + while (len) {
  471 + transfer = min_t(int, len, 4096);
  472 + memcpy(buf, data, transfer);
  473 +
  474 + err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
  475 + 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
  476 + addr >> 8, 0, buf, transfer, 1000);
  477 +
  478 + if (err < 0) {
  479 + kfree(buf);
  480 + return err;
  481 + }
  482 +
  483 + len -= transfer;
  484 + data += transfer;
  485 + addr += transfer;
  486 + }
  487 + kfree(buf);
  488 +
  489 + if (complete) {
  490 + err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
  491 + 0x31 /* FW DL COMPLETE */,
  492 + 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
  493 + }
  494 +
  495 + return 0;
  496 +}
  497 +
  498 +static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
  499 +{
  500 + int err = 0;
  501 +
  502 + err = request_firmware(&aru->init_values, "ar9170-1.fw",
  503 + &aru->udev->dev);
  504 + if (err) {
  505 + dev_err(&aru->udev->dev, "file with init values not found.\n");
  506 + return err;
  507 + }
  508 +
  509 + err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
  510 + if (err) {
  511 + release_firmware(aru->init_values);
  512 + dev_err(&aru->udev->dev, "firmware file not found.\n");
  513 + return err;
  514 + }
  515 +
  516 + return err;
  517 +}
  518 +
  519 +static int ar9170_usb_reset(struct ar9170_usb *aru)
  520 +{
  521 + int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
  522 +
  523 + if (lock) {
  524 + ret = usb_lock_device_for_reset(aru->udev, aru->intf);
  525 + if (ret < 0) {
  526 + dev_err(&aru->udev->dev, "unable to lock device "
  527 + "for reset (%d).\n", ret);
  528 + return ret;
  529 + }
  530 + }
  531 +
  532 + ret = usb_reset_device(aru->udev);
  533 + if (lock)
  534 + usb_unlock_device(aru->udev);
  535 +
  536 + /* let it rest - for a second - */
  537 + msleep(1000);
  538 +
  539 + return ret;
  540 +}
  541 +
  542 +static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
  543 +{
  544 + int err;
  545 +
  546 + /* First, upload initial values to device RAM */
  547 + err = ar9170_usb_upload(aru, aru->init_values->data,
  548 + aru->init_values->size, 0x102800, false);
  549 + if (err) {
  550 + dev_err(&aru->udev->dev, "firmware part 1 "
  551 + "upload failed (%d).\n", err);
  552 + return err;
  553 + }
  554 +
  555 + /* Then, upload the firmware itself and start it */
  556 + return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
  557 + 0x200000, true);
  558 +}
  559 +
  560 +static int ar9170_usb_init_transport(struct ar9170_usb *aru)
  561 +{
  562 + struct ar9170 *ar = (void *) &aru->common;
  563 + int err;
  564 +
  565 + ar9170_regwrite_begin(ar);
  566 +
  567 + /* Set USB Rx stream mode MAX packet number to 2 */
  568 + ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
  569 +
  570 + /* Set USB Rx stream mode timeout to 10us */
  571 + ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
  572 +
  573 + ar9170_regwrite_finish();
  574 +
  575 + err = ar9170_regwrite_result();
  576 + if (err)
  577 + dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
  578 +
  579 + return err;
  580 +}
  581 +
  582 +static void ar9170_usb_stop(struct ar9170 *ar)
  583 +{
  584 + struct ar9170_usb *aru = (void *) ar;
  585 + int ret;
  586 +
  587 + if (IS_ACCEPTING_CMD(ar))
  588 + aru->common.state = AR9170_STOPPED;
  589 +
  590 + /* lets wait a while until the tx - queues are dried out */
  591 + ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
  592 + msecs_to_jiffies(1000));
  593 + if (ret == 0)
  594 + dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
  595 +
  596 + usb_poison_anchored_urbs(&aru->tx_submitted);
  597 +
  598 + /*
  599 + * Note:
  600 + * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
  601 + * Else we would end up with a unresponsive device...
  602 + */
  603 +}
  604 +
  605 +static int ar9170_usb_open(struct ar9170 *ar)
  606 +{
  607 + struct ar9170_usb *aru = (void *) ar;
  608 + int err;
  609 +
  610 + usb_unpoison_anchored_urbs(&aru->tx_submitted);
  611 + err = ar9170_usb_init_transport(aru);
  612 + if (err) {
  613 + usb_poison_anchored_urbs(&aru->tx_submitted);
  614 + return err;
  615 + }
  616 +
  617 + aru->common.state = AR9170_IDLE;
  618 + return 0;
  619 +}
  620 +
  621 +static int ar9170_usb_probe(struct usb_interface *intf,
  622 + const struct usb_device_id *id)
  623 +{
  624 + struct ar9170_usb *aru;
  625 + struct ar9170 *ar;
  626 + struct usb_device *udev;
  627 + int err;
  628 +
  629 + aru = ar9170_alloc(sizeof(*aru));
  630 + if (IS_ERR(aru)) {
  631 + err = PTR_ERR(aru);
  632 + goto out;
  633 + }
  634 +
  635 + udev = interface_to_usbdev(intf);
  636 + usb_get_dev(udev);
  637 + aru->udev = udev;
  638 + aru->intf = intf;
  639 + ar = &aru->common;
  640 +
  641 + usb_set_intfdata(intf, aru);
  642 + SET_IEEE80211_DEV(ar->hw, &udev->dev);
  643 +
  644 + init_usb_anchor(&aru->rx_submitted);
  645 + init_usb_anchor(&aru->tx_submitted);
  646 + init_completion(&aru->cmd_wait);
  647 +
  648 + aru->common.stop = ar9170_usb_stop;
  649 + aru->common.open = ar9170_usb_open;
  650 + aru->common.tx = ar9170_usb_tx;
  651 + aru->common.exec_cmd = ar9170_usb_exec_cmd;
  652 + aru->common.callback_cmd = ar9170_usb_callback_cmd;
  653 +
  654 + err = ar9170_usb_reset(aru);
  655 + if (err)
  656 + goto err_unlock;
  657 +
  658 + err = ar9170_usb_request_firmware(aru);
  659 + if (err)
  660 + goto err_unlock;
  661 +
  662 + err = ar9170_usb_alloc_rx_irq_urb(aru);
  663 + if (err)
  664 + goto err_freefw;
  665 +
  666 + err = ar9170_usb_alloc_rx_bulk_urbs(aru);
  667 + if (err)
  668 + goto err_unrx;
  669 +
  670 + err = ar9170_usb_upload_firmware(aru);
  671 + if (err) {
  672 + err = ar9170_echo_test(&aru->common, 0x60d43110);
  673 + if (err) {
  674 + /* force user invention, by disabling the device */
  675 + err = usb_driver_set_configuration(aru->udev, -1);
  676 + dev_err(&aru->udev->dev, "device is in a bad state. "
  677 + "please reconnect it!\n");
  678 + goto err_unrx;
  679 + }
  680 + }
  681 +
  682 + err = ar9170_usb_open(ar);
  683 + if (err)
  684 + goto err_unrx;
  685 +
  686 + err = ar9170_register(ar, &udev->dev);
  687 +
  688 + ar9170_usb_stop(ar);
  689 + if (err)
  690 + goto err_unrx;
  691 +
  692 + return 0;
  693 +
  694 +err_unrx:
  695 + ar9170_usb_cancel_urbs(aru);
  696 +
  697 +err_freefw:
  698 + release_firmware(aru->init_values);
  699 + release_firmware(aru->firmware);
  700 +
  701 +err_unlock:
  702 + usb_set_intfdata(intf, NULL);
  703 + usb_put_dev(udev);
  704 + ieee80211_free_hw(ar->hw);
  705 +out:
  706 + return err;
  707 +}
  708 +
  709 +static void ar9170_usb_disconnect(struct usb_interface *intf)
  710 +{
  711 + struct ar9170_usb *aru = usb_get_intfdata(intf);
  712 +
  713 + if (!aru)
  714 + return;
  715 +
  716 + aru->common.state = AR9170_IDLE;
  717 + ar9170_unregister(&aru->common);
  718 + ar9170_usb_cancel_urbs(aru);
  719 +
  720 + release_firmware(aru->init_values);
  721 + release_firmware(aru->firmware);
  722 +
  723 + usb_put_dev(aru->udev);
  724 + usb_set_intfdata(intf, NULL);
  725 + ieee80211_free_hw(aru->common.hw);
  726 +}
  727 +
  728 +static struct usb_driver ar9170_driver = {
  729 + .name = "ar9170usb",
  730 + .probe = ar9170_usb_probe,
  731 + .disconnect = ar9170_usb_disconnect,
  732 + .id_table = ar9170_usb_ids,
  733 + .soft_unbind = 1,
  734 +};
  735 +
  736 +static int __init ar9170_init(void)
  737 +{
  738 + return usb_register(&ar9170_driver);
  739 +}
  740 +
  741 +static void __exit ar9170_exit(void)
  742 +{
  743 + usb_deregister(&ar9170_driver);
  744 +}
  745 +
  746 +module_init(ar9170_init);
  747 +module_exit(ar9170_exit);
drivers/net/wireless/ar9170/usb.h
  1 +/*
  2 + * Atheros AR9170 USB driver
  3 + *
  4 + * Driver specific definitions
  5 + *
  6 + * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
  7 + * Copyright 2009, Christian Lamparter <chunkeey@web.de>
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License as published by
  11 + * the Free Software Foundation; either version 2 of the License, or
  12 + * (at your option) any later version.
  13 + *
  14 + * This program is distributed in the hope that it will be useful,
  15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17 + * GNU General Public License for more details.
  18 + *
  19 + * You should have received a copy of the GNU General Public License
  20 + * along with this program; see the file COPYING. If not, see
  21 + * http://www.gnu.org/licenses/.
  22 + *
  23 + * This file incorporates work covered by the following copyright and
  24 + * permission notice:
  25 + * Copyright (c) 2007-2008 Atheros Communications, Inc.
  26 + *
  27 + * Permission to use, copy, modify, and/or distribute this software for any
  28 + * purpose with or without fee is hereby granted, provided that the above
  29 + * copyright notice and this permission notice appear in all copies.
  30 + *
  31 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  32 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  33 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  34 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  35 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  36 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  37 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  38 + */
  39 +#ifndef __USB_H
  40 +#define __USB_H
  41 +
  42 +#include <linux/usb.h>
  43 +#include <linux/completion.h>
  44 +#include <linux/spinlock.h>
  45 +#include <linux/leds.h>
  46 +#include <net/wireless.h>
  47 +#include <net/mac80211.h>
  48 +#include <linux/firmware.h>
  49 +#include "eeprom.h"
  50 +#include "hw.h"
  51 +#include "ar9170.h"
  52 +
  53 +#define AR9170_NUM_RX_URBS 16
  54 +
  55 +struct firmware;
  56 +
  57 +struct ar9170_usb {
  58 + struct ar9170 common;
  59 + struct usb_device *udev;
  60 + struct usb_interface *intf;
  61 +
  62 + struct usb_anchor rx_submitted;
  63 + struct usb_anchor tx_submitted;
  64 +
  65 + spinlock_t cmdlock;
  66 + struct completion cmd_wait;
  67 + int readlen;
  68 + u8 *readbuf;
  69 +
  70 + const struct firmware *init_values;
  71 + const struct firmware *firmware;
  72 +};
  73 +
  74 +#endif /* __USB_H */