Commit f213bbe8 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Integrate it with DesignWare XPCS



Adds all the necessary logic so that stmmac can be used with Synopsys
DesignWare XPCS.

Signed-off-by: default avatarJose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fcb26bd2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@ config STMMAC_ETH
	tristate "STMicroelectronics Multi-Gigabit Ethernet driver"
	depends on HAS_IOMEM && HAS_DMA
	select MII
	select MDIO_XPCS
	select PAGE_POOL
	select PHYLINK
	select CRC32
+3 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/netdevice.h>
#include <linux/stmmac.h>
#include <linux/phy.h>
#include <linux/mdio-xpcs.h>
#include <linux/module.h>
#if IS_ENABLED(CONFIG_VLAN_8021Q)
#define STMMAC_VLAN_TAG_USED
@@ -446,6 +447,8 @@ 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 mii_regs mii;	/* MII register Addresses */
	struct mac_link link;
	void __iomem *pcsr;     /* vpointer to device CSRs */
+12 −0
Original line number Diff line number Diff line
@@ -577,6 +577,18 @@ 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)

struct stmmac_regs_off {
	u32 ptp_off;
	u32 mmc_off;
+14 −2
Original line number Diff line number Diff line
@@ -863,18 +863,26 @@ static void stmmac_validate(struct phylink_config *config,

	linkmode_and(state->advertising, state->advertising, mac_supported);
	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);
}

static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
			      const struct phylink_link_state *state)
{
	/* Nothing for now. */
	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)
@@ -902,6 +910,8 @@ 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;

@@ -1042,6 +1052,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;

	if (!fwnode)
		fwnode = dev_fwnode(priv->device);
@@ -2689,7 +2700,8 @@ static int stmmac_open(struct net_device *dev)
	int ret;

	if (priv->hw->pcs != STMMAC_PCS_TBI &&
	    priv->hw->pcs != STMMAC_PCS_RTBI) {
	    priv->hw->pcs != STMMAC_PCS_RTBI &&
	    priv->hw->xpcs == NULL) {
		ret = stmmac_init_phy(dev);
		if (ret) {
			netdev_err(priv->dev,
+27 −0
Original line number Diff line number Diff line
@@ -382,6 +382,14 @@ 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;

@@ -433,6 +441,25 @@ int stmmac_mdio_register(struct net_device *ndev)
		found = 1;
	}

	/* 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;

		xpcs->bus = new_bus;

		for (addr = 0; addr < max_addr; addr++) {
			xpcs->addr = addr;

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

	if (!found && !mdio_node) {
		dev_warn(dev, "No PHY found\n");
		mdiobus_unregister(new_bus);
Loading