Commit c3c9f441 authored by David S. Miller's avatar David S. Miller

Merge branch 'bcmgenet-start-stop-sequence-refinement'

Doug Berger says:

====================
net: bcmgenet: start/stop sequence refinement

This commit set is the result of an investigation into an issue that
occurred when bringing the interface up and down repeatedly with an
external 100BASE-T PHY. In some cases the MAC would experience mass
receive packet duplication that could in rare cases lead to a stall
from overflow.  The fix for this is contained in the third commit.

The first 3 commits represent bug fixes that should be applied to the
net repository and are candidates for backporting to stable releases.
The remaining commits are enhancements which is why the set is being
submitted to net-next but they are implemented on top of the fixes.

The first fix is provided as justification for why the set isn't
split between a net submission and a net-next submission.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 88ca59d1 6c97f010
...@@ -617,7 +617,6 @@ struct bcmgenet_priv { ...@@ -617,7 +617,6 @@ struct bcmgenet_priv {
/* MDIO bus variables */ /* MDIO bus variables */
wait_queue_head_t wq; wait_queue_head_t wq;
struct phy_device *phydev;
bool internal_phy; bool internal_phy;
struct device_node *phy_dn; struct device_node *phy_dn;
struct device_node *mdio_dn; struct device_node *mdio_dn;
...@@ -711,7 +710,6 @@ int bcmgenet_mii_init(struct net_device *dev); ...@@ -711,7 +710,6 @@ int bcmgenet_mii_init(struct net_device *dev);
int bcmgenet_mii_config(struct net_device *dev, bool init); int bcmgenet_mii_config(struct net_device *dev, bool init);
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);
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
void bcmgenet_mii_setup(struct net_device *dev) void bcmgenet_mii_setup(struct net_device *dev)
{ {
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev; struct phy_device *phydev = dev->phydev;
u32 reg, cmd_bits = 0; u32 reg, cmd_bits = 0;
bool status_changed = false; bool status_changed = false;
...@@ -121,22 +121,6 @@ static int bcmgenet_fixed_phy_link_update(struct net_device *dev, ...@@ -121,22 +121,6 @@ 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);
...@@ -182,14 +166,14 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv) ...@@ -182,14 +166,14 @@ static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
} }
if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET) if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
fixed_phy_set_link_update(priv->phydev, fixed_phy_set_link_update(priv->dev->phydev,
bcmgenet_fixed_phy_link_update); bcmgenet_fixed_phy_link_update);
} }
int bcmgenet_mii_config(struct net_device *dev, bool init) int bcmgenet_mii_config(struct net_device *dev, bool init)
{ {
struct bcmgenet_priv *priv = netdev_priv(dev); struct bcmgenet_priv *priv = netdev_priv(dev);
struct phy_device *phydev = priv->phydev; struct phy_device *phydev = dev->phydev;
struct device *kdev = &priv->pdev->dev; struct device *kdev = &priv->pdev->dev;
const char *phy_name = NULL; const char *phy_name = NULL;
u32 id_mode_dis = 0; u32 id_mode_dis = 0;
...@@ -236,7 +220,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) ...@@ -236,7 +220,7 @@ int bcmgenet_mii_config(struct net_device *dev, bool init)
* capabilities, use that knowledge to also configure the * capabilities, use that knowledge to also configure the
* Reverse MII interface correctly. * Reverse MII interface correctly.
*/ */
if ((priv->phydev->supported & PHY_BASIC_FEATURES) == if ((dev->phydev->supported & PHY_BASIC_FEATURES) ==
PHY_BASIC_FEATURES) PHY_BASIC_FEATURES)
port_ctrl = PORT_MODE_EXT_RVMII_25; port_ctrl = PORT_MODE_EXT_RVMII_25;
else else
...@@ -306,7 +290,7 @@ int bcmgenet_mii_probe(struct net_device *dev) ...@@ -306,7 +290,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
return -ENODEV; return -ENODEV;
} }
} else { } else {
phydev = priv->phydev; phydev = dev->phydev;
phydev->dev_flags = phy_flags; phydev->dev_flags = phy_flags;
ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup, ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
...@@ -317,8 +301,6 @@ int bcmgenet_mii_probe(struct net_device *dev) ...@@ -317,8 +301,6 @@ int bcmgenet_mii_probe(struct net_device *dev)
} }
} }
priv->phydev = phydev;
/* Configure port multiplexer based on what the probed PHY device since /* Configure port multiplexer based on what the probed PHY device since
* reading the 'max-speed' property determines the maximum supported * reading the 'max-speed' property determines the maximum supported
* PHY speed which is needed for bcmgenet_mii_config() to configure * PHY speed which is needed for bcmgenet_mii_config() to configure
...@@ -326,7 +308,7 @@ int bcmgenet_mii_probe(struct net_device *dev) ...@@ -326,7 +308,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
*/ */
ret = bcmgenet_mii_config(dev, true); ret = bcmgenet_mii_config(dev, true);
if (ret) { if (ret) {
phy_disconnect(priv->phydev); phy_disconnect(dev->phydev);
return ret; return ret;
} }
...@@ -336,7 +318,7 @@ int bcmgenet_mii_probe(struct net_device *dev) ...@@ -336,7 +318,7 @@ int bcmgenet_mii_probe(struct net_device *dev)
* Ethernet MAC ISRs * Ethernet MAC ISRs
*/ */
if (priv->internal_phy) if (priv->internal_phy)
priv->phydev->irq = PHY_IGNORE_INTERRUPT; dev->phydev->irq = PHY_IGNORE_INTERRUPT;
return 0; return 0;
} }
...@@ -545,7 +527,6 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) ...@@ -545,7 +527,6 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
} }
priv->phydev = phydev;
priv->phy_interface = pd->phy_interface; priv->phy_interface = pd->phy_interface;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment