mediatek: add support for Clause 45 MDIO access
Add support for Clause 45 MDIO PHY register read and write operations to mtk_eth_soc driver. Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
parent
215c78eef5
commit
13b3474294
1 changed files with 94 additions and 0 deletions
|
@ -0,0 +1,94 @@
|
||||||
|
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||||
|
@@ -103,10 +103,30 @@ static u32 _mtk_mdio_write(struct mtk_et
|
||||||
|
|
||||||
|
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,
|
||||||
|
- MTK_PHY_IAC);
|
||||||
|
+ if (phy_register & MII_ADDR_C45) {
|
||||||
|
+ u8 dev_num = (phy_register >> 16) & 0x1f;
|
||||||
|
+ u16 reg = (u16)(phy_register & 0xffff);
|
||||||
|
+
|
||||||
|
+ 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 0xffff;
|
||||||
|
+
|
||||||
|
+ 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_register << PHY_IAC_REG_SHIFT) |
|
||||||
|
+ (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data,
|
||||||
|
+ MTK_PHY_IAC);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (mtk_mdio_busy_wait(eth))
|
||||||
|
return -1;
|
||||||
|
@@ -121,10 +141,29 @@ static u32 _mtk_mdio_read(struct mtk_eth
|
||||||
|
if (mtk_mdio_busy_wait(eth))
|
||||||
|
return 0xffff;
|
||||||
|
|
||||||
|
- 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 >> 16) & 0x1f;
|
||||||
|
+ u16 reg = (u16)(phy_reg & 0xffff);
|
||||||
|
+
|
||||||
|
+ 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 0xffff;
|
||||||
|
+
|
||||||
|
+ 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 0xffff;
|
||||||
|
@@ -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
|
Loading…
Reference in a new issue