diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2026-01-23 05:27:34 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-01-23 05:27:35 +0300 |
| commit | 3b87882bb399bf6d1900a1c2cc8dde65d336680a (patch) | |
| tree | 87afe886fb6f8838275c7a00c0b9e00e81808d24 | |
| parent | 31d44a37820f00de8156d1c1960dbf1bf04263c2 (diff) | |
| parent | dc6597fab3e3d291da9e0b4c6f7da01a5a863e80 (diff) | |
| download | linux-3b87882bb399bf6d1900a1c2cc8dde65d336680a.tar.xz | |
Merge branch 'net-stmmac-dwmac-enforce-preamble-before-sfd-for-i-mx8mp'
Stefan Eichenberger says:
====================
net: stmmac: dwmac: enforce preamble before SFD for i.MX8MP
This series adds a new phy_device flag PHY_F_KEEP_PREAMBLE_BEFORE_SFD
that allows a MAC driver to request to keep the preamble bytes before
the start frame delimiter (SFD) when receiving frames from the PHY.
This flag is set in the stmmac driver for the i.MX8MP SoC due to errata
(ERR050694), which causes it to drop frames without a preamble.
The Micrel KSZ9131 PHY supports keeping the preamble before SFD by
setting an undocumented flag, that was confirmed by NXP and Micrel. This
new feature has been added to the Micrel PHY driver for the KSZ9131 PHY.
====================
Link: https://patch.msgid.link/20260120203905.23805-1-eichest@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c | 6 | ||||
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 | ||||
| -rw-r--r-- | drivers/net/phy/micrel.c | 14 | ||||
| -rw-r--r-- | include/linux/phy.h | 5 | ||||
| -rw-r--r-- | include/linux/stmmac.h | 1 |
5 files changed, 29 insertions, 5 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c index db288fbd5a4d..c722ff2dc1fc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c @@ -320,6 +320,9 @@ static int imx_dwmac_probe(struct platform_device *pdev) if (data->flags & STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY) plat_dat->flags |= STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY; + if (data->flags & STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD) + plat_dat->flags |= STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD; + /* Default TX Q0 to use TSO and rest TXQ for TBS */ for (int i = 1; i < plat_dat->tx_queues_to_use; i++) plat_dat->tx_queues_cfg[i].tbs_en = 1; @@ -355,7 +358,8 @@ static struct imx_dwmac_ops imx8mp_dwmac_data = { .addr_width = 34, .mac_rgmii_txclk_auto_adj = false, .set_intf_mode = imx8mp_set_intf_mode, - .flags = STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY, + .flags = STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY | + STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD, }; static struct imx_dwmac_ops imx8dxl_dwmac_data = { diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c2589f02ff7e..59e5fb2e7e05 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1206,6 +1206,7 @@ static int stmmac_init_phy(struct net_device *dev) struct fwnode_handle *phy_fwnode; struct fwnode_handle *fwnode; struct ethtool_keee eee; + u32 dev_flags = 0; int ret; if (!phylink_expects_phy(priv->phylink)) @@ -1224,6 +1225,9 @@ static int stmmac_init_phy(struct net_device *dev) else phy_fwnode = NULL; + if (priv->plat->flags & STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD) + dev_flags |= PHY_F_KEEP_PREAMBLE_BEFORE_SFD; + /* Some DT bindings do not set-up the PHY handle. Let's try to * manually parse it */ @@ -1242,10 +1246,12 @@ static int stmmac_init_phy(struct net_device *dev) return -ENODEV; } + phydev->dev_flags |= dev_flags; + ret = phylink_connect_phy(priv->phylink, phydev); } else { fwnode_handle_put(phy_fwnode); - ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, 0); + ret = phylink_fwnode_phy_connect(priv->phylink, fwnode, dev_flags); } if (ret) { diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 225d4adf28be..b2a584b60bff 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -101,6 +101,14 @@ #define LAN8814_CABLE_DIAG_VCT_DATA_MASK GENMASK(7, 0) #define LAN8814_PAIR_BIT_SHIFT 12 +/* KSZ9x31 remote loopback register */ +#define KSZ9x31_REMOTE_LOOPBACK 0x11 +/* This is an undocumented bit of the KSZ9131RNX. + * It was reported by NXP in cooperation with Micrel. + */ +#define KSZ9x31_REMOTE_LOOPBACK_KEEP_PREAMBLE BIT(2) +#define KSZ9x31_REMOTE_LOOPBACK_EN BIT(8) + #define LAN8814_SKUS 0xB #define LAN8814_WIRE_PAIR_MASK 0xF @@ -1500,7 +1508,11 @@ static int ksz9131_config_init(struct phy_device *phydev) if (ret < 0) return ret; - return 0; + if (phydev->dev_flags & PHY_F_KEEP_PREAMBLE_BEFORE_SFD) + ret = phy_modify(phydev, KSZ9x31_REMOTE_LOOPBACK, 0, + KSZ9x31_REMOTE_LOOPBACK_KEEP_PREAMBLE); + + return ret; } #define MII_KSZ9131_AUTO_MDIX 0x1C diff --git a/include/linux/phy.h b/include/linux/phy.h index 5972f19af16d..6f9979a26892 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -810,8 +810,9 @@ struct phy_device { }; /* Generic phy_device::dev_flags */ -#define PHY_F_NO_IRQ 0x80000000 -#define PHY_F_RXC_ALWAYS_ON 0x40000000 +#define PHY_F_NO_IRQ 0x80000000 +#define PHY_F_RXC_ALWAYS_ON 0x40000000 +#define PHY_F_KEEP_PREAMBLE_BEFORE_SFD 0x20000000 #define to_phy_device(__dev) container_of_const(to_mdio_device(__dev), struct phy_device, mdio) diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h index f1054b9c2d8a..e308c98c7bd3 100644 --- a/include/linux/stmmac.h +++ b/include/linux/stmmac.h @@ -191,6 +191,7 @@ enum dwmac_core_type { #define STMMAC_FLAG_EN_TX_LPI_CLOCKGATING BIT(11) #define STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP BIT(12) #define STMMAC_FLAG_HWTSTAMP_CORRECT_LATENCY BIT(13) +#define STMMAC_FLAG_KEEP_PREAMBLE_BEFORE_SFD BIT(14) struct mac_device_info; |
