Commit 2cac15da authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: pcs: xpcs: convert to mdio_device

Unify the 2 existing PCS drivers (lynx and xpcs) by doing a similar
thing on probe, which is to have a *_create function that takes a
struct mdio_device * given by the caller, and builds a private PCS
structure around that.

This changes stmmac to hold only a pointer to the xpcs, as opposed to
the full structure. This will be used in the next patch when struct
mdio_xpcs_ops is removed. Currently a pointer to struct mdio_xpcs_ops
is used as a shorthand to determine whether the port has an XPCS or not.
We can do the same now with the mdio_xpcs_args pointer.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 679e283e
...@@ -504,7 +504,7 @@ struct mac_device_info { ...@@ -504,7 +504,7 @@ struct mac_device_info {
const struct stmmac_tc_ops *tc; const struct stmmac_tc_ops *tc;
const struct stmmac_mmc_ops *mmc; const struct stmmac_mmc_ops *mmc;
const struct mdio_xpcs_ops *xpcs; const struct mdio_xpcs_ops *xpcs;
struct mdio_xpcs_args xpcs_args; struct mdio_xpcs_args *xpcs_args;
struct mii_regs mii; /* MII register Addresses */ struct mii_regs mii; /* MII register Addresses */
struct mac_link link; struct mac_link link;
void __iomem *pcsr; /* vpointer to device CSRs */ void __iomem *pcsr; /* vpointer to device CSRs */
......
...@@ -721,7 +721,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev, ...@@ -721,7 +721,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
"Setting EEE tx-lpi is not supported\n"); "Setting EEE tx-lpi is not supported\n");
if (priv->hw->xpcs) { if (priv->hw->xpcs) {
ret = xpcs_config_eee(&priv->hw->xpcs_args, ret = xpcs_config_eee(priv->hw->xpcs_args,
priv->plat->mult_fact_100ns, priv->plat->mult_fact_100ns,
edata->eee_enabled); edata->eee_enabled);
if (ret) if (ret)
......
...@@ -997,7 +997,7 @@ static void stmmac_validate(struct phylink_config *config, ...@@ -997,7 +997,7 @@ static void stmmac_validate(struct phylink_config *config,
/* If PCS is supported, check which modes it supports. */ /* If PCS is supported, check which modes it supports. */
if (priv->hw->xpcs) if (priv->hw->xpcs)
xpcs_validate(&priv->hw->xpcs_args, supported, state); xpcs_validate(priv->hw->xpcs_args, supported, state);
} }
static void stmmac_mac_pcs_get_state(struct phylink_config *config, static void stmmac_mac_pcs_get_state(struct phylink_config *config,
...@@ -1006,7 +1006,7 @@ static void stmmac_mac_pcs_get_state(struct phylink_config *config, ...@@ -1006,7 +1006,7 @@ static void stmmac_mac_pcs_get_state(struct phylink_config *config,
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
state->link = 0; state->link = 0;
stmmac_xpcs_get_state(priv, &priv->hw->xpcs_args, state); stmmac_xpcs_get_state(priv, priv->hw->xpcs_args, state);
} }
static void stmmac_mac_config(struct phylink_config *config, unsigned int mode, static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
...@@ -1014,7 +1014,7 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode, ...@@ -1014,7 +1014,7 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
{ {
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
stmmac_xpcs_config(priv, &priv->hw->xpcs_args, state); stmmac_xpcs_config(priv, priv->hw->xpcs_args, state);
} }
static void stmmac_mac_an_restart(struct phylink_config *config) static void stmmac_mac_an_restart(struct phylink_config *config)
...@@ -1061,7 +1061,7 @@ static void stmmac_mac_link_up(struct phylink_config *config, ...@@ -1061,7 +1061,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
u32 ctrl; u32 ctrl;
stmmac_xpcs_link_up(priv, &priv->hw->xpcs_args, speed, interface); stmmac_xpcs_link_up(priv, priv->hw->xpcs_args, speed, interface);
ctrl = readl(priv->ioaddr + MAC_CTRL_REG); ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
ctrl &= ~priv->hw->link.speed_mask; ctrl &= ~priv->hw->link.speed_mask;
...@@ -3653,7 +3653,7 @@ int stmmac_open(struct net_device *dev) ...@@ -3653,7 +3653,7 @@ int stmmac_open(struct net_device *dev)
if (priv->hw->pcs != STMMAC_PCS_TBI && if (priv->hw->pcs != STMMAC_PCS_TBI &&
priv->hw->pcs != STMMAC_PCS_RTBI && priv->hw->pcs != STMMAC_PCS_RTBI &&
(!priv->hw->xpcs || (!priv->hw->xpcs ||
xpcs_get_an_mode(&priv->hw->xpcs_args, mode) != DW_AN_C73)) { xpcs_get_an_mode(priv->hw->xpcs_args, mode) != DW_AN_C73)) {
ret = stmmac_init_phy(dev); ret = stmmac_init_phy(dev);
if (ret) { if (ret) {
netdev_err(priv->dev, netdev_err(priv->dev,
......
...@@ -510,25 +510,27 @@ int stmmac_mdio_register(struct net_device *ndev) ...@@ -510,25 +510,27 @@ int stmmac_mdio_register(struct net_device *ndev)
} }
/* Try to probe the XPCS by scanning all addresses. */ /* Try to probe the XPCS by scanning all addresses. */
if (priv->hw->xpcs) { if (mdio_bus_data->has_xpcs) {
struct mdio_xpcs_args *xpcs = &priv->hw->xpcs_args; int mode = priv->plat->phy_interface;
int ret, mode = priv->plat->phy_interface; struct mdio_device *mdiodev;
max_addr = PHY_MAX_ADDR; struct mdio_xpcs_args *xpcs;
xpcs->bus = new_bus; for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
mdiodev = mdio_device_create(new_bus, addr);
if (IS_ERR(mdiodev))
continue;
found = 0; xpcs = xpcs_create(mdiodev, mode);
for (addr = 0; addr < max_addr; addr++) { if (IS_ERR_OR_NULL(xpcs)) {
xpcs->addr = addr; mdio_device_free(mdiodev);
continue;
}
ret = xpcs_probe(xpcs, mode); priv->hw->xpcs_args = xpcs;
if (!ret) {
found = 1;
break; break;
} }
}
if (!found && !mdio_node) { if (!priv->hw->xpcs_args) {
dev_warn(dev, "No XPCS found\n"); dev_warn(dev, "No XPCS found\n");
err = -ENODEV; err = -ENODEV;
goto no_xpcs_found; goto no_xpcs_found;
...@@ -560,6 +562,11 @@ int stmmac_mdio_unregister(struct net_device *ndev) ...@@ -560,6 +562,11 @@ int stmmac_mdio_unregister(struct net_device *ndev)
if (!priv->mii) if (!priv->mii)
return 0; return 0;
if (priv->hw->xpcs) {
mdio_device_free(priv->hw->xpcs_args->mdiodev);
xpcs_destroy(priv->hw->xpcs_args);
}
mdiobus_unregister(priv->mii); mdiobus_unregister(priv->mii);
priv->mii->priv = NULL; priv->mii->priv = NULL;
mdiobus_free(priv->mii); mdiobus_free(priv->mii);
......
...@@ -241,15 +241,19 @@ static bool __xpcs_linkmode_supported(const struct xpcs_compat *compat, ...@@ -241,15 +241,19 @@ static bool __xpcs_linkmode_supported(const struct xpcs_compat *compat,
static int xpcs_read(struct mdio_xpcs_args *xpcs, int dev, u32 reg) static int xpcs_read(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
{ {
u32 reg_addr = mdiobus_c45_addr(dev, reg); u32 reg_addr = mdiobus_c45_addr(dev, reg);
struct mii_bus *bus = xpcs->mdiodev->bus;
int addr = xpcs->mdiodev->addr;
return mdiobus_read(xpcs->bus, xpcs->addr, reg_addr); return mdiobus_read(bus, addr, reg_addr);
} }
static int xpcs_write(struct mdio_xpcs_args *xpcs, int dev, u32 reg, u16 val) static int xpcs_write(struct mdio_xpcs_args *xpcs, int dev, u32 reg, u16 val)
{ {
u32 reg_addr = mdiobus_c45_addr(dev, reg); u32 reg_addr = mdiobus_c45_addr(dev, reg);
struct mii_bus *bus = xpcs->mdiodev->bus;
int addr = xpcs->mdiodev->addr;
return mdiobus_write(xpcs->bus, xpcs->addr, reg_addr, val); return mdiobus_write(bus, addr, reg_addr, val);
} }
static int xpcs_read_vendor(struct mdio_xpcs_args *xpcs, int dev, u32 reg) static int xpcs_read_vendor(struct mdio_xpcs_args *xpcs, int dev, u32 reg)
...@@ -315,7 +319,7 @@ static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs, ...@@ -315,7 +319,7 @@ static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs,
#define xpcs_warn(__xpcs, __state, __args...) \ #define xpcs_warn(__xpcs, __state, __args...) \
({ \ ({ \
if ((__state)->link) \ if ((__state)->link) \
dev_warn(&(__xpcs)->bus->dev, ##__args); \ dev_warn(&(__xpcs)->mdiodev->dev, ##__args); \
}) })
static int xpcs_read_fault_c73(struct mdio_xpcs_args *xpcs, static int xpcs_read_fault_c73(struct mdio_xpcs_args *xpcs,
...@@ -1005,10 +1009,20 @@ static const struct xpcs_id xpcs_id_list[] = { ...@@ -1005,10 +1009,20 @@ static const struct xpcs_id xpcs_id_list[] = {
}, },
}; };
int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface) struct mdio_xpcs_args *xpcs_create(struct mdio_device *mdiodev,
phy_interface_t interface)
{ {
u32 xpcs_id = xpcs_get_id(xpcs); struct mdio_xpcs_args *xpcs;
int i; u32 xpcs_id;
int i, ret;
xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL);
if (!xpcs)
return NULL;
xpcs->mdiodev = mdiodev;
xpcs_id = xpcs_get_id(xpcs);
for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) { for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
const struct xpcs_id *entry = &xpcs_id_list[i]; const struct xpcs_id *entry = &xpcs_id_list[i];
...@@ -1020,15 +1034,32 @@ int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface) ...@@ -1020,15 +1034,32 @@ int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface)
xpcs->id = entry; xpcs->id = entry;
compat = xpcs_find_compat(entry, interface); compat = xpcs_find_compat(entry, interface);
if (!compat) if (!compat) {
return -ENODEV; ret = -ENODEV;
goto out;
}
return xpcs_soft_reset(xpcs, compat); ret = xpcs_soft_reset(xpcs, compat);
if (ret)
goto out;
return xpcs;
} }
return -ENODEV; ret = -ENODEV;
out:
kfree(xpcs);
return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(xpcs_create);
void xpcs_destroy(struct mdio_xpcs_args *xpcs)
{
kfree(xpcs);
} }
EXPORT_SYMBOL_GPL(xpcs_probe); EXPORT_SYMBOL_GPL(xpcs_destroy);
static struct mdio_xpcs_ops xpcs_ops = { static struct mdio_xpcs_ops xpcs_ops = {
.config = xpcs_config, .config = xpcs_config,
......
...@@ -17,9 +17,8 @@ ...@@ -17,9 +17,8 @@
struct xpcs_id; struct xpcs_id;
struct mdio_xpcs_args { struct mdio_xpcs_args {
struct mii_bus *bus; struct mdio_device *mdiodev;
const struct xpcs_id *id; const struct xpcs_id *id;
int addr;
}; };
struct mdio_xpcs_ops { struct mdio_xpcs_ops {
...@@ -37,6 +36,8 @@ void xpcs_validate(struct mdio_xpcs_args *xpcs, unsigned long *supported, ...@@ -37,6 +36,8 @@ void xpcs_validate(struct mdio_xpcs_args *xpcs, unsigned long *supported,
struct phylink_link_state *state); struct phylink_link_state *state);
int xpcs_config_eee(struct mdio_xpcs_args *xpcs, int mult_fact_100ns, int xpcs_config_eee(struct mdio_xpcs_args *xpcs, int mult_fact_100ns,
int enable); int enable);
int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface); struct mdio_xpcs_args *xpcs_create(struct mdio_device *mdiodev,
phy_interface_t interface);
void xpcs_destroy(struct mdio_xpcs_args *xpcs);
#endif /* __LINUX_PCS_XPCS_H */ #endif /* __LINUX_PCS_XPCS_H */
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