Commit 33f84614 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller

net: dsa: bcm_sf2: reset switch prior to initialization

Our boot agent may have left the switch in an certain configuration
state, make sure we issue a software reset prior to configuring the
switch in order to ensure the HW is in a consistent state, in particular
transmit queues and internal buffers.

Fixes: 246d7f77 ("net: dsa: add Broadcom SF2 switch driver")
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a566059d
...@@ -377,6 +377,29 @@ static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id) ...@@ -377,6 +377,29 @@ static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
{
unsigned int timeout = 1000;
u32 reg;
reg = core_readl(priv, CORE_WATCHDOG_CTRL);
reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
core_writel(priv, reg, CORE_WATCHDOG_CTRL);
do {
reg = core_readl(priv, CORE_WATCHDOG_CTRL);
if (!(reg & SOFTWARE_RESET))
break;
usleep_range(1000, 2000);
} while (timeout-- > 0);
if (timeout == 0)
return -ETIMEDOUT;
return 0;
}
static int bcm_sf2_sw_setup(struct dsa_switch *ds) static int bcm_sf2_sw_setup(struct dsa_switch *ds)
{ {
const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME; const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
...@@ -410,6 +433,12 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds) ...@@ -410,6 +433,12 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
base++; base++;
} }
ret = bcm_sf2_sw_rst(priv);
if (ret) {
pr_err("unable to software reset switch: %d\n", ret);
goto out_unmap;
}
/* Disable all interrupts and request them */ /* Disable all interrupts and request them */
intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET); intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR); intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
...@@ -735,29 +764,6 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds) ...@@ -735,29 +764,6 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
return 0; return 0;
} }
static int bcm_sf2_sw_rst(struct bcm_sf2_priv *priv)
{
unsigned int timeout = 1000;
u32 reg;
reg = core_readl(priv, CORE_WATCHDOG_CTRL);
reg |= SOFTWARE_RESET | EN_CHIP_RST | EN_SW_RESET;
core_writel(priv, reg, CORE_WATCHDOG_CTRL);
do {
reg = core_readl(priv, CORE_WATCHDOG_CTRL);
if (!(reg & SOFTWARE_RESET))
break;
usleep_range(1000, 2000);
} while (timeout-- > 0);
if (timeout == 0)
return -ETIMEDOUT;
return 0;
}
static int bcm_sf2_sw_resume(struct dsa_switch *ds) static int bcm_sf2_sw_resume(struct dsa_switch *ds)
{ {
struct bcm_sf2_priv *priv = ds_to_priv(ds); struct bcm_sf2_priv *priv = ds_to_priv(ds);
......
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