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>
This commit is contained in:
Jakub Kicinski 2026-01-22 18:27:34 -08:00
commit 3b87882bb3
5 changed files with 29 additions and 5 deletions

View File

@ -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 = {

View File

@ -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) {

View File

@ -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

View File

@ -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)

View File

@ -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;