aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Reis <idor@ti.com>2012-04-23 10:35:25 -0400
committerLuciano Coelho <coelho@ti.com>2012-06-07 11:11:01 -0400
commitf5755fe96cb010031a50458e6d1391377d94c275 (patch)
treeb33e6dc91f3a3d1c5e975a4553973d7cd2761eef
parent16ea4733210d741eeb5413acd261e675a12f980e (diff)
wl18xx: PG2.0 HW Watch dog interrupt support
In PG2, the HW watchdog interrupt occupies bit0 of the event vector, and the SW watchdog is relocated to bit9. We perform the relocation globally, as there's only one watchdog bit on previous platforms (bit0). [Only mask in the new bit9 for platforms supporting it. This avoids spurious events on other platforms - Arik] Signed-off-by: Orit Brayer <orit@ti.com> Signed-off-by: Ido Reis <idor@ti.com> Signed-off-by: Arik Nemtsov <arik@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
-rw-r--r--drivers/net/wireless/ti/wl12xx/acx.h14
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c4
-rw-r--r--drivers/net/wireless/ti/wl18xx/acx.h20
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c14
-rw-r--r--drivers/net/wireless/ti/wlcore/acx.h27
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c13
6 files changed, 71 insertions, 21 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/acx.h b/drivers/net/wireless/ti/wl12xx/acx.h
index 1be0f2d31b19..2a26868b837d 100644
--- a/drivers/net/wireless/ti/wl12xx/acx.h
+++ b/drivers/net/wireless/ti/wl12xx/acx.h
@@ -26,6 +26,20 @@
26#include "../wlcore/wlcore.h" 26#include "../wlcore/wlcore.h"
27#include "../wlcore/acx.h" 27#include "../wlcore/acx.h"
28 28
29#define WL12XX_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \
30 WL1271_ACX_INTR_INIT_COMPLETE | \
31 WL1271_ACX_INTR_EVENT_A | \
32 WL1271_ACX_INTR_EVENT_B | \
33 WL1271_ACX_INTR_CMD_COMPLETE | \
34 WL1271_ACX_INTR_HW_AVAILABLE | \
35 WL1271_ACX_INTR_DATA)
36
37#define WL12XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
38 WL1271_ACX_INTR_EVENT_A | \
39 WL1271_ACX_INTR_EVENT_B | \
40 WL1271_ACX_INTR_HW_AVAILABLE | \
41 WL1271_ACX_INTR_DATA)
42
29struct wl1271_acx_host_config_bitmap { 43struct wl1271_acx_host_config_bitmap {
30 struct acx_header header; 44 struct acx_header header;
31 45
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index 41017baaf253..f74d76c95a7f 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1034,11 +1034,11 @@ static void wl12xx_pre_upload(struct wl1271 *wl)
1034 1034
1035static void wl12xx_enable_interrupts(struct wl1271 *wl) 1035static void wl12xx_enable_interrupts(struct wl1271 *wl)
1036{ 1036{
1037 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); 1037 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR);
1038 1038
1039 wlcore_enable_interrupts(wl); 1039 wlcore_enable_interrupts(wl);
1040 wlcore_write_reg(wl, REG_INTERRUPT_MASK, 1040 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
1041 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 1041 WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK));
1042 1042
1043 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); 1043 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
1044} 1044}
diff --git a/drivers/net/wireless/ti/wl18xx/acx.h b/drivers/net/wireless/ti/wl18xx/acx.h
index cb6fd85d077f..7d74b031f114 100644
--- a/drivers/net/wireless/ti/wl18xx/acx.h
+++ b/drivers/net/wireless/ti/wl18xx/acx.h
@@ -28,6 +28,26 @@
28/* numbers of bits the length field takes (add 1 for the actual number) */ 28/* numbers of bits the length field takes (add 1 for the actual number) */
29#define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 29#define WL18XX_HOST_IF_LEN_SIZE_FIELD 15
30 30
31#define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \
32 WL1271_ACX_INTR_INIT_COMPLETE | \
33 WL1271_ACX_INTR_EVENT_A | \
34 WL1271_ACX_INTR_EVENT_B | \
35 WL1271_ACX_INTR_CMD_COMPLETE | \
36 WL1271_ACX_INTR_HW_AVAILABLE | \
37 WL1271_ACX_INTR_DATA)
38
39#define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \
40 WL1271_ACX_SW_INTR_WATCHDOG)
41
42#define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \
43 WL1271_ACX_INTR_EVENT_A | \
44 WL1271_ACX_INTR_EVENT_B | \
45 WL1271_ACX_INTR_HW_AVAILABLE | \
46 WL1271_ACX_INTR_DATA)
47
48#define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \
49 WL1271_ACX_SW_INTR_WATCHDOG)
50
31struct wl18xx_acx_host_config_bitmap { 51struct wl18xx_acx_host_config_bitmap {
32 struct acx_header header; 52 struct acx_header header;
33 53
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index bdf4ee12914d..84f8e27c29ab 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -776,11 +776,21 @@ static void wl18xx_set_mac_and_phy(struct wl1271 *wl)
776 776
777static void wl18xx_enable_interrupts(struct wl1271 *wl) 777static void wl18xx_enable_interrupts(struct wl1271 *wl)
778{ 778{
779 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR); 779 u32 event_mask, intr_mask;
780
781 if (wl->chip.id == CHIP_ID_185x_PG10) {
782 event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1;
783 intr_mask = WL18XX_INTR_MASK_PG1;
784 } else {
785 event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2;
786 intr_mask = WL18XX_INTR_MASK_PG2;
787 }
788
789 wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
780 790
781 wlcore_enable_interrupts(wl); 791 wlcore_enable_interrupts(wl);
782 wlcore_write_reg(wl, REG_INTERRUPT_MASK, 792 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
783 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK)); 793 WL1271_ACX_INTR_ALL & ~intr_mask);
784} 794}
785 795
786static int wl18xx_boot(struct wl1271 *wl) 796static int wl18xx_boot(struct wl1271 *wl)
diff --git a/drivers/net/wireless/ti/wlcore/acx.h b/drivers/net/wireless/ti/wlcore/acx.h
index 46c300d4dea4..c0181258b722 100644
--- a/drivers/net/wireless/ti/wlcore/acx.h
+++ b/drivers/net/wireless/ti/wlcore/acx.h
@@ -51,21 +51,18 @@
51#define WL1271_ACX_INTR_TRACE_A BIT(7) 51#define WL1271_ACX_INTR_TRACE_A BIT(7)
52/* Trace message on MBOX #B */ 52/* Trace message on MBOX #B */
53#define WL1271_ACX_INTR_TRACE_B BIT(8) 53#define WL1271_ACX_INTR_TRACE_B BIT(8)
54 54/* SW FW Initiated interrupt Watchdog timer expiration */
55#define WL1271_ACX_INTR_ALL 0xFFFFFFFF 55#define WL1271_ACX_SW_INTR_WATCHDOG BIT(9)
56#define WL1271_ACX_ALL_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ 56
57 WL1271_ACX_INTR_INIT_COMPLETE | \ 57#define WL1271_ACX_INTR_ALL 0xFFFFFFFF
58 WL1271_ACX_INTR_EVENT_A | \ 58
59 WL1271_ACX_INTR_EVENT_B | \ 59/* all possible interrupts - only appropriate ones will be masked in */
60 WL1271_ACX_INTR_CMD_COMPLETE | \ 60#define WLCORE_ALL_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \
61 WL1271_ACX_INTR_HW_AVAILABLE | \ 61 WL1271_ACX_INTR_EVENT_A | \
62 WL1271_ACX_INTR_DATA) 62 WL1271_ACX_INTR_EVENT_B | \
63 63 WL1271_ACX_INTR_HW_AVAILABLE | \
64#define WL1271_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ 64 WL1271_ACX_INTR_DATA | \
65 WL1271_ACX_INTR_EVENT_A | \ 65 WL1271_ACX_SW_INTR_WATCHDOG)
66 WL1271_ACX_INTR_EVENT_B | \
67 WL1271_ACX_INTR_HW_AVAILABLE | \
68 WL1271_ACX_INTR_DATA)
69 66
70/* Target's information element */ 67/* Target's information element */
71struct acx_header { 68struct acx_header {
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 8800a63539e3..176a3117889b 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -535,14 +535,23 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
535 wlcore_hw_tx_immediate_compl(wl); 535 wlcore_hw_tx_immediate_compl(wl);
536 536
537 intr = le32_to_cpu(wl->fw_status_1->intr); 537 intr = le32_to_cpu(wl->fw_status_1->intr);
538 intr &= WL1271_INTR_MASK; 538 intr &= WLCORE_ALL_INTR_MASK;
539 if (!intr) { 539 if (!intr) {
540 done = true; 540 done = true;
541 continue; 541 continue;
542 } 542 }
543 543
544 if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { 544 if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
545 wl1271_error("watchdog interrupt received! " 545 wl1271_error("HW watchdog interrupt received! starting recovery.");
546 wl->watchdog_recovery = true;
547 wl12xx_queue_recovery_work(wl);
548
549 /* restarting the chip. ignore any other interrupt. */
550 goto out;
551 }
552
553 if (unlikely(intr & WL1271_ACX_SW_INTR_WATCHDOG)) {
554 wl1271_error("SW watchdog interrupt received! "
546 "starting recovery."); 555 "starting recovery.");
547 wl->watchdog_recovery = true; 556 wl->watchdog_recovery = true;
548 wl12xx_queue_recovery_work(wl); 557 wl12xx_queue_recovery_work(wl);