Commit 55f7acdd authored by Vladimir Kondratiev's avatar Vladimir Kondratiev Committed by John W. Linville

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: default avatarVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent c7996ef8
...@@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil) ...@@ -240,6 +240,15 @@ static void wil_notify_fw_error(struct wil6210_priv *wil)
kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
} }
static void wil_cache_mbox_regs(struct wil6210_priv *wil)
{
/* make shadow copy of registers that should not change on run time */
wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
sizeof(struct wil6210_mbox_ctl));
wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
}
static irqreturn_t wil6210_irq_misc(int irq, void *cookie) static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
{ {
struct wil6210_priv *wil = cookie; struct wil6210_priv *wil = cookie;
...@@ -268,6 +277,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie) ...@@ -268,6 +277,8 @@ static irqreturn_t wil6210_irq_misc(int irq, void *cookie)
if (isr & ISR_MISC_FW_READY) { if (isr & ISR_MISC_FW_READY) {
wil_dbg_irq(wil, "IRQ: FW ready\n"); wil_dbg_irq(wil, "IRQ: FW ready\n");
wil_cache_mbox_regs(wil);
set_bit(wil_status_reset_done, &wil->status);
/** /**
* Actual FW ready indicated by the * Actual FW ready indicated by the
* WMI_FW_READY_EVENTID * WMI_FW_READY_EVENTID
......
...@@ -103,15 +103,6 @@ static void wil_connect_timer_fn(ulong x) ...@@ -103,15 +103,6 @@ static void wil_connect_timer_fn(ulong x)
schedule_work(&wil->disconnect_worker); schedule_work(&wil->disconnect_worker);
} }
static void wil_cache_mbox_regs(struct wil6210_priv *wil)
{
/* make shadow copy of registers that should not change on run time */
wil_memcpy_fromio_32(&wil->mbox_ctl, wil->csr + HOST_MBOX,
sizeof(struct wil6210_mbox_ctl));
wil_mbox_ring_le2cpus(&wil->mbox_ctl.rx);
wil_mbox_ring_le2cpus(&wil->mbox_ctl.tx);
}
static void wil_connect_worker(struct work_struct *work) static void wil_connect_worker(struct work_struct *work)
{ {
int rc; int rc;
...@@ -161,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil) ...@@ -161,8 +152,6 @@ int wil_priv_init(struct wil6210_priv *wil)
return -EAGAIN; return -EAGAIN;
} }
wil_cache_mbox_regs(wil);
return 0; return 0;
} }
...@@ -199,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil) ...@@ -199,15 +188,11 @@ static void wil_target_reset(struct wil6210_priv *wil)
W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
msleep(100);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170); W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000170);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00);
msleep(100);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
...@@ -217,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil) ...@@ -217,12 +202,6 @@ static void wil_target_reset(struct wil6210_priv *wil)
W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080); W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00000080);
W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
msleep(2000);
W(RGF_USER_USER_CPU_0, BIT(0)); /* user_cpu_man_de_rst */
msleep(2000);
wil_dbg_misc(wil, "Reset completed\n"); wil_dbg_misc(wil, "Reset completed\n");
#undef W #undef W
...@@ -279,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil) ...@@ -279,8 +258,6 @@ int wil_reset(struct wil6210_priv *wil)
wil->pending_connect_cid = -1; wil->pending_connect_cid = -1;
INIT_COMPLETION(wil->wmi_ready); INIT_COMPLETION(wil->wmi_ready);
wil_cache_mbox_regs(wil);
/* TODO: release MAC reset */ /* TODO: release MAC reset */
wil6210_enable_irq(wil); wil6210_enable_irq(wil);
......
...@@ -186,6 +186,7 @@ enum { /* for wil6210_priv.status */ ...@@ -186,6 +186,7 @@ enum { /* for wil6210_priv.status */
wil_status_fwready = 0, wil_status_fwready = 0,
wil_status_fwconnected, wil_status_fwconnected,
wil_status_dontscan, wil_status_dontscan,
wil_status_reset_done,
wil_status_irqen, /* FIXME: interrupts enabled - for debug */ wil_status_irqen, /* FIXME: interrupts enabled - for debug */
}; };
......
...@@ -585,6 +585,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil) ...@@ -585,6 +585,11 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
void __iomem *src; void __iomem *src;
ulong flags; ulong flags;
if (!test_bit(wil_status_reset_done, &wil->status)) {
wil_err(wil, "Reset not completed\n");
return;
}
for (;;) { for (;;) {
u16 len; u16 len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment