]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/wireless/ath/ath9k/hif_usb.c
ath9k-htc:respect usb buffer cacheline alignment in reg out path
[net-next-2.6.git] / drivers / net / wireless / ath / ath9k / hif_usb.c
CommitLineData
fb9987d0
S
1/*
2 * Copyright (c) 2010 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "htc.h"
18
19#define ATH9K_FW_USB_DEV(devid, fw) \
20 { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw }
21
22static struct usb_device_id ath9k_hif_usb_ids[] = {
23 ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"),
e92119ca 24 ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"),
fb9987d0
S
25 { },
26};
27
28MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
29
30static int __hif_usb_tx(struct hif_device_usb *hif_dev);
31
32static void hif_usb_regout_cb(struct urb *urb)
33{
34 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
fb9987d0
S
35
36 switch (urb->status) {
37 case 0:
38 break;
39 case -ENOENT:
40 case -ECONNRESET:
fb9987d0
S
41 case -ENODEV:
42 case -ESHUTDOWN:
6f0f2669 43 goto free;
fb9987d0
S
44 default:
45 break;
46 }
47
48 if (cmd) {
49 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
50 cmd->skb, 1);
51 kfree(cmd);
fb9987d0 52 }
6f0f2669
S
53
54 return;
55free:
0fa35a58 56 kfree_skb(cmd->skb);
6f0f2669 57 kfree(cmd);
fb9987d0
S
58}
59
60static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
61 struct sk_buff *skb)
62{
63 struct urb *urb;
64 struct cmd_buf *cmd;
65 int ret = 0;
66
67 urb = usb_alloc_urb(0, GFP_KERNEL);
68 if (urb == NULL)
69 return -ENOMEM;
70
71 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
72 if (cmd == NULL) {
73 usb_free_urb(urb);
74 return -ENOMEM;
75 }
76
77 cmd->skb = skb;
78 cmd->hif_dev = hif_dev;
79
80 usb_fill_int_urb(urb, hif_dev->udev,
81 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
82 skb->data, skb->len,
83 hif_usb_regout_cb, cmd, 1);
84
6f0f2669 85 usb_anchor_urb(urb, &hif_dev->regout_submitted);
fb9987d0
S
86 ret = usb_submit_urb(urb, GFP_KERNEL);
87 if (ret) {
6f0f2669 88 usb_unanchor_urb(urb);
fb9987d0
S
89 kfree(cmd);
90 }
6f0f2669 91 usb_free_urb(urb);
fb9987d0
S
92
93 return ret;
94}
95
96static void hif_usb_tx_cb(struct urb *urb)
97{
98 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
99 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
100 struct sk_buff *skb;
101 bool drop, flush;
102
103 if (!hif_dev)
104 return;
105
106 switch (urb->status) {
107 case 0:
108 break;
109 case -ENOENT:
110 case -ECONNRESET:
111 break;
112 case -ENODEV:
113 case -ESHUTDOWN:
114 return;
115 default:
116 break;
117 }
118
119 if (tx_buf) {
120 spin_lock(&hif_dev->tx.tx_lock);
121 drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
122 flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
123 spin_unlock(&hif_dev->tx.tx_lock);
124
125 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
126 if (!drop && !flush) {
127 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
128 skb, 1);
129 TX_STAT_INC(skb_completed);
130 } else {
131 dev_kfree_skb_any(skb);
132 }
133 }
134
135 if (flush)
136 return;
137
138 tx_buf->len = tx_buf->offset = 0;
139 __skb_queue_head_init(&tx_buf->skb_queue);
140
141 spin_lock(&hif_dev->tx.tx_lock);
142 list_del(&tx_buf->list);
143 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
144 hif_dev->tx.tx_buf_cnt++;
145 if (!drop)
146 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
147 TX_STAT_INC(buf_completed);
148 spin_unlock(&hif_dev->tx.tx_lock);
149 }
150}
151
152/* TX lock has to be taken */
153static int __hif_usb_tx(struct hif_device_usb *hif_dev)
154{
155 struct tx_buf *tx_buf = NULL;
156 struct sk_buff *nskb = NULL;
157 int ret = 0, i;
158 u16 *hdr, tx_skb_cnt = 0;
159 u8 *buf;
160
161 if (hif_dev->tx.tx_skb_cnt == 0)
162 return 0;
163
164 /* Check if a free TX buffer is available */
165 if (list_empty(&hif_dev->tx.tx_buf))
166 return 0;
167
168 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
169 list_del(&tx_buf->list);
170 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
171 hif_dev->tx.tx_buf_cnt--;
172
173 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
174
175 for (i = 0; i < tx_skb_cnt; i++) {
176 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
177
178 /* Should never be NULL */
179 BUG_ON(!nskb);
180
181 hif_dev->tx.tx_skb_cnt--;
182
183 buf = tx_buf->buf;
184 buf += tx_buf->offset;
185 hdr = (u16 *)buf;
186 *hdr++ = nskb->len;
187 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
188 buf += 4;
189 memcpy(buf, nskb->data, nskb->len);
190 tx_buf->len = nskb->len + 4;
191
192 if (i < (tx_skb_cnt - 1))
193 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
194
195 if (i == (tx_skb_cnt - 1))
196 tx_buf->len += tx_buf->offset;
197
198 __skb_queue_tail(&tx_buf->skb_queue, nskb);
199 TX_STAT_INC(skb_queued);
200 }
201
202 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
203 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
204 tx_buf->buf, tx_buf->len,
205 hif_usb_tx_cb, tx_buf);
206
207 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
208 if (ret) {
209 tx_buf->len = tx_buf->offset = 0;
210 __skb_queue_purge(&tx_buf->skb_queue);
211 __skb_queue_head_init(&tx_buf->skb_queue);
212 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
213 hif_dev->tx.tx_buf_cnt++;
214 }
215
216 if (!ret)
217 TX_STAT_INC(buf_queued);
218
219 return ret;
220}
221
222static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
223 struct ath9k_htc_tx_ctl *tx_ctl)
224{
225 unsigned long flags;
226
227 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
228
229 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
230 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
231 return -ENODEV;
232 }
233
234 /* Check if the max queue count has been reached */
235 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
236 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
237 return -ENOMEM;
238 }
239
240 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
241 hif_dev->tx.tx_skb_cnt++;
242
243 /* Send normal frames immediately */
244 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
245 __hif_usb_tx(hif_dev);
246
247 /* Check if AMPDUs have to be sent immediately */
248 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
249 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
250 (hif_dev->tx.tx_skb_cnt < 2)) {
251 __hif_usb_tx(hif_dev);
252 }
253
254 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
255
256 return 0;
257}
258
259static void hif_usb_start(void *hif_handle, u8 pipe_id)
260{
261 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
262 unsigned long flags;
263
264 hif_dev->flags |= HIF_USB_START;
265
266 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
267 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
268 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
269}
270
271static void hif_usb_stop(void *hif_handle, u8 pipe_id)
272{
273 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
274 unsigned long flags;
275
276 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
277 __skb_queue_purge(&hif_dev->tx.tx_skb_queue);
278 hif_dev->tx.tx_skb_cnt = 0;
279 hif_dev->tx.flags |= HIF_USB_TX_STOP;
280 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
281}
282
283static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
284 struct ath9k_htc_tx_ctl *tx_ctl)
285{
286 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
287 int ret = 0;
288
289 switch (pipe_id) {
290 case USB_WLAN_TX_PIPE:
291 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
292 break;
293 case USB_REG_OUT_PIPE:
294 ret = hif_usb_send_regout(hif_dev, skb);
295 break;
296 default:
6335ed0f
S
297 dev_err(&hif_dev->udev->dev,
298 "ath9k_htc: Invalid TX pipe: %d\n", pipe_id);
fb9987d0
S
299 ret = -EINVAL;
300 break;
301 }
302
303 return ret;
304}
305
306static struct ath9k_htc_hif hif_usb = {
307 .transport = ATH9K_HIF_USB,
308 .name = "ath9k_hif_usb",
309
310 .control_ul_pipe = USB_REG_OUT_PIPE,
311 .control_dl_pipe = USB_REG_IN_PIPE,
312
313 .start = hif_usb_start,
314 .stop = hif_usb_stop,
315 .send = hif_usb_send,
316};
317
318static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
319 struct sk_buff *skb)
320{
c503269a 321 struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
fb9987d0
S
322 int index = 0, i = 0, chk_idx, len = skb->len;
323 int rx_remain_len = 0, rx_pkt_len = 0;
324 u16 pkt_len, pkt_tag, pool_index = 0;
325 u8 *ptr;
326
46baa1a2
S
327 spin_lock(&hif_dev->rx_lock);
328
fb9987d0
S
329 rx_remain_len = hif_dev->rx_remain_len;
330 rx_pkt_len = hif_dev->rx_transfer_len;
331
332 if (rx_remain_len != 0) {
333 struct sk_buff *remain_skb = hif_dev->remain_skb;
334
335 if (remain_skb) {
336 ptr = (u8 *) remain_skb->data;
337
338 index = rx_remain_len;
339 rx_remain_len -= hif_dev->rx_pad_len;
340 ptr += rx_pkt_len;
341
342 memcpy(ptr, skb->data, rx_remain_len);
343
344 rx_pkt_len += rx_remain_len;
345 hif_dev->rx_remain_len = 0;
346 skb_put(remain_skb, rx_pkt_len);
347
348 skb_pool[pool_index++] = remain_skb;
349
350 } else {
351 index = rx_remain_len;
352 }
353 }
354
46baa1a2
S
355 spin_unlock(&hif_dev->rx_lock);
356
fb9987d0
S
357 while (index < len) {
358 ptr = (u8 *) skb->data;
359
360 pkt_len = ptr[index] + (ptr[index+1] << 8);
361 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
362
363 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
364 u16 pad_len;
365
366 pad_len = 4 - (pkt_len & 0x3);
367 if (pad_len == 4)
368 pad_len = 0;
369
370 chk_idx = index;
371 index = index + 4 + pkt_len + pad_len;
372
373 if (index > MAX_RX_BUF_SIZE) {
46baa1a2 374 spin_lock(&hif_dev->rx_lock);
fb9987d0
S
375 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
376 hif_dev->rx_transfer_len =
377 MAX_RX_BUF_SIZE - chk_idx - 4;
378 hif_dev->rx_pad_len = pad_len;
379
380 nskb = __dev_alloc_skb(pkt_len + 32,
381 GFP_ATOMIC);
382 if (!nskb) {
383 dev_err(&hif_dev->udev->dev,
384 "ath9k_htc: RX memory allocation"
385 " error\n");
46baa1a2 386 spin_unlock(&hif_dev->rx_lock);
fb9987d0
S
387 goto err;
388 }
389 skb_reserve(nskb, 32);
390 RX_STAT_INC(skb_allocated);
391
392 memcpy(nskb->data, &(skb->data[chk_idx+4]),
393 hif_dev->rx_transfer_len);
394
395 /* Record the buffer pointer */
396 hif_dev->remain_skb = nskb;
46baa1a2 397 spin_unlock(&hif_dev->rx_lock);
fb9987d0
S
398 } else {
399 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
400 if (!nskb) {
401 dev_err(&hif_dev->udev->dev,
402 "ath9k_htc: RX memory allocation"
403 " error\n");
404 goto err;
405 }
406 skb_reserve(nskb, 32);
407 RX_STAT_INC(skb_allocated);
408
409 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
410 skb_put(nskb, pkt_len);
411 skb_pool[pool_index++] = nskb;
412 }
413 } else {
414 RX_STAT_INC(skb_dropped);
fb9987d0
S
415 return;
416 }
417 }
418
419err:
fb9987d0
S
420 for (i = 0; i < pool_index; i++) {
421 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
422 skb_pool[i]->len, USB_WLAN_RX_PIPE);
423 RX_STAT_INC(skb_completed);
424 }
425}
426
427static void ath9k_hif_usb_rx_cb(struct urb *urb)
428{
429 struct sk_buff *skb = (struct sk_buff *) urb->context;
fb9987d0
S
430 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
431 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
432 int ret;
433
6335ed0f
S
434 if (!skb)
435 return;
436
fb9987d0
S
437 if (!hif_dev)
438 goto free;
439
440 switch (urb->status) {
441 case 0:
442 break;
443 case -ENOENT:
444 case -ECONNRESET:
445 case -ENODEV:
446 case -ESHUTDOWN:
447 goto free;
448 default:
449 goto resubmit;
450 }
451
452 if (likely(urb->actual_length != 0)) {
453 skb_put(skb, urb->actual_length);
fb9987d0 454 ath9k_hif_usb_rx_stream(hif_dev, skb);
fb9987d0
S
455 }
456
457resubmit:
458 skb_reset_tail_pointer(skb);
459 skb_trim(skb, 0);
460
6335ed0f 461 usb_anchor_urb(urb, &hif_dev->rx_submitted);
fb9987d0 462 ret = usb_submit_urb(urb, GFP_ATOMIC);
6335ed0f
S
463 if (ret) {
464 usb_unanchor_urb(urb);
fb9987d0 465 goto free;
6335ed0f 466 }
fb9987d0
S
467
468 return;
469free:
f28a7b30 470 kfree_skb(skb);
fb9987d0
S
471}
472
473static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
474{
475 struct sk_buff *skb = (struct sk_buff *) urb->context;
476 struct sk_buff *nskb;
477 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
478 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
479 int ret;
480
6335ed0f
S
481 if (!skb)
482 return;
483
fb9987d0
S
484 if (!hif_dev)
485 goto free;
486
487 switch (urb->status) {
488 case 0:
489 break;
490 case -ENOENT:
491 case -ECONNRESET:
492 case -ENODEV:
493 case -ESHUTDOWN:
494 goto free;
495 default:
496 goto resubmit;
497 }
498
499 if (likely(urb->actual_length != 0)) {
500 skb_put(skb, urb->actual_length);
501
e6c6d33c 502 nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
fb9987d0
S
503 if (!nskb)
504 goto resubmit;
505
506 usb_fill_int_urb(urb, hif_dev->udev,
507 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
508 nskb->data, MAX_REG_IN_BUF_SIZE,
509 ath9k_hif_usb_reg_in_cb, nskb, 1);
510
511 ret = usb_submit_urb(urb, GFP_ATOMIC);
512 if (ret) {
e6c6d33c 513 kfree_skb(nskb);
fb9987d0
S
514 goto free;
515 }
516
517 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
518 skb->len, USB_REG_IN_PIPE);
519
520 return;
521 }
522
523resubmit:
524 skb_reset_tail_pointer(skb);
525 skb_trim(skb, 0);
526
527 ret = usb_submit_urb(urb, GFP_ATOMIC);
528 if (ret)
529 goto free;
530
531 return;
532free:
e6c6d33c 533 kfree_skb(skb);
6335ed0f 534 urb->context = NULL;
fb9987d0
S
535}
536
537static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
538{
539 unsigned long flags;
540 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
541
542 list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
543 list_del(&tx_buf->list);
544 usb_free_urb(tx_buf->urb);
545 kfree(tx_buf->buf);
546 kfree(tx_buf);
547 }
548
549 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
550 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
551 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
552
553 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
554 &hif_dev->tx.tx_pending, list) {
555 usb_kill_urb(tx_buf->urb);
556 list_del(&tx_buf->list);
557 usb_free_urb(tx_buf->urb);
558 kfree(tx_buf->buf);
559 kfree(tx_buf);
560 }
561
562 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
563 hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
564 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
565}
566
567static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
568{
569 struct tx_buf *tx_buf;
570 int i;
571
572 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
573 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
574 spin_lock_init(&hif_dev->tx.tx_lock);
575 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
576
577 for (i = 0; i < MAX_TX_URB_NUM; i++) {
578 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
579 if (!tx_buf)
580 goto err;
581
582 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
583 if (!tx_buf->buf)
584 goto err;
585
586 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
587 if (!tx_buf->urb)
588 goto err;
589
590 tx_buf->hif_dev = hif_dev;
591 __skb_queue_head_init(&tx_buf->skb_queue);
592
593 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
594 }
595
596 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
597
598 return 0;
599err:
600 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
601 return -ENOMEM;
602}
603
fb9987d0
S
604static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
605{
6335ed0f 606 usb_kill_anchored_urbs(&hif_dev->rx_submitted);
fb9987d0
S
607}
608
609static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
610{
6335ed0f
S
611 struct urb *urb = NULL;
612 struct sk_buff *skb = NULL;
fb9987d0
S
613 int i, ret;
614
6335ed0f 615 init_usb_anchor(&hif_dev->rx_submitted);
46baa1a2 616 spin_lock_init(&hif_dev->rx_lock);
6335ed0f 617
fb9987d0
S
618 for (i = 0; i < MAX_RX_URB_NUM; i++) {
619
620 /* Allocate URB */
6335ed0f
S
621 urb = usb_alloc_urb(0, GFP_KERNEL);
622 if (urb == NULL) {
fb9987d0 623 ret = -ENOMEM;
6335ed0f 624 goto err_urb;
fb9987d0
S
625 }
626
627 /* Allocate buffer */
f28a7b30 628 skb = alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
6335ed0f
S
629 if (!skb) {
630 ret = -ENOMEM;
631 goto err_skb;
632 }
fb9987d0 633
6335ed0f
S
634 usb_fill_bulk_urb(urb, hif_dev->udev,
635 usb_rcvbulkpipe(hif_dev->udev,
636 USB_WLAN_RX_PIPE),
637 skb->data, MAX_RX_BUF_SIZE,
638 ath9k_hif_usb_rx_cb, skb);
639
640 /* Anchor URB */
641 usb_anchor_urb(urb, &hif_dev->rx_submitted);
fb9987d0 642
6335ed0f
S
643 /* Submit URB */
644 ret = usb_submit_urb(urb, GFP_KERNEL);
645 if (ret) {
646 usb_unanchor_urb(urb);
647 goto err_submit;
648 }
66b10e33
S
649
650 /*
651 * Drop reference count.
652 * This ensures that the URB is freed when killing them.
653 */
654 usb_free_urb(urb);
fb9987d0
S
655 }
656
657 return 0;
658
6335ed0f 659err_submit:
f28a7b30 660 kfree_skb(skb);
6335ed0f
S
661err_skb:
662 usb_free_urb(urb);
663err_urb:
fb9987d0
S
664 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
665 return ret;
666}
667
668static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
669{
670 if (hif_dev->reg_in_urb) {
671 usb_kill_urb(hif_dev->reg_in_urb);
6335ed0f 672 if (hif_dev->reg_in_urb->context)
e6c6d33c 673 kfree_skb((void *)hif_dev->reg_in_urb->context);
fb9987d0
S
674 usb_free_urb(hif_dev->reg_in_urb);
675 hif_dev->reg_in_urb = NULL;
676 }
677}
678
679static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
680{
681 struct sk_buff *skb;
682
683 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
684 if (hif_dev->reg_in_urb == NULL)
685 return -ENOMEM;
686
e6c6d33c 687 skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
fb9987d0
S
688 if (!skb)
689 goto err;
690
691 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
692 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
693 skb->data, MAX_REG_IN_BUF_SIZE,
694 ath9k_hif_usb_reg_in_cb, skb, 1);
695
696 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
6335ed0f 697 goto err;
fb9987d0
S
698
699 return 0;
700
fb9987d0
S
701err:
702 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
703 return -ENOMEM;
704}
705
706static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
707{
6f0f2669
S
708 /* Register Write */
709 init_usb_anchor(&hif_dev->regout_submitted);
710
fb9987d0
S
711 /* TX */
712 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
713 goto err;
714
715 /* RX */
716 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
717 goto err;
718
6f0f2669 719 /* Register Read */
fb9987d0
S
720 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
721 goto err;
722
723 return 0;
724err:
725 return -ENOMEM;
726}
727
728static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
729{
730 int transfer, err;
731 const void *data = hif_dev->firmware->data;
732 size_t len = hif_dev->firmware->size;
733 u32 addr = AR9271_FIRMWARE;
734 u8 *buf = kzalloc(4096, GFP_KERNEL);
735
736 if (!buf)
737 return -ENOMEM;
738
739 while (len) {
740 transfer = min_t(int, len, 4096);
741 memcpy(buf, data, transfer);
742
743 err = usb_control_msg(hif_dev->udev,
744 usb_sndctrlpipe(hif_dev->udev, 0),
745 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
746 addr >> 8, 0, buf, transfer, HZ);
747 if (err < 0) {
748 kfree(buf);
749 return err;
750 }
751
752 len -= transfer;
753 data += transfer;
754 addr += transfer;
755 }
756 kfree(buf);
757
758 /*
759 * Issue FW download complete command to firmware.
760 */
761 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
762 FIRMWARE_DOWNLOAD_COMP,
763 0x40 | USB_DIR_OUT,
764 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
765 if (err)
766 return -EIO;
767
768 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
769 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
770
771 return 0;
772}
773
774static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
775 const char *fw_name)
776{
777 int ret;
778
779 /* Request firmware */
780 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
781 if (ret) {
782 dev_err(&hif_dev->udev->dev,
783 "ath9k_htc: Firmware - %s not found\n", fw_name);
784 goto err_fw_req;
785 }
786
787 /* Download firmware */
788 ret = ath9k_hif_usb_download_fw(hif_dev);
789 if (ret) {
790 dev_err(&hif_dev->udev->dev,
791 "ath9k_htc: Firmware - %s download failed\n", fw_name);
792 goto err_fw_download;
793 }
794
795 /* Alloc URBs */
796 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
797 if (ret) {
798 dev_err(&hif_dev->udev->dev,
799 "ath9k_htc: Unable to allocate URBs\n");
800 goto err_urb;
801 }
802
803 return 0;
804
805err_urb:
806 /* Nothing */
807err_fw_download:
808 release_firmware(hif_dev->firmware);
809err_fw_req:
810 hif_dev->firmware = NULL;
811 return ret;
812}
813
814static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
815{
6f0f2669 816 usb_kill_anchored_urbs(&hif_dev->regout_submitted);
fb9987d0
S
817 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
818 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
819 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
820}
821
822static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
823{
824 ath9k_hif_usb_dealloc_urbs(hif_dev);
825 if (hif_dev->firmware)
826 release_firmware(hif_dev->firmware);
827}
828
829static int ath9k_hif_usb_probe(struct usb_interface *interface,
830 const struct usb_device_id *id)
831{
832 struct usb_device *udev = interface_to_usbdev(interface);
833 struct hif_device_usb *hif_dev;
834 const char *fw_name = (const char *) id->driver_info;
835 int ret = 0;
836
837 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
838 if (!hif_dev) {
839 ret = -ENOMEM;
840 goto err_alloc;
841 }
842
843 usb_get_dev(udev);
844 hif_dev->udev = udev;
845 hif_dev->interface = interface;
846 hif_dev->device_id = id->idProduct;
847#ifdef CONFIG_PM
848 udev->reset_resume = 1;
849#endif
850 usb_set_intfdata(interface, hif_dev);
851
852 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
853 if (ret) {
854 ret = -EINVAL;
855 goto err_hif_init_usb;
856 }
857
858 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
859 if (hif_dev->htc_handle == NULL) {
860 ret = -ENOMEM;
861 goto err_htc_hw_alloc;
862 }
863
864 ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
865 &hif_dev->udev->dev, hif_dev->device_id,
866 ATH9K_HIF_USB);
867 if (ret) {
868 ret = -EINVAL;
869 goto err_htc_hw_init;
870 }
871
872 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
873
874 return 0;
875
876err_htc_hw_init:
877 ath9k_htc_hw_free(hif_dev->htc_handle);
878err_htc_hw_alloc:
879 ath9k_hif_usb_dev_deinit(hif_dev);
880err_hif_init_usb:
881 usb_set_intfdata(interface, NULL);
882 kfree(hif_dev);
883 usb_put_dev(udev);
884err_alloc:
885 return ret;
886}
887
888static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
889{
890 struct usb_device *udev = interface_to_usbdev(interface);
891 struct hif_device_usb *hif_dev =
892 (struct hif_device_usb *) usb_get_intfdata(interface);
893
894 if (hif_dev) {
895 ath9k_htc_hw_deinit(hif_dev->htc_handle, true);
896 ath9k_htc_hw_free(hif_dev->htc_handle);
897 ath9k_hif_usb_dev_deinit(hif_dev);
898 usb_set_intfdata(interface, NULL);
899 }
900
901 if (hif_dev->flags & HIF_USB_START)
902 usb_reset_device(udev);
903
904 kfree(hif_dev);
905 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
906 usb_put_dev(udev);
907}
908
909#ifdef CONFIG_PM
910static int ath9k_hif_usb_suspend(struct usb_interface *interface,
911 pm_message_t message)
912{
913 struct hif_device_usb *hif_dev =
914 (struct hif_device_usb *) usb_get_intfdata(interface);
915
916 ath9k_hif_usb_dealloc_urbs(hif_dev);
917
918 return 0;
919}
920
921static int ath9k_hif_usb_resume(struct usb_interface *interface)
922{
923 struct hif_device_usb *hif_dev =
924 (struct hif_device_usb *) usb_get_intfdata(interface);
925 int ret;
926
927 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
928 if (ret)
929 return ret;
930
931 if (hif_dev->firmware) {
932 ret = ath9k_hif_usb_download_fw(hif_dev);
933 if (ret)
934 goto fail_resume;
935 } else {
936 ath9k_hif_usb_dealloc_urbs(hif_dev);
937 return -EIO;
938 }
939
940 mdelay(100);
941
942 ret = ath9k_htc_resume(hif_dev->htc_handle);
943
944 if (ret)
945 goto fail_resume;
946
947 return 0;
948
949fail_resume:
950 ath9k_hif_usb_dealloc_urbs(hif_dev);
951
952 return ret;
953}
954#endif
955
956static struct usb_driver ath9k_hif_usb_driver = {
957 .name = "ath9k_hif_usb",
958 .probe = ath9k_hif_usb_probe,
959 .disconnect = ath9k_hif_usb_disconnect,
960#ifdef CONFIG_PM
961 .suspend = ath9k_hif_usb_suspend,
962 .resume = ath9k_hif_usb_resume,
963 .reset_resume = ath9k_hif_usb_resume,
964#endif
965 .id_table = ath9k_hif_usb_ids,
966 .soft_unbind = 1,
967};
968
969int ath9k_hif_usb_init(void)
970{
971 return usb_register(&ath9k_hif_usb_driver);
972}
973
974void ath9k_hif_usb_exit(void)
975{
976 usb_deregister(&ath9k_hif_usb_driver);
977}