Commit 5d93cfcf authored by Sean Anderson's avatar Sean Anderson Committed by David S. Miller
Browse files

net: dpaa: Convert to phylink



This converts DPAA to phylink. All macs are converted. This should work
with no device tree modifications (including those made in this series),
except for QSGMII (as noted previously).

The mEMAC configuration is one of the tricker areas. I have tried to
capture all the restrictions across the various models. Most of the time,
we assume that if the serdes supports a mode or the phy-interface-mode
specifies it, then we support it. The only place we can't do this is
(RG)MII, since there's no serdes. In that case, we rely on a (new)
devicetree property. There are also several cases where half-duplex is
broken. Unfortunately, only a single compatible is used for the MAC, so we
have to use the board compatible instead.

The 10GEC conversion is very straightforward, since it only supports XAUI.
There is generally nothing to configure.

The dTSEC conversion is broadly similar to mEMAC, but is simpler because we
don't support configuring the SerDes (though this can be easily added) and
we don't have multiple PCSs. From what I can tell, there's nothing
different in the driver or documentation between SGMII and 1000BASE-X
except for the advertising. Similarly, I couldn't find anything about
2500BASE-X. In both cases, I treat them like SGMII. These modes aren't used
by any in-tree boards. Similarly, despite being mentioned in the driver, I
couldn't find any documented SoCs which supported QSGMII.  I have left it
unimplemented for now.

Signed-off-by: default avatarSean Anderson <sean.anderson@seco.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a7c2a32e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -2,8 +2,8 @@
menuconfig FSL_DPAA_ETH
	tristate "DPAA Ethernet"
	depends on FSL_DPAA && FSL_FMAN
	select PHYLIB
	select FIXED_PHY
	select PHYLINK
	select PCS_LYNX
	help
	  Data Path Acceleration Architecture Ethernet driver,
	  supporting the Freescale QorIQ chips.
+26 −63
Original line number Diff line number Diff line
@@ -264,8 +264,19 @@ static int dpaa_netdev_init(struct net_device *net_dev,
	net_dev->needed_headroom = priv->tx_headroom;
	net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);

	mac_dev->net_dev = net_dev;
	/* The rest of the config is filled in by the mac device already */
	mac_dev->phylink_config.dev = &net_dev->dev;
	mac_dev->phylink_config.type = PHYLINK_NETDEV;
	mac_dev->update_speed = dpaa_eth_cgr_set_speed;
	mac_dev->phylink = phylink_create(&mac_dev->phylink_config,
					  dev_fwnode(mac_dev->dev),
					  mac_dev->phy_if,
					  mac_dev->phylink_ops);
	if (IS_ERR(mac_dev->phylink)) {
		err = PTR_ERR(mac_dev->phylink);
		dev_err_probe(dev, err, "Could not create phylink\n");
		return err;
	}

	/* start without the RUNNING flag, phylib controls it later */
	netif_carrier_off(net_dev);
@@ -273,6 +284,7 @@ static int dpaa_netdev_init(struct net_device *net_dev,
	err = register_netdev(net_dev);
	if (err < 0) {
		dev_err(dev, "register_netdev() = %d\n", err);
		phylink_destroy(mac_dev->phylink);
		return err;
	}

@@ -294,8 +306,7 @@ static int dpaa_stop(struct net_device *net_dev)
	 */
	msleep(200);

	if (mac_dev->phy_dev)
		phy_stop(mac_dev->phy_dev);
	phylink_stop(mac_dev->phylink);
	mac_dev->disable(mac_dev->fman_mac);

	for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
@@ -304,8 +315,7 @@ static int dpaa_stop(struct net_device *net_dev)
			err = error;
	}

	if (net_dev->phydev)
		phy_disconnect(net_dev->phydev);
	phylink_disconnect_phy(mac_dev->phylink);
	net_dev->phydev = NULL;

	msleep(200);
@@ -833,10 +843,10 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)

	/* Set different thresholds based on the configured MAC speed.
	 * This may turn suboptimal if the MAC is reconfigured at another
	 * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
	 * speed, so MACs must call dpaa_eth_cgr_set_speed in their link_up
	 * callback.
	 */
	if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
	if (priv->mac_dev->phylink_config.mac_capabilities & MAC_10000FD)
		cs_th = DPAA_CS_THRESHOLD_10G;
	else
		cs_th = DPAA_CS_THRESHOLD_1G;
