mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-20 17:32:57 +00:00
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@makrotopia.org>
This commit is contained in:
parent
b2d769673a
commit
87b6e10c71
@ -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@makrotopia.org>
|
||||
X-Patchwork-Id: 12699993
|
||||
X-Patchwork-Delegate: kuba@kernel.org
|
||||
Return-Path: <netdev-owner@kernel.org>
|
||||
Date: Mon, 27 Dec 2021 18:31:09 +0000
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
To: linux-mediatek@lists.infradead.org, netdev@vger.kernel.org,
|
||||
linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
|
||||
Cc: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
|
||||
Sean Wang <sean.wang@mediatek.com>,
|
||||
Mark Lee <Mark-MC.Lee@mediatek.com>,
|
||||
"David S. Miller" <davem@davemloft.net>,
|
||||
Jakub Kicinski <kuba@kernel.org>,
|
||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Andrew Lunn <andrew@lunn.ch>
|
||||
Subject: [PATCH v5 1/2] net: ethernet: mtk_eth_soc: fix return value of MDIO
|
||||
ops
|
||||
Message-ID: <YcoGbf/klFzaJhGE@makrotopia.org>
|
||||
References: <YcnoAscVe+2YILT8@shell.armlinux.org.uk>
|
||||
<YcnlMtninjjjPhjI@makrotopia.org>
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: inline
|
||||
In-Reply-To: <YcnoAscVe+2YILT8@shell.armlinux.org.uk>
|
||||
<YcnlMtninjjjPhjI@makrotopia.org>
|
||||
Precedence: bulk
|
||||
List-ID: <netdev.vger.kernel.org>
|
||||
X-Mailing-List: netdev@vger.kernel.org
|
||||
X-Patchwork-Delegate: kuba@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@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;
|
||||
|
@ -0,0 +1,128 @@
|
||||
From eda80b249df7bbc7b3dd13907343a3e59bfc57fd Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@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@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@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
|
@ -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@makrotopia.org>
|
||||
X-Patchwork-Id: 12699994
|
||||
X-Patchwork-Delegate: kuba@kernel.org
|
||||
Return-Path: <netdev-owner@kernel.org>
|
||||
Date: Mon, 27 Dec 2021 18:31:43 +0000
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
To: linux-mediatek@lists.infradead.org, netdev@vger.kernel.org,
|
||||
linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org
|
||||
Cc: Felix Fietkau <nbd@nbd.name>, John Crispin <john@phrozen.org>,
|
||||
Sean Wang <sean.wang@mediatek.com>,
|
||||
Mark Lee <Mark-MC.Lee@mediatek.com>,
|
||||
"David S. Miller" <davem@davemloft.net>,
|
||||
Jakub Kicinski <kuba@kernel.org>,
|
||||
Matthias Brugger <matthias.bgg@gmail.com>,
|
||||
Russell King <linux@armlinux.org.uk>,
|
||||
Andrew Lunn <andrew@lunn.ch>
|
||||
Subject: [PATCH v5 2/2] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
|
||||
access
|
||||
Message-ID: <YcoGj4Rj5mJlXz4D@makrotopia.org>
|
||||
References: <YcnoAscVe+2YILT8@shell.armlinux.org.uk>
|
||||
<YcnlMtninjjjPhjI@makrotopia.org>
|
||||
MIME-Version: 1.0
|
||||
Content-Disposition: inline
|
||||
In-Reply-To: <YcnoAscVe+2YILT8@shell.armlinux.org.uk>
|
||||
<YcnlMtninjjjPhjI@makrotopia.org>
|
||||
Precedence: bulk
|
||||
List-ID: <netdev.vger.kernel.org>
|
||||
X-Mailing-List: netdev@vger.kernel.org
|
||||
X-Patchwork-Delegate: kuba@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@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
|
@ -0,0 +1,53 @@
|
||||
From c6af53f038aa32cec12e8a305ba07c7ef168f1b0 Mon Sep 17 00:00:00 2001
|
||||
From: "Russell King (Oracle)" <rmk+kernel@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@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@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)
|
||||
{
|
@ -0,0 +1,128 @@
|
||||
From e2e7f6e29c99a1c6afc0e0aa4b9ea80302d28720 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@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@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@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))
|
@ -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);
|
Loading…
x
Reference in New Issue
Block a user