blob: e0799d92405773206f9e2128b5a5cddeb6765d06 [file] [log] [blame]
Christian Lamparterb63a2cb2009-03-21 23:05:48 +01001/*
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
Christian Lamparterde00c042009-03-24 16:21:55 +010050MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010051MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
52MODULE_LICENSE("GPL");
Christian Lamparterde00c042009-03-24 16:21:55 +010053MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
Luis R. Rodriguezc768b582009-05-28 17:36:04 -040054MODULE_FIRMWARE("ar9170.fw");
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010055MODULE_FIRMWARE("ar9170-1.fw");
56MODULE_FIRMWARE("ar9170-2.fw");
57
Luis R. Rodriguezbdf6d322009-05-28 17:36:05 -040058enum ar9170_requirements {
59 AR9170_REQ_FW1_ONLY = 1,
60};
61
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010062static struct usb_device_id ar9170_usb_ids[] = {
63 /* Atheros 9170 */
64 { USB_DEVICE(0x0cf3, 0x9170) },
65 /* Atheros TG121N */
66 { USB_DEVICE(0x0cf3, 0x1001) },
Christian Lamparterfe9f6342009-09-17 13:46:53 +020067 /* TP-Link TL-WN821N v2 */
68 { USB_DEVICE(0x0cf3, 0x1002) },
Christian Lamparter4fc298b2009-03-24 21:58:08 +010069 /* Cace Airpcap NX */
70 { USB_DEVICE(0xcace, 0x0300) },
Thomas Klute15295382009-11-17 11:58:18 +010071 /* D-Link DWA 160 A1 */
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010072 { USB_DEVICE(0x07d1, 0x3c10) },
Thomas Klute15295382009-11-17 11:58:18 +010073 /* D-Link DWA 160 A2 */
74 { USB_DEVICE(0x07d1, 0x3a09) },
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010075 /* Netgear WNDA3100 */
76 { USB_DEVICE(0x0846, 0x9010) },
77 /* Netgear WN111 v2 */
78 { USB_DEVICE(0x0846, 0x9001) },
79 /* Zydas ZD1221 */
80 { USB_DEVICE(0x0ace, 0x1221) },
Christian Lamparter957b0512009-04-17 14:52:23 +020081 /* ZyXEL NWD271N */
82 { USB_DEVICE(0x0586, 0x3417) },
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010083 /* Z-Com UB81 BG */
84 { USB_DEVICE(0x0cde, 0x0023) },
85 /* Z-Com UB82 ABG */
86 { USB_DEVICE(0x0cde, 0x0026) },
87 /* Arcadyan WN7512 */
88 { USB_DEVICE(0x083a, 0xf522) },
89 /* Planex GWUS300 */
90 { USB_DEVICE(0x2019, 0x5304) },
91 /* IO-Data WNGDNUS2 */
92 { USB_DEVICE(0x04bb, 0x093f) },
Luis R. Rodriguezbdf6d322009-05-28 17:36:05 -040093 /* AVM FRITZ!WLAN USB Stick N */
94 { USB_DEVICE(0x057C, 0x8401) },
95 /* AVM FRITZ!WLAN USB Stick N 2.4 */
96 { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
Christian Lamparterb63a2cb2009-03-21 23:05:48 +010097
98 /* terminate */
99 {}
100};
101MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
102
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200103static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
104{
105 struct urb *urb;
106 unsigned long flags;
107 int err;
108
109 if (unlikely(!IS_STARTED(&aru->common)))
110 return ;
111
112 spin_lock_irqsave(&aru->tx_urb_lock, flags);
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200113 if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200114 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
115 return ;
116 }
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200117 atomic_inc(&aru->tx_submitted_urbs);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200118
119 urb = usb_get_from_anchor(&aru->tx_pending);
120 if (!urb) {
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200121 atomic_dec(&aru->tx_submitted_urbs);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200122 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
123
124 return ;
125 }
126 spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
127
128 aru->tx_pending_urbs--;
129 usb_anchor_urb(urb, &aru->tx_submitted);
130
131 err = usb_submit_urb(urb, GFP_ATOMIC);
132 if (unlikely(err)) {
133 if (ar9170_nag_limiter(&aru->common))
134 dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
135 err);
136
137 usb_unanchor_urb(urb);
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200138 atomic_dec(&aru->tx_submitted_urbs);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200139 ar9170_tx_callback(&aru->common, urb->context);
140 }
141
142 usb_free_urb(urb);
143}
144
145static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100146{
147 struct sk_buff *skb = urb->context;
148 struct ar9170_usb *aru = (struct ar9170_usb *)
149 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
150
Christian Lamparter66d00812009-05-28 17:04:27 +0200151 if (unlikely(!aru)) {
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100152 dev_kfree_skb_irq(skb);
153 return ;
154 }
155
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200156 atomic_dec(&aru->tx_submitted_urbs);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200157
158 ar9170_tx_callback(&aru->common, skb);
159
160 ar9170_usb_submit_urb(aru);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100161}
162
163static void ar9170_usb_tx_urb_complete(struct urb *urb)
164{
165}
166
167static void ar9170_usb_irq_completed(struct urb *urb)
168{
169 struct ar9170_usb *aru = urb->context;
170
171 switch (urb->status) {
172 /* everything is fine */
173 case 0:
174 break;
175
176 /* disconnect */
177 case -ENOENT:
178 case -ECONNRESET:
179 case -ENODEV:
180 case -ESHUTDOWN:
181 goto free;
182
183 default:
184 goto resubmit;
185 }
186
Christian Lamparter66d00812009-05-28 17:04:27 +0200187 ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
188 urb->actual_length);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100189
190resubmit:
191 usb_anchor_urb(urb, &aru->rx_submitted);
192 if (usb_submit_urb(urb, GFP_ATOMIC)) {
193 usb_unanchor_urb(urb);
194 goto free;
195 }
196
197 return;
198
199free:
200 usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
201}
202
203static void ar9170_usb_rx_completed(struct urb *urb)
204{
205 struct sk_buff *skb = urb->context;
206 struct ar9170_usb *aru = (struct ar9170_usb *)
207 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
208 int err;
209
210 if (!aru)
211 goto free;
212
213 switch (urb->status) {
214 /* everything is fine */
215 case 0:
216 break;
217
218 /* disconnect */
219 case -ENOENT:
220 case -ECONNRESET:
221 case -ENODEV:
222 case -ESHUTDOWN:
223 goto free;
224
225 default:
226 goto resubmit;
227 }
228
229 skb_put(skb, urb->actual_length);
230 ar9170_rx(&aru->common, skb);
231
232resubmit:
233 skb_reset_tail_pointer(skb);
234 skb_trim(skb, 0);
235
236 usb_anchor_urb(urb, &aru->rx_submitted);
237 err = usb_submit_urb(urb, GFP_ATOMIC);
Christian Lamparter66d00812009-05-28 17:04:27 +0200238 if (unlikely(err)) {
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100239 usb_unanchor_urb(urb);
Christian Lamparter66d00812009-05-28 17:04:27 +0200240 goto free;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100241 }
242
243 return ;
244
245free:
246 dev_kfree_skb_irq(skb);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100247}
248
249static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
250 struct urb *urb, gfp_t gfp)
251{
252 struct sk_buff *skb;
253
254 skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
255 if (!skb)
256 return -ENOMEM;
257
258 /* reserve some space for mac80211's radiotap */
259 skb_reserve(skb, 32);
260
261 usb_fill_bulk_urb(urb, aru->udev,
262 usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
263 skb->data, min(skb_tailroom(skb),
264 AR9170_MAX_RX_BUFFER_SIZE),
265 ar9170_usb_rx_completed, skb);
266
267 return 0;
268}
269
270static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
271{
272 struct urb *urb = NULL;
273 void *ibuf;
274 int err = -ENOMEM;
275
276 /* initialize interrupt endpoint */
277 urb = usb_alloc_urb(0, GFP_KERNEL);
278 if (!urb)
279 goto out;
280
281 ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
282 if (!ibuf)
283 goto out;
284
285 usb_fill_int_urb(urb, aru->udev,
286 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
287 64, ar9170_usb_irq_completed, aru, 1);
288 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
289
290 usb_anchor_urb(urb, &aru->rx_submitted);
291 err = usb_submit_urb(urb, GFP_KERNEL);
292 if (err) {
293 usb_unanchor_urb(urb);
294 usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
295 urb->transfer_dma);
296 }
297
298out:
299 usb_free_urb(urb);
300 return err;
301}
302
303static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
304{
305 struct urb *urb;
306 int i;
307 int err = -EINVAL;
308
309 for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
310 err = -ENOMEM;
311 urb = usb_alloc_urb(0, GFP_KERNEL);
312 if (!urb)
313 goto err_out;
314
315 err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
316 if (err) {
317 usb_free_urb(urb);
318 goto err_out;
319 }
320
321 usb_anchor_urb(urb, &aru->rx_submitted);
322 err = usb_submit_urb(urb, GFP_KERNEL);
323 if (err) {
324 usb_unanchor_urb(urb);
325 dev_kfree_skb_any((void *) urb->transfer_buffer);
326 usb_free_urb(urb);
327 goto err_out;
328 }
329 usb_free_urb(urb);
330 }
331
332 /* the device now waiting for a firmware. */
333 aru->common.state = AR9170_IDLE;
334 return 0;
335
336err_out:
337
338 usb_kill_anchored_urbs(&aru->rx_submitted);
339 return err;
340}
341
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200342static int ar9170_usb_flush(struct ar9170 *ar)
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100343{
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200344 struct ar9170_usb *aru = (void *) ar;
345 struct urb *urb;
346 int ret, err = 0;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100347
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200348 if (IS_STARTED(ar))
349 aru->common.state = AR9170_IDLE;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100350
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200351 usb_wait_anchor_empty_timeout(&aru->tx_pending,
352 msecs_to_jiffies(800));
353 while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
354 ar9170_tx_callback(&aru->common, (void *) urb->context);
355 usb_free_urb(urb);
356 }
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100357
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200358 /* lets wait a while until the tx - queues are dried out */
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100359 ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
360 msecs_to_jiffies(100));
361 if (ret == 0)
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200362 err = -ETIMEDOUT;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100363
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200364 usb_kill_anchored_urbs(&aru->tx_submitted);
365
366 if (IS_ACCEPTING_CMD(ar))
367 aru->common.state = AR9170_STARTED;
368
369 return err;
370}
371
372static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
373{
374 int err;
375
376 aru->common.state = AR9170_UNKNOWN_STATE;
377
378 err = ar9170_usb_flush(&aru->common);
379 if (err)
380 dev_err(&aru->udev->dev, "stuck tx urbs!\n");
381
382 usb_poison_anchored_urbs(&aru->tx_submitted);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100383 usb_poison_anchored_urbs(&aru->rx_submitted);
384}
385
386static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
387 unsigned int plen, void *payload,
388 unsigned int outlen, void *out)
389{
390 struct ar9170_usb *aru = (void *) ar;
391 struct urb *urb = NULL;
392 unsigned long flags;
393 int err = -ENOMEM;
394
395 if (unlikely(!IS_ACCEPTING_CMD(ar)))
396 return -EPERM;
397
398 if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
399 return -EINVAL;
400
401 urb = usb_alloc_urb(0, GFP_ATOMIC);
402 if (unlikely(!urb))
403 goto err_free;
404
405 ar->cmdbuf[0] = cpu_to_le32(plen);
406 ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
407 /* writing multiple regs fills this buffer already */
408 if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
409 memcpy(&ar->cmdbuf[1], payload, plen);
410
411 spin_lock_irqsave(&aru->common.cmdlock, flags);
412 aru->readbuf = (u8 *)out;
413 aru->readlen = outlen;
414 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
415
416 usb_fill_int_urb(urb, aru->udev,
417 usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
418 aru->common.cmdbuf, plen + 4,
419 ar9170_usb_tx_urb_complete, NULL, 1);
420
421 usb_anchor_urb(urb, &aru->tx_submitted);
422 err = usb_submit_urb(urb, GFP_ATOMIC);
Christian Lamparter66d00812009-05-28 17:04:27 +0200423 if (unlikely(err)) {
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100424 usb_unanchor_urb(urb);
425 usb_free_urb(urb);
426 goto err_unbuf;
427 }
428 usb_free_urb(urb);
429
430 err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
431 if (err == 0) {
432 err = -ETIMEDOUT;
433 goto err_unbuf;
434 }
435
Roel Kluinba5101d2009-04-26 14:40:59 +0200436 if (aru->readlen != outlen) {
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100437 err = -EMSGSIZE;
438 goto err_unbuf;
439 }
440
441 return 0;
442
443err_unbuf:
444 /* Maybe the device was removed in the second we were waiting? */
445 if (IS_STARTED(ar)) {
446 dev_err(&aru->udev->dev, "no command feedback "
447 "received (%d).\n", err);
448
449 /* provide some maybe useful debug information */
450 print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
451 aru->common.cmdbuf, plen + 4);
452 dump_stack();
453 }
454
455 /* invalidate to avoid completing the next prematurely */
456 spin_lock_irqsave(&aru->common.cmdlock, flags);
457 aru->readbuf = NULL;
458 aru->readlen = 0;
459 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
460
461err_free:
462
463 return err;
464}
465
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200466static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100467{
468 struct ar9170_usb *aru = (struct ar9170_usb *) ar;
469 struct urb *urb;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100470
471 if (unlikely(!IS_STARTED(ar))) {
472 /* Seriously, what were you drink... err... thinking!? */
473 return -EPERM;
474 }
475
476 urb = usb_alloc_urb(0, GFP_ATOMIC);
477 if (unlikely(!urb))
478 return -ENOMEM;
479
480 usb_fill_bulk_urb(urb, aru->udev,
481 usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200482 skb->data, skb->len,
483 ar9170_usb_tx_urb_complete_frame, skb);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100484 urb->transfer_flags |= URB_ZERO_PACKET;
485
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200486 usb_anchor_urb(urb, &aru->tx_pending);
487 aru->tx_pending_urbs++;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100488
489 usb_free_urb(urb);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200490
491 ar9170_usb_submit_urb(aru);
492 return 0;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100493}
494
495static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
496{
497 struct ar9170_usb *aru = (void *) ar;
498 unsigned long flags;
499 u32 in, out;
500
Christian Lamparter66d00812009-05-28 17:04:27 +0200501 if (unlikely(!buffer))
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100502 return ;
503
504 in = le32_to_cpup((__le32 *)buffer);
505 out = le32_to_cpu(ar->cmdbuf[0]);
506
507 /* mask off length byte */
508 out &= ~0xFF;
509
510 if (aru->readlen >= 0) {
511 /* add expected length */
512 out |= aru->readlen;
513 } else {
514 /* add obtained length */
515 out |= in & 0xFF;
516 }
517
518 /*
519 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
520 * length and we cannot predict the correct length in advance.
521 * So we only check if we provided enough space for the data.
522 */
523 if (unlikely(out < in)) {
524 dev_warn(&aru->udev->dev, "received invalid command response "
525 "got %d bytes, instead of %d bytes "
526 "and the resp length is %d bytes\n",
527 in, out, len);
528 print_hex_dump_bytes("ar9170 invalid resp: ",
529 DUMP_PREFIX_OFFSET, buffer, len);
530 /*
531 * Do not complete, then the command times out,
532 * and we get a stack trace from there.
533 */
534 return ;
535 }
536
537 spin_lock_irqsave(&aru->common.cmdlock, flags);
538 if (aru->readbuf && len > 0) {
539 memcpy(aru->readbuf, buffer + 4, len - 4);
540 aru->readbuf = NULL;
541 }
542 complete(&aru->cmd_wait);
543 spin_unlock_irqrestore(&aru->common.cmdlock, flags);
544}
545
546static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
547 size_t len, u32 addr, bool complete)
548{
549 int transfer, err;
550 u8 *buf = kmalloc(4096, GFP_KERNEL);
551
552 if (!buf)
553 return -ENOMEM;
554
555 while (len) {
556 transfer = min_t(int, len, 4096);
557 memcpy(buf, data, transfer);
558
559 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
560 0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
561 addr >> 8, 0, buf, transfer, 1000);
562
563 if (err < 0) {
564 kfree(buf);
565 return err;
566 }
567
568 len -= transfer;
569 data += transfer;
570 addr += transfer;
571 }
572 kfree(buf);
573
574 if (complete) {
575 err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
576 0x31 /* FW DL COMPLETE */,
577 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
578 }
579
580 return 0;
581}
582
583static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
584{
585 int err = 0;
586
Luis R. Rodriguezc768b582009-05-28 17:36:04 -0400587 err = request_firmware(&aru->firmware, "ar9170.fw",
588 &aru->udev->dev);
589 if (!err) {
590 aru->init_values = NULL;
591 return 0;
592 }
593
Luis R. Rodriguezbdf6d322009-05-28 17:36:05 -0400594 if (aru->req_one_stage_fw) {
595 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
596 "not found and is required for this device\n");
597 return -EINVAL;
598 }
599
Luis R. Rodriguezc768b582009-05-28 17:36:04 -0400600 dev_err(&aru->udev->dev, "ar9170.fw firmware file "
601 "not found, trying old firmware...\n");
602
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100603 err = request_firmware(&aru->init_values, "ar9170-1.fw",
604 &aru->udev->dev);
Christian Lamparter363ec562009-08-08 17:09:48 +0200605 if (err) {
606 dev_err(&aru->udev->dev, "file with init values not found.\n");
607 return err;
608 }
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100609
610 err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
611 if (err) {
612 release_firmware(aru->init_values);
Christian Lamparter363ec562009-08-08 17:09:48 +0200613 dev_err(&aru->udev->dev, "firmware file not found.\n");
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100614 return err;
615 }
616
617 return err;
618}
619
620static int ar9170_usb_reset(struct ar9170_usb *aru)
621{
622 int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
623
624 if (lock) {
625 ret = usb_lock_device_for_reset(aru->udev, aru->intf);
626 if (ret < 0) {
627 dev_err(&aru->udev->dev, "unable to lock device "
628 "for reset (%d).\n", ret);
629 return ret;
630 }
631 }
632
633 ret = usb_reset_device(aru->udev);
634 if (lock)
635 usb_unlock_device(aru->udev);
636
637 /* let it rest - for a second - */
638 msleep(1000);
639
640 return ret;
641}
642
643static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
644{
645 int err;
646
Luis R. Rodriguezc768b582009-05-28 17:36:04 -0400647 if (!aru->init_values)
648 goto upload_fw_start;
649
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100650 /* First, upload initial values to device RAM */
651 err = ar9170_usb_upload(aru, aru->init_values->data,
652 aru->init_values->size, 0x102800, false);
653 if (err) {
654 dev_err(&aru->udev->dev, "firmware part 1 "
655 "upload failed (%d).\n", err);
656 return err;
657 }
658
Luis R. Rodriguezc768b582009-05-28 17:36:04 -0400659upload_fw_start:
660
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100661 /* Then, upload the firmware itself and start it */
662 return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
663 0x200000, true);
664}
665
666static int ar9170_usb_init_transport(struct ar9170_usb *aru)
667{
668 struct ar9170 *ar = (void *) &aru->common;
669 int err;
670
671 ar9170_regwrite_begin(ar);
672
673 /* Set USB Rx stream mode MAX packet number to 2 */
674 ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
675
676 /* Set USB Rx stream mode timeout to 10us */
677 ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
678
679 ar9170_regwrite_finish();
680
681 err = ar9170_regwrite_result();
682 if (err)
683 dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
684
685 return err;
686}
687
688static void ar9170_usb_stop(struct ar9170 *ar)
689{
690 struct ar9170_usb *aru = (void *) ar;
691 int ret;
692
693 if (IS_ACCEPTING_CMD(ar))
694 aru->common.state = AR9170_STOPPED;
695
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200696 ret = ar9170_usb_flush(ar);
697 if (ret)
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100698 dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
699
700 usb_poison_anchored_urbs(&aru->tx_submitted);
701
702 /*
703 * Note:
704 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
705 * Else we would end up with a unresponsive device...
706 */
707}
708
709static int ar9170_usb_open(struct ar9170 *ar)
710{
711 struct ar9170_usb *aru = (void *) ar;
712 int err;
713
714 usb_unpoison_anchored_urbs(&aru->tx_submitted);
715 err = ar9170_usb_init_transport(aru);
716 if (err) {
717 usb_poison_anchored_urbs(&aru->tx_submitted);
718 return err;
719 }
720
721 aru->common.state = AR9170_IDLE;
722 return 0;
723}
724
Christian Lampartere10a9df2009-04-18 17:12:18 +0200725static int ar9170_usb_init_device(struct ar9170_usb *aru)
726{
727 int err;
728
729 err = ar9170_usb_alloc_rx_irq_urb(aru);
730 if (err)
731 goto err_out;
732
733 err = ar9170_usb_alloc_rx_bulk_urbs(aru);
734 if (err)
735 goto err_unrx;
736
737 err = ar9170_usb_upload_firmware(aru);
738 if (err) {
739 err = ar9170_echo_test(&aru->common, 0x60d43110);
740 if (err) {
741 /* force user invention, by disabling the device */
742 err = usb_driver_set_configuration(aru->udev, -1);
743 dev_err(&aru->udev->dev, "device is in a bad state. "
744 "please reconnect it!\n");
745 goto err_unrx;
746 }
747 }
748
749 return 0;
750
751err_unrx:
752 ar9170_usb_cancel_urbs(aru);
753
754err_out:
755 return err;
756}
757
Luis R. Rodriguezbdf6d322009-05-28 17:36:05 -0400758static bool ar9170_requires_one_stage(const struct usb_device_id *id)
759{
760 if (!id->driver_info)
761 return false;
762 if (id->driver_info == AR9170_REQ_FW1_ONLY)
763 return true;
764 return false;
765}
766
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100767static int ar9170_usb_probe(struct usb_interface *intf,
768 const struct usb_device_id *id)
769{
770 struct ar9170_usb *aru;
771 struct ar9170 *ar;
772 struct usb_device *udev;
773 int err;
774
775 aru = ar9170_alloc(sizeof(*aru));
776 if (IS_ERR(aru)) {
777 err = PTR_ERR(aru);
778 goto out;
779 }
780
781 udev = interface_to_usbdev(intf);
782 usb_get_dev(udev);
783 aru->udev = udev;
784 aru->intf = intf;
785 ar = &aru->common;
786
Luis R. Rodriguezbdf6d322009-05-28 17:36:05 -0400787 aru->req_one_stage_fw = ar9170_requires_one_stage(id);
788
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100789 usb_set_intfdata(intf, aru);
Christian Lamparter92179982009-06-20 05:10:24 +0200790 SET_IEEE80211_DEV(ar->hw, &intf->dev);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100791
792 init_usb_anchor(&aru->rx_submitted);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200793 init_usb_anchor(&aru->tx_pending);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100794 init_usb_anchor(&aru->tx_submitted);
795 init_completion(&aru->cmd_wait);
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200796 spin_lock_init(&aru->tx_urb_lock);
797
798 aru->tx_pending_urbs = 0;
Christian Lamparter731d6bf2009-10-17 21:56:51 +0200799 atomic_set(&aru->tx_submitted_urbs, 0);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100800
801 aru->common.stop = ar9170_usb_stop;
Christian Lamparter9b9c5aa2009-06-06 05:07:23 +0200802 aru->common.flush = ar9170_usb_flush;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100803 aru->common.open = ar9170_usb_open;
804 aru->common.tx = ar9170_usb_tx;
805 aru->common.exec_cmd = ar9170_usb_exec_cmd;
806 aru->common.callback_cmd = ar9170_usb_callback_cmd;
807
Alexander Beregalov8a713042009-05-04 20:46:25 +0400808#ifdef CONFIG_PM
Christian Lamparter90ccda92009-04-25 21:32:09 +0200809 udev->reset_resume = 1;
Christian Lamparter66d00812009-05-28 17:04:27 +0200810#endif /* CONFIG_PM */
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100811 err = ar9170_usb_reset(aru);
812 if (err)
Christian Lampartere10a9df2009-04-18 17:12:18 +0200813 goto err_freehw;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100814
815 err = ar9170_usb_request_firmware(aru);
816 if (err)
Christian Lampartere10a9df2009-04-18 17:12:18 +0200817 goto err_freehw;
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100818
Christian Lampartere10a9df2009-04-18 17:12:18 +0200819 err = ar9170_usb_init_device(aru);
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100820 if (err)
821 goto err_freefw;
822
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100823 err = ar9170_usb_open(ar);
824 if (err)
825 goto err_unrx;
826
827 err = ar9170_register(ar, &udev->dev);
828
829 ar9170_usb_stop(ar);
830 if (err)
831 goto err_unrx;
832
833 return 0;
834
835err_unrx:
836 ar9170_usb_cancel_urbs(aru);
837
838err_freefw:
839 release_firmware(aru->init_values);
840 release_firmware(aru->firmware);
841
Christian Lampartere10a9df2009-04-18 17:12:18 +0200842err_freehw:
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100843 usb_set_intfdata(intf, NULL);
844 usb_put_dev(udev);
845 ieee80211_free_hw(ar->hw);
846out:
847 return err;
848}
849
850static void ar9170_usb_disconnect(struct usb_interface *intf)
851{
852 struct ar9170_usb *aru = usb_get_intfdata(intf);
853
854 if (!aru)
855 return;
856
857 aru->common.state = AR9170_IDLE;
858 ar9170_unregister(&aru->common);
859 ar9170_usb_cancel_urbs(aru);
860
861 release_firmware(aru->init_values);
862 release_firmware(aru->firmware);
863
864 usb_put_dev(aru->udev);
865 usb_set_intfdata(intf, NULL);
866 ieee80211_free_hw(aru->common.hw);
867}
868
Christian Lampartere10a9df2009-04-18 17:12:18 +0200869#ifdef CONFIG_PM
870static int ar9170_suspend(struct usb_interface *intf,
871 pm_message_t message)
872{
873 struct ar9170_usb *aru = usb_get_intfdata(intf);
874
875 if (!aru)
876 return -ENODEV;
877
878 aru->common.state = AR9170_IDLE;
879 ar9170_usb_cancel_urbs(aru);
880
881 return 0;
882}
883
884static int ar9170_resume(struct usb_interface *intf)
885{
886 struct ar9170_usb *aru = usb_get_intfdata(intf);
887 int err;
888
889 if (!aru)
890 return -ENODEV;
891
892 usb_unpoison_anchored_urbs(&aru->rx_submitted);
893 usb_unpoison_anchored_urbs(&aru->tx_submitted);
894
Christian Lampartere10a9df2009-04-18 17:12:18 +0200895 err = ar9170_usb_init_device(aru);
896 if (err)
897 goto err_unrx;
898
899 err = ar9170_usb_open(&aru->common);
900 if (err)
901 goto err_unrx;
902
903 return 0;
904
905err_unrx:
906 aru->common.state = AR9170_IDLE;
907 ar9170_usb_cancel_urbs(aru);
908
909 return err;
910}
911#endif /* CONFIG_PM */
912
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100913static struct usb_driver ar9170_driver = {
914 .name = "ar9170usb",
915 .probe = ar9170_usb_probe,
916 .disconnect = ar9170_usb_disconnect,
917 .id_table = ar9170_usb_ids,
918 .soft_unbind = 1,
Christian Lampartere10a9df2009-04-18 17:12:18 +0200919#ifdef CONFIG_PM
920 .suspend = ar9170_suspend,
921 .resume = ar9170_resume,
Christian Lamparter90ccda92009-04-25 21:32:09 +0200922 .reset_resume = ar9170_resume,
Christian Lampartere10a9df2009-04-18 17:12:18 +0200923#endif /* CONFIG_PM */
Christian Lamparterb63a2cb2009-03-21 23:05:48 +0100924};
925
926static int __init ar9170_init(void)
927{
928 return usb_register(&ar9170_driver);
929}
930
931static void __exit ar9170_exit(void)
932{
933 usb_deregister(&ar9170_driver);
934}
935
936module_init(ar9170_init);
937module_exit(ar9170_exit);