aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2010-03-17 04:55:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-23 16:50:17 -0400
commitfb9987d0f748c983bb795a86f47522313f701a08 (patch)
treee70d809b887ba25ed1a5da018e8baae829d0b8ad
parent736b3a27b3c50c4a23717b802240435a69e8d0ff (diff)
ath9k_htc: Support for AR9271 chipset.
Features: * Station mode * IBSS mode * Monitor mode * Legacy support * HT support * TX/RX 11n Aggregation * HW encryption * LED * Suspend/Resume For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile10
-rw-r--r--drivers/net/wireless/ath/ath9k/common.c421
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c993
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.h105
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h441
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c260
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c713
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c1626
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c604
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.c463
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_hst.h246
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h26
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c319
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h126
-rw-r--r--drivers/net/wireless/ath/debug.h1
18 files changed, 6393 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index 4e7a7fd695c8..0a75be027afa 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON
3 depends on CFG80211 3 depends on CFG80211
4 ---help--- 4 ---help---
5 This will enable the support for the Atheros wireless drivers. 5 This will enable the support for the Atheros wireless drivers.
6 ath5k, ath9k and ar9170 drivers share some common code, this option 6 ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option
7 enables the common ath.ko module which shares common helpers. 7 enables the common ath.ko module which shares common helpers.
8 8
9 For more information and documentation on this module you can visit: 9 For more information and documentation on this module you can visit:
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 5774cea23a3b..35f23bdc442f 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS
32 32
33 Also required for changing debug message flags at run time. 33 Also required for changing debug message flags at run time.
34 34
35config ATH9K_HTC
36 tristate "Atheros HTC based wireless cards support"
37 depends on USB && MAC80211
38 select ATH9K_HW
39 select MAC80211_LEDS
40 select LEDS_CLASS
41 select NEW_LEDS
42 select ATH9K_COMMON
43 ---help---
44 Support for Atheros HTC based cards.
45 Chipsets supported: AR9271
46
47 For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc
48
49 The built module will be ath9k_htc.
50
51config ATH9K_HTC_DEBUGFS
52 bool "Atheros ath9k_htc debugging"
53 depends on ATH9K_HTC && DEBUG_FS
54 ---help---
55 Say Y, if you need access to ath9k_htc's statistics.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b50d5eb9ec3..97133beda269 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -28,3 +28,13 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
28 28
29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 29obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
30ath9k_common-y:= common.o 30ath9k_common-y:= common.o
31
32ath9k_htc-y += htc_hst.o \
33 hif_usb.o \
34 wmi.o \
35 htc_drv_txrx.o \
36 htc_drv_main.o \
37 htc_drv_beacon.o \
38 htc_drv_init.o
39
40obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c
index 4d775ae141db..7902d287f671 100644
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -286,6 +286,427 @@ int ath9k_cmn_padpos(__le16 frame_control)
286} 286}
287EXPORT_SYMBOL(ath9k_cmn_padpos); 287EXPORT_SYMBOL(ath9k_cmn_padpos);
288 288
289int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb)
290{
291 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
292
293 if (tx_info->control.hw_key) {
294 if (tx_info->control.hw_key->alg == ALG_WEP)
295 return ATH9K_KEY_TYPE_WEP;
296 else if (tx_info->control.hw_key->alg == ALG_TKIP)
297 return ATH9K_KEY_TYPE_TKIP;
298 else if (tx_info->control.hw_key->alg == ALG_CCMP)
299 return ATH9K_KEY_TYPE_AES;
300 }
301
302 return ATH9K_KEY_TYPE_CLEAR;
303}
304EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype);
305
306/*
307 * Calculate the RX filter to be set in the HW.
308 */
309u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
310 unsigned int rxfilter)
311{
312#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
313
314 u32 rfilt;
315
316 rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE)
317 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
318 | ATH9K_RX_FILTER_MCAST;
319
320 /* If not a STA, enable processing of Probe Requests */
321 if (ah->opmode != NL80211_IFTYPE_STATION)
322 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
323
324 /*
325 * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
326 * mode interface or when in monitor mode. AP mode does not need this
327 * since it receives all in-BSS frames anyway.
328 */
329 if (((ah->opmode != NL80211_IFTYPE_AP) &&
330 (rxfilter & FIF_PROMISC_IN_BSS)) ||
331 (ah->opmode == NL80211_IFTYPE_MONITOR))
332 rfilt |= ATH9K_RX_FILTER_PROM;
333
334 if (rxfilter & FIF_CONTROL)
335 rfilt |= ATH9K_RX_FILTER_CONTROL;
336
337 if ((ah->opmode == NL80211_IFTYPE_STATION) &&
338 !(rxfilter & FIF_BCN_PRBRESP_PROMISC))
339 rfilt |= ATH9K_RX_FILTER_MYBEACON;
340 else
341 rfilt |= ATH9K_RX_FILTER_BEACON;
342
343 if ((AR_SREV_9280_10_OR_LATER(ah) ||
344 AR_SREV_9285_10_OR_LATER(ah)) &&
345 (ah->opmode == NL80211_IFTYPE_AP) &&
346 (rxfilter & FIF_PSPOLL))
347 rfilt |= ATH9K_RX_FILTER_PSPOLL;
348
349 if (conf_is_ht(&hw->conf))
350 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
351
352 return rfilt;
353
354#undef RX_FILTER_PRESERVE
355}
356EXPORT_SYMBOL(ath9k_cmn_calcrxfilter);
357
358/*
359 * Recv initialization for opmode change.
360 */
361void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
362 unsigned int rxfilter)
363{
364 struct ath_common *common = ath9k_hw_common(ah);
365
366 u32 rfilt, mfilt[2];
367
368 /* configure rx filter */
369 rfilt = ath9k_cmn_calcrxfilter(hw, ah, rxfilter);
370 ath9k_hw_setrxfilter(ah, rfilt);
371
372 /* configure bssid mask */
373 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
374 ath_hw_setbssidmask(common);
375
376 /* configure operational mode */
377 ath9k_hw_setopmode(ah);
378
379 /* Handle any link-level address change. */
380 ath9k_hw_setmac(ah, common->macaddr);
381
382 /* calculate and install multicast filter */
383 mfilt[0] = mfilt[1] = ~0;
384 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
385}
386EXPORT_SYMBOL(ath9k_cmn_opmode_init);
387
388static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan,
389 enum nl80211_channel_type channel_type)
390{
391 u32 chanmode = 0;
392
393 switch (chan->band) {
394 case IEEE80211_BAND_2GHZ:
395 switch (channel_type) {
396 case NL80211_CHAN_NO_HT:
397 case NL80211_CHAN_HT20:
398 chanmode = CHANNEL_G_HT20;
399 break;
400 case NL80211_CHAN_HT40PLUS:
401 chanmode = CHANNEL_G_HT40PLUS;
402 break;
403 case NL80211_CHAN_HT40MINUS:
404 chanmode = CHANNEL_G_HT40MINUS;
405 break;
406 }
407 break;
408 case IEEE80211_BAND_5GHZ:
409 switch (channel_type) {
410 case NL80211_CHAN_NO_HT:
411 case NL80211_CHAN_HT20:
412 chanmode = CHANNEL_A_HT20;
413 break;
414 case NL80211_CHAN_HT40PLUS:
415 chanmode = CHANNEL_A_HT40PLUS;
416 break;
417 case NL80211_CHAN_HT40MINUS:
418 chanmode = CHANNEL_A_HT40MINUS;
419 break;
420 }
421 break;
422 default:
423 break;
424 }
425
426 return chanmode;
427}
428
429/*
430 * Update internal channel flags.
431 */
432void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
433 struct ath9k_channel *ichan)
434{
435 struct ieee80211_channel *chan = hw->conf.channel;
436 struct ieee80211_conf *conf = &hw->conf;
437
438 ichan->channel = chan->center_freq;
439 ichan->chan = chan;
440
441 if (chan->band == IEEE80211_BAND_2GHZ) {
442 ichan->chanmode = CHANNEL_G;
443 ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
444 } else {
445 ichan->chanmode = CHANNEL_A;
446 ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
447 }
448
449 if (conf_is_ht(conf))
450 ichan->chanmode = ath9k_get_extchanmode(chan,
451 conf->channel_type);
452}
453EXPORT_SYMBOL(ath9k_cmn_update_ichannel);
454
455/*
456 * Get the internal channel reference.
457 */
458struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
459 struct ath_hw *ah)
460{
461 struct ieee80211_channel *curchan = hw->conf.channel;
462 struct ath9k_channel *channel;
463 u8 chan_idx;
464
465 chan_idx = curchan->hw_value;
466 channel = &ah->channels[chan_idx];
467 ath9k_cmn_update_ichannel(hw, channel);
468
469 return channel;
470}
471EXPORT_SYMBOL(ath9k_cmn_get_curchannel);
472
473static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key,
474 struct ath9k_keyval *hk, const u8 *addr,
475 bool authenticator)
476{
477 struct ath_hw *ah = common->ah;
478 const u8 *key_rxmic;
479 const u8 *key_txmic;
480
481 key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
482 key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
483
484 if (addr == NULL) {
485 /*
486 * Group key installation - only two key cache entries are used
487 * regardless of splitmic capability since group key is only
488 * used either for TX or RX.
489 */
490 if (authenticator) {
491 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
492 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
493 } else {
494 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
495 memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
496 }
497 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
498 }
499 if (!common->splitmic) {
500 /* TX and RX keys share the same key cache entry. */
501 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
502 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
503 return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr);
504 }
505
506 /* Separate key cache entries for TX and RX */
507
508 /* TX key goes at first index, RX key at +32. */
509 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
510 if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) {
511 /* TX MIC entry failed. No need to proceed further */
512 ath_print(common, ATH_DBG_FATAL,
513 "Setting TX MIC Key Failed\n");
514 return 0;
515 }
516
517 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
518 /* XXX delete tx key on failure? */
519 return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr);
520}
521
522static int ath_reserve_key_cache_slot_tkip(struct ath_common *common)
523{
524 int i;
525
526 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
527 if (test_bit(i, common->keymap) ||
528 test_bit(i + 64, common->keymap))
529 continue; /* At least one part of TKIP key allocated */
530 if (common->splitmic &&
531 (test_bit(i + 32, common->keymap) ||
532 test_bit(i + 64 + 32, common->keymap)))
533 continue; /* At least one part of TKIP key allocated */
534
535 /* Found a free slot for a TKIP key */
536 return i;
537 }
538 return -1;
539}
540
541static int ath_reserve_key_cache_slot(struct ath_common *common)
542{
543 int i;
544
545 /* First, try to find slots that would not be available for TKIP. */
546 if (common->splitmic) {
547 for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) {
548 if (!test_bit(i, common->keymap) &&
549 (test_bit(i + 32, common->keymap) ||
550 test_bit(i + 64, common->keymap) ||
551 test_bit(i + 64 + 32, common->keymap)))
552 return i;
553 if (!test_bit(i + 32, common->keymap) &&
554 (test_bit(i, common->keymap) ||
555 test_bit(i + 64, common->keymap) ||
556 test_bit(i + 64 + 32, common->keymap)))
557 return i + 32;
558 if (!test_bit(i + 64, common->keymap) &&
559 (test_bit(i , common->keymap) ||
560 test_bit(i + 32, common->keymap) ||
561 test_bit(i + 64 + 32, common->keymap)))
562 return i + 64;
563 if (!test_bit(i + 64 + 32, common->keymap) &&
564 (test_bit(i, common->keymap) ||
565 test_bit(i + 32, common->keymap) ||
566 test_bit(i + 64, common->keymap)))
567 return i + 64 + 32;
568 }
569 } else {
570 for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) {
571 if (!test_bit(i, common->keymap) &&
572 test_bit(i + 64, common->keymap))
573 return i;
574 if (test_bit(i, common->keymap) &&
575 !test_bit(i + 64, common->keymap))
576 return i + 64;
577 }
578 }
579
580 /* No partially used TKIP slots, pick any available slot */
581 for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) {
582 /* Do not allow slots that could be needed for TKIP group keys
583 * to be used. This limitation could be removed if we know that
584 * TKIP will not be used. */
585 if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
586 continue;
587 if (common->splitmic) {
588 if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
589 continue;
590 if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
591 continue;
592 }
593
594 if (!test_bit(i, common->keymap))
595 return i; /* Found a free slot for a key */
596 }
597
598 /* No free slot found */
599 return -1;
600}
601
602/*
603 * Configure encryption in the HW.
604 */
605int ath9k_cmn_key_config(struct ath_common *common,
606 struct ieee80211_vif *vif,
607 struct ieee80211_sta *sta,
608 struct ieee80211_key_conf *key)
609{
610 struct ath_hw *ah = common->ah;
611 struct ath9k_keyval hk;
612 const u8 *mac = NULL;
613 int ret = 0;
614 int idx;
615
616 memset(&hk, 0, sizeof(hk));
617
618 switch (key->alg) {
619 case ALG_WEP:
620 hk.kv_type = ATH9K_CIPHER_WEP;
621 break;
622 case ALG_TKIP:
623 hk.kv_type = ATH9K_CIPHER_TKIP;
624 break;
625 case ALG_CCMP:
626 hk.kv_type = ATH9K_CIPHER_AES_CCM;
627 break;
628 default:
629 return -EOPNOTSUPP;
630 }
631
632 hk.kv_len = key->keylen;
633 memcpy(hk.kv_val, key->key, key->keylen);
634
635 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
636 /* For now, use the default keys for broadcast keys. This may
637 * need to change with virtual interfaces. */
638 idx = key->keyidx;
639 } else if (key->keyidx) {
640 if (WARN_ON(!sta))
641 return -EOPNOTSUPP;
642 mac = sta->addr;
643
644 if (vif->type != NL80211_IFTYPE_AP) {
645 /* Only keyidx 0 should be used with unicast key, but
646 * allow this for client mode for now. */
647 idx = key->keyidx;
648 } else
649 return -EIO;
650 } else {
651 if (WARN_ON(!sta))
652 return -EOPNOTSUPP;
653 mac = sta->addr;
654
655 if (key->alg == ALG_TKIP)
656 idx = ath_reserve_key_cache_slot_tkip(common);
657 else
658 idx = ath_reserve_key_cache_slot(common);
659 if (idx < 0)
660 return -ENOSPC; /* no free key cache entries */
661 }
662
663 if (key->alg == ALG_TKIP)
664 ret = ath_setkey_tkip(common, idx, key->key, &hk, mac,
665 vif->type == NL80211_IFTYPE_AP);
666 else
667 ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac);
668
669 if (!ret)
670 return -EIO;
671
672 set_bit(idx, common->keymap);
673 if (key->alg == ALG_TKIP) {
674 set_bit(idx + 64, common->keymap);
675 if (common->splitmic) {
676 set_bit(idx + 32, common->keymap);
677 set_bit(idx + 64 + 32, common->keymap);
678 }
679 }
680
681 return idx;
682}
683EXPORT_SYMBOL(ath9k_cmn_key_config);
684
685/*
686 * Delete Key.
687 */
688void ath9k_cmn_key_delete(struct ath_common *common,
689 struct ieee80211_key_conf *key)
690{
691 struct ath_hw *ah = common->ah;
692
693 ath9k_hw_keyreset(ah, key->hw_key_idx);
694 if (key->hw_key_idx < IEEE80211_WEP_NKID)
695 return;
696
697 clear_bit(key->hw_key_idx, common->keymap);
698 if (key->alg != ALG_TKIP)
699 return;
700
701 clear_bit(key->hw_key_idx + 64, common->keymap);
702 if (common->splitmic) {
703 ath9k_hw_keyreset(ah, key->hw_key_idx + 32);
704 clear_bit(key->hw_key_idx + 32, common->keymap);
705 clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
706 }
707}
708EXPORT_SYMBOL(ath9k_cmn_key_delete);
709
289static int __init ath9k_cmn_init(void) 710static int __init ath9k_cmn_init(void)
290{ 711{
291 return 0; 712 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 042999c2fe9c..bbcc57f6eba3 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,6 +23,8 @@
23 23
24/* Common header for Atheros 802.11n base driver cores */ 24/* Common header for Atheros 802.11n base driver cores */
25 25
26#define IEEE80211_WEP_NKID 4
27
26#define WME_NUM_TID 16 28#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 29#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 30#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -125,3 +127,18 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common,
125 bool decrypt_error); 127 bool decrypt_error);
126 128
127int ath9k_cmn_padpos(__le16 frame_control); 129int ath9k_cmn_padpos(__le16 frame_control);
130int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
131u32 ath9k_cmn_calcrxfilter(struct ieee80211_hw *hw, struct ath_hw *ah,
132 unsigned int rxfilter);
133void ath9k_cmn_opmode_init(struct ieee80211_hw *hw, struct ath_hw *ah,
134 unsigned int rxfilter);
135void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw,
136 struct ath9k_channel *ichan);
137struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw,
138 struct ath_hw *ah);
139int ath9k_cmn_key_config(struct ath_common *common,
140 struct ieee80211_vif *vif,
141 struct ieee80211_sta *sta,
142 struct ieee80211_key_conf *key);
143void ath9k_cmn_key_delete(struct ath_common *common,
144 struct ieee80211_key_conf *key);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
new file mode 100644
index 000000000000..fc4f6e8c9ef3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -0,0 +1,993 @@
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"),
24 { },
25};
26
27MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids);
28
29static int __hif_usb_tx(struct hif_device_usb *hif_dev);
30
31static void hif_usb_regout_cb(struct urb *urb)
32{
33 struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
34 struct hif_device_usb *hif_dev = cmd->hif_dev;
35
36 if (!hif_dev) {
37 usb_free_urb(urb);
38 if (cmd) {
39 if (cmd->skb)
40 dev_kfree_skb_any(cmd->skb);
41 kfree(cmd);
42 }
43 return;
44 }
45
46 switch (urb->status) {
47 case 0:
48 break;
49 case -ENOENT:
50 case -ECONNRESET:
51 break;
52 case -ENODEV:
53 case -ESHUTDOWN:
54 return;
55 default:
56 break;
57 }
58
59 if (cmd) {
60 ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
61 cmd->skb, 1);
62 kfree(cmd);
63 usb_free_urb(urb);
64 }
65}
66
67static int hif_usb_send_regout(struct hif_device_usb *hif_dev,
68 struct sk_buff *skb)
69{
70 struct urb *urb;
71 struct cmd_buf *cmd;
72 int ret = 0;
73
74 urb = usb_alloc_urb(0, GFP_KERNEL);
75 if (urb == NULL)
76 return -ENOMEM;
77
78 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
79 if (cmd == NULL) {
80 usb_free_urb(urb);
81 return -ENOMEM;
82 }
83
84 cmd->skb = skb;
85 cmd->hif_dev = hif_dev;
86
87 usb_fill_int_urb(urb, hif_dev->udev,
88 usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE),
89 skb->data, skb->len,
90 hif_usb_regout_cb, cmd, 1);
91
92 ret = usb_submit_urb(urb, GFP_KERNEL);
93 if (ret) {
94 usb_free_urb(urb);
95 kfree(cmd);
96 }
97
98 return ret;
99}
100
101static void hif_usb_tx_cb(struct urb *urb)
102{
103 struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
104 struct hif_device_usb *hif_dev = tx_buf->hif_dev;
105 struct sk_buff *skb;
106 bool drop, flush;
107
108 if (!hif_dev)
109 return;
110
111 switch (urb->status) {
112 case 0:
113 break;
114 case -ENOENT:
115 case -ECONNRESET:
116 break;
117 case -ENODEV:
118 case -ESHUTDOWN:
119 return;
120 default:
121 break;
122 }
123
124 if (tx_buf) {
125 spin_lock(&hif_dev->tx.tx_lock);
126 drop = !!(hif_dev->tx.flags & HIF_USB_TX_STOP);
127 flush = !!(hif_dev->tx.flags & HIF_USB_TX_FLUSH);
128 spin_unlock(&hif_dev->tx.tx_lock);
129
130 while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
131 if (!drop && !flush) {
132 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
133 skb, 1);
134 TX_STAT_INC(skb_completed);
135 } else {
136 dev_kfree_skb_any(skb);
137 }
138 }
139
140 if (flush)
141 return;
142
143 tx_buf->len = tx_buf->offset = 0;
144 __skb_queue_head_init(&tx_buf->skb_queue);
145
146 spin_lock(&hif_dev->tx.tx_lock);
147 list_del(&tx_buf->list);
148 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
149 hif_dev->tx.tx_buf_cnt++;
150 if (!drop)
151 __hif_usb_tx(hif_dev); /* Check for pending SKBs */
152 TX_STAT_INC(buf_completed);
153 spin_unlock(&hif_dev->tx.tx_lock);
154 }
155}
156
157/* TX lock has to be taken */
158static int __hif_usb_tx(struct hif_device_usb *hif_dev)
159{
160 struct tx_buf *tx_buf = NULL;
161 struct sk_buff *nskb = NULL;
162 int ret = 0, i;
163 u16 *hdr, tx_skb_cnt = 0;
164 u8 *buf;
165
166 if (hif_dev->tx.tx_skb_cnt == 0)
167 return 0;
168
169 /* Check if a free TX buffer is available */
170 if (list_empty(&hif_dev->tx.tx_buf))
171 return 0;
172
173 tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list);
174 list_del(&tx_buf->list);
175 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_pending);
176 hif_dev->tx.tx_buf_cnt--;
177
178 tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM);
179
180 for (i = 0; i < tx_skb_cnt; i++) {
181 nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue);
182
183 /* Should never be NULL */
184 BUG_ON(!nskb);
185
186 hif_dev->tx.tx_skb_cnt--;
187
188 buf = tx_buf->buf;
189 buf += tx_buf->offset;
190 hdr = (u16 *)buf;
191 *hdr++ = nskb->len;
192 *hdr++ = ATH_USB_TX_STREAM_MODE_TAG;
193 buf += 4;
194 memcpy(buf, nskb->data, nskb->len);
195 tx_buf->len = nskb->len + 4;
196
197 if (i < (tx_skb_cnt - 1))
198 tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4;
199
200 if (i == (tx_skb_cnt - 1))
201 tx_buf->len += tx_buf->offset;
202
203 __skb_queue_tail(&tx_buf->skb_queue, nskb);
204 TX_STAT_INC(skb_queued);
205 }
206
207 usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev,
208 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
209 tx_buf->buf, tx_buf->len,
210 hif_usb_tx_cb, tx_buf);
211
212 ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
213 if (ret) {
214 tx_buf->len = tx_buf->offset = 0;
215 __skb_queue_purge(&tx_buf->skb_queue);
216 __skb_queue_head_init(&tx_buf->skb_queue);
217 list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
218 hif_dev->tx.tx_buf_cnt++;
219 }
220
221 if (!ret)
222 TX_STAT_INC(buf_queued);
223
224 return ret;
225}
226
227static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
228 struct ath9k_htc_tx_ctl *tx_ctl)
229{
230 unsigned long flags;
231
232 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
233
234 if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
235 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
236 return -ENODEV;
237 }
238
239 /* Check if the max queue count has been reached */
240 if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) {
241 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
242 return -ENOMEM;
243 }
244
245 __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
246 hif_dev->tx.tx_skb_cnt++;
247
248 /* Send normal frames immediately */
249 if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
250 __hif_usb_tx(hif_dev);
251
252 /* Check if AMPDUs have to be sent immediately */
253 if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
254 (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
255 (hif_dev->tx.tx_skb_cnt < 2)) {
256 __hif_usb_tx(hif_dev);
257 }
258
259 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
260
261 return 0;
262}
263
264static void hif_usb_start(void *hif_handle, u8 pipe_id)
265{
266 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
267 unsigned long flags;
268
269 hif_dev->flags |= HIF_USB_START;
270
271 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
272 hif_dev->tx.flags &= ~HIF_USB_TX_STOP;
273 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
274}
275
276static void hif_usb_stop(void *hif_handle, u8 pipe_id)
277{
278 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
279 unsigned long flags;
280
281 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
282 __skb_queue_purge(&hif_dev->tx.tx_skb_queue);
283 hif_dev->tx.tx_skb_cnt = 0;
284 hif_dev->tx.flags |= HIF_USB_TX_STOP;
285 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
286}
287
288static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
289 struct ath9k_htc_tx_ctl *tx_ctl)
290{
291 struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
292 int ret = 0;
293
294 switch (pipe_id) {
295 case USB_WLAN_TX_PIPE:
296 ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
297 break;
298 case USB_REG_OUT_PIPE:
299 ret = hif_usb_send_regout(hif_dev, skb);
300 break;
301 default:
302 ret = -EINVAL;
303 break;
304 }
305
306 return ret;
307}
308
309static struct ath9k_htc_hif hif_usb = {
310 .transport = ATH9K_HIF_USB,
311 .name = "ath9k_hif_usb",
312
313 .control_ul_pipe = USB_REG_OUT_PIPE,
314 .control_dl_pipe = USB_REG_IN_PIPE,
315
316 .start = hif_usb_start,
317 .stop = hif_usb_stop,
318 .send = hif_usb_send,
319};
320
321static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
322 struct sk_buff *skb)
323{
324 struct sk_buff *nskb, *skb_pool[8];
325 int index = 0, i = 0, chk_idx, len = skb->len;
326 int rx_remain_len = 0, rx_pkt_len = 0;
327 u16 pkt_len, pkt_tag, pool_index = 0;
328 u8 *ptr;
329
330 rx_remain_len = hif_dev->rx_remain_len;
331 rx_pkt_len = hif_dev->rx_transfer_len;
332
333 if (rx_remain_len != 0) {
334 struct sk_buff *remain_skb = hif_dev->remain_skb;
335
336 if (remain_skb) {
337 ptr = (u8 *) remain_skb->data;
338
339 index = rx_remain_len;
340 rx_remain_len -= hif_dev->rx_pad_len;
341 ptr += rx_pkt_len;
342
343 memcpy(ptr, skb->data, rx_remain_len);
344
345 rx_pkt_len += rx_remain_len;
346 hif_dev->rx_remain_len = 0;
347 skb_put(remain_skb, rx_pkt_len);
348
349 skb_pool[pool_index++] = remain_skb;
350
351 } else {
352 index = rx_remain_len;
353 }
354 }
355
356 while (index < len) {
357 ptr = (u8 *) skb->data;
358
359 pkt_len = ptr[index] + (ptr[index+1] << 8);
360 pkt_tag = ptr[index+2] + (ptr[index+3] << 8);
361
362 if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) {
363 u16 pad_len;
364
365 pad_len = 4 - (pkt_len & 0x3);
366 if (pad_len == 4)
367 pad_len = 0;
368
369 chk_idx = index;
370 index = index + 4 + pkt_len + pad_len;
371
372 if (index > MAX_RX_BUF_SIZE) {
373 hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
374 hif_dev->rx_transfer_len =
375 MAX_RX_BUF_SIZE - chk_idx - 4;
376 hif_dev->rx_pad_len = pad_len;
377
378 nskb = __dev_alloc_skb(pkt_len + 32,
379 GFP_ATOMIC);
380 if (!nskb) {
381 dev_err(&hif_dev->udev->dev,
382 "ath9k_htc: RX memory allocation"
383 " error\n");
384 goto err;
385 }
386 skb_reserve(nskb, 32);
387 RX_STAT_INC(skb_allocated);
388
389 memcpy(nskb->data, &(skb->data[chk_idx+4]),
390 hif_dev->rx_transfer_len);
391
392 /* Record the buffer pointer */
393 hif_dev->remain_skb = nskb;
394 } else {
395 nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
396 if (!nskb) {
397 dev_err(&hif_dev->udev->dev,
398 "ath9k_htc: RX memory allocation"
399 " error\n");
400 goto err;
401 }
402 skb_reserve(nskb, 32);
403 RX_STAT_INC(skb_allocated);
404
405 memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len);
406 skb_put(nskb, pkt_len);
407 skb_pool[pool_index++] = nskb;
408 }
409 } else {
410 RX_STAT_INC(skb_dropped);
411 dev_kfree_skb_any(skb);
412 return;
413 }
414 }
415
416err:
417 dev_kfree_skb_any(skb);
418
419 for (i = 0; i < pool_index; i++) {
420 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
421 skb_pool[i]->len, USB_WLAN_RX_PIPE);
422 RX_STAT_INC(skb_completed);
423 }
424}
425
426static void ath9k_hif_usb_rx_cb(struct urb *urb)
427{
428 struct sk_buff *skb = (struct sk_buff *) urb->context;
429 struct sk_buff *nskb;
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
434 if (!hif_dev)
435 goto free;
436
437 switch (urb->status) {
438 case 0:
439 break;
440 case -ENOENT:
441 case -ECONNRESET:
442 case -ENODEV:
443 case -ESHUTDOWN:
444 goto free;
445 default:
446 goto resubmit;
447 }
448
449 if (likely(urb->actual_length != 0)) {
450 skb_put(skb, urb->actual_length);
451
452 nskb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_ATOMIC);
453 if (!nskb)
454 goto resubmit;
455
456 usb_fill_bulk_urb(urb, hif_dev->udev,
457 usb_rcvbulkpipe(hif_dev->udev,
458 USB_WLAN_RX_PIPE),
459 nskb->data, MAX_RX_BUF_SIZE,
460 ath9k_hif_usb_rx_cb, nskb);
461
462 ret = usb_submit_urb(urb, GFP_ATOMIC);
463 if (ret) {
464 dev_kfree_skb_any(nskb);
465 goto free;
466 }
467
468 ath9k_hif_usb_rx_stream(hif_dev, skb);
469 return;
470 }
471
472resubmit:
473 skb_reset_tail_pointer(skb);
474 skb_trim(skb, 0);
475
476 ret = usb_submit_urb(urb, GFP_ATOMIC);
477 if (ret)
478 goto free;
479
480 return;
481free:
482 dev_kfree_skb_any(skb);
483}
484
485static void ath9k_hif_usb_reg_in_cb(struct urb *urb)
486{
487 struct sk_buff *skb = (struct sk_buff *) urb->context;
488 struct sk_buff *nskb;
489 struct hif_device_usb *hif_dev = (struct hif_device_usb *)
490 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
491 int ret;
492
493 if (!hif_dev)
494 goto free;
495
496 switch (urb->status) {
497 case 0:
498 break;
499 case -ENOENT:
500 case -ECONNRESET:
501 case -ENODEV:
502 case -ESHUTDOWN:
503 goto free;
504 default:
505 goto resubmit;
506 }
507
508 if (likely(urb->actual_length != 0)) {
509 skb_put(skb, urb->actual_length);
510
511 nskb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC);
512 if (!nskb)
513 goto resubmit;
514
515 usb_fill_int_urb(urb, hif_dev->udev,
516 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
517 nskb->data, MAX_REG_IN_BUF_SIZE,
518 ath9k_hif_usb_reg_in_cb, nskb, 1);
519
520 ret = usb_submit_urb(urb, GFP_ATOMIC);
521 if (ret) {
522 dev_kfree_skb_any(nskb);
523 goto free;
524 }
525
526 ath9k_htc_rx_msg(hif_dev->htc_handle, skb,
527 skb->len, USB_REG_IN_PIPE);
528
529 return;
530 }
531
532resubmit:
533 skb_reset_tail_pointer(skb);
534 skb_trim(skb, 0);
535
536 ret = usb_submit_urb(urb, GFP_ATOMIC);
537 if (ret)
538 goto free;
539
540 return;
541free:
542 dev_kfree_skb_any(skb);
543}
544
545static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
546{
547 unsigned long flags;
548 struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
549
550 list_for_each_entry_safe(tx_buf, tx_buf_tmp, &hif_dev->tx.tx_buf, list) {
551 list_del(&tx_buf->list);
552 usb_free_urb(tx_buf->urb);
553 kfree(tx_buf->buf);
554 kfree(tx_buf);
555 }
556
557 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
558 hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
559 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
560
561 list_for_each_entry_safe(tx_buf, tx_buf_tmp,
562 &hif_dev->tx.tx_pending, list) {
563 usb_kill_urb(tx_buf->urb);
564 list_del(&tx_buf->list);
565 usb_free_urb(tx_buf->urb);
566 kfree(tx_buf->buf);
567 kfree(tx_buf);
568 }
569
570 spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
571 hif_dev->tx.flags &= ~HIF_USB_TX_FLUSH;
572 spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
573}
574
575static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
576{
577 struct tx_buf *tx_buf;
578 int i;
579
580 INIT_LIST_HEAD(&hif_dev->tx.tx_buf);
581 INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
582 spin_lock_init(&hif_dev->tx.tx_lock);
583 __skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
584
585 for (i = 0; i < MAX_TX_URB_NUM; i++) {
586 tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
587 if (!tx_buf)
588 goto err;
589
590 tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL);
591 if (!tx_buf->buf)
592 goto err;
593
594 tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL);
595 if (!tx_buf->urb)
596 goto err;
597
598 tx_buf->hif_dev = hif_dev;
599 __skb_queue_head_init(&tx_buf->skb_queue);
600
601 list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
602 }
603
604 hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM;
605
606 return 0;
607err:
608 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
609 return -ENOMEM;
610}
611
612static void ath9k_hif_usb_dealloc_rx_skbs(struct hif_device_usb *hif_dev)
613{
614 int i;
615
616 for (i = 0; i < MAX_RX_URB_NUM; i++) {
617 if (hif_dev->wlan_rx_data_urb[i]) {
618 if (hif_dev->wlan_rx_data_urb[i]->transfer_buffer)
619 dev_kfree_skb_any((void *)
620 hif_dev->wlan_rx_data_urb[i]->context);
621 }
622 }
623}
624
625static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev)
626{
627 int i;
628
629 for (i = 0; i < MAX_RX_URB_NUM; i++) {
630 if (hif_dev->wlan_rx_data_urb[i]) {
631 usb_kill_urb(hif_dev->wlan_rx_data_urb[i]);
632 usb_free_urb(hif_dev->wlan_rx_data_urb[i]);
633 hif_dev->wlan_rx_data_urb[i] = NULL;
634 }
635 }
636}
637
638static int ath9k_hif_usb_prep_rx_urb(struct hif_device_usb *hif_dev,
639 struct urb *urb)
640{
641 struct sk_buff *skb;
642
643 skb = __dev_alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL);
644 if (!skb)
645 return -ENOMEM;
646
647 usb_fill_bulk_urb(urb, hif_dev->udev,
648 usb_rcvbulkpipe(hif_dev->udev, USB_WLAN_RX_PIPE),
649 skb->data, MAX_RX_BUF_SIZE,
650 ath9k_hif_usb_rx_cb, skb);
651 return 0;
652}
653
654static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev)
655{
656 int i, ret;
657
658 for (i = 0; i < MAX_RX_URB_NUM; i++) {
659
660 /* Allocate URB */
661 hif_dev->wlan_rx_data_urb[i] = usb_alloc_urb(0, GFP_KERNEL);
662 if (hif_dev->wlan_rx_data_urb[i] == NULL) {
663 ret = -ENOMEM;
664 goto err_rx_urb;
665 }
666
667 /* Allocate buffer */
668 ret = ath9k_hif_usb_prep_rx_urb(hif_dev,
669 hif_dev->wlan_rx_data_urb[i]);
670 if (ret)
671 goto err_rx_urb;
672
673 /* Submit URB */
674 ret = usb_submit_urb(hif_dev->wlan_rx_data_urb[i], GFP_KERNEL);
675 if (ret)
676 goto err_rx_urb;
677
678 }
679
680 return 0;
681
682err_rx_urb:
683 ath9k_hif_usb_dealloc_rx_skbs(hif_dev);
684 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
685 return ret;
686}
687
688static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
689{
690 if (hif_dev->reg_in_urb) {
691 usb_kill_urb(hif_dev->reg_in_urb);
692 usb_free_urb(hif_dev->reg_in_urb);
693 hif_dev->reg_in_urb = NULL;
694 }
695}
696
697static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
698{
699 struct sk_buff *skb;
700
701 hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
702 if (hif_dev->reg_in_urb == NULL)
703 return -ENOMEM;
704
705 skb = __dev_alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
706 if (!skb)
707 goto err;
708
709 usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev,
710 usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE),
711 skb->data, MAX_REG_IN_BUF_SIZE,
712 ath9k_hif_usb_reg_in_cb, skb, 1);
713
714 if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
715 goto err_skb;
716
717 return 0;
718
719err_skb:
720 dev_kfree_skb_any(skb);
721err:
722 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
723 return -ENOMEM;
724}
725
726static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
727{
728 /* TX */
729 if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0)
730 goto err;
731
732 /* RX */
733 if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
734 goto err;
735
736 /* Register Read/Write */
737 if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
738 goto err;
739
740 return 0;
741err:
742 return -ENOMEM;
743}
744
745static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
746{
747 int transfer, err;
748 const void *data = hif_dev->firmware->data;
749 size_t len = hif_dev->firmware->size;
750 u32 addr = AR9271_FIRMWARE;
751 u8 *buf = kzalloc(4096, GFP_KERNEL);
752
753 if (!buf)
754 return -ENOMEM;
755
756 while (len) {
757 transfer = min_t(int, len, 4096);
758 memcpy(buf, data, transfer);
759
760 err = usb_control_msg(hif_dev->udev,
761 usb_sndctrlpipe(hif_dev->udev, 0),
762 FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT,
763 addr >> 8, 0, buf, transfer, HZ);
764 if (err < 0) {
765 kfree(buf);
766 return err;
767 }
768
769 len -= transfer;
770 data += transfer;
771 addr += transfer;
772 }
773 kfree(buf);
774
775 /*
776 * Issue FW download complete command to firmware.
777 */
778 err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0),
779 FIRMWARE_DOWNLOAD_COMP,
780 0x40 | USB_DIR_OUT,
781 AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ);
782 if (err)
783 return -EIO;
784
785 dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
786 "ar9271.fw", (unsigned long) hif_dev->firmware->size);
787
788 return 0;
789}
790
791static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
792 const char *fw_name)
793{
794 int ret;
795
796 /* Request firmware */
797 ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev);
798 if (ret) {
799 dev_err(&hif_dev->udev->dev,
800 "ath9k_htc: Firmware - %s not found\n", fw_name);
801 goto err_fw_req;
802 }
803
804 /* Download firmware */
805 ret = ath9k_hif_usb_download_fw(hif_dev);
806 if (ret) {
807 dev_err(&hif_dev->udev->dev,
808 "ath9k_htc: Firmware - %s download failed\n", fw_name);
809 goto err_fw_download;
810 }
811
812 /* Alloc URBs */
813 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
814 if (ret) {
815 dev_err(&hif_dev->udev->dev,
816 "ath9k_htc: Unable to allocate URBs\n");
817 goto err_urb;
818 }
819
820 return 0;
821
822err_urb:
823 /* Nothing */
824err_fw_download:
825 release_firmware(hif_dev->firmware);
826err_fw_req:
827 hif_dev->firmware = NULL;
828 return ret;
829}
830
831static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
832{
833 ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
834 ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
835 ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
836}
837
838static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
839{
840 ath9k_hif_usb_dealloc_urbs(hif_dev);
841 if (hif_dev->firmware)
842 release_firmware(hif_dev->firmware);
843}
844
845static int ath9k_hif_usb_probe(struct usb_interface *interface,
846 const struct usb_device_id *id)
847{
848 struct usb_device *udev = interface_to_usbdev(interface);
849 struct hif_device_usb *hif_dev;
850 const char *fw_name = (const char *) id->driver_info;
851 int ret = 0;
852
853 hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL);
854 if (!hif_dev) {
855 ret = -ENOMEM;
856 goto err_alloc;
857 }
858
859 usb_get_dev(udev);
860 hif_dev->udev = udev;
861 hif_dev->interface = interface;
862 hif_dev->device_id = id->idProduct;
863#ifdef CONFIG_PM
864 udev->reset_resume = 1;
865#endif
866 usb_set_intfdata(interface, hif_dev);
867
868 ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
869 if (ret) {
870 ret = -EINVAL;
871 goto err_hif_init_usb;
872 }
873
874 hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
875 if (hif_dev->htc_handle == NULL) {
876 ret = -ENOMEM;
877 goto err_htc_hw_alloc;
878 }
879
880 ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
881 &hif_dev->udev->dev, hif_dev->device_id,
882 ATH9K_HIF_USB);
883 if (ret) {
884 ret = -EINVAL;
885 goto err_htc_hw_init;
886 }
887
888 dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n");
889
890 return 0;
891
892err_htc_hw_init:
893 ath9k_htc_hw_free(hif_dev->htc_handle);
894err_htc_hw_alloc:
895 ath9k_hif_usb_dev_deinit(hif_dev);
896err_hif_init_usb:
897 usb_set_intfdata(interface, NULL);
898 kfree(hif_dev);
899 usb_put_dev(udev);
900err_alloc:
901 return ret;
902}
903
904static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
905{
906 struct usb_device *udev = interface_to_usbdev(interface);
907 struct hif_device_usb *hif_dev =
908 (struct hif_device_usb *) usb_get_intfdata(interface);
909
910 if (hif_dev) {
911 ath9k_htc_hw_deinit(hif_dev->htc_handle, true);
912 ath9k_htc_hw_free(hif_dev->htc_handle);
913 ath9k_hif_usb_dev_deinit(hif_dev);
914 usb_set_intfdata(interface, NULL);
915 }
916
917 if (hif_dev->flags & HIF_USB_START)
918 usb_reset_device(udev);
919
920 kfree(hif_dev);
921 dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n");
922 usb_put_dev(udev);
923}
924
925#ifdef CONFIG_PM
926static int ath9k_hif_usb_suspend(struct usb_interface *interface,
927 pm_message_t message)
928{
929 struct hif_device_usb *hif_dev =
930 (struct hif_device_usb *) usb_get_intfdata(interface);
931
932 ath9k_hif_usb_dealloc_urbs(hif_dev);
933
934 return 0;
935}
936
937static int ath9k_hif_usb_resume(struct usb_interface *interface)
938{
939 struct hif_device_usb *hif_dev =
940 (struct hif_device_usb *) usb_get_intfdata(interface);
941 int ret;
942
943 ret = ath9k_hif_usb_alloc_urbs(hif_dev);
944 if (ret)
945 return ret;
946
947 if (hif_dev->firmware) {
948 ret = ath9k_hif_usb_download_fw(hif_dev);
949 if (ret)
950 goto fail_resume;
951 } else {
952 ath9k_hif_usb_dealloc_urbs(hif_dev);
953 return -EIO;
954 }
955
956 mdelay(100);
957
958 ret = ath9k_htc_resume(hif_dev->htc_handle);
959
960 if (ret)
961 goto fail_resume;
962
963 return 0;
964
965fail_resume:
966 ath9k_hif_usb_dealloc_urbs(hif_dev);
967
968 return ret;
969}
970#endif
971
972static struct usb_driver ath9k_hif_usb_driver = {
973 .name = "ath9k_hif_usb",
974 .probe = ath9k_hif_usb_probe,
975 .disconnect = ath9k_hif_usb_disconnect,
976#ifdef CONFIG_PM
977 .suspend = ath9k_hif_usb_suspend,
978 .resume = ath9k_hif_usb_resume,
979 .reset_resume = ath9k_hif_usb_resume,
980#endif
981 .id_table = ath9k_hif_usb_ids,
982 .soft_unbind = 1,
983};
984
985int ath9k_hif_usb_init(void)
986{
987 return usb_register(&ath9k_hif_usb_driver);
988}
989
990void ath9k_hif_usb_exit(void)
991{
992 usb_deregister(&ath9k_hif_usb_driver);
993}
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
new file mode 100644
index 000000000000..7cc3762a6789
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -0,0 +1,105 @@
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#ifndef HTC_USB_H
18#define HTC_USB_H
19
20#define AR9271_FIRMWARE 0x501000
21#define AR9271_FIRMWARE_TEXT 0x903000
22
23#define FIRMWARE_DOWNLOAD 0x30
24#define FIRMWARE_DOWNLOAD_COMP 0x31
25
26#define ATH_USB_RX_STREAM_MODE_TAG 0x4e00
27#define ATH_USB_TX_STREAM_MODE_TAG 0x697e
28
29/* FIXME: Verify these numbers (with Windows) */
30#define MAX_TX_URB_NUM 8
31#define MAX_TX_BUF_NUM 1024
32#define MAX_TX_BUF_SIZE 32768
33#define MAX_TX_AGGR_NUM 20
34
35#define MAX_RX_URB_NUM 8
36#define MAX_RX_BUF_SIZE 16384
37
38#define MAX_REG_OUT_URB_NUM 1
39#define MAX_REG_OUT_BUF_NUM 8
40
41#define MAX_REG_IN_BUF_SIZE 64
42
43/* USB Endpoint definition */
44#define USB_WLAN_TX_PIPE 1
45#define USB_WLAN_RX_PIPE 2
46#define USB_REG_IN_PIPE 3
47#define USB_REG_OUT_PIPE 4
48
49#define HIF_USB_MAX_RXPIPES 2
50#define HIF_USB_MAX_TXPIPES 4
51
52struct tx_buf {
53 u8 *buf;
54 u16 len;
55 u16 offset;
56 struct urb *urb;
57 struct sk_buff_head skb_queue;
58 struct hif_device_usb *hif_dev;
59 struct list_head list;
60};
61
62#define HIF_USB_TX_STOP BIT(0)
63#define HIF_USB_TX_FLUSH BIT(1)
64
65struct hif_usb_tx {
66 u8 flags;
67 u8 tx_buf_cnt;
68 u16 tx_skb_cnt;
69 struct sk_buff_head tx_skb_queue;
70 struct list_head tx_buf;
71 struct list_head tx_pending;
72 spinlock_t tx_lock;
73};
74
75struct cmd_buf {
76 struct sk_buff *skb;
77 struct hif_device_usb *hif_dev;
78};
79
80#define HIF_USB_START BIT(0)
81
82struct hif_device_usb {
83 u16 device_id;
84 struct usb_device *udev;
85 struct usb_interface *interface;
86 const struct firmware *firmware;
87 struct htc_target *htc_handle;
88 u8 flags;
89
90 struct hif_usb_tx tx;
91
92 struct urb *wlan_rx_data_urb[MAX_RX_URB_NUM];
93 struct urb *reg_in_urb;
94
95 struct sk_buff *remain_skb;
96 int rx_remain_len;
97 int rx_pkt_len;
98 int rx_transfer_len;
99 int rx_pad_len;
100};
101
102int ath9k_hif_usb_init(void);
103void ath9k_hif_usb_exit(void);
104
105#endif /* HTC_USB_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
new file mode 100644
index 000000000000..ab09fe3416c7
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -0,0 +1,441 @@
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#ifndef HTC_H
18#define HTC_H
19
20#include <linux/module.h>
21#include <linux/usb.h>
22#include <linux/firmware.h>
23#include <linux/skbuff.h>
24#include <linux/netdevice.h>
25#include <linux/leds.h>
26#include <net/mac80211.h>
27
28#include "common.h"
29#include "htc_hst.h"
30#include "hif_usb.h"
31#include "wmi.h"
32
33#define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */
34#define ATH_ANI_POLLINTERVAL 100 /* 100 ms */
35#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
36#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
37
38#define ATH_DEFAULT_BMISS_LIMIT 10
39#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
40#define TSF_TO_TU(_h, _l) \
41 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
42
43extern struct ieee80211_ops ath9k_htc_ops;
44extern int modparam_nohwcrypt;
45
46enum htc_phymode {
47 HTC_MODE_AUTO = 0,
48 HTC_MODE_11A = 1,
49 HTC_MODE_11B = 2,
50 HTC_MODE_11G = 3,
51 HTC_MODE_FH = 4,
52 HTC_MODE_TURBO_A = 5,
53 HTC_MODE_TURBO_G = 6,
54 HTC_MODE_11NA = 7,
55 HTC_MODE_11NG = 8
56};
57
58enum htc_opmode {
59 HTC_M_STA = 1,
60 HTC_M_IBSS = 0,
61 HTC_M_AHDEMO = 3,
62 HTC_M_HOSTAP = 6,
63 HTC_M_MONITOR = 8,
64 HTC_M_WDS = 2
65};
66
67#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
68#define ATH9K_HTC_AMPDU 1
69#define ATH9K_HTC_NORMAL 2
70
71#define ATH9K_HTC_TX_CTSONLY 0x1
72#define ATH9K_HTC_TX_RTSCTS 0x2
73#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
74
75struct tx_frame_hdr {
76 u8 data_type;
77 u8 node_idx;
78 u8 vif_idx;
79 u8 tidno;
80 u32 flags; /* ATH9K_HTC_TX_* */
81 u8 key_type;
82 u8 keyix;
83 u8 reserved[26];
84} __packed;
85
86struct tx_mgmt_hdr {
87 u8 node_idx;
88 u8 vif_idx;
89 u8 tidno;
90 u8 flags;
91 u8 key_type;
92 u8 keyix;
93 u16 reserved;
94} __packed;
95
96struct tx_beacon_header {
97 u8 len_changed;
98 u8 vif_index;
99 u16 rev;
100} __packed;
101
102struct ath9k_htc_target_hw {
103 u32 flags;
104 u32 flags_ext;
105 u32 ampdu_limit;
106 u8 ampdu_subframes;
107 u8 tx_chainmask;
108 u8 tx_chainmask_legacy;
109 u8 rtscts_ratecode;
110 u8 protmode;
111} __packed;
112
113struct ath9k_htc_cap_target {
114 u32 flags;
115 u32 flags_ext;
116 u32 ampdu_limit;
117 u8 ampdu_subframes;
118 u8 tx_chainmask;
119 u8 tx_chainmask_legacy;
120 u8 rtscts_ratecode;
121 u8 protmode;
122} __packed;
123
124struct ath9k_htc_target_vif {
125 u8 index;
126 u8 des_bssid[ETH_ALEN];
127 enum htc_opmode opmode;
128 u8 myaddr[ETH_ALEN];
129 u8 bssid[ETH_ALEN];
130 u32 flags;
131 u32 flags_ext;
132 u16 ps_sta;
133 u16 rtsthreshold;
134 u8 ath_cap;
135 u8 node;
136 s8 mcast_rate;
137} __packed;
138
139#define ATH_HTC_STA_AUTH 0x0001
140#define ATH_HTC_STA_QOS 0x0002
141#define ATH_HTC_STA_ERP 0x0004
142#define ATH_HTC_STA_HT 0x0008
143
144/* FIXME: UAPSD variables */
145struct ath9k_htc_target_sta {
146 u16 associd;
147 u16 txpower;
148 u32 ucastkey;
149 u8 macaddr[ETH_ALEN];
150 u8 bssid[ETH_ALEN];
151 u8 sta_index;
152 u8 vif_index;
153 u8 vif_sta;
154 u16 flags; /* ATH_HTC_STA_* */
155 u16 htcap;
156 u8 valid;
157 u16 capinfo;
158 struct ath9k_htc_target_hw *hw;
159 struct ath9k_htc_target_vif *vif;
160 u16 txseqmgmt;
161 u8 is_vif_sta;
162 u16 maxampdu;
163 u16 iv16;
164 u32 iv32;
165} __packed;
166
167struct ath9k_htc_target_aggr {
168 u8 sta_index;
169 u8 tidno;
170 u8 aggr_enable;
171 u8 padding;
172} __packed;
173
174#define ATH_HTC_RATE_MAX 30
175
176#define WLAN_RC_DS_FLAG 0x01
177#define WLAN_RC_40_FLAG 0x02
178#define WLAN_RC_SGI_FLAG 0x04
179#define WLAN_RC_HT_FLAG 0x08
180
181struct ath9k_htc_rateset {
182 u8 rs_nrates;
183 u8 rs_rates[ATH_HTC_RATE_MAX];
184};
185
186struct ath9k_htc_rate {
187 struct ath9k_htc_rateset legacy_rates;
188 struct ath9k_htc_rateset ht_rates;
189} __packed;
190
191struct ath9k_htc_target_rate {
192 u8 sta_index;
193 u8 isnew;
194 u32 capflags;
195 struct ath9k_htc_rate rates;
196};
197
198struct ath9k_htc_target_stats {
199 u32 tx_shortretry;
200 u32 tx_longretry;
201 u32 tx_xretries;
202 u32 ht_txunaggr_xretry;
203 u32 ht_tx_xretries;
204} __packed;
205
206struct ath9k_htc_vif {
207 u8 index;
208};
209
210#define ATH9K_HTC_MAX_STA 8
211#define ATH9K_HTC_MAX_TID 8
212
213enum tid_aggr_state {
214 AGGR_STOP = 0,
215 AGGR_PROGRESS,
216 AGGR_START,
217 AGGR_OPERATIONAL
218};
219
220struct ath9k_htc_sta {
221 u8 index;
222 enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
223};
224
225struct ath9k_htc_aggr_work {
226 u16 tid;
227 u8 sta_addr[ETH_ALEN];
228 struct ieee80211_hw *hw;
229 struct ieee80211_vif *vif;
230 enum ieee80211_ampdu_mlme_action action;
231 struct mutex mutex;
232};
233
234#define ATH9K_HTC_RXBUF 256
235#define HTC_RX_FRAME_HEADER_SIZE 40
236
237struct ath9k_htc_rxbuf {
238 bool in_process;
239 struct sk_buff *skb;
240 struct ath_htc_rx_status rxstatus;
241 struct list_head list;
242};
243
244struct ath9k_htc_rx {
245 int last_rssi; /* FIXME: per-STA */
246 struct list_head rxbuf;
247 spinlock_t rxbuflock;
248};
249
250struct ath9k_htc_tx_ctl {
251 u8 type; /* ATH9K_HTC_* */
252};
253
254#ifdef CONFIG_ATH9K_HTC_DEBUGFS
255
256#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
257#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
258
259struct ath_tx_stats {
260 u32 buf_queued;
261 u32 buf_completed;
262 u32 skb_queued;
263 u32 skb_completed;
264};
265
266struct ath_rx_stats {
267 u32 skb_allocated;
268 u32 skb_completed;
269 u32 skb_dropped;
270};
271
272struct ath9k_debug {
273 struct dentry *debugfs_phy;
274 struct dentry *debugfs_tgt_stats;
275 struct dentry *debugfs_xmit;
276 struct dentry *debugfs_recv;
277 struct ath_tx_stats tx_stats;
278 struct ath_rx_stats rx_stats;
279 u32 txrate;
280};
281
282#else
283
284#define TX_STAT_INC(c) do { } while (0)
285#define RX_STAT_INC(c) do { } while (0)
286
287#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
288
289#define ATH_LED_PIN_DEF 1
290#define ATH_LED_PIN_9287 8
291#define ATH_LED_PIN_9271 15
292#define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */
293#define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */
294
295enum ath_led_type {
296 ATH_LED_RADIO,
297 ATH_LED_ASSOC,
298 ATH_LED_TX,
299 ATH_LED_RX
300};
301
302struct ath_led {
303 struct ath9k_htc_priv *priv;
304 struct led_classdev led_cdev;
305 enum ath_led_type led_type;
306 struct delayed_work brightness_work;
307 char name[32];
308 bool registered;
309 int brightness;
310};
311
312#define OP_INVALID BIT(0)
313#define OP_SCANNING BIT(1)
314#define OP_FULL_RESET BIT(2)
315#define OP_LED_ASSOCIATED BIT(3)
316#define OP_LED_ON BIT(4)
317#define OP_PREAMBLE_SHORT BIT(5)
318#define OP_PROTECT_ENABLE BIT(6)
319#define OP_TXAGGR BIT(7)
320#define OP_ASSOCIATED BIT(8)
321#define OP_ENABLE_BEACON BIT(9)
322#define OP_LED_DEINIT BIT(10)
323
324struct ath9k_htc_priv {
325 struct device *dev;
326 struct ieee80211_hw *hw;
327 struct ath_hw *ah;
328 struct htc_target *htc;
329 struct wmi *wmi;
330
331 enum htc_endpoint_id wmi_cmd_ep;
332 enum htc_endpoint_id beacon_ep;
333 enum htc_endpoint_id cab_ep;
334 enum htc_endpoint_id uapsd_ep;
335 enum htc_endpoint_id mgmt_ep;
336 enum htc_endpoint_id data_be_ep;
337 enum htc_endpoint_id data_bk_ep;
338 enum htc_endpoint_id data_vi_ep;
339 enum htc_endpoint_id data_vo_ep;
340
341 u16 op_flags;
342 u16 curtxpow;
343 u16 txpowlimit;
344 u16 nvifs;
345 u16 nstations;
346 u16 seq_no;
347 u32 bmiss_cnt;
348
349 struct sk_buff *beacon;
350 spinlock_t beacon_lock;
351
352 struct ieee80211_vif *vif;
353 unsigned int rxfilter;
354 struct tasklet_struct wmi_tasklet;
355 struct tasklet_struct rx_tasklet;
356 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
357 struct ath9k_htc_rx rx;
358 struct tasklet_struct tx_tasklet;
359 struct sk_buff_head tx_queue;
360 struct ath9k_htc_aggr_work aggr_work;
361 struct delayed_work ath9k_aggr_work;
362 struct delayed_work ath9k_ani_work;
363
364 struct ath_led radio_led;
365 struct ath_led assoc_led;
366 struct ath_led tx_led;
367 struct ath_led rx_led;
368 struct delayed_work ath9k_led_blink_work;
369 int led_on_duration;
370 int led_off_duration;
371 int led_on_cnt;
372 int led_off_cnt;
373 int hwq_map[ATH9K_WME_AC_VO+1];
374
375#ifdef CONFIG_ATH9K_HTC_DEBUGFS
376 struct ath9k_debug debug;
377#endif
378 struct ath9k_htc_target_rate tgt_rate;
379
380 struct mutex mutex;
381};
382
383static inline void ath_read_cachesize(struct ath_common *common, int *csz)
384{
385 common->bus_ops->read_cachesize(common, csz);
386}
387
388void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
389 struct ieee80211_vif *vif,
390 struct ieee80211_bss_conf *bss_conf);
391void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
392void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
393 struct ieee80211_vif *vif);
394
395void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
396 enum htc_endpoint_id ep_id);
397void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
398 bool txok);
399
400void ath9k_htc_station_work(struct work_struct *work);
401void ath9k_htc_aggr_work(struct work_struct *work);
402void ath9k_ani_work(struct work_struct *work);;
403
404int ath9k_tx_init(struct ath9k_htc_priv *priv);
405void ath9k_tx_tasklet(unsigned long data);
406int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
407void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
408bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
409 enum ath9k_tx_queue_subtype qtype);
410int get_hw_qnum(u16 queue, int *hwq_map);
411int ath_txq_update(struct ath9k_htc_priv *priv, int qnum,
412 struct ath9k_tx_queue_info *qinfo);
413
414int ath9k_rx_init(struct ath9k_htc_priv *priv);
415void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
416void ath9k_host_rx_init(struct ath9k_htc_priv *priv);
417void ath9k_rx_tasklet(unsigned long data);
418
419void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
420void ath9k_init_leds(struct ath9k_htc_priv *priv);
421void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
422
423int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
424 u16 devid);
425void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug);
426#ifdef CONFIG_PM
427int ath9k_htc_resume(struct htc_target *htc_handle);
428#endif
429#ifdef CONFIG_ATH9K_HTC_DEBUGFS
430int ath9k_debug_create_root(void);
431void ath9k_debug_remove_root(void);
432int ath9k_init_debug(struct ath_hw *ah);
433void ath9k_exit_debug(struct ath_hw *ah);
434#else
435static inline int ath9k_debug_create_root(void) { return 0; };
436static inline void ath9k_debug_remove_root(void) {};
437static inline int ath9k_init_debug(struct ath_hw *ah) { return 0; };
438static inline void ath9k_exit_debug(struct ath_hw *ah) {};
439#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
440
441#endif /* HTC_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
new file mode 100644
index 000000000000..25f5b5377bac
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -0,0 +1,260 @@
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 FUDGE 2
20
21static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
22 struct ieee80211_bss_conf *bss_conf)
23{
24 struct ath_common *common = ath9k_hw_common(priv->ah);
25 struct ath9k_beacon_state bs;
26 enum ath9k_int imask = 0;
27 int dtimperiod, dtimcount, sleepduration;
28 int cfpperiod, cfpcount, bmiss_timeout;
29 u32 nexttbtt = 0, intval, tsftu, htc_imask = 0;
30 u64 tsf;
31 int num_beacons, offset, dtim_dec_count, cfp_dec_count;
32 int ret;
33 u8 cmd_rsp;
34
35 memset(&bs, 0, sizeof(bs));
36
37 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
38 bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_int);
39
40 /*
41 * Setup dtim and cfp parameters according to
42 * last beacon we received (which may be none).
43 */
44 dtimperiod = bss_conf->dtim_period;
45 if (dtimperiod <= 0) /* NB: 0 if not known */
46 dtimperiod = 1;
47 dtimcount = 1;
48 if (dtimcount >= dtimperiod) /* NB: sanity check */
49 dtimcount = 0;
50 cfpperiod = 1; /* NB: no PCF support yet */
51 cfpcount = 0;
52
53 sleepduration = intval;
54 if (sleepduration <= 0)
55 sleepduration = intval;
56
57 /*
58 * Pull nexttbtt forward to reflect the current
59 * TSF and calculate dtim+cfp state for the result.
60 */
61 tsf = ath9k_hw_gettsf64(priv->ah);
62 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
63
64 num_beacons = tsftu / intval + 1;
65 offset = tsftu % intval;
66 nexttbtt = tsftu - offset;
67 if (offset)
68 nexttbtt += intval;
69
70 /* DTIM Beacon every dtimperiod Beacon */
71 dtim_dec_count = num_beacons % dtimperiod;
72 /* CFP every cfpperiod DTIM Beacon */
73 cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
74 if (dtim_dec_count)
75 cfp_dec_count++;
76
77 dtimcount -= dtim_dec_count;
78 if (dtimcount < 0)
79 dtimcount += dtimperiod;
80
81 cfpcount -= cfp_dec_count;
82 if (cfpcount < 0)
83 cfpcount += cfpperiod;
84
85 bs.bs_intval = intval;
86 bs.bs_nexttbtt = nexttbtt;
87 bs.bs_dtimperiod = dtimperiod*intval;
88 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
89 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
90 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
91 bs.bs_cfpmaxduration = 0;
92
93 /*
94 * Calculate the number of consecutive beacons to miss* before taking
95 * a BMISS interrupt. The configuration is specified in TU so we only
96 * need calculate based on the beacon interval. Note that we clamp the
97 * result to at most 15 beacons.
98 */
99 if (sleepduration > intval) {
100 bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2;
101 } else {
102 bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval);
103 if (bs.bs_bmissthreshold > 15)
104 bs.bs_bmissthreshold = 15;
105 else if (bs.bs_bmissthreshold <= 0)
106 bs.bs_bmissthreshold = 1;
107 }
108
109 /*
110 * Calculate sleep duration. The configuration is given in ms.
111 * We ensure a multiple of the beacon period is used. Also, if the sleep
112 * duration is greater than the DTIM period then it makes senses
113 * to make it a multiple of that.
114 *
115 * XXX fixed at 100ms
116 */
117
118 bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
119 if (bs.bs_sleepduration > bs.bs_dtimperiod)
120 bs.bs_sleepduration = bs.bs_dtimperiod;
121
122 /* TSF out of range threshold fixed at 1 second */
123 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
124
125 ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
126 ath_print(common, ATH_DBG_BEACON,
127 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
128 bs.bs_bmissthreshold, bs.bs_sleepduration,
129 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
130
131 /* Set the computed STA beacon timers */
132
133 WMI_CMD(WMI_DISABLE_INTR_CMDID);
134 ath9k_hw_set_sta_beacon_timers(priv->ah, &bs);
135 imask |= ATH9K_INT_BMISS;
136 htc_imask = cpu_to_be32(imask);
137 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
138}
139
140static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
141 struct ieee80211_bss_conf *bss_conf)
142{
143 struct ath_common *common = ath9k_hw_common(priv->ah);
144 enum ath9k_int imask = 0;
145 u32 nexttbtt, intval, htc_imask = 0;
146 int ret;
147 u8 cmd_rsp;
148
149 intval = bss_conf->beacon_int & ATH9K_BEACON_PERIOD;
150 nexttbtt = intval;
151 intval |= ATH9K_BEACON_ENA;
152 if (priv->op_flags & OP_ENABLE_BEACON)
153 imask |= ATH9K_INT_SWBA;
154
155 ath_print(common, ATH_DBG_BEACON,
156 "IBSS Beacon config, intval: %d, imask: 0x%x\n",
157 bss_conf->beacon_int, imask);
158
159 WMI_CMD(WMI_DISABLE_INTR_CMDID);
160 ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
161 priv->bmiss_cnt = 0;
162 htc_imask = cpu_to_be32(imask);
163 WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
164}
165
166void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv,
167 struct ieee80211_vif *vif)
168{
169 struct ath_common *common = ath9k_hw_common(priv->ah);
170
171 spin_lock_bh(&priv->beacon_lock);
172
173 if (priv->beacon)
174 dev_kfree_skb_any(priv->beacon);
175
176 priv->beacon = ieee80211_beacon_get(priv->hw, vif);
177 if (!priv->beacon)
178 ath_print(common, ATH_DBG_BEACON,
179 "Unable to allocate beacon\n");
180
181 spin_unlock_bh(&priv->beacon_lock);
182}
183
184void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
185{
186 struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
187 struct tx_beacon_header beacon_hdr;
188 struct ath9k_htc_tx_ctl tx_ctl;
189 struct ieee80211_tx_info *info;
190 u8 *tx_fhdr;
191
192 memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
193 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
194
195 /* FIXME: Handle BMISS */
196 if (beacon_pending != 0) {
197 priv->bmiss_cnt++;
198 return;
199 }
200
201 spin_lock_bh(&priv->beacon_lock);
202
203 if (unlikely(priv->op_flags & OP_SCANNING)) {
204 spin_unlock_bh(&priv->beacon_lock);
205 return;
206 }
207
208 if (unlikely(priv->beacon == NULL)) {
209 spin_unlock_bh(&priv->beacon_lock);
210 return;
211 }
212
213 /* Free the old SKB first */
214 dev_kfree_skb_any(priv->beacon);
215
216 /* Get a new beacon */
217 priv->beacon = ieee80211_beacon_get(priv->hw, priv->vif);
218 if (!priv->beacon) {
219 spin_unlock_bh(&priv->beacon_lock);
220 return;
221 }
222
223 info = IEEE80211_SKB_CB(priv->beacon);
224 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
225 struct ieee80211_hdr *hdr =
226 (struct ieee80211_hdr *) priv->beacon->data;
227 priv->seq_no += 0x10;
228 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
229 hdr->seq_ctrl |= cpu_to_le16(priv->seq_no);
230 }
231
232 tx_ctl.type = ATH9K_HTC_NORMAL;
233 beacon_hdr.vif_index = avp->index;
234 tx_fhdr = skb_push(priv->beacon, sizeof(beacon_hdr));
235 memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
236
237 htc_send(priv->htc, priv->beacon, priv->beacon_ep, &tx_ctl);
238
239 spin_unlock_bh(&priv->beacon_lock);
240}
241
242void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
243 struct ieee80211_vif *vif,
244 struct ieee80211_bss_conf *bss_conf)
245{
246 struct ath_common *common = ath9k_hw_common(priv->ah);
247
248 switch (vif->type) {
249 case NL80211_IFTYPE_STATION:
250 ath9k_htc_beacon_config_sta(priv, bss_conf);
251 break;
252 case NL80211_IFTYPE_ADHOC:
253 ath9k_htc_beacon_config_adhoc(priv, bss_conf);
254 break;
255 default:
256 ath_print(common, ATH_DBG_CONFIG,
257 "Unsupported beaconing mode\n");
258 return;
259 }
260}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
new file mode 100644
index 000000000000..a653dec140b9
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -0,0 +1,713 @@
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
19MODULE_AUTHOR("Atheros Communications");
20MODULE_LICENSE("Dual BSD/GPL");
21MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices");
22
23static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
24module_param_named(debug, ath9k_debug, uint, 0);
25MODULE_PARM_DESC(debug, "Debugging mask");
26
27int modparam_nohwcrypt;
28module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
29MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
30
31#define CHAN2G(_freq, _idx) { \
32 .center_freq = (_freq), \
33 .hw_value = (_idx), \
34 .max_power = 20, \
35}
36
37static struct ieee80211_channel ath9k_2ghz_channels[] = {
38 CHAN2G(2412, 0), /* Channel 1 */
39 CHAN2G(2417, 1), /* Channel 2 */
40 CHAN2G(2422, 2), /* Channel 3 */
41 CHAN2G(2427, 3), /* Channel 4 */
42 CHAN2G(2432, 4), /* Channel 5 */
43 CHAN2G(2437, 5), /* Channel 6 */
44 CHAN2G(2442, 6), /* Channel 7 */
45 CHAN2G(2447, 7), /* Channel 8 */
46 CHAN2G(2452, 8), /* Channel 9 */
47 CHAN2G(2457, 9), /* Channel 10 */
48 CHAN2G(2462, 10), /* Channel 11 */
49 CHAN2G(2467, 11), /* Channel 12 */
50 CHAN2G(2472, 12), /* Channel 13 */
51 CHAN2G(2484, 13), /* Channel 14 */
52};
53
54/* Atheros hardware rate code addition for short premble */
55#define SHPCHECK(__hw_rate, __flags) \
56 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0)
57
58#define RATE(_bitrate, _hw_rate, _flags) { \
59 .bitrate = (_bitrate), \
60 .flags = (_flags), \
61 .hw_value = (_hw_rate), \
62 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
63}
64
65static struct ieee80211_rate ath9k_legacy_rates[] = {
66 RATE(10, 0x1b, 0),
67 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */
68 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */
69 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */
70 RATE(60, 0x0b, 0),
71 RATE(90, 0x0f, 0),
72 RATE(120, 0x0a, 0),
73 RATE(180, 0x0e, 0),
74 RATE(240, 0x09, 0),
75 RATE(360, 0x0d, 0),
76 RATE(480, 0x08, 0),
77 RATE(540, 0x0c, 0),
78};
79
80static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
81{
82 int time_left;
83
84 /* Firmware can take up to 50ms to get ready, to be safe use 1 second */
85 time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
86 if (!time_left) {
87 dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n");
88 return -ETIMEDOUT;
89 }
90
91 return 0;
92}
93
94static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
95{
96 ath9k_exit_debug(priv->ah);
97 ath9k_hw_deinit(priv->ah);
98 tasklet_kill(&priv->wmi_tasklet);
99 tasklet_kill(&priv->rx_tasklet);
100 tasklet_kill(&priv->tx_tasklet);
101 kfree(priv->ah);
102 priv->ah = NULL;
103}
104
105static void ath9k_deinit_device(struct ath9k_htc_priv *priv)
106{
107 struct ieee80211_hw *hw = priv->hw;
108
109 wiphy_rfkill_stop_polling(hw->wiphy);
110 ath9k_deinit_leds(priv);
111 ieee80211_unregister_hw(hw);
112 ath9k_rx_cleanup(priv);
113 ath9k_tx_cleanup(priv);
114 ath9k_deinit_priv(priv);
115}
116
117static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv,
118 u16 service_id,
119 void (*tx) (void *,
120 struct sk_buff *,
121 enum htc_endpoint_id,
122 bool txok),
123 enum htc_endpoint_id *ep_id)
124{
125 struct htc_service_connreq req;
126
127 memset(&req, 0, sizeof(struct htc_service_connreq));
128
129 req.service_id = service_id;
130 req.ep_callbacks.priv = priv;
131 req.ep_callbacks.rx = ath9k_htc_rxep;
132 req.ep_callbacks.tx = tx;
133
134 return htc_connect_service(priv->htc, &req, ep_id);
135}
136
137static int ath9k_init_htc_services(struct ath9k_htc_priv *priv)
138{
139 int ret;
140
141 /* WMI CMD*/
142 ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep);
143 if (ret)
144 goto err;
145
146 /* Beacon */
147 ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, NULL,
148 &priv->beacon_ep);
149 if (ret)
150 goto err;
151
152 /* CAB */
153 ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep,
154 &priv->cab_ep);
155 if (ret)
156 goto err;
157
158
159 /* UAPSD */
160 ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep,
161 &priv->uapsd_ep);
162 if (ret)
163 goto err;
164
165 /* MGMT */
166 ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep,
167 &priv->mgmt_ep);
168 if (ret)
169 goto err;
170
171 /* DATA BE */
172 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep,
173 &priv->data_be_ep);
174 if (ret)
175 goto err;
176
177 /* DATA BK */
178 ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep,
179 &priv->data_bk_ep);
180 if (ret)
181 goto err;
182
183 /* DATA VI */
184 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep,
185 &priv->data_vi_ep);
186 if (ret)
187 goto err;
188
189 /* DATA VO */
190 ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep,
191 &priv->data_vo_ep);
192 if (ret)
193 goto err;
194
195 ret = htc_init(priv->htc);
196 if (ret)
197 goto err;
198
199 return 0;
200
201err:
202 dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n");
203 return ret;
204}
205
206static int ath9k_reg_notifier(struct wiphy *wiphy,
207 struct regulatory_request *request)
208{
209 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
210 struct ath9k_htc_priv *priv = hw->priv;
211
212 return ath_reg_notifier_apply(wiphy, request,
213 ath9k_hw_regulatory(priv->ah));
214}
215
216static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
217{
218 struct ath_hw *ah = (struct ath_hw *) hw_priv;
219 struct ath_common *common = ath9k_hw_common(ah);
220 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
221 __be32 val, reg = cpu_to_be32(reg_offset);
222 int r;
223
224 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID,
225 (u8 *) &reg, sizeof(reg),
226 (u8 *) &val, sizeof(val),
227 100);
228 if (unlikely(r)) {
229 ath_print(common, ATH_DBG_WMI,
230 "REGISTER READ FAILED: (0x%04x, %d)\n",
231 reg_offset, r);
232 return -EIO;
233 }
234
235 return be32_to_cpu(val);
236}
237
238static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
239{
240 struct ath_hw *ah = (struct ath_hw *) hw_priv;
241 struct ath_common *common = ath9k_hw_common(ah);
242 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
243 __be32 buf[2] = {
244 cpu_to_be32(reg_offset),
245 cpu_to_be32(val),
246 };
247 int r;
248
249 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID,
250 (u8 *) &buf, sizeof(buf),
251 (u8 *) &val, sizeof(val),
252 100);
253 if (unlikely(r)) {
254 ath_print(common, ATH_DBG_WMI,
255 "REGISTER WRITE FAILED:(0x%04x, %d)\n",
256 reg_offset, r);
257 }
258}
259
260static const struct ath_ops ath9k_common_ops = {
261 .read = ath9k_ioread32,
262 .write = ath9k_iowrite32,
263};
264
265static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
266{
267 *csz = L1_CACHE_BYTES >> 2;
268}
269
270static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
271{
272 struct ath_hw *ah = (struct ath_hw *) common->ah;
273
274 (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
275
276 if (!ath9k_hw_wait(ah,
277 AR_EEPROM_STATUS_DATA,
278 AR_EEPROM_STATUS_DATA_BUSY |
279 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
280 AH_WAIT_TIMEOUT))
281 return false;
282
283 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
284 AR_EEPROM_STATUS_DATA_VAL);
285
286 return true;
287}
288
289static const struct ath_bus_ops ath9k_usb_bus_ops = {
290 .read_cachesize = ath_usb_read_cachesize,
291 .eeprom_read = ath_usb_eeprom_read,
292};
293
294static void setup_ht_cap(struct ath9k_htc_priv *priv,
295 struct ieee80211_sta_ht_cap *ht_info)
296{
297 ht_info->ht_supported = true;
298 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
299 IEEE80211_HT_CAP_SM_PS |
300 IEEE80211_HT_CAP_SGI_40 |
301 IEEE80211_HT_CAP_DSSSCCK40;
302
303 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
304 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
305
306 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
307 ht_info->mcs.rx_mask[0] = 0xff;
308 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
309}
310
311static int ath9k_init_queues(struct ath9k_htc_priv *priv)
312{
313 struct ath_common *common = ath9k_hw_common(priv->ah);
314 int i;
315
316 for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++)
317 priv->hwq_map[i] = -1;
318
319 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
320 ath_print(common, ATH_DBG_FATAL,
321 "Unable to setup xmit queue for BE traffic\n");
322 goto err;
323 }
324
325 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
326 ath_print(common, ATH_DBG_FATAL,
327 "Unable to setup xmit queue for BK traffic\n");
328 goto err;
329 }
330 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
331 ath_print(common, ATH_DBG_FATAL,
332 "Unable to setup xmit queue for VI traffic\n");
333 goto err;
334 }
335 if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
336 ath_print(common, ATH_DBG_FATAL,
337 "Unable to setup xmit queue for VO traffic\n");
338 goto err;
339 }
340
341 return 0;
342
343err:
344 return -EINVAL;
345}
346
347static void ath9k_init_crypto(struct ath9k_htc_priv *priv)
348{
349 struct ath_common *common = ath9k_hw_common(priv->ah);
350 int i = 0;
351
352 /* Get the hardware key cache size. */
353 common->keymax = priv->ah->caps.keycache_size;
354 if (common->keymax > ATH_KEYMAX) {
355 ath_print(common, ATH_DBG_ANY,
356 "Warning, using only %u entries in %u key cache\n",
357 ATH_KEYMAX, common->keymax);
358 common->keymax = ATH_KEYMAX;
359 }
360
361 /*
362 * Reset the key cache since some parts do not
363 * reset the contents on initial power up.
364 */
365 for (i = 0; i < common->keymax; i++)
366 ath9k_hw_keyreset(priv->ah, (u16) i);
367
368 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
369 ATH9K_CIPHER_TKIP, NULL)) {
370 /*
371 * Whether we should enable h/w TKIP MIC.
372 * XXX: if we don't support WME TKIP MIC, then we wouldn't
373 * report WMM capable, so it's always safe to turn on
374 * TKIP MIC in this case.
375 */
376 ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
377 }
378
379 /*
380 * Check whether the separate key cache entries
381 * are required to handle both tx+rx MIC keys.
382 * With split mic keys the number of stations is limited
383 * to 27 otherwise 59.
384 */
385 if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
386 ATH9K_CIPHER_TKIP, NULL)
387 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER,
388 ATH9K_CIPHER_MIC, NULL)
389 && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT,
390 0, NULL))
391 common->splitmic = 1;
392
393 /* turn on mcast key search if possible */
394 if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
395 (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH,
396 1, 1, NULL);
397}
398
399static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv)
400{
401 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) {
402 priv->sbands[IEEE80211_BAND_2GHZ].channels =
403 ath9k_2ghz_channels;
404 priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
405 priv->sbands[IEEE80211_BAND_2GHZ].n_channels =
406 ARRAY_SIZE(ath9k_2ghz_channels);
407 priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
408 priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
409 ARRAY_SIZE(ath9k_legacy_rates);
410 }
411}
412
413static void ath9k_init_misc(struct ath9k_htc_priv *priv)
414{
415 struct ath_common *common = ath9k_hw_common(priv->ah);
416
417 common->tx_chainmask = priv->ah->caps.tx_chainmask;
418 common->rx_chainmask = priv->ah->caps.rx_chainmask;
419
420 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
421 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
422
423 priv->op_flags |= OP_TXAGGR;
424}
425
426static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
427{
428 struct ath_hw *ah = NULL;
429 struct ath_common *common;
430 int ret = 0, csz = 0;
431
432 priv->op_flags |= OP_INVALID;
433
434 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
435 if (!ah)
436 return -ENOMEM;
437
438 ah->hw_version.devid = devid;
439 ah->hw_version.subsysid = 0; /* FIXME */
440 priv->ah = ah;
441
442 common = ath9k_hw_common(ah);
443 common->ops = &ath9k_common_ops;
444 common->bus_ops = &ath9k_usb_bus_ops;
445 common->ah = ah;
446 common->hw = priv->hw;
447 common->priv = priv;
448 common->debug_mask = ath9k_debug;
449
450 spin_lock_init(&priv->wmi->wmi_lock);
451 spin_lock_init(&priv->beacon_lock);
452 mutex_init(&priv->mutex);
453 mutex_init(&priv->aggr_work.mutex);
454 tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
455 (unsigned long)priv);
456 tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
457 (unsigned long)priv);
458 tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
459 INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
460 INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
461
462 /*
463 * Cache line size is used to size and align various
464 * structures used to communicate with the hardware.
465 */
466 ath_read_cachesize(common, &csz);
467 common->cachelsz = csz << 2; /* convert to bytes */
468
469 ret = ath9k_hw_init(ah);
470 if (ret) {
471 ath_print(common, ATH_DBG_FATAL,
472 "Unable to initialize hardware; "
473 "initialization status: %d\n", ret);
474 goto err_hw;
475 }
476
477 ret = ath9k_init_debug(ah);
478 if (ret) {
479 ath_print(common, ATH_DBG_FATAL,
480 "Unable to create debugfs files\n");
481 goto err_debug;
482 }
483
484 ret = ath9k_init_queues(priv);
485 if (ret)
486 goto err_queues;
487
488 ath9k_init_crypto(priv);
489 ath9k_init_channels_rates(priv);
490 ath9k_init_misc(priv);
491
492 return 0;
493
494err_queues:
495 ath9k_exit_debug(ah);
496err_debug:
497 ath9k_hw_deinit(ah);
498err_hw:
499
500 kfree(ah);
501 priv->ah = NULL;
502
503 return ret;
504}
505
506static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
507 struct ieee80211_hw *hw)
508{
509 struct ath_common *common = ath9k_hw_common(priv->ah);
510
511 hw->flags = IEEE80211_HW_SIGNAL_DBM |
512 IEEE80211_HW_AMPDU_AGGREGATION |
513 IEEE80211_HW_SPECTRUM_MGMT |
514 IEEE80211_HW_HAS_RATE_CONTROL;
515
516 hw->wiphy->interface_modes =
517 BIT(NL80211_IFTYPE_STATION) |
518 BIT(NL80211_IFTYPE_ADHOC);
519
520 hw->queues = 4;
521 hw->channel_change_time = 5000;
522 hw->max_listen_interval = 10;
523 hw->vif_data_size = sizeof(struct ath9k_htc_vif);
524 hw->sta_data_size = sizeof(struct ath9k_htc_sta);
525
526 /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */
527 hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) +
528 sizeof(struct htc_frame_hdr) + 4;
529
530 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
531 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
532 &priv->sbands[IEEE80211_BAND_2GHZ];
533
534 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
535 if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes))
536 setup_ht_cap(priv,
537 &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap);
538 }
539
540 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
541}
542
543static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid)
544{
545 struct ieee80211_hw *hw = priv->hw;
546 struct ath_common *common;
547 struct ath_hw *ah;
548 int error = 0;
549 struct ath_regulatory *reg;
550
551 /* Bring up device */
552 error = ath9k_init_priv(priv, devid);
553 if (error != 0)
554 goto err_init;
555
556 ah = priv->ah;
557 common = ath9k_hw_common(ah);
558 ath9k_set_hw_capab(priv, hw);
559
560 /* Initialize regulatory */
561 error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
562 ath9k_reg_notifier);
563 if (error)
564 goto err_regd;
565
566 reg = &common->regulatory;
567
568 /* Setup TX */
569 error = ath9k_tx_init(priv);
570 if (error != 0)
571 goto err_tx;
572
573 /* Setup RX */
574 error = ath9k_rx_init(priv);
575 if (error != 0)
576 goto err_rx;
577
578 /* Register with mac80211 */
579 error = ieee80211_register_hw(hw);
580 if (error)
581 goto err_register;
582
583 /* Handle world regulatory */
584 if (!ath_is_world_regd(reg)) {
585 error = regulatory_hint(hw->wiphy, reg->alpha2);
586 if (error)
587 goto err_world;
588 }
589
590 ath9k_init_leds(priv);
591 ath9k_start_rfkill_poll(priv);
592
593 return 0;
594
595err_world:
596 ieee80211_unregister_hw(hw);
597err_register:
598 ath9k_rx_cleanup(priv);
599err_rx:
600 ath9k_tx_cleanup(priv);
601err_tx:
602 /* Nothing */
603err_regd:
604 ath9k_deinit_priv(priv);
605err_init:
606 return error;
607}
608
609int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
610 u16 devid)
611{
612 struct ieee80211_hw *hw;
613 struct ath9k_htc_priv *priv;
614 int ret;
615
616 hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops);
617 if (!hw)
618 return -ENOMEM;
619
620 priv = hw->priv;
621 priv->hw = hw;
622 priv->htc = htc_handle;
623 priv->dev = dev;
624 htc_handle->drv_priv = priv;
625 SET_IEEE80211_DEV(hw, priv->dev);
626
627 ret = ath9k_htc_wait_for_target(priv);
628 if (ret)
629 goto err_free;
630
631 priv->wmi = ath9k_init_wmi(priv);
632 if (!priv->wmi) {
633 ret = -EINVAL;
634 goto err_free;
635 }
636
637 ret = ath9k_init_htc_services(priv);
638 if (ret)
639 goto err_init;
640
641 ret = ath9k_init_device(priv, devid);
642 if (ret)
643 goto err_init;
644
645 return 0;
646
647err_init:
648 ath9k_deinit_wmi(priv);
649err_free:
650 ieee80211_free_hw(hw);
651 return ret;
652}
653
654void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug)
655{
656 if (htc_handle->drv_priv) {
657 ath9k_deinit_device(htc_handle->drv_priv);
658 ath9k_deinit_wmi(htc_handle->drv_priv);
659 ieee80211_free_hw(htc_handle->drv_priv->hw);
660 }
661}
662
663#ifdef CONFIG_PM
664int ath9k_htc_resume(struct htc_target *htc_handle)
665{
666 int ret;
667
668 ret = ath9k_htc_wait_for_target(htc_handle->drv_priv);
669 if (ret)
670 return ret;
671
672 ret = ath9k_init_htc_services(htc_handle->drv_priv);
673 return ret;
674}
675#endif
676
677static int __init ath9k_htc_init(void)
678{
679 int error;
680
681 error = ath9k_debug_create_root();
682 if (error < 0) {
683 printk(KERN_ERR
684 "ath9k_htc: Unable to create debugfs root: %d\n",
685 error);
686 goto err_dbg;
687 }
688
689 error = ath9k_hif_usb_init();
690 if (error < 0) {
691 printk(KERN_ERR
692 "ath9k_htc: No USB devices found,"
693 " driver not installed.\n");
694 error = -ENODEV;
695 goto err_usb;
696 }
697
698 return 0;
699
700err_usb:
701 ath9k_debug_remove_root();
702err_dbg:
703 return error;
704}
705module_init(ath9k_htc_init);
706
707static void __exit ath9k_htc_exit(void)
708{
709 ath9k_hif_usb_exit();
710 ath9k_debug_remove_root();
711 printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
712}
713module_exit(ath9k_htc_exit);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
new file mode 100644
index 000000000000..3184a2ac7b88
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -0,0 +1,1626 @@
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#ifdef CONFIG_ATH9K_HTC_DEBUGFS
20static struct dentry *ath9k_debugfs_root;
21#endif
22
23/*************/
24/* Utilities */
25/*************/
26
27static void ath_update_txpow(struct ath9k_htc_priv *priv)
28{
29 struct ath_hw *ah = priv->ah;
30 u32 txpow;
31
32 if (priv->curtxpow != priv->txpowlimit) {
33 ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit);
34 /* read back in case value is clamped */
35 ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
36 priv->curtxpow = txpow;
37 }
38}
39
40/* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */
41static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv,
42 struct ath9k_channel *ichan)
43{
44 enum htc_phymode mode;
45
46 mode = HTC_MODE_AUTO;
47
48 switch (ichan->chanmode) {
49 case CHANNEL_G:
50 case CHANNEL_G_HT20:
51 case CHANNEL_G_HT40PLUS:
52 case CHANNEL_G_HT40MINUS:
53 mode = HTC_MODE_11NG;
54 break;
55 case CHANNEL_A:
56 case CHANNEL_A_HT20:
57 case CHANNEL_A_HT40PLUS:
58 case CHANNEL_A_HT40MINUS:
59 mode = HTC_MODE_11NA;
60 break;
61 default:
62 break;
63 }
64
65 return mode;
66}
67
68static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
69 struct ieee80211_hw *hw,
70 struct ath9k_channel *hchan)
71{
72 struct ath_hw *ah = priv->ah;
73 struct ath_common *common = ath9k_hw_common(ah);
74 struct ieee80211_conf *conf = &common->hw->conf;
75 bool fastcc = true;
76 struct ieee80211_channel *channel = hw->conf.channel;
77 enum htc_phymode mode;
78 u16 htc_mode;
79 u8 cmd_rsp;
80 int ret;
81
82 if (priv->op_flags & OP_INVALID)
83 return -EIO;
84
85 if (priv->op_flags & OP_FULL_RESET)
86 fastcc = false;
87
88 /* Fiddle around with fastcc later on, for now just use full reset */
89 fastcc = false;
90
91 htc_stop(priv->htc);
92 WMI_CMD(WMI_DISABLE_INTR_CMDID);
93 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
94 WMI_CMD(WMI_STOP_RECV_CMDID);
95
96 ath_print(common, ATH_DBG_CONFIG,
97 "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n",
98 priv->ah->curchan->channel,
99 channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
100
101 ret = ath9k_hw_reset(ah, hchan, fastcc);
102 if (ret) {
103 ath_print(common, ATH_DBG_FATAL,
104 "Unable to reset channel (%u Mhz) "
105 "reset status %d\n", channel->center_freq, ret);
106 goto err;
107 }
108
109 ath_update_txpow(priv);
110
111 WMI_CMD(WMI_START_RECV_CMDID);
112 if (ret)
113 goto err;
114
115 ath9k_host_rx_init(priv);
116
117 mode = ath9k_htc_get_curmode(priv, hchan);
118 htc_mode = cpu_to_be16(mode);
119 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
120 if (ret)
121 goto err;
122
123 WMI_CMD(WMI_ENABLE_INTR_CMDID);
124 if (ret)
125 goto err;
126
127 htc_start(priv->htc);
128
129 priv->op_flags &= ~OP_FULL_RESET;
130err:
131 return ret;
132}
133
134static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv)
135{
136 struct ath_common *common = ath9k_hw_common(priv->ah);
137 struct ath9k_htc_target_vif hvif;
138 int ret = 0;
139 u8 cmd_rsp;
140
141 if (priv->nvifs > 0)
142 return -ENOBUFS;
143
144 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
145 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
146
147 hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
148 priv->ah->opmode = NL80211_IFTYPE_MONITOR;
149 hvif.index = priv->nvifs;
150
151 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
152 if (ret)
153 return ret;
154
155 priv->nvifs++;
156 return 0;
157}
158
159static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
160{
161 struct ath_common *common = ath9k_hw_common(priv->ah);
162 struct ath9k_htc_target_vif hvif;
163 int ret = 0;
164 u8 cmd_rsp;
165
166 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
167 memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
168 hvif.index = 0; /* Should do for now */
169 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
170 priv->nvifs--;
171
172 return ret;
173}
174
175static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
176 struct ieee80211_vif *vif,
177 struct ieee80211_sta *sta)
178{
179 struct ath_common *common = ath9k_hw_common(priv->ah);
180 struct ath9k_htc_target_sta tsta;
181 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
182 struct ath9k_htc_sta *ista;
183 int ret;
184 u8 cmd_rsp;
185
186 if (priv->nstations >= ATH9K_HTC_MAX_STA)
187 return -ENOBUFS;
188
189 memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta));
190
191 if (sta) {
192 ista = (struct ath9k_htc_sta *) sta->drv_priv;
193 memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
194 memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
195 tsta.associd = common->curaid;
196 tsta.is_vif_sta = 0;
197 tsta.valid = true;
198 ista->index = priv->nstations;
199 } else {
200 memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
201 tsta.is_vif_sta = 1;
202 }
203
204 tsta.sta_index = priv->nstations;
205 tsta.vif_index = avp->index;
206 tsta.maxampdu = 0xffff;
207 if (sta && sta->ht_cap.ht_supported)
208 tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
209
210 WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
211 if (ret) {
212 if (sta)
213 ath_print(common, ATH_DBG_FATAL,
214 "Unable to add station entry for: %pM\n", sta->addr);
215 return ret;
216 }
217
218 if (sta)
219 ath_print(common, ATH_DBG_CONFIG,
220 "Added a station entry for: %pM (idx: %d)\n",
221 sta->addr, tsta.sta_index);
222
223 priv->nstations++;
224 return 0;
225}
226
227static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
228 struct ieee80211_vif *vif,
229 struct ieee80211_sta *sta)
230{
231 struct ath_common *common = ath9k_hw_common(priv->ah);
232 struct ath9k_htc_sta *ista;
233 int ret;
234 u8 cmd_rsp, sta_idx;
235
236 if (sta) {
237 ista = (struct ath9k_htc_sta *) sta->drv_priv;
238 sta_idx = ista->index;
239 } else {
240 sta_idx = 0;
241 }
242
243 WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx);
244 if (ret) {
245 if (sta)
246 ath_print(common, ATH_DBG_FATAL,
247 "Unable to remove station entry for: %pM\n",
248 sta->addr);
249 return ret;
250 }
251
252 if (sta)
253 ath_print(common, ATH_DBG_CONFIG,
254 "Removed a station entry for: %pM (idx: %d)\n",
255 sta->addr, sta_idx);
256
257 priv->nstations--;
258 return 0;
259}
260
261static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
262{
263 struct ath9k_htc_cap_target tcap;
264 int ret;
265 u8 cmd_rsp;
266
267 memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
268
269 /* FIXME: Values are hardcoded */
270 tcap.flags = 0x240c40;
271 tcap.flags_ext = 0x80601000;
272 tcap.ampdu_limit = 0xffff0000;
273 tcap.ampdu_subframes = 20;
274 tcap.tx_chainmask_legacy = 1;
275 tcap.protmode = 1;
276 tcap.tx_chainmask = 1;
277
278 WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
279
280 return ret;
281}
282
283static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv,
284 struct ieee80211_vif *vif,
285 struct ieee80211_sta *sta)
286{
287 struct ath_common *common = ath9k_hw_common(priv->ah);
288 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
289 struct ieee80211_supported_band *sband;
290 struct ath9k_htc_target_rate trate;
291 u32 caps = 0;
292 u8 cmd_rsp;
293 int i, j, ret;
294
295 memset(&trate, 0, sizeof(trate));
296
297 /* Only 2GHz is supported */
298 sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ];
299
300 for (i = 0, j = 0; i < sband->n_bitrates; i++) {
301 if (sta->supp_rates[sband->band] & BIT(i)) {
302 priv->tgt_rate.rates.legacy_rates.rs_rates[j]
303 = (sband->bitrates[i].bitrate * 2) / 10;
304 j++;
305 }
306 }
307 priv->tgt_rate.rates.legacy_rates.rs_nrates = j;
308
309 if (sta->ht_cap.ht_supported) {
310 for (i = 0, j = 0; i < 77; i++) {
311 if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
312 priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i;
313 if (j == ATH_HTC_RATE_MAX)
314 break;
315 }
316 priv->tgt_rate.rates.ht_rates.rs_nrates = j;
317
318 caps = WLAN_RC_HT_FLAG;
319 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
320 caps |= WLAN_RC_40_FLAG;
321 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
322 caps |= WLAN_RC_SGI_FLAG;
323
324 }
325
326 priv->tgt_rate.sta_index = ista->index;
327 priv->tgt_rate.isnew = 1;
328 trate = priv->tgt_rate;
329 priv->tgt_rate.capflags = caps;
330 trate.capflags = cpu_to_be32(caps);
331
332 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
333 if (ret) {
334 ath_print(common, ATH_DBG_FATAL,
335 "Unable to initialize Rate information on target\n");
336 return ret;
337 }
338
339 ath_print(common, ATH_DBG_CONFIG,
340 "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps);
341 return 0;
342}
343
344static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40)
345{
346 struct ath9k_htc_priv *priv = hw->priv;
347 struct ieee80211_conf *conf = &hw->conf;
348
349 if (!conf_is_ht(conf))
350 return false;
351
352 if (!(priv->op_flags & OP_ASSOCIATED) ||
353 (priv->op_flags & OP_SCANNING))
354 return false;
355
356 if (conf_is_ht40(conf)) {
357 if (priv->ah->curchan->chanmode &
358 (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) {
359 return false;
360 } else {
361 *cw40 = true;
362 return true;
363 }
364 } else { /* ht20 */
365 if (priv->ah->curchan->chanmode & CHANNEL_HT20)
366 return false;
367 else
368 return true;
369 }
370}
371
372static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40)
373{
374 struct ath9k_htc_target_rate trate;
375 struct ath_common *common = ath9k_hw_common(priv->ah);
376 int ret;
377 u8 cmd_rsp;
378
379 memset(&trate, 0, sizeof(trate));
380
381 trate = priv->tgt_rate;
382
383 if (is_cw40)
384 priv->tgt_rate.capflags |= WLAN_RC_40_FLAG;
385 else
386 priv->tgt_rate.capflags &= ~WLAN_RC_40_FLAG;
387
388 trate.capflags = cpu_to_be32(priv->tgt_rate.capflags);
389
390 WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate);
391 if (ret) {
392 ath_print(common, ATH_DBG_FATAL,
393 "Unable to update Rate information on target\n");
394 return;
395 }
396
397 ath_print(common, ATH_DBG_CONFIG, "Rate control updated with "
398 "caps:0x%x on target\n", priv->tgt_rate.capflags);
399}
400
401static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
402 struct ieee80211_vif *vif,
403 u8 *sta_addr, u8 tid, bool oper)
404{
405 struct ath_common *common = ath9k_hw_common(priv->ah);
406 struct ath9k_htc_target_aggr aggr;
407 struct ieee80211_sta *sta = NULL;
408 struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
409 int ret = 0;
410 u8 cmd_rsp;
411
412 if (tid > ATH9K_HTC_MAX_TID)
413 return -EINVAL;
414
415 rcu_read_lock();
416 sta = ieee80211_find_sta(vif, sta_addr);
417 if (sta) {
418 ista = (struct ath9k_htc_sta *) sta->drv_priv;
419 } else {
420 rcu_read_unlock();
421 return -EINVAL;
422 }
423
424 if (!ista) {
425 rcu_read_unlock();
426 return -EINVAL;
427 }
428
429 memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
430
431 aggr.sta_index = ista->index;
432 rcu_read_unlock();
433 aggr.tidno = tid;
434 aggr.aggr_enable = oper;
435
436 if (oper)
437 ista->tid_state[tid] = AGGR_START;
438 else
439 ista->tid_state[tid] = AGGR_STOP;
440
441 WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
442 if (ret)
443 ath_print(common, ATH_DBG_CONFIG,
444 "Unable to %s TX aggregation for (%pM, %d)\n",
445 (oper) ? "start" : "stop", sta->addr, tid);
446 else
447 ath_print(common, ATH_DBG_CONFIG,
448 "%s aggregation for (%pM, %d)\n",
449 (oper) ? "Starting" : "Stopping", sta->addr, tid);
450
451 return ret;
452}
453
454void ath9k_htc_aggr_work(struct work_struct *work)
455{
456 int ret = 0;
457 struct ath9k_htc_priv *priv =
458 container_of(work, struct ath9k_htc_priv,
459 ath9k_aggr_work.work);
460 struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
461
462 mutex_lock(&wk->mutex);
463
464 switch (wk->action) {
465 case IEEE80211_AMPDU_TX_START:
466 ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
467 wk->tid, true);
468 if (!ret)
469 ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr,
470 wk->tid);
471 break;
472 case IEEE80211_AMPDU_TX_STOP:
473 ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
474 wk->tid, false);
475 ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid);
476 break;
477 default:
478 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
479 "Unknown AMPDU action\n");
480 }
481
482 mutex_unlock(&wk->mutex);
483}
484
485/*********/
486/* DEBUG */
487/*********/
488
489#ifdef CONFIG_ATH9K_HTC_DEBUGFS
490
491static int ath9k_debugfs_open(struct inode *inode, struct file *file)
492{
493 file->private_data = inode->i_private;
494 return 0;
495}
496
497static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
498 size_t count, loff_t *ppos)
499{
500 struct ath9k_htc_priv *priv =
501 (struct ath9k_htc_priv *) file->private_data;
502 struct ath9k_htc_target_stats cmd_rsp;
503 char buf[512];
504 unsigned int len = 0;
505 int ret = 0;
506
507 memset(&cmd_rsp, 0, sizeof(cmd_rsp));
508
509 WMI_CMD(WMI_TGT_STATS_CMDID);
510 if (ret)
511 return -EINVAL;
512
513
514 len += snprintf(buf + len, sizeof(buf) - len,
515 "%19s : %10u\n", "TX Short Retries",
516 be32_to_cpu(cmd_rsp.tx_shortretry));
517 len += snprintf(buf + len, sizeof(buf) - len,
518 "%19s : %10u\n", "TX Long Retries",
519 be32_to_cpu(cmd_rsp.tx_longretry));
520 len += snprintf(buf + len, sizeof(buf) - len,
521 "%19s : %10u\n", "TX Xretries",
522 be32_to_cpu(cmd_rsp.tx_xretries));
523 len += snprintf(buf + len, sizeof(buf) - len,
524 "%19s : %10u\n", "TX Unaggr. Xretries",
525 be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
526 len += snprintf(buf + len, sizeof(buf) - len,
527 "%19s : %10u\n", "TX Xretries (HT)",
528 be32_to_cpu(cmd_rsp.ht_tx_xretries));
529 len += snprintf(buf + len, sizeof(buf) - len,
530 "%19s : %10u\n", "TX Rate", priv->debug.txrate);
531
532 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
533}
534
535static const struct file_operations fops_tgt_stats = {
536 .read = read_file_tgt_stats,
537 .open = ath9k_debugfs_open,
538 .owner = THIS_MODULE
539};
540
541static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
542 size_t count, loff_t *ppos)
543{
544 struct ath9k_htc_priv *priv =
545 (struct ath9k_htc_priv *) file->private_data;
546 char buf[512];
547 unsigned int len = 0;
548
549 len += snprintf(buf + len, sizeof(buf) - len,
550 "%20s : %10u\n", "Buffers queued",
551 priv->debug.tx_stats.buf_queued);
552 len += snprintf(buf + len, sizeof(buf) - len,
553 "%20s : %10u\n", "Buffers completed",
554 priv->debug.tx_stats.buf_completed);
555 len += snprintf(buf + len, sizeof(buf) - len,
556 "%20s : %10u\n", "SKBs queued",
557 priv->debug.tx_stats.skb_queued);
558 len += snprintf(buf + len, sizeof(buf) - len,
559 "%20s : %10u\n", "SKBs completed",
560 priv->debug.tx_stats.skb_completed);
561
562 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
563}
564
565static const struct file_operations fops_xmit = {
566 .read = read_file_xmit,
567 .open = ath9k_debugfs_open,
568 .owner = THIS_MODULE
569};
570
571static ssize_t read_file_recv(struct file *file, char __user *user_buf,
572 size_t count, loff_t *ppos)
573{
574 struct ath9k_htc_priv *priv =
575 (struct ath9k_htc_priv *) file->private_data;
576 char buf[512];
577 unsigned int len = 0;
578
579 len += snprintf(buf + len, sizeof(buf) - len,
580 "%20s : %10u\n", "SKBs allocated",
581 priv->debug.rx_stats.skb_allocated);
582 len += snprintf(buf + len, sizeof(buf) - len,
583 "%20s : %10u\n", "SKBs completed",
584 priv->debug.rx_stats.skb_completed);
585 len += snprintf(buf + len, sizeof(buf) - len,
586 "%20s : %10u\n", "SKBs Dropped",
587 priv->debug.rx_stats.skb_dropped);
588
589 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
590}
591
592static const struct file_operations fops_recv = {
593 .read = read_file_recv,
594 .open = ath9k_debugfs_open,
595 .owner = THIS_MODULE
596};
597
598int ath9k_init_debug(struct ath_hw *ah)
599{
600 struct ath_common *common = ath9k_hw_common(ah);
601 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
602
603 if (!ath9k_debugfs_root)
604 return -ENOENT;
605
606 priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
607 ath9k_debugfs_root);
608 if (!priv->debug.debugfs_phy)
609 goto err;
610
611 priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
612 priv->debug.debugfs_phy,
613 priv, &fops_tgt_stats);
614 if (!priv->debug.debugfs_tgt_stats)
615 goto err;
616
617
618 priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
619 priv->debug.debugfs_phy,
620 priv, &fops_xmit);
621 if (!priv->debug.debugfs_xmit)
622 goto err;
623
624 priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
625 priv->debug.debugfs_phy,
626 priv, &fops_recv);
627 if (!priv->debug.debugfs_recv)
628 goto err;
629
630 return 0;
631
632err:
633 ath9k_exit_debug(ah);
634 return -ENOMEM;
635}
636
637void ath9k_exit_debug(struct ath_hw *ah)
638{
639 struct ath_common *common = ath9k_hw_common(ah);
640 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
641
642 debugfs_remove(priv->debug.debugfs_recv);
643 debugfs_remove(priv->debug.debugfs_xmit);
644 debugfs_remove(priv->debug.debugfs_tgt_stats);
645 debugfs_remove(priv->debug.debugfs_phy);
646}
647
648int ath9k_debug_create_root(void)
649{
650 ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
651 if (!ath9k_debugfs_root)
652 return -ENOENT;
653
654 return 0;
655}
656
657void ath9k_debug_remove_root(void)
658{
659 debugfs_remove(ath9k_debugfs_root);
660 ath9k_debugfs_root = NULL;
661}
662
663#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
664
665/*******/
666/* ANI */
667/*******/
668
669static void ath_start_ani(struct ath9k_htc_priv *priv)
670{
671 struct ath_common *common = ath9k_hw_common(priv->ah);
672 unsigned long timestamp = jiffies_to_msecs(jiffies);
673
674 common->ani.longcal_timer = timestamp;
675 common->ani.shortcal_timer = timestamp;
676 common->ani.checkani_timer = timestamp;
677
678 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
679 msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
680}
681
682void ath9k_ani_work(struct work_struct *work)
683{
684 struct ath9k_htc_priv *priv =
685 container_of(work, struct ath9k_htc_priv,
686 ath9k_ani_work.work);
687 struct ath_hw *ah = priv->ah;
688 struct ath_common *common = ath9k_hw_common(ah);
689 bool longcal = false;
690 bool shortcal = false;
691 bool aniflag = false;
692 unsigned int timestamp = jiffies_to_msecs(jiffies);
693 u32 cal_interval, short_cal_interval;
694
695 short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
696
697 /* Long calibration runs independently of short calibration. */
698 if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
699 longcal = true;
700 ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
701 common->ani.longcal_timer = timestamp;
702 }
703
704 /* Short calibration applies only while caldone is false */
705 if (!common->ani.caldone) {
706 if ((timestamp - common->ani.shortcal_timer) >=
707 short_cal_interval) {
708 shortcal = true;
709 ath_print(common, ATH_DBG_ANI,
710 "shortcal @%lu\n", jiffies);
711 common->ani.shortcal_timer = timestamp;
712 common->ani.resetcal_timer = timestamp;
713 }
714 } else {
715 if ((timestamp - common->ani.resetcal_timer) >=
716 ATH_RESTART_CALINTERVAL) {
717 common->ani.caldone = ath9k_hw_reset_calvalid(ah);
718 if (common->ani.caldone)
719 common->ani.resetcal_timer = timestamp;
720 }
721 }
722
723 /* Verify whether we must check ANI */
724 if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
725 aniflag = true;
726 common->ani.checkani_timer = timestamp;
727 }
728
729 /* Skip all processing if there's nothing to do. */
730 if (longcal || shortcal || aniflag) {
731 /* Call ANI routine if necessary */
732 if (aniflag)
733 ath9k_hw_ani_monitor(ah, ah->curchan);
734
735 /* Perform calibration if necessary */
736 if (longcal || shortcal) {
737 common->ani.caldone =
738 ath9k_hw_calibrate(ah, ah->curchan,
739 common->rx_chainmask,
740 longcal);
741
742 if (longcal)
743 common->ani.noise_floor =
744 ath9k_hw_getchan_noise(ah, ah->curchan);
745
746 ath_print(common, ATH_DBG_ANI,
747 " calibrate chan %u/%x nf: %d\n",
748 ah->curchan->channel,
749 ah->curchan->channelFlags,
750 common->ani.noise_floor);
751 }
752 }
753
754 /*
755 * Set timer interval based on previous results.
756 * The interval must be the shortest necessary to satisfy ANI,
757 * short calibration and long calibration.
758 */
759 cal_interval = ATH_LONG_CALINTERVAL;
760 if (priv->ah->config.enable_ani)
761 cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
762 if (!common->ani.caldone)
763 cal_interval = min(cal_interval, (u32)short_cal_interval);
764
765 ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work,
766 msecs_to_jiffies(cal_interval));
767}
768
769/*******/
770/* LED */
771/*******/
772
773static void ath9k_led_blink_work(struct work_struct *work)
774{
775 struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
776 ath9k_led_blink_work.work);
777
778 if (!(priv->op_flags & OP_LED_ASSOCIATED))
779 return;
780
781 if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
782 (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
783 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
784 else
785 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
786 (priv->op_flags & OP_LED_ON) ? 1 : 0);
787
788 ieee80211_queue_delayed_work(priv->hw,
789 &priv->ath9k_led_blink_work,
790 (priv->op_flags & OP_LED_ON) ?
791 msecs_to_jiffies(priv->led_off_duration) :
792 msecs_to_jiffies(priv->led_on_duration));
793
794 priv->led_on_duration = priv->led_on_cnt ?
795 max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
796 ATH_LED_ON_DURATION_IDLE;
797 priv->led_off_duration = priv->led_off_cnt ?
798 max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
799 ATH_LED_OFF_DURATION_IDLE;
800 priv->led_on_cnt = priv->led_off_cnt = 0;
801
802 if (priv->op_flags & OP_LED_ON)
803 priv->op_flags &= ~OP_LED_ON;
804 else
805 priv->op_flags |= OP_LED_ON;
806}
807
808static void ath9k_led_brightness_work(struct work_struct *work)
809{
810 struct ath_led *led = container_of(work, struct ath_led,
811 brightness_work.work);
812 struct ath9k_htc_priv *priv = led->priv;
813
814 switch (led->brightness) {
815 case LED_OFF:
816 if (led->led_type == ATH_LED_ASSOC ||
817 led->led_type == ATH_LED_RADIO) {
818 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
819 (led->led_type == ATH_LED_RADIO));
820 priv->op_flags &= ~OP_LED_ASSOCIATED;
821 if (led->led_type == ATH_LED_RADIO)
822 priv->op_flags &= ~OP_LED_ON;
823 } else {
824 priv->led_off_cnt++;
825 }
826 break;
827 case LED_FULL:
828 if (led->led_type == ATH_LED_ASSOC) {
829 priv->op_flags |= OP_LED_ASSOCIATED;
830 ieee80211_queue_delayed_work(priv->hw,
831 &priv->ath9k_led_blink_work, 0);
832 } else if (led->led_type == ATH_LED_RADIO) {
833 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
834 priv->op_flags |= OP_LED_ON;
835 } else {
836 priv->led_on_cnt++;
837 }
838 break;
839 default:
840 break;
841 }
842}
843
844static void ath9k_led_brightness(struct led_classdev *led_cdev,
845 enum led_brightness brightness)
846{
847 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
848 struct ath9k_htc_priv *priv = led->priv;
849
850 led->brightness = brightness;
851 if (!(priv->op_flags & OP_LED_DEINIT))
852 ieee80211_queue_delayed_work(priv->hw,
853 &led->brightness_work, 0);
854}
855
856static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
857{
858 cancel_delayed_work_sync(&priv->radio_led.brightness_work);
859 cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
860 cancel_delayed_work_sync(&priv->tx_led.brightness_work);
861 cancel_delayed_work_sync(&priv->rx_led.brightness_work);
862}
863
864static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
865 char *trigger)
866{
867 int ret;
868
869 led->priv = priv;
870 led->led_cdev.name = led->name;
871 led->led_cdev.default_trigger = trigger;
872 led->led_cdev.brightness_set = ath9k_led_brightness;
873
874 ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
875 if (ret)
876 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
877 "Failed to register led:%s", led->name);
878 else
879 led->registered = 1;
880
881 INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
882
883 return ret;
884}
885
886static void ath9k_unregister_led(struct ath_led *led)
887{
888 if (led->registered) {
889 led_classdev_unregister(&led->led_cdev);
890 led->registered = 0;
891 }
892}
893
894void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
895{
896 priv->op_flags |= OP_LED_DEINIT;
897 ath9k_unregister_led(&priv->assoc_led);
898 priv->op_flags &= ~OP_LED_ASSOCIATED;
899 ath9k_unregister_led(&priv->tx_led);
900 ath9k_unregister_led(&priv->rx_led);
901 ath9k_unregister_led(&priv->radio_led);
902 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
903}
904
905void ath9k_init_leds(struct ath9k_htc_priv *priv)
906{
907 char *trigger;
908 int ret;
909
910 if (AR_SREV_9287(priv->ah))
911 priv->ah->led_pin = ATH_LED_PIN_9287;
912 else if (AR_SREV_9271(priv->ah))
913 priv->ah->led_pin = ATH_LED_PIN_9271;
914 else
915 priv->ah->led_pin = ATH_LED_PIN_DEF;
916
917 /* Configure gpio 1 for output */
918 ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin,
919 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
920 /* LED off, active low */
921 ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
922
923 INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
924
925 trigger = ieee80211_get_radio_led_name(priv->hw);
926 snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
927 "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
928 ret = ath9k_register_led(priv, &priv->radio_led, trigger);
929 priv->radio_led.led_type = ATH_LED_RADIO;
930 if (ret)
931 goto fail;
932
933 trigger = ieee80211_get_assoc_led_name(priv->hw);
934 snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
935 "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
936 ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
937 priv->assoc_led.led_type = ATH_LED_ASSOC;
938 if (ret)
939 goto fail;
940
941 trigger = ieee80211_get_tx_led_name(priv->hw);
942 snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
943 "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
944 ret = ath9k_register_led(priv, &priv->tx_led, trigger);
945 priv->tx_led.led_type = ATH_LED_TX;
946 if (ret)
947 goto fail;
948
949 trigger = ieee80211_get_rx_led_name(priv->hw);
950 snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
951 "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
952 ret = ath9k_register_led(priv, &priv->rx_led, trigger);
953 priv->rx_led.led_type = ATH_LED_RX;
954 if (ret)
955 goto fail;
956
957 priv->op_flags &= ~OP_LED_DEINIT;
958
959 return;
960
961fail:
962 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
963 ath9k_deinit_leds(priv);
964}
965
966/*******************/
967/* Rfkill */
968/*******************/
969
970static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv)
971{
972 return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) ==
973 priv->ah->rfkill_polarity;
974}
975
976static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw)
977{
978 struct ath9k_htc_priv *priv = hw->priv;
979 bool blocked = !!ath_is_rfkill_set(priv);
980
981 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
982}
983
984void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv)
985{
986 if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
987 wiphy_rfkill_start_polling(priv->hw->wiphy);
988}
989
990/**********************/
991/* mac80211 Callbacks */
992/**********************/
993
994static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
995{
996 struct ieee80211_hdr *hdr;
997 struct ath9k_htc_priv *priv = hw->priv;
998 int padpos, padsize;
999
1000 hdr = (struct ieee80211_hdr *) skb->data;
1001
1002 /* Add the padding after the header if this is not already done */
1003 padpos = ath9k_cmn_padpos(hdr->frame_control);
1004 padsize = padpos & 3;
1005 if (padsize && skb->len > padpos) {
1006 if (skb_headroom(skb) < padsize)
1007 return -1;
1008 skb_push(skb, padsize);
1009 memmove(skb->data, skb->data + padsize, padpos);
1010 }
1011
1012 if (ath9k_htc_tx_start(priv, skb) != 0) {
1013 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, "Tx failed");
1014 goto fail_tx;
1015 }
1016
1017 return 0;
1018
1019fail_tx:
1020 dev_kfree_skb_any(skb);
1021 return 0;
1022}
1023
1024static int ath9k_htc_start(struct ieee80211_hw *hw)
1025{
1026 struct ath9k_htc_priv *priv = hw->priv;
1027 struct ath_hw *ah = priv->ah;
1028 struct ath_common *common = ath9k_hw_common(ah);
1029 struct ieee80211_channel *curchan = hw->conf.channel;
1030 struct ath9k_channel *init_channel;
1031 int ret = 0;
1032 enum htc_phymode mode;
1033 u16 htc_mode;
1034 u8 cmd_rsp;
1035
1036 ath_print(common, ATH_DBG_CONFIG,
1037 "Starting driver with initial channel: %d MHz\n",
1038 curchan->center_freq);
1039
1040 mutex_lock(&priv->mutex);
1041
1042 /* setup initial channel */
1043 init_channel = ath9k_cmn_get_curchannel(hw, ah);
1044
1045 /* Reset SERDES registers */
1046 ath9k_hw_configpcipowersave(ah, 0, 0);
1047
1048 ath9k_hw_htc_resetinit(ah);
1049 ret = ath9k_hw_reset(ah, init_channel, false);
1050 if (ret) {
1051 ath_print(common, ATH_DBG_FATAL,
1052 "Unable to reset hardware; reset status %d "
1053 "(freq %u MHz)\n", ret, curchan->center_freq);
1054 goto mutex_unlock;
1055 }
1056
1057 ath_update_txpow(priv);
1058
1059 mode = ath9k_htc_get_curmode(priv, init_channel);
1060 htc_mode = cpu_to_be16(mode);
1061 WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode);
1062 if (ret)
1063 goto mutex_unlock;
1064
1065 WMI_CMD(WMI_ATH_INIT_CMDID);
1066 if (ret)
1067 goto mutex_unlock;
1068
1069 WMI_CMD(WMI_START_RECV_CMDID);
1070 if (ret)
1071 goto mutex_unlock;
1072
1073 ath9k_host_rx_init(priv);
1074
1075 priv->op_flags &= ~OP_INVALID;
1076 htc_start(priv->htc);
1077
1078mutex_unlock:
1079 mutex_unlock(&priv->mutex);
1080 return ret;
1081}
1082
1083static void ath9k_htc_stop(struct ieee80211_hw *hw)
1084{
1085 struct ath9k_htc_priv *priv = hw->priv;
1086 struct ath_hw *ah = priv->ah;
1087 struct ath_common *common = ath9k_hw_common(ah);
1088 int ret = 0;
1089 u8 cmd_rsp;
1090
1091 mutex_lock(&priv->mutex);
1092
1093 if (priv->op_flags & OP_INVALID) {
1094 ath_print(common, ATH_DBG_ANY, "Device not present\n");
1095 mutex_unlock(&priv->mutex);
1096 return;
1097 }
1098
1099 htc_stop(priv->htc);
1100 WMI_CMD(WMI_DISABLE_INTR_CMDID);
1101 WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
1102 WMI_CMD(WMI_STOP_RECV_CMDID);
1103 ath9k_hw_phy_disable(ah);
1104 ath9k_hw_disable(ah);
1105 ath9k_hw_configpcipowersave(ah, 1, 1);
1106 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1107
1108 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1109 cancel_delayed_work_sync(&priv->ath9k_aggr_work);
1110 cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
1111 ath9k_led_stop_brightness(priv);
1112 skb_queue_purge(&priv->tx_queue);
1113
1114 /* Remove monitor interface here */
1115 if (ah->opmode == NL80211_IFTYPE_MONITOR) {
1116 if (ath9k_htc_remove_monitor_interface(priv))
1117 ath_print(common, ATH_DBG_FATAL,
1118 "Unable to remove monitor interface\n");
1119 else
1120 ath_print(common, ATH_DBG_CONFIG,
1121 "Monitor interface removed\n");
1122 }
1123
1124 priv->op_flags |= OP_INVALID;
1125 mutex_unlock(&priv->mutex);
1126
1127 ath_print(common, ATH_DBG_CONFIG, "Driver halt\n");
1128}
1129
1130static int ath9k_htc_add_interface(struct ieee80211_hw *hw,
1131 struct ieee80211_vif *vif)
1132{
1133 struct ath9k_htc_priv *priv = hw->priv;
1134 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1135 struct ath_common *common = ath9k_hw_common(priv->ah);
1136 struct ath9k_htc_target_vif hvif;
1137 int ret = 0;
1138 u8 cmd_rsp;
1139
1140 mutex_lock(&priv->mutex);
1141
1142 /* Only one interface for now */
1143 if (priv->nvifs > 0) {
1144 ret = -ENOBUFS;
1145 goto out;
1146 }
1147
1148 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1149 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1150
1151 switch (vif->type) {
1152 case NL80211_IFTYPE_STATION:
1153 hvif.opmode = cpu_to_be32(HTC_M_STA);
1154 break;
1155 case NL80211_IFTYPE_ADHOC:
1156 hvif.opmode = cpu_to_be32(HTC_M_IBSS);
1157 break;
1158 default:
1159 ath_print(common, ATH_DBG_FATAL,
1160 "Interface type %d not yet supported\n", vif->type);
1161 ret = -EOPNOTSUPP;
1162 goto out;
1163 }
1164
1165 ath_print(common, ATH_DBG_CONFIG,
1166 "Attach a VIF of type: %d\n", vif->type);
1167
1168 priv->ah->opmode = vif->type;
1169
1170 /* Index starts from zero on the target */
1171 avp->index = hvif.index = priv->nvifs;
1172 hvif.rtsthreshold = cpu_to_be16(2304);
1173 WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
1174 if (ret)
1175 goto out;
1176
1177 priv->nvifs++;
1178
1179 /*
1180 * We need a node in target to tx mgmt frames
1181 * before association.
1182 */
1183 ret = ath9k_htc_add_station(priv, vif, NULL);
1184 if (ret)
1185 goto out;
1186
1187 ret = ath9k_htc_update_cap_target(priv);
1188 if (ret)
1189 ath_print(common, ATH_DBG_CONFIG, "Failed to update"
1190 " capability in target \n");
1191
1192 priv->vif = vif;
1193out:
1194 mutex_unlock(&priv->mutex);
1195 return ret;
1196}
1197
1198static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
1199 struct ieee80211_vif *vif)
1200{
1201 struct ath9k_htc_priv *priv = hw->priv;
1202 struct ath_common *common = ath9k_hw_common(priv->ah);
1203 struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
1204 struct ath9k_htc_target_vif hvif;
1205 int ret = 0;
1206 u8 cmd_rsp;
1207
1208 ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n");
1209
1210 mutex_lock(&priv->mutex);
1211
1212 memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
1213 memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
1214 hvif.index = avp->index;
1215 WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
1216 priv->nvifs--;
1217
1218 ath9k_htc_remove_station(priv, vif, NULL);
1219
1220 if (vif->type == NL80211_IFTYPE_ADHOC) {
1221 spin_lock_bh(&priv->beacon_lock);
1222 if (priv->beacon)
1223 dev_kfree_skb_any(priv->beacon);
1224 priv->beacon = NULL;
1225 spin_unlock_bh(&priv->beacon_lock);
1226 }
1227
1228 priv->vif = NULL;
1229
1230 mutex_unlock(&priv->mutex);
1231}
1232
1233static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1234{
1235 struct ath9k_htc_priv *priv = hw->priv;
1236 struct ath_common *common = ath9k_hw_common(priv->ah);
1237 struct ieee80211_conf *conf = &hw->conf;
1238
1239 mutex_lock(&priv->mutex);
1240
1241 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
1242 struct ieee80211_channel *curchan = hw->conf.channel;
1243 int pos = curchan->hw_value;
1244 bool is_cw40 = false;
1245
1246 ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
1247 curchan->center_freq);
1248
1249 if (check_rc_update(hw, &is_cw40))
1250 ath9k_htc_rc_update(priv, is_cw40);
1251
1252 ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]);
1253
1254 if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) {
1255 ath_print(common, ATH_DBG_FATAL,
1256 "Unable to set channel\n");
1257 mutex_unlock(&priv->mutex);
1258 return -EINVAL;
1259 }
1260
1261 }
1262
1263 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1264 if (conf->flags & IEEE80211_CONF_MONITOR) {
1265 if (ath9k_htc_add_monitor_interface(priv))
1266 ath_print(common, ATH_DBG_FATAL,
1267 "Failed to set monitor mode\n");
1268 else
1269 ath_print(common, ATH_DBG_CONFIG,
1270 "HW opmode set to Monitor mode\n");
1271 }
1272 }
1273
1274 mutex_unlock(&priv->mutex);
1275
1276 return 0;
1277}
1278
1279#define SUPPORTED_FILTERS \
1280 (FIF_PROMISC_IN_BSS | \
1281 FIF_ALLMULTI | \
1282 FIF_CONTROL | \
1283 FIF_PSPOLL | \
1284 FIF_OTHER_BSS | \
1285 FIF_BCN_PRBRESP_PROMISC | \
1286 FIF_FCSFAIL)
1287
1288static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
1289 unsigned int changed_flags,
1290 unsigned int *total_flags,
1291 u64 multicast)
1292{
1293 struct ath9k_htc_priv *priv = hw->priv;
1294 u32 rfilt;
1295
1296 mutex_lock(&priv->mutex);
1297
1298 changed_flags &= SUPPORTED_FILTERS;
1299 *total_flags &= SUPPORTED_FILTERS;
1300
1301 priv->rxfilter = *total_flags;
1302 rfilt = ath9k_cmn_calcrxfilter(hw, priv->ah, priv->rxfilter);
1303 ath9k_hw_setrxfilter(priv->ah, rfilt);
1304
1305 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG,
1306 "Set HW RX filter: 0x%x\n", rfilt);
1307
1308 mutex_unlock(&priv->mutex);
1309}
1310
1311static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
1312 struct ieee80211_vif *vif,
1313 enum sta_notify_cmd cmd,
1314 struct ieee80211_sta *sta)
1315{
1316 struct ath9k_htc_priv *priv = hw->priv;
1317 int ret;
1318
1319 switch (cmd) {
1320 case STA_NOTIFY_ADD:
1321 ret = ath9k_htc_add_station(priv, vif, sta);
1322 if (!ret)
1323 ath9k_htc_init_rate(priv, vif, sta);
1324 break;
1325 case STA_NOTIFY_REMOVE:
1326 ath9k_htc_remove_station(priv, vif, sta);
1327 break;
1328 default:
1329 break;
1330 }
1331}
1332
1333static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
1334 const struct ieee80211_tx_queue_params *params)
1335{
1336 struct ath9k_htc_priv *priv = hw->priv;
1337 struct ath_common *common = ath9k_hw_common(priv->ah);
1338 struct ath9k_tx_queue_info qi;
1339 int ret = 0, qnum;
1340
1341 if (queue >= WME_NUM_AC)
1342 return 0;
1343
1344 mutex_lock(&priv->mutex);
1345
1346 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1347
1348 qi.tqi_aifs = params->aifs;
1349 qi.tqi_cwmin = params->cw_min;
1350 qi.tqi_cwmax = params->cw_max;
1351 qi.tqi_burstTime = params->txop;
1352
1353 qnum = get_hw_qnum(queue, priv->hwq_map);
1354
1355 ath_print(common, ATH_DBG_CONFIG,
1356 "Configure tx [queue/hwq] [%d/%d], "
1357 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1358 queue, qnum, params->aifs, params->cw_min,
1359 params->cw_max, params->txop);
1360
1361 ret = ath_txq_update(priv, qnum, &qi);
1362 if (ret)
1363 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1364
1365 mutex_unlock(&priv->mutex);
1366
1367 return ret;
1368}
1369
1370static int ath9k_htc_set_key(struct ieee80211_hw *hw,
1371 enum set_key_cmd cmd,
1372 struct ieee80211_vif *vif,
1373 struct ieee80211_sta *sta,
1374 struct ieee80211_key_conf *key)
1375{
1376 struct ath9k_htc_priv *priv = hw->priv;
1377 struct ath_common *common = ath9k_hw_common(priv->ah);
1378 int ret = 0;
1379
1380 if (modparam_nohwcrypt)
1381 return -ENOSPC;
1382
1383 mutex_lock(&priv->mutex);
1384 ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n");
1385
1386 switch (cmd) {
1387 case SET_KEY:
1388 ret = ath9k_cmn_key_config(common, vif, sta, key);
1389 if (ret >= 0) {
1390 key->hw_key_idx = ret;
1391 /* push IV and Michael MIC generation to stack */
1392 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1393 if (key->alg == ALG_TKIP)
1394 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1395 if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
1396 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
1397 ret = 0;
1398 }
1399 break;
1400 case DISABLE_KEY:
1401 ath9k_cmn_key_delete(common, key);
1402 break;
1403 default:
1404 ret = -EINVAL;
1405 }
1406
1407 mutex_unlock(&priv->mutex);
1408
1409 return ret;
1410}
1411
1412static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1413 struct ieee80211_vif *vif,
1414 struct ieee80211_bss_conf *bss_conf,
1415 u32 changed)
1416{
1417 struct ath9k_htc_priv *priv = hw->priv;
1418 struct ath_hw *ah = priv->ah;
1419 struct ath_common *common = ath9k_hw_common(ah);
1420
1421 mutex_lock(&priv->mutex);
1422
1423 if (changed & BSS_CHANGED_ASSOC) {
1424 common->curaid = bss_conf->assoc ?
1425 bss_conf->aid : 0;
1426 ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1427 bss_conf->assoc);
1428
1429 if (bss_conf->assoc) {
1430 priv->op_flags |= OP_ASSOCIATED;
1431 ath_start_ani(priv);
1432 } else {
1433 priv->op_flags &= ~OP_ASSOCIATED;
1434 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1435 }
1436 }
1437
1438 if (changed & BSS_CHANGED_BSSID) {
1439 /* Set BSSID */
1440 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1441 ath9k_hw_write_associd(ah);
1442
1443 ath_print(common, ATH_DBG_CONFIG,
1444 "BSSID: %pM aid: 0x%x\n",
1445 common->curbssid, common->curaid);
1446 }
1447
1448 if ((changed & BSS_CHANGED_BEACON_INT) ||
1449 (changed & BSS_CHANGED_BEACON) ||
1450 ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1451 bss_conf->enable_beacon)) {
1452 priv->op_flags |= OP_ENABLE_BEACON;
1453 ath9k_htc_beacon_config(priv, vif, bss_conf);
1454 }
1455
1456 if (changed & BSS_CHANGED_BEACON)
1457 ath9k_htc_beacon_update(priv, vif);
1458
1459 if ((changed & BSS_CHANGED_BEACON_ENABLED) &&
1460 !bss_conf->enable_beacon) {
1461 priv->op_flags &= ~OP_ENABLE_BEACON;
1462 ath9k_htc_beacon_config(priv, vif, bss_conf);
1463 }
1464
1465 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1466 ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
1467 bss_conf->use_short_preamble);
1468 if (bss_conf->use_short_preamble)
1469 priv->op_flags |= OP_PREAMBLE_SHORT;
1470 else
1471 priv->op_flags &= ~OP_PREAMBLE_SHORT;
1472 }
1473
1474 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1475 ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
1476 bss_conf->use_cts_prot);
1477 if (bss_conf->use_cts_prot &&
1478 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
1479 priv->op_flags |= OP_PROTECT_ENABLE;
1480 else
1481 priv->op_flags &= ~OP_PROTECT_ENABLE;
1482 }
1483
1484 if (changed & BSS_CHANGED_ERP_SLOT) {
1485 if (bss_conf->use_short_slot)
1486 ah->slottime = 9;
1487 else
1488 ah->slottime = 20;
1489
1490 ath9k_hw_init_global_settings(ah);
1491 }
1492
1493 mutex_unlock(&priv->mutex);
1494}
1495
1496static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw)
1497{
1498 struct ath9k_htc_priv *priv = hw->priv;
1499 u64 tsf;
1500
1501 mutex_lock(&priv->mutex);
1502 tsf = ath9k_hw_gettsf64(priv->ah);
1503 mutex_unlock(&priv->mutex);
1504
1505 return tsf;
1506}
1507
1508static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf)
1509{
1510 struct ath9k_htc_priv *priv = hw->priv;
1511
1512 mutex_lock(&priv->mutex);
1513 ath9k_hw_settsf64(priv->ah, tsf);
1514 mutex_unlock(&priv->mutex);
1515}
1516
1517static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw)
1518{
1519 struct ath9k_htc_priv *priv = hw->priv;
1520
1521 mutex_lock(&priv->mutex);
1522 ath9k_hw_reset_tsf(priv->ah);
1523 mutex_unlock(&priv->mutex);
1524}
1525
1526static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
1527 struct ieee80211_vif *vif,
1528 enum ieee80211_ampdu_mlme_action action,
1529 struct ieee80211_sta *sta,
1530 u16 tid, u16 *ssn)
1531{
1532 struct ath9k_htc_priv *priv = hw->priv;
1533 struct ath9k_htc_aggr_work *work = &priv->aggr_work;
1534 struct ath9k_htc_sta *ista;
1535
1536 switch (action) {
1537 case IEEE80211_AMPDU_RX_START:
1538 break;
1539 case IEEE80211_AMPDU_RX_STOP:
1540 break;
1541 case IEEE80211_AMPDU_TX_START:
1542 case IEEE80211_AMPDU_TX_STOP:
1543 if (!(priv->op_flags & OP_TXAGGR))
1544 return -ENOTSUPP;
1545 memcpy(work->sta_addr, sta->addr, ETH_ALEN);
1546 work->hw = hw;
1547 work->vif = vif;
1548 work->action = action;
1549 work->tid = tid;
1550 ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
1551 break;
1552 case IEEE80211_AMPDU_TX_OPERATIONAL:
1553 ista = (struct ath9k_htc_sta *) sta->drv_priv;
1554 ista->tid_state[tid] = AGGR_OPERATIONAL;
1555 break;
1556 default:
1557 ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
1558 "Unknown AMPDU action\n");
1559 }
1560
1561 return 0;
1562}
1563
1564static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
1565{
1566 struct ath9k_htc_priv *priv = hw->priv;
1567
1568 mutex_lock(&priv->mutex);
1569 spin_lock_bh(&priv->beacon_lock);
1570 priv->op_flags |= OP_SCANNING;
1571 spin_unlock_bh(&priv->beacon_lock);
1572 cancel_delayed_work_sync(&priv->ath9k_ani_work);
1573 mutex_unlock(&priv->mutex);
1574}
1575
1576static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw)
1577{
1578 struct ath9k_htc_priv *priv = hw->priv;
1579
1580 mutex_lock(&priv->mutex);
1581 spin_lock_bh(&priv->beacon_lock);
1582 priv->op_flags &= ~OP_SCANNING;
1583 spin_unlock_bh(&priv->beacon_lock);
1584 priv->op_flags |= OP_FULL_RESET;
1585 ath_start_ani(priv);
1586 mutex_unlock(&priv->mutex);
1587}
1588
1589static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1590{
1591 return 0;
1592}
1593
1594static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1595 u8 coverage_class)
1596{
1597 struct ath9k_htc_priv *priv = hw->priv;
1598
1599 mutex_lock(&priv->mutex);
1600 priv->ah->coverage_class = coverage_class;
1601 ath9k_hw_init_global_settings(priv->ah);
1602 mutex_unlock(&priv->mutex);
1603}
1604
1605struct ieee80211_ops ath9k_htc_ops = {
1606 .tx = ath9k_htc_tx,
1607 .start = ath9k_htc_start,
1608 .stop = ath9k_htc_stop,
1609 .add_interface = ath9k_htc_add_interface,
1610 .remove_interface = ath9k_htc_remove_interface,
1611 .config = ath9k_htc_config,
1612 .configure_filter = ath9k_htc_configure_filter,
1613 .sta_notify = ath9k_htc_sta_notify,
1614 .conf_tx = ath9k_htc_conf_tx,
1615 .bss_info_changed = ath9k_htc_bss_info_changed,
1616 .set_key = ath9k_htc_set_key,
1617 .get_tsf = ath9k_htc_get_tsf,
1618 .set_tsf = ath9k_htc_set_tsf,
1619 .reset_tsf = ath9k_htc_reset_tsf,
1620 .ampdu_action = ath9k_htc_ampdu_action,
1621 .sw_scan_start = ath9k_htc_sw_scan_start,
1622 .sw_scan_complete = ath9k_htc_sw_scan_complete,
1623 .set_rts_threshold = ath9k_htc_set_rts_threshold,
1624 .rfkill_poll = ath9k_htc_rfkill_poll_state,
1625 .set_coverage_class = ath9k_htc_set_coverage_class,
1626};
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
new file mode 100644
index 000000000000..dba22d3f87c3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -0,0 +1,604 @@
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/******/
20/* TX */
21/******/
22
23int get_hw_qnum(u16 queue, int *hwq_map)
24{
25 switch (queue) {
26 case 0:
27 return hwq_map[ATH9K_WME_AC_VO];
28 case 1:
29 return hwq_map[ATH9K_WME_AC_VI];
30 case 2:
31 return hwq_map[ATH9K_WME_AC_BE];
32 case 3:
33 return hwq_map[ATH9K_WME_AC_BK];
34 default:
35 return hwq_map[ATH9K_WME_AC_BE];
36 }
37}
38
39int ath_txq_update(struct ath9k_htc_priv *priv, int qnum,
40 struct ath9k_tx_queue_info *qinfo)
41{
42 struct ath_hw *ah = priv->ah;
43 int error = 0;
44 struct ath9k_tx_queue_info qi;
45
46 ath9k_hw_get_txq_props(ah, qnum, &qi);
47
48 qi.tqi_aifs = qinfo->tqi_aifs;
49 qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */
50 qi.tqi_cwmax = qinfo->tqi_cwmax;
51 qi.tqi_burstTime = qinfo->tqi_burstTime;
52 qi.tqi_readyTime = qinfo->tqi_readyTime;
53
54 if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
55 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL,
56 "Unable to update hardware queue %u!\n", qnum);
57 error = -EIO;
58 } else {
59 ath9k_hw_resettxqueue(ah, qnum);
60 }
61
62 return error;
63}
64
65int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
66{
67 struct ieee80211_hdr *hdr;
68 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
69 struct ieee80211_sta *sta = tx_info->control.sta;
70 struct ath9k_htc_sta *ista;
71 struct ath9k_htc_vif *avp;
72 struct ath9k_htc_tx_ctl tx_ctl;
73 enum htc_endpoint_id epid;
74 u16 qnum, hw_qnum;
75 __le16 fc;
76 u8 *tx_fhdr;
77 u8 sta_idx;
78
79 hdr = (struct ieee80211_hdr *) skb->data;
80 fc = hdr->frame_control;
81
82 avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv;
83 if (sta) {
84 ista = (struct ath9k_htc_sta *) sta->drv_priv;
85 sta_idx = ista->index;
86 } else {
87 sta_idx = 0;
88 }
89
90 memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
91
92 if (ieee80211_is_data(fc)) {
93 struct tx_frame_hdr tx_hdr;
94 u8 *qc;
95
96 memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
97
98 tx_hdr.node_idx = sta_idx;
99 tx_hdr.vif_idx = avp->index;
100
101 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
102 tx_ctl.type = ATH9K_HTC_AMPDU;
103 tx_hdr.data_type = ATH9K_HTC_AMPDU;
104 } else {
105 tx_ctl.type = ATH9K_HTC_NORMAL;
106 tx_hdr.data_type = ATH9K_HTC_NORMAL;
107 }
108
109 if (ieee80211_is_data(fc)) {
110 qc = ieee80211_get_qos_ctl(hdr);
111 tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
112 }
113
114 /* Check for RTS protection */
115 if (priv->hw->wiphy->rts_threshold != (u32) -1)
116 if (skb->len > priv->hw->wiphy->rts_threshold)
117 tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS;
118
119 /* CTS-to-self */
120 if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) &&
121 (priv->op_flags & OP_PROTECT_ENABLE))
122 tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY;
123
124 tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
125 if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
126 tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
127 else
128 tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
129
130 tx_fhdr = skb_push(skb, sizeof(tx_hdr));
131 memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
132
133 qnum = skb_get_queue_mapping(skb);
134 hw_qnum = get_hw_qnum(qnum, priv->hwq_map);
135
136 switch (hw_qnum) {
137 case 0:
138 epid = priv->data_be_ep;
139 break;
140 case 2:
141 epid = priv->data_vi_ep;
142 break;
143 case 3:
144 epid = priv->data_vo_ep;
145 break;
146 case 1:
147 default:
148 epid = priv->data_bk_ep;
149 break;
150 }
151 } else {
152 struct tx_mgmt_hdr mgmt_hdr;
153
154 memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
155
156 tx_ctl.type = ATH9K_HTC_NORMAL;
157
158 mgmt_hdr.node_idx = sta_idx;
159 mgmt_hdr.vif_idx = avp->index;
160 mgmt_hdr.tidno = 0;
161 mgmt_hdr.flags = 0;
162
163 mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
164 if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
165 mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
166 else
167 mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
168
169 tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
170 memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
171 epid = priv->mgmt_ep;
172 }
173
174 return htc_send(priv->htc, skb, epid, &tx_ctl);
175}
176
177void ath9k_tx_tasklet(unsigned long data)
178{
179 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
180 struct ieee80211_sta *sta;
181 struct ieee80211_hdr *hdr;
182 struct ieee80211_tx_info *tx_info;
183 struct sk_buff *skb = NULL;
184 __le16 fc;
185
186 while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
187
188 hdr = (struct ieee80211_hdr *) skb->data;
189 fc = hdr->frame_control;
190 tx_info = IEEE80211_SKB_CB(skb);
191 sta = tx_info->control.sta;
192
193 rcu_read_lock();
194
195 if (sta && conf_is_ht(&priv->hw->conf) &&
196 (priv->op_flags & OP_TXAGGR)
197 && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
198 if (ieee80211_is_data_qos(fc)) {
199 u8 *qc, tid;
200 struct ath9k_htc_sta *ista;
201
202 qc = ieee80211_get_qos_ctl(hdr);
203 tid = qc[0] & 0xf;
204 ista = (struct ath9k_htc_sta *)sta->drv_priv;
205
206 if ((tid < ATH9K_HTC_MAX_TID) &&
207 ista->tid_state[tid] == AGGR_STOP) {
208 ieee80211_start_tx_ba_session(sta, tid);
209 ista->tid_state[tid] = AGGR_PROGRESS;
210 }
211 }
212 }
213
214 rcu_read_unlock();
215
216 memset(&tx_info->status, 0, sizeof(tx_info->status));
217 ieee80211_tx_status(priv->hw, skb);
218 }
219}
220
221void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
222 enum htc_endpoint_id ep_id, bool txok)
223{
224 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
225 struct ieee80211_tx_info *tx_info;
226
227 if (!skb)
228 return;
229
230 if (ep_id == priv->mgmt_ep)
231 skb_pull(skb, sizeof(struct tx_mgmt_hdr));
232 else
233 /* TODO: Check for cab/uapsd/data */
234 skb_pull(skb, sizeof(struct tx_frame_hdr));
235
236 tx_info = IEEE80211_SKB_CB(skb);
237
238 if (txok)
239 tx_info->flags |= IEEE80211_TX_STAT_ACK;
240
241 skb_queue_tail(&priv->tx_queue, skb);
242 tasklet_schedule(&priv->tx_tasklet);
243}
244
245int ath9k_tx_init(struct ath9k_htc_priv *priv)
246{
247 skb_queue_head_init(&priv->tx_queue);
248 return 0;
249}
250
251void ath9k_tx_cleanup(struct ath9k_htc_priv *priv)
252{
253
254}
255
256bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv,
257 enum ath9k_tx_queue_subtype subtype)
258{
259 struct ath_hw *ah = priv->ah;
260 struct ath_common *common = ath9k_hw_common(ah);
261 struct ath9k_tx_queue_info qi;
262 int qnum;
263
264 memset(&qi, 0, sizeof(qi));
265
266 qi.tqi_subtype = subtype;
267 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
268 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
269 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
270 qi.tqi_physCompBuf = 0;
271 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE;
272
273 qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi);
274 if (qnum == -1)
275 return false;
276
277 if (qnum >= ARRAY_SIZE(priv->hwq_map)) {
278 ath_print(common, ATH_DBG_FATAL,
279 "qnum %u out of range, max %u!\n",
280 qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map));
281 ath9k_hw_releasetxqueue(ah, qnum);
282 return false;
283 }
284
285 priv->hwq_map[subtype] = qnum;
286 return true;
287}
288
289/******/
290/* RX */
291/******/
292
293void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
294{
295 ath9k_hw_rxena(priv->ah);
296 ath9k_cmn_opmode_init(priv->hw, priv->ah, priv->rxfilter);
297 ath9k_hw_startpcureceive(priv->ah);
298 priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER;
299}
300
301static void ath9k_process_rate(struct ieee80211_hw *hw,
302 struct ieee80211_rx_status *rxs,
303 u8 rx_rate, u8 rs_flags)
304{
305 struct ieee80211_supported_band *sband;
306 enum ieee80211_band band;
307 unsigned int i = 0;
308
309 if (rx_rate & 0x80) {
310 /* HT rate */
311 rxs->flag |= RX_FLAG_HT;
312 if (rs_flags & ATH9K_RX_2040)
313 rxs->flag |= RX_FLAG_40MHZ;
314 if (rs_flags & ATH9K_RX_GI)
315 rxs->flag |= RX_FLAG_SHORT_GI;
316 rxs->rate_idx = rx_rate & 0x7f;
317 return;
318 }
319
320 band = hw->conf.channel->band;
321 sband = hw->wiphy->bands[band];
322
323 for (i = 0; i < sband->n_bitrates; i++) {
324 if (sband->bitrates[i].hw_value == rx_rate) {
325 rxs->rate_idx = i;
326 return;
327 }
328 if (sband->bitrates[i].hw_value_short == rx_rate) {
329 rxs->rate_idx = i;
330 rxs->flag |= RX_FLAG_SHORTPRE;
331 return;
332 }
333 }
334
335}
336
337static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
338 struct ath9k_htc_rxbuf *rxbuf,
339 struct ieee80211_rx_status *rx_status)
340
341{
342 struct ieee80211_hdr *hdr;
343 struct ieee80211_hw *hw = priv->hw;
344 struct sk_buff *skb = rxbuf->skb;
345 struct ath_common *common = ath9k_hw_common(priv->ah);
346 int hdrlen, padpos, padsize;
347 int last_rssi = ATH_RSSI_DUMMY_MARKER;
348 __le16 fc;
349
350 hdr = (struct ieee80211_hdr *)skb->data;
351 fc = hdr->frame_control;
352 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
353
354 padpos = ath9k_cmn_padpos(fc);
355
356 padsize = padpos & 3;
357 if (padsize && skb->len >= padpos+padsize) {
358 memmove(skb->data + padsize, skb->data, padpos);
359 skb_pull(skb, padsize);
360 }
361
362 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
363
364 if (rxbuf->rxstatus.rs_status != 0) {
365 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC)
366 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
367 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY)
368 goto rx_next;
369
370 if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) {
371 /* FIXME */
372 } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) {
373 if (ieee80211_is_ctl(fc))
374 /*
375 * Sometimes, we get invalid
376 * MIC failures on valid control frames.
377 * Remove these mic errors.
378 */
379 rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC;
380 else
381 rx_status->flag |= RX_FLAG_MMIC_ERROR;
382 }
383
384 /*
385 * Reject error frames with the exception of
386 * decryption and MIC failures. For monitor mode,
387 * we also ignore the CRC error.
388 */
389 if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) {
390 if (rxbuf->rxstatus.rs_status &
391 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
392 ATH9K_RXERR_CRC))
393 goto rx_next;
394 } else {
395 if (rxbuf->rxstatus.rs_status &
396 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
397 goto rx_next;
398 }
399 }
400 }
401
402 if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) {
403 u8 keyix;
404 keyix = rxbuf->rxstatus.rs_keyix;
405 if (keyix != ATH9K_RXKEYIX_INVALID) {
406 rx_status->flag |= RX_FLAG_DECRYPTED;
407 } else if (ieee80211_has_protected(fc) &&
408 skb->len >= hdrlen + 4) {
409 keyix = skb->data[hdrlen + 3] >> 6;
410 if (test_bit(keyix, common->keymap))
411 rx_status->flag |= RX_FLAG_DECRYPTED;
412 }
413 }
414
415 ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate,
416 rxbuf->rxstatus.rs_flags);
417
418 if (priv->op_flags & OP_ASSOCIATED) {
419 if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD &&
420 !rxbuf->rxstatus.rs_moreaggr)
421 ATH_RSSI_LPF(priv->rx.last_rssi,
422 rxbuf->rxstatus.rs_rssi);
423
424 last_rssi = priv->rx.last_rssi;
425
426 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
427 rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi,
428 ATH_RSSI_EP_MULTIPLIER);
429
430 if (rxbuf->rxstatus.rs_rssi < 0)
431 rxbuf->rxstatus.rs_rssi = 0;
432
433 if (ieee80211_is_beacon(fc))
434 priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi;
435 }
436
437 rx_status->mactime = rxbuf->rxstatus.rs_tstamp;
438 rx_status->band = hw->conf.channel->band;
439 rx_status->freq = hw->conf.channel->center_freq;
440 rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
441 rx_status->antenna = rxbuf->rxstatus.rs_antenna;
442 rx_status->flag |= RX_FLAG_TSFT;
443
444 return true;
445
446rx_next:
447 return false;
448}
449
450/*
451 * FIXME: Handle FLUSH later on.
452 */
453void ath9k_rx_tasklet(unsigned long data)
454{
455 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
456 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
457 struct ieee80211_rx_status rx_status;
458 struct sk_buff *skb;
459 unsigned long flags;
460
461
462 do {
463 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
464 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
465 if (tmp_buf->in_process) {
466 rxbuf = tmp_buf;
467 break;
468 }
469 }
470
471 if (rxbuf == NULL) {
472 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
473 break;
474 }
475
476 if (!rxbuf->skb)
477 goto requeue;
478
479 if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) {
480 dev_kfree_skb_any(rxbuf->skb);
481 goto requeue;
482 }
483
484 memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status,
485 sizeof(struct ieee80211_rx_status));
486 skb = rxbuf->skb;
487 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
488
489 ieee80211_rx(priv->hw, skb);
490
491 spin_lock_irqsave(&priv->rx.rxbuflock, flags);
492requeue:
493 rxbuf->in_process = false;
494 rxbuf->skb = NULL;
495 list_move_tail(&rxbuf->list, &priv->rx.rxbuf);
496 rxbuf = NULL;
497 spin_unlock_irqrestore(&priv->rx.rxbuflock, flags);
498 } while (1);
499
500}
501
502void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb,
503 enum htc_endpoint_id ep_id)
504{
505 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv;
506 struct ath_hw *ah = priv->ah;
507 struct ath_common *common = ath9k_hw_common(ah);
508 struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL;
509 struct ath_htc_rx_status *rxstatus;
510 u32 len = 0;
511
512 spin_lock(&priv->rx.rxbuflock);
513 list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) {
514 if (!tmp_buf->in_process) {
515 rxbuf = tmp_buf;
516 break;
517 }
518 }
519 spin_unlock(&priv->rx.rxbuflock);
520
521 if (rxbuf == NULL) {
522 ath_print(common, ATH_DBG_ANY,
523 "No free RX buffer\n");
524 goto err;
525 }
526
527 len = skb->len;
528 if (len <= HTC_RX_FRAME_HEADER_SIZE) {
529 ath_print(common, ATH_DBG_FATAL,
530 "Corrupted RX frame, dropping\n");
531 goto err;
532 }
533
534 rxstatus = (struct ath_htc_rx_status *)skb->data;
535
536 rxstatus->rs_tstamp = be64_to_cpu(rxstatus->rs_tstamp);
537 rxstatus->rs_datalen = be16_to_cpu(rxstatus->rs_datalen);
538 rxstatus->evm0 = be32_to_cpu(rxstatus->evm0);
539 rxstatus->evm1 = be32_to_cpu(rxstatus->evm1);
540 rxstatus->evm2 = be32_to_cpu(rxstatus->evm2);
541
542 if (rxstatus->rs_datalen - (len - HTC_RX_FRAME_HEADER_SIZE) != 0) {
543 ath_print(common, ATH_DBG_FATAL,
544 "Corrupted RX data len, dropping "
545 "(epid: %d, dlen: %d, skblen: %d)\n",
546 ep_id, rxstatus->rs_datalen, len);
547 goto err;
548 }
549
550 spin_lock(&priv->rx.rxbuflock);
551 memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
552 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
553 skb->len = rxstatus->rs_datalen;
554 rxbuf->skb = skb;
555 rxbuf->in_process = true;
556 spin_unlock(&priv->rx.rxbuflock);
557
558 tasklet_schedule(&priv->rx_tasklet);
559 return;
560err:
561 dev_kfree_skb_any(skb);
562 return;
563}
564
565/* FIXME: Locking for cleanup/init */
566
567void ath9k_rx_cleanup(struct ath9k_htc_priv *priv)
568{
569 struct ath9k_htc_rxbuf *rxbuf, *tbuf;
570
571 list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) {
572 list_del(&rxbuf->list);
573 if (rxbuf->skb)
574 dev_kfree_skb_any(rxbuf->skb);
575 kfree(rxbuf);
576 }
577}
578
579int ath9k_rx_init(struct ath9k_htc_priv *priv)
580{
581 struct ath_hw *ah = priv->ah;
582 struct ath_common *common = ath9k_hw_common(ah);
583 struct ath9k_htc_rxbuf *rxbuf;
584 int i = 0;
585
586 INIT_LIST_HEAD(&priv->rx.rxbuf);
587 spin_lock_init(&priv->rx.rxbuflock);
588
589 for (i = 0; i < ATH9K_HTC_RXBUF; i++) {
590 rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL);
591 if (rxbuf == NULL) {
592 ath_print(common, ATH_DBG_FATAL,
593 "Unable to allocate RX buffers\n");
594 goto err;
595 }
596 list_add_tail(&rxbuf->list, &priv->rx.rxbuf);
597 }
598
599 return 0;
600
601err:
602 ath9k_rx_cleanup(priv);
603 return -ENOMEM;
604}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c
new file mode 100644
index 000000000000..9a48999d0979
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.c
@@ -0,0 +1,463 @@
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
19static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
20 u16 len, u8 flags, u8 epid,
21 struct ath9k_htc_tx_ctl *tx_ctl)
22{
23 struct htc_frame_hdr *hdr;
24 struct htc_endpoint *endpoint = &target->endpoint[epid];
25 int status;
26
27 hdr = (struct htc_frame_hdr *)
28 skb_push(skb, sizeof(struct htc_frame_hdr));
29 hdr->endpoint_id = epid;
30 hdr->flags = flags;
31 hdr->payload_len = cpu_to_be16(len);
32
33 status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
34 tx_ctl);
35 return status;
36}
37
38static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
39{
40 enum htc_endpoint_id avail_epid;
41
42 for (avail_epid = ENDPOINT_MAX; avail_epid > ENDPOINT0; avail_epid--)
43 if (endpoint[avail_epid].service_id == 0)
44 return &endpoint[avail_epid];
45 return NULL;
46}
47
48static u8 service_to_ulpipe(u16 service_id)
49{
50 switch (service_id) {
51 case WMI_CONTROL_SVC:
52 return 4;
53 case WMI_BEACON_SVC:
54 case WMI_CAB_SVC:
55 case WMI_UAPSD_SVC:
56 case WMI_MGMT_SVC:
57 case WMI_DATA_VO_SVC:
58 case WMI_DATA_VI_SVC:
59 case WMI_DATA_BE_SVC:
60 case WMI_DATA_BK_SVC:
61 return 1;
62 default:
63 return 0;
64 }
65}
66
67static u8 service_to_dlpipe(u16 service_id)
68{
69 switch (service_id) {
70 case WMI_CONTROL_SVC:
71 return 3;
72 case WMI_BEACON_SVC:
73 case WMI_CAB_SVC:
74 case WMI_UAPSD_SVC:
75 case WMI_MGMT_SVC:
76 case WMI_DATA_VO_SVC:
77 case WMI_DATA_VI_SVC:
78 case WMI_DATA_BE_SVC:
79 case WMI_DATA_BK_SVC:
80 return 2;
81 default:
82 return 0;
83 }
84}
85
86static void htc_process_target_rdy(struct htc_target *target,
87 void *buf)
88{
89 struct htc_endpoint *endpoint;
90 struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf;
91
92 target->credits = be16_to_cpu(htc_ready_msg->credits);
93 target->credit_size = be16_to_cpu(htc_ready_msg->credit_size);
94
95 endpoint = &target->endpoint[ENDPOINT0];
96 endpoint->service_id = HTC_CTRL_RSVD_SVC;
97 endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
98 complete(&target->target_wait);
99}
100
101static void htc_process_conn_rsp(struct htc_target *target,
102 struct htc_frame_hdr *htc_hdr)
103{
104 struct htc_conn_svc_rspmsg *svc_rspmsg;
105 struct htc_endpoint *endpoint, *tmp_endpoint = NULL;
106 u16 service_id;
107 u16 max_msglen;
108 enum htc_endpoint_id epid, tepid;
109
110 svc_rspmsg = (struct htc_conn_svc_rspmsg *)
111 ((void *) htc_hdr + sizeof(struct htc_frame_hdr));
112
113 if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) {
114 epid = svc_rspmsg->endpoint_id;
115 service_id = be16_to_cpu(svc_rspmsg->service_id);
116 max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
117 endpoint = &target->endpoint[epid];
118
119 for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
120 tmp_endpoint = &target->endpoint[tepid];
121 if (tmp_endpoint->service_id == service_id) {
122 tmp_endpoint->service_id = 0;
123 break;
124 }
125 }
126
127 if (!tmp_endpoint)
128 return;
129
130 endpoint->service_id = service_id;
131 endpoint->max_txqdepth = tmp_endpoint->max_txqdepth;
132 endpoint->ep_callbacks = tmp_endpoint->ep_callbacks;
133 endpoint->ul_pipeid = tmp_endpoint->ul_pipeid;
134 endpoint->dl_pipeid = tmp_endpoint->dl_pipeid;
135 endpoint->max_msglen = max_msglen;
136 target->conn_rsp_epid = epid;
137 complete(&target->cmd_wait);
138 } else {
139 target->conn_rsp_epid = ENDPOINT_UNUSED;
140 }
141}
142
143static int htc_config_pipe_credits(struct htc_target *target)
144{
145 struct sk_buff *skb;
146 struct htc_config_pipe_msg *cp_msg;
147 int ret, time_left;
148
149 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
150 if (!skb) {
151 dev_err(target->dev, "failed to allocate send buffer\n");
152 return -ENOMEM;
153 }
154 skb_reserve(skb, sizeof(struct htc_frame_hdr));
155
156 cp_msg = (struct htc_config_pipe_msg *)
157 skb_put(skb, sizeof(struct htc_config_pipe_msg));
158
159 cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID);
160 cp_msg->pipe_id = USB_WLAN_TX_PIPE;
161 cp_msg->credits = 28;
162
163 target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
164
165 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
166 if (ret)
167 goto err;
168
169 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
170 if (!time_left) {
171 dev_err(target->dev, "HTC credit config timeout\n");
172 return -ETIMEDOUT;
173 }
174
175 return 0;
176err:
177 dev_kfree_skb(skb);
178 return -EINVAL;
179}
180
181static int htc_setup_complete(struct htc_target *target)
182{
183 struct sk_buff *skb;
184 struct htc_comp_msg *comp_msg;
185 int ret = 0, time_left;
186
187 skb = dev_alloc_skb(50 + sizeof(struct htc_frame_hdr));
188 if (!skb) {
189 dev_err(target->dev, "failed to allocate send buffer\n");
190 return -ENOMEM;
191 }
192 skb_reserve(skb, sizeof(struct htc_frame_hdr));
193
194 comp_msg = (struct htc_comp_msg *)
195 skb_put(skb, sizeof(struct htc_comp_msg));
196 comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID);
197
198 target->htc_flags |= HTC_OP_START_WAIT;
199
200 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
201 if (ret)
202 goto err;
203
204 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
205 if (!time_left) {
206 dev_err(target->dev, "HTC start timeout\n");
207 return -ETIMEDOUT;
208 }
209
210 return 0;
211
212err:
213 dev_kfree_skb(skb);
214 return -EINVAL;
215}
216
217/* HTC APIs */
218
219int htc_init(struct htc_target *target)
220{
221 int ret;
222
223 ret = htc_config_pipe_credits(target);
224 if (ret)
225 return ret;
226
227 return htc_setup_complete(target);
228}
229
230int htc_connect_service(struct htc_target *target,
231 struct htc_service_connreq *service_connreq,
232 enum htc_endpoint_id *conn_rsp_epid)
233{
234 struct sk_buff *skb;
235 struct htc_endpoint *endpoint;
236 struct htc_conn_svc_msg *conn_msg;
237 int ret, time_left;
238
239 /* Find an available endpoint */
240 endpoint = get_next_avail_ep(target->endpoint);
241 if (!endpoint) {
242 dev_err(target->dev, "Endpoint is not available for"
243 "service %d\n", service_connreq->service_id);
244 return -EINVAL;
245 }
246
247 endpoint->service_id = service_connreq->service_id;
248 endpoint->max_txqdepth = service_connreq->max_send_qdepth;
249 endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id);
250 endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id);
251 endpoint->ep_callbacks = service_connreq->ep_callbacks;
252
253 skb = dev_alloc_skb(sizeof(struct htc_conn_svc_msg) +
254 sizeof(struct htc_frame_hdr));
255 if (!skb) {
256 dev_err(target->dev, "Failed to allocate buf to send"
257 "service connect req\n");
258 return -ENOMEM;
259 }
260
261 skb_reserve(skb, sizeof(struct htc_frame_hdr));
262
263 conn_msg = (struct htc_conn_svc_msg *)
264 skb_put(skb, sizeof(struct htc_conn_svc_msg));
265 conn_msg->service_id = cpu_to_be16(service_connreq->service_id);
266 conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID);
267 conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags);
268 conn_msg->dl_pipeid = endpoint->dl_pipeid;
269 conn_msg->ul_pipeid = endpoint->ul_pipeid;
270
271 ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
272 if (ret)
273 goto err;
274
275 time_left = wait_for_completion_timeout(&target->cmd_wait, HZ);
276 if (!time_left) {
277 dev_err(target->dev, "Service connection timeout for: %d\n",
278 service_connreq->service_id);
279 return -ETIMEDOUT;
280 }
281
282 *conn_rsp_epid = target->conn_rsp_epid;
283 return 0;
284err:
285 dev_kfree_skb(skb);
286 return ret;
287}
288
289int htc_send(struct htc_target *target, struct sk_buff *skb,
290 enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
291{
292 return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
293}
294
295void htc_stop(struct htc_target *target)
296{
297 enum htc_endpoint_id epid;
298 struct htc_endpoint *endpoint;
299
300 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
301 endpoint = &target->endpoint[epid];
302 if (endpoint->service_id != 0)
303 target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
304 }
305}
306
307void htc_start(struct htc_target *target)
308{
309 enum htc_endpoint_id epid;
310 struct htc_endpoint *endpoint;
311
312 for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
313 endpoint = &target->endpoint[epid];
314 if (endpoint->service_id != 0)
315 target->hif->start(target->hif_dev,
316 endpoint->ul_pipeid);
317 }
318}
319
320void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
321 struct sk_buff *skb, bool txok)
322{
323 struct htc_endpoint *endpoint;
324 struct htc_frame_hdr *htc_hdr;
325
326 if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) {
327 complete(&htc_handle->cmd_wait);
328 htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS;
329 }
330
331 if (htc_handle->htc_flags & HTC_OP_START_WAIT) {
332 complete(&htc_handle->cmd_wait);
333 htc_handle->htc_flags &= ~HTC_OP_START_WAIT;
334 }
335
336 if (skb) {
337 htc_hdr = (struct htc_frame_hdr *) skb->data;
338 endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id];
339 skb_pull(skb, sizeof(struct htc_frame_hdr));
340
341 if (endpoint->ep_callbacks.tx) {
342 endpoint->ep_callbacks.tx(htc_handle->drv_priv, skb,
343 htc_hdr->endpoint_id, txok);
344 }
345 }
346}
347
348/*
349 * HTC Messages are handled directly here and the obtained SKB
350 * is freed.
351 *
352 * Sevice messages (Data, WMI) passed to the corresponding
353 * endpoint RX handlers, which have to free the SKB.
354 */
355void ath9k_htc_rx_msg(struct htc_target *htc_handle,
356 struct sk_buff *skb, u32 len, u8 pipe_id)
357{
358 struct htc_frame_hdr *htc_hdr;
359 enum htc_endpoint_id epid;
360 struct htc_endpoint *endpoint;
361 u16 *msg_id;
362
363 if (!htc_handle || !skb)
364 return;
365
366 htc_hdr = (struct htc_frame_hdr *) skb->data;
367 epid = htc_hdr->endpoint_id;
368
369 if (epid >= ENDPOINT_MAX) {
370 dev_kfree_skb_any(skb);
371 return;
372 }
373
374 if (epid == ENDPOINT0) {
375
376 /* Handle trailer */
377 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) {
378 if (be32_to_cpu(*(u32 *) skb->data) == 0x00C60000)
379 /* Move past the Watchdog pattern */
380 htc_hdr = (struct htc_frame_hdr *) skb->data + 4;
381 }
382
383 /* Get the message ID */
384 msg_id = (u16 *) ((void *) htc_hdr +
385 sizeof(struct htc_frame_hdr));
386
387 /* Now process HTC messages */
388 switch (be16_to_cpu(*msg_id)) {
389 case HTC_MSG_READY_ID:
390 htc_process_target_rdy(htc_handle, htc_hdr);
391 break;
392 case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID:
393 htc_process_conn_rsp(htc_handle, htc_hdr);
394 break;
395 default:
396 break;
397 }
398
399 dev_kfree_skb_any(skb);
400
401 } else {
402 if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER)
403 skb_trim(skb, len - htc_hdr->control[0]);
404
405 skb_pull(skb, sizeof(struct htc_frame_hdr));
406
407 endpoint = &htc_handle->endpoint[epid];
408 if (endpoint->ep_callbacks.rx)
409 endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv,
410 skb, epid);
411 }
412}
413
414struct htc_target *ath9k_htc_hw_alloc(void *hif_handle)
415{
416 struct htc_target *target;
417
418 target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
419 if (!target)
420 printk(KERN_ERR "Unable to allocate memory for"
421 "target device\n");
422
423 return target;
424}
425
426void ath9k_htc_hw_free(struct htc_target *htc)
427{
428 kfree(htc);
429}
430
431int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
432 void *hif_handle, struct device *dev, u16 devid,
433 enum ath9k_hif_transports transport)
434{
435 struct htc_endpoint *endpoint;
436 int err = 0;
437
438 init_completion(&target->target_wait);
439 init_completion(&target->cmd_wait);
440
441 target->hif = hif;
442 target->hif_dev = hif_handle;
443 target->dev = dev;
444
445 /* Assign control endpoint pipe IDs */
446 endpoint = &target->endpoint[ENDPOINT0];
447 endpoint->ul_pipeid = hif->control_ul_pipe;
448 endpoint->dl_pipeid = hif->control_dl_pipe;
449
450 err = ath9k_htc_probe_device(target, dev, devid);
451 if (err) {
452 printk(KERN_ERR "Failed to initialize the device\n");
453 return -ENODEV;
454 }
455
456 return 0;
457}
458
459void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug)
460{
461 if (target)
462 ath9k_htc_disconnect_device(target, hot_unplug);
463}
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h
new file mode 100644
index 000000000000..cd7048ffd239
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/htc_hst.h
@@ -0,0 +1,246 @@
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#ifndef HTC_HST_H
18#define HTC_HST_H
19
20struct ath9k_htc_priv;
21struct htc_target;
22struct ath9k_htc_tx_ctl;
23
24enum ath9k_hif_transports {
25 ATH9K_HIF_USB,
26};
27
28struct ath9k_htc_hif {
29 struct list_head list;
30 const enum ath9k_hif_transports transport;
31 const char *name;
32
33 u8 control_dl_pipe;
34 u8 control_ul_pipe;
35
36 void (*start) (void *hif_handle, u8 pipe);
37 void (*stop) (void *hif_handle, u8 pipe);
38 int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
39 struct ath9k_htc_tx_ctl *tx_ctl);
40};
41
42enum htc_endpoint_id {
43 ENDPOINT_UNUSED = -1,
44 ENDPOINT0 = 0,
45 ENDPOINT1 = 1,
46 ENDPOINT2 = 2,
47 ENDPOINT3 = 3,
48 ENDPOINT4 = 4,
49 ENDPOINT5 = 5,
50 ENDPOINT6 = 6,
51 ENDPOINT7 = 7,
52 ENDPOINT8 = 8,
53 ENDPOINT_MAX = 22
54};
55
56/* Htc frame hdr flags */
57#define HTC_FLAGS_RECV_TRAILER (1 << 1)
58
59struct htc_frame_hdr {
60 u8 endpoint_id;
61 u8 flags;
62 u16 payload_len;
63 u8 control[4];
64} __packed;
65
66struct htc_ready_msg {
67 u16 message_id;
68 u16 credits;
69 u16 credit_size;
70 u8 max_endpoints;
71 u8 pad;
72} __packed;
73
74struct htc_config_pipe_msg {
75 u16 message_id;
76 u8 pipe_id;
77 u8 credits;
78} __packed;
79
80struct htc_packet {
81 void *pktcontext;
82 u8 *buf;
83 u8 *buf_payload;
84 u32 buflen;
85 u32 payload_len;
86
87 int endpoint;
88 int status;
89
90 void *context;
91 u32 reserved;
92};
93
94struct htc_ep_callbacks {
95 void *priv;
96 void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok);
97 void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
98};
99
100#define HTC_TX_QUEUE_SIZE 256
101
102struct htc_txq {
103 struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
104 u32 txqdepth;
105 u16 txbuf_cnt;
106 u16 txq_head;
107 u16 txq_tail;
108};
109
110struct htc_endpoint {
111 u16 service_id;
112
113 struct htc_ep_callbacks ep_callbacks;
114 struct htc_txq htc_txq;
115 u32 max_txqdepth;
116 int max_msglen;
117
118 u8 ul_pipeid;
119 u8 dl_pipeid;
120};
121
122#define HTC_MAX_CONTROL_MESSAGE_LENGTH 255
123#define HTC_CONTROL_BUFFER_SIZE \
124 (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
125
126#define NUM_CONTROL_BUFFERS 8
127#define HST_ENDPOINT_MAX 8
128
129struct htc_control_buf {
130 struct htc_packet htc_pkt;
131 u8 buf[HTC_CONTROL_BUFFER_SIZE];
132};
133
134#define HTC_OP_START_WAIT BIT(0)
135#define HTC_OP_CONFIG_PIPE_CREDITS BIT(1)
136
137struct htc_target {
138 void *hif_dev;
139 struct ath9k_htc_priv *drv_priv;
140 struct device *dev;
141 struct ath9k_htc_hif *hif;
142 struct htc_endpoint endpoint[HST_ENDPOINT_MAX];
143 struct completion target_wait;
144 struct completion cmd_wait;
145 struct list_head list;
146 enum htc_endpoint_id conn_rsp_epid;
147 u16 credits;
148 u16 credit_size;
149 u8 htc_flags;
150};
151
152enum htc_msg_id {
153 HTC_MSG_READY_ID = 1,
154 HTC_MSG_CONNECT_SERVICE_ID,
155 HTC_MSG_CONNECT_SERVICE_RESPONSE_ID,
156 HTC_MSG_SETUP_COMPLETE_ID,
157 HTC_MSG_CONFIG_PIPE_ID,
158 HTC_MSG_CONFIG_PIPE_RESPONSE_ID,
159};
160
161struct htc_service_connreq {
162 u16 service_id;
163 u16 con_flags;
164 u32 max_send_qdepth;
165 struct htc_ep_callbacks ep_callbacks;
166};
167
168/* Current service IDs */
169
170enum htc_service_group_ids{
171 RSVD_SERVICE_GROUP = 0,
172 WMI_SERVICE_GROUP = 1,
173
174 HTC_SERVICE_GROUP_LAST = 255
175};
176
177#define MAKE_SERVICE_ID(group, index) \
178 (int)(((int)group << 8) | (int)(index))
179
180/* NOTE: service ID of 0x0000 is reserved and should never be used */
181#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
182#define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2)
183
184#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
185#define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
186#define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
187#define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
188#define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
189#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5)
190#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6)
191#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7)
192#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8)
193
194struct htc_conn_svc_msg {
195 u16 msg_id;
196 u16 service_id;
197 u16 con_flags;
198 u8 dl_pipeid;
199 u8 ul_pipeid;
200 u8 svc_meta_len;
201 u8 pad;
202} __packed;
203
204/* connect response status codes */
205#define HTC_SERVICE_SUCCESS 0
206#define HTC_SERVICE_NOT_FOUND 1
207#define HTC_SERVICE_FAILED 2
208#define HTC_SERVICE_NO_RESOURCES 3
209#define HTC_SERVICE_NO_MORE_EP 4
210
211struct htc_conn_svc_rspmsg {
212 u16 msg_id;
213 u16 service_id;
214 u8 status;
215 u8 endpoint_id;
216 u16 max_msg_len;
217 u8 svc_meta_len;
218 u8 pad;
219} __packed;
220
221struct htc_comp_msg {
222 u16 msg_id;
223} __packed;
224
225int htc_init(struct htc_target *target);
226int htc_connect_service(struct htc_target *target,
227 struct htc_service_connreq *service_connreq,
228 enum htc_endpoint_id *conn_rsp_eid);
229int htc_send(struct htc_target *target, struct sk_buff *skb,
230 enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
231void htc_stop(struct htc_target *target);
232void htc_start(struct htc_target *target);
233
234void ath9k_htc_rx_msg(struct htc_target *htc_handle,
235 struct sk_buff *skb, u32 len, u8 pipe_id);
236void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
237 struct sk_buff *skb, bool txok);
238
239struct htc_target *ath9k_htc_hw_alloc(void *hif_handle);
240void ath9k_htc_hw_free(struct htc_target *htc);
241int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
242 void *hif_handle, struct device *dev, u16 devid,
243 enum ath9k_hif_transports transport);
244void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
245
246#endif /* HTC_HST_H */
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 29851e6376a9..a5e543bd2271 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -150,6 +150,32 @@ struct ath_rx_status {
150 u32 evm2; 150 u32 evm2;
151}; 151};
152 152
153struct ath_htc_rx_status {
154 u64 rs_tstamp;
155 u16 rs_datalen;
156 u8 rs_status;
157 u8 rs_phyerr;
158 int8_t rs_rssi;
159 int8_t rs_rssi_ctl0;
160 int8_t rs_rssi_ctl1;
161 int8_t rs_rssi_ctl2;
162 int8_t rs_rssi_ext0;
163 int8_t rs_rssi_ext1;
164 int8_t rs_rssi_ext2;
165 u8 rs_keyix;
166 u8 rs_rate;
167 u8 rs_antenna;
168 u8 rs_more;
169 u8 rs_isaggr;
170 u8 rs_moreaggr;
171 u8 rs_num_delims;
172 u8 rs_flags;
173 u8 rs_dummy;
174 u32 evm0;
175 u32 evm1;
176 u32 evm2;
177};
178
153#define ATH9K_RXERR_CRC 0x01 179#define ATH9K_RXERR_CRC 0x01
154#define ATH9K_RXERR_PHY 0x02 180#define ATH9K_RXERR_PHY 0x02
155#define ATH9K_RXERR_FIFO 0x04 181#define ATH9K_RXERR_FIFO 0x04
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
new file mode 100644
index 000000000000..818dea0164ec
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -0,0 +1,319 @@
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
19static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
20{
21 switch (wmi_cmd) {
22 case WMI_ECHO_CMDID:
23 return "WMI_ECHO_CMDID";
24 case WMI_ACCESS_MEMORY_CMDID:
25 return "WMI_ACCESS_MEMORY_CMDID";
26 case WMI_DISABLE_INTR_CMDID:
27 return "WMI_DISABLE_INTR_CMDID";
28 case WMI_ENABLE_INTR_CMDID:
29 return "WMI_ENABLE_INTR_CMDID";
30 case WMI_RX_LINK_CMDID:
31 return "WMI_RX_LINK_CMDID";
32 case WMI_ATH_INIT_CMDID:
33 return "WMI_ATH_INIT_CMDID";
34 case WMI_ABORT_TXQ_CMDID:
35 return "WMI_ABORT_TXQ_CMDID";
36 case WMI_STOP_TX_DMA_CMDID:
37 return "WMI_STOP_TX_DMA_CMDID";
38 case WMI_STOP_DMA_RECV_CMDID:
39 return "WMI_STOP_DMA_RECV_CMDID";
40 case WMI_ABORT_TX_DMA_CMDID:
41 return "WMI_ABORT_TX_DMA_CMDID";
42 case WMI_DRAIN_TXQ_CMDID:
43 return "WMI_DRAIN_TXQ_CMDID";
44 case WMI_DRAIN_TXQ_ALL_CMDID:
45 return "WMI_DRAIN_TXQ_ALL_CMDID";
46 case WMI_START_RECV_CMDID:
47 return "WMI_START_RECV_CMDID";
48 case WMI_STOP_RECV_CMDID:
49 return "WMI_STOP_RECV_CMDID";
50 case WMI_FLUSH_RECV_CMDID:
51 return "WMI_FLUSH_RECV_CMDID";
52 case WMI_SET_MODE_CMDID:
53 return "WMI_SET_MODE_CMDID";
54 case WMI_RESET_CMDID:
55 return "WMI_RESET_CMDID";
56 case WMI_NODE_CREATE_CMDID:
57 return "WMI_NODE_CREATE_CMDID";
58 case WMI_NODE_REMOVE_CMDID:
59 return "WMI_NODE_REMOVE_CMDID";
60 case WMI_VAP_REMOVE_CMDID:
61 return "WMI_VAP_REMOVE_CMDID";
62 case WMI_VAP_CREATE_CMDID:
63 return "WMI_VAP_CREATE_CMDID";
64 case WMI_BEACON_UPDATE_CMDID:
65 return "WMI_BEACON_UPDATE_CMDID";
66 case WMI_REG_READ_CMDID:
67 return "WMI_REG_READ_CMDID";
68 case WMI_REG_WRITE_CMDID:
69 return "WMI_REG_WRITE_CMDID";
70 case WMI_RC_STATE_CHANGE_CMDID:
71 return "WMI_RC_STATE_CHANGE_CMDID";
72 case WMI_RC_RATE_UPDATE_CMDID:
73 return "WMI_RC_RATE_UPDATE_CMDID";
74 case WMI_DEBUG_INFO_CMDID:
75 return "WMI_DEBUG_INFO_CMDID";
76 case WMI_HOST_ATTACH:
77 return "WMI_HOST_ATTACH";
78 case WMI_TARGET_IC_UPDATE_CMDID:
79 return "WMI_TARGET_IC_UPDATE_CMDID";
80 case WMI_TGT_STATS_CMDID:
81 return "WMI_TGT_STATS_CMDID";
82 case WMI_TX_AGGR_ENABLE_CMDID:
83 return "WMI_TX_AGGR_ENABLE_CMDID";
84 case WMI_TGT_DETACH_CMDID:
85 return "WMI_TGT_DETACH_CMDID";
86 case WMI_TGT_TXQ_ENABLE_CMDID:
87 return "WMI_TGT_TXQ_ENABLE_CMDID";
88 }
89
90 return "Bogus";
91}
92
93struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
94{
95 struct wmi *wmi;
96
97 wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
98 if (!wmi)
99 return NULL;
100
101 wmi->drv_priv = priv;
102 wmi->stopped = false;
103 mutex_init(&wmi->op_mutex);
104 init_completion(&wmi->cmd_wait);
105
106 return wmi;
107}
108
109void ath9k_deinit_wmi(struct ath9k_htc_priv *priv)
110{
111 struct wmi *wmi = priv->wmi;
112
113 mutex_lock(&wmi->op_mutex);
114 wmi->stopped = true;
115 mutex_unlock(&wmi->op_mutex);
116
117 kfree(priv->wmi);
118}
119
120void ath9k_wmi_tasklet(unsigned long data)
121{
122 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
123 struct ath_common *common = ath9k_hw_common(priv->ah);
124 struct wmi_cmd_hdr *hdr;
125 struct wmi_swba *swba_hdr;
126 enum wmi_event_id event;
127 struct sk_buff *skb;
128 void *wmi_event;
129 unsigned long flags;
130#ifdef CONFIG_ATH9K_HTC_DEBUGFS
131 u32 txrate;
132#endif
133
134 spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
135 skb = priv->wmi->wmi_skb;
136 spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
137
138 hdr = (struct wmi_cmd_hdr *) skb->data;
139 event = be16_to_cpu(hdr->command_id);
140 wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
141
142 ath_print(common, ATH_DBG_WMI,
143 "WMI Event: 0x%x\n", event);
144
145 switch (event) {
146 case WMI_TGT_RDY_EVENTID:
147 break;
148 case WMI_SWBA_EVENTID:
149 swba_hdr = (struct wmi_swba *) wmi_event;
150 ath9k_htc_swba(priv, swba_hdr->beacon_pending);
151 break;
152 case WMI_FATAL_EVENTID:
153 break;
154 case WMI_TXTO_EVENTID:
155 break;
156 case WMI_BMISS_EVENTID:
157 break;
158 case WMI_WLAN_TXCOMP_EVENTID:
159 break;
160 case WMI_DELBA_EVENTID:
161 break;
162 case WMI_TXRATE_EVENTID:
163#ifdef CONFIG_ATH9K_HTC_DEBUGFS
164 txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
165 priv->debug.txrate = be32_to_cpu(txrate);
166#endif
167 break;
168 default:
169 break;
170 }
171
172 dev_kfree_skb_any(skb);
173}
174
175static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb)
176{
177 skb_pull(skb, sizeof(struct wmi_cmd_hdr));
178
179 if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0)
180 memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len);
181
182 complete(&wmi->cmd_wait);
183}
184
185static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb,
186 enum htc_endpoint_id epid)
187{
188 struct wmi *wmi = (struct wmi *) priv;
189 struct wmi_cmd_hdr *hdr;
190 u16 cmd_id;
191
192 if (unlikely(wmi->stopped))
193 goto free_skb;
194
195 hdr = (struct wmi_cmd_hdr *) skb->data;
196 cmd_id = be16_to_cpu(hdr->command_id);
197
198 if (cmd_id & 0x1000) {
199 spin_lock(&wmi->wmi_lock);
200 wmi->wmi_skb = skb;
201 spin_unlock(&wmi->wmi_lock);
202 tasklet_schedule(&wmi->drv_priv->wmi_tasklet);
203 return;
204 }
205
206 /* WMI command response */
207 ath9k_wmi_rsp_callback(wmi, skb);
208
209free_skb:
210 dev_kfree_skb_any(skb);
211}
212
213static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb,
214 enum htc_endpoint_id epid, bool txok)
215{
216 dev_kfree_skb_any(skb);
217}
218
219int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
220 enum htc_endpoint_id *wmi_ctrl_epid)
221{
222 struct htc_service_connreq connect;
223 int ret;
224
225 wmi->htc = htc;
226
227 memset(&connect, 0, sizeof(connect));
228
229 connect.ep_callbacks.priv = wmi;
230 connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx;
231 connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx;
232 connect.service_id = WMI_CONTROL_SVC;
233
234 ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid);
235 if (ret)
236 return ret;
237
238 *wmi_ctrl_epid = wmi->ctrl_epid;
239
240 return 0;
241}
242
243static int ath9k_wmi_cmd_issue(struct wmi *wmi,
244 struct sk_buff *skb,
245 enum wmi_cmd_id cmd, u16 len)
246{
247 struct wmi_cmd_hdr *hdr;
248
249 hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr));
250 hdr->command_id = cpu_to_be16(cmd);
251 hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
252
253 return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
254}
255
256int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
257 u8 *cmd_buf, u32 cmd_len,
258 u8 *rsp_buf, u32 rsp_len,
259 u32 timeout)
260{
261 struct ath_hw *ah = wmi->drv_priv->ah;
262 struct ath_common *common = ath9k_hw_common(ah);
263 u16 headroom = sizeof(struct htc_frame_hdr) +
264 sizeof(struct wmi_cmd_hdr);
265 struct sk_buff *skb;
266 u8 *data;
267 int time_left, ret = 0;
268
269 if (!wmi)
270 return -EINVAL;
271
272 skb = dev_alloc_skb(headroom + cmd_len);
273 if (!skb)
274 return -ENOMEM;
275
276 skb_reserve(skb, headroom);
277
278 if (cmd_len != 0 && cmd_buf != NULL) {
279 data = (u8 *) skb_put(skb, cmd_len);
280 memcpy(data, cmd_buf, cmd_len);
281 }
282
283 mutex_lock(&wmi->op_mutex);
284
285 /* check if wmi stopped flag is set */
286 if (unlikely(wmi->stopped)) {
287 ret = -EPROTO;
288 goto out;
289 }
290
291 /* record the rsp buffer and length */
292 wmi->cmd_rsp_buf = rsp_buf;
293 wmi->cmd_rsp_len = rsp_len;
294
295 ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len);
296 if (ret)
297 goto out;
298
299 time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout);
300 if (!time_left) {
301 ath_print(common, ATH_DBG_WMI,
302 "Timeout waiting for WMI command: %s\n",
303 wmi_cmd_to_name(cmd_id));
304 mutex_unlock(&wmi->op_mutex);
305 return -ETIMEDOUT;
306 }
307
308 mutex_unlock(&wmi->op_mutex);
309
310 return 0;
311
312out:
313 ath_print(common, ATH_DBG_WMI,
314 "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id));
315 mutex_unlock(&wmi->op_mutex);
316 dev_kfree_skb_any(skb);
317
318 return ret;
319}
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
new file mode 100644
index 000000000000..39ef926f27c2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -0,0 +1,126 @@
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#ifndef WMI_H
18#define WMI_H
19
20
21struct wmi_event_txrate {
22 u32 txrate;
23 struct {
24 u8 rssi_thresh;
25 u8 per;
26 } rc_stats;
27} __packed;
28
29struct wmi_cmd_hdr {
30 u16 command_id;
31 u16 seq_no;
32} __packed;
33
34struct wmi_swba {
35 u8 beacon_pending;
36} __packed;
37
38enum wmi_cmd_id {
39 WMI_ECHO_CMDID = 0x0001,
40 WMI_ACCESS_MEMORY_CMDID,
41
42 /* Commands to Target */
43 WMI_DISABLE_INTR_CMDID,
44 WMI_ENABLE_INTR_CMDID,
45 WMI_RX_LINK_CMDID,
46 WMI_ATH_INIT_CMDID,
47 WMI_ABORT_TXQ_CMDID,
48 WMI_STOP_TX_DMA_CMDID,
49 WMI_STOP_DMA_RECV_CMDID,
50 WMI_ABORT_TX_DMA_CMDID,
51 WMI_DRAIN_TXQ_CMDID,
52 WMI_DRAIN_TXQ_ALL_CMDID,
53 WMI_START_RECV_CMDID,
54 WMI_STOP_RECV_CMDID,
55 WMI_FLUSH_RECV_CMDID,
56 WMI_SET_MODE_CMDID,
57 WMI_RESET_CMDID,
58 WMI_NODE_CREATE_CMDID,
59 WMI_NODE_REMOVE_CMDID,
60 WMI_VAP_REMOVE_CMDID,
61 WMI_VAP_CREATE_CMDID,
62 WMI_BEACON_UPDATE_CMDID,
63 WMI_REG_READ_CMDID,
64 WMI_REG_WRITE_CMDID,
65 WMI_RC_STATE_CHANGE_CMDID,
66 WMI_RC_RATE_UPDATE_CMDID,
67 WMI_DEBUG_INFO_CMDID,
68 WMI_HOST_ATTACH,
69 WMI_TARGET_IC_UPDATE_CMDID,
70 WMI_TGT_STATS_CMDID,
71 WMI_TX_AGGR_ENABLE_CMDID,
72 WMI_TGT_DETACH_CMDID,
73 WMI_TGT_TXQ_ENABLE_CMDID,
74};
75
76enum wmi_event_id {
77 WMI_TGT_RDY_EVENTID = 0x1001,
78 WMI_SWBA_EVENTID,
79 WMI_FATAL_EVENTID,
80 WMI_TXTO_EVENTID,
81 WMI_BMISS_EVENTID,
82 WMI_WLAN_TXCOMP_EVENTID,
83 WMI_DELBA_EVENTID,
84 WMI_TXRATE_EVENTID,
85};
86
87struct wmi {
88 struct ath9k_htc_priv *drv_priv;
89 struct htc_target *htc;
90 enum htc_endpoint_id ctrl_epid;
91 struct mutex op_mutex;
92 struct completion cmd_wait;
93 u16 tx_seq_id;
94 u8 *cmd_rsp_buf;
95 u32 cmd_rsp_len;
96 bool stopped;
97
98 struct sk_buff *wmi_skb;
99 spinlock_t wmi_lock;
100};
101
102struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
103void ath9k_deinit_wmi(struct ath9k_htc_priv *priv);
104int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi,
105 enum htc_endpoint_id *wmi_ctrl_epid);
106int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
107 u8 *cmd_buf, u32 cmd_len,
108 u8 *rsp_buf, u32 rsp_len,
109 u32 timeout);
110void ath9k_wmi_tasklet(unsigned long data);
111
112#define WMI_CMD(_wmi_cmd) \
113 do { \
114 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \
115 (u8 *) &cmd_rsp, \
116 sizeof(cmd_rsp), HZ); \
117 } while (0)
118
119#define WMI_CMD_BUF(_wmi_cmd, _buf) \
120 do { \
121 ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \
122 (u8 *) _buf, sizeof(*_buf), \
123 &cmd_rsp, sizeof(cmd_rsp), HZ); \
124 } while (0)
125
126#endif /* WMI_H */
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h
index 8263633c003c..873bf526e11f 100644
--- a/drivers/net/wireless/ath/debug.h
+++ b/drivers/net/wireless/ath/debug.h
@@ -59,6 +59,7 @@ enum ATH_DEBUG {
59 ATH_DBG_PS = 0x00000800, 59 ATH_DBG_PS = 0x00000800,
60 ATH_DBG_HWTIMER = 0x00001000, 60 ATH_DBG_HWTIMER = 0x00001000,
61 ATH_DBG_BTCOEX = 0x00002000, 61 ATH_DBG_BTCOEX = 0x00002000,
62 ATH_DBG_WMI = 0x00004000,
62 ATH_DBG_ANY = 0xffffffff 63 ATH_DBG_ANY = 0xffffffff
63}; 64};
64 65