| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- From e2e7f6e29c99a1c6afc0e0aa4b9ea80302d28720 Mon Sep 17 00:00:00 2001
- From: Daniel Golle <[email protected]>
- 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 <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- 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
- @@ -231,13 +231,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)
- @@ -254,12 +276,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))
|