Merge branch 'net-mdio-continue-separating-c22-and-c45'

Michael Walle says:

====================
net: mdio: Continue separating C22 and C45

I've picked this older series from Andrew up and rebased it onto
the latest net-next.

This is the second patch set in the series which separates the C22
and C45 MDIO bus transactions at the API level to the MDIO bus drivers.
====================

Link: https://lore.kernel.org/r/20230112-net-next-c45-seperation-part-2-v1-0-5eeaae931526@walle.cc
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2023-01-13 21:40:56 -08:00
commit da1b0b5c1b
16 changed files with 778 additions and 444 deletions

View File

@ -954,8 +954,10 @@ static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
return -ENOMEM;
bus->name = "VSC9959 internal MDIO bus";
bus->read = enetc_mdio_read;
bus->write = enetc_mdio_write;
bus->read = enetc_mdio_read_c22;
bus->write = enetc_mdio_write_c22;
bus->read_c45 = enetc_mdio_read_c45;
bus->write_c45 = enetc_mdio_write_c45;
bus->parent = dev;
mdio_priv = bus->priv;
mdio_priv->hw = hw;

View File

@ -55,7 +55,8 @@ static int enetc_mdio_wait_complete(struct enetc_mdio_priv *mdio_priv)
is_busy, !is_busy, 10, 10 * 1000);
}
int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
int enetc_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum,
u16 value)
{
struct enetc_mdio_priv *mdio_priv = bus->priv;
u32 mdio_ctl, mdio_cfg;
@ -63,14 +64,39 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
int ret;
mdio_cfg = ENETC_EMDIO_CFG;
if (regnum & MII_ADDR_C45) {
dev_addr = (regnum >> 16) & 0x1f;
mdio_cfg |= MDIO_CFG_ENC45;
} else {
/* clause 22 (ie 1G) */
dev_addr = regnum & 0x1f;
mdio_cfg &= ~MDIO_CFG_ENC45;
}
dev_addr = regnum & 0x1f;
mdio_cfg &= ~MDIO_CFG_ENC45;
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
/* set port and dev addr */
mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);
/* write the value */
enetc_mdio_wr(mdio_priv, ENETC_MDIO_DATA, value);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(enetc_mdio_write_c22);
int enetc_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
int regnum, u16 value)
{
struct enetc_mdio_priv *mdio_priv = bus->priv;
u32 mdio_ctl, mdio_cfg;
int ret;
mdio_cfg = ENETC_EMDIO_CFG;
mdio_cfg |= MDIO_CFG_ENC45;
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);
@ -83,13 +109,11 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);
/* set the register address */
if (regnum & MII_ADDR_C45) {
enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);
enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
}
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
/* write the value */
enetc_mdio_wr(mdio_priv, ENETC_MDIO_DATA, value);
@ -100,9 +124,9 @@ int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value)
return 0;
}
EXPORT_SYMBOL_GPL(enetc_mdio_write);
EXPORT_SYMBOL_GPL(enetc_mdio_write_c45);
int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
int enetc_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
struct enetc_mdio_priv *mdio_priv = bus->priv;
u32 mdio_ctl, mdio_cfg;
@ -110,13 +134,8 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
int ret;
mdio_cfg = ENETC_EMDIO_CFG;
if (regnum & MII_ADDR_C45) {
dev_addr = (regnum >> 16) & 0x1f;
mdio_cfg |= MDIO_CFG_ENC45;
} else {
dev_addr = regnum & 0x1f;
mdio_cfg &= ~MDIO_CFG_ENC45;
}
dev_addr = regnum & 0x1f;
mdio_cfg &= ~MDIO_CFG_ENC45;
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);
@ -128,15 +147,6 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);
/* set the register address */
if (regnum & MII_ADDR_C45) {
enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
}
/* initiate the read */
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl | MDIO_CTL_READ);
@ -156,7 +166,56 @@ int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
return value;
}
EXPORT_SYMBOL_GPL(enetc_mdio_read);
EXPORT_SYMBOL_GPL(enetc_mdio_read_c22);
int enetc_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr,
int regnum)
{
struct enetc_mdio_priv *mdio_priv = bus->priv;
u32 mdio_ctl, mdio_cfg;
u16 value;
int ret;
mdio_cfg = ENETC_EMDIO_CFG;
mdio_cfg |= MDIO_CFG_ENC45;
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CFG, mdio_cfg);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
/* set port and device addr */
mdio_ctl = MDIO_CTL_PORT_ADDR(phy_id) | MDIO_CTL_DEV_ADDR(dev_addr);
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl);
/* set the register address */
enetc_mdio_wr(mdio_priv, ENETC_MDIO_ADDR, regnum & 0xffff);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
/* initiate the read */
enetc_mdio_wr(mdio_priv, ENETC_MDIO_CTL, mdio_ctl | MDIO_CTL_READ);
ret = enetc_mdio_wait_complete(mdio_priv);
if (ret)
return ret;
/* return all Fs if nothing was there */
if (enetc_mdio_rd(mdio_priv, ENETC_MDIO_CFG) & MDIO_CFG_RD_ER) {
dev_dbg(&bus->dev,
"Error while reading PHY%d reg at %d.%d\n",
phy_id, dev_addr, regnum);
return 0xffff;
}
value = enetc_mdio_rd(mdio_priv, ENETC_MDIO_DATA) & 0xffff;
return value;
}
EXPORT_SYMBOL_GPL(enetc_mdio_read_c45);
struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
{

View File

@ -39,8 +39,10 @@ static int enetc_pci_mdio_probe(struct pci_dev *pdev,
}
bus->name = ENETC_MDIO_BUS_NAME;
bus->read = enetc_mdio_read;
bus->write = enetc_mdio_write;
bus->read = enetc_mdio_read_c22;
bus->write = enetc_mdio_write_c22;
bus->read_c45 = enetc_mdio_read_c45;
bus->write_c45 = enetc_mdio_write_c45;
bus->parent = dev;
mdio_priv = bus->priv;
mdio_priv->hw = hw;

View File

@ -848,8 +848,10 @@ static int enetc_mdio_probe(struct enetc_pf *pf, struct device_node *np)
return -ENOMEM;
bus->name = "Freescale ENETC MDIO Bus";
bus->read = enetc_mdio_read;
bus->write = enetc_mdio_write;
bus->read = enetc_mdio_read_c22;
bus->write = enetc_mdio_write_c22;
bus->read_c45 = enetc_mdio_read_c45;
bus->write_c45 = enetc_mdio_write_c45;
bus->parent = dev;
mdio_priv = bus->priv;
mdio_priv->hw = &pf->si->hw;
@ -885,8 +887,10 @@ static int enetc_imdio_create(struct enetc_pf *pf)
return -ENOMEM;
bus->name = "Freescale ENETC internal MDIO Bus";
bus->read = enetc_mdio_read;
bus->write = enetc_mdio_write;
bus->read = enetc_mdio_read_c22;
bus->write = enetc_mdio_write_c22;
bus->read_c45 = enetc_mdio_read_c45;
bus->write_c45 = enetc_mdio_write_c45;
bus->parent = dev;
bus->phy_mask = ~0;
mdio_priv = bus->priv;

View File

@ -215,8 +215,8 @@ 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,
u32 write_data)
static int _mtk_mdio_write_c22(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
u32 write_data)
{
int ret;
@ -224,35 +224,13 @@ 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_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);
}
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)
@ -261,7 +239,8 @@ static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg,
return 0;
}
static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg)
static int _mtk_mdio_write_c45(struct mtk_eth *eth, u32 phy_addr,
u32 devad, u32 phy_reg, u32 write_data)
{
int ret;
@ -269,33 +248,47 @@ 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_ADDR(phy_addr) |
PHY_IAC_DATA(mdiobus_c45_regad(phy_reg)),
MTK_PHY_IAC);
mtk_w32(eth, PHY_IAC_ACCESS |
PHY_IAC_START_C45 |
PHY_IAC_CMD_C45_ADDR |
PHY_IAC_REG(devad) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(phy_reg),
MTK_PHY_IAC);
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
return 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_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);
}
mtk_w32(eth, PHY_IAC_ACCESS |
PHY_IAC_START_C45 |
PHY_IAC_CMD_WRITE |
PHY_IAC_REG(devad) |
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_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_C22_READ |
PHY_IAC_REG(phy_reg) |
PHY_IAC_ADDR(phy_addr),
MTK_PHY_IAC);
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
@ -304,19 +297,70 @@ 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,
int phy_reg, u16 val)
static int _mtk_mdio_read_c45(struct mtk_eth *eth, u32 phy_addr,
u32 devad, u32 phy_reg)
{
struct mtk_eth *eth = bus->priv;
int ret;
return _mtk_mdio_write(eth, phy_addr, phy_reg, val);
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(devad) |
PHY_IAC_ADDR(phy_addr) |
PHY_IAC_DATA(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(devad) |
PHY_IAC_ADDR(phy_addr),
MTK_PHY_IAC);
ret = mtk_mdio_busy_wait(eth);
if (ret < 0)
return ret;
return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK;
}
static int mtk_mdio_read(struct mii_bus *bus, int phy_addr, int phy_reg)
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_read(eth, phy_addr, phy_reg);
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_c45(struct mii_bus *bus, int phy_addr, int devad,
int phy_reg)
{
struct mtk_eth *eth = bus->priv;
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;

View File

@ -792,7 +792,7 @@ static int lan743x_mac_mii_wait_till_not_busy(struct lan743x_adapter *adapter)
!(data & MAC_MII_ACC_MII_BUSY_), 0, 1000000);
}
static int lan743x_mdiobus_read(struct mii_bus *bus, int phy_id, int index)
static int lan743x_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int index)
{
struct lan743x_adapter *adapter = bus->priv;
u32 val, mii_access;
@ -814,8 +814,8 @@ static int lan743x_mdiobus_read(struct mii_bus *bus, int phy_id, int index)
return (int)(val & 0xFFFF);
}
static int lan743x_mdiobus_write(struct mii_bus *bus,
int phy_id, int index, u16 regval)
static int lan743x_mdiobus_write_c22(struct mii_bus *bus,
int phy_id, int index, u16 regval)
{
struct lan743x_adapter *adapter = bus->priv;
u32 val, mii_access;
@ -835,12 +835,10 @@ static int lan743x_mdiobus_write(struct mii_bus *bus,
return ret;
}
static u32 lan743x_mac_mmd_access(int id, int index, int op)
static u32 lan743x_mac_mmd_access(int id, int dev_addr, int op)
{
u16 dev_addr;
u32 ret;
dev_addr = (index >> 16) & 0x1f;
ret = (id << MAC_MII_ACC_PHY_ADDR_SHIFT_) &
MAC_MII_ACC_PHY_ADDR_MASK_;
ret |= (dev_addr << MAC_MII_ACC_MIIMMD_SHIFT_) &
@ -858,7 +856,8 @@ static u32 lan743x_mac_mmd_access(int id, int index, int op)
return ret;
}
static int lan743x_mdiobus_c45_read(struct mii_bus *bus, int phy_id, int index)
static int lan743x_mdiobus_read_c45(struct mii_bus *bus, int phy_id,
int dev_addr, int index)
{
struct lan743x_adapter *adapter = bus->priv;
u32 mmd_access;
@ -868,32 +867,30 @@ static int lan743x_mdiobus_c45_read(struct mii_bus *bus, int phy_id, int index)
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
if (index & MII_ADDR_C45) {
/* Load Register Address */
lan743x_csr_write(adapter, MAC_MII_DATA, (u32)(index & 0xffff));
mmd_access = lan743x_mac_mmd_access(phy_id, index,
MMD_ACCESS_ADDRESS);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
/* Read Data */
mmd_access = lan743x_mac_mmd_access(phy_id, index,
MMD_ACCESS_READ);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
ret = lan743x_csr_read(adapter, MAC_MII_DATA);
return (int)(ret & 0xFFFF);
}
ret = lan743x_mdiobus_read(bus, phy_id, index);
return ret;
/* Load Register Address */
lan743x_csr_write(adapter, MAC_MII_DATA, index);
mmd_access = lan743x_mac_mmd_access(phy_id, dev_addr,
MMD_ACCESS_ADDRESS);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
/* Read Data */
mmd_access = lan743x_mac_mmd_access(phy_id, dev_addr,
MMD_ACCESS_READ);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
ret = lan743x_csr_read(adapter, MAC_MII_DATA);
return (int)(ret & 0xFFFF);
}
static int lan743x_mdiobus_c45_write(struct mii_bus *bus,
int phy_id, int index, u16 regval)
static int lan743x_mdiobus_write_c45(struct mii_bus *bus, int phy_id,
int dev_addr, int index, u16 regval)
{
struct lan743x_adapter *adapter = bus->priv;
u32 mmd_access;
@ -903,26 +900,23 @@ static int lan743x_mdiobus_c45_write(struct mii_bus *bus,
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
if (index & MII_ADDR_C45) {
/* Load Register Address */
lan743x_csr_write(adapter, MAC_MII_DATA, (u32)(index & 0xffff));
mmd_access = lan743x_mac_mmd_access(phy_id, index,
MMD_ACCESS_ADDRESS);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
/* Write Data */
lan743x_csr_write(adapter, MAC_MII_DATA, (u32)regval);
mmd_access = lan743x_mac_mmd_access(phy_id, index,
MMD_ACCESS_WRITE);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
} else {
ret = lan743x_mdiobus_write(bus, phy_id, index, regval);
}
return ret;
/* Load Register Address */
lan743x_csr_write(adapter, MAC_MII_DATA, (u32)index);
mmd_access = lan743x_mac_mmd_access(phy_id, dev_addr,
MMD_ACCESS_ADDRESS);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
ret = lan743x_mac_mii_wait_till_not_busy(adapter);
if (ret < 0)
return ret;
/* Write Data */
lan743x_csr_write(adapter, MAC_MII_DATA, (u32)regval);
mmd_access = lan743x_mac_mmd_access(phy_id, dev_addr,
MMD_ACCESS_WRITE);
lan743x_csr_write(adapter, MAC_MII_ACC, mmd_access);
return lan743x_mac_mii_wait_till_not_busy(adapter);
}
static int lan743x_sgmii_wait_till_not_busy(struct lan743x_adapter *adapter)
@ -3286,8 +3280,10 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter)
netif_dbg(adapter, drv, adapter->netdev,
"SGMII operation\n");
adapter->mdiobus->probe_capabilities = MDIOBUS_C22_C45;
adapter->mdiobus->read = lan743x_mdiobus_c45_read;
adapter->mdiobus->write = lan743x_mdiobus_c45_write;
adapter->mdiobus->read = lan743x_mdiobus_read_c22;
adapter->mdiobus->write = lan743x_mdiobus_write_c22;
adapter->mdiobus->read_c45 = lan743x_mdiobus_read_c45;
adapter->mdiobus->write_c45 = lan743x_mdiobus_write_c45;
adapter->mdiobus->name = "lan743x-mdiobus-c45";
netif_dbg(adapter, drv, adapter->netdev,
"lan743x-mdiobus-c45\n");
@ -3300,15 +3296,15 @@ static int lan743x_mdiobus_init(struct lan743x_adapter *adapter)
"RGMII operation\n");
// Only C22 support when RGMII I/F
adapter->mdiobus->probe_capabilities = MDIOBUS_C22;
adapter->mdiobus->read = lan743x_mdiobus_read;
adapter->mdiobus->write = lan743x_mdiobus_write;
adapter->mdiobus->read = lan743x_mdiobus_read_c22;
adapter->mdiobus->write = lan743x_mdiobus_write_c22;
adapter->mdiobus->name = "lan743x-mdiobus";
netif_dbg(adapter, drv, adapter->netdev,
"lan743x-mdiobus\n");
}
} else {
adapter->mdiobus->read = lan743x_mdiobus_read;
adapter->mdiobus->write = lan743x_mdiobus_write;
adapter->mdiobus->read = lan743x_mdiobus_read_c22;
adapter->mdiobus->write = lan743x_mdiobus_write_c22;
adapter->mdiobus->name = "lan743x-mdiobus";
netif_dbg(adapter, drv, adapter->netdev, "lan743x-mdiobus\n");
}

View File

@ -45,8 +45,8 @@
#define MII_XGMAC_PA_SHIFT 16
#define MII_XGMAC_DA_SHIFT 21
static int stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr,
int phyreg, u32 *hw_addr)
static void stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr,
int devad, int phyreg, u32 *hw_addr)
{
u32 tmp;
@ -56,19 +56,14 @@ static int stmmac_xgmac2_c45_format(struct stmmac_priv *priv, int phyaddr,
writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
*hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0xffff);
*hw_addr |= (phyreg >> MII_DEVADDR_C45_SHIFT) << MII_XGMAC_DA_SHIFT;
return 0;
*hw_addr |= devad << MII_XGMAC_DA_SHIFT;
}
static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
int phyreg, u32 *hw_addr)
static void stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
int phyreg, u32 *hw_addr)
{
u32 tmp;
/* HW does not support C22 addr >= 4 */
if (phyaddr > MII_XGMAC_MAX_C22ADDR)
return -ENODEV;
/* Set port as Clause 22 */
tmp = readl(priv->ioaddr + XGMAC_MDIO_C22P);
tmp &= ~MII_XGMAC_C22P_MASK;
@ -76,16 +71,14 @@ static int stmmac_xgmac2_c22_format(struct stmmac_priv *priv, int phyaddr,
writel(tmp, priv->ioaddr + XGMAC_MDIO_C22P);
*hw_addr = (phyaddr << MII_XGMAC_PA_SHIFT) | (phyreg & 0x1f);
return 0;
}
static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
static int stmmac_xgmac2_mdio_read(struct stmmac_priv *priv, u32 addr,
u32 value)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
u32 tmp, addr, value = MII_XGMAC_BUSY;
u32 tmp;
int ret;
ret = pm_runtime_resume_and_get(priv->device);
@ -99,20 +92,6 @@ static int stmmac_xgmac2_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
goto err_disable_clks;
}
if (phyreg & MII_ADDR_C45) {
phyreg &= ~MII_ADDR_C45;
ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
if (ret)
goto err_disable_clks;
} else {
ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
if (ret)
goto err_disable_clks;
value |= MII_XGMAC_SADDR;
}
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
value |= MII_XGMAC_READ;
@ -144,14 +123,44 @@ err_disable_clks:
return ret;
}
static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
int phyreg, u16 phydata)
static int stmmac_xgmac2_mdio_read_c22(struct mii_bus *bus, int phyaddr,
int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
struct stmmac_priv *priv;
u32 addr;
priv = netdev_priv(ndev);
/* HW does not support C22 addr >= 4 */
if (phyaddr > MII_XGMAC_MAX_C22ADDR)
return -ENODEV;
stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
return stmmac_xgmac2_mdio_read(priv, addr, MII_XGMAC_BUSY);
}
static int stmmac_xgmac2_mdio_read_c45(struct mii_bus *bus, int phyaddr,
int devad, int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv;
u32 addr;
priv = netdev_priv(ndev);
stmmac_xgmac2_c45_format(priv, phyaddr, devad, phyreg, &addr);
return stmmac_xgmac2_mdio_read(priv, addr, MII_XGMAC_BUSY);
}
static int stmmac_xgmac2_mdio_write(struct stmmac_priv *priv, u32 addr,
u32 value, u16 phydata)
{
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
u32 addr, tmp, value = MII_XGMAC_BUSY;
u32 tmp;
int ret;
ret = pm_runtime_resume_and_get(priv->device);
@ -165,20 +174,6 @@ static int stmmac_xgmac2_mdio_write(struct mii_bus *bus, int phyaddr,
goto err_disable_clks;
}
if (phyreg & MII_ADDR_C45) {
phyreg &= ~MII_ADDR_C45;
ret = stmmac_xgmac2_c45_format(priv, phyaddr, phyreg, &addr);
if (ret)
goto err_disable_clks;
} else {
ret = stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
if (ret)
goto err_disable_clks;
value |= MII_XGMAC_SADDR;
}
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
value |= phydata;
@ -205,8 +200,63 @@ err_disable_clks:
return ret;
}
static int stmmac_xgmac2_mdio_write_c22(struct mii_bus *bus, int phyaddr,
int phyreg, u16 phydata)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv;
u32 addr;
priv = netdev_priv(ndev);
/* HW does not support C22 addr >= 4 */
if (phyaddr > MII_XGMAC_MAX_C22ADDR)
return -ENODEV;
stmmac_xgmac2_c22_format(priv, phyaddr, phyreg, &addr);
return stmmac_xgmac2_mdio_write(priv, addr,
MII_XGMAC_BUSY | MII_XGMAC_SADDR, phydata);
}
static int stmmac_xgmac2_mdio_write_c45(struct mii_bus *bus, int phyaddr,
int devad, int phyreg, u16 phydata)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv;
u32 addr;
priv = netdev_priv(ndev);
stmmac_xgmac2_c45_format(priv, phyaddr, devad, phyreg, &addr);
return stmmac_xgmac2_mdio_write(priv, addr, MII_XGMAC_BUSY,
phydata);
}
static int stmmac_mdio_read(struct stmmac_priv *priv, int data, u32 value)
{
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
u32 v;
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000))
return -EBUSY;
writel(data, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000))
return -EBUSY;
/* Read the data from the MII data register */
return readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
}
/**
* stmmac_mdio_read
* stmmac_mdio_read_c22
* @bus: points to the mii_bus structure
* @phyaddr: MII addr
* @phyreg: MII reg
@ -215,15 +265,12 @@ err_disable_clks:
* accessing the PHY registers.
* Fortunately, it seems this has no drawback for the 7109 MAC.
*/
static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
static int stmmac_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
u32 value = MII_BUSY;
int data = 0;
u32 v;
data = pm_runtime_resume_and_get(priv->device);
if (data < 0)
@ -236,60 +283,94 @@ static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
& priv->hw->mii.clk_csr_mask;
if (priv->plat->has_gmac4) {
value |= MII_GMAC4_READ;
if (phyreg & MII_ADDR_C45) {
value |= MII_GMAC4_C45E;
value &= ~priv->hw->mii.reg_mask;
value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
priv->hw->mii.reg_shift) &
priv->hw->mii.reg_mask;
data |= (phyreg & MII_REGADDR_C45_MASK) <<
MII_GMAC4_REG_ADDR_SHIFT;
}
}
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000)) {
data = -EBUSY;
goto err_disable_clks;
}
data = stmmac_mdio_read(priv, data, value);
writel(data, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000)) {
data = -EBUSY;
goto err_disable_clks;
}
/* Read the data from the MII data register */
data = (int)readl(priv->ioaddr + mii_data) & MII_DATA_MASK;
err_disable_clks:
pm_runtime_put(priv->device);
return data;
}
/**
* stmmac_mdio_write
* stmmac_mdio_read_c45
* @bus: points to the mii_bus structure
* @phyaddr: MII addr
* @devad: device address to read
* @phyreg: MII reg
* Description: it reads data from the MII register from within the phy device.
* For the 7111 GMAC, we must set the bit 0 in the MII address register while
* accessing the PHY registers.
* Fortunately, it seems this has no drawback for the 7109 MAC.
*/
static int stmmac_mdio_read_c45(struct mii_bus *bus, int phyaddr, int devad,
int phyreg)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
u32 value = MII_BUSY;
int data = 0;
data = pm_runtime_get_sync(priv->device);
if (data < 0) {
pm_runtime_put_noidle(priv->device);
return data;
}
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
value |= MII_GMAC4_READ;
value |= MII_GMAC4_C45E;
value &= ~priv->hw->mii.reg_mask;
value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
data |= phyreg << MII_GMAC4_REG_ADDR_SHIFT;
data = stmmac_mdio_read(priv, data, value);
pm_runtime_put(priv->device);
return data;
}
static int stmmac_mdio_write(struct stmmac_priv *priv, int data, u32 value)
{
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
u32 v;
/* Wait until any existing MII operation is complete */
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000))
return -EBUSY;
/* Set the MII address register to write */
writel(data, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
/* Wait until any existing MII operation is complete */
return readl_poll_timeout(priv->ioaddr + mii_address, v,
!(v & MII_BUSY), 100, 10000);
}
/**
* stmmac_mdio_write_c22
* @bus: points to the mii_bus structure
* @phyaddr: MII addr
* @phyreg: MII reg
* @phydata: phy data
* Description: it writes the data into the MII register from within the device.
*/
static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
u16 phydata)
static int stmmac_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
u16 phydata)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
unsigned int mii_address = priv->hw->mii.addr;
unsigned int mii_data = priv->hw->mii.data;
int ret, data = phydata;
u32 value = MII_BUSY;
u32 v;
ret = pm_runtime_resume_and_get(priv->device);
if (ret < 0)
@ -301,38 +382,57 @@ static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
if (priv->plat->has_gmac4) {
if (priv->plat->has_gmac4)
value |= MII_GMAC4_WRITE;
if (phyreg & MII_ADDR_C45) {
value |= MII_GMAC4_C45E;
value &= ~priv->hw->mii.reg_mask;
value |= ((phyreg >> MII_DEVADDR_C45_SHIFT) <<
priv->hw->mii.reg_shift) &
priv->hw->mii.reg_mask;
data |= (phyreg & MII_REGADDR_C45_MASK) <<
MII_GMAC4_REG_ADDR_SHIFT;
}
} else {
else
value |= MII_WRITE;
ret = stmmac_mdio_write(priv, data, value);
pm_runtime_put(priv->device);
return ret;
}
/**
* stmmac_mdio_write_c45
* @bus: points to the mii_bus structure
* @phyaddr: MII addr
* @phyreg: MII reg
* @devad: device address to read
* @phydata: phy data
* Description: it writes the data into the MII register from within the device.
*/
static int stmmac_mdio_write_c45(struct mii_bus *bus, int phyaddr,
int devad, int phyreg, u16 phydata)
{
struct net_device *ndev = bus->priv;
struct stmmac_priv *priv = netdev_priv(ndev);
int ret, data = phydata;
u32 value = MII_BUSY;
ret = pm_runtime_get_sync(priv->device);
if (ret < 0) {
pm_runtime_put_noidle(priv->device);
return ret;
}
/* Wait until any existing MII operation is complete */
if (readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000)) {
ret = -EBUSY;
goto err_disable_clks;
}
value |= (phyaddr << priv->hw->mii.addr_shift)
& priv->hw->mii.addr_mask;
value |= (phyreg << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
/* Set the MII address register to write */
writel(data, priv->ioaddr + mii_data);
writel(value, priv->ioaddr + mii_address);
value |= (priv->clk_csr << priv->hw->mii.clk_csr_shift)
& priv->hw->mii.clk_csr_mask;
/* Wait until any existing MII operation is complete */
ret = readl_poll_timeout(priv->ioaddr + mii_address, v, !(v & MII_BUSY),
100, 10000);
value |= MII_GMAC4_WRITE;
value |= MII_GMAC4_C45E;
value &= ~priv->hw->mii.reg_mask;
value |= (devad << priv->hw->mii.reg_shift) & priv->hw->mii.reg_mask;
data |= phyreg << MII_GMAC4_REG_ADDR_SHIFT;
ret = stmmac_mdio_write(priv, data, value);
err_disable_clks:
pm_runtime_put(priv->device);
return ret;
@ -457,8 +557,10 @@ int stmmac_mdio_register(struct net_device *ndev)
new_bus->probe_capabilities = MDIOBUS_C22_C45;
if (priv->plat->has_xgmac) {
new_bus->read = &stmmac_xgmac2_mdio_read;
new_bus->write = &stmmac_xgmac2_mdio_write;
new_bus->read = &stmmac_xgmac2_mdio_read_c22;
new_bus->write = &stmmac_xgmac2_mdio_write_c22;
new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45;
new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45;
/* Right now only C22 phys are supported */
max_addr = MII_XGMAC_MAX_C22ADDR + 1;
@ -468,8 +570,13 @@ int stmmac_mdio_register(struct net_device *ndev)
dev_err(dev, "Unsupported phy_addr (max=%d)\n",
MII_XGMAC_MAX_C22ADDR);
} else {
new_bus->read = &stmmac_mdio_read;
new_bus->write = &stmmac_mdio_write;
new_bus->read = &stmmac_mdio_read_c22;
new_bus->write = &stmmac_mdio_write_c22;
if (priv->plat->has_gmac4) {
new_bus->read_c45 = &stmmac_mdio_read_c45;
new_bus->write_c45 = &stmmac_mdio_write_c45;
}
max_addr = PHY_MAX_ADDR;
}
@ -490,7 +597,7 @@ int stmmac_mdio_register(struct net_device *ndev)
/* Looks like we need a dummy read for XGMAC only and C45 PHYs */
if (priv->plat->has_xgmac)
stmmac_xgmac2_mdio_read(new_bus, 0, MII_ADDR_C45);
stmmac_xgmac2_mdio_read_c45(new_bus, 0, 0, 0);
/* If fixed-link is set, skip PHY scanning */
if (!fwnode)

View File

@ -104,61 +104,36 @@ static int aspeed_mdio_write_c22(struct mii_bus *bus, int addr, int regnum,
addr, regnum, val);
}
static int aspeed_mdio_read_c45(struct mii_bus *bus, int addr, int regnum)
static int aspeed_mdio_read_c45(struct mii_bus *bus, int addr, int devad,
int regnum)
{
u8 c45_dev = (regnum >> 16) & 0x1F;
u16 c45_addr = regnum & 0xFFFF;
int rc;
rc = aspeed_mdio_op(bus, ASPEED_MDIO_CTRL_ST_C45, MDIO_C45_OP_ADDR,
addr, c45_dev, c45_addr);
addr, devad, regnum);
if (rc < 0)
return rc;
rc = aspeed_mdio_op(bus, ASPEED_MDIO_CTRL_ST_C45, MDIO_C45_OP_READ,
addr, c45_dev, 0);
addr, devad, 0);
if (rc < 0)
return rc;
return aspeed_mdio_get_data(bus);
}
static int aspeed_mdio_write_c45(struct mii_bus *bus, int addr, int regnum,
u16 val)
static int aspeed_mdio_write_c45(struct mii_bus *bus, int addr, int devad,
int regnum, u16 val)
{
u8 c45_dev = (regnum >> 16) & 0x1F;
u16 c45_addr = regnum & 0xFFFF;
int rc;
rc = aspeed_mdio_op(bus, ASPEED_MDIO_CTRL_ST_C45, MDIO_C45_OP_ADDR,
addr, c45_dev, c45_addr);
addr, devad, regnum);
if (rc < 0)
return rc;
return aspeed_mdio_op(bus, ASPEED_MDIO_CTRL_ST_C45, MDIO_C45_OP_WRITE,
addr, c45_dev, val);
}
static int aspeed_mdio_read(struct mii_bus *bus, int addr, int regnum)
{
dev_dbg(&bus->dev, "%s: addr: %d, regnum: %d\n", __func__, addr,
regnum);
if (regnum & MII_ADDR_C45)
return aspeed_mdio_read_c45(bus, addr, regnum);
return aspeed_mdio_read_c22(bus, addr, regnum);
}
static int aspeed_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
{
dev_dbg(&bus->dev, "%s: addr: %d, regnum: %d, val: 0x%x\n",
__func__, addr, regnum, val);
if (regnum & MII_ADDR_C45)
return aspeed_mdio_write_c45(bus, addr, regnum, val);
return aspeed_mdio_write_c22(bus, addr, regnum, val);
addr, devad, val);
}
static int aspeed_mdio_probe(struct platform_device *pdev)
@ -185,8 +160,10 @@ static int aspeed_mdio_probe(struct platform_device *pdev)
bus->name = DRV_NAME;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);
bus->parent = &pdev->dev;
bus->read = aspeed_mdio_read;
bus->write = aspeed_mdio_write;
bus->read = aspeed_mdio_read_c22;
bus->write = aspeed_mdio_write_c22;
bus->read_c45 = aspeed_mdio_read_c45;
bus->write_c45 = aspeed_mdio_write_c45;
bus->probe_capabilities = MDIOBUS_C22_C45;
rc = of_mdiobus_register(bus, pdev->dev.of_node);

View File

@ -26,7 +26,7 @@ static void cavium_mdiobus_set_mode(struct cavium_mdiobus *p,
}
static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p,
int phy_id, int regnum)
int phy_id, int devad, int regnum)
{
union cvmx_smix_cmd smi_cmd;
union cvmx_smix_wr_dat smi_wr;
@ -38,12 +38,10 @@ static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p,
smi_wr.s.dat = regnum & 0xffff;
oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
regnum = (regnum >> 16) & 0x1f;
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_45_ADDRESS */
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
smi_cmd.s.reg_adr = devad;
oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
do {
@ -59,28 +57,17 @@ static int cavium_mdiobus_c45_addr(struct cavium_mdiobus *p,
return 0;
}
int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
int cavium_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int regnum)
{
struct cavium_mdiobus *p = bus->priv;
union cvmx_smix_cmd smi_cmd;
union cvmx_smix_rd_dat smi_rd;
unsigned int op = 1; /* MDIO_CLAUSE_22_READ */
int timeout = 1000;
if (regnum & MII_ADDR_C45) {
int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
if (r < 0)
return r;
regnum = (regnum >> 16) & 0x1f;
op = 3; /* MDIO_CLAUSE_45_READ */
} else {
cavium_mdiobus_set_mode(p, C22);
}
cavium_mdiobus_set_mode(p, C22);
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = op;
smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */;
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
@ -98,34 +85,58 @@ int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum)
else
return -EIO;
}
EXPORT_SYMBOL(cavium_mdiobus_read);
EXPORT_SYMBOL(cavium_mdiobus_read_c22);
int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)
int cavium_mdiobus_read_c45(struct mii_bus *bus, int phy_id, int devad,
int regnum)
{
struct cavium_mdiobus *p = bus->priv;
union cvmx_smix_cmd smi_cmd;
union cvmx_smix_rd_dat smi_rd;
int timeout = 1000;
int r;
r = cavium_mdiobus_c45_addr(p, phy_id, devad, regnum);
if (r < 0)
return r;
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = 3; /* MDIO_CLAUSE_45_READ */
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
do {
/* Wait 1000 clocks so we don't saturate the RSL bus
* doing reads.
*/
__delay(1000);
smi_rd.u64 = oct_mdio_readq(p->register_base + SMI_RD_DAT);
} while (smi_rd.s.pending && --timeout);
if (smi_rd.s.val)
return smi_rd.s.dat;
else
return -EIO;
}
EXPORT_SYMBOL(cavium_mdiobus_read_c45);
int cavium_mdiobus_write_c22(struct mii_bus *bus, int phy_id, int regnum,
u16 val)
{
struct cavium_mdiobus *p = bus->priv;
union cvmx_smix_cmd smi_cmd;
union cvmx_smix_wr_dat smi_wr;
unsigned int op = 0; /* MDIO_CLAUSE_22_WRITE */
int timeout = 1000;
if (regnum & MII_ADDR_C45) {
int r = cavium_mdiobus_c45_addr(p, phy_id, regnum);
if (r < 0)
return r;
regnum = (regnum >> 16) & 0x1f;
op = 1; /* MDIO_CLAUSE_45_WRITE */
} else {
cavium_mdiobus_set_mode(p, C22);
}
cavium_mdiobus_set_mode(p, C22);
smi_wr.u64 = 0;
smi_wr.s.dat = val;
oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = op;
smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */;
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = regnum;
oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
@ -143,7 +154,45 @@ int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val)
return 0;
}
EXPORT_SYMBOL(cavium_mdiobus_write);
EXPORT_SYMBOL(cavium_mdiobus_write_c22);
int cavium_mdiobus_write_c45(struct mii_bus *bus, int phy_id, int devad,
int regnum, u16 val)
{
struct cavium_mdiobus *p = bus->priv;
union cvmx_smix_cmd smi_cmd;
union cvmx_smix_wr_dat smi_wr;
int timeout = 1000;
int r;
r = cavium_mdiobus_c45_addr(p, phy_id, devad, regnum);
if (r < 0)
return r;
smi_wr.u64 = 0;
smi_wr.s.dat = val;
oct_mdio_writeq(smi_wr.u64, p->register_base + SMI_WR_DAT);
smi_cmd.u64 = 0;
smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_45_WRITE */
smi_cmd.s.phy_adr = phy_id;
smi_cmd.s.reg_adr = devad;
oct_mdio_writeq(smi_cmd.u64, p->register_base + SMI_CMD);
do {
/* Wait 1000 clocks so we don't saturate the RSL bus
* doing reads.
*/
__delay(1000);
smi_wr.u64 = oct_mdio_readq(p->register_base + SMI_WR_DAT);
} while (smi_wr.s.pending && --timeout);
if (timeout <= 0)
return -EIO;
return 0;
}
EXPORT_SYMBOL(cavium_mdiobus_write_c45);
MODULE_DESCRIPTION("Common code for OCTEON and Thunder MDIO bus drivers");
MODULE_AUTHOR("David Daney");

View File

@ -114,5 +114,10 @@ static inline u64 oct_mdio_readq(void __iomem *addr)
#define oct_mdio_readq(addr) readq(addr)
#endif
int cavium_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum);
int cavium_mdiobus_write(struct mii_bus *bus, int phy_id, int regnum, u16 val);
int cavium_mdiobus_read_c22(struct mii_bus *bus, int phy_id, int regnum);
int cavium_mdiobus_write_c22(struct mii_bus *bus, int phy_id, int regnum,
u16 val);
int cavium_mdiobus_read_c45(struct mii_bus *bus, int phy_id, int devad,
int regnum);
int cavium_mdiobus_write_c45(struct mii_bus *bus, int phy_id, int devad,
int regnum, u16 val);

View File

@ -30,7 +30,8 @@ static unsigned int i2c_mii_phy_addr(int phy_id)
return phy_id + 0x40;
}
static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
static int i2c_mii_read_default_c45(struct mii_bus *bus, int phy_id, int devad,
int reg)
{
struct i2c_adapter *i2c = bus->priv;
struct i2c_msg msgs[2];
@ -41,8 +42,8 @@ static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
return 0xffff;
p = addr;
if (reg & MII_ADDR_C45) {
*p++ = 0x20 | ((reg >> 16) & 31);
if (devad >= 0) {
*p++ = 0x20 | devad;
*p++ = reg >> 8;
}
*p++ = reg;
@ -64,8 +65,8 @@ static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
return data[0] << 8 | data[1];
}
static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
u16 val)
static int i2c_mii_write_default_c45(struct mii_bus *bus, int phy_id,
int devad, int reg, u16 val)
{
struct i2c_adapter *i2c = bus->priv;
struct i2c_msg msg;
@ -76,8 +77,8 @@ static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
return 0;
p = data;
if (reg & MII_ADDR_C45) {
*p++ = (reg >> 16) & 31;
if (devad >= 0) {
*p++ = devad;
*p++ = reg >> 8;
}
*p++ = reg;
@ -94,6 +95,17 @@ static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
return ret < 0 ? ret : 0;
}
static int i2c_mii_read_default_c22(struct mii_bus *bus, int phy_id, int reg)
{
return i2c_mii_read_default_c45(bus, phy_id, -1, reg);
}
static int i2c_mii_write_default_c22(struct mii_bus *bus, int phy_id, int reg,
u16 val)
{
return i2c_mii_write_default_c45(bus, phy_id, -1, reg, val);
}
/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
* instead via address 0x51, when SFP page is set to 0x03 and password to
* 0xffffffff.
@ -403,8 +415,10 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
mii->write = i2c_mii_write_rollball;
break;
default:
mii->read = i2c_mii_read_default;
mii->write = i2c_mii_write_default;
mii->read = i2c_mii_read_default_c22;
mii->write = i2c_mii_write_default_c22;
mii->read_c45 = i2c_mii_read_default_c45;
mii->write_c45 = i2c_mii_write_default_c45;
break;
}

View File

@ -53,7 +53,8 @@ static int ipq4019_mdio_wait_busy(struct mii_bus *bus)
IPQ4019_MDIO_SLEEP, IPQ4019_MDIO_TIMEOUT);
}
static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
static int ipq4019_mdio_read_c45(struct mii_bus *bus, int mii_id, int mmd,
int reg)
{
struct ipq4019_mdio_data *priv = bus->priv;
unsigned int data;
@ -62,38 +63,19 @@ static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
/* Clause 45 support */
if (regnum & MII_ADDR_C45) {
unsigned int mmd = (regnum >> 16) & 0x1F;
unsigned int reg = regnum & 0xFFFF;
data = readl(priv->membase + MDIO_MODE_REG);
/* Enter Clause 45 mode */
data = readl(priv->membase + MDIO_MODE_REG);
data |= MDIO_MODE_C45;
data |= MDIO_MODE_C45;
writel(data, priv->membase + MDIO_MODE_REG);
writel(data, priv->membase + MDIO_MODE_REG);
/* issue the phy address and mmd */
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
/* issue the phy address and mmd */
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
/* issue reg */
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
/* issue reg */
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
} else {
/* Enter Clause 22 mode */
data = readl(priv->membase + MDIO_MODE_REG);
data &= ~MDIO_MODE_C45;
writel(data, priv->membase + MDIO_MODE_REG);
/* issue the phy address and reg */
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ;
}
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
/* issue read command */
writel(cmd, priv->membase + MDIO_CMD_REG);
@ -102,21 +84,18 @@ static int ipq4019_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
if (regnum & MII_ADDR_C45) {
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_READ;
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_READ;
writel(cmd, priv->membase + MDIO_CMD_REG);
writel(cmd, priv->membase + MDIO_CMD_REG);
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
}
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
/* Read and return data */
return readl(priv->membase + MDIO_DATA_READ_REG);
}
static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
u16 value)
static int ipq4019_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
{
struct ipq4019_mdio_data *priv = bus->priv;
unsigned int data;
@ -125,50 +104,95 @@ static int ipq4019_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
/* Clause 45 support */
if (regnum & MII_ADDR_C45) {
unsigned int mmd = (regnum >> 16) & 0x1F;
unsigned int reg = regnum & 0xFFFF;
data = readl(priv->membase + MDIO_MODE_REG);
/* Enter Clause 45 mode */
data = readl(priv->membase + MDIO_MODE_REG);
data &= ~MDIO_MODE_C45;
data |= MDIO_MODE_C45;
writel(data, priv->membase + MDIO_MODE_REG);
writel(data, priv->membase + MDIO_MODE_REG);
/* issue the phy address and reg */
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
/* issue the phy address and mmd */
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_READ;
/* issue reg */
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
/* issue read command */
writel(cmd, priv->membase + MDIO_CMD_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
/* Wait read complete */
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
writel(cmd, priv->membase + MDIO_CMD_REG);
/* Read and return data */
return readl(priv->membase + MDIO_DATA_READ_REG);
}
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
} else {
/* Enter Clause 22 mode */
data = readl(priv->membase + MDIO_MODE_REG);
static int ipq4019_mdio_write_c45(struct mii_bus *bus, int mii_id, int mmd,
int reg, u16 value)
{
struct ipq4019_mdio_data *priv = bus->priv;
unsigned int data;
unsigned int cmd;
data &= ~MDIO_MODE_C45;
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
writel(data, priv->membase + MDIO_MODE_REG);
data = readl(priv->membase + MDIO_MODE_REG);
/* issue the phy address and reg */
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
}
data |= MDIO_MODE_C45;
writel(data, priv->membase + MDIO_MODE_REG);
/* issue the phy address and mmd */
writel((mii_id << 8) | mmd, priv->membase + MDIO_ADDR_REG);
/* issue reg */
writel(reg, priv->membase + MDIO_DATA_WRITE_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_ADDR;
writel(cmd, priv->membase + MDIO_CMD_REG);
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
/* issue write data */
writel(value, priv->membase + MDIO_DATA_WRITE_REG);
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_WRITE;
writel(cmd, priv->membase + MDIO_CMD_REG);
/* Wait write complete */
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
return 0;
}
static int ipq4019_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
u16 value)
{
struct ipq4019_mdio_data *priv = bus->priv;
unsigned int data;
unsigned int cmd;
if (ipq4019_mdio_wait_busy(bus))
return -ETIMEDOUT;
/* Enter Clause 22 mode */
data = readl(priv->membase + MDIO_MODE_REG);
data &= ~MDIO_MODE_C45;
writel(data, priv->membase + MDIO_MODE_REG);
/* issue the phy address and reg */
writel((mii_id << 8) | regnum, priv->membase + MDIO_ADDR_REG);
/* issue write data */
writel(value, priv->membase + MDIO_DATA_WRITE_REG);
/* issue write command */
if (regnum & MII_ADDR_C45)
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_C45_WRITE;
else
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE;
cmd = MDIO_CMD_ACCESS_START | MDIO_CMD_ACCESS_CODE_WRITE;
writel(cmd, priv->membase + MDIO_CMD_REG);
@ -235,8 +259,10 @@ static int ipq4019_mdio_probe(struct platform_device *pdev)
priv->eth_ldo_rdy = devm_ioremap_resource(&pdev->dev, res);
bus->name = "ipq4019_mdio";
bus->read = ipq4019_mdio_read;
bus->write = ipq4019_mdio_write;
bus->read = ipq4019_mdio_read_c22;
bus->write = ipq4019_mdio_write_c22;
bus->read_c45 = ipq4019_mdio_read_c45;
bus->write_c45 = ipq4019_mdio_write_c45;
bus->reset = ipq_mdio_reset;
bus->parent = &pdev->dev;
snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);

View File

@ -98,7 +98,7 @@ static int iproc_mdio_wait_for_idle(void __iomem *base, bool result)
* Return value: Successful Read operation returns read reg values and write
* operation returns 0. Failure operation returns negative error code.
*/
static int start_miim_ops(void __iomem *base,
static int start_miim_ops(void __iomem *base, bool c45,
u16 phyid, u32 reg, u16 val, u32 op)
{
u32 param;
@ -112,7 +112,7 @@ static int start_miim_ops(void __iomem *base,
param = readl(base + MDIO_PARAM_OFFSET);
param |= phyid << MDIO_PARAM_PHY_ID;
param |= val << MDIO_PARAM_PHY_DATA;
if (reg & MII_ADDR_C45)
if (c45)
param |= BIT(MDIO_PARAM_C45_SEL);
writel(param, base + MDIO_PARAM_OFFSET);
@ -131,28 +131,58 @@ err:
return ret;
}
static int iproc_mdiomux_read(struct mii_bus *bus, int phyid, int reg)
static int iproc_mdiomux_read_c22(struct mii_bus *bus, int phyid, int reg)
{
struct iproc_mdiomux_desc *md = bus->priv;
int ret;
ret = start_miim_ops(md->base, phyid, reg, 0, MDIO_CTRL_READ_OP);
ret = start_miim_ops(md->base, false, phyid, reg, 0, MDIO_CTRL_READ_OP);
if (ret < 0)
dev_err(&bus->dev, "mdiomux read operation failed!!!");
dev_err(&bus->dev, "mdiomux c22 read operation failed!!!");
return ret;
}
static int iproc_mdiomux_write(struct mii_bus *bus,
int phyid, int reg, u16 val)
static int iproc_mdiomux_read_c45(struct mii_bus *bus, int phyid, int devad,
int reg)
{
struct iproc_mdiomux_desc *md = bus->priv;
int ret;
ret = start_miim_ops(md->base, true, phyid, reg | devad << 16, 0,
MDIO_CTRL_READ_OP);
if (ret < 0)
dev_err(&bus->dev, "mdiomux read c45 operation failed!!!");
return ret;
}
static int iproc_mdiomux_write_c22(struct mii_bus *bus,
int phyid, int reg, u16 val)
{
struct iproc_mdiomux_desc *md = bus->priv;
int ret;
/* Write val at reg offset */
ret = start_miim_ops(md->base, phyid, reg, val, MDIO_CTRL_WRITE_OP);
ret = start_miim_ops(md->base, false, phyid, reg, val,
MDIO_CTRL_WRITE_OP);
if (ret < 0)
dev_err(&bus->dev, "mdiomux write operation failed!!!");
dev_err(&bus->dev, "mdiomux write c22 operation failed!!!");
return ret;
}
static int iproc_mdiomux_write_c45(struct mii_bus *bus,
int phyid, int devad, int reg, u16 val)
{
struct iproc_mdiomux_desc *md = bus->priv;
int ret;
/* Write val at reg offset */
ret = start_miim_ops(md->base, true, phyid, reg | devad << 16, val,
MDIO_CTRL_WRITE_OP);
if (ret < 0)
dev_err(&bus->dev, "mdiomux write c45 operation failed!!!");
return ret;
}
@ -223,8 +253,10 @@ static int mdio_mux_iproc_probe(struct platform_device *pdev)
bus->name = "iProc MDIO mux bus";
snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id);
bus->parent = &pdev->dev;
bus->read = iproc_mdiomux_read;
bus->write = iproc_mdiomux_write;
bus->read = iproc_mdiomux_read_c22;
bus->write = iproc_mdiomux_write_c22;
bus->read_c45 = iproc_mdiomux_read_c45;
bus->write_c45 = iproc_mdiomux_write_c45;
bus->phy_mask = ~0;
bus->dev.of_node = pdev->dev.of_node;

View File

@ -58,8 +58,10 @@ static int octeon_mdiobus_probe(struct platform_device *pdev)
snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%px", bus->register_base);
bus->mii_bus->parent = &pdev->dev;
bus->mii_bus->read = cavium_mdiobus_read;
bus->mii_bus->write = cavium_mdiobus_write;
bus->mii_bus->read = cavium_mdiobus_read_c22;
bus->mii_bus->write = cavium_mdiobus_write_c22;
bus->mii_bus->read_c45 = cavium_mdiobus_read_c45;
bus->mii_bus->write_c45 = cavium_mdiobus_write_c45;
platform_set_drvdata(pdev, bus);

View File

@ -93,8 +93,10 @@ static int thunder_mdiobus_pci_probe(struct pci_dev *pdev,
bus->mii_bus->name = KBUILD_MODNAME;
snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", r.start);
bus->mii_bus->parent = &pdev->dev;
bus->mii_bus->read = cavium_mdiobus_read;
bus->mii_bus->write = cavium_mdiobus_write;
bus->mii_bus->read = cavium_mdiobus_read_c22;
bus->mii_bus->write = cavium_mdiobus_write_c22;
bus->mii_bus->read_c45 = cavium_mdiobus_read_c45;
bus->mii_bus->write_c45 = cavium_mdiobus_write_c45;
err = of_mdiobus_register(bus->mii_bus, node);
if (err)

View File

@ -37,16 +37,27 @@ struct enetc_mdio_priv {
#if IS_REACHABLE(CONFIG_FSL_ENETC_MDIO)
int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum);
int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum, u16 value);
int enetc_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum);
int enetc_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum,
u16 value);
int enetc_mdio_read_c45(struct mii_bus *bus, int phy_id, int devad, int regnum);
int enetc_mdio_write_c45(struct mii_bus *bus, int phy_id, int devad, int regnum,
u16 value);
struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs);
#else
static inline int enetc_mdio_read(struct mii_bus *bus, int phy_id, int regnum)
static inline int enetc_mdio_read_c22(struct mii_bus *bus, int phy_id,
int regnum)
{ return -EINVAL; }
static inline int enetc_mdio_write(struct mii_bus *bus, int phy_id, int regnum,
u16 value)
static inline int enetc_mdio_write_c22(struct mii_bus *bus, int phy_id,
int regnum, u16 value)
{ return -EINVAL; }
static inline int enetc_mdio_read_c45(struct mii_bus *bus, int phy_id,
int devad, int regnum)
{ return -EINVAL; }
static inline int enetc_mdio_write_c45(struct mii_bus *bus, int phy_id,
int devad, int regnum, u16 value)
{ return -EINVAL; }
struct enetc_hw *enetc_hw_alloc(struct device *dev, void __iomem *port_regs)
{ return ERR_PTR(-EINVAL); }