Skip to content

Commit

Permalink
net: dsa: bcm_sf2: reset switch prior to initialization
Browse files Browse the repository at this point in the history
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: 246d7f7 ("net: dsa: add Broadcom SF2 switch driver")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Florian Fainelli authored and David S. Miller committed Nov 26, 2014
1 parent a566059 commit 33f8461
Showing 1 changed file with 29 additions and 23 deletions.
52 changes: 29 additions & 23 deletions drivers/net/dsa/bcm_sf2.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,29 @@ static irqreturn_t bcm_sf2_switch_1_isr(int irq, void *dev_id)
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)
{
const char *reg_names[BCM_SF2_REGS_NUM] = BCM_SF2_REGS_NAME;
Expand Down Expand Up @@ -410,6 +433,12 @@ static int bcm_sf2_sw_setup(struct dsa_switch *ds)
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 */
intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
Expand Down Expand Up @@ -735,29 +764,6 @@ static int bcm_sf2_sw_suspend(struct dsa_switch *ds)
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)
{
struct bcm_sf2_priv *priv = ds_to_priv(ds);
Expand Down

0 comments on commit 33f8461

Please sign in to comment.