Skip to content

Commit

Permalink
Merge branch 'net-bcmgenet-revisit-MAC-reset'
Browse files Browse the repository at this point in the history
Doug Berger says:

====================
net: bcmgenet: revisit MAC reset

Commit 3a55402 ("net: bcmgenet: use RGMII loopback for MAC
reset") was intended to resolve issues with reseting the UniMAC
core within the GENET block by providing better control over the
clocks used by the UniMAC core. Unfortunately, it is not
compatible with all of the supported system configurations so an
alternative method must be applied.

This commit set provides such an alternative. The first commit
reverts the previous change and the second commit provides the
alternative reset sequence that addresses the concerns observed
with the previous implementation.

This replacement implementation should be applied to the stable
branches wherever commit 3a55402 ("net: bcmgenet: use RGMII
loopback for MAC reset") has been applied.

Unfortunately, reverting that commit may conflict with some
restructuring changes introduced by commit 4f8d81b ("net:
bcmgenet: Refactor register access in bcmgenet_mii_config").
The first commit in this set has been manually edited to
resolve the conflict on net/master. I would be happy to help
stable maintainers with resolving any such conflicts if they
occur. However, I do not expect that commit to have been
backported to stable branch so hopefully the revert can be
applied cleanly.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 18, 2020
2 parents d36963b + 88f6c8b commit af4e667
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 40 deletions.
10 changes: 5 additions & 5 deletions drivers/net/ethernet/broadcom/genet/bcmgenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1965,6 +1965,8 @@ static void umac_enable_set(struct bcmgenet_priv *priv, u32 mask, bool enable)
u32 reg;

reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (reg & CMD_SW_RESET)
return;
if (enable)
reg |= mask;
else
Expand All @@ -1984,11 +1986,9 @@ static void reset_umac(struct bcmgenet_priv *priv)
bcmgenet_rbuf_ctrl_set(priv, 0);
udelay(10);

/* disable MAC while updating its registers */
bcmgenet_umac_writel(priv, 0, UMAC_CMD);

/* issue soft reset with (rg)mii loopback to ensure a stable rxclk */
bcmgenet_umac_writel(priv, CMD_SW_RESET | CMD_LCL_LOOP_EN, UMAC_CMD);
/* issue soft reset and disable MAC while updating its registers */
bcmgenet_umac_writel(priv, CMD_SW_RESET, UMAC_CMD);
udelay(2);
}

static void bcmgenet_intr_disable(struct bcmgenet_priv *priv)
Expand Down
6 changes: 5 additions & 1 deletion drivers/net/ethernet/broadcom/genet/bcmgenet_wol.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,12 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv,
return -EINVAL;
}

/* disable RX */
/* Can't suspend with WoL if MAC is still in reset */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (reg & CMD_SW_RESET)
reg &= ~CMD_SW_RESET;

/* disable RX */
reg &= ~CMD_RX_EN;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
mdelay(10);
Expand Down
40 changes: 6 additions & 34 deletions drivers/net/ethernet/broadcom/genet/bcmmii.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ void bcmgenet_mii_setup(struct net_device *dev)
CMD_HD_EN |
CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
reg |= cmd_bits;
if (reg & CMD_SW_RESET) {
reg &= ~CMD_SW_RESET;
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
udelay(2);
reg |= CMD_TX_EN | CMD_RX_EN;
}
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
} else {
/* done if nothing has changed */
Expand Down Expand Up @@ -181,38 +187,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
const char *phy_name = NULL;
u32 id_mode_dis = 0;
u32 port_ctrl;
int bmcr = -1;
int ret;
u32 reg;

/* MAC clocking workaround during reset of umac state machines */
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
if (reg & CMD_SW_RESET) {
/* An MII PHY must be isolated to prevent TXC contention */
if (priv->phy_interface == PHY_INTERFACE_MODE_MII) {
ret = phy_read(phydev, MII_BMCR);
if (ret >= 0) {
bmcr = ret;
ret = phy_write(phydev, MII_BMCR,
bmcr | BMCR_ISOLATE);
}
if (ret) {
netdev_err(dev, "failed to isolate PHY\n");
return ret;
}
}
/* Switch MAC clocking to RGMII generated clock */
bcmgenet_sys_writel(priv, PORT_MODE_EXT_GPHY, SYS_PORT_CTRL);
/* Ensure 5 clks with Rx disabled
* followed by 5 clks with Reset asserted
*/
udelay(4);
reg &= ~(CMD_SW_RESET | CMD_LCL_LOOP_EN);
bcmgenet_umac_writel(priv, reg, UMAC_CMD);
/* Ensure 5 more clocks before Rx is enabled */
udelay(2);
}

switch (priv->phy_interface) {
case PHY_INTERFACE_MODE_INTERNAL:
phy_name = "internal PHY";
Expand Down Expand Up @@ -282,10 +258,6 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)

bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);

/* Restore the MII PHY after isolation */
if (bmcr >= 0)
phy_write(phydev, MII_BMCR, bmcr);

priv->ext_phy = !priv->internal_phy &&
(priv->phy_interface != PHY_INTERFACE_MODE_MOCA);

Expand Down

0 comments on commit af4e667

Please sign in to comment.