[openwrt/openwrt] mediatek: Clause-45 MDIO patch accepted upstream

LEDE Commits lede-commits at lists.infradead.org
Wed Jan 5 06:43:05 PST 2022


dangole pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/87b6e10c71203d2dedd8a56dea91390dac00c525

commit 87b6e10c71203d2dedd8a56dea91390dac00c525
Author: Daniel Golle <daniel at makrotopia.org>
AuthorDate: Wed Jan 5 14:11:06 2022 +0000

    mediatek: Clause-45 MDIO patch accepted upstream
    
    To easy future maintainance, replace the local patch with what has been
    accepted into net-next and is likely to end up in Linux 5.17.
    
    Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 ...-mtk_eth_soc-fix-return-value-of-MDIO-ops.patch |  97 -------------
 ...t-mtk_eth_soc-fix-return-values-and-refac.patch | 128 +++++++++++++++++
 ...k_eth_soc-implement-Clause-45-MDIO-access.patch | 157 ---------------------
 ...d-helpers-to-extract-clause-45-regad-and-.patch |  53 +++++++
 ...t-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch | 128 +++++++++++++++++
 ...-ethernet-mtk_eth_soc-announce-2500baseT.patch} |   2 +-
 6 files changed, 310 insertions(+), 255 deletions(-)

