Commit c356be05 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'xpcs-phylink_pcs_ops'



Vladimir Oltean says:

====================
Convert xpcs to phylink_pcs_ops

Background: the sja1105 DSA driver currently drives a Designware XPCS
for SGMII and 2500base-X, and it would be nice to reuse some code with
the xpcs module. This would also help consolidate the phylink_pcs_ops,
since the only other dedicated PCS driver, currently, is the lynx_pcs.

Therefore, this series makes the xpcs expose the same kind of API that
the lynx_pcs module does. The main changes are getting rid of struct
mdio_xpcs_ops, being compatible with struct phylink_pcs_ops and being
less reliant on the phy_interface_t passed to xpcs_probe (now renamed to
xpcs_create).

This patch series is partially tested (some code paths have been covered
on the NXP SJA1105 and some others with the help of Vee Khee Wong on
Intel Tiger Lake / stmmac) but further testing on 10G setups would be
appreciated, if possible.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b596ce68 11059740
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -503,8 +503,7 @@ struct mac_device_info {
	const struct stmmac_hwtimestamp *ptp;
	const struct stmmac_tc_ops *tc;
	const struct stmmac_mmc_ops *mmc;
	const struct mdio_xpcs_ops *xpcs;
	struct mdio_xpcs_args xpcs_args;
	struct mdio_xpcs_args *xpcs;
	struct mii_regs mii;	/* MII register Addresses */
	struct mac_link link;
	void __iomem *pcsr;     /* vpointer to device CSRs */
+0 −14
Original line number Diff line number Diff line
@@ -613,20 +613,6 @@ struct stmmac_mmc_ops {
#define stmmac_mmc_read(__priv, __args...) \
	stmmac_do_void_callback(__priv, mmc, read, __args)

/* XPCS callbacks */
#define stmmac_xpcs_validate(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, validate, __args)
#define stmmac_xpcs_config(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, config, __args)
#define stmmac_xpcs_get_state(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, get_state, __args)
#define stmmac_xpcs_link_up(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, link_up, __args)
#define stmmac_xpcs_probe(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, probe, __args)
#define stmmac_xpcs_config_eee(__priv, __args...) \
	stmmac_do_callback(__priv, xpcs, config_eee, __args)

struct stmmac_regs_off {
	u32 ptp_off;
	u32 mmc_off;
+7 −5
Original line number Diff line number Diff line
@@ -720,11 +720,13 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
		netdev_warn(priv->dev,
			    "Setting EEE tx-lpi is not supported\n");

	ret = stmmac_xpcs_config_eee(priv, &priv->hw->xpcs_args,
	if (priv->hw->xpcs) {
		ret = xpcs_config_eee(priv->hw->xpcs,
				      priv->plat->mult_fact_100ns,
				      edata->eee_enabled);
		if (ret)
			return ret;
	}

	if (!edata->eee_enabled)
		stmmac_disable_eee_mode(priv);
+14 −25
Original line number Diff line number Diff line
@@ -996,29 +996,14 @@ static void stmmac_validate(struct phylink_config *config,
	linkmode_andnot(state->advertising, state->advertising, mask);

	/* If PCS is supported, check which modes it supports. */
	stmmac_xpcs_validate(priv, &priv->hw->xpcs_args, supported, state);
}

static void stmmac_mac_pcs_get_state(struct phylink_config *config,
				     struct phylink_link_state *state)
{
	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));

	state->link = 0;
	stmmac_xpcs_get_state(priv, &priv->hw->xpcs_args, state);
	if (priv->hw->xpcs)
		xpcs_validate(priv->hw->xpcs, supported, state);
}

static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
			      const struct phylink_link_state *state)
{
	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));

	stmmac_xpcs_config(priv, &priv->hw->xpcs_args, state);
}

static void stmmac_mac_an_restart(struct phylink_config *config)
{
	/* Not Supported */
	/* Nothing to do, xpcs_config() handles everything */
}

static void stmmac_fpe_link_state_handle(struct stmmac_priv *priv, bool is_up)
@@ -1060,8 +1045,6 @@ static void stmmac_mac_link_up(struct phylink_config *config,
	struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
	u32 ctrl;

	stmmac_xpcs_link_up(priv, &priv->hw->xpcs_args, speed, interface);

	ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
	ctrl &= ~priv->hw->link.speed_mask;

@@ -1154,9 +1137,7 @@ static void stmmac_mac_link_up(struct phylink_config *config,

static const struct phylink_mac_ops stmmac_phylink_mac_ops = {
	.validate = stmmac_validate,
	.mac_pcs_get_state = stmmac_mac_pcs_get_state,
	.mac_config = stmmac_mac_config,
	.mac_an_restart = stmmac_mac_an_restart,
	.mac_link_down = stmmac_mac_link_down,
	.mac_link_up = stmmac_mac_link_up,
};
@@ -1233,6 +1214,7 @@ static int stmmac_init_phy(struct net_device *dev)

static int stmmac_phy_setup(struct stmmac_priv *priv)
{
	struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
	struct fwnode_handle *fwnode = of_fwnode_handle(priv->plat->phylink_node);
	int mode = priv->plat->phy_interface;
	struct phylink *phylink;
@@ -1240,8 +1222,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
	priv->phylink_config.dev = &priv->dev->dev;
	priv->phylink_config.type = PHYLINK_NETDEV;
	priv->phylink_config.pcs_poll = true;
	priv->phylink_config.ovr_an_inband =
		priv->plat->mdio_bus_data->xpcs_an_inband;
	priv->phylink_config.ovr_an_inband = mdio_bus_data->xpcs_an_inband;

	if (!fwnode)
		fwnode = dev_fwnode(priv->device);
@@ -1251,6 +1232,12 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
	if (IS_ERR(phylink))
		return PTR_ERR(phylink);

	if (mdio_bus_data->has_xpcs) {
		struct mdio_xpcs_args *xpcs = priv->hw->xpcs;

		phylink_set_pcs(phylink, &xpcs->pcs);
	}

	priv->phylink = phylink;
	return 0;
}
@@ -3638,6 +3625,7 @@ static int stmmac_request_irq(struct net_device *dev)
int stmmac_open(struct net_device *dev)
{
	struct stmmac_priv *priv = netdev_priv(dev);
	int mode = priv->plat->phy_interface;
	int bfsize = 0;
	u32 chan;
	int ret;
@@ -3650,7 +3638,8 @@ int stmmac_open(struct net_device *dev)

	if (priv->hw->pcs != STMMAC_PCS_TBI &&
	    priv->hw->pcs != STMMAC_PCS_RTBI &&
	    priv->hw->xpcs_args.an_mode != DW_AN_C73) {
	    (!priv->hw->xpcs ||
	     xpcs_get_an_mode(priv->hw->xpcs, mode) != DW_AN_C73)) {
		ret = stmmac_init_phy(dev);
		if (ret) {
			netdev_err(priv->dev,
+23 −24
Original line number Diff line number Diff line
@@ -444,14 +444,6 @@ int stmmac_mdio_register(struct net_device *ndev)
		max_addr = PHY_MAX_ADDR;
	}

	if (mdio_bus_data->has_xpcs) {
		priv->hw->xpcs = mdio_xpcs_get_ops();
		if (!priv->hw->xpcs) {
			err = -ENODEV;
			goto bus_register_fail;
		}
	}

	if (mdio_bus_data->needs_reset)
		new_bus->reset = &stmmac_mdio_reset;

@@ -510,25 +502,27 @@ int stmmac_mdio_register(struct net_device *ndev)
	}

	/* Try to probe the XPCS by scanning all addresses. */
	if (priv->hw->xpcs) {
		struct mdio_xpcs_args *xpcs = &priv->hw->xpcs_args;
		int ret, mode = priv->plat->phy_interface;
		max_addr = PHY_MAX_ADDR;
	if (mdio_bus_data->has_xpcs) {
		int mode = priv->plat->phy_interface;
		struct mdio_device *mdiodev;
		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;
		for (addr = 0; addr < max_addr; addr++) {
			xpcs->addr = addr;
			xpcs = xpcs_create(mdiodev, mode);
			if (IS_ERR_OR_NULL(xpcs)) {
				mdio_device_free(mdiodev);
				continue;
			}

			ret = stmmac_xpcs_probe(priv, xpcs, mode);
			if (!ret) {
				found = 1;
			priv->hw->xpcs = xpcs;
			break;
		}
		}

		if (!found && !mdio_node) {
		if (!priv->hw->xpcs) {
			dev_warn(dev, "No XPCS found\n");
			err = -ENODEV;
			goto no_xpcs_found;
@@ -560,6 +554,11 @@ int stmmac_mdio_unregister(struct net_device *ndev)
	if (!priv->mii)
		return 0;

	if (priv->hw->xpcs) {
		mdio_device_free(priv->hw->xpcs->mdiodev);
		xpcs_destroy(priv->hw->xpcs);
	}

	mdiobus_unregister(priv->mii);
	priv->mii->priv = NULL;
	mdiobus_free(priv->mii);
Loading