Commit 425b0fad authored by David S. Miller's avatar David S. Miller

Merge branch 'net-stmmac-Convert-to-phylink'

Jose Abreu says:

====================
net: stmmac: Convert to phylink

This converts stmmac to use phylink. Besides the code redution this will
allow to gain more flexibility.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5948d117 74371272
...@@ -3,7 +3,7 @@ config STMMAC_ETH ...@@ -3,7 +3,7 @@ config STMMAC_ETH
tristate "STMicroelectronics 10/100/1000/EQOS Ethernet driver" tristate "STMicroelectronics 10/100/1000/EQOS Ethernet driver"
depends on HAS_IOMEM && HAS_DMA depends on HAS_IOMEM && HAS_DMA
select MII select MII
select PHYLIB select PHYLINK
select CRC32 select CRC32
imply PTP_1588_CLOCK imply PTP_1588_CLOCK
select RESET_CONTROLLER select RESET_CONTROLLER
...@@ -41,7 +41,6 @@ if STMMAC_PLATFORM ...@@ -41,7 +41,6 @@ if STMMAC_PLATFORM
config DWMAC_DWC_QOS_ETH config DWMAC_DWC_QOS_ETH
tristate "Support for snps,dwc-qos-ethernet.txt DT binding." tristate "Support for snps,dwc-qos-ethernet.txt DT binding."
select PHYLIB
select CRC32 select CRC32
select MII select MII
depends on OF && HAS_DMA depends on OF && HAS_DMA
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/stmmac.h> #include <linux/stmmac.h>
#include <linux/phy.h> #include <linux/phylink.h>
#include <linux/pci.h> #include <linux/pci.h>
#include "common.h" #include "common.h"
#include <linux/ptp_clock_kernel.h> #include <linux/ptp_clock_kernel.h>
...@@ -147,14 +147,15 @@ struct stmmac_priv { ...@@ -147,14 +147,15 @@ struct stmmac_priv {
/* Generic channel for NAPI */ /* Generic channel for NAPI */
struct stmmac_channel channel[STMMAC_CH_MAX]; struct stmmac_channel channel[STMMAC_CH_MAX];
bool oldlink;
int speed; int speed;
int oldduplex;
unsigned int flow_ctrl; unsigned int flow_ctrl;
unsigned int pause; unsigned int pause;
struct mii_bus *mii; struct mii_bus *mii;
int mii_irq[PHY_MAX_ADDR]; int mii_irq[PHY_MAX_ADDR];
struct phylink_config phylink_config;
struct phylink *phylink;
struct stmmac_extra_stats xstats ____cacheline_aligned_in_smp; struct stmmac_extra_stats xstats ____cacheline_aligned_in_smp;
struct stmmac_safety_stats sstats; struct stmmac_safety_stats sstats;
struct plat_stmmacenet_data *plat; struct plat_stmmacenet_data *plat;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/phy.h> #include <linux/phylink.h>
#include <linux/net_tstamp.h> #include <linux/net_tstamp.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -274,7 +274,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, ...@@ -274,7 +274,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd) struct ethtool_link_ksettings *cmd)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phy = dev->phydev;
if (priv->hw->pcs & STMMAC_PCS_RGMII || if (priv->hw->pcs & STMMAC_PCS_RGMII ||
priv->hw->pcs & STMMAC_PCS_SGMII) { priv->hw->pcs & STMMAC_PCS_SGMII) {
...@@ -353,18 +352,7 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, ...@@ -353,18 +352,7 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
return 0; return 0;
} }
if (phy == NULL) { return phylink_ethtool_ksettings_get(priv->phylink, cmd);
pr_err("%s: %s: PHY is not registered\n",
__func__, dev->name);
return -ENODEV;
}
if (!netif_running(dev)) {
pr_err("%s: interface is disabled: we cannot track "
"link speed / duplex setting\n", dev->name);
return -EBUSY;
}
phy_ethtool_ksettings_get(phy, cmd);
return 0;
} }
static int static int
...@@ -372,8 +360,6 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, ...@@ -372,8 +360,6 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd) const struct ethtool_link_ksettings *cmd)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
struct phy_device *phy = dev->phydev;
int rc;
if (priv->hw->pcs & STMMAC_PCS_RGMII || if (priv->hw->pcs & STMMAC_PCS_RGMII ||
priv->hw->pcs & STMMAC_PCS_SGMII) { priv->hw->pcs & STMMAC_PCS_SGMII) {
...@@ -397,9 +383,7 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, ...@@ -397,9 +383,7 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
return 0; return 0;
} }
rc = phy_ethtool_ksettings_set(phy, cmd); return phylink_ethtool_ksettings_set(priv->phylink, cmd);
return rc;
} }
static u32 stmmac_ethtool_getmsglevel(struct net_device *dev) static u32 stmmac_ethtool_getmsglevel(struct net_device *dev)
...@@ -443,6 +427,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev, ...@@ -443,6 +427,13 @@ static void stmmac_ethtool_gregs(struct net_device *dev,
NUM_DWMAC1000_DMA_REGS * 4); NUM_DWMAC1000_DMA_REGS * 4);
} }
static int stmmac_nway_reset(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
return phylink_ethtool_nway_reset(priv->phylink);
}
static void static void
stmmac_get_pauseparam(struct net_device *netdev, stmmac_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
...@@ -450,28 +441,13 @@ stmmac_get_pauseparam(struct net_device *netdev, ...@@ -450,28 +441,13 @@ stmmac_get_pauseparam(struct net_device *netdev,
struct stmmac_priv *priv = netdev_priv(netdev); struct stmmac_priv *priv = netdev_priv(netdev);
struct rgmii_adv adv_lp; struct rgmii_adv adv_lp;
pause->rx_pause = 0;
pause->tx_pause = 0;
if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) { if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
pause->autoneg = 1; pause->autoneg = 1;
if (!adv_lp.pause) if (!adv_lp.pause)
return; return;
} else { } else {
if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phylink_ethtool_get_pauseparam(priv->phylink, pause);
netdev->phydev->supported) ||
!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
netdev->phydev->supported))
return;
} }
pause->autoneg = netdev->phydev->autoneg;
if (priv->flow_ctrl & FLOW_RX)
pause->rx_pause = 1;
if (priv->flow_ctrl & FLOW_TX)
pause->tx_pause = 1;
} }
static int static int
...@@ -479,39 +455,16 @@ stmmac_set_pauseparam(struct net_device *netdev, ...@@ -479,39 +455,16 @@ stmmac_set_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause) struct ethtool_pauseparam *pause)
{ {
struct stmmac_priv *priv = netdev_priv(netdev); struct stmmac_priv *priv = netdev_priv(netdev);
u32 tx_cnt = priv->plat->tx_queues_to_use;
struct phy_device *phy = netdev->phydev;
int new_pause = FLOW_OFF;
struct rgmii_adv adv_lp; struct rgmii_adv adv_lp;
if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) { if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) {
pause->autoneg = 1; pause->autoneg = 1;
if (!adv_lp.pause) if (!adv_lp.pause)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return 0;
} else { } else {
if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, return phylink_ethtool_set_pauseparam(priv->phylink, pause);
phy->supported) ||
!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
phy->supported))
return -EOPNOTSUPP;
} }
if (pause->rx_pause)
new_pause |= FLOW_RX;
if (pause->tx_pause)
new_pause |= FLOW_TX;
priv->flow_ctrl = new_pause;
phy->autoneg = pause->autoneg;
if (phy->autoneg) {
if (netif_running(netdev))
return phy_start_aneg(phy);
}
stmmac_flow_ctrl(priv, priv->hw, phy->duplex, priv->flow_ctrl,
priv->pause, tx_cnt);
return 0;
} }
static void stmmac_get_ethtool_stats(struct net_device *dev, static void stmmac_get_ethtool_stats(struct net_device *dev,
...@@ -549,7 +502,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev, ...@@ -549,7 +502,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
} }
} }
if (priv->eee_enabled) { if (priv->eee_enabled) {
int val = phy_get_eee_err(dev->phydev); int val = phylink_get_eee_err(priv->phylink);
if (val) if (val)
priv->xstats.phy_eee_wakeup_error_n = val; priv->xstats.phy_eee_wakeup_error_n = val;
} }
...@@ -694,7 +647,7 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev, ...@@ -694,7 +647,7 @@ static int stmmac_ethtool_op_get_eee(struct net_device *dev,
edata->eee_active = priv->eee_active; edata->eee_active = priv->eee_active;
edata->tx_lpi_timer = priv->tx_lpi_timer; edata->tx_lpi_timer = priv->tx_lpi_timer;
return phy_ethtool_get_eee(dev->phydev, edata); return phylink_ethtool_get_eee(priv->phylink, edata);
} }
static int stmmac_ethtool_op_set_eee(struct net_device *dev, static int stmmac_ethtool_op_set_eee(struct net_device *dev,
...@@ -715,7 +668,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev, ...@@ -715,7 +668,7 @@ static int stmmac_ethtool_op_set_eee(struct net_device *dev,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
ret = phy_ethtool_set_eee(dev->phydev, edata); ret = phylink_ethtool_set_eee(priv->phylink, edata);
if (ret) if (ret)
return ret; return ret;
...@@ -892,7 +845,7 @@ static const struct ethtool_ops stmmac_ethtool_ops = { ...@@ -892,7 +845,7 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
.get_regs = stmmac_ethtool_gregs, .get_regs = stmmac_ethtool_gregs,
.get_regs_len = stmmac_ethtool_get_regs_len, .get_regs_len = stmmac_ethtool_get_regs_len,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.nway_reset = phy_ethtool_nway_reset, .nway_reset = stmmac_nway_reset,
.get_pauseparam = stmmac_get_pauseparam, .get_pauseparam = stmmac_get_pauseparam,
.set_pauseparam = stmmac_set_pauseparam, .set_pauseparam = stmmac_set_pauseparam,
.self_test = stmmac_selftest_run, .self_test = stmmac_selftest_run,
......
...@@ -333,21 +333,6 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, ...@@ -333,21 +333,6 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
{}, {},
}; };
/* If phy-handle property is passed from DT, use it as the PHY */
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
if (plat->phy_node)
dev_dbg(dev, "Found phy-handle subnode\n");
/* If phy-handle is not specified, check if we have a fixed-phy */
if (!plat->phy_node && of_phy_is_fixed_link(np)) {
if ((of_phy_register_fixed_link(np) < 0))
return -ENODEV;
dev_dbg(dev, "Found fixed-link subnode\n");
plat->phy_node = of_node_get(np);
mdio = false;
}
if (of_match_node(need_mdio_ids, np)) { if (of_match_node(need_mdio_ids, np)) {
plat->mdio_node = of_get_child_by_name(np, "mdio"); plat->mdio_node = of_get_child_by_name(np, "mdio");
} else { } else {
...@@ -396,6 +381,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) ...@@ -396,6 +381,7 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
*mac = of_get_mac_address(np); *mac = of_get_mac_address(np);
plat->interface = of_get_phy_mode(np); plat->interface = of_get_phy_mode(np);
plat->phy_node = np;
/* Get max speed of operation from device tree */ /* Get max speed of operation from device tree */
if (of_property_read_u32(np, "max-speed", &plat->max_speed)) if (of_property_read_u32(np, "max-speed", &plat->max_speed))
...@@ -591,11 +577,6 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) ...@@ -591,11 +577,6 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
void stmmac_remove_config_dt(struct platform_device *pdev, void stmmac_remove_config_dt(struct platform_device *pdev,
struct plat_stmmacenet_data *plat) struct plat_stmmacenet_data *plat)
{ {
struct device_node *np = pdev->dev.of_node;
if (of_phy_is_fixed_link(np))
of_phy_deregister_fixed_link(np);
of_node_put(plat->phy_node);
of_node_put(plat->mdio_node); of_node_put(plat->mdio_node);
} }
#else #else
......
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