diff --git a/target/linux/mediatek/patches-5.10/701-net-ethernet-mtk_eth_soc-fix-return-value-of-MDIO-ops.patch b/target/linux/mediatek/patches-5.10/701-net-ethernet-mtk_eth_soc-fix-return-value-of-MDIO-ops.patch
deleted file mode 100644
index 696b68df47..0000000000
--- a/target/linux/mediatek/patches-5.10/701-net-ethernet-mtk_eth_soc-fix-return-value-of-MDIO-ops.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From patchwork Mon Dec 27 18:31:09 2021
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel at makrotopia.org>
-X-Patchwork-Id: 12699993
-X-Patchwork-Delegate: kuba at kernel.org
-Return-Path: <netdev-owner at kernel.org>
-Date: Mon, 27 Dec 2021 18:31:09 +0000
-From: Daniel Golle <daniel at makrotopia.org>
-To: linux-mediatek at lists.infradead.org, netdev at vger.kernel.org,
-        linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
-Cc: Felix Fietkau <nbd at nbd.name>, John Crispin <john at phrozen.org>,
-        Sean Wang <sean.wang at mediatek.com>,
-        Mark Lee <Mark-MC.Lee at mediatek.com>,
-        "David S. Miller" <davem at davemloft.net>,
-        Jakub Kicinski <kuba at kernel.org>,
-        Matthias Brugger <matthias.bgg at gmail.com>,
-        Russell King <linux at armlinux.org.uk>,
-        Andrew Lunn <andrew at lunn.ch>
-Subject: [PATCH v5 1/2] net: ethernet: mtk_eth_soc: fix return value of MDIO
- ops
-Message-ID: <YcoGbf/klFzaJhGE at makrotopia.org>
-References: <YcnoAscVe+2YILT8 at shell.armlinux.org.uk>
- <YcnlMtninjjjPhjI at makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-In-Reply-To: <YcnoAscVe+2YILT8 at shell.armlinux.org.uk>
- <YcnlMtninjjjPhjI at makrotopia.org>
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev at vger.kernel.org
-X-Patchwork-Delegate: kuba at kernel.org
-
-Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
-while writing or 0xffff if it happens while reading, return the
-appropriate -EBUSY. Also fix return type to int instead of u32.
-
-Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
-Signed-off-by: Daniel Golle <daniel at makrotopia.org>
----
-v5: fix incomplete unification of variable names phy_reg vs. phy_register
-v4: clean-up return values and types, split into two commits
-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 ++++++++--------
- 1 file changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -95,31 +95,31 @@ static int mtk_mdio_busy_wait(struct mtk
- 	return -1;
- }
- 
--static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
--			   u32 phy_register, u32 write_data)
-+static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
-+			   u32 write_data)
- {
- 	if (mtk_mdio_busy_wait(eth))
--		return -1;
-+		return -EBUSY;
- 
- 	write_data &= 0xffff;
- 
- 	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
--		(phy_register << PHY_IAC_REG_SHIFT) |
-+		(phy_reg << PHY_IAC_REG_SHIFT) |
- 		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
- 		MTK_PHY_IAC);
- 
- 	if (mtk_mdio_busy_wait(eth))
--		return -1;
-+		return -EBUSY;
- 
- 	return 0;
- }
- 
--static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
-+static int _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
- {
- 	u32 d;
- 
- 	if (mtk_mdio_busy_wait(eth))
--		return 0xffff;
-+		return -EBUSY;
- 
- 	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
- 		(phy_reg << PHY_IAC_REG_SHIFT) |
-@@ -127,7 +127,7 @@ static u32 _mtk_mdio_read(struct mtk_eth
- 		MTK_PHY_IAC);
- 
- 	if (mtk_mdio_busy_wait(eth))
--		return 0xffff;
-+		return -EBUSY;
- 
- 	d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
- 
diff --git a/target/linux/mediatek/patches-5.10/701-v5.17-net-ethernet-mtk_eth_soc-fix-return-values-and-refac.patch b/target/linux/mediatek/patches-5.10/701-v5.17-net-ethernet-mtk_eth_soc-fix-return-values-and-refac.patch
new file mode 100644
index 0000000000..5da46f07e0
--- /dev/null
+++ b/target/linux/mediatek/patches-5.10/701-v5.17-net-ethernet-mtk_eth_soc-fix-return-values-and-refac.patch
@@ -0,0 +1,128 @@
+From eda80b249df7bbc7b3dd13907343a3e59bfc57fd Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel at makrotopia.org>
+Date: Tue, 4 Jan 2022 12:06:22 +0000
+Subject: [PATCH 1/3] net: ethernet: mtk_eth_soc: fix return values and
+ refactor MDIO ops
+
+Instead of returning -1 (-EPERM) when MDIO bus is stuck busy
+while writing or 0xffff if it happens while reading, return the
+appropriate -ETIMEDOUT. Also fix return type to int instead of u32.
+Refactor functions to use bitfield helpers instead of having various
+masking and shifting constants in the code, which also results in the
+register definitions in the header file being more obviously related
+to what is stated in the MediaTek's Reference Manual.
+
+Fixes: 656e705243fd0 ("net-next: mediatek: add support for MT7623 ethernet")
+Signed-off-by: Daniel Golle <daniel at makrotopia.org>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++++++++++++---------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 16 +++++--
+ 2 files changed, 41 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -92,46 +92,53 @@ static int mtk_mdio_busy_wait(struct mtk
+ 	}
+ 
+ 	dev_err(eth->dev, "mdio: MDIO timeout\n");
+-	return -1;
++	return -ETIMEDOUT;
+ }
+ 
+-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr,
+-			   u32 phy_register, u32 write_data)
++static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
++			   u32 write_data)
+ {
+-	if (mtk_mdio_busy_wait(eth))
+-		return -1;
++	int ret;
+ 
+-	write_data &= 0xffff;
+-
+-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
+-		(phy_register << PHY_IAC_REG_SHIFT) |
+-		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
++	ret = mtk_mdio_busy_wait(eth);
++	if (ret < 0)
++		return ret;
++
++	mtk_w32(eth, PHY_IAC_ACCESS |
++		     PHY_IAC_START_C22 |
++		     PHY_IAC_CMD_WRITE |
++		     PHY_IAC_REG(phy_reg) |
++		     PHY_IAC_ADDR(phy_addr) |
++		     PHY_IAC_DATA(write_data),
+ 		MTK_PHY_IAC);
+ 
+-	if (mtk_mdio_busy_wait(eth))
+-		return -1;
++	ret = mtk_mdio_busy_wait(eth);
++	if (ret < 0)
++		return ret;
+ 
+ 	return 0;
+ }
+ 
+-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
++static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
+ {
+-	u32 d;
+-
+-	if (mtk_mdio_busy_wait(eth))
+-		return 0xffff;
++	int ret;
+ 
+-	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
+-		(phy_reg << PHY_IAC_REG_SHIFT) |
+-		(phy_addr << PHY_IAC_ADDR_SHIFT),
++	ret = mtk_mdio_busy_wait(eth);
++	if (ret < 0)
++		return ret;
++
++	mtk_w32(eth, PHY_IAC_ACCESS |
++		     PHY_IAC_START_C22 |
++		     PHY_IAC_CMD_C22_READ |
++		     PHY_IAC_REG(phy_reg) |
++		     PHY_IAC_ADDR(phy_addr),
+ 		MTK_PHY_IAC);
+ 
+-	if (mtk_mdio_busy_wait(eth))
+-		return 0xffff;
+-
+-	d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff;
++	ret = mtk_mdio_busy_wait(eth);
++	if (ret < 0)
++		return ret;
+ 
+-	return d;
++	return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
+ }
+ 
+ static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -340,11 +340,17 @@
+ /* PHY Indirect Access Control registers */
+ #define MTK_PHY_IAC		0x10004
+ #define PHY_IAC_ACCESS		BIT(31)
+-#define PHY_IAC_READ		BIT(19)
+-#define PHY_IAC_WRITE		BIT(18)
+-#define PHY_IAC_START		BIT(16)
+-#define PHY_IAC_ADDR_SHIFT	20
+-#define PHY_IAC_REG_SHIFT	25
++#define PHY_IAC_REG_MASK	GENMASK(29, 25)
++#define PHY_IAC_REG(x)		FIELD_PREP(PHY_IAC_REG_MASK, (x))
++#define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
++#define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
++#define PHY_IAC_CMD_MASK	GENMASK(19, 18)
++#define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
++#define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
++#define PHY_IAC_START_MASK	GENMASK(17, 16)
++#define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
++#define PHY_IAC_DATA_MASK	GENMASK(15, 0)
++#define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
+ #define PHY_IAC_TIMEOUT		HZ
+ 
+ #define MTK_MAC_MISC		0x1000c
diff --git a/target/linux/mediatek/patches-5.10/702-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-access.patch b/target/linux/mediatek/patches-5.10/702-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-access.patch
deleted file mode 100644
index f7732cae9b..0000000000
--- a/target/linux/mediatek/patches-5.10/702-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-access.patch
+++ /dev/null
@@ -1,157 +0,0 @@
-From patchwork Mon Dec 27 18:31:43 2021
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-X-Patchwork-Submitter: Daniel Golle <daniel at makrotopia.org>
-X-Patchwork-Id: 12699994
-X-Patchwork-Delegate: kuba at kernel.org
-Return-Path: <netdev-owner at kernel.org>
-Date: Mon, 27 Dec 2021 18:31:43 +0000
-From: Daniel Golle <daniel at makrotopia.org>
-To: linux-mediatek at lists.infradead.org, netdev at vger.kernel.org,
-        linux-arm-kernel at lists.infradead.org, linux-kernel at vger.kernel.org
-Cc: Felix Fietkau <nbd at nbd.name>, John Crispin <john at phrozen.org>,
-        Sean Wang <sean.wang at mediatek.com>,
-        Mark Lee <Mark-MC.Lee at mediatek.com>,
-        "David S. Miller" <davem at davemloft.net>,
-        Jakub Kicinski <kuba at kernel.org>,
-        Matthias Brugger <matthias.bgg at gmail.com>,
-        Russell King <linux at armlinux.org.uk>,
-        Andrew Lunn <andrew at lunn.ch>
-Subject: [PATCH v5 2/2] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
- access
-Message-ID: <YcoGj4Rj5mJlXz4D at makrotopia.org>
-References: <YcnoAscVe+2YILT8 at shell.armlinux.org.uk>
- <YcnlMtninjjjPhjI at makrotopia.org>
-MIME-Version: 1.0
-Content-Disposition: inline
-In-Reply-To: <YcnoAscVe+2YILT8 at shell.armlinux.org.uk>
- <YcnlMtninjjjPhjI at makrotopia.org>
-Precedence: bulk
-List-ID: <netdev.vger.kernel.org>
-X-Mailing-List: netdev at vger.kernel.org
-X-Patchwork-Delegate: kuba at kernel.org
-
-Implement read and write access to IEEE 802.3 Clause 45 Ethernet
-phy registers.
-Tested on the Ubiquiti UniFi 6 LR access point featuring
-MediaTek MT7622BV WiSoC with Aquantia AQR112C.
-
-Signed-off-by: Daniel Golle <daniel at makrotopia.org>
----
-v5: unchanged
-v4: clean-up return values and types, split into two commits
-v3: return -1 instead of 0xffff on error in _mtk_mdio_write
-v2: use MII_DEVADDR_C45_SHIFT and MII_REGADDR_C45_MASK to extract
-    device id and register address. Unify read and write functions to
-    have identical types and parameter names where possible as we are
-    anyway already replacing both function bodies.
-
-
- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 60 +++++++++++++++++----
- drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 ++
- 2 files changed, 53 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -103,10 +103,30 @@ static int _mtk_mdio_write(struct mtk_et
- 
- 	write_data &= 0xffff;
- 
--	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
--		(phy_reg << PHY_IAC_REG_SHIFT) |
--		(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
--		MTK_PHY_IAC);
-+	if (phy_reg & MII_ADDR_C45) {
-+		u8 dev_num = (phy_reg >> MII_DEVADDR_C45_SHIFT) & GENMASK(4, 0);
-+		u16 reg = (u16)(phy_reg & MII_REGADDR_C45_MASK);
-+
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_SET_ADDR |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT) |
-+			(dev_num << PHY_IAC_REG_SHIFT) |
-+			reg,
-+			MTK_PHY_IAC);
-+
-+		if (mtk_mdio_busy_wait(eth))
-+			return -EBUSY;
-+
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_WRITE |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT) |
-+			(dev_num << PHY_IAC_REG_SHIFT) |
-+			write_data,
-+			MTK_PHY_IAC);
-+	} else {
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE |
-+			(phy_reg << PHY_IAC_REG_SHIFT) |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
-+			MTK_PHY_IAC);
-+	}
- 
- 	if (mtk_mdio_busy_wait(eth))
- 		return -EBUSY;
-@@ -114,17 +134,36 @@ static int _mtk_mdio_write(struct mtk_et
- 	return 0;
- }
- 
--static int _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg)
-+static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
- {
--	u32 d;
-+	int d;
- 
- 	if (mtk_mdio_busy_wait(eth))
- 		return -EBUSY;
- 
--	mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
--		(phy_reg << PHY_IAC_REG_SHIFT) |
--		(phy_addr << PHY_IAC_ADDR_SHIFT),
--		MTK_PHY_IAC);
-+	if (phy_reg & MII_ADDR_C45) {
-+		u8 dev_num = (phy_reg >> MII_DEVADDR_C45_SHIFT) & GENMASK(4, 0);
-+		u16 reg = (u16)(phy_reg & MII_REGADDR_C45_MASK);
-+
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_SET_ADDR |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT) |
-+			(dev_num << PHY_IAC_REG_SHIFT) |
-+			reg,
-+			MTK_PHY_IAC);
-+
-+		if (mtk_mdio_busy_wait(eth))
-+			return -EBUSY;
-+
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START_C45 | PHY_IAC_READ_C45 |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT) |
-+			(dev_num << PHY_IAC_REG_SHIFT),
-+			MTK_PHY_IAC);
-+	} else {
-+		mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ |
-+			(phy_reg << PHY_IAC_REG_SHIFT) |
-+			(phy_addr << PHY_IAC_ADDR_SHIFT),
-+			MTK_PHY_IAC);
-+	}
- 
- 	if (mtk_mdio_busy_wait(eth))
- 		return -EBUSY;
-@@ -584,6 +623,7 @@ static int mtk_mdio_init(struct mtk_eth
- 	eth->mii_bus->name = "mdio";
- 	eth->mii_bus->read = mtk_mdio_read;
- 	eth->mii_bus->write = mtk_mdio_write;
-+	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
- 	eth->mii_bus->priv = eth;
- 	eth->mii_bus->parent = eth->dev;
- 
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
-@@ -340,9 +340,12 @@
- /* PHY Indirect Access Control registers */
- #define MTK_PHY_IAC		0x10004
- #define PHY_IAC_ACCESS		BIT(31)
-+#define PHY_IAC_SET_ADDR	0
- #define PHY_IAC_READ		BIT(19)
-+#define PHY_IAC_READ_C45	(BIT(18) | BIT(19))
- #define PHY_IAC_WRITE		BIT(18)
- #define PHY_IAC_START		BIT(16)
-+#define PHY_IAC_START_C45	0
- #define PHY_IAC_ADDR_SHIFT	20
- #define PHY_IAC_REG_SHIFT	25
- #define PHY_IAC_TIMEOUT		HZ
diff --git a/target/linux/mediatek/patches-5.10/702-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch b/target/linux/mediatek/patches-5.10/702-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch
new file mode 100644
index 0000000000..ef2e225717
--- /dev/null
+++ b/target/linux/mediatek/patches-5.10/702-v5.17-net-mdio-add-helpers-to-extract-clause-45-regad-and-.patch
@@ -0,0 +1,53 @@
+From c6af53f038aa32cec12e8a305ba07c7ef168f1b0 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel at armlinux.org.uk>
+Date: Tue, 4 Jan 2022 12:07:00 +0000
+Subject: [PATCH 2/3] net: mdio: add helpers to extract clause 45 regad and
+ devad fields
+
+Add a couple of helpers and definitions to extract the clause 45 regad
+and devad fields from the regnum passed into MDIO drivers.
+
+Tested-by: Daniel Golle <daniel at makrotopia.org>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Signed-off-by: Russell King (Oracle) <rmk+kernel at armlinux.org.uk>
+Signed-off-by: Daniel Golle <daniel at makrotopia.org>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ include/linux/mdio.h | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/include/linux/mdio.h
++++ b/include/linux/mdio.h
+@@ -7,6 +7,7 @@
+ #define __LINUX_MDIO_H__
+ 
+ #include <uapi/linux/mdio.h>
++#include <linux/bitfield.h>
+ #include <linux/mod_devicetable.h>
+ 
+ /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
+@@ -14,6 +15,7 @@
+  */
+ #define MII_ADDR_C45		(1<<30)
+ #define MII_DEVADDR_C45_SHIFT	16
++#define MII_DEVADDR_C45_MASK	GENMASK(20, 16)
+ #define MII_REGADDR_C45_MASK	GENMASK(15, 0)
+ 
+ struct gpio_desc;
+@@ -342,6 +344,16 @@ static inline u32 mdiobus_c45_addr(int d
+ 	return MII_ADDR_C45 | devad << MII_DEVADDR_C45_SHIFT | regnum;
+ }
+ 
++static inline u16 mdiobus_c45_regad(u32 regnum)
++{
++	return FIELD_GET(MII_REGADDR_C45_MASK, regnum);
++}
++
++static inline u16 mdiobus_c45_devad(u32 regnum)
++{
++	return FIELD_GET(MII_DEVADDR_C45_MASK, regnum);
++}
++
+ static inline int __mdiobus_c45_read(struct mii_bus *bus, int prtad, int devad,
+ 				     u16 regnum)
+ {
diff --git a/target/linux/mediatek/patches-5.10/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch b/target/linux/mediatek/patches-5.10/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch
new file mode 100644
index 0000000000..88c600f791
--- /dev/null
+++ b/target/linux/mediatek/patches-5.10/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch
@@ -0,0 +1,128 @@
+From e2e7f6e29c99a1c6afc0e0aa4b9ea80302d28720 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel at makrotopia.org>
+Date: Tue, 4 Jan 2022 12:07:46 +0000
+Subject: [PATCH 3/3] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
+ access
+
+Implement read and write access to IEEE 802.3 Clause 45 Ethernet
+phy registers while making use of new mdiobus_c45_regad and
+mdiobus_c45_devad helpers.
+
+Tested on the Ubiquiti UniFi 6 LR access point featuring
+MediaTek MT7622BV WiSoC with Aquantia AQR112C.
+
+Signed-off-by: Daniel Golle <daniel at makrotopia.org>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 70 +++++++++++++++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  3 +
+ 2 files changed, 60 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -104,13 +104,35 @@ static int _mtk_mdio_write(struct mtk_et
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	mtk_w32(eth, PHY_IAC_ACCESS |
+-		     PHY_IAC_START_C22 |
+-		     PHY_IAC_CMD_WRITE |
+-		     PHY_IAC_REG(phy_reg) |
+-		     PHY_IAC_ADDR(phy_addr) |
+-		     PHY_IAC_DATA(write_data),
+-		MTK_PHY_IAC);
++	if (phy_reg & MII_ADDR_C45) {
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C45 |
++			     PHY_IAC_CMD_C45_ADDR |
++			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
++			     PHY_IAC_ADDR(phy_addr) |
++			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
++			MTK_PHY_IAC);
++
++		ret = mtk_mdio_busy_wait(eth);
++		if (ret < 0)
++			return ret;
++
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C45 |
++			     PHY_IAC_CMD_WRITE |
++			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
++			     PHY_IAC_ADDR(phy_addr) |
++			     PHY_IAC_DATA(write_data),
++			MTK_PHY_IAC);
++	} else {
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C22 |
++			     PHY_IAC_CMD_WRITE |
++			     PHY_IAC_REG(phy_reg) |
++			     PHY_IAC_ADDR(phy_addr) |
++			     PHY_IAC_DATA(write_data),
++			MTK_PHY_IAC);
++	}
+ 
+ 	ret = mtk_mdio_busy_wait(eth);
+ 	if (ret < 0)
+@@ -127,12 +149,33 @@ static int _mtk_mdio_read(struct mtk_eth
+ 	if (ret < 0)
+ 		return ret;
+ 
+-	mtk_w32(eth, PHY_IAC_ACCESS |
+-		     PHY_IAC_START_C22 |
+-		     PHY_IAC_CMD_C22_READ |
+-		     PHY_IAC_REG(phy_reg) |
+-		     PHY_IAC_ADDR(phy_addr),
+-		MTK_PHY_IAC);
++	if (phy_reg & MII_ADDR_C45) {
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C45 |
++			     PHY_IAC_CMD_C45_ADDR |
++			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
++			     PHY_IAC_ADDR(phy_addr) |
++			     PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
++			MTK_PHY_IAC);
++
++		ret = mtk_mdio_busy_wait(eth);
++		if (ret < 0)
++			return ret;
++
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C45 |
++			     PHY_IAC_CMD_C45_READ |
++			     PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
++			     PHY_IAC_ADDR(phy_addr),
++			MTK_PHY_IAC);
++	} else {
++		mtk_w32(eth, PHY_IAC_ACCESS |
++			     PHY_IAC_START_C22 |
++			     PHY_IAC_CMD_C22_READ |
++			     PHY_IAC_REG(phy_reg) |
++			     PHY_IAC_ADDR(phy_addr),
++			MTK_PHY_IAC);
++	}
+ 
+ 	ret = mtk_mdio_busy_wait(eth);
+ 	if (ret < 0)
+@@ -591,6 +634,7 @@ static int mtk_mdio_init(struct mtk_eth
+ 	eth->mii_bus->name = "mdio";
+ 	eth->mii_bus->read = mtk_mdio_read;
+ 	eth->mii_bus->write = mtk_mdio_write;
++	eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
+ 	eth->mii_bus->priv = eth;
+ 	eth->mii_bus->parent = eth->dev;
+ 
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -345,9 +345,12 @@
+ #define PHY_IAC_ADDR_MASK	GENMASK(24, 20)
+ #define PHY_IAC_ADDR(x)		FIELD_PREP(PHY_IAC_ADDR_MASK, (x))
+ #define PHY_IAC_CMD_MASK	GENMASK(19, 18)
++#define PHY_IAC_CMD_C45_ADDR	FIELD_PREP(PHY_IAC_CMD_MASK, 0)
+ #define PHY_IAC_CMD_WRITE	FIELD_PREP(PHY_IAC_CMD_MASK, 1)
+ #define PHY_IAC_CMD_C22_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 2)
++#define PHY_IAC_CMD_C45_READ	FIELD_PREP(PHY_IAC_CMD_MASK, 3)
+ #define PHY_IAC_START_MASK	GENMASK(17, 16)
++#define PHY_IAC_START_C45	FIELD_PREP(PHY_IAC_START_MASK, 0)
+ #define PHY_IAC_START_C22	FIELD_PREP(PHY_IAC_START_MASK, 1)
+ #define PHY_IAC_DATA_MASK	GENMASK(15, 0)
+ #define PHY_IAC_DATA(x)		FIELD_PREP(PHY_IAC_DATA_MASK, (x))
diff --git a/target/linux/mediatek/patches-5.10/703-net-ethernet-mtk_eth_soc-announce-2500baseT.patch b/target/linux/mediatek/patches-5.10/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
similarity index 85%
rename from target/linux/mediatek/patches-5.10/703-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
rename to target/linux/mediatek/patches-5.10/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
index 3dbeec08ac..3afbc01017 100644
--- a/target/linux/mediatek/patches-5.10/703-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
+++ b/target/linux/mediatek/patches-5.10/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
@@ -1,6 +1,6 @@
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -564,6 +564,7 @@ static void mtk_validate(struct phylink_
+@@ -575,6 +575,7 @@ static void mtk_validate(struct phylink_
  		if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
  			phylink_set(mask, 1000baseT_Full);
  			phylink_set(mask, 1000baseX_Full);



More information about the lede-commits mailing list