@@ -865,7 +875,7 @@ static int dpaa_eth_cgr_init(struct dpaa_priv *priv)

static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
{
	struct net_device *net_dev = mac_dev->net_dev;
	struct net_device *net_dev = to_net_dev(mac_dev->phylink_config.dev);
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct qm_mcc_initcgr opts = { };
	u32 cs_th;
@@ -2904,58 +2914,6 @@ static void dpaa_eth_napi_disable(struct dpaa_priv *priv)
	}
}

static void dpaa_adjust_link(struct net_device *net_dev)
{
	struct mac_device *mac_dev;
	struct dpaa_priv *priv;

	priv = netdev_priv(net_dev);
	mac_dev = priv->mac_dev;
	mac_dev->adjust_link(mac_dev);
}

/* The Aquantia PHYs are capable of performing rate adaptation */
#define PHY_VEND_AQUANTIA	0x03a1b400
#define PHY_VEND_AQUANTIA2	0x31c31c00

static int dpaa_phy_init(struct net_device *net_dev)
{
	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
	struct mac_device *mac_dev;
	struct phy_device *phy_dev;
	struct dpaa_priv *priv;
	u32 phy_vendor;

	priv = netdev_priv(net_dev);
	mac_dev = priv->mac_dev;

	phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
				 &dpaa_adjust_link, 0,
				 mac_dev->phy_if);
	if (!phy_dev) {
		netif_err(priv, ifup, net_dev, "init_phy() failed\n");
		return -ENODEV;
	}

	phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10);
	/* Unless the PHY is capable of rate adaptation */
	if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
	    (phy_vendor != PHY_VEND_AQUANTIA &&
	     phy_vendor != PHY_VEND_AQUANTIA2)) {
		/* remove any features not supported by the controller */
		ethtool_convert_legacy_u32_to_link_mode(mask,
							mac_dev->if_support);
		linkmode_and(phy_dev->supported, phy_dev->supported, mask);
	}

	phy_support_asym_pause(phy_dev);

	mac_dev->phy_dev = phy_dev;
	net_dev->phydev = phy_dev;

	return 0;
}

static int dpaa_open(struct net_device *net_dev)
{
	struct mac_device *mac_dev;
@@ -2966,7 +2924,8 @@ static int dpaa_open(struct net_device *net_dev)
	mac_dev = priv->mac_dev;
	dpaa_eth_napi_enable(priv);

	err = dpaa_phy_init(net_dev);
	err = phylink_of_phy_connect(mac_dev->phylink,
				     mac_dev->dev->of_node, 0);
	if (err)
		goto phy_init_failed;

@@ -2981,7 +2940,7 @@ static int dpaa_open(struct net_device *net_dev)
		netif_err(priv, ifup, net_dev, "mac_dev->enable() = %d\n", err);
		goto mac_start_failed;
	}
	phy_start(priv->mac_dev->phy_dev);
	phylink_start(mac_dev->phylink);

	netif_tx_start_all_queues(net_dev);

@@ -2990,6 +2949,7 @@ static int dpaa_open(struct net_device *net_dev)
mac_start_failed:
	for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
		fman_port_disable(mac_dev->port[i]);
	phylink_disconnect_phy(mac_dev->phylink);

phy_init_failed:
	dpaa_eth_napi_disable(priv);
