openwrt/target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch
Daniel Golle 5b972d7272 generic: mtk_eth_soc: allow setting MDIO clock frequency
Backport patch allowing to set the MDIO bus clock frequency.
By default the MDIO bus clock runs on 2.5 MHz, allow increasing it
up to 25 MHz.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2023-03-27 19:07:54 +01:00

129 lines
4.1 KiB
Diff

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
@@ -230,13 +230,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)
@@ -253,12 +275,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)
@@ -729,6 +772,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
@@ -376,9 +376,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))