summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-01-23 05:27:34 +0300
committerJakub Kicinski <kuba@kernel.org>2026-01-23 05:27:35 +0300
commit3b87882bb399bf6d1900a1c2cc8dde65d336680a (patch)
tree87afe886fb6f8838275c7a00c0b9e00e81808d24
parent31d44a37820f00de8156d1c1960dbf1bf04263c2 (diff)
parentdc6597fab3e3d291da9e0b4c6f7da01a5a863e80 (diff)
downloadlinux-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.c6
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c8
-rw-r--r--drivers/net/phy/micrel.c14
-rw-r--r--include/linux/phy.h5
-rw-r--r--include/linux/stmmac.h1
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;