Commit bea4b309 authored by Jakub Kicinski's avatar Jakub Kicinski

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
......@@ -199,6 +199,7 @@ qsgmii_phy3: ethernet-phy@13 {
&enetc_port0 {
phy-handle = <&sgmii_phy0>;
phy-connection-type = "sgmii";
managed = "in-band-status";
status = "okay";
mdio {
......
......@@ -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
......
......@@ -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 @@ int enetc_open(struct net_device *ndev)
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)
......
......@@ -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
......
......@@ -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,
......
......@@ -2,6 +2,7 @@
/* Copyright 2017-2019 NXP */
#include "enetc.h"
#include <linux/pcs-lynx.h>
#define ENETC_PF_NUM_RINGS 8
......@@ -45,12 +46,15 @@ struct enetc_pf {
struct mii_bus *mdio; /* saved for cleanup */
struct mii_bus *imdio;
struct phy_device *pcs;
struct lynx_pcs *pcs;
struct device_node *phy_node;
phy_interface_t if_mode;
struct phylink_config phylink_config;
};
#define phylink_to_enetc_pf(config) \
container_of((config), struct enetc_pf, phylink_config)
int enetc_msg_psi_init(struct enetc_pf *pf);
void enetc_msg_psi_free(struct enetc_pf *pf);
void enetc_msg_handle_rxmsg(struct enetc_pf *pf, int mbox_id, u16 *status);
......@@ -15,17 +15,14 @@ static u16 enetc_get_max_gcl_len(struct enetc_hw *hw)
& ENETC_QBV_MAX_GCL_LEN_MASK;
}
void enetc_sched_speed_set(struct net_device *ndev)
void enetc_sched_speed_set(struct enetc_ndev_priv *priv, int speed)
{
struct enetc_ndev_priv *priv = netdev_priv(ndev);
struct phy_device *phydev = ndev->phydev;
u32 old_speed = priv->speed;
u32 speed, pspeed;
u32 pspeed;
if (phydev->speed == old_speed)
if (speed == old_speed)
return;
speed = phydev->speed;
switch (speed) {
case SPEED_1000:
pspeed = ENETC_PMR_PSPEED_1000M;
......
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