Commit 90088837 authored by Andrew Lunn's avatar Andrew Lunn Committed by Jakub Kicinski

net: ethernet: mtk_eth_soc: Separate C22 and C45 transactions

The mediatek bus driver can perform both C22 and C45 transfers.
Create separate functions for each and register the C45 versions using
the new API calls.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarMichael Walle <michael@walle.cc>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c58e3994
......@@ -215,7 +215,7 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth)
return -ETIMEDOUT;
}
static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
static int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
u32 write_data)
{
int ret;
......@@ -224,13 +224,36 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
if (ret < 0)
return ret;
if (phy_reg & MII_ADDR_C45) {
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)
return ret;
return 0;
}
static int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr,
u32 devad, u32 phy_reg, u32 write_data)
{
int ret;
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_ADDR |
PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
PHY_IAC_REG(devad) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
PHY_IAC_DATA(phy_reg),
MTK_PHY_IAC);
ret = mtk_mdio_busy_wait(eth);
......@@ -240,28 +263,42 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
mtk_w32(eth, PHY_IAC_ACCESS |
PHY_IAC_START_C45 |
PHY_IAC_CMD_WRITE |
PHY_IAC_REG(mdiobus_c45_devad(phy_reg)) |
PHY_IAC_REG(devad) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(write_data),
MTK_PHY_IAC);
} else {
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
return ret;
return 0;
}
static int _mtk_mdio_read_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
{
int ret;
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_CMD_C22_READ |
PHY_IAC_REG(phy_reg) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(write_data),
PHY_IAC_ADDR(phy_addr),
MTK_PHY_IAC);
}
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
return ret;
return 0;
return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
}
static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
static int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr,
u32 devad, u32 phy_reg)
{
int ret;
......@@ -269,13 +306,12 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
if (ret < 0)
return ret;
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_REG(devad) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
PHY_IAC_DATA(phy_reg),
MTK_PHY_IAC);
ret = mtk_mdio_busy_wait(eth);
......@@ -285,17 +321,9 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
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_REG(devad) |
PHY_IAC_ADDR(phy_addr),
MTK_PHY_IAC);
}
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
......@@ -304,19 +332,35 @@ static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
}
static int mtk_mdio_write(struct mii_bus *bus, int phy_addr,
static int mtk_mdio_write_c22(struct mii_bus *bus, int phy_addr,
int phy_reg, u16 val)
{
struct mtk_eth *eth = bus->priv;
return _mtk_mdio_write(eth, phy_addr, phy_reg, val);
return _mtk_mdio_write_c22(eth, phy_addr, phy_reg, val);
}
static int mtk_mdio_write_c45(struct mii_bus *bus, int phy_addr,
int devad, int phy_reg, u16 val)
{
struct mtk_eth *eth = bus->priv;
return _mtk_mdio_write_c45(eth, phy_addr, devad, phy_reg, val);
}
static int mtk_mdio_read_c22(struct mii_bus *bus, int phy_addr, int phy_reg)
{
struct mtk_eth *eth = bus->priv;
return _mtk_mdio_read_c22(eth, phy_addr, phy_reg);
}
static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
static int mtk_mdio_read_c45(struct mii_bus *bus, int phy_addr, int devad,
int phy_reg)
{
struct mtk_eth *eth = bus->priv;
return _mtk_mdio_read(eth, phy_addr, phy_reg);
return _mtk_mdio_read_c45(eth, phy_addr, devad, phy_reg);
}
static int mt7621_gmac0_rgmii_adjust(struct mtk_eth *eth,
......@@ -760,8 +804,10 @@ static int mtk_mdio_init(struct mtk_eth *eth)
}
eth->mii_bus->name = "mdio";
eth->mii_bus->read = mtk_mdio_read;
eth->mii_bus->write = mtk_mdio_write;
eth->mii_bus->read = mtk_mdio_read_c22;
eth->mii_bus->write = mtk_mdio_write_c22;
eth->mii_bus->read_c45 = mtk_mdio_read_c45;
eth->mii_bus->write_c45 = mtk_mdio_write_c45;
eth->mii_bus->probe_capabilities = MDIOBUS_C22_C45;
eth->mii_bus->priv = eth;
eth->mii_bus->parent = eth->dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment