aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2009-03-21 18:05:48 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-03-27 20:13:09 -0400
commitb63a2cb30405777033d58045c562a3b04d87d702 (patch)
tree6c14c8772cb507c2ed3597311faebe5d1d3c6dbb /drivers
parent6cb19353535f9f02fc2a753e3261a255406ba8fa (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ar9170/usb.c747
-rw-r--r--drivers/net/wireless/ar9170/usb.h74
2 files changed, 821 insertions, 0 deletions
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
new file mode 100644
index 000000000000..ede511e40475
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.c
@@ -0,0 +1,747 @@
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
50MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
51MODULE_LICENSE("GPL");
52MODULE_DESCRIPTION("USB Driver for Atheros AR9170 based devices");
53MODULE_FIRMWARE("ar9170-1.fw");
54MODULE_FIRMWARE("ar9170-2.fw");
55
56static 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};
83MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
84
85static 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
100static void ar9170_usb_tx_urb_complete(struct urb *urb)
101{
102}
103
104static 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
127resubmit:
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
136free:
137 usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
138}
139
140static 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
169resubmit:
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
182free:
183 dev_kfree_skb_irq(skb);
184 return;
185}
186
187static 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
208static 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
236out:
237 usb_free_urb(urb);
238 return err;
239}
240
241static 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
274err_out:
275
276 usb_kill_anchored_urbs(&aru->rx_submitted);
277 return err;
278}
279
280static 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
298static 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
355err_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
373err_free:
374
375 return err;
376}
377
378static 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
410static 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
461static 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
498static 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
519static 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
542static 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
560static 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
582static 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
605static 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
621static 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
694err_unrx:
695 ar9170_usb_cancel_urbs(aru);
696
697err_freefw:
698 release_firmware(aru->init_values);
699 release_firmware(aru->firmware);
700
701err_unlock:
702 usb_set_intfdata(intf, NULL);
703 usb_put_dev(udev);
704 ieee80211_free_hw(ar->hw);
705out:
706 return err;
707}
708
709static 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
728static 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
736static int __init ar9170_init(void)
737{
738 return usb_register(&ar9170_driver);
739}
740
741static void __exit ar9170_exit(void)
742{
743 usb_deregister(&ar9170_driver);
744}
745
746module_init(ar9170_init);
747module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ar9170/usb.h
new file mode 100644
index 000000000000..f5852924cd64
--- /dev/null
+++ b/drivers/net/wireless/ar9170/usb.h
@@ -0,0 +1,74 @@
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
55struct firmware;
56
57struct 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 */