Commit bea4b309 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'enetc-Migrate-to-PHYLINK-and-PCS_LYNX'



Claudiu Manoil says:

====================
enetc: Migrate to PHYLINK and PCS_LYNX

Transitioning the enetc driver from phylib to phylink.
Offloading the serdes configuration to the PCS_LYNX
module is a mandatory part of this transition. Aiming
for a cleaner, more maintainable design, and better
code reuse.
The first 2 patches are clean up prerequisites.

Tested on a p1028rdb board.

v2: validate() explicitly rejects now all interface modes not
supported by the driver instead of relying on the device tree
to provide only supported interfaces, and dropped redundant
activation of pcs_poll (addressing Ioana's findings)
====================

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents df41c19a 71b77a7a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -199,6 +199,7 @@
&enetc_port0 {
	phy-handle = <&sgmii_phy0>;
	phy-connection-type = "sgmii";
	managed = "in-band-status";
	status = "okay";

	mdio {
+3 −2
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@ config FSL_ENETC
	tristate "ENETC PF driver"
	depends on PCI && PCI_MSI
	select FSL_ENETC_MDIO
	select PHYLIB
	select PHYLINK
	select PCS_LYNX
	select DIMLIB
	help
	  This driver supports NXP ENETC gigabit ethernet controller PCIe
@@ -15,7 +16,7 @@ config FSL_ENETC
config FSL_ENETC_VF
	tristate "ENETC VF driver"
	depends on PCI && PCI_MSI
	select PHYLIB
	select PHYLINK
	select DIMLIB
	help
	  This driver supports NXP ENETC gigabit ethernet controller PCIe
+20 −33
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@
#include "enetc.h"
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/of_mdio.h>
#include <linux/vmalloc.h>

/* ENETC overhead: optional extension BD + 1 BD gap */
@@ -1392,38 +1391,24 @@ static void enetc_clear_interrupts(struct enetc_ndev_priv *priv)
		enetc_rxbdr_wr(&priv->si->hw, i, ENETC_RBIER, 0);
}

static void adjust_link(struct net_device *ndev)
static int enetc_phylink_connect(struct net_device *ndev)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev = ndev->phydev;

	if (priv->active_offloads & ENETC_F_QBV)
		enetc_sched_speed_set(ndev);

	phy_print_status(phydev);
}

static int enetc_phy_connect(struct net_device *ndev)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
	struct phy_device *phydev;
	struct ethtool_eee edata;
	int err;

	if (!priv->phy_node)
	if (!priv->phylink)
		return 0; /* phy-less mode */

	phydev = of_phy_connect(ndev, priv->phy_node, &adjust_link,
				0, priv->if_mode);
	if (!phydev) {
	err = phylink_of_phy_connect(priv->phylink, priv->dev->of_node, 0);
	if (err) {
		dev_err(&ndev->dev, "could not attach to PHY\n");
		return -ENODEV;
		return err;
	}

	phy_attached_info(phydev);

	/* disable EEE autoneg, until ENETC driver supports it */
	memset(&edata, 0, sizeof(struct ethtool_eee));
	phy_ethtool_set_eee(phydev, &edata);
	phylink_ethtool_set_eee(priv->phylink, &edata);

	return 0;
}
@@ -1443,8 +1428,8 @@ void enetc_start(struct net_device *ndev)
		enable_irq(irq);
	}

	if (ndev->phydev)
		phy_start(ndev->phydev);
	if (priv->phylink)
		phylink_start(priv->phylink);
	else
		netif_carrier_on(ndev);

@@ -1460,7 +1445,7 @@ int enetc_open(struct net_device *ndev)
	if (err)
		return err;

	err = enetc_phy_connect(ndev);
	err = enetc_phylink_connect(ndev);
	if (err)
		goto err_phy_connect;

@@ -1490,8 +1475,8 @@ err_set_queues:
err_alloc_rx:
	enetc_free_tx_resources(priv);
err_alloc_tx:
	if (ndev->phydev)
		phy_disconnect(ndev->phydev);
	if (priv->phylink)
		phylink_disconnect_phy(priv->phylink);
err_phy_connect:
	enetc_free_irqs(priv);

@@ -1514,8 +1499,8 @@ void enetc_stop(struct net_device *ndev)
		napi_disable(&priv->int_vector[i]->napi);
	}

	if (ndev->phydev)
		phy_stop(ndev->phydev);
	if (priv->phylink)
		phylink_stop(priv->phylink);
	else
		netif_carrier_off(ndev);

@@ -1529,8 +1514,8 @@ int enetc_close(struct net_device *ndev)
	enetc_stop(ndev);
	enetc_clear_bdrs(priv);

	if (ndev->phydev)
		phy_disconnect(ndev->phydev);
	if (priv->phylink)
		phylink_disconnect_phy(priv->phylink);
	enetc_free_rxtx_rings(priv);
	enetc_free_rx_resources(priv);
	enetc_free_tx_resources(priv);
@@ -1780,6 +1765,7 @@ static int enetc_hwtstamp_get(struct net_device *ndev, struct ifreq *ifr)

int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
{
	struct enetc_ndev_priv *priv = netdev_priv(ndev);
#ifdef CONFIG_FSL_ENETC_PTP_CLOCK
	if (cmd == SIOCSHWTSTAMP)
		return enetc_hwtstamp_set(ndev, rq);
@@ -1787,9 +1773,10 @@ int enetc_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
		return enetc_hwtstamp_get(ndev, rq);
#endif

	if (!ndev->phydev)
	if (!priv->phylink)
		return -EOPNOTSUPP;
	return phy_mii_ioctl(ndev->phydev, rq, cmd);

	return phylink_mii_ioctl(priv->phylink, rq, cmd);
}

int enetc_alloc_msix(struct enetc_ndev_priv *priv)
+4 −5
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/phy.h>
#include <linux/phylink.h>
#include <linux/dim.h>

#include "enetc_hw.h"
@@ -264,8 +264,7 @@ struct enetc_ndev_priv {

	struct psfp_cap psfp_cap;

	struct device_node *phy_node;
	phy_interface_t if_mode;
	struct phylink *phylink;
	int ic_mode;
	u32 tx_ictt;
};
@@ -323,7 +322,7 @@ int enetc_send_cmd(struct enetc_si *si, struct enetc_cbd *cbd);

#ifdef CONFIG_FSL_ENETC_QOS
int enetc_setup_tc_taprio(struct net_device *ndev, void *type_data);
void enetc_sched_speed_set(struct net_device *ndev);
void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed);
int enetc_setup_tc_cbs(struct net_device *ndev, void *type_data);
int enetc_setup_tc_txtime(struct net_device *ndev, void *type_data);
int enetc_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
@@ -388,7 +387,7 @@ static inline int enetc_psfp_disable(struct enetc_ndev_priv *priv)

#else
#define enetc_setup_tc_taprio(ndev, type_data) -EOPNOTSUPP
#define enetc_sched_speed_set(ndev) (void)0
#define enetc_sched_speed_set(priv, speed) (void)0
#define enetc_setup_tc_cbs(ndev, type_data) -EOPNOTSUPP
#define enetc_setup_tc_txtime(ndev, type_data) -EOPNOTSUPP
#define enetc_setup_tc_psfp(ndev, type_data) -EOPNOTSUPP
+24 −2
Original line number Diff line number Diff line
@@ -686,6 +686,28 @@ static int enetc_set_wol(struct net_device *dev,
	return ret;
}

static int enetc_get_link_ksettings(struct net_device *dev,
				    struct ethtool_link_ksettings *cmd)
{
	struct enetc_ndev_priv *priv = netdev_priv(dev);

	if (!priv->phylink)
		return -EOPNOTSUPP;

	return phylink_ethtool_ksettings_get(priv->phylink, cmd);
}

static int enetc_set_link_ksettings(struct net_device *dev,
				    const struct ethtool_link_ksettings *cmd)
{
	struct enetc_ndev_priv *priv = netdev_priv(dev);

	if (!priv->phylink)
		return -EOPNOTSUPP;

	return phylink_ethtool_ksettings_set(priv->phylink, cmd);
}

static const struct ethtool_ops enetc_pf_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
				     ETHTOOL_COALESCE_MAX_FRAMES |
@@ -704,8 +726,8 @@ static const struct ethtool_ops enetc_pf_ethtool_ops = {
	.get_ringparam = enetc_get_ringparam,
	.get_coalesce = enetc_get_coalesce,
	.set_coalesce = enetc_set_coalesce,
	.get_link_ksettings = phy_ethtool_get_link_ksettings,
	.set_link_ksettings = phy_ethtool_set_link_ksettings,
	.get_link_ksettings = enetc_get_link_ksettings,
	.set_link_ksettings = enetc_set_link_ksettings,
	.get_link = ethtool_op_get_link,
	.get_ts_info = enetc_get_ts_info,
	.get_wol = enetc_get_wol,
Loading