netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller
       [not found] <20251216180331.61586-1-me@ziyao.cc>
@ 2025-12-16 18:03 ` Yao Zi
  2025-12-21 20:29   ` Andrew Lunn
  2025-12-16 18:03 ` [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller Yao Zi
  2025-12-16 18:03 ` [RFC PATCH net-next v4 3/3] MAINTAINERS: Assign myself as maintainer of Motorcomm DWMAC glue driver Yao Zi
  2 siblings, 1 reply; 6+ messages in thread
From: Yao Zi @ 2025-12-16 18:03 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu
  Cc: linux-kernel, netdev, Mingcong Bai, Kexy Biscuit, Yao Zi

YT6801's internal PHY is confirmed as a GMII-capable variant of YT8531S
by a previous series[1] and reading PHY ID. Add support for
PHY_INTERFACE_MODE_GMII for YT8531S to allow the Ethernet driver to
reuse the PHY code for its internal PHY.

Link: https://lore.kernel.org/all/a48d76ac-db08-46d5-9528-f046a7b541dc@motor-comm.com/ # [1]
Co-developed-by: Frank Sae <Frank.Sae@motor-comm.com>
Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
Signed-off-by: Yao Zi <me@ziyao.cc>
---
 drivers/net/phy/motorcomm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
index 89b5b19a9bd2..b751fbc6711a 100644
--- a/drivers/net/phy/motorcomm.c
+++ b/drivers/net/phy/motorcomm.c
@@ -910,6 +910,10 @@ static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
 		val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
 		       FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
 		break;
+	case PHY_INTERFACE_MODE_GMII:
+		if (phydev->drv->phy_id != PHY_ID_YT8531S)
+			return -EOPNOTSUPP;
+		break;
 	default: /* do not support other modes */
 		return -EOPNOTSUPP;
 	}
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller
       [not found] <20251216180331.61586-1-me@ziyao.cc>
  2025-12-16 18:03 ` [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller Yao Zi
@ 2025-12-16 18:03 ` Yao Zi
  2025-12-21 20:42   ` Andrew Lunn
  2025-12-16 18:03 ` [RFC PATCH net-next v4 3/3] MAINTAINERS: Assign myself as maintainer of Motorcomm DWMAC glue driver Yao Zi
  2 siblings, 1 reply; 6+ messages in thread
From: Yao Zi @ 2025-12-16 18:03 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu
  Cc: linux-kernel, netdev, Mingcong Bai, Kexy Biscuit, Yao Zi,
	Runhua He, Xi Ruoyao

Motorcomm YT6801 is a PCIe ethernet controller based on DWMAC4 IP. It
integrates an GbE phy, supporting WOL, VLAN tagging and various types
of offloading. It ships an on-chip eFuse for storing various vendor
configuration, including MAC address.

This patch adds basic glue code for the controller, allowing it to be
set up and transmit data at a reasonable speed. Features like WOL could
be implemented in the future.

Signed-off-by: Yao Zi <me@ziyao.cc>
Tested-by: Mingcong Bai <jeffbai@aosc.io>
Tested-by: Runhua He <hua@aosc.io>
Tested-by: Xi Ruoyao <xry111@xry111.site>
---
 drivers/net/ethernet/stmicro/stmmac/Kconfig   |   9 +
 drivers/net/ethernet/stmicro/stmmac/Makefile  |   1 +
 .../ethernet/stmicro/stmmac/dwmac-motorcomm.c | 383 ++++++++++++++++++
 3 files changed, 393 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 907fe2e927f0..07088d03dbab 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -374,6 +374,15 @@ config DWMAC_LOONGSON
 	  This selects the LOONGSON PCI bus support for the stmmac driver,
 	  Support for ethernet controller on Loongson-2K1000 SoC and LS7A1000 bridge.
 