@@ -3145,10 +3105,12 @@ static int dpaa_ts_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
{
	int ret = -EINVAL;
	struct dpaa_priv *priv = netdev_priv(net_dev);

	if (cmd == SIOCGMIIREG) {
		if (net_dev->phydev)
			return phy_mii_ioctl(net_dev->phydev, rq, cmd);
			return phylink_mii_ioctl(priv->mac_dev->phylink, rq,
						 cmd);
	}

	if (cmd == SIOCSHWTSTAMP)
@@ -3551,6 +3513,7 @@ static int dpaa_remove(struct platform_device *pdev)

	dev_set_drvdata(dev, NULL);
	unregister_netdev(net_dev);
	phylink_destroy(priv->mac_dev->phylink);

	err = dpaa_fq_free(dev, &priv->dpaa_fq_list);

+15 −75
Original line number Diff line number Diff line
@@ -54,27 +54,19 @@ static char dpaa_stats_global[][ETH_GSTRING_LEN] = {
static int dpaa_get_link_ksettings(struct net_device *net_dev,
				   struct ethtool_link_ksettings *cmd)
{
	if (!net_dev->phydev)
		return 0;

	phy_ethtool_ksettings_get(net_dev->phydev, cmd);
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct mac_device *mac_dev = priv->mac_dev;

	return 0;
	return phylink_ethtool_ksettings_get(mac_dev->phylink, cmd);
}

static int dpaa_set_link_ksettings(struct net_device *net_dev,
				   const struct ethtool_link_ksettings *cmd)
{
	int err;

	if (!net_dev->phydev)
		return -ENODEV;
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct mac_device *mac_dev = priv->mac_dev;

	err = phy_ethtool_ksettings_set(net_dev->phydev, cmd);
	if (err < 0)
		netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", err);

	return err;
	return phylink_ethtool_ksettings_set(mac_dev->phylink, cmd);
}

static void dpaa_get_drvinfo(struct net_device *net_dev,
@@ -99,80 +91,28 @@ static void dpaa_set_msglevel(struct net_device *net_dev,

static int dpaa_nway_reset(struct net_device *net_dev)
{
	int err;

	if (!net_dev->phydev)
		return -ENODEV;

	err = 0;
	if (net_dev->phydev->autoneg) {
		err = phy_start_aneg(net_dev->phydev);
		if (err < 0)
			netdev_err(net_dev, "phy_start_aneg() = %d\n",
				   err);
	}
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct mac_device *mac_dev = priv->mac_dev;

	return err;
	return phylink_ethtool_nway_reset(mac_dev->phylink);
}

static void dpaa_get_pauseparam(struct net_device *net_dev,
				struct ethtool_pauseparam *epause)
{
	struct mac_device *mac_dev;
	struct dpaa_priv *priv;
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct mac_device *mac_dev = priv->mac_dev;

	priv = netdev_priv(net_dev);
	mac_dev = priv->mac_dev;

	if (!net_dev->phydev)
		return;

	epause->autoneg = mac_dev->autoneg_pause;
	epause->rx_pause = mac_dev->rx_pause_active;
	epause->tx_pause = mac_dev->tx_pause_active;
	phylink_ethtool_get_pauseparam(mac_dev->phylink, epause);
}

static int dpaa_set_pauseparam(struct net_device *net_dev,
			       struct ethtool_pauseparam *epause)
{
	struct mac_device *mac_dev;
	struct phy_device *phydev;
	bool rx_pause, tx_pause;
	struct dpaa_priv *priv;
	int err;

	priv = netdev_priv(net_dev);
	mac_dev = priv->mac_dev;

	phydev = net_dev->phydev;
	if (!phydev) {
		netdev_err(net_dev, "phy device not initialized\n");
		return -ENODEV;
	}

	if (!phy_validate_pause(phydev, epause))
		return -EINVAL;

	/* The MAC should know how to handle PAUSE frame autonegotiation before
	 * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
	 * settings.
	 */
	mac_dev->autoneg_pause = !!epause->autoneg;
	mac_dev->rx_pause_req = !!epause->rx_pause;
	mac_dev->tx_pause_req = !!epause->tx_pause;

	/* Determine the sym/asym advertised PAUSE capabilities from the desired
	 * rx/tx pause settings.
	 */

	phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause);

	fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
	err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
	if (err < 0)
		netdev_err(net_dev, "set_mac_active_pause() = %d\n", err);
	struct dpaa_priv *priv = netdev_priv(net_dev);
	struct mac_device *mac_dev = priv->mac_dev;

	return err;
	return phylink_ethtool_set_pauseparam(mac_dev->phylink, epause);
}

static int dpaa_get_sset_count(struct net_device *net_dev, int type)
+0 −1
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@ config FSL_FMAN
	tristate "FMan support"
	depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
	select GENERIC_ALLOCATOR
	select PHYLIB
	select PHYLINK
	select PCS
	select PCS_LYNX
+212 −246

File changed.

Preview size limit exceeded, changes collapsed.

Loading