aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2013-03-13 08:12:49 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-03-13 14:26:21 -0400
commit55f7acdd2440285c5b1236e29c4194eacd624008 (patch)
treeac50f8b9987ccf4a065c70e468d6eb0259c552e3
parentc7996ef852d2c8382b381268b53657175cc2dbc0 (diff)
wil6210: new SW reset
New firmware allows for shorter SW reset procedure. After SW reset, FW raises "fw done" IRQ, at this moment mailbox control structures are initialized, driver caches it. New status bit wil_status_reset_done introduced to track completion of the reset. It is set by "fw ready" irq, and required for WMI rx flow to access control structures. WMI Tx flow protected by other status bit, wil_status_fwready. It can't be set before wil_status_reset_done is set by design. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c11
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c23
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h1
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c5
4 files changed, 17 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index de9b971ea159..e3c1e7684f9c 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
240 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 240 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
241} 241}
242 242
243static void wil_cache_mbox_regs(struct wil6210_priv *wil)
244{
245 /* make shadow copy of registers that should not change on run time */
246 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
247 sizeof(struct wil6210_mbox_ctl));
248 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
249 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
250}
251
243static irqreturn_t wil6210_irq_misc(int irq, void *cookie) 252static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
244{ 253{
245 struct wil6210_priv *wil = cookie; 254 struct wil6210_priv *wil = cookie;
@@ -268,6 +277,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
268 277
269 if (isr & ISR_MISC_FW_READY) { 278 if (isr & ISR_MISC_FW_READY) {
270 wil_dbg_irq(wil, "IRQ: FW ready\n"); 279 wil_dbg_irq(wil, "IRQ: FW ready\n");
280 wil_cache_mbox_regs(wil);
281 set_bit(wil_status_reset_done, &wil->status);
271 /** 282 /**
272 * Actual FW ready indicated by the 283 * Actual FW ready indicated by the
273 * WMI_FW_READY_EVENTID 284 * WMI_FW_READY_EVENTID
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index f11efa4d6ab8..9d05628e450d 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -103,15 +103,6 @@ static void wil_connect_timer_fn(ulong x)
103 schedule_work(&wil->disconnect_worker); 103 schedule_work(&wil->disconnect_worker);
104} 104}
105 105
106static void wil_cache_mbox_regs(struct wil6210_priv *wil)
107{
108 /* make shadow copy of registers that should not change on run time */
109 wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
110 sizeof(struct wil6210_mbox_ctl));
111 wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
112 wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
113}
114
115static void wil_connect_worker(struct work_struct *work) 106static void wil_connect_worker(struct work_struct *work)
116{ 107{
117 int rc; 108 int rc;
@@ -161,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil)
161 return -EAGAIN; 152 return -EAGAIN;
162 } 153 }
163 154
164 wil_cache_mbox_regs(wil);
165
166 return 0; 155 return 0;
167} 156}
168 157
@@ -199,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil)
199 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ 188 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
200 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ 189 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
201 190
202 msleep(100);
203
204 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 191 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
205 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 192 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
206 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); 193 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
207 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 194 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
208 195
209 msleep(100);
210
211 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 196 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
212 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 197 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
213 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 198 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
@@ -217,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil)
217 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); 202 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
218 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 203 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
219 204
220 msleep(2000);
221
222 W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
223
224 msleep(2000);
225
226 wil_dbg_misc(wil, "Reset completed\n"); 205 wil_dbg_misc(wil, "Reset completed\n");
227 206
228#undef W 207#undef W
@@ -279,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil)
279 wil->pending_connect_cid = -1; 258 wil->pending_connect_cid = -1;
280 INIT_COMPLETION(wil->wmi_ready); 259 INIT_COMPLETION(wil->wmi_ready);
281 260
282 wil_cache_mbox_regs(wil);
283
284 /* TODO: release MAC reset */ 261 /* TODO: release MAC reset */
285 wil6210_enable_irq(wil); 262 wil6210_enable_irq(wil);
286 263
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index 5f500de957fe..2ec7258b191c 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -186,6 +186,7 @@ enum { /* for wil6210_priv.status */
186 wil_status_fwready = 0, 186 wil_status_fwready = 0,
187 wil_status_fwconnected, 187 wil_status_fwconnected,
188 wil_status_dontscan, 188 wil_status_dontscan,
189 wil_status_reset_done,
189 wil_status_irqen, /* FIXME: interrupts enabled - for debug */ 190 wil_status_irqen, /* FIXME: interrupts enabled - for debug */
190}; 191};
191 192
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 8d9e145f0983..ed2b097ee02a 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -585,6 +585,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
585 void __iomem *src; 585 void __iomem *src;
586 ulong flags; 586 ulong flags;
587 587
588 if (!test_bit(wil_status_reset_done, &wil->status)) {
589 wil_err(wil, "Reset not completed\n");
590 return;
591 }
592
588 for (;;) { 593 for (;;) {
589 u16 len; 594 u16 len;
590 595