+config DWMAC_MOTORCOMM
+	tristate "Motorcomm PCI DWMAC support"
+	depends on PCI
+	select MOTORCOMM_PHY
+	select STMMAC_LIBPCI
+	help
+	  This enables glue driver for Motorcomm DWMAC-based PCI Ethernet
+	  controllers. Currently only YT6801 is supported.
+
 config STMMAC_PCI
 	tristate "STMMAC PCI bus support"
 	depends on PCI
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index 7bf528731034..c9263987ef8d 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -48,4 +48,5 @@ obj-$(CONFIG_STMMAC_LIBPCI)	+= stmmac_libpci.o
 obj-$(CONFIG_STMMAC_PCI)	+= stmmac-pci.o
 obj-$(CONFIG_DWMAC_INTEL)	+= dwmac-intel.o
 obj-$(CONFIG_DWMAC_LOONGSON)	+= dwmac-loongson.o
+obj-$(CONFIG_DWMAC_MOTORCOMM)	+= dwmac-motorcomm.o
 stmmac-pci-objs:= stmmac_pci.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c
new file mode 100644
index 000000000000..11ee470ac8f7
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * DWMAC glue driver for Motorcomm PCI Ethernet controllers
+ *
+ * Copyright (c) 2025 Yao Zi <me@ziyao.cc>
+ */
+
+#include <linux/bits.h>
+#include <linux/dev_printk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/stmmac.h>
+
+#include "dwmac4.h"
+#include "stmmac.h"
+#include "stmmac_libpci.h"
+
+#define DRIVER_NAME "dwmac-motorcomm"
+
+#define PCI_VENDOR_ID_MOTORCOMM			0x1f0a
+
+/* Register definition */
+#define EPHY_CTRL				0x1004
+/* Clearing this bit asserts resets for internal MDIO bus and PHY */
+#define  EPHY_MDIO_PHY_RESET			BIT(0)
+#define OOB_WOL_CTRL				0x1010
+#define  OOB_WOL_CTRL_DIS			BIT(0)
+#define MGMT_INT_CTRL0				0x1100
+#define MGMT_INT_CTRL0_MASK			GENMASK(31, 16)
+#define  MGMT_INT_CTRL0_MASK_RXCH		GENMASK(3, 0)
+#define  MGMT_INT_CTRL0_MASK_TXCH		BIT(4)
+#define  MGMT_INT_CTRL0_MASK_MISC		BIT(5)
+#define INT_MODERATION				0x1108
+#define INT_MODERATION_RX			GENMASK(11, 0)
+#define INT_MODERATION_TX			GENMASK(27, 16)
+#define EFUSE_OP_CTRL_0				0x1500
+#define  EFUSE_OP_MODE				GENMASK(1, 0)
+#define   EFUSE_OP_ROW_READ			0x1
+#define  EFUSE_OP_START				BIT(2)
+#define  EFUSE_OP_ADDR				GENMASK(15, 8)
+#define EFUSE_OP_CTRL_1				0x1504
+#define  EFUSE_OP_DONE				BIT(1)
+#define  EFUSE_OP_RD_DATA			GENMASK(31, 24)
+#define SYS_RESET				0x152c
+#define  SYS_RESET_RESET			BIT(31)
+#define GMAC_OFFSET				0x2000
+
+/* Constants */
+#define EFUSE_READ_TIMEOUT_US			20000
+#define EFUSE_PATCH_REGION_OFFSET		18
+#define EFUSE_PATCH_MAX_NUM			39
+#define EFUSE_ADDR_MACA0LR			0x1520
+#define EFUSE_ADDR_MACA0HR			0x1524
+
+struct motorcomm_efuse_patch {
+	__le16 addr;
+	__le32 data;
+} __packed;
+
+struct dwmac_motorcomm_priv {
+	void __iomem *base;
+	struct device *dev;
+};
+
+static int motorcomm_efuse_read_byte(struct dwmac_motorcomm_priv *priv,
+				     u8 offset, u8 *byte)
+{
+	u32 reg;
+	int ret;
+
+	writel(FIELD_PREP(EFUSE_OP_MODE, EFUSE_OP_ROW_READ)	|
+	       FIELD_PREP(EFUSE_OP_ADDR, offset)		|
+	       EFUSE_OP_START, priv->base + EFUSE_OP_CTRL_0);
+
+	ret = readl_poll_timeout(priv->base + EFUSE_OP_CTRL_1,
+				 reg, reg & EFUSE_OP_DONE, 2000,
+				 EFUSE_READ_TIMEOUT_US);
+
+	*byte = FIELD_GET(EFUSE_OP_RD_DATA, reg);
+
+	return ret;
+}
+
+static int motorcomm_efuse_read_patch(struct dwmac_motorcomm_priv *priv,
+				      u8 index,
+				      struct motorcomm_efuse_patch *patch)
+{
+	u8 buf[sizeof(*patch)], offset;
+	int i, ret;
+
+	for (i = 0; i < sizeof(*patch); i++) {
+		offset = EFUSE_PATCH_REGION_OFFSET + sizeof(*patch) * index + i;
+
+		ret = motorcomm_efuse_read_byte(priv, offset, &buf[i]);
+		if (ret)
+			return ret;
+	}
+
+	memcpy(patch, buf, sizeof(*patch));
+
+	return 0;
+}
+
+static int motorcomm_efuse_get_patch_value(struct dwmac_motorcomm_priv *priv,
+					   u16 addr, u32 *value)
+{
+	struct motorcomm_efuse_patch patch;
+	int i, ret;
+
+	for (i = 0; i < EFUSE_PATCH_MAX_NUM; i++) {
+		ret = motorcomm_efuse_read_patch(priv, i, &patch);
+		if (ret)
+			return ret;
+
+		if (patch.addr == 0) {
+			return -ENOENT;
+		} else if (le16_to_cpu(patch.addr) == addr) {
+			*value = le32_to_cpu(patch.data);
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+static int motorcomm_efuse_read_mac(struct dwmac_motorcomm_priv *priv, u8 *mac)
+{
+	u32 maca0lr, maca0hr;
+	int ret;
+
+	ret = motorcomm_efuse_get_patch_value(priv, EFUSE_ADDR_MACA0LR,
+					      &maca0lr);
+	if (ret)
+		return dev_err_probe(priv->dev, ret,
+				     "failed to read maca0lr from eFuse\n");
+
+	ret = motorcomm_efuse_get_patch_value(priv, EFUSE_ADDR_MACA0HR,
+					      &maca0hr);
+	if (ret)
+		return dev_err_probe(priv->dev, ret,
+				     "failed to read maca0hr from eFuse\n");
+
+	mac[0] = FIELD_GET(GENMASK(15, 8), maca0hr);
+	mac[1] = FIELD_GET(GENMASK(7, 0), maca0hr);
+	mac[2] = FIELD_GET(GENMASK(31, 24), maca0lr);
+	mac[3] = FIELD_GET(GENMASK(23, 16), maca0lr);
+	mac[4] = FIELD_GET(GENMASK(15, 8), maca0lr);
+	mac[5] = FIELD_GET(GENMASK(7, 0), maca0lr);
+
+	return 0;
+}
+
+static void motorcomm_deassert_mdio_phy_reset(struct dwmac_motorcomm_priv *priv)
+{
+	u32 reg = readl(priv->base + EPHY_CTRL);
+
+	reg |= EPHY_MDIO_PHY_RESET;
+
+	writel(reg, priv->base + EPHY_CTRL);
+}
+
+static void motorcomm_reset(struct dwmac_motorcomm_priv *priv)
+{
+	u32 reg = readl(priv->base + SYS_RESET);
+
+	reg &= ~SYS_RESET_RESET;
+	writel(reg, priv->base + SYS_RESET);
+
+	reg |= SYS_RESET_RESET;
+	writel(reg, priv->base + SYS_RESET);
+
+	motorcomm_deassert_mdio_phy_reset(priv);
+}
+
+static void motorcomm_init(struct dwmac_motorcomm_priv *priv)
+{
+	writel(0x0, priv->base + MGMT_INT_CTRL0);
+
+	writel(FIELD_PREP(INT_MODERATION_RX, 200) |
+	       FIELD_PREP(INT_MODERATION_TX, 200),
+	       priv->base + INT_MODERATION);
+
+	/*
+	 * OOB WOL must be disabled during normal operation, or DMA interrupts
+	 * cannot be delivered to the host.
+	 */
+	writel(OOB_WOL_CTRL_DIS, priv->base + OOB_WOL_CTRL);
+}
+
+static int motorcomm_resume(struct device *dev, void *bsp_priv)
+{
+	struct dwmac_motorcomm_priv *priv = bsp_priv;
+	int ret;
+
+	ret = stmmac_pci_plat_resume(dev, bsp_priv);
+	if (ret)
+		return ret;
+
+	/*
+	 * When recovering from D3hot, EPHY_MDIO_PHY_RESET is automatically
+	 * asserted, and must be deasserted for normal operation.
+	 */
+	motorcomm_deassert_mdio_phy_reset(priv);
+	motorcomm_init(priv);
+
+	return 0;
+}
+
+static struct plat_stmmacenet_data *
+motorcomm_default_plat_data(struct pci_dev *pdev)
+{
+	struct plat_stmmacenet_data *plat;
+	struct device *dev = &pdev->dev;
+
+	plat = stmmac_plat_dat_alloc(dev);
+	if (!plat)
+		return NULL;
+
+	plat->mdio_bus_data = devm_kzalloc(dev, sizeof(*plat->mdio_bus_data),
+					   GFP_KERNEL);
+	if (!plat->mdio_bus_data)
+		return NULL;
+
+	plat->dma_cfg = devm_kzalloc(dev, sizeof(*plat->dma_cfg), GFP_KERNEL);
+	if (!plat->dma_cfg)
+		return NULL;
+
+	plat->axi = devm_kzalloc(dev, sizeof(*plat->axi), GFP_KERNEL);
+	if (!plat->axi)
+		return NULL;
+
+	plat->dma_cfg->pbl		= DEFAULT_DMA_PBL;
+	plat->dma_cfg->pblx8		= true;
+	plat->dma_cfg->txpbl		= 32;
+	plat->dma_cfg->rxpbl		= 32;
+	plat->dma_cfg->eame		= true;
+	plat->dma_cfg->mixed_burst	= true;
+
+	plat->axi->axi_wr_osr_lmt	= 1;
+	plat->axi->axi_rd_osr_lmt	= 1;
+	plat->axi->axi_mb		= true;
+	plat->axi->axi_blen_regval	= DMA_AXI_BLEN4 | DMA_AXI_BLEN8 |
+					  DMA_AXI_BLEN16 | DMA_AXI_BLEN32;
+
+	plat->bus_id		= pci_dev_id(pdev);
+	plat->phy_interface	= PHY_INTERFACE_MODE_GMII;
+	/*
+	 * YT6801 requires an 25MHz clock input/oscillator to function, which
+	 * is likely the source of CSR clock.
+	 */
+	plat->clk_csr		= STMMAC_CSR_20_35M;
+	plat->tx_coe		= 1;
+	plat->rx_coe		= 1;
+	plat->clk_ref_rate	= 125000000;
+	plat->core_type		= DWMAC_CORE_GMAC4;
+	plat->suspend		= stmmac_pci_plat_suspend;
+	plat->resume		= motorcomm_resume;
+	plat->flags		= STMMAC_FLAG_TSO_EN |
+				  STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP;
+
+	return plat;
+}
+
+static void motorcomm_free_irq(void *data)
+{
+	struct pci_dev *pdev = data;
+
+	pci_free_irq_vectors(pdev);
+}
+
+static int motorcomm_setup_irq(struct pci_dev *pdev,
+			       struct stmmac_resources *res,
+			       struct plat_stmmacenet_data *plat)
+{
+	int ret;
+
+	ret = pci_alloc_irq_vectors(pdev, 6, 6, PCI_IRQ_MSIX);
+	if (ret > 0) {
+		res->rx_irq[0]	= pci_irq_vector(pdev, 0);
+		res->tx_irq[0]	= pci_irq_vector(pdev, 4);
+		res->irq	= pci_irq_vector(pdev, 5);
+
+		plat->flags |= STMMAC_FLAG_MULTI_MSI_EN;
+	} else {
+		dev_info(&pdev->dev, "failed to allocate MSI-X vector: %d\n",
+			 ret);
+		dev_info(&pdev->dev, "try MSI instead\n");
+
+		ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
+		if (ret < 0)
+			return dev_err_probe(&pdev->dev, ret,
+					     "failed to allocate MSI\n");
+
+		res->irq = pci_irq_vector(pdev, 0);
+	}
+
+	return devm_add_action_or_reset(&pdev->dev, motorcomm_free_irq, pdev);
+}
+
+static int motorcomm_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct plat_stmmacenet_data *plat;
+	struct dwmac_motorcomm_priv *priv;
+	struct stmmac_resources res = {};
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = &pdev->dev;
+
+	plat = motorcomm_default_plat_data(pdev);
+	if (!plat)
+		return -ENOMEM;
+
+	plat->bsp_priv = priv;
+
+	ret = pcim_enable_device(pdev);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to enable device\n");
+
+	priv->base = pcim_iomap_region(pdev, 0, DRIVER_NAME);
+	if (IS_ERR(priv->base))
+		return dev_err_probe(&pdev->dev, PTR_ERR(priv->base),
+				     "failed to map IO region\n");
+
+	pci_set_master(pdev);
+
+	motorcomm_reset(priv);
+
+	ret = motorcomm_efuse_read_mac(priv, res.mac);
+	if (ret == -ENOENT) {
+		dev_warn(&pdev->dev, "eFuse contains no valid MAC address\n");
+		dev_warn(&pdev->dev, "fallback to random MAC address\n");
+
+		memset(res.mac, 0, sizeof(res.mac));
+	} else if (ret) {
+		return dev_err_probe(&pdev->dev, ret,
+				     "failed to read MAC address from eFuse\n");
+	}
+
+	ret = motorcomm_setup_irq(pdev, &res, plat);
+	if (ret)
+		return dev_err_probe(&pdev->dev, ret, "failed to setup IRQ\n");
+
+	motorcomm_init(priv);
+
+	res.addr = priv->base + GMAC_OFFSET;
+
+	return stmmac_dvr_probe(&pdev->dev, plat, &res);
+}
+
+static void motorcomm_remove(struct pci_dev *pdev)
+{
+	stmmac_dvr_remove(&pdev->dev);
+}
+
+static const struct pci_device_id dwmac_motorcomm_pci_id_table[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_MOTORCOMM, 0x6801) },
+	{ },
+};
+MODULE_DEVICE_TABLE(pci, dwmac_motorcomm_pci_id_table);
+
+static struct pci_driver dwmac_motorcomm_pci_driver = {
+	.name = DRIVER_NAME,
+	.id_table = dwmac_motorcomm_pci_id_table,
+	.probe = motorcomm_probe,
+	.remove = motorcomm_remove,
+	.driver = {
+		.pm = &stmmac_simple_pm_ops,
+	},
+};
+
+module_pci_driver(dwmac_motorcomm_pci_driver);
+
+MODULE_DESCRIPTION("DWMAC glue driver for Motorcomm PCI Ethernet controllers");
+MODULE_AUTHOR("Yao Zi <me@ziyao.cc>");
+MODULE_LICENSE("GPL");
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [RFC PATCH net-next v4 3/3] MAINTAINERS: Assign myself as maintainer of Motorcomm DWMAC glue driver
       [not found] <20251216180331.61586-1-me@ziyao.cc>
  2025-12-16 18:03 ` [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller Yao Zi
  2025-12-16 18:03 ` [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller Yao Zi
@ 2025-12-16 18:03 ` Yao Zi
  2 siblings, 0 replies; 6+ messages in thread
From: Yao Zi @ 2025-12-16 18:03 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu
  Cc: linux-kernel, netdev, Mingcong Bai, Kexy Biscuit, Yao Zi

I volunteer to maintain the DWMAC glue driver for Motorcomm ethernet
controllers.

Signed-off-by: Yao Zi <me@ziyao.cc>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e5b1342ee2a6..1483c1071d16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17666,6 +17666,12 @@ F:	drivers/most/
 F:	drivers/staging/most/
 F:	include/linux/most.h
 
+MOTORCOMM DWMAC GLUE DRIVER
+M:	Yao Zi <me@ziyao.cc>
+L:	netdev@vger.kernel.org
+S:	Maintained
+F:	drivers/net/ethernet/stmicro/stmmac/dwmac-motorcomm.c
+
 MOTORCOMM PHY DRIVER
 M:	Frank <Frank.Sae@motor-comm.com>
 L:	netdev@vger.kernel.org
-- 
2.51.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller
  2025-12-16 18:03 ` [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller Yao Zi
@ 2025-12-21 20:29   ` Andrew Lunn
  2025-12-23 17:40     ` Yao Zi
  0 siblings, 1 reply; 6+ messages in thread
From: Andrew Lunn @ 2025-12-21 20:29 UTC (permalink / raw)
  To: Yao Zi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu, linux-kernel, netdev,
	Mingcong Bai, Kexy Biscuit

On Tue, Dec 16, 2025 at 06:03:29PM +0000, Yao Zi wrote:
> YT6801's internal PHY is confirmed as a GMII-capable variant of YT8531S
> by a previous series[1] and reading PHY ID. Add support for
> PHY_INTERFACE_MODE_GMII for YT8531S to allow the Ethernet driver to
> reuse the PHY code for its internal PHY.
> 
> Link: https://lore.kernel.org/all/a48d76ac-db08-46d5-9528-f046a7b541dc@motor-comm.com/ # [1]
> Co-developed-by: Frank Sae <Frank.Sae@motor-comm.com>
> Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
> Signed-off-by: Yao Zi <me@ziyao.cc>
> ---
>  drivers/net/phy/motorcomm.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
> index 89b5b19a9bd2..b751fbc6711a 100644
> --- a/drivers/net/phy/motorcomm.c
> +++ b/drivers/net/phy/motorcomm.c
> @@ -910,6 +910,10 @@ static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
>  		val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
>  		       FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
>  		break;
> +	case PHY_INTERFACE_MODE_GMII:
> +		if (phydev->drv->phy_id != PHY_ID_YT8531S)
> +			return -EOPNOTSUPP;
> +		break;

You have a break here. So the write to RGMII delay register will be
performed, even thought this is an GMII PHY. Does the register exists?
Would it be better to just return 0;

      Andrew

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller
  2025-12-16 18:03 ` [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller Yao Zi
@ 2025-12-21 20:42   ` Andrew Lunn
  0 siblings, 0 replies; 6+ messages in thread
From: Andrew Lunn @ 2025-12-21 20:42 UTC (permalink / raw)
  To: Yao Zi
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu, linux-kernel, netdev,
	Mingcong Bai, Kexy Biscuit, Runhua He, Xi Ruoyao

> +static int motorcomm_efuse_read_patch(struct dwmac_motorcomm_priv *priv,
> +				      u8 index,
> +				      struct motorcomm_efuse_patch *patch)
> +{
> +	u8 buf[sizeof(*patch)], offset;
> +	int i, ret;
> +
> +	for (i = 0; i < sizeof(*patch); i++) {
> +		offset = EFUSE_PATCH_REGION_OFFSET + sizeof(*patch) * index + i;
> +
> +		ret = motorcomm_efuse_read_byte(priv, offset, &buf[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	memcpy(patch, buf, sizeof(*patch));

Why do you write it into a temporary buffer and then copy it to patch?
Why not put it straight into patch?

> +	ret = motorcomm_efuse_read_mac(priv, res.mac);
> +	if (ret == -ENOENT) {
> +		dev_warn(&pdev->dev, "eFuse contains no valid MAC address\n");
> +		dev_warn(&pdev->dev, "fallback to random MAC address\n");
> +
> +		memset(res.mac, 0, sizeof(res.mac));

It is not clear how setting this to zero results in a random MAC
address. Maybe actually call eth_random_addr()?

	 Andrew 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller
  2025-12-21 20:29   ` Andrew Lunn
@ 2025-12-23 17:40     ` Yao Zi
  0 siblings, 0 replies; 6+ messages in thread
From: Yao Zi @ 2025-12-23 17:40 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Frank, Heiner Kallweit, Russell King,
	Russell King (Oracle), Vladimir Oltean, Choong Yong Liang,
	Chen-Yu Tsai, Jisheng Zhang, Furong Xu, linux-kernel, netdev,
	Mingcong Bai, Kexy Biscuit

On Sun, Dec 21, 2025 at 09:29:01PM +0100, Andrew Lunn wrote:
> On Tue, Dec 16, 2025 at 06:03:29PM +0000, Yao Zi wrote:
> > YT6801's internal PHY is confirmed as a GMII-capable variant of YT8531S
> > by a previous series[1] and reading PHY ID. Add support for
> > PHY_INTERFACE_MODE_GMII for YT8531S to allow the Ethernet driver to
> > reuse the PHY code for its internal PHY.
> > 
> > Link: https://lore.kernel.org/all/a48d76ac-db08-46d5-9528-f046a7b541dc@motor-comm.com/ # [1]
> > Co-developed-by: Frank Sae <Frank.Sae@motor-comm.com>
> > Signed-off-by: Frank Sae <Frank.Sae@motor-comm.com>
> > Signed-off-by: Yao Zi <me@ziyao.cc>
> > ---
> >  drivers/net/phy/motorcomm.c | 4 ++++
> >  1 file changed, 4 insertions(+)
> > 
> > diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c
> > index 89b5b19a9bd2..b751fbc6711a 100644
> > --- a/drivers/net/phy/motorcomm.c
> > +++ b/drivers/net/phy/motorcomm.c
> > @@ -910,6 +910,10 @@ static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev)
> >  		val |= FIELD_PREP(YT8521_RC1R_RX_DELAY_MASK, rx_reg) |
> >  		       FIELD_PREP(YT8521_RC1R_GE_TX_DELAY_MASK, tx_reg);
> >  		break;
> > +	case PHY_INTERFACE_MODE_GMII:
> > +		if (phydev->drv->phy_id != PHY_ID_YT8531S)
> > +			return -EOPNOTSUPP;
> > +		break;
> 
> You have a break here. So the write to RGMII delay register will be
> performed, even thought this is an GMII PHY. Does the register exists?

With testing it seems the register simply makes no effect on the YT8531S
PHY integrated in YT6801.

> Would it be better to just return 0;

However, returning early here could avoid possible confusion. Will
change it in v5.

>       Andrew

Regards,
Yao Zi

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-12-23 17:40 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20251216180331.61586-1-me@ziyao.cc>
2025-12-16 18:03 ` [RFC PATCH net-next v4 1/3] net: phy: motorcomm: Support YT8531S PHY in YT6801 Ethernet controller Yao Zi
2025-12-21 20:29   ` Andrew Lunn
2025-12-23 17:40     ` Yao Zi
2025-12-16 18:03 ` [RFC PATCH net-next v4 2/3] net: stmmac: Add glue driver for Motorcomm YT6801 ethernet controller Yao Zi
2025-12-21 20:42   ` Andrew Lunn
2025-12-16 18:03 ` [RFC PATCH net-next v4 3/3] MAINTAINERS: Assign myself as maintainer of Motorcomm DWMAC glue driver Yao Zi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).