Merge branch 'net-bcmgenet-revisit-MAC-reset'
Doug Berger says: ==================== net: bcmgenet: revisit MAC reset Commit 3a55402c9387 ("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 3a55402c9387 ("net: bcmgenet: use RGMII loopback for MAC reset") has been applied. Unfortunately, reverting that commit may conflict with some restructuring changes introduced by commit 4f8d81b77e66 ("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>
This commit is contained in:
commit
af4e6671b2
@ -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
|
||||
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
@ -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";
|
||||
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user