diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-03-04 14:00:29 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-03-04 14:00:29 -0500 |
commit | 95f84f2959482ee25b5cfe28a048a331ded8667c (patch) | |
tree | ee15748fa93710bdd81898e9b69acfb73aee8cfd /drivers/net | |
parent | a177584609f7eb2ab1f1c0211bee4ec20d98d892 (diff) | |
parent | 95a776107a131823c87147dff083696d8814c1b3 (diff) |
Merge branch 'for-linville' of git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/wl12xx/acx.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/boot.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/boot.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/cmd.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/debugfs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/io.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 170 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/ps.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/ps.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/rx.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/scan.c | 20 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/sdio.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/spi.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/tx.c | 47 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl12xx.h | 28 |
15 files changed, 235 insertions, 125 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index 3badc6bb7866..a3db755ceeda 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -1361,7 +1361,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, | |||
1361 | acx->ht_protection = | 1361 | acx->ht_protection = |
1362 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); | 1362 | (u8)(ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION); |
1363 | acx->rifs_mode = 0; | 1363 | acx->rifs_mode = 0; |
1364 | acx->gf_protection = 0; | 1364 | acx->gf_protection = |
1365 | !!(ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); | ||
1365 | acx->ht_tx_burst_limit = 0; | 1366 | acx->ht_tx_burst_limit = 0; |
1366 | acx->dual_cts_protection = 0; | 1367 | acx->dual_cts_protection = 0; |
1367 | 1368 | ||
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index 1ffbad67d2d8..6934dffd5174 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c | |||
@@ -488,6 +488,9 @@ static void wl1271_boot_hw_version(struct wl1271 *wl) | |||
488 | fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; | 488 | fuse = (fuse & PG_VER_MASK) >> PG_VER_OFFSET; |
489 | 489 | ||
490 | wl->hw_pg_ver = (s8)fuse; | 490 | wl->hw_pg_ver = (s8)fuse; |
491 | |||
492 | if (((wl->hw_pg_ver & PG_MAJOR_VER_MASK) >> PG_MAJOR_VER_OFFSET) < 3) | ||
493 | wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; | ||
491 | } | 494 | } |
492 | 495 | ||
493 | /* uploads NVS and firmware */ | 496 | /* uploads NVS and firmware */ |
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h index d67dcffa31eb..17229b86fc71 100644 --- a/drivers/net/wireless/wl12xx/boot.h +++ b/drivers/net/wireless/wl12xx/boot.h | |||
@@ -59,6 +59,11 @@ struct wl1271_static_data { | |||
59 | #define PG_VER_MASK 0x3c | 59 | #define PG_VER_MASK 0x3c |
60 | #define PG_VER_OFFSET 2 | 60 | #define PG_VER_OFFSET 2 |
61 | 61 | ||
62 | #define PG_MAJOR_VER_MASK 0x3 | ||
63 | #define PG_MAJOR_VER_OFFSET 0x0 | ||
64 | #define PG_MINOR_VER_MASK 0xc | ||
65 | #define PG_MINOR_VER_OFFSET 0x2 | ||
66 | |||
62 | #define CMD_MBOX_ADDRESS 0x407B4 | 67 | #define CMD_MBOX_ADDRESS 0x407B4 |
63 | 68 | ||
64 | #define POLARITY_LOW BIT(1) | 69 | #define POLARITY_LOW BIT(1) |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 97ffd7aa57a8..f0aa7ab97bf7 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -63,6 +63,7 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, | |||
63 | cmd->status = 0; | 63 | cmd->status = 0; |
64 | 64 | ||
65 | WARN_ON(len % 4 != 0); | 65 | WARN_ON(len % 4 != 0); |
66 | WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); | ||
66 | 67 | ||
67 | wl1271_write(wl, wl->cmd_box_addr, buf, len, false); | 68 | wl1271_write(wl, wl->cmd_box_addr, buf, len, false); |
68 | 69 | ||
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c index bebfa28a171a..8e75b09723b9 100644 --- a/drivers/net/wireless/wl12xx/debugfs.c +++ b/drivers/net/wireless/wl12xx/debugfs.c | |||
@@ -99,7 +99,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl) | |||
99 | 99 | ||
100 | mutex_lock(&wl->mutex); | 100 | mutex_lock(&wl->mutex); |
101 | 101 | ||
102 | ret = wl1271_ps_elp_wakeup(wl, false); | 102 | ret = wl1271_ps_elp_wakeup(wl); |
103 | if (ret < 0) | 103 | if (ret < 0) |
104 | goto out; | 104 | goto out; |
105 | 105 | ||
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h index 844b32b170bb..c1aac8292089 100644 --- a/drivers/net/wireless/wl12xx/io.h +++ b/drivers/net/wireless/wl12xx/io.h | |||
@@ -168,5 +168,6 @@ void wl1271_unregister_hw(struct wl1271 *wl); | |||
168 | int wl1271_init_ieee80211(struct wl1271 *wl); | 168 | int wl1271_init_ieee80211(struct wl1271 *wl); |
169 | struct ieee80211_hw *wl1271_alloc_hw(void); | 169 | struct ieee80211_hw *wl1271_alloc_hw(void); |
170 | int wl1271_free_hw(struct wl1271 *wl); | 170 | int wl1271_free_hw(struct wl1271 *wl); |
171 | irqreturn_t wl1271_irq(int irq, void *data); | ||
171 | 172 | ||
172 | #endif | 173 | #endif |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 947491a1d9cc..8b3c8d196b03 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -304,7 +304,7 @@ static struct conf_drv_settings default_conf = { | |||
304 | .rx_block_num = 70, | 304 | .rx_block_num = 70, |
305 | .tx_min_block_num = 40, | 305 | .tx_min_block_num = 40, |
306 | .dynamic_memory = 0, | 306 | .dynamic_memory = 0, |
307 | .min_req_tx_blocks = 104, | 307 | .min_req_tx_blocks = 100, |
308 | .min_req_rx_blocks = 22, | 308 | .min_req_rx_blocks = 22, |
309 | .tx_min = 27, | 309 | .tx_min = 27, |
310 | } | 310 | } |
@@ -374,7 +374,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, | |||
374 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 374 | if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) |
375 | goto out; | 375 | goto out; |
376 | 376 | ||
377 | ret = wl1271_ps_elp_wakeup(wl, false); | 377 | ret = wl1271_ps_elp_wakeup(wl); |
378 | if (ret < 0) | 378 | if (ret < 0) |
379 | goto out; | 379 | goto out; |
380 | 380 | ||
@@ -635,16 +635,44 @@ static void wl1271_fw_status(struct wl1271 *wl, | |||
635 | (s64)le32_to_cpu(status->fw_localtime); | 635 | (s64)le32_to_cpu(status->fw_localtime); |
636 | } | 636 | } |
637 | 637 | ||
638 | #define WL1271_IRQ_MAX_LOOPS 10 | 638 | static void wl1271_flush_deferred_work(struct wl1271 *wl) |
639 | { | ||
640 | struct sk_buff *skb; | ||
641 | |||
642 | /* Pass all received frames to the network stack */ | ||
643 | while ((skb = skb_dequeue(&wl->deferred_rx_queue))) | ||
644 | ieee80211_rx_ni(wl->hw, skb); | ||
639 | 645 | ||
640 | static void wl1271_irq_work(struct work_struct *work) | 646 | /* Return sent skbs to the network stack */ |
647 | while ((skb = skb_dequeue(&wl->deferred_tx_queue))) | ||
648 | ieee80211_tx_status(wl->hw, skb); | ||
649 | } | ||
650 | |||
651 | static void wl1271_netstack_work(struct work_struct *work) | ||
652 | { | ||
653 | struct wl1271 *wl = | ||
654 | container_of(work, struct wl1271, netstack_work); | ||
655 | |||
656 | do { | ||
657 | wl1271_flush_deferred_work(wl); | ||
658 | } while (skb_queue_len(&wl->deferred_rx_queue)); | ||
659 | } | ||
660 | |||
661 | #define WL1271_IRQ_MAX_LOOPS 256 | ||
662 | |||
663 | irqreturn_t wl1271_irq(int irq, void *cookie) | ||
641 | { | 664 | { |
642 | int ret; | 665 | int ret; |
643 | u32 intr; | 666 | u32 intr; |
644 | int loopcount = WL1271_IRQ_MAX_LOOPS; | 667 | int loopcount = WL1271_IRQ_MAX_LOOPS; |
668 | struct wl1271 *wl = (struct wl1271 *)cookie; | ||
669 | bool done = false; | ||
670 | unsigned int defer_count; | ||
645 | unsigned long flags; | 671 | unsigned long flags; |
646 | struct wl1271 *wl = | 672 | |
647 | container_of(work, struct wl1271, irq_work); | 673 | /* TX might be handled here, avoid redundant work */ |
674 | set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); | ||
675 | cancel_work_sync(&wl->tx_work); | ||
648 | 676 | ||
649 | mutex_lock(&wl->mutex); | 677 | mutex_lock(&wl->mutex); |
650 | 678 | ||
@@ -653,26 +681,27 @@ static void wl1271_irq_work(struct work_struct *work) | |||
653 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 681 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
654 | goto out; | 682 | goto out; |
655 | 683 | ||
656 | ret = wl1271_ps_elp_wakeup(wl, true); | 684 | ret = wl1271_ps_elp_wakeup(wl); |
657 | if (ret < 0) | 685 | if (ret < 0) |
658 | goto out; | 686 | goto out; |
659 | 687 | ||
660 | spin_lock_irqsave(&wl->wl_lock, flags); | 688 | while (!done && loopcount--) { |
661 | while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) { | 689 | /* |
662 | clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | 690 | * In order to avoid a race with the hardirq, clear the flag |
663 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 691 | * before acknowledging the chip. Since the mutex is held, |
664 | loopcount--; | 692 | * wl1271_ps_elp_wakeup cannot be called concurrently. |
693 | */ | ||
694 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
695 | smp_mb__after_clear_bit(); | ||
665 | 696 | ||
666 | wl1271_fw_status(wl, wl->fw_status); | 697 | wl1271_fw_status(wl, wl->fw_status); |
667 | intr = le32_to_cpu(wl->fw_status->common.intr); | 698 | intr = le32_to_cpu(wl->fw_status->common.intr); |
699 | intr &= WL1271_INTR_MASK; | ||
668 | if (!intr) { | 700 | if (!intr) { |
669 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 701 | done = true; |
670 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
671 | continue; | 702 | continue; |
672 | } | 703 | } |
673 | 704 | ||
674 | intr &= WL1271_INTR_MASK; | ||
675 | |||
676 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { | 705 | if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { |
677 | wl1271_error("watchdog interrupt received! " | 706 | wl1271_error("watchdog interrupt received! " |
678 | "starting recovery."); | 707 | "starting recovery."); |
@@ -682,25 +711,35 @@ static void wl1271_irq_work(struct work_struct *work) | |||
682 | goto out; | 711 | goto out; |
683 | } | 712 | } |
684 | 713 | ||
685 | if (intr & WL1271_ACX_INTR_DATA) { | 714 | if (likely(intr & WL1271_ACX_INTR_DATA)) { |
686 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 715 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
687 | 716 | ||
688 | /* check for tx results */ | 717 | wl1271_rx(wl, &wl->fw_status->common); |
689 | if (wl->fw_status->common.tx_results_counter != | ||
690 | (wl->tx_results_count & 0xff)) | ||
691 | wl1271_tx_complete(wl); | ||
692 | 718 | ||
693 | /* Check if any tx blocks were freed */ | 719 | /* Check if any tx blocks were freed */ |
720 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
694 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && | 721 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && |
695 | wl->tx_queue_count) { | 722 | wl->tx_queue_count) { |
723 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
696 | /* | 724 | /* |
697 | * In order to avoid starvation of the TX path, | 725 | * In order to avoid starvation of the TX path, |
698 | * call the work function directly. | 726 | * call the work function directly. |
699 | */ | 727 | */ |
700 | wl1271_tx_work_locked(wl); | 728 | wl1271_tx_work_locked(wl); |
729 | } else { | ||
730 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
701 | } | 731 | } |
702 | 732 | ||
703 | wl1271_rx(wl, &wl->fw_status->common); | 733 | /* check for tx results */ |
734 | if (wl->fw_status->common.tx_results_counter != | ||
735 | (wl->tx_results_count & 0xff)) | ||
736 | wl1271_tx_complete(wl); | ||
737 | |||
738 | /* Make sure the deferred queues don't get too long */ | ||
739 | defer_count = skb_queue_len(&wl->deferred_tx_queue) + | ||
740 | skb_queue_len(&wl->deferred_rx_queue); | ||
741 | if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT) | ||
742 | wl1271_flush_deferred_work(wl); | ||
704 | } | 743 | } |
705 | 744 | ||
706 | if (intr & WL1271_ACX_INTR_EVENT_A) { | 745 | if (intr & WL1271_ACX_INTR_EVENT_A) { |
@@ -719,21 +758,24 @@ static void wl1271_irq_work(struct work_struct *work) | |||
719 | 758 | ||
720 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) | 759 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) |
721 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); | 760 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); |
722 | |||
723 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
724 | } | 761 | } |
725 | 762 | ||
726 | if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags)) | ||
727 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
728 | else | ||
729 | clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
730 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
731 | |||
732 | wl1271_ps_elp_sleep(wl); | 763 | wl1271_ps_elp_sleep(wl); |
733 | 764 | ||
734 | out: | 765 | out: |
766 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
767 | /* In case TX was not handled here, queue TX work */ | ||
768 | clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); | ||
769 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && | ||
770 | wl->tx_queue_count) | ||
771 | ieee80211_queue_work(wl->hw, &wl->tx_work); | ||
772 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
773 | |||
735 | mutex_unlock(&wl->mutex); | 774 | mutex_unlock(&wl->mutex); |
775 | |||
776 | return IRQ_HANDLED; | ||
736 | } | 777 | } |
778 | EXPORT_SYMBOL_GPL(wl1271_irq); | ||
737 | 779 | ||
738 | static int wl1271_fetch_firmware(struct wl1271 *wl) | 780 | static int wl1271_fetch_firmware(struct wl1271 *wl) |
739 | { | 781 | { |
@@ -974,7 +1016,6 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
974 | goto out; | 1016 | goto out; |
975 | 1017 | ||
976 | irq_disable: | 1018 | irq_disable: |
977 | wl1271_disable_interrupts(wl); | ||
978 | mutex_unlock(&wl->mutex); | 1019 | mutex_unlock(&wl->mutex); |
979 | /* Unlocking the mutex in the middle of handling is | 1020 | /* Unlocking the mutex in the middle of handling is |
980 | inherently unsafe. In this case we deem it safe to do, | 1021 | inherently unsafe. In this case we deem it safe to do, |
@@ -983,7 +1024,9 @@ irq_disable: | |||
983 | work function will not do anything.) Also, any other | 1024 | work function will not do anything.) Also, any other |
984 | possible concurrent operations will fail due to the | 1025 | possible concurrent operations will fail due to the |
985 | current state, hence the wl1271 struct should be safe. */ | 1026 | current state, hence the wl1271 struct should be safe. */ |
986 | cancel_work_sync(&wl->irq_work); | 1027 | wl1271_disable_interrupts(wl); |
1028 | wl1271_flush_deferred_work(wl); | ||
1029 | cancel_work_sync(&wl->netstack_work); | ||
987 | mutex_lock(&wl->mutex); | 1030 | mutex_lock(&wl->mutex); |
988 | power_off: | 1031 | power_off: |
989 | wl1271_power_off(wl); | 1032 | wl1271_power_off(wl); |
@@ -1010,14 +1053,15 @@ int __wl1271_plt_stop(struct wl1271 *wl) | |||
1010 | goto out; | 1053 | goto out; |
1011 | } | 1054 | } |
1012 | 1055 | ||
1013 | wl1271_disable_interrupts(wl); | ||
1014 | wl1271_power_off(wl); | 1056 | wl1271_power_off(wl); |
1015 | 1057 | ||
1016 | wl->state = WL1271_STATE_OFF; | 1058 | wl->state = WL1271_STATE_OFF; |
1017 | wl->rx_counter = 0; | 1059 | wl->rx_counter = 0; |
1018 | 1060 | ||
1019 | mutex_unlock(&wl->mutex); | 1061 | mutex_unlock(&wl->mutex); |
1020 | cancel_work_sync(&wl->irq_work); | 1062 | wl1271_disable_interrupts(wl); |
1063 | wl1271_flush_deferred_work(wl); | ||
1064 | cancel_work_sync(&wl->netstack_work); | ||
1021 | cancel_work_sync(&wl->recovery_work); | 1065 | cancel_work_sync(&wl->recovery_work); |
1022 | mutex_lock(&wl->mutex); | 1066 | mutex_lock(&wl->mutex); |
1023 | out: | 1067 | out: |
@@ -1041,7 +1085,13 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1041 | int q; | 1085 | int q; |
1042 | u8 hlid = 0; | 1086 | u8 hlid = 0; |
1043 | 1087 | ||
1088 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | ||
1089 | |||
1090 | if (wl->bss_type == BSS_TYPE_AP_BSS) | ||
1091 | hlid = wl1271_tx_get_hlid(skb); | ||
1092 | |||
1044 | spin_lock_irqsave(&wl->wl_lock, flags); | 1093 | spin_lock_irqsave(&wl->wl_lock, flags); |
1094 | |||
1045 | wl->tx_queue_count++; | 1095 | wl->tx_queue_count++; |
1046 | 1096 | ||
1047 | /* | 1097 | /* |
@@ -1054,12 +1104,8 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1054 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); | 1104 | set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); |
1055 | } | 1105 | } |
1056 | 1106 | ||
1057 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1058 | |||
1059 | /* queue the packet */ | 1107 | /* queue the packet */ |
1060 | q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); | ||
1061 | if (wl->bss_type == BSS_TYPE_AP_BSS) { | 1108 | if (wl->bss_type == BSS_TYPE_AP_BSS) { |
1062 | hlid = wl1271_tx_get_hlid(skb); | ||
1063 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); | 1109 | wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); |
1064 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); | 1110 | skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); |
1065 | } else { | 1111 | } else { |
@@ -1071,8 +1117,11 @@ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1071 | * before that, the tx_work will not be initialized! | 1117 | * before that, the tx_work will not be initialized! |
1072 | */ | 1118 | */ |
1073 | 1119 | ||
1074 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) | 1120 | if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && |
1121 | !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags)) | ||
1075 | ieee80211_queue_work(wl->hw, &wl->tx_work); | 1122 | ieee80211_queue_work(wl->hw, &wl->tx_work); |
1123 | |||
1124 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
1076 | } | 1125 | } |
1077 | 1126 | ||
1078 | static struct notifier_block wl1271_dev_notifier = { | 1127 | static struct notifier_block wl1271_dev_notifier = { |
@@ -1169,7 +1218,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, | |||
1169 | break; | 1218 | break; |
1170 | 1219 | ||
1171 | irq_disable: | 1220 | irq_disable: |
1172 | wl1271_disable_interrupts(wl); | ||
1173 | mutex_unlock(&wl->mutex); | 1221 | mutex_unlock(&wl->mutex); |
1174 | /* Unlocking the mutex in the middle of handling is | 1222 | /* Unlocking the mutex in the middle of handling is |
1175 | inherently unsafe. In this case we deem it safe to do, | 1223 | inherently unsafe. In this case we deem it safe to do, |
@@ -1178,7 +1226,9 @@ irq_disable: | |||
1178 | work function will not do anything.) Also, any other | 1226 | work function will not do anything.) Also, any other |
1179 | possible concurrent operations will fail due to the | 1227 | possible concurrent operations will fail due to the |
1180 | current state, hence the wl1271 struct should be safe. */ | 1228 | current state, hence the wl1271 struct should be safe. */ |
1181 | cancel_work_sync(&wl->irq_work); | 1229 | wl1271_disable_interrupts(wl); |
1230 | wl1271_flush_deferred_work(wl); | ||
1231 | cancel_work_sync(&wl->netstack_work); | ||
1182 | mutex_lock(&wl->mutex); | 1232 | mutex_lock(&wl->mutex); |
1183 | power_off: | 1233 | power_off: |
1184 | wl1271_power_off(wl); | 1234 | wl1271_power_off(wl); |
@@ -1244,12 +1294,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1244 | 1294 | ||
1245 | wl->state = WL1271_STATE_OFF; | 1295 | wl->state = WL1271_STATE_OFF; |
1246 | 1296 | ||
1247 | wl1271_disable_interrupts(wl); | ||
1248 | |||
1249 | mutex_unlock(&wl->mutex); | 1297 | mutex_unlock(&wl->mutex); |
1250 | 1298 | ||
1299 | wl1271_disable_interrupts(wl); | ||
1300 | wl1271_flush_deferred_work(wl); | ||
1251 | cancel_delayed_work_sync(&wl->scan_complete_work); | 1301 | cancel_delayed_work_sync(&wl->scan_complete_work); |
1252 | cancel_work_sync(&wl->irq_work); | 1302 | cancel_work_sync(&wl->netstack_work); |
1253 | cancel_work_sync(&wl->tx_work); | 1303 | cancel_work_sync(&wl->tx_work); |
1254 | cancel_delayed_work_sync(&wl->pspoll_work); | 1304 | cancel_delayed_work_sync(&wl->pspoll_work); |
1255 | cancel_delayed_work_sync(&wl->elp_work); | 1305 | cancel_delayed_work_sync(&wl->elp_work); |
@@ -1525,7 +1575,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) | |||
1525 | 1575 | ||
1526 | is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | 1576 | is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); |
1527 | 1577 | ||
1528 | ret = wl1271_ps_elp_wakeup(wl, false); | 1578 | ret = wl1271_ps_elp_wakeup(wl); |
1529 | if (ret < 0) | 1579 | if (ret < 0) |
1530 | goto out; | 1580 | goto out; |
1531 | 1581 | ||
@@ -1681,7 +1731,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, | |||
1681 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 1731 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
1682 | goto out; | 1732 | goto out; |
1683 | 1733 | ||
1684 | ret = wl1271_ps_elp_wakeup(wl, false); | 1734 | ret = wl1271_ps_elp_wakeup(wl); |
1685 | if (ret < 0) | 1735 | if (ret < 0) |
1686 | goto out; | 1736 | goto out; |
1687 | 1737 | ||
@@ -1910,7 +1960,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1910 | goto out_unlock; | 1960 | goto out_unlock; |
1911 | } | 1961 | } |
1912 | 1962 | ||
1913 | ret = wl1271_ps_elp_wakeup(wl, false); | 1963 | ret = wl1271_ps_elp_wakeup(wl); |
1914 | if (ret < 0) | 1964 | if (ret < 0) |
1915 | goto out_unlock; | 1965 | goto out_unlock; |
1916 | 1966 | ||
@@ -2013,7 +2063,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
2013 | goto out; | 2063 | goto out; |
2014 | } | 2064 | } |
2015 | 2065 | ||
2016 | ret = wl1271_ps_elp_wakeup(wl, false); | 2066 | ret = wl1271_ps_elp_wakeup(wl); |
2017 | if (ret < 0) | 2067 | if (ret < 0) |
2018 | goto out; | 2068 | goto out; |
2019 | 2069 | ||
@@ -2039,7 +2089,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) | |||
2039 | goto out; | 2089 | goto out; |
2040 | } | 2090 | } |
2041 | 2091 | ||
2042 | ret = wl1271_ps_elp_wakeup(wl, false); | 2092 | ret = wl1271_ps_elp_wakeup(wl); |
2043 | if (ret < 0) | 2093 | if (ret < 0) |
2044 | goto out; | 2094 | goto out; |
2045 | 2095 | ||
@@ -2067,7 +2117,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
2067 | goto out; | 2117 | goto out; |
2068 | } | 2118 | } |
2069 | 2119 | ||
2070 | ret = wl1271_ps_elp_wakeup(wl, false); | 2120 | ret = wl1271_ps_elp_wakeup(wl); |
2071 | if (ret < 0) | 2121 | if (ret < 0) |
2072 | goto out; | 2122 | goto out; |
2073 | 2123 | ||
@@ -2546,7 +2596,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, | |||
2546 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 2596 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
2547 | goto out; | 2597 | goto out; |
2548 | 2598 | ||
2549 | ret = wl1271_ps_elp_wakeup(wl, false); | 2599 | ret = wl1271_ps_elp_wakeup(wl); |
2550 | if (ret < 0) | 2600 | if (ret < 0) |
2551 | goto out; | 2601 | goto out; |
2552 | 2602 | ||
@@ -2601,7 +2651,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
2601 | conf_tid->apsd_conf[0] = 0; | 2651 | conf_tid->apsd_conf[0] = 0; |
2602 | conf_tid->apsd_conf[1] = 0; | 2652 | conf_tid->apsd_conf[1] = 0; |
2603 | } else { | 2653 | } else { |
2604 | ret = wl1271_ps_elp_wakeup(wl, false); | 2654 | ret = wl1271_ps_elp_wakeup(wl); |
2605 | if (ret < 0) | 2655 | if (ret < 0) |
2606 | goto out; | 2656 | goto out; |
2607 | 2657 | ||
@@ -2647,7 +2697,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw) | |||
2647 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 2697 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
2648 | goto out; | 2698 | goto out; |
2649 | 2699 | ||
2650 | ret = wl1271_ps_elp_wakeup(wl, false); | 2700 | ret = wl1271_ps_elp_wakeup(wl); |
2651 | if (ret < 0) | 2701 | if (ret < 0) |
2652 | goto out; | 2702 | goto out; |
2653 | 2703 | ||
@@ -2736,7 +2786,7 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw, | |||
2736 | if (ret < 0) | 2786 | if (ret < 0) |
2737 | goto out; | 2787 | goto out; |
2738 | 2788 | ||
2739 | ret = wl1271_ps_elp_wakeup(wl, false); | 2789 | ret = wl1271_ps_elp_wakeup(wl); |
2740 | if (ret < 0) | 2790 | if (ret < 0) |
2741 | goto out_free_sta; | 2791 | goto out_free_sta; |
2742 | 2792 | ||
@@ -2779,7 +2829,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw, | |||
2779 | if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) | 2829 | if (WARN_ON(!test_bit(id, wl->ap_hlid_map))) |
2780 | goto out; | 2830 | goto out; |
2781 | 2831 | ||
2782 | ret = wl1271_ps_elp_wakeup(wl, false); | 2832 | ret = wl1271_ps_elp_wakeup(wl); |
2783 | if (ret < 0) | 2833 | if (ret < 0) |
2784 | goto out; | 2834 | goto out; |
2785 | 2835 | ||
@@ -2812,7 +2862,7 @@ int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2812 | goto out; | 2862 | goto out; |
2813 | } | 2863 | } |
2814 | 2864 | ||
2815 | ret = wl1271_ps_elp_wakeup(wl, false); | 2865 | ret = wl1271_ps_elp_wakeup(wl); |
2816 | if (ret < 0) | 2866 | if (ret < 0) |
2817 | goto out; | 2867 | goto out; |
2818 | 2868 | ||
@@ -3176,7 +3226,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev, | |||
3176 | if (wl->state == WL1271_STATE_OFF) | 3226 | if (wl->state == WL1271_STATE_OFF) |
3177 | goto out; | 3227 | goto out; |
3178 | 3228 | ||
3179 | ret = wl1271_ps_elp_wakeup(wl, false); | 3229 | ret = wl1271_ps_elp_wakeup(wl); |
3180 | if (ret < 0) | 3230 | if (ret < 0) |
3181 | goto out; | 3231 | goto out; |
3182 | 3232 | ||
@@ -3376,9 +3426,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3376 | for (j = 0; j < AP_MAX_LINKS; j++) | 3426 | for (j = 0; j < AP_MAX_LINKS; j++) |
3377 | skb_queue_head_init(&wl->links[j].tx_queue[i]); | 3427 | skb_queue_head_init(&wl->links[j].tx_queue[i]); |
3378 | 3428 | ||
3429 | skb_queue_head_init(&wl->deferred_rx_queue); | ||
3430 | skb_queue_head_init(&wl->deferred_tx_queue); | ||
3431 | |||
3379 | INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); | 3432 | INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work); |
3380 | INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); | 3433 | INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work); |
3381 | INIT_WORK(&wl->irq_work, wl1271_irq_work); | 3434 | INIT_WORK(&wl->netstack_work, wl1271_netstack_work); |
3382 | INIT_WORK(&wl->tx_work, wl1271_tx_work); | 3435 | INIT_WORK(&wl->tx_work, wl1271_tx_work); |
3383 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); | 3436 | INIT_WORK(&wl->recovery_work, wl1271_recovery_work); |
3384 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); | 3437 | INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work); |
@@ -3404,6 +3457,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3404 | wl->last_tx_hlid = 0; | 3457 | wl->last_tx_hlid = 0; |
3405 | wl->ap_ps_map = 0; | 3458 | wl->ap_ps_map = 0; |
3406 | wl->ap_fw_ps_map = 0; | 3459 | wl->ap_fw_ps_map = 0; |
3460 | wl->quirks = 0; | ||
3407 | 3461 | ||
3408 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); | 3462 | memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map)); |
3409 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 3463 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 5c347b1bd17f..971f13e792da 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -69,7 +69,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) | |||
69 | } | 69 | } |
70 | } | 70 | } |
71 | 71 | ||
72 | int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) | 72 | int wl1271_ps_elp_wakeup(struct wl1271 *wl) |
73 | { | 73 | { |
74 | DECLARE_COMPLETION_ONSTACK(compl); | 74 | DECLARE_COMPLETION_ONSTACK(compl); |
75 | unsigned long flags; | 75 | unsigned long flags; |
@@ -87,7 +87,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake) | |||
87 | * the completion variable in one entity. | 87 | * the completion variable in one entity. |
88 | */ | 88 | */ |
89 | spin_lock_irqsave(&wl->wl_lock, flags); | 89 | spin_lock_irqsave(&wl->wl_lock, flags); |
90 | if (work_pending(&wl->irq_work) || chip_awake) | 90 | if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) |
91 | pending = true; | 91 | pending = true; |
92 | else | 92 | else |
93 | wl->elp_compl = &compl; | 93 | wl->elp_compl = &compl; |
@@ -149,7 +149,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | |||
149 | case STATION_ACTIVE_MODE: | 149 | case STATION_ACTIVE_MODE: |
150 | default: | 150 | default: |
151 | wl1271_debug(DEBUG_PSM, "leaving psm"); | 151 | wl1271_debug(DEBUG_PSM, "leaving psm"); |
152 | ret = wl1271_ps_elp_wakeup(wl, false); | 152 | ret = wl1271_ps_elp_wakeup(wl); |
153 | if (ret < 0) | 153 | if (ret < 0) |
154 | return ret; | 154 | return ret; |
155 | 155 | ||
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h index fc1f4c193593..c41bd0a711bc 100644 --- a/drivers/net/wireless/wl12xx/ps.h +++ b/drivers/net/wireless/wl12xx/ps.h | |||
@@ -30,7 +30,7 @@ | |||
30 | int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | 30 | int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, |
31 | u32 rates, bool send); | 31 | u32 rates, bool send); |
32 | void wl1271_ps_elp_sleep(struct wl1271 *wl); | 32 | void wl1271_ps_elp_sleep(struct wl1271 *wl); |
33 | int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); | 33 | int wl1271_ps_elp_wakeup(struct wl1271 *wl); |
34 | void wl1271_elp_work(struct work_struct *work); | 34 | void wl1271_elp_work(struct work_struct *work); |
35 | void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); | 35 | void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues); |
36 | void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); | 36 | void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid); |
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index 3d13d7a83ea1..919b59f00301 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -129,7 +129,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
129 | 129 | ||
130 | skb_trim(skb, skb->len - desc->pad_len); | 130 | skb_trim(skb, skb->len - desc->pad_len); |
131 | 131 | ||
132 | ieee80211_rx_ni(wl->hw, skb); | 132 | skb_queue_tail(&wl->deferred_rx_queue, skb); |
133 | ieee80211_queue_work(wl->hw, &wl->netstack_work); | ||
133 | 134 | ||
134 | return 0; | 135 | return 0; |
135 | } | 136 | } |
@@ -198,7 +199,13 @@ void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) | |||
198 | pkt_offset += pkt_length; | 199 | pkt_offset += pkt_length; |
199 | } | 200 | } |
200 | } | 201 | } |
201 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | 202 | |
203 | /* | ||
204 | * Write the driver's packet counter to the FW. This is only required | ||
205 | * for older hardware revisions | ||
206 | */ | ||
207 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) | ||
208 | wl1271_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter); | ||
202 | } | 209 | } |
203 | 210 | ||
204 | void wl1271_set_default_filters(struct wl1271 *wl) | 211 | void wl1271_set_default_filters(struct wl1271 *wl) |
diff --git a/drivers/net/wireless/wl12xx/scan.c b/drivers/net/wireless/wl12xx/scan.c index 6f897b9d90ca..420653a2859c 100644 --- a/drivers/net/wireless/wl12xx/scan.c +++ b/drivers/net/wireless/wl12xx/scan.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "cmd.h" | 27 | #include "cmd.h" |
28 | #include "scan.h" | 28 | #include "scan.h" |
29 | #include "acx.h" | 29 | #include "acx.h" |
30 | #include "ps.h" | ||
30 | 31 | ||
31 | void wl1271_scan_complete_work(struct work_struct *work) | 32 | void wl1271_scan_complete_work(struct work_struct *work) |
32 | { | 33 | { |
@@ -40,10 +41,11 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
40 | 41 | ||
41 | mutex_lock(&wl->mutex); | 42 | mutex_lock(&wl->mutex); |
42 | 43 | ||
43 | if (wl->scan.state == WL1271_SCAN_STATE_IDLE) { | 44 | if (wl->state == WL1271_STATE_OFF) |
44 | mutex_unlock(&wl->mutex); | 45 | goto out; |
45 | return; | 46 | |
46 | } | 47 | if (wl->scan.state == WL1271_SCAN_STATE_IDLE) |
48 | goto out; | ||
47 | 49 | ||
48 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 50 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
49 | kfree(wl->scan.scanned_ch); | 51 | kfree(wl->scan.scanned_ch); |
@@ -52,13 +54,19 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
52 | ieee80211_scan_completed(wl->hw, false); | 54 | ieee80211_scan_completed(wl->hw, false); |
53 | 55 | ||
54 | /* restore hardware connection monitoring template */ | 56 | /* restore hardware connection monitoring template */ |
55 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) | 57 | if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) { |
56 | wl1271_cmd_build_ap_probe_req(wl, wl->probereq); | 58 | if (wl1271_ps_elp_wakeup(wl) == 0) { |
59 | wl1271_cmd_build_ap_probe_req(wl, wl->probereq); | ||
60 | wl1271_ps_elp_sleep(wl); | ||
61 | } | ||
62 | } | ||
57 | 63 | ||
58 | if (wl->scan.failed) { | 64 | if (wl->scan.failed) { |
59 | wl1271_info("Scan completed due to error."); | 65 | wl1271_info("Scan completed due to error."); |
60 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | 66 | ieee80211_queue_work(wl->hw, &wl->recovery_work); |
61 | } | 67 | } |
68 | |||
69 | out: | ||
62 | mutex_unlock(&wl->mutex); | 70 | mutex_unlock(&wl->mutex); |
63 | 71 | ||
64 | } | 72 | } |
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c index d5e874825069..5b9dbeafec06 100644 --- a/drivers/net/wireless/wl12xx/sdio.c +++ b/drivers/net/wireless/wl12xx/sdio.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mmc/sdio_func.h> | 28 | #include <linux/mmc/sdio_func.h> |
29 | #include <linux/mmc/sdio_ids.h> | 29 | #include <linux/mmc/sdio_ids.h> |
30 | #include <linux/mmc/card.h> | 30 | #include <linux/mmc/card.h> |
31 | #include <linux/mmc/host.h> | ||
31 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
32 | #include <linux/wl12xx.h> | 33 | #include <linux/wl12xx.h> |
33 | #include <linux/pm_runtime.h> | 34 | #include <linux/pm_runtime.h> |
@@ -60,7 +61,7 @@ static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl) | |||
60 | return &(wl_to_func(wl)->dev); | 61 | return &(wl_to_func(wl)->dev); |
61 | } | 62 | } |
62 | 63 | ||
63 | static irqreturn_t wl1271_irq(int irq, void *cookie) | 64 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) |
64 | { | 65 | { |
65 | struct wl1271 *wl = cookie; | 66 | struct wl1271 *wl = cookie; |
66 | unsigned long flags; | 67 | unsigned long flags; |
@@ -69,17 +70,14 @@ static irqreturn_t wl1271_irq(int irq, void *cookie) | |||
69 | 70 | ||
70 | /* complete the ELP completion */ | 71 | /* complete the ELP completion */ |
71 | spin_lock_irqsave(&wl->wl_lock, flags); | 72 | spin_lock_irqsave(&wl->wl_lock, flags); |
73 | set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
72 | if (wl->elp_compl) { | 74 | if (wl->elp_compl) { |
73 | complete(wl->elp_compl); | 75 | complete(wl->elp_compl); |
74 | wl->elp_compl = NULL; | 76 | wl->elp_compl = NULL; |
75 | } | 77 | } |
76 | |||
77 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
78 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
79 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
80 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 78 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
81 | 79 | ||
82 | return IRQ_HANDLED; | 80 | return IRQ_WAKE_THREAD; |
83 | } | 81 | } |
84 | 82 | ||
85 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) | 83 | static void wl1271_sdio_disable_interrupts(struct wl1271 *wl) |
@@ -106,8 +104,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
106 | int ret; | 104 | int ret; |
107 | struct sdio_func *func = wl_to_func(wl); | 105 | struct sdio_func *func = wl_to_func(wl); |
108 | 106 | ||
109 | sdio_claim_host(func); | ||
110 | |||
111 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 107 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
112 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); | 108 | ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); |
113 | wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", | 109 | wl1271_debug(DEBUG_SDIO, "sdio read 52 addr 0x%x, byte 0x%02x", |
@@ -123,8 +119,6 @@ static void wl1271_sdio_raw_read(struct wl1271 *wl, int addr, void *buf, | |||
123 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); | 119 | wl1271_dump_ascii(DEBUG_SDIO, "data: ", buf, len); |
124 | } | 120 | } |
125 | 121 | ||
126 | sdio_release_host(func); | ||
127 | |||
128 | if (ret) | 122 | if (ret) |
129 | wl1271_error("sdio read failed (%d)", ret); | 123 | wl1271_error("sdio read failed (%d)", ret); |
130 | } | 124 | } |
@@ -135,8 +129,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
135 | int ret; | 129 | int ret; |
136 | struct sdio_func *func = wl_to_func(wl); | 130 | struct sdio_func *func = wl_to_func(wl); |
137 | 131 | ||
138 | sdio_claim_host(func); | ||
139 | |||
140 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { | 132 | if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG_ADDR)) { |
141 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); | 133 | sdio_f0_writeb(func, ((u8 *)buf)[0], addr, &ret); |
142 | wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", | 134 | wl1271_debug(DEBUG_SDIO, "sdio write 52 addr 0x%x, byte 0x%02x", |
@@ -152,8 +144,6 @@ static void wl1271_sdio_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
152 | ret = sdio_memcpy_toio(func, addr, buf, len); | 144 | ret = sdio_memcpy_toio(func, addr, buf, len); |
153 | } | 145 | } |
154 | 146 | ||
155 | sdio_release_host(func); | ||
156 | |||
157 | if (ret) | 147 | if (ret) |
158 | wl1271_error("sdio write failed (%d)", ret); | 148 | wl1271_error("sdio write failed (%d)", ret); |
159 | } | 149 | } |
@@ -163,14 +153,18 @@ static int wl1271_sdio_power_on(struct wl1271 *wl) | |||
163 | struct sdio_func *func = wl_to_func(wl); | 153 | struct sdio_func *func = wl_to_func(wl); |
164 | int ret; | 154 | int ret; |
165 | 155 | ||
166 | /* Power up the card */ | 156 | /* Make sure the card will not be powered off by runtime PM */ |
167 | ret = pm_runtime_get_sync(&func->dev); | 157 | ret = pm_runtime_get_sync(&func->dev); |
168 | if (ret < 0) | 158 | if (ret < 0) |
169 | goto out; | 159 | goto out; |
170 | 160 | ||
161 | /* Runtime PM might be disabled, so power up the card manually */ | ||
162 | ret = mmc_power_restore_host(func->card->host); | ||
163 | if (ret < 0) | ||
164 | goto out; | ||
165 | |||
171 | sdio_claim_host(func); | 166 | sdio_claim_host(func); |
172 | sdio_enable_func(func); | 167 | sdio_enable_func(func); |
173 | sdio_release_host(func); | ||
174 | 168 | ||
175 | out: | 169 | out: |
176 | return ret; | 170 | return ret; |
@@ -179,12 +173,17 @@ out: | |||
179 | static int wl1271_sdio_power_off(struct wl1271 *wl) | 173 | static int wl1271_sdio_power_off(struct wl1271 *wl) |
180 | { | 174 | { |
181 | struct sdio_func *func = wl_to_func(wl); | 175 | struct sdio_func *func = wl_to_func(wl); |
176 | int ret; | ||
182 | 177 | ||
183 | sdio_claim_host(func); | ||
184 | sdio_disable_func(func); | 178 | sdio_disable_func(func); |
185 | sdio_release_host(func); | 179 | sdio_release_host(func); |
186 | 180 | ||
187 | /* Power down the card */ | 181 | /* Runtime PM might be disabled, so power off the card manually */ |
182 | ret = mmc_power_save_host(func->card->host); | ||
183 | if (ret < 0) | ||
184 | return ret; | ||
185 | |||
186 | /* Let runtime PM know the card is powered off */ | ||
188 | return pm_runtime_put_sync(&func->dev); | 187 | return pm_runtime_put_sync(&func->dev); |
189 | } | 188 | } |
190 | 189 | ||
@@ -241,14 +240,14 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
241 | wl->irq = wlan_data->irq; | 240 | wl->irq = wlan_data->irq; |
242 | wl->ref_clock = wlan_data->board_ref_clock; | 241 | wl->ref_clock = wlan_data->board_ref_clock; |
243 | 242 | ||
244 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | 243 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
244 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
245 | DRIVER_NAME, wl); | ||
245 | if (ret < 0) { | 246 | if (ret < 0) { |
246 | wl1271_error("request_irq() failed: %d", ret); | 247 | wl1271_error("request_irq() failed: %d", ret); |
247 | goto out_free; | 248 | goto out_free; |
248 | } | 249 | } |
249 | 250 | ||
250 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
251 | |||
252 | disable_irq(wl->irq); | 251 | disable_irq(wl->irq); |
253 | 252 | ||
254 | ret = wl1271_init_ieee80211(wl); | 253 | ret = wl1271_init_ieee80211(wl); |
@@ -271,7 +270,6 @@ static int __devinit wl1271_probe(struct sdio_func *func, | |||
271 | out_irq: | 270 | out_irq: |
272 | free_irq(wl->irq, wl); | 271 | free_irq(wl->irq, wl); |
273 | 272 | ||
274 | |||
275 | out_free: | 273 | out_free: |
276 | wl1271_free_hw(wl); | 274 | wl1271_free_hw(wl); |
277 | 275 | ||
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c index 0132dad756c4..18cf01719ae0 100644 --- a/drivers/net/wireless/wl12xx/spi.c +++ b/drivers/net/wireless/wl12xx/spi.c | |||
@@ -320,28 +320,23 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf, | |||
320 | spi_sync(wl_to_spi(wl), &m); | 320 | spi_sync(wl_to_spi(wl), &m); |
321 | } | 321 | } |
322 | 322 | ||
323 | static irqreturn_t wl1271_irq(int irq, void *cookie) | 323 | static irqreturn_t wl1271_hardirq(int irq, void *cookie) |
324 | { | 324 | { |
325 | struct wl1271 *wl; | 325 | struct wl1271 *wl = cookie; |
326 | unsigned long flags; | 326 | unsigned long flags; |
327 | 327 | ||
328 | wl1271_debug(DEBUG_IRQ, "IRQ"); | 328 | wl1271_debug(DEBUG_IRQ, "IRQ"); |
329 | 329 | ||
330 | wl = cookie; | ||
331 | |||
332 | /* complete the ELP completion */ | 330 | /* complete the ELP completion */ |
333 | spin_lock_irqsave(&wl->wl_lock, flags); | 331 | spin_lock_irqsave(&wl->wl_lock, flags); |
332 | set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); | ||
334 | if (wl->elp_compl) { | 333 | if (wl->elp_compl) { |
335 | complete(wl->elp_compl); | 334 | complete(wl->elp_compl); |
336 | wl->elp_compl = NULL; | 335 | wl->elp_compl = NULL; |
337 | } | 336 | } |
338 | |||
339 | if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags)) | ||
340 | ieee80211_queue_work(wl->hw, &wl->irq_work); | ||
341 | set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags); | ||
342 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 337 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
343 | 338 | ||
344 | return IRQ_HANDLED; | 339 | return IRQ_WAKE_THREAD; |
345 | } | 340 | } |
346 | 341 | ||
347 | static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) | 342 | static int wl1271_spi_set_power(struct wl1271 *wl, bool enable) |
@@ -413,14 +408,14 @@ static int __devinit wl1271_probe(struct spi_device *spi) | |||
413 | goto out_free; | 408 | goto out_free; |
414 | } | 409 | } |
415 | 410 | ||
416 | ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl); | 411 | ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq, |
412 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
413 | DRIVER_NAME, wl); | ||
417 | if (ret < 0) { | 414 | if (ret < 0) { |
418 | wl1271_error("request_irq() failed: %d", ret); | 415 | wl1271_error("request_irq() failed: %d", ret); |
419 | goto out_free; | 416 | goto out_free; |
420 | } | 417 | } |
421 | 418 | ||
422 | set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); | ||
423 | |||
424 | disable_irq(wl->irq); | 419 | disable_irq(wl->irq); |
425 | 420 | ||
426 | ret = wl1271_init_ieee80211(wl); | 421 | ret = wl1271_init_ieee80211(wl); |
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index ac60d577319f..5e9ef7d53e7e 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -464,7 +464,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
464 | 464 | ||
465 | while ((skb = wl1271_skb_dequeue(wl))) { | 465 | while ((skb = wl1271_skb_dequeue(wl))) { |
466 | if (!woken_up) { | 466 | if (!woken_up) { |
467 | ret = wl1271_ps_elp_wakeup(wl, false); | 467 | ret = wl1271_ps_elp_wakeup(wl); |
468 | if (ret < 0) | 468 | if (ret < 0) |
469 | goto out_ack; | 469 | goto out_ack; |
470 | woken_up = true; | 470 | woken_up = true; |
@@ -506,8 +506,14 @@ out_ack: | |||
506 | sent_packets = true; | 506 | sent_packets = true; |
507 | } | 507 | } |
508 | if (sent_packets) { | 508 | if (sent_packets) { |
509 | /* interrupt the firmware with the new packets */ | 509 | /* |
510 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count); | 510 | * Interrupt the firmware with the new packets. This is only |
511 | * required for older hardware revisions | ||
512 | */ | ||
513 | if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) | ||
514 | wl1271_write32(wl, WL1271_HOST_WR_ACCESS, | ||
515 | wl->tx_packets_count); | ||
516 | |||
511 | wl1271_handle_tx_low_watermark(wl); | 517 | wl1271_handle_tx_low_watermark(wl); |
512 | } | 518 | } |
513 | 519 | ||
@@ -583,7 +589,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, | |||
583 | result->rate_class_index, result->status); | 589 | result->rate_class_index, result->status); |
584 | 590 | ||
585 | /* return the packet to the stack */ | 591 | /* return the packet to the stack */ |
586 | ieee80211_tx_status(wl->hw, skb); | 592 | skb_queue_tail(&wl->deferred_tx_queue, skb); |
593 | ieee80211_queue_work(wl->hw, &wl->netstack_work); | ||
587 | wl1271_free_tx_id(wl, result->id); | 594 | wl1271_free_tx_id(wl, result->id); |
588 | } | 595 | } |
589 | 596 | ||
@@ -687,16 +694,30 @@ void wl1271_tx_reset(struct wl1271 *wl) | |||
687 | */ | 694 | */ |
688 | wl1271_handle_tx_low_watermark(wl); | 695 | wl1271_handle_tx_low_watermark(wl); |
689 | 696 | ||
690 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) | 697 | for (i = 0; i < ACX_TX_DESCRIPTORS; i++) { |
691 | if (wl->tx_frames[i] != NULL) { | 698 | if (wl->tx_frames[i] == NULL) |
692 | skb = wl->tx_frames[i]; | 699 | continue; |
693 | wl1271_free_tx_id(wl, i); | 700 | |
694 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); | 701 | skb = wl->tx_frames[i]; |
695 | info = IEEE80211_SKB_CB(skb); | 702 | wl1271_free_tx_id(wl, i); |
696 | info->status.rates[0].idx = -1; | 703 | wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb); |
697 | info->status.rates[0].count = 0; | 704 | |
698 | ieee80211_tx_status(wl->hw, skb); | 705 | /* Remove private headers before passing the skb to mac80211 */ |
706 | info = IEEE80211_SKB_CB(skb); | ||
707 | skb_pull(skb, sizeof(struct wl1271_tx_hw_descr)); | ||
708 | if (info->control.hw_key && | ||
709 | info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) { | ||
710 | int hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
711 | memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data, | ||
712 | hdrlen); | ||
713 | skb_pull(skb, WL1271_TKIP_IV_SPACE); | ||
699 | } | 714 | } |
715 | |||
716 | info->status.rates[0].idx = -1; | ||
717 | info->status.rates[0].count = 0; | ||
718 | |||
719 | ieee80211_tx_status(wl->hw, skb); | ||
720 | } | ||
700 | } | 721 | } |
701 | 722 | ||
702 | #define WL1271_TX_FLUSH_TIMEOUT 500000 | 723 | #define WL1271_TX_FLUSH_TIMEOUT 500000 |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 338acc9f60b3..86be83e25ec5 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -130,10 +130,10 @@ extern u32 wl12xx_debug_level; | |||
130 | 130 | ||
131 | 131 | ||
132 | 132 | ||
133 | #define WL1271_FW_NAME "wl1271-fw-2.bin" | 133 | #define WL1271_FW_NAME "ti-connectivity/wl1271-fw-2.bin" |
134 | #define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" | 134 | #define WL1271_AP_FW_NAME "ti-connectivity/wl1271-fw-ap.bin" |
135 | 135 | ||
136 | #define WL1271_NVS_NAME "wl1271-nvs.bin" | 136 | #define WL1271_NVS_NAME "ti-connectivity/wl1271-nvs.bin" |
137 | 137 | ||
138 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) | 138 | #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff)) |
139 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) | 139 | #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff)) |
@@ -317,10 +317,10 @@ enum wl12xx_flags { | |||
317 | WL1271_FLAG_JOINED, | 317 | WL1271_FLAG_JOINED, |
318 | WL1271_FLAG_GPIO_POWER, | 318 | WL1271_FLAG_GPIO_POWER, |
319 | WL1271_FLAG_TX_QUEUE_STOPPED, | 319 | WL1271_FLAG_TX_QUEUE_STOPPED, |
320 | WL1271_FLAG_TX_PENDING, | ||
320 | WL1271_FLAG_IN_ELP, | 321 | WL1271_FLAG_IN_ELP, |
321 | WL1271_FLAG_PSM, | 322 | WL1271_FLAG_PSM, |
322 | WL1271_FLAG_PSM_REQUESTED, | 323 | WL1271_FLAG_PSM_REQUESTED, |
323 | WL1271_FLAG_IRQ_PENDING, | ||
324 | WL1271_FLAG_IRQ_RUNNING, | 324 | WL1271_FLAG_IRQ_RUNNING, |
325 | WL1271_FLAG_IDLE, | 325 | WL1271_FLAG_IDLE, |
326 | WL1271_FLAG_IDLE_REQUESTED, | 326 | WL1271_FLAG_IDLE_REQUESTED, |
@@ -404,6 +404,12 @@ struct wl1271 { | |||
404 | struct sk_buff_head tx_queue[NUM_TX_QUEUES]; | 404 | struct sk_buff_head tx_queue[NUM_TX_QUEUES]; |
405 | int tx_queue_count; | 405 | int tx_queue_count; |
406 | 406 | ||
407 | /* Frames received, not handled yet by mac80211 */ | ||
408 | struct sk_buff_head deferred_rx_queue; | ||
409 | |||
410 | /* Frames sent, not returned yet to mac80211 */ | ||
411 | struct sk_buff_head deferred_tx_queue; | ||
412 | |||
407 | struct work_struct tx_work; | 413 | struct work_struct tx_work; |
408 | 414 | ||
409 | /* Pending TX frames */ | 415 | /* Pending TX frames */ |
@@ -424,8 +430,8 @@ struct wl1271 { | |||
424 | /* Intermediate buffer, used for packet aggregation */ | 430 | /* Intermediate buffer, used for packet aggregation */ |
425 | u8 *aggr_buf; | 431 | u8 *aggr_buf; |
426 | 432 | ||
427 | /* The target interrupt mask */ | 433 | /* Network stack work */ |
428 | struct work_struct irq_work; | 434 | struct work_struct netstack_work; |
429 | 435 | ||
430 | /* Hardware recovery work */ | 436 | /* Hardware recovery work */ |
431 | struct work_struct recovery_work; | 437 | struct work_struct recovery_work; |
@@ -535,6 +541,9 @@ struct wl1271 { | |||
535 | 541 | ||
536 | /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ | 542 | /* AP-mode - a bitmap of links currently in PS mode in mac80211 */ |
537 | unsigned long ap_ps_map; | 543 | unsigned long ap_ps_map; |
544 | |||
545 | /* Quirks of specific hardware revisions */ | ||
546 | unsigned int quirks; | ||
538 | }; | 547 | }; |
539 | 548 | ||
540 | struct wl1271_station { | 549 | struct wl1271_station { |
@@ -553,6 +562,8 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
553 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 | 562 | #define WL1271_TX_QUEUE_LOW_WATERMARK 10 |
554 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 | 563 | #define WL1271_TX_QUEUE_HIGH_WATERMARK 25 |
555 | 564 | ||
565 | #define WL1271_DEFERRED_QUEUE_LIMIT 64 | ||
566 | |||
556 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power | 567 | /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power |
557 | on in case is has been shut down shortly before */ | 568 | on in case is has been shut down shortly before */ |
558 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ | 569 | #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */ |
@@ -562,4 +573,9 @@ int wl1271_plt_stop(struct wl1271 *wl); | |||
562 | #define HW_BG_RATES_MASK 0xffff | 573 | #define HW_BG_RATES_MASK 0xffff |
563 | #define HW_HT_RATES_OFFSET 16 | 574 | #define HW_HT_RATES_OFFSET 16 |
564 | 575 | ||
576 | /* Quirks */ | ||
577 | |||
578 | /* Each RX/TX transaction requires an end-of-transaction transfer */ | ||
579 | #define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0) | ||
580 | |||
565 | #endif | 581 | #endif |