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

net: sxgbe: Separate C22 and C45 transactions

The sxgdb MDIO bus driver can perform both C22 and C45 transfers.
Create separate functions for each and register the C45 versions using
the new API calls where appropriate.
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 defa2e54
......@@ -50,12 +50,12 @@ static void sxgbe_mdio_ctrl_data(struct sxgbe_priv_data *sp, u32 cmd,
}
static void sxgbe_mdio_c45(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
int phyreg, u16 phydata)
int devad, int phyreg, u16 phydata)
{
u32 reg;
/* set mdio address register */
reg = ((phyreg >> 16) & 0x1f) << 21;
reg = (devad & 0x1f) << 21;
reg |= (phyaddr << 16) | (phyreg & 0xffff);
writel(reg, sp->ioaddr + sp->hw->mii.addr);
......@@ -76,8 +76,8 @@ static void sxgbe_mdio_c22(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
sxgbe_mdio_ctrl_data(sp, cmd, phydata);
}
static int sxgbe_mdio_access(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
int phyreg, u16 phydata)
static int sxgbe_mdio_access_c22(struct sxgbe_priv_data *sp, u32 cmd,
int phyaddr, int phyreg, u16 phydata)
{
const struct mii_regs *mii = &sp->hw->mii;
int rc;
......@@ -86,33 +86,46 @@ static int sxgbe_mdio_access(struct sxgbe_priv_data *sp, u32 cmd, int phyaddr,
if (rc < 0)
return rc;
if (phyreg & MII_ADDR_C45) {
sxgbe_mdio_c45(sp, cmd, phyaddr, phyreg, phydata);
} else {
/* Ports 0-3 only support C22. */
if (phyaddr >= 4)
return -ENODEV;
/* Ports 0-3 only support C22. */
if (phyaddr >= 4)
return -ENODEV;
sxgbe_mdio_c22(sp, cmd, phyaddr, phyreg, phydata);
}
sxgbe_mdio_c22(sp, cmd, phyaddr, phyreg, phydata);
return sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
}
static int sxgbe_mdio_access_c45(struct sxgbe_priv_data *sp, u32 cmd,
int phyaddr, int devad, int phyreg,
u16 phydata)
{
const struct mii_regs *mii = &sp->hw->mii;
int rc;
rc = sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
if (rc < 0)
return rc;
sxgbe_mdio_c45(sp, cmd, phyaddr, devad, phyreg, phydata);
return sxgbe_mdio_busy_wait(sp->ioaddr, mii->data);
}
/**
* sxgbe_mdio_read
* sxgbe_mdio_read_c22
* @bus: points to the mii_bus structure
* @phyaddr: address of phy port
* @phyreg: address of register with in phy register
* Description: this function used for C45 and C22 MDIO Read
* Description: this function used for C22 MDIO Read
*/
static int sxgbe_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
static int sxgbe_mdio_read_c22(struct mii_bus *bus, int phyaddr, int phyreg)
{
struct net_device *ndev = bus->priv;
struct sxgbe_priv_data *priv = netdev_priv(ndev);
int rc;
rc = sxgbe_mdio_access(priv, SXGBE_SMA_READ_CMD, phyaddr, phyreg, 0);
rc = sxgbe_mdio_access_c22(priv, SXGBE_SMA_READ_CMD, phyaddr,
phyreg, 0);
if (rc < 0)
return rc;
......@@ -120,21 +133,63 @@ static int sxgbe_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
}
/**
* sxgbe_mdio_write
* sxgbe_mdio_read_c45
* @bus: points to the mii_bus structure
* @phyaddr: address of phy port
* @devad: device (MMD) address
* @phyreg: address of register with in phy register
* Description: this function used for C45 MDIO Read
*/
static int sxgbe_mdio_read_c45(struct mii_bus *bus, int phyaddr, int devad,
int phyreg)
{
struct net_device *ndev = bus->priv;
struct sxgbe_priv_data *priv = netdev_priv(ndev);
int rc;
rc = sxgbe_mdio_access_c45(priv, SXGBE_SMA_READ_CMD, phyaddr,
devad, phyreg, 0);
if (rc < 0)
return rc;
return readl(priv->ioaddr + priv->hw->mii.data) & 0xffff;
}
/**
* sxgbe_mdio_write_c22
* @bus: points to the mii_bus structure
* @phyaddr: address of phy port
* @phyreg: address of phy registers
* @phydata: data to be written into phy register
* Description: this function is used for C22 MDIO write
*/
static int sxgbe_mdio_write_c22(struct mii_bus *bus, int phyaddr, int phyreg,
u16 phydata)
{
struct net_device *ndev = bus->priv;
struct sxgbe_priv_data *priv = netdev_priv(ndev);
return sxgbe_mdio_access_c22(priv, SXGBE_SMA_WRITE_CMD, phyaddr, phyreg,
phydata);
}
/**
* sxgbe_mdio_write_c45
* @bus: points to the mii_bus structure
* @phyaddr: address of phy port
* @phyreg: address of phy registers
* @devad: device (MMD) address
* @phydata: data to be written into phy register
* Description: this function is used for C45 and C22 MDIO write
* Description: this function is used for C45 MDIO write
*/
static int sxgbe_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
u16 phydata)
static int sxgbe_mdio_write_c45(struct mii_bus *bus, int phyaddr, int devad,
int phyreg, u16 phydata)
{
struct net_device *ndev = bus->priv;
struct sxgbe_priv_data *priv = netdev_priv(ndev);
return sxgbe_mdio_access(priv, SXGBE_SMA_WRITE_CMD, phyaddr, phyreg,
phydata);
return sxgbe_mdio_access_c45(priv, SXGBE_SMA_WRITE_CMD, phyaddr,
devad, phyreg, phydata);
}
int sxgbe_mdio_register(struct net_device *ndev)
......@@ -161,8 +216,10 @@ int sxgbe_mdio_register(struct net_device *ndev)
/* assign mii bus fields */
mdio_bus->name = "sxgbe";
mdio_bus->read = &sxgbe_mdio_read;
mdio_bus->write = &sxgbe_mdio_write;
mdio_bus->read = sxgbe_mdio_read_c22;
mdio_bus->write = sxgbe_mdio_write_c22;
mdio_bus->read_c45 = sxgbe_mdio_read_c45;
mdio_bus->write_c45 = sxgbe_mdio_write_c45;
snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x",
mdio_bus->name, priv->plat->bus_id);
mdio_bus->priv = ndev;
......
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