diff options
Diffstat (limited to 'drivers/net/wireless/ath/carl9170/usb.c')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/usb.c | 1175 |
1 files changed, 1175 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c new file mode 100644 index 000000000000..333b69ef2ae2 --- /dev/null +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
@@ -0,0 +1,1175 @@ | |||
1 | /* | ||
2 | * Atheros CARL9170 driver | ||
3 | * | ||
4 | * USB - frontend | ||
5 | * | ||
6 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | ||
7 | * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com> | ||
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/slab.h> | ||
42 | #include <linux/usb.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/etherdevice.h> | ||
45 | #include <linux/device.h> | ||
46 | #include <net/mac80211.h> | ||
47 | #include "carl9170.h" | ||
48 | #include "cmd.h" | ||
49 | #include "hw.h" | ||
50 | #include "fwcmd.h" | ||
51 | |||
52 | MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); | ||
53 | MODULE_AUTHOR("Christian Lamparter <chunkeey@googlemail.com>"); | ||
54 | MODULE_LICENSE("GPL"); | ||
55 | MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless"); | ||
56 | MODULE_FIRMWARE(CARL9170FW_NAME); | ||
57 | MODULE_ALIAS("ar9170usb"); | ||
58 | MODULE_ALIAS("arusb_lnx"); | ||
59 | |||
60 | /* | ||
61 | * Note: | ||
62 | * | ||
63 | * Always update our wiki's device list (located at: | ||
64 | * http://wireless.kernel.org/en/users/Drivers/ar9170/devices ), | ||
65 | * whenever you add a new device. | ||
66 | */ | ||
67 | static struct usb_device_id carl9170_usb_ids[] = { | ||
68 | /* Atheros 9170 */ | ||
69 | { USB_DEVICE(0x0cf3, 0x9170) }, | ||
70 | /* Atheros TG121N */ | ||
71 | { USB_DEVICE(0x0cf3, 0x1001) }, | ||
72 | /* TP-Link TL-WN821N v2 */ | ||
73 | { USB_DEVICE(0x0cf3, 0x1002), .driver_info = CARL9170_WPS_BUTTON | | ||
74 | CARL9170_ONE_LED }, | ||
75 | /* 3Com Dual Band 802.11n USB Adapter */ | ||
76 | { USB_DEVICE(0x0cf3, 0x1010) }, | ||
77 | /* H3C Dual Band 802.11n USB Adapter */ | ||
78 | { USB_DEVICE(0x0cf3, 0x1011) }, | ||
79 | /* Cace Airpcap NX */ | ||
80 | { USB_DEVICE(0xcace, 0x0300) }, | ||
81 | /* D-Link DWA 160 A1 */ | ||
82 | { USB_DEVICE(0x07d1, 0x3c10) }, | ||
83 | /* D-Link DWA 160 A2 */ | ||
84 | { USB_DEVICE(0x07d1, 0x3a09) }, | ||
85 | /* D-Link DWA 130 D */ | ||
86 | { USB_DEVICE(0x07d1, 0x3a0f) }, | ||
87 | /* Netgear WNA1000 */ | ||
88 | { USB_DEVICE(0x0846, 0x9040) }, | ||
89 | /* Netgear WNDA3100 (v1) */ | ||
90 | { USB_DEVICE(0x0846, 0x9010) }, | ||
91 | /* Netgear WN111 v2 */ | ||
92 | { USB_DEVICE(0x0846, 0x9001), .driver_info = CARL9170_ONE_LED }, | ||
93 | /* Zydas ZD1221 */ | ||
94 | { USB_DEVICE(0x0ace, 0x1221) }, | ||
95 | /* Proxim ORiNOCO 802.11n USB */ | ||
96 | { USB_DEVICE(0x1435, 0x0804) }, | ||
97 | /* WNC Generic 11n USB Dongle */ | ||
98 | { USB_DEVICE(0x1435, 0x0326) }, | ||
99 | /* ZyXEL NWD271N */ | ||
100 | { USB_DEVICE(0x0586, 0x3417) }, | ||
101 | /* Z-Com UB81 BG */ | ||
102 | { USB_DEVICE(0x0cde, 0x0023) }, | ||
103 | /* Z-Com UB82 ABG */ | ||
104 | { USB_DEVICE(0x0cde, 0x0026) }, | ||
105 | /* Sphairon Homelink 1202 */ | ||
106 | { USB_DEVICE(0x0cde, 0x0027) }, | ||
107 | /* Arcadyan WN7512 */ | ||
108 | { USB_DEVICE(0x083a, 0xf522) }, | ||
109 | /* Planex GWUS300 */ | ||
110 | { USB_DEVICE(0x2019, 0x5304) }, | ||
111 | /* IO-Data WNGDNUS2 */ | ||
112 | { USB_DEVICE(0x04bb, 0x093f) }, | ||
113 | /* NEC WL300NU-G */ | ||
114 | { USB_DEVICE(0x0409, 0x0249) }, | ||
115 | /* NEC WL300NU-AG */ | ||
116 | { USB_DEVICE(0x0409, 0x02b4) }, | ||
117 | /* AVM FRITZ!WLAN USB Stick N */ | ||
118 | { USB_DEVICE(0x057c, 0x8401) }, | ||
119 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | ||
120 | { USB_DEVICE(0x057c, 0x8402) }, | ||
121 | /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ | ||
122 | { USB_DEVICE(0x1668, 0x1200) }, | ||
123 | /* Airlive X.USB a/b/g/n */ | ||
124 | { USB_DEVICE(0x1b75, 0x9170) }, | ||
125 | |||
126 | /* terminate */ | ||
127 | {} | ||
128 | }; | ||
129 | MODULE_DEVICE_TABLE(usb, carl9170_usb_ids); | ||
130 | |||
131 | static void carl9170_usb_submit_data_urb(struct ar9170 *ar) | ||
132 | { | ||
133 | struct urb *urb; | ||
134 | int err; | ||
135 | |||
136 | if (atomic_inc_return(&ar->tx_anch_urbs) > AR9170_NUM_TX_URBS) | ||
137 | goto err_acc; | ||
138 | |||
139 | urb = usb_get_from_anchor(&ar->tx_wait); | ||
140 | if (!urb) | ||
141 | goto err_acc; | ||
142 | |||
143 | usb_anchor_urb(urb, &ar->tx_anch); | ||
144 | |||
145 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
146 | if (unlikely(err)) { | ||
147 | if (net_ratelimit()) { | ||
148 | dev_err(&ar->udev->dev, "tx submit failed (%d)\n", | ||
149 | urb->status); | ||
150 | } | ||
151 | |||
152 | usb_unanchor_urb(urb); | ||
153 | usb_anchor_urb(urb, &ar->tx_err); | ||
154 | } | ||
155 | |||
156 | usb_free_urb(urb); | ||
157 | |||
158 | if (likely(err == 0)) | ||
159 | return; | ||
160 | |||
161 | err_acc: | ||
162 | atomic_dec(&ar->tx_anch_urbs); | ||
163 | } | ||
164 | |||
165 | static void carl9170_usb_tx_data_complete(struct urb *urb) | ||
166 | { | ||
167 | struct ar9170 *ar = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
168 | |||
169 | if (WARN_ON_ONCE(!ar)) { | ||
170 | dev_kfree_skb_irq(urb->context); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | atomic_dec(&ar->tx_anch_urbs); | ||
175 | |||
176 | switch (urb->status) { | ||
177 | /* everything is fine */ | ||
178 | case 0: | ||
179 | carl9170_tx_callback(ar, (void *)urb->context); | ||
180 | break; | ||
181 | |||
182 | /* disconnect */ | ||
183 | case -ENOENT: | ||
184 | case -ECONNRESET: | ||
185 | case -ENODEV: | ||
186 | case -ESHUTDOWN: | ||
187 | /* | ||
188 | * Defer the frame clean-up to the tasklet worker. | ||
189 | * This is necessary, because carl9170_tx_drop | ||
190 | * does not work in an irqsave context. | ||
191 | */ | ||
192 | usb_anchor_urb(urb, &ar->tx_err); | ||
193 | return; | ||
194 | |||
195 | /* a random transmission error has occurred? */ | ||
196 | default: | ||
197 | if (net_ratelimit()) { | ||
198 | dev_err(&ar->udev->dev, "tx failed (%d)\n", | ||
199 | urb->status); | ||
200 | } | ||
201 | |||
202 | usb_anchor_urb(urb, &ar->tx_err); | ||
203 | break; | ||
204 | } | ||
205 | |||
206 | if (likely(IS_STARTED(ar))) | ||
207 | carl9170_usb_submit_data_urb(ar); | ||
208 | } | ||
209 | |||
210 | static int carl9170_usb_submit_cmd_urb(struct ar9170 *ar) | ||
211 | { | ||
212 | struct urb *urb; | ||
213 | int err; | ||
214 | |||
215 | if (atomic_inc_return(&ar->tx_cmd_urbs) != 1) { | ||
216 | atomic_dec(&ar->tx_cmd_urbs); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | urb = usb_get_from_anchor(&ar->tx_cmd); | ||
221 | if (!urb) { | ||
222 | atomic_dec(&ar->tx_cmd_urbs); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | usb_anchor_urb(urb, &ar->tx_anch); | ||
227 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
228 | if (unlikely(err)) { | ||
229 | usb_unanchor_urb(urb); | ||
230 | atomic_dec(&ar->tx_cmd_urbs); | ||
231 | } | ||
232 | usb_free_urb(urb); | ||
233 | |||
234 | return err; | ||
235 | } | ||
236 | |||
237 | static void carl9170_usb_cmd_complete(struct urb *urb) | ||
238 | { | ||
239 | struct ar9170 *ar = urb->context; | ||
240 | int err = 0; | ||
241 | |||
242 | if (WARN_ON_ONCE(!ar)) | ||
243 | return; | ||
244 | |||
245 | atomic_dec(&ar->tx_cmd_urbs); | ||
246 | |||
247 | switch (urb->status) { | ||
248 | /* everything is fine */ | ||
249 | case 0: | ||
250 | break; | ||
251 | |||
252 | /* disconnect */ | ||
253 | case -ENOENT: | ||
254 | case -ECONNRESET: | ||
255 | case -ENODEV: | ||
256 | case -ESHUTDOWN: | ||
257 | return; | ||
258 | |||
259 | default: | ||
260 | err = urb->status; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | if (!IS_INITIALIZED(ar)) | ||
265 | return; | ||
266 | |||
267 | if (err) | ||
268 | dev_err(&ar->udev->dev, "submit cmd cb failed (%d).\n", err); | ||
269 | |||
270 | err = carl9170_usb_submit_cmd_urb(ar); | ||
271 | if (err) | ||
272 | dev_err(&ar->udev->dev, "submit cmd failed (%d).\n", err); | ||
273 | } | ||
274 | |||
275 | static void carl9170_usb_rx_irq_complete(struct urb *urb) | ||
276 | { | ||
277 | struct ar9170 *ar = urb->context; | ||
278 | |||
279 | if (WARN_ON_ONCE(!ar)) | ||
280 | return; | ||
281 | |||
282 | switch (urb->status) { | ||
283 | /* everything is fine */ | ||
284 | case 0: | ||
285 | break; | ||
286 | |||
287 | /* disconnect */ | ||
288 | case -ENOENT: | ||
289 | case -ECONNRESET: | ||
290 | case -ENODEV: | ||
291 | case -ESHUTDOWN: | ||
292 | return; | ||
293 | |||
294 | default: | ||
295 | goto resubmit; | ||
296 | } | ||
297 | |||
298 | carl9170_handle_command_response(ar, urb->transfer_buffer, | ||
299 | urb->actual_length); | ||
300 | |||
301 | resubmit: | ||
302 | usb_anchor_urb(urb, &ar->rx_anch); | ||
303 | if (unlikely(usb_submit_urb(urb, GFP_ATOMIC))) | ||
304 | usb_unanchor_urb(urb); | ||
305 | } | ||
306 | |||
307 | static int carl9170_usb_submit_rx_urb(struct ar9170 *ar, gfp_t gfp) | ||
308 | { | ||
309 | struct urb *urb; | ||
310 | int err = 0, runs = 0; | ||
311 | |||
312 | while ((atomic_read(&ar->rx_anch_urbs) < AR9170_NUM_RX_URBS) && | ||
313 | (runs++ < AR9170_NUM_RX_URBS)) { | ||
314 | err = -ENOSPC; | ||
315 | urb = usb_get_from_anchor(&ar->rx_pool); | ||
316 | if (urb) { | ||
317 | usb_anchor_urb(urb, &ar->rx_anch); | ||
318 | err = usb_submit_urb(urb, gfp); | ||
319 | if (unlikely(err)) { | ||
320 | usb_unanchor_urb(urb); | ||
321 | usb_anchor_urb(urb, &ar->rx_pool); | ||
322 | } else { | ||
323 | atomic_dec(&ar->rx_pool_urbs); | ||
324 | atomic_inc(&ar->rx_anch_urbs); | ||
325 | } | ||
326 | usb_free_urb(urb); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | return err; | ||
331 | } | ||
332 | |||
333 | static void carl9170_usb_rx_work(struct ar9170 *ar) | ||
334 | { | ||
335 | struct urb *urb; | ||
336 | int i; | ||
337 | |||
338 | for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { | ||
339 | urb = usb_get_from_anchor(&ar->rx_work); | ||
340 | if (!urb) | ||
341 | break; | ||
342 | |||
343 | atomic_dec(&ar->rx_work_urbs); | ||
344 | if (IS_INITIALIZED(ar)) { | ||
345 | carl9170_rx(ar, urb->transfer_buffer, | ||
346 | urb->actual_length); | ||
347 | } | ||
348 | |||
349 | usb_anchor_urb(urb, &ar->rx_pool); | ||
350 | atomic_inc(&ar->rx_pool_urbs); | ||
351 | |||
352 | usb_free_urb(urb); | ||
353 | |||
354 | carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); | ||
355 | } | ||
356 | } | ||
357 | |||
358 | void carl9170_usb_handle_tx_err(struct ar9170 *ar) | ||
359 | { | ||
360 | struct urb *urb; | ||
361 | |||
362 | while ((urb = usb_get_from_anchor(&ar->tx_err))) { | ||
363 | struct sk_buff *skb = (void *)urb->context; | ||
364 | |||
365 | carl9170_tx_drop(ar, skb); | ||
366 | carl9170_tx_callback(ar, skb); | ||
367 | usb_free_urb(urb); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | static void carl9170_usb_tasklet(unsigned long data) | ||
372 | { | ||
373 | struct ar9170 *ar = (struct ar9170 *) data; | ||
374 | |||
375 | if (!IS_INITIALIZED(ar)) | ||
376 | return; | ||
377 | |||
378 | carl9170_usb_rx_work(ar); | ||
379 | |||
380 | /* | ||
381 | * Strictly speaking: The tx scheduler is not part of the USB system. | ||
382 | * But the rx worker returns frames back to the mac80211-stack and | ||
383 | * this is the _perfect_ place to generate the next transmissions. | ||
384 | */ | ||
385 | if (IS_STARTED(ar)) | ||
386 | carl9170_tx_scheduler(ar); | ||
387 | } | ||
388 | |||
389 | static void carl9170_usb_rx_complete(struct urb *urb) | ||
390 | { | ||
391 | struct ar9170 *ar = (struct ar9170 *)urb->context; | ||
392 | int err; | ||
393 | |||
394 | if (WARN_ON_ONCE(!ar)) | ||
395 | return; | ||
396 | |||
397 | atomic_dec(&ar->rx_anch_urbs); | ||
398 | |||
399 | switch (urb->status) { | ||
400 | case 0: | ||
401 | /* rx path */ | ||
402 | usb_anchor_urb(urb, &ar->rx_work); | ||
403 | atomic_inc(&ar->rx_work_urbs); | ||
404 | break; | ||
405 | |||
406 | case -ENOENT: | ||
407 | case -ECONNRESET: | ||
408 | case -ENODEV: | ||
409 | case -ESHUTDOWN: | ||
410 | /* handle disconnect events*/ | ||
411 | return; | ||
412 | |||
413 | default: | ||
414 | /* handle all other errors */ | ||
415 | usb_anchor_urb(urb, &ar->rx_pool); | ||
416 | atomic_inc(&ar->rx_pool_urbs); | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | err = carl9170_usb_submit_rx_urb(ar, GFP_ATOMIC); | ||
421 | if (unlikely(err)) { | ||
422 | /* | ||
423 | * usb_submit_rx_urb reported a problem. | ||
424 | * In case this is due to a rx buffer shortage, | ||
425 | * elevate the tasklet worker priority to | ||
426 | * the highest available level. | ||
427 | */ | ||
428 | tasklet_hi_schedule(&ar->usb_tasklet); | ||
429 | |||
430 | if (atomic_read(&ar->rx_anch_urbs) == 0) { | ||
431 | /* | ||
432 | * The system is too slow to cope with | ||
433 | * the enormous workload. We have simply | ||
434 | * run out of active rx urbs and this | ||
435 | * unfortunately leads to an unpredictable | ||
436 | * device. | ||
437 | */ | ||
438 | |||
439 | ieee80211_queue_work(ar->hw, &ar->ping_work); | ||
440 | } | ||
441 | } else { | ||
442 | /* | ||
443 | * Using anything less than _high_ priority absolutely | ||
444 | * kills the rx performance my UP-System... | ||
445 | */ | ||
446 | tasklet_hi_schedule(&ar->usb_tasklet); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | static struct urb *carl9170_usb_alloc_rx_urb(struct ar9170 *ar, gfp_t gfp) | ||
451 | { | ||
452 | struct urb *urb; | ||
453 | void *buf; | ||
454 | |||
455 | buf = kmalloc(ar->fw.rx_size, gfp); | ||
456 | if (!buf) | ||
457 | return NULL; | ||
458 | |||
459 | urb = usb_alloc_urb(0, gfp); | ||
460 | if (!urb) { | ||
461 | kfree(buf); | ||
462 | return NULL; | ||
463 | } | ||
464 | |||
465 | usb_fill_bulk_urb(urb, ar->udev, usb_rcvbulkpipe(ar->udev, | ||
466 | AR9170_USB_EP_RX), buf, ar->fw.rx_size, | ||
467 | carl9170_usb_rx_complete, ar); | ||
468 | |||
469 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
470 | |||
471 | return urb; | ||
472 | } | ||
473 | |||
474 | static int carl9170_usb_send_rx_irq_urb(struct ar9170 *ar) | ||
475 | { | ||
476 | struct urb *urb = NULL; | ||
477 | void *ibuf; | ||
478 | int err = -ENOMEM; | ||
479 | |||
480 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
481 | if (!urb) | ||
482 | goto out; | ||
483 | |||
484 | ibuf = kmalloc(AR9170_USB_EP_CTRL_MAX, GFP_KERNEL); | ||
485 | if (!ibuf) | ||
486 | goto out; | ||
487 | |||
488 | usb_fill_int_urb(urb, ar->udev, usb_rcvintpipe(ar->udev, | ||
489 | AR9170_USB_EP_IRQ), ibuf, AR9170_USB_EP_CTRL_MAX, | ||
490 | carl9170_usb_rx_irq_complete, ar, 1); | ||
491 | |||
492 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
493 | |||
494 | usb_anchor_urb(urb, &ar->rx_anch); | ||
495 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
496 | if (err) | ||
497 | usb_unanchor_urb(urb); | ||
498 | |||
499 | out: | ||
500 | usb_free_urb(urb); | ||
501 | return err; | ||
502 | } | ||
503 | |||
504 | static int carl9170_usb_init_rx_bulk_urbs(struct ar9170 *ar) | ||
505 | { | ||
506 | struct urb *urb; | ||
507 | int i, err = -EINVAL; | ||
508 | |||
509 | /* | ||
510 | * The driver actively maintains a second shadow | ||
511 | * pool for inactive, but fully-prepared rx urbs. | ||
512 | * | ||
513 | * The pool should help the driver to master huge | ||
514 | * workload spikes without running the risk of | ||
515 | * undersupplying the hardware or wasting time by | ||
516 | * processing rx data (streams) inside the urb | ||
517 | * completion (hardirq context). | ||
518 | */ | ||
519 | for (i = 0; i < AR9170_NUM_RX_URBS_POOL; i++) { | ||
520 | urb = carl9170_usb_alloc_rx_urb(ar, GFP_KERNEL); | ||
521 | if (!urb) { | ||
522 | err = -ENOMEM; | ||
523 | goto err_out; | ||
524 | } | ||
525 | |||
526 | usb_anchor_urb(urb, &ar->rx_pool); | ||
527 | atomic_inc(&ar->rx_pool_urbs); | ||
528 | usb_free_urb(urb); | ||
529 | } | ||
530 | |||
531 | err = carl9170_usb_submit_rx_urb(ar, GFP_KERNEL); | ||
532 | if (err) | ||
533 | goto err_out; | ||
534 | |||
535 | /* the device now waiting for the firmware. */ | ||
536 | carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); | ||
537 | return 0; | ||
538 | |||
539 | err_out: | ||
540 | |||
541 | usb_scuttle_anchored_urbs(&ar->rx_pool); | ||
542 | usb_scuttle_anchored_urbs(&ar->rx_work); | ||
543 | usb_kill_anchored_urbs(&ar->rx_anch); | ||
544 | return err; | ||
545 | } | ||
546 | |||
547 | static int carl9170_usb_flush(struct ar9170 *ar) | ||
548 | { | ||
549 | struct urb *urb; | ||
550 | int ret, err = 0; | ||
551 | |||
552 | while ((urb = usb_get_from_anchor(&ar->tx_wait))) { | ||
553 | struct sk_buff *skb = (void *)urb->context; | ||
554 | carl9170_tx_drop(ar, skb); | ||
555 | carl9170_tx_callback(ar, skb); | ||
556 | usb_free_urb(urb); | ||
557 | } | ||
558 | |||
559 | ret = usb_wait_anchor_empty_timeout(&ar->tx_cmd, 1000); | ||
560 | if (ret == 0) | ||
561 | err = -ETIMEDOUT; | ||
562 | |||
563 | /* lets wait a while until the tx - queues are dried out */ | ||
564 | ret = usb_wait_anchor_empty_timeout(&ar->tx_anch, 1000); | ||
565 | if (ret == 0) | ||
566 | err = -ETIMEDOUT; | ||
567 | |||
568 | usb_kill_anchored_urbs(&ar->tx_anch); | ||
569 | carl9170_usb_handle_tx_err(ar); | ||
570 | |||
571 | return err; | ||
572 | } | ||
573 | |||
574 | static void carl9170_usb_cancel_urbs(struct ar9170 *ar) | ||
575 | { | ||
576 | int err; | ||
577 | |||
578 | carl9170_set_state(ar, CARL9170_UNKNOWN_STATE); | ||
579 | |||
580 | err = carl9170_usb_flush(ar); | ||
581 | if (err) | ||
582 | dev_err(&ar->udev->dev, "stuck tx urbs!\n"); | ||
583 | |||
584 | usb_poison_anchored_urbs(&ar->tx_anch); | ||
585 | carl9170_usb_handle_tx_err(ar); | ||
586 | usb_poison_anchored_urbs(&ar->rx_anch); | ||
587 | |||
588 | tasklet_kill(&ar->usb_tasklet); | ||
589 | |||
590 | usb_scuttle_anchored_urbs(&ar->rx_work); | ||
591 | usb_scuttle_anchored_urbs(&ar->rx_pool); | ||
592 | usb_scuttle_anchored_urbs(&ar->tx_cmd); | ||
593 | } | ||
594 | |||
595 | int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, | ||
596 | const bool free_buf) | ||
597 | { | ||
598 | struct urb *urb; | ||
599 | int err = 0; | ||
600 | |||
601 | if (!IS_INITIALIZED(ar)) { | ||
602 | err = -EPERM; | ||
603 | goto err_free; | ||
604 | } | ||
605 | |||
606 | if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) { | ||
607 | err = -EINVAL; | ||
608 | goto err_free; | ||
609 | } | ||
610 | |||
611 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
612 | if (!urb) { | ||
613 | err = -ENOMEM; | ||
614 | goto err_free; | ||
615 | } | ||
616 | |||
617 | usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, | ||
618 | AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, | ||
619 | carl9170_usb_cmd_complete, ar, 1); | ||
620 | |||
621 | if (free_buf) | ||
622 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
623 | |||
624 | usb_anchor_urb(urb, &ar->tx_cmd); | ||
625 | usb_free_urb(urb); | ||
626 | |||
627 | return carl9170_usb_submit_cmd_urb(ar); | ||
628 | |||
629 | err_free: | ||
630 | if (free_buf) | ||
631 | kfree(cmd); | ||
632 | |||
633 | return err; | ||
634 | } | ||
635 | |||
636 | int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, | ||
637 | unsigned int plen, void *payload, unsigned int outlen, void *out) | ||
638 | { | ||
639 | int err = -ENOMEM; | ||
640 | |||
641 | if (!IS_ACCEPTING_CMD(ar)) | ||
642 | return -EIO; | ||
643 | |||
644 | if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) | ||
645 | might_sleep(); | ||
646 | |||
647 | ar->cmd.hdr.len = plen; | ||
648 | ar->cmd.hdr.cmd = cmd; | ||
649 | /* writing multiple regs fills this buffer already */ | ||
650 | if (plen && payload != (u8 *)(ar->cmd.data)) | ||
651 | memcpy(ar->cmd.data, payload, plen); | ||
652 | |||
653 | spin_lock_bh(&ar->cmd_lock); | ||
654 | ar->readbuf = (u8 *)out; | ||
655 | ar->readlen = outlen; | ||
656 | spin_unlock_bh(&ar->cmd_lock); | ||
657 | |||
658 | err = __carl9170_exec_cmd(ar, &ar->cmd, false); | ||
659 | |||
660 | if (!(cmd & CARL9170_CMD_ASYNC_FLAG)) { | ||
661 | err = wait_for_completion_timeout(&ar->cmd_wait, HZ); | ||
662 | if (err == 0) { | ||
663 | err = -ETIMEDOUT; | ||
664 | goto err_unbuf; | ||
665 | } | ||
666 | |||
667 | if (ar->readlen != outlen) { | ||
668 | err = -EMSGSIZE; | ||
669 | goto err_unbuf; | ||
670 | } | ||
671 | } | ||
672 | |||
673 | return 0; | ||
674 | |||
675 | err_unbuf: | ||
676 | /* Maybe the device was removed in the moment we were waiting? */ | ||
677 | if (IS_STARTED(ar)) { | ||
678 | dev_err(&ar->udev->dev, "no command feedback " | ||
679 | "received (%d).\n", err); | ||
680 | |||
681 | /* provide some maybe useful debug information */ | ||
682 | print_hex_dump_bytes("carl9170 cmd: ", DUMP_PREFIX_NONE, | ||
683 | &ar->cmd, plen + 4); | ||
684 | |||
685 | carl9170_restart(ar, CARL9170_RR_COMMAND_TIMEOUT); | ||
686 | } | ||
687 | |||
688 | /* invalidate to avoid completing the next command prematurely */ | ||
689 | spin_lock_bh(&ar->cmd_lock); | ||
690 | ar->readbuf = NULL; | ||
691 | ar->readlen = 0; | ||
692 | spin_unlock_bh(&ar->cmd_lock); | ||
693 | |||
694 | return err; | ||
695 | } | ||
696 | |||
697 | void carl9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb) | ||
698 | { | ||
699 | struct urb *urb; | ||
700 | struct ar9170_stream *tx_stream; | ||
701 | void *data; | ||
702 | unsigned int len; | ||
703 | |||
704 | if (!IS_STARTED(ar)) | ||
705 | goto err_drop; | ||
706 | |||
707 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
708 | if (!urb) | ||
709 | goto err_drop; | ||
710 | |||
711 | if (ar->fw.tx_stream) { | ||
712 | tx_stream = (void *) (skb->data - sizeof(*tx_stream)); | ||
713 | |||
714 | len = skb->len + sizeof(*tx_stream); | ||
715 | tx_stream->length = cpu_to_le16(len); | ||
716 | tx_stream->tag = cpu_to_le16(AR9170_TX_STREAM_TAG); | ||
717 | data = tx_stream; | ||
718 | } else { | ||
719 | data = skb->data; | ||
720 | len = skb->len; | ||
721 | } | ||
722 | |||
723 | usb_fill_bulk_urb(urb, ar->udev, usb_sndbulkpipe(ar->udev, | ||
724 | AR9170_USB_EP_TX), data, len, | ||
725 | carl9170_usb_tx_data_complete, skb); | ||
726 | |||
727 | urb->transfer_flags |= URB_ZERO_PACKET; | ||
728 | |||
729 | usb_anchor_urb(urb, &ar->tx_wait); | ||
730 | |||
731 | usb_free_urb(urb); | ||
732 | |||
733 | carl9170_usb_submit_data_urb(ar); | ||
734 | return; | ||
735 | |||
736 | err_drop: | ||
737 | carl9170_tx_drop(ar, skb); | ||
738 | carl9170_tx_callback(ar, skb); | ||
739 | } | ||
740 | |||
741 | static void carl9170_release_firmware(struct ar9170 *ar) | ||
742 | { | ||
743 | if (ar->fw.fw) { | ||
744 | release_firmware(ar->fw.fw); | ||
745 | memset(&ar->fw, 0, sizeof(ar->fw)); | ||
746 | } | ||
747 | } | ||
748 | |||
749 | void carl9170_usb_stop(struct ar9170 *ar) | ||
750 | { | ||
751 | int ret; | ||
752 | |||
753 | carl9170_set_state_when(ar, CARL9170_IDLE, CARL9170_STOPPED); | ||
754 | |||
755 | ret = carl9170_usb_flush(ar); | ||
756 | if (ret) | ||
757 | dev_err(&ar->udev->dev, "kill pending tx urbs.\n"); | ||
758 | |||
759 | usb_poison_anchored_urbs(&ar->tx_anch); | ||
760 | carl9170_usb_handle_tx_err(ar); | ||
761 | |||
762 | /* kill any pending command */ | ||
763 | spin_lock_bh(&ar->cmd_lock); | ||
764 | ar->readlen = 0; | ||
765 | spin_unlock_bh(&ar->cmd_lock); | ||
766 | complete_all(&ar->cmd_wait); | ||
767 | |||
768 | /* This is required to prevent an early completion on _start */ | ||
769 | INIT_COMPLETION(ar->cmd_wait); | ||
770 | |||
771 | /* | ||
772 | * Note: | ||
773 | * So far we freed all tx urbs, but we won't dare to touch any rx urbs. | ||
774 | * Else we would end up with a unresponsive device... | ||
775 | */ | ||
776 | } | ||
777 | |||
778 | int carl9170_usb_open(struct ar9170 *ar) | ||
779 | { | ||
780 | usb_unpoison_anchored_urbs(&ar->tx_anch); | ||
781 | |||
782 | carl9170_set_state_when(ar, CARL9170_STOPPED, CARL9170_IDLE); | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static int carl9170_usb_load_firmware(struct ar9170 *ar) | ||
787 | { | ||
788 | const u8 *data; | ||
789 | u8 *buf; | ||
790 | unsigned int transfer; | ||
791 | size_t len; | ||
792 | u32 addr; | ||
793 | int err = 0; | ||
794 | |||
795 | buf = kmalloc(4096, GFP_KERNEL); | ||
796 | if (!buf) { | ||
797 | err = -ENOMEM; | ||
798 | goto err_out; | ||
799 | } | ||
800 | |||
801 | data = ar->fw.fw->data; | ||
802 | len = ar->fw.fw->size; | ||
803 | addr = ar->fw.address; | ||
804 | |||
805 | /* this removes the miniboot image */ | ||
806 | data += ar->fw.offset; | ||
807 | len -= ar->fw.offset; | ||
808 | |||
809 | while (len) { | ||
810 | transfer = min_t(unsigned int, len, 4096u); | ||
811 | memcpy(buf, data, transfer); | ||
812 | |||
813 | err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), | ||
814 | 0x30 /* FW DL */, 0x40 | USB_DIR_OUT, | ||
815 | addr >> 8, 0, buf, transfer, 100); | ||
816 | |||
817 | if (err < 0) { | ||
818 | kfree(buf); | ||
819 | goto err_out; | ||
820 | } | ||
821 | |||
822 | len -= transfer; | ||
823 | data += transfer; | ||
824 | addr += transfer; | ||
825 | } | ||
826 | kfree(buf); | ||
827 | |||
828 | err = usb_control_msg(ar->udev, usb_sndctrlpipe(ar->udev, 0), | ||
829 | 0x31 /* FW DL COMPLETE */, | ||
830 | 0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 200); | ||
831 | |||
832 | if (wait_for_completion_timeout(&ar->fw_boot_wait, HZ) == 0) { | ||
833 | err = -ETIMEDOUT; | ||
834 | goto err_out; | ||
835 | } | ||
836 | |||
837 | err = carl9170_echo_test(ar, 0x4a110123); | ||
838 | if (err) | ||
839 | goto err_out; | ||
840 | |||
841 | /* now, start the command response counter */ | ||
842 | ar->cmd_seq = -1; | ||
843 | |||
844 | return 0; | ||
845 | |||
846 | err_out: | ||
847 | dev_err(&ar->udev->dev, "firmware upload failed (%d).\n", err); | ||
848 | return err; | ||
849 | } | ||
850 | |||
851 | int carl9170_usb_restart(struct ar9170 *ar) | ||
852 | { | ||
853 | int err = 0; | ||
854 | |||
855 | if (ar->intf->condition != USB_INTERFACE_BOUND) | ||
856 | return 0; | ||
857 | |||
858 | /* | ||
859 | * Disable the command response sequence counter check. | ||
860 | * We already know that the device/firmware is in a bad state. | ||
861 | * So, no extra points are awarded to anyone who reminds the | ||
862 | * driver about that. | ||
863 | */ | ||
864 | ar->cmd_seq = -2; | ||
865 | |||
866 | err = carl9170_reboot(ar); | ||
867 | |||
868 | carl9170_usb_stop(ar); | ||
869 | |||
870 | if (err) | ||
871 | goto err_out; | ||
872 | |||
873 | tasklet_schedule(&ar->usb_tasklet); | ||
874 | |||
875 | /* The reboot procedure can take quite a while to complete. */ | ||
876 | msleep(1100); | ||
877 | |||
878 | err = carl9170_usb_open(ar); | ||
879 | if (err) | ||
880 | goto err_out; | ||
881 | |||
882 | err = carl9170_usb_load_firmware(ar); | ||
883 | if (err) | ||
884 | goto err_out; | ||
885 | |||
886 | return 0; | ||
887 | |||
888 | err_out: | ||
889 | carl9170_usb_cancel_urbs(ar); | ||
890 | return err; | ||
891 | } | ||
892 | |||
893 | void carl9170_usb_reset(struct ar9170 *ar) | ||
894 | { | ||
895 | /* | ||
896 | * This is the last resort to get the device going again | ||
897 | * without any *user replugging action*. | ||
898 | * | ||
899 | * But there is a catch: usb_reset really is like a physical | ||
900 | * *reconnect*. The mac80211 state will be lost in the process. | ||
901 | * Therefore a userspace application, which is monitoring | ||
902 | * the link must step in. | ||
903 | */ | ||
904 | carl9170_usb_cancel_urbs(ar); | ||
905 | |||
906 | carl9170_usb_stop(ar); | ||
907 | |||
908 | usb_queue_reset_device(ar->intf); | ||
909 | } | ||
910 | |||
911 | static int carl9170_usb_init_device(struct ar9170 *ar) | ||
912 | { | ||
913 | int err; | ||
914 | |||
915 | /* | ||
916 | * The carl9170 firmware let's the driver know when it's | ||
917 | * ready for action. But we have to be prepared to gracefully | ||
918 | * handle all spurious [flushed] messages after each (re-)boot. | ||
919 | * Thus the command response counter remains disabled until it | ||
920 | * can be safely synchronized. | ||
921 | */ | ||
922 | ar->cmd_seq = -2; | ||
923 | |||
924 | err = carl9170_usb_send_rx_irq_urb(ar); | ||
925 | if (err) | ||
926 | goto err_out; | ||
927 | |||
928 | err = carl9170_usb_init_rx_bulk_urbs(ar); | ||
929 | if (err) | ||
930 | goto err_unrx; | ||
931 | |||
932 | err = carl9170_usb_open(ar); | ||
933 | if (err) | ||
934 | goto err_unrx; | ||
935 | |||
936 | mutex_lock(&ar->mutex); | ||
937 | err = carl9170_usb_load_firmware(ar); | ||
938 | mutex_unlock(&ar->mutex); | ||
939 | if (err) | ||
940 | goto err_stop; | ||
941 | |||
942 | return 0; | ||
943 | |||
944 | err_stop: | ||
945 | carl9170_usb_stop(ar); | ||
946 | |||
947 | err_unrx: | ||
948 | carl9170_usb_cancel_urbs(ar); | ||
949 | |||
950 | err_out: | ||
951 | return err; | ||
952 | } | ||
953 | |||
954 | static void carl9170_usb_firmware_failed(struct ar9170 *ar) | ||
955 | { | ||
956 | struct device *parent = ar->udev->dev.parent; | ||
957 | struct usb_device *udev; | ||
958 | |||
959 | /* | ||
960 | * Store a copy of the usb_device pointer locally. | ||
961 | * This is because device_release_driver initiates | ||
962 | * carl9170_usb_disconnect, which in turn frees our | ||
963 | * driver context (ar). | ||
964 | */ | ||
965 | udev = ar->udev; | ||
966 | |||
967 | complete(&ar->fw_load_wait); | ||
968 | |||
969 | /* unbind anything failed */ | ||
970 | if (parent) | ||
971 | device_lock(parent); | ||
972 | |||
973 | device_release_driver(&udev->dev); | ||
974 | if (parent) | ||
975 | device_unlock(parent); | ||
976 | |||
977 | usb_put_dev(udev); | ||
978 | } | ||
979 | |||
980 | static void carl9170_usb_firmware_finish(struct ar9170 *ar) | ||
981 | { | ||
982 | int err; | ||
983 | |||
984 | err = carl9170_parse_firmware(ar); | ||
985 | if (err) | ||
986 | goto err_freefw; | ||
987 | |||
988 | err = carl9170_usb_init_device(ar); | ||
989 | if (err) | ||
990 | goto err_freefw; | ||
991 | |||
992 | err = carl9170_register(ar); | ||
993 | |||
994 | carl9170_usb_stop(ar); | ||
995 | if (err) | ||
996 | goto err_unrx; | ||
997 | |||
998 | complete(&ar->fw_load_wait); | ||
999 | usb_put_dev(ar->udev); | ||
1000 | return; | ||
1001 | |||
1002 | err_unrx: | ||
1003 | carl9170_usb_cancel_urbs(ar); | ||
1004 | |||
1005 | err_freefw: | ||
1006 | carl9170_release_firmware(ar); | ||
1007 | carl9170_usb_firmware_failed(ar); | ||
1008 | } | ||
1009 | |||
1010 | static void carl9170_usb_firmware_step2(const struct firmware *fw, | ||
1011 | void *context) | ||
1012 | { | ||
1013 | struct ar9170 *ar = context; | ||
1014 | |||
1015 | if (fw) { | ||
1016 | ar->fw.fw = fw; | ||
1017 | carl9170_usb_firmware_finish(ar); | ||
1018 | return; | ||
1019 | } | ||
1020 | |||
1021 | dev_err(&ar->udev->dev, "firmware not found.\n"); | ||
1022 | carl9170_usb_firmware_failed(ar); | ||
1023 | } | ||
1024 | |||
1025 | static int carl9170_usb_probe(struct usb_interface *intf, | ||
1026 | const struct usb_device_id *id) | ||
1027 | { | ||
1028 | struct ar9170 *ar; | ||
1029 | struct usb_device *udev; | ||
1030 | int err; | ||
1031 | |||
1032 | err = usb_reset_device(interface_to_usbdev(intf)); | ||
1033 | if (err) | ||
1034 | return err; | ||
1035 | |||
1036 | ar = carl9170_alloc(sizeof(*ar)); | ||
1037 | if (IS_ERR(ar)) | ||
1038 | return PTR_ERR(ar); | ||
1039 | |||
1040 | udev = interface_to_usbdev(intf); | ||
1041 | usb_get_dev(udev); | ||
1042 | ar->udev = udev; | ||
1043 | ar->intf = intf; | ||
1044 | ar->features = id->driver_info; | ||
1045 | |||
1046 | usb_set_intfdata(intf, ar); | ||
1047 | SET_IEEE80211_DEV(ar->hw, &intf->dev); | ||
1048 | |||
1049 | init_usb_anchor(&ar->rx_anch); | ||
1050 | init_usb_anchor(&ar->rx_pool); | ||
1051 | init_usb_anchor(&ar->rx_work); | ||
1052 | init_usb_anchor(&ar->tx_wait); | ||
1053 | init_usb_anchor(&ar->tx_anch); | ||
1054 | init_usb_anchor(&ar->tx_cmd); | ||
1055 | init_usb_anchor(&ar->tx_err); | ||
1056 | init_completion(&ar->cmd_wait); | ||
1057 | init_completion(&ar->fw_boot_wait); | ||
1058 | init_completion(&ar->fw_load_wait); | ||
1059 | tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, | ||
1060 | (unsigned long)ar); | ||
1061 | |||
1062 | atomic_set(&ar->tx_cmd_urbs, 0); | ||
1063 | atomic_set(&ar->tx_anch_urbs, 0); | ||
1064 | atomic_set(&ar->rx_work_urbs, 0); | ||
1065 | atomic_set(&ar->rx_anch_urbs, 0); | ||
1066 | atomic_set(&ar->rx_pool_urbs, 0); | ||
1067 | |||
1068 | usb_get_dev(ar->udev); | ||
1069 | |||
1070 | carl9170_set_state(ar, CARL9170_STOPPED); | ||
1071 | |||
1072 | return request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, | ||
1073 | &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); | ||
1074 | } | ||
1075 | |||
1076 | static void carl9170_usb_disconnect(struct usb_interface *intf) | ||
1077 | { | ||
1078 | struct ar9170 *ar = usb_get_intfdata(intf); | ||
1079 | struct usb_device *udev; | ||
1080 | |||
1081 | if (WARN_ON(!ar)) | ||
1082 | return; | ||
1083 | |||
1084 | udev = ar->udev; | ||
1085 | wait_for_completion(&ar->fw_load_wait); | ||
1086 | |||
1087 | if (IS_INITIALIZED(ar)) { | ||
1088 | carl9170_reboot(ar); | ||
1089 | carl9170_usb_stop(ar); | ||
1090 | } | ||
1091 | |||
1092 | carl9170_usb_cancel_urbs(ar); | ||
1093 | carl9170_unregister(ar); | ||
1094 | |||
1095 | usb_set_intfdata(intf, NULL); | ||
1096 | |||
1097 | carl9170_release_firmware(ar); | ||
1098 | carl9170_free(ar); | ||
1099 | usb_put_dev(udev); | ||
1100 | } | ||
1101 | |||
1102 | #ifdef CONFIG_PM | ||
1103 | static int carl9170_usb_suspend(struct usb_interface *intf, | ||
1104 | pm_message_t message) | ||
1105 | { | ||
1106 | struct ar9170 *ar = usb_get_intfdata(intf); | ||
1107 | |||
1108 | if (!ar) | ||
1109 | return -ENODEV; | ||
1110 | |||
1111 | carl9170_usb_cancel_urbs(ar); | ||
1112 | |||
1113 | return 0; | ||
1114 | } | ||
1115 | |||
1116 | static int carl9170_usb_resume(struct usb_interface *intf) | ||
1117 | { | ||
1118 | struct ar9170 *ar = usb_get_intfdata(intf); | ||
1119 | int err; | ||
1120 | |||
1121 | if (!ar) | ||
1122 | return -ENODEV; | ||
1123 | |||
1124 | usb_unpoison_anchored_urbs(&ar->rx_anch); | ||
1125 | carl9170_set_state(ar, CARL9170_STOPPED); | ||
1126 | |||
1127 | /* | ||
1128 | * The USB documentation demands that [for suspend] all traffic | ||
1129 | * to and from the device has to stop. This would be fine, but | ||
1130 | * there's a catch: the device[usb phy] does not come back. | ||
1131 | * | ||
1132 | * Upon resume the firmware will "kill" itself and the | ||
1133 | * boot-code sorts out the magic voodoo. | ||
1134 | * Not very nice, but there's not much what could go wrong. | ||
1135 | */ | ||
1136 | msleep(1100); | ||
1137 | |||
1138 | err = carl9170_usb_init_device(ar); | ||
1139 | if (err) | ||
1140 | goto err_unrx; | ||
1141 | |||
1142 | return 0; | ||
1143 | |||
1144 | err_unrx: | ||
1145 | carl9170_usb_cancel_urbs(ar); | ||
1146 | |||
1147 | return err; | ||
1148 | } | ||
1149 | #endif /* CONFIG_PM */ | ||
1150 | |||
1151 | static struct usb_driver carl9170_driver = { | ||
1152 | .name = KBUILD_MODNAME, | ||
1153 | .probe = carl9170_usb_probe, | ||
1154 | .disconnect = carl9170_usb_disconnect, | ||
1155 | .id_table = carl9170_usb_ids, | ||
1156 | .soft_unbind = 1, | ||
1157 | #ifdef CONFIG_PM | ||
1158 | .suspend = carl9170_usb_suspend, | ||
1159 | .resume = carl9170_usb_resume, | ||
1160 | .reset_resume = carl9170_usb_resume, | ||
1161 | #endif /* CONFIG_PM */ | ||
1162 | }; | ||
1163 | |||
1164 | static int __init carl9170_usb_init(void) | ||
1165 | { | ||
1166 | return usb_register(&carl9170_driver); | ||
1167 | } | ||
1168 | |||
1169 | static void __exit carl9170_usb_exit(void) | ||
1170 | { | ||
1171 | usb_deregister(&carl9170_driver); | ||
1172 | } | ||
1173 | |||
1174 | module_init(carl9170_usb_init); | ||
1175 | module_exit(carl9170_usb_exit); | ||