Commit 08ad4839 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-dsa-lantiq_gswip-two-fixes-for-net-stable'

Martin Blumenstingl says:

====================
net: dsa: lantiq_gswip: two fixes for -net/-stable

While testing the lantiq_gswip driver in OpenWrt at least one board had
a non-working Ethernet port connected to an internal 100Mbit/s PHY22F
GPHY. The problem which could be observed:
- the PHY would detect the link just fine
- ethtool stats would see the TX counter rise
- the RX counter in ethtool was stuck at zero

It turns out that two independent patches are needed to fix this:
- first we need to enable the MII data lines also for internal PHYs
- second we need to program the GSWIP_MII_CFG registers for all ports
  except the CPU port

These two patches have also been tested by back-porting them on top of
Linux 5.4.86 in OpenWrt.

Special thanks to Hauke for debugging and brainstorming this on IRC
with me!
====================

Link: https://lore.kernel.org/r/20210103012544.3259029-1-martin.blumenstingl@googlemail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents b40f97b9 709a3c9d
...@@ -92,9 +92,7 @@ ...@@ -92,9 +92,7 @@
GSWIP_MDIO_PHY_FDUP_MASK) GSWIP_MDIO_PHY_FDUP_MASK)
/* GSWIP MII Registers */ /* GSWIP MII Registers */
#define GSWIP_MII_CFG0 0x00 #define GSWIP_MII_CFGp(p) (0x2 * (p))
#define GSWIP_MII_CFG1 0x02
#define GSWIP_MII_CFG5 0x04
#define GSWIP_MII_CFG_EN BIT(14) #define GSWIP_MII_CFG_EN BIT(14)
#define GSWIP_MII_CFG_LDCLKDIS BIT(12) #define GSWIP_MII_CFG_LDCLKDIS BIT(12)
#define GSWIP_MII_CFG_MODE_MIIP 0x0 #define GSWIP_MII_CFG_MODE_MIIP 0x0
...@@ -392,17 +390,9 @@ static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set, ...@@ -392,17 +390,9 @@ static void gswip_mii_mask(struct gswip_priv *priv, u32 clear, u32 set,
static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set, static void gswip_mii_mask_cfg(struct gswip_priv *priv, u32 clear, u32 set,
int port) int port)
{ {
switch (port) { /* There's no MII_CFG register for the CPU port */
case 0: if (!dsa_is_cpu_port(priv->ds, port))
gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG0); gswip_mii_mask(priv, clear, set, GSWIP_MII_CFGp(port));
break;
case 1:
gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG1);
break;
case 5:
gswip_mii_mask(priv, clear, set, GSWIP_MII_CFG5);
break;
}
} }
static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set, static void gswip_mii_mask_pcdu(struct gswip_priv *priv, u32 clear, u32 set,
...@@ -822,9 +812,8 @@ static int gswip_setup(struct dsa_switch *ds) ...@@ -822,9 +812,8 @@ static int gswip_setup(struct dsa_switch *ds)
gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1); gswip_mdio_mask(priv, 0xff, 0x09, GSWIP_MDIO_MDC_CFG1);
/* Disable the xMII link */ /* Disable the xMII link */
gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 0); for (i = 0; i < priv->hw_info->max_ports; i++)
gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 1); gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, i);
gswip_mii_mask_cfg(priv, GSWIP_MII_CFG_EN, 0, 5);
/* enable special tag insertion on cpu port */ /* enable special tag insertion on cpu port */
gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN, gswip_switch_mask(priv, 0, GSWIP_FDMA_PCTRL_STEN,
...@@ -1541,8 +1530,6 @@ static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port, ...@@ -1541,8 +1530,6 @@ static void gswip_phylink_mac_link_up(struct dsa_switch *ds, int port,
{ {
struct gswip_priv *priv = ds->priv; struct gswip_priv *priv = ds->priv;
/* Enable the xMII interface only for the external PHY */
if (interface != PHY_INTERFACE_MODE_INTERNAL)
gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port); gswip_mii_mask_cfg(priv, 0, GSWIP_MII_CFG_EN, port);
} }
......
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