|
|
@@ -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 <[email protected]>
|
|
|
-X-Patchwork-Id: 12699994
|
|
|
-X-Patchwork-Delegate: [email protected]
|
|
|
-Return-Path: <[email protected]>
|
|
|
-Date: Mon, 27 Dec 2021 18:31:43 +0000
|
|
|
-From: Daniel Golle <[email protected]>
|
|
|
-To: [email protected], [email protected],
|
|
|
- [email protected], [email protected]
|
|
|
-Cc: Felix Fietkau <[email protected]>, John Crispin <[email protected]>,
|
|
|
- Sean Wang <[email protected]>,
|
|
|
- Mark Lee <[email protected]>,
|
|
|
- "David S. Miller" <[email protected]>,
|
|
|
- Jakub Kicinski <[email protected]>,
|
|
|
- Matthias Brugger <[email protected]>,
|
|
|
- Russell King <[email protected]>,
|
|
|
- Andrew Lunn <[email protected]>
|
|
|
-Subject: [PATCH v5 2/2] net: ethernet: mtk_eth_soc: implement Clause 45 MDIO
|
|
|
- access
|
|
|
-Message-ID: <[email protected]>
|
|
|
-References: <[email protected]>
|
|
|
- <[email protected]>
|
|
|
-MIME-Version: 1.0
|
|
|
-Content-Disposition: inline
|
|
|
-In-Reply-To: <[email protected]>
|
|
|
- <[email protected]>
|
|
|
-Precedence: bulk
|
|
|
-List-ID: <netdev.vger.kernel.org>
|
|
|
-X-Mailing-List: [email protected]
|
|
|
-X-Patchwork-Delegate: [email protected]
|
|
|
-
|
|
|
-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 <[email protected]>
|
|
|
----
|
|
|
-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
|