Skip to content

Commit 5dbebbb

Browse files
ffainellidavem330
authored andcommitted
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: 6ac3ce8 ("net: bcmgenet: Remove excessive PHY reset") Signed-off-by: Florian Fainelli <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b43c142 commit 5dbebbb

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

drivers/net/ethernet/broadcom/genet/bcmgenet.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -907,8 +907,10 @@ static void bcmgenet_power_up(struct bcmgenet_priv *priv,
907907
}
908908

909909
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
910-
if (mode == GENET_POWER_PASSIVE)
910+
if (mode == GENET_POWER_PASSIVE) {
911911
bcmgenet_phy_power_set(priv->dev, true);
912+
bcmgenet_mii_reset(priv->dev);
913+
}
912914
}
913915

914916
/* ioctl handle special commands that are not present in ethtool. */

drivers/net/ethernet/broadcom/genet/bcmgenet.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,7 @@ int bcmgenet_mii_init(struct net_device *dev);
674674
int bcmgenet_mii_config(struct net_device *dev);
675675
int bcmgenet_mii_probe(struct net_device *dev);
676676
void bcmgenet_mii_exit(struct net_device *dev);
677+
void bcmgenet_mii_reset(struct net_device *dev);
677678
void bcmgenet_phy_power_set(struct net_device *dev, bool enable);
678679
void bcmgenet_mii_setup(struct net_device *dev);
679680

drivers/net/ethernet/broadcom/genet/bcmmii.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ void bcmgenet_mii_setup(struct net_device *dev)
163163
phy_print_status(phydev);
164164
}
165165

166+
166167
static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
167168
struct fixed_phy_status *status)
168169
{
@@ -172,6 +173,22 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
172173
return 0;
173174
}
174175

176+
/* Perform a voluntary PHY software reset, since the EPHY is very finicky about
177+
* not doing it and will start corrupting packets
178+
*/
179+
void bcmgenet_mii_reset(struct net_device *dev)
180+
{
181+
struct bcmgenet_priv *priv = netdev_priv(dev);
182+
183+
if (GENET_IS_V4(priv))
184+
return;
185+
186+
if (priv->phydev) {
187+
phy_init_hw(priv->phydev);
188+
phy_start_aneg(priv->phydev);
189+
}
190+
}
191+
175192
void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
176193
{
177194
struct bcmgenet_priv *priv = netdev_priv(dev);
@@ -214,6 +231,7 @@ static void bcmgenet_internal_phy_setup(struct net_device *dev)
214231
reg = bcmgenet_ext_readl(priv, EXT_EXT_PWR_MGMT);
215232
reg |= EXT_PWR_DN_EN_LD;
216233
bcmgenet_ext_writel(priv, reg, EXT_EXT_PWR_MGMT);
234+
bcmgenet_mii_reset(dev);
217235
}
218236

219237
static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)

0 commit comments

Comments
 (0)