Skip to content

Commit

Permalink
net: bcmgenet: Software reset EPHY after power on
Browse files Browse the repository at this point in the history
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: 6ac3ce8 ("net: bcmgenet: Remove excessive PHY reset")
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
ffainelli authored and davem330 committed Nov 1, 2015
1 parent b43c142 commit 5dbebbb
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
4 changes: 3 additions & 1 deletion drivers/net/ethernet/broadcom/genet/bcmgenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
}

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_mii_reset(priv->dev);
}
}

/* ioctl handle special commands that are not present in ethtool. */
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/broadcom/genet/bcmgenet.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device *dev);
int bcmgenet_mii_config(struct net_device *dev);
int bcmgenet_mii_probe(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_mii_setup(struct net_device *dev);

Expand Down
18 changes: 18 additions & 0 deletions drivers/net/ethernet/broadcom/genet/bcmmii.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_device *dev)
phy_print_status(phydev);
}


static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
struct fixed_phy_status *status)
{
Expand All @@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
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)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
Expand Down Expand Up @@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev)
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
reg |= EXT_PWR_DN_EN_LD;
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
bcmgenet_mii_reset(dev);
}

static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
Expand Down

0 comments on commit 5dbebbb

Please sign in to comment.