Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5dbebbb4 authored by Florian Fainelli's avatar Florian Fainelli Committed by David S. Miller
Browse files

net: bcmgenet: Software reset EPHY after power on



The EPHY on GENET v1->v3 is extremely finicky, and will show occasional
failures based on the timing and reset sequence, ranging from duplicate
packets, to extremely high latencies.

Perform an additional software reset, and re-configuration to make sure it is
in a consistent and working state.

Fixes: 6ac3ce82 ("net: bcmgenet: Remove excessive PHY reset")
Signed-off-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b43c142f
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
	}
	}


	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
	if (mode == GENET_POWER_PASSIVE)
	if (mode == GENET_POWER_PASSIVE) {
		bcmgenet_phy_power_set(priv->dev, true);
		bcmgenet_phy_power_set(priv->dev, true);
		bcmgenet_mii_reset(priv->dev);
	}
}
}


/* ioctl handle special commands that are not present in ethtool. */
/* ioctl handle special commands that are not present in ethtool. */
+1 −0
Original line number Original line Diff line number Diff line
@@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device *dev);
int bcmgenet_mii_config(struct net_device *dev);
int bcmgenet_mii_config(struct net_device *dev);
int bcmgenet_mii_probe(struct net_device *dev);
int bcmgenet_mii_probe(struct net_device *dev);
void bcmgenet_mii_exit(struct net_device *dev);
void bcmgenet_mii_exit(struct net_device *dev);
void bcmgenet_mii_reset(struct net_device *dev);
void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
void bcmgenet_mii_setup(struct net_device *dev);
void bcmgenet_mii_setup(struct net_device *dev);


+18 −0
Original line number Original line Diff line number Diff line
@@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_device *dev)
	phy_print_status(phydev);
	phy_print_status(phydev);
}
}



static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
					  struct fixed_phy_status *status)
					  struct fixed_phy_status *status)
{
{
@@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
	return 0;
	return 0;
}
}


/* Perform a voluntary PHY software reset, since the EPHY is very finicky about
 * not doing it and will start corrupting packets
 */
void bcmgenet_mii_reset(struct net_device *dev)
{
	struct bcmgenet_priv *priv = netdev_priv(dev);

	if (GENET_IS_V4(priv))
		return;

	if (priv->phydev) {
		phy_init_hw(priv->phydev);
		phy_start_aneg(priv->phydev);
	}
}

void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
{
{
	struct bcmgenet_priv *priv = netdev_priv(dev);
	struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev)
	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
	reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
	reg |= EXT_PWR_DN_EN_LD;
	reg |= EXT_PWR_DN_EN_LD;
	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
	bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
	bcmgenet_mii_reset(dev);
}
}


static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)