diff options
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 74 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_reg.h | 2 |
2 files changed, 31 insertions, 45 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 22d44ba2e96..8ac9bc1b944 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -76,20 +76,14 @@ static void wl1271_power_on(struct wl1271 *wl) | |||
76 | wl->set_power(true); | 76 | wl->set_power(true); |
77 | } | 77 | } |
78 | 78 | ||
79 | static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status) | 79 | static void wl1271_fw_status(struct wl1271 *wl, |
80 | struct wl1271_fw_status *status) | ||
80 | { | 81 | { |
81 | u32 total = 0; | 82 | u32 total = 0; |
82 | int i; | 83 | int i; |
83 | 84 | ||
84 | /* | 85 | wl1271_spi_reg_read(wl, FW_STATUS_ADDR, status, |
85 | * FIXME: Reading the FW status directly from the registers seems to | 86 | sizeof(*status), false); |
86 | * be the right thing to do, but it doesn't work. And in the | ||
87 | * reference driver, there is a workaround called | ||
88 | * USE_SDIO_24M_WORKAROUND, which reads the status from memory | ||
89 | * instead, so we do the same here. | ||
90 | */ | ||
91 | |||
92 | wl1271_spi_mem_read(wl, STATUS_MEM_ADDRESS, status, sizeof(*status)); | ||
93 | 87 | ||
94 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 88 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
95 | "drv_rx_counter = %d, tx_results_counter = %d)", | 89 | "drv_rx_counter = %d, tx_results_counter = %d)", |
@@ -114,11 +108,10 @@ static void wl1271_fw_status(struct wl1271 *wl, struct wl1271_fw_status *status) | |||
114 | wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime; | 108 | wl->time_offset = jiffies_to_usecs(jiffies) - status->fw_localtime; |
115 | } | 109 | } |
116 | 110 | ||
117 | #define WL1271_IRQ_MAX_LOOPS 10 | ||
118 | static void wl1271_irq_work(struct work_struct *work) | 111 | static void wl1271_irq_work(struct work_struct *work) |
119 | { | 112 | { |
120 | u32 intr, ctr = WL1271_IRQ_MAX_LOOPS; | ||
121 | int ret; | 113 | int ret; |
114 | u32 intr; | ||
122 | struct wl1271 *wl = | 115 | struct wl1271 *wl = |
123 | container_of(work, struct wl1271, irq_work); | 116 | container_of(work, struct wl1271, irq_work); |
124 | 117 | ||
@@ -135,7 +128,8 @@ static void wl1271_irq_work(struct work_struct *work) | |||
135 | 128 | ||
136 | wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); | 129 | wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); |
137 | 130 | ||
138 | intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); | 131 | wl1271_fw_status(wl, wl->fw_status); |
132 | intr = wl->fw_status->intr; | ||
139 | if (!intr) { | 133 | if (!intr) { |
140 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 134 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); |
141 | goto out_sleep; | 135 | goto out_sleep; |
@@ -143,43 +137,35 @@ static void wl1271_irq_work(struct work_struct *work) | |||
143 | 137 | ||
144 | intr &= WL1271_INTR_MASK; | 138 | intr &= WL1271_INTR_MASK; |
145 | 139 | ||
146 | do { | 140 | if (intr & (WL1271_ACX_INTR_EVENT_A | |
147 | wl1271_fw_status(wl, wl->fw_status); | 141 | WL1271_ACX_INTR_EVENT_B)) { |
148 | 142 | wl1271_debug(DEBUG_IRQ, | |
149 | 143 | "WL1271_ACX_INTR_EVENT (0x%x)", intr); | |
150 | if (intr & (WL1271_ACX_INTR_EVENT_A | | 144 | if (intr & WL1271_ACX_INTR_EVENT_A) |
151 | WL1271_ACX_INTR_EVENT_B)) { | 145 | wl1271_event_handle(wl, 0); |
152 | wl1271_debug(DEBUG_IRQ, | 146 | else |
153 | "WL1271_ACX_INTR_EVENT (0x%x)", intr); | 147 | wl1271_event_handle(wl, 1); |
154 | if (intr & WL1271_ACX_INTR_EVENT_A) | 148 | } |
155 | wl1271_event_handle(wl, 0); | ||
156 | else | ||
157 | wl1271_event_handle(wl, 1); | ||
158 | } | ||
159 | 149 | ||
160 | if (intr & WL1271_ACX_INTR_INIT_COMPLETE) | 150 | if (intr & WL1271_ACX_INTR_INIT_COMPLETE) |
161 | wl1271_debug(DEBUG_IRQ, | 151 | wl1271_debug(DEBUG_IRQ, |
162 | "WL1271_ACX_INTR_INIT_COMPLETE"); | 152 | "WL1271_ACX_INTR_INIT_COMPLETE"); |
163 | 153 | ||
164 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) | 154 | if (intr & WL1271_ACX_INTR_HW_AVAILABLE) |
165 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); | 155 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE"); |
166 | 156 | ||
167 | if (intr & WL1271_ACX_INTR_DATA) { | 157 | if (intr & WL1271_ACX_INTR_DATA) { |
168 | u8 tx_res_cnt = wl->fw_status->tx_results_counter - | 158 | u8 tx_res_cnt = wl->fw_status->tx_results_counter - |
169 | wl->tx_results_count; | 159 | wl->tx_results_count; |
170 | 160 | ||
171 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 161 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
172 | 162 | ||
173 | /* check for tx results */ | 163 | /* check for tx results */ |
174 | if (tx_res_cnt) | 164 | if (tx_res_cnt) |
175 | wl1271_tx_complete(wl, tx_res_cnt); | 165 | wl1271_tx_complete(wl, tx_res_cnt); |
176 | 166 | ||
177 | wl1271_rx(wl, wl->fw_status); | 167 | wl1271_rx(wl, wl->fw_status); |
178 | } | 168 | } |
179 | |||
180 | intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR); | ||
181 | intr &= WL1271_INTR_MASK; | ||
182 | } while (intr && --ctr); | ||
183 | 169 | ||
184 | out_sleep: | 170 | out_sleep: |
185 | wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, | 171 | wl1271_reg_write32(wl, ACX_REG_INTERRUPT_MASK, |
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h index bd12615e4ca..6af87b5573b 100644 --- a/drivers/net/wireless/wl12xx/wl1271_reg.h +++ b/drivers/net/wireless/wl12xx/wl1271_reg.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #define REGISTERS_WORK_SIZE 0x0000b000 | 34 | #define REGISTERS_WORK_SIZE 0x0000b000 |
35 | 35 | ||
36 | #define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC | 36 | #define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC |
37 | #define STATUS_MEM_ADDRESS 0x40400 | 37 | #define FW_STATUS_ADDR (0x14FC0 + 0xA000) |
38 | 38 | ||
39 | /* ELP register commands */ | 39 | /* ELP register commands */ |
40 | #define ELPCTRL_WAKE_UP 0x1 | 40 | #define ELPCTRL_WAKE_UP 0x1 |