hif_usb.c 26.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * Copyright (c) 2010 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "htc.h"

19
20
21
22
23
24
25
/* identify firmware images */
#define FIRMWARE_AR7010_1_1	"ar7010_1_1.fw"
#define FIRMWARE_AR9271		"ar9271.fw"

MODULE_FIRMWARE(FIRMWARE_AR7010_1_1);
MODULE_FIRMWARE(FIRMWARE_AR9271);

26
static struct usb_device_id ath9k_hif_usb_ids[] = {
27
28
29
30
31
32
	{ USB_DEVICE(0x0cf3, 0x9271) }, /* Atheros */
	{ USB_DEVICE(0x0cf3, 0x1006) }, /* Atheros */
	{ USB_DEVICE(0x0846, 0x9030) }, /* Netgear N150 */
	{ USB_DEVICE(0x07D1, 0x3A10) }, /* Dlink Wireless 150 */
	{ USB_DEVICE(0x13D3, 0x3327) }, /* Azurewave */
	{ USB_DEVICE(0x13D3, 0x3328) }, /* Azurewave */
33
	{ USB_DEVICE(0x13D3, 0x3346) }, /* IMC Networks */
34
35
36
	{ USB_DEVICE(0x13D3, 0x3348) }, /* Azurewave */
	{ USB_DEVICE(0x13D3, 0x3349) }, /* Azurewave */
	{ USB_DEVICE(0x13D3, 0x3350) }, /* Azurewave */
37
	{ USB_DEVICE(0x04CA, 0x4605) }, /* Liteon */
38
	{ USB_DEVICE(0x040D, 0x3801) }, /* VIA */
39
	{ USB_DEVICE(0x0cf3, 0xb003) }, /* Ubiquiti WifiStation Ext */
40
41
42

	{ USB_DEVICE(0x0cf3, 0x7015),
	  .driver_info = AR9287_USB },  /* Atheros */
43
	{ USB_DEVICE(0x1668, 0x1200),
44
45
46
47
48
49
50
51
52
	  .driver_info = AR9287_USB },  /* Verizon */

	{ USB_DEVICE(0x0cf3, 0x7010),
	  .driver_info = AR9280_USB },  /* Atheros */
	{ USB_DEVICE(0x0846, 0x9018),
	  .driver_info = AR9280_USB },  /* Netgear WNDA3200 */
	{ USB_DEVICE(0x083A, 0xA704),
	  .driver_info = AR9280_USB },  /* SMC Networks */

53
54
55
	{ USB_DEVICE(0x0cf3, 0x20ff),
	  .driver_info = STORAGE_DEVICE },

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
	{ },
};

MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);

static int __hif_usb_tx(struct hif_device_usb *hif_dev);

static void hif_usb_regout_cb(struct urb *urb)
{
	struct cmd_buf *cmd = (struct cmd_buf *)urb->context;

	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
74
		goto free;
75
76
77
78
79
80
81
82
83
	default:
		break;
	}

	if (cmd) {
		ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
					  cmd->skb, 1);
		kfree(cmd);
	}
84
85
86

	return;
free:
87
	kfree_skb(cmd->skb);
88
	kfree(cmd);
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
}

static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
			       struct sk_buff *skb)
{
	struct urb *urb;
	struct cmd_buf *cmd;
	int ret = 0;

	urb = usb_alloc_urb(0, GFP_KERNEL);
	if (urb == NULL)
		return -ENOMEM;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (cmd == NULL) {
		usb_free_urb(urb);
		return -ENOMEM;
	}

	cmd->skb = skb;
	cmd->hif_dev = hif_dev;

111
112
	usb_fill_bulk_urb(urb, hif_dev->udev,
			 usb_sndbulkpipe(hif_dev->udev, USB_REG_OUT_PIPE),
113
			 skb->data, skb->len,
114
			 hif_usb_regout_cb, cmd);
115

116
	usb_anchor_urb(urb, &hif_dev->regout_submitted);
117
118
	ret = usb_submit_urb(urb, GFP_KERNEL);
	if (ret) {
119
		usb_unanchor_urb(urb);
120
121
		kfree(cmd);
	}
122
	usb_free_urb(urb);
123
124
125
126

	return ret;
}

Sujith's avatar
Sujith committed
127
128
129
130
131
132
133
134
135
136
137
static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
					 struct sk_buff_head *list)
{
	struct sk_buff *skb;

	while ((skb = __skb_dequeue(list)) != NULL) {
		dev_kfree_skb_any(skb);
		TX_STAT_INC(skb_dropped);
	}
}

138
139
140
static void hif_usb_tx_cb(struct urb *urb)
{
	struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
141
	struct hif_device_usb *hif_dev;
142
143
	struct sk_buff *skb;

144
	if (!tx_buf || !tx_buf->hif_dev)
145
146
		return;

147
148
	hif_dev = tx_buf->hif_dev;

149
150
151
152
153
154
155
	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
Sujith's avatar
Sujith committed
156
		/*
157
		 * The URB has been killed, free the SKBs.
Sujith's avatar
Sujith committed
158
159
		 */
		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176

		/*
		 * If the URBs are being flushed, no need to add this
		 * URB to the free list.
		 */
		spin_lock(&hif_dev->tx.tx_lock);
		if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
			spin_unlock(&hif_dev->tx.tx_lock);
			return;
		}
		spin_unlock(&hif_dev->tx.tx_lock);

		/*
		 * In the stop() case, this URB has to be added to
		 * the free list.
		 */
		goto add_free;
177
178
179
180
	default:
		break;
	}

181
182
183
184
185
186
	/*
	 * Check if TX has been stopped, this is needed because
	 * this CB could have been invoked just after the TX lock
	 * was released in hif_stop() and kill_urb() hasn't been
	 * called yet.
	 */
Sujith's avatar
Sujith committed
187
188
	spin_lock(&hif_dev->tx.tx_lock);
	if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
189
		spin_unlock(&hif_dev->tx.tx_lock);
Sujith's avatar
Sujith committed
190
191
		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
		goto add_free;
192
	}
Sujith's avatar
Sujith committed
193
	spin_unlock(&hif_dev->tx.tx_lock);
194

Sujith's avatar
Sujith committed
195
196
197
198
199
	/* Complete the queued SKBs. */
	while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
		ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
					  skb, 1);
		TX_STAT_INC(skb_completed);
200
	}
Sujith's avatar
Sujith committed
201
202
203
204
205
206
207
208
209
210
211
212
213
214

add_free:
	/* Re-initialize the SKB queue */
	tx_buf->len = tx_buf->offset = 0;
	__skb_queue_head_init(&tx_buf->skb_queue);

	/* Add this TX buffer to the free list */
	spin_lock(&hif_dev->tx.tx_lock);
	list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
	hif_dev->tx.tx_buf_cnt++;
	if (!(hif_dev->tx.flags & HIF_USB_TX_STOP))
		__hif_usb_tx(hif_dev); /* Check for pending SKBs */
	TX_STAT_INC(buf_completed);
	spin_unlock(&hif_dev->tx.tx_lock);
215
216
}

217
218
219
220
221
222
/* TX lock has to be taken */
static int __hif_usb_tx(struct hif_device_usb *hif_dev)
{
	struct tx_buf *tx_buf = NULL;
	struct sk_buff *nskb = NULL;
	int ret = 0, i;
223
	u16 tx_skb_cnt = 0;
224
	u8 *buf;
225
	__le16 *hdr;
226
227
228
229
230
231
232
233
234

	if (hif_dev->tx.tx_skb_cnt == 0)
		return 0;

	/* Check if a free TX buffer is available */
	if (list_empty(&hif_dev->tx.tx_buf))
		return 0;

	tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
Sujith's avatar
Sujith committed
235
	list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
	hif_dev->tx.tx_buf_cnt--;

	tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);

	for (i = 0; i < tx_skb_cnt; i++) {
		nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);

		/* Should never be NULL */
		BUG_ON(!nskb);

		hif_dev->tx.tx_skb_cnt--;

		buf = tx_buf->buf;
		buf += tx_buf->offset;
250
251
252
		hdr = (__le16 *)buf;
		*hdr++ = cpu_to_le16(nskb->len);
		*hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG);
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
		buf += 4;
		memcpy(buf, nskb->data, nskb->len);
		tx_buf->len = nskb->len + 4;

		if (i < (tx_skb_cnt - 1))
			tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;

		if (i == (tx_skb_cnt - 1))
			tx_buf->len += tx_buf->offset;

		__skb_queue_tail(&tx_buf->skb_queue, nskb);
		TX_STAT_INC(skb_queued);
	}

	usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
			  usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
			  tx_buf->buf, tx_buf->len,
			  hif_usb_tx_cb, tx_buf);

	ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
	if (ret) {
		tx_buf->len = tx_buf->offset = 0;
275
		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
		__skb_queue_head_init(&tx_buf->skb_queue);
		list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
		hif_dev->tx.tx_buf_cnt++;
	}

	if (!ret)
		TX_STAT_INC(buf_queued);

	return ret;
}

static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
			   struct ath9k_htc_tx_ctl *tx_ctl)
{
	unsigned long flags;

	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);

	if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
		return -ENODEV;
	}

	/* Check if the max queue count has been reached */
	if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
		return -ENOMEM;
	}

	__skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
	hif_dev->tx.tx_skb_cnt++;

	/* Send normal frames immediately */
	if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
		__hif_usb_tx(hif_dev);

	/* Check if AMPDUs have to be sent immediately */
	if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
	    (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
	    (hif_dev->tx.tx_skb_cnt < 2)) {
		__hif_usb_tx(hif_dev);
	}

	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

	return 0;
}

static void hif_usb_start(void *hif_handle, u8 pipe_id)
{
	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
	unsigned long flags;

	hif_dev->flags |= HIF_USB_START;

	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
	hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
}

static void hif_usb_stop(void *hif_handle, u8 pipe_id)
{
	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
339
	struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
340
341
342
	unsigned long flags;

	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
343
	ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
344
345
346
	hif_dev->tx.tx_skb_cnt = 0;
	hif_dev->tx.flags |= HIF_USB_TX_STOP;
	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
347
348
349
350
351
352

	/* The pending URBs have to be canceled. */
	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
				 &hif_dev->tx.tx_pending, list) {
		usb_kill_urb(tx_buf->urb);
	}
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
}

static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
			struct ath9k_htc_tx_ctl *tx_ctl)
{
	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
	int ret = 0;

	switch (pipe_id) {
	case USB_WLAN_TX_PIPE:
		ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
		break;
	case USB_REG_OUT_PIPE:
		ret = hif_usb_send_regout(hif_dev, skb);
		break;
	default:
Sujith's avatar
Sujith committed
369
370
		dev_err(&hif_dev->udev->dev,
			"ath9k_htc: Invalid TX pipe: %d\n", pipe_id);
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
		ret = -EINVAL;
		break;
	}

	return ret;
}

static struct ath9k_htc_hif hif_usb = {
	.transport = ATH9K_HIF_USB,
	.name = "ath9k_hif_usb",

	.control_ul_pipe = USB_REG_OUT_PIPE,
	.control_dl_pipe = USB_REG_IN_PIPE,

	.start = hif_usb_start,
	.stop = hif_usb_stop,
	.send = hif_usb_send,
};

static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
				    struct sk_buff *skb)
{
Sujith's avatar
Sujith committed
393
	struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER];
394
395
396
	int index = 0, i = 0, len = skb->len;
	int rx_remain_len, rx_pkt_len;
	u16 pool_index = 0;
397
398
	u8 *ptr;

399
400
	spin_lock(&hif_dev->rx_lock);

401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
	rx_remain_len = hif_dev->rx_remain_len;
	rx_pkt_len = hif_dev->rx_transfer_len;

	if (rx_remain_len != 0) {
		struct sk_buff *remain_skb = hif_dev->remain_skb;

		if (remain_skb) {
			ptr = (u8 *) remain_skb->data;

			index = rx_remain_len;
			rx_remain_len -= hif_dev->rx_pad_len;
			ptr += rx_pkt_len;

			memcpy(ptr, skb->data, rx_remain_len);

			rx_pkt_len += rx_remain_len;
			hif_dev->rx_remain_len = 0;
			skb_put(remain_skb, rx_pkt_len);

			skb_pool[pool_index++] = remain_skb;

		} else {
			index = rx_remain_len;
		}
	}

427
428
	spin_unlock(&hif_dev->rx_lock);

429
	while (index < len) {
430
431
432
433
434
		u16 pkt_len;
		u16 pkt_tag;
		u16 pad_len;
		int chk_idx;

435
436
437
438
439
		ptr = (u8 *) skb->data;

		pkt_len = ptr[index] + (ptr[index+1] << 8);
		pkt_tag = ptr[index+2] + (ptr[index+3] << 8);

440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
			RX_STAT_INC(skb_dropped);
			return;
		}

		pad_len = 4 - (pkt_len & 0x3);
		if (pad_len == 4)
			pad_len = 0;

		chk_idx = index;
		index = index + 4 + pkt_len + pad_len;

		if (index > MAX_RX_BUF_SIZE) {
			spin_lock(&hif_dev->rx_lock);
			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
			hif_dev->rx_transfer_len =
				MAX_RX_BUF_SIZE - chk_idx - 4;
			hif_dev->rx_pad_len = pad_len;

			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
			if (!nskb) {
				dev_err(&hif_dev->udev->dev,
					"ath9k_htc: RX memory allocation error\n");
463
				spin_unlock(&hif_dev->rx_lock);
464
				goto err;
465
			}
466
467
468
469
470
471
472
473
474
			skb_reserve(nskb, 32);
			RX_STAT_INC(skb_allocated);

			memcpy(nskb->data, &(skb->data[chk_idx+4]),
			       hif_dev->rx_transfer_len);

			/* Record the buffer pointer */
			hif_dev->remain_skb = nskb;
			spin_unlock(&hif_dev->rx_lock);
475
		} else {
476
477
478
479
480
481
482
483
484
485
486
487
			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
			if (!nskb) {
				dev_err(&hif_dev->udev->dev,
					"ath9k_htc: RX memory allocation error\n");
				goto err;
			}
			skb_reserve(nskb, 32);
			RX_STAT_INC(skb_allocated);

			memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
			skb_put(nskb, pkt_len);
			skb_pool[pool_index++] = nskb;
488
489
490
491
492
493
494
495
496
497
498
499
500
501
		}
	}

err:
	for (i = 0; i < pool_index; i++) {
		ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
		RX_STAT_INC(skb_completed);
	}
}

static void ath9k_hif_usb_rx_cb(struct urb *urb)
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
502
	struct hif_device_usb *hif_dev =
503
504
505
		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
	int ret;

Sujith's avatar
Sujith committed
506
507
508
	if (!skb)
		return;

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
	if (!hif_dev)
		goto free;

	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
		goto free;
	default:
		goto resubmit;
	}

	if (likely(urb->actual_length != 0)) {
		skb_put(skb, urb->actual_length);
		ath9k_hif_usb_rx_stream(hif_dev, skb);
	}

resubmit:
	skb_reset_tail_pointer(skb);
	skb_trim(skb, 0);

Sujith's avatar
Sujith committed
533
	usb_anchor_urb(urb, &hif_dev->rx_submitted);
534
	ret = usb_submit_urb(urb, GFP_ATOMIC);
Sujith's avatar
Sujith committed
535
536
	if (ret) {
		usb_unanchor_urb(urb);
537
		goto free;
Sujith's avatar
Sujith committed
538
	}
539
540
541

	return;
free:
542
	kfree_skb(skb);
543
544
545
546
547
548
}

static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
{
	struct sk_buff *skb = (struct sk_buff *) urb->context;
	struct sk_buff *nskb;
549
	struct hif_device_usb *hif_dev =
550
551
552
		usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
	int ret;

Sujith's avatar
Sujith committed
553
554
555
	if (!skb)
		return;

556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
	if (!hif_dev)
		goto free;

	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
	case -ECONNRESET:
	case -ENODEV:
	case -ESHUTDOWN:
		goto free;
	default:
		goto resubmit;
	}

	if (likely(urb->actual_length != 0)) {
		skb_put(skb, urb->actual_length);

574
575
576
577
578
		/* Process the command first */
		ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
				 skb->len, USB_REG_IN_PIPE);


579
		nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
580
581
582
583
584
585
		if (!nskb) {
			dev_err(&hif_dev->udev->dev,
				"ath9k_htc: REG_IN memory allocation failure\n");
			urb->context = NULL;
			return;
		}
586

587
		usb_fill_bulk_urb(urb, hif_dev->udev,
588
589
				 usb_rcvbulkpipe(hif_dev->udev,
						 USB_REG_IN_PIPE),
590
				 nskb->data, MAX_REG_IN_BUF_SIZE,
591
				 ath9k_hif_usb_reg_in_cb, nskb);
592
593
594

		ret = usb_submit_urb(urb, GFP_ATOMIC);
		if (ret) {
595
			kfree_skb(nskb);
596
			urb->context = NULL;
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
		}

		return;
	}

resubmit:
	skb_reset_tail_pointer(skb);
	skb_trim(skb, 0);

	ret = usb_submit_urb(urb, GFP_ATOMIC);
	if (ret)
		goto free;

	return;
free:
612
	kfree_skb(skb);
Sujith's avatar
Sujith committed
613
	urb->context = NULL;
614
615
616
617
618
}

static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
{
	struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
619
	unsigned long flags;
620

Sujith's avatar
Sujith committed
621
622
623
	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
				 &hif_dev->tx.tx_buf, list) {
		usb_kill_urb(tx_buf->urb);
624
625
626
627
628
629
		list_del(&tx_buf->list);
		usb_free_urb(tx_buf->urb);
		kfree(tx_buf->buf);
		kfree(tx_buf);
	}

630
631
632
633
	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
	hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
				 &hif_dev->tx.tx_pending, list) {
		usb_kill_urb(tx_buf->urb);
		list_del(&tx_buf->list);
		usb_free_urb(tx_buf->urb);
		kfree(tx_buf->buf);
		kfree(tx_buf);
	}
}

static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
{
	struct tx_buf *tx_buf;
	int i;

	INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
	INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
	spin_lock_init(&hif_dev->tx.tx_lock);
	__skb_queue_head_init(&hif_dev->tx.tx_skb_queue);

	for (i = 0; i < MAX_TX_URB_NUM; i++) {
		tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
		if (!tx_buf)
			goto err;

		tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
		if (!tx_buf->buf)
			goto err;

		tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!tx_buf->urb)
			goto err;

		tx_buf->hif_dev = hif_dev;
		__skb_queue_head_init(&tx_buf->skb_queue);

		list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
	}

	hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;

	return 0;
err:
677
678
679
680
	if (tx_buf) {
		kfree(tx_buf->buf);
		kfree(tx_buf);
	}
681
682
683
684
685
686
	ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
	return -ENOMEM;
}

static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
{
Sujith's avatar
Sujith committed
687
	usb_kill_anchored_urbs(&hif_dev->rx_submitted);
688
689
690
691
}

static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
{
Sujith's avatar
Sujith committed
692
693
	struct urb *urb = NULL;
	struct sk_buff *skb = NULL;
694
695
	int i, ret;

Sujith's avatar
Sujith committed
696
	init_usb_anchor(&hif_dev->rx_submitted);
697
	spin_lock_init(&hif_dev->rx_lock);
Sujith's avatar
Sujith committed
698

699
700
701
	for (i = 0; i < MAX_RX_URB_NUM; i++) {

		/* Allocate URB */
Sujith's avatar
Sujith committed
702
703
		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (urb == NULL) {
704
			ret = -ENOMEM;
Sujith's avatar
Sujith committed
705
			goto err_urb;
706
707
708
		}

		/* Allocate buffer */
709
		skb = alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
Sujith's avatar
Sujith committed
710
711
712
713
		if (!skb) {
			ret = -ENOMEM;
			goto err_skb;
		}
714

Sujith's avatar
Sujith committed
715
716
717
718
719
720
721
722
		usb_fill_bulk_urb(urb, hif_dev->udev,
				  usb_rcvbulkpipe(hif_dev->udev,
						  USB_WLAN_RX_PIPE),
				  skb->data, MAX_RX_BUF_SIZE,
				  ath9k_hif_usb_rx_cb, skb);

		/* Anchor URB */
		usb_anchor_urb(urb, &hif_dev->rx_submitted);
723

Sujith's avatar
Sujith committed
724
725
726
727
728
729
		/* Submit URB */
		ret = usb_submit_urb(urb, GFP_KERNEL);
		if (ret) {
			usb_unanchor_urb(urb);
			goto err_submit;
		}
Sujith's avatar
Sujith committed
730
731
732
733
734
735

		/*
		 * Drop reference count.
		 * This ensures that the URB is freed when killing them.
		 */
		usb_free_urb(urb);
736
737
738
739
	}

	return 0;

Sujith's avatar
Sujith committed
740
err_submit:
741
	kfree_skb(skb);
Sujith's avatar
Sujith committed
742
743
744
err_skb:
	usb_free_urb(urb);
err_urb:
745
746
747
748
749
750
751
752
	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
	return ret;
}

static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
{
	if (hif_dev->reg_in_urb) {
		usb_kill_urb(hif_dev->reg_in_urb);
Sujith's avatar
Sujith committed
753
		if (hif_dev->reg_in_urb->context)
754
			kfree_skb((void *)hif_dev->reg_in_urb->context);
755
756
757
758
759
760
761
762
763
764
765
766
767
		usb_free_urb(hif_dev->reg_in_urb);
		hif_dev->reg_in_urb = NULL;
	}
}

static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
{
	struct sk_buff *skb;

	hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (hif_dev->reg_in_urb == NULL)
		return -ENOMEM;

768
	skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
769
770
771
	if (!skb)
		goto err;

772
	usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev,
773
774
			 usb_rcvbulkpipe(hif_dev->udev,
					 USB_REG_IN_PIPE),
775
			 skb->data, MAX_REG_IN_BUF_SIZE,
776
			 ath9k_hif_usb_reg_in_cb, skb);
777
778

	if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
Sujith's avatar
Sujith committed
779
		goto err;
780
781
782
783
784
785
786
787
788
789

	return 0;

err:
	ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
	return -ENOMEM;
}

static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
{
790
791
792
	/* Register Write */
	init_usb_anchor(&hif_dev->regout_submitted);

793
794
795
796
797
798
	/* TX */
	if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
		goto err;

	/* RX */
	if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
799
		goto err_rx;
800

801
	/* Register Read */
802
	if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
803
		goto err_reg;
804
805

	return 0;
806
807
808
809
err_reg:
	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
err_rx:
	ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
810
811
812
813
err:
	return -ENOMEM;
}

814
815
816
817
818
819
820
821
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
{
	usb_kill_anchored_urbs(&hif_dev->regout_submitted);
	ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
	ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}

822
823
static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev,
				     u32 drv_info)
824
825
826
827
828
829
{
	int transfer, err;
	const void *data = hif_dev->firmware->data;
	size_t len = hif_dev->firmware->size;
	u32 addr = AR9271_FIRMWARE;
	u8 *buf = kzalloc(4096, GFP_KERNEL);
Sujith's avatar
Sujith committed
830
	u32 firm_offset;
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

	if (!buf)
		return -ENOMEM;

	while (len) {
		transfer = min_t(int, len, 4096);
		memcpy(buf, data, transfer);

		err = usb_control_msg(hif_dev->udev,
				      usb_sndctrlpipe(hif_dev->udev, 0),
				      FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
				      addr >> 8, 0, buf, transfer, HZ);
		if (err < 0) {
			kfree(buf);
			return err;
		}

		len -= transfer;
		data += transfer;
		addr += transfer;
	}
	kfree(buf);

854
	if (IS_AR7010_DEVICE(drv_info))
Sujith's avatar
Sujith committed
855
		firm_offset = AR7010_FIRMWARE_TEXT;
856
	else
Sujith's avatar
Sujith committed
857
858
		firm_offset = AR9271_FIRMWARE_TEXT;

859
860
861
862
863
864
	/*
	 * Issue FW download complete command to firmware.
	 */
	err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
			      FIRMWARE_DOWNLOAD_COMP,
			      0x40 | USB_DIR_OUT,
Sujith's avatar
Sujith committed
865
			      firm_offset >> 8, 0, NULL, 0, HZ);
866
867
868
869
	if (err)
		return -EIO;

	dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
Sujith's avatar
Sujith committed
870
		 hif_dev->fw_name, (unsigned long) hif_dev->firmware->size);
871
872
873
874

	return 0;
}

875
static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info)
876
{
877
878
879
	int ret, idx;
	struct usb_host_interface *alt = &hif_dev->interface->altsetting[0];
	struct usb_endpoint_descriptor *endp;
880
881

	/* Request firmware */
Sujith's avatar
Sujith committed
882
883
	ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name,
			       &hif_dev->udev->dev);
884
885
	if (ret) {
		dev_err(&hif_dev->udev->dev,
Sujith's avatar
Sujith committed
886
			"ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name);
887
888
889
		goto err_fw_req;
	}

890
	/* Download firmware */
891
	ret = ath9k_hif_usb_download_fw(hif_dev, drv_info);
892
893
	if (ret) {
		dev_err(&hif_dev->udev->dev,
Sujith's avatar
Sujith committed
894
895
			"ath9k_htc: Firmware - %s download failed\n",
			hif_dev->fw_name);
896
897
898
		goto err_fw_download;
	}

899
900
901
902
903
904
	/* On downloading the firmware to the target, the USB descriptor of EP4
	 * is 'patched' to change the type of the endpoint to Bulk. This will
	 * bring down CPU usage during the scan period.
	 */
	for (idx = 0; idx < alt->desc.bNumEndpoints; idx++) {
		endp = &alt->endpoint[idx].desc;
905
906
		if ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
				== USB_ENDPOINT_XFER_INT) {
907
908
909
910
911
912
			endp->bmAttributes &= ~USB_ENDPOINT_XFERTYPE_MASK;
			endp->bmAttributes |= USB_ENDPOINT_XFER_BULK;
			endp->bInterval = 0;
		}
	}

913
914
915
916
917
	/* Alloc URBs */
	ret = ath9k_hif_usb_alloc_urbs(hif_dev);
	if (ret) {
		dev_err(&hif_dev->udev->dev,
			"ath9k_htc: Unable to allocate URBs\n");
918
		goto err_fw_download;
919
920
	}

921
922
	return 0;

923
err_fw_download:
924
925
926
927
928
929
930
931
932
933
934
935
936
	release_firmware(hif_dev->firmware);
err_fw_req:
	hif_dev->firmware = NULL;
	return ret;
}

static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
{
	ath9k_hif_usb_dealloc_urbs(hif_dev);
	if (hif_dev->firmware)
		release_firmware(hif_dev->firmware);
}

937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
/*
 * An exact copy of the function from zd1211rw.
 */
static int send_eject_command(struct usb_interface *interface)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_host_interface *iface_desc = &interface->altsetting[0];
	struct usb_endpoint_descriptor *endpoint;
	unsigned char *cmd;
	u8 bulk_out_ep;
	int r;

	/* Find bulk out endpoint */
	for (r = 1; r >= 0; r--) {
		endpoint = &iface_desc->endpoint[r].desc;
		if (usb_endpoint_dir_out(endpoint) &&
		    usb_endpoint_xfer_bulk(endpoint)) {
			bulk_out_ep = endpoint->bEndpointAddress;
			break;
		}
	}
	if (r == -1) {
		dev_err(&udev->dev,
			"ath9k_htc: Could not find bulk out endpoint\n");
		return -ENODEV;
	}

	cmd = kzalloc(31, GFP_KERNEL);
	if (cmd == NULL)
		return -ENODEV;

	/* USB bulk command block */
	cmd[0] = 0x55;	/* bulk command signature */
	cmd[1] = 0x53;	/* bulk command signature */
	cmd[2] = 0x42;	/* bulk command signature */
	cmd[3] = 0x43;	/* bulk command signature */
	cmd[14] = 6;	/* command length */

	cmd[15] = 0x1b;	/* SCSI command: START STOP UNIT */
	cmd[19] = 0x2;	/* eject disc */

	dev_info(&udev->dev, "Ejecting storage device...\n");
	r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, bulk_out_ep),
		cmd, 31, NULL, 2000);
	kfree(cmd);
	if (r)
		return r;

	/* At this point, the device disconnects and reconnects with the real
	 * ID numbers. */

	usb_set_intfdata(interface, NULL);
	return 0;
}

992
993
994
995
996
997
998
static int ath9k_hif_usb_probe(struct usb_interface *interface,
			       const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct hif_device_usb *hif_dev;
	int ret = 0;

999
1000
1001
	if (id->driver_info == STORAGE_DEVICE)
		return send_eject_command(interface);

1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
	hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
	if (!hif_dev) {
		ret = -ENOMEM;
		goto err_alloc;
	}

	usb_get_dev(udev);
	hif_dev->udev = udev;
	hif_dev->interface = interface;
	hif_dev->device_id = id->idProduct;
#ifdef CONFIG_PM
	udev->reset_resume = 1;
#endif
	usb_set_intfdata(interface, hif_dev);

1017
1018
1019
1020
1021
1022
1023
	hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
						 &hif_dev->udev->dev);
	if (hif_dev->htc_handle == NULL) {
		ret = -ENOMEM;
		goto err_htc_hw_alloc;
	}

Sujith's avatar
Sujith committed
1024
1025
	/* Find out which firmware to load */

1026
	if (IS_AR7010_DEVICE(id->driver_info))
1027
		hif_dev->fw_name = FIRMWARE_AR7010_1_1;
1028
	else
1029
		hif_dev->fw_name = FIRMWARE_AR9271;
Sujith's avatar
Sujith committed
1030

1031
	ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info);
1032
1033
1034
1035
1036
	if (ret) {
		ret = -EINVAL;
		goto err_hif_init_usb;
	}

1037
	ret = ath9k_htc_hw_init(hif_dev->htc_handle,
1038
				&hif_dev->udev->dev, hif_dev->device_id,
1039
				hif_dev->udev->product, id->driver_info);
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
	if (ret) {
		ret = -EINVAL;
		goto err_htc_hw_init;
	}

	dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");

	return 0;

err_htc_hw_init:
	ath9k_hif_usb_dev_deinit(hif_dev);
err_hif_init_usb:
1052
1053
	ath9k_htc_hw_free(hif_dev->htc_handle);
err_htc_hw_alloc:
1054
1055
1056
1057
1058
1059
1060
	usb_set_intfdata(interface, NULL);
	kfree(hif_dev);
	usb_put_dev(udev);
err_alloc:
	return ret;
}

Sujith's avatar
Sujith committed
1061
1062
1063
1064
1065
1066
static void ath9k_hif_usb_reboot(struct usb_device *udev)
{
	u32 reboot_cmd = 0xffffffff;
	void *buf;
	int ret;

1067
	buf = kmemdup(&reboot_cmd, 4, GFP_KERNEL);
Sujith's avatar
Sujith committed
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
	if (!buf)
		return;

	ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE),
			   buf, 4, NULL, HZ);
	if (ret)
		dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n");

	kfree(buf);
}

1079
1080
1081
static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
{
	struct usb_device *udev = interface_to_usbdev(interface);
1082
	struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1083
	bool unplugged = (udev->state == USB_STATE_NOTATTACHED) ? true : false;
1084

1085
1086
1087
1088
1089
1090
1091
	if (!hif_dev)
		return;

	ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
	ath9k_htc_hw_free(hif_dev->htc_handle);
	ath9k_hif_usb_dev_deinit(hif_dev);
	usb_set_intfdata(interface, NULL);
1092

1093
	if (!unplugged && (hif_dev->flags & HIF_USB_START))
Sujith's avatar
Sujith committed
1094
		ath9k_hif_usb_reboot(udev);
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104

	kfree(hif_dev);
	dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
	usb_put_dev(udev);
}

#ifdef CONFIG_PM
static int ath9k_hif_usb_suspend(struct usb_interface *interface,
				 pm_message_t message)
{
1105
	struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1106

1107
1108
1109
1110
1111
1112
1113
	/*
	 * The device has to be set to FULLSLEEP mode in case no
	 * interface is up.
	 */
	if (!(hif_dev->flags & HIF_USB_START))
		ath9k_htc_suspend(hif_dev->htc_handle);

1114
1115
1116
1117
1118
1119
1120
	ath9k_hif_usb_dealloc_urbs(hif_dev);

	return 0;
}

static int ath9k_hif_usb_resume(struct usb_interface *interface)
{
1121
	struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
1122
	struct htc_target *htc_handle = hif_dev->htc_handle;
1123
1124
1125
1126
1127
1128
1129
	int ret;

	ret = ath9k_hif_usb_alloc_urbs(hif_dev);
	if (ret)
		return ret;

	if (hif_dev->firmware) {
1130
		ret = ath9k_hif_usb_download_fw(hif_dev,
1131
				htc_handle->drv_priv->ah->hw_version.usbdev);
1132
1133
1134
1135
1136
1137
1138
1139
1140
		if (ret)
			goto fail_resume;
	} else {
		ath9k_hif_usb_dealloc_urbs(hif_dev);
		return -EIO;
	}

	mdelay(100);

1141
	ret = ath9k_htc_resume(htc_handle);
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176

	if (ret)
		goto fail_resume;

	return 0;

fail_resume:
	ath9k_hif_usb_dealloc_urbs(hif_dev);

	return ret;
}
#endif

static struct usb_driver ath9k_hif_usb_driver = {
	.name = "ath9k_hif_usb",
	.probe = ath9k_hif_usb_probe,
	.disconnect = ath9k_hif_usb_disconnect,
#ifdef CONFIG_PM
	.suspend = ath9k_hif_usb_suspend,
	.resume = ath9k_hif_usb_resume,
	.reset_resume = ath9k_hif_usb_resume,
#endif
	.id_table = ath9k_hif_usb_ids,
	.soft_unbind = 1,
};

int ath9k_hif_usb_init(void)
{
	return usb_register(&ath9k_hif_usb_driver);
}

void ath9k_hif_usb_exit(void)
{
	usb_deregister(&ath9k_hif_usb_driver);
}