diff options
author | Giuseppe CAVALLARO <peppe.cavallaro@st.com> | 2016-06-24 15:16:24 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-06-28 08:54:23 -0400 |
commit | 70523e639bf8ca09b3357371c3546cee55c06351 (patch) | |
tree | 5e54e3884e7269febca967aeeb9c31c8c54ab160 /drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | |
parent | a5e4bd991362223346e1d3561e61d7a25797fe25 (diff) |
drivers: net: stmmac: reworking the PCS code.
The 3.xx and 4.xx synopsys gmacs have a very similar
PCS embedded module and they share almost the same registers:
for example:
AN_Control, AN_Status, AN_Advertisement, AN_Link_Partner_Ability,
AN_Expansion, TBI_Extended_Status.
Just the RGMII/SMII Control/Status register differs.
So This patch aims to reorganize and enhance the PCS support.
It removes the existent support from the dwmac1000/dwmac4_core.c
moving basic PCS functions inside a new file called: stmmac_pcs.h.
The patch also reviews the available APIs to be better shared among
different hardware and easily enhanced to support new features.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index e2b98b01647e..a5f4f46da42b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -289,10 +289,10 @@ static int stmmac_ethtool_getsettings(struct net_device *dev, ethtool_cmd_speed_set(cmd, priv->xstats.pcs_speed); /* Get and convert ADV/LP_ADV from the HW AN registers */ - if (!priv->hw->mac->get_adv) + if (!priv->hw->mac->pcs_get_adv_lp) return -EOPNOTSUPP; /* should never happen indeed */ - priv->hw->mac->get_adv(priv->hw, &adv); + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv); /* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */ @@ -376,8 +376,10 @@ static int stmmac_ethtool_setsettings(struct net_device *dev, ADVERTISED_10baseT_Full); spin_lock(&priv->lock); - if (priv->hw->mac->ctrl_ane) - priv->hw->mac->ctrl_ane(priv->hw, 1); + + if (priv->hw->mac->pcs_ctrl_ane) + priv->hw->mac->pcs_ctrl_ane(priv->ioaddr, 1, 0, 0); + spin_unlock(&priv->lock); return 0; @@ -452,11 +454,22 @@ stmmac_get_pauseparam(struct net_device *netdev, { struct stmmac_priv *priv = netdev_priv(netdev); - if (priv->pcs) /* FIXME */ - return; - pause->rx_pause = 0; pause->tx_pause = 0; + + if (priv->pcs && priv->hw->mac->pcs_get_adv_lp) { + struct rgmii_adv adv_lp; + + pause->autoneg = 1; + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp); + if (!adv_lp.pause) + return; + } else { + if (!(priv->phydev->supported & SUPPORTED_Pause) || + !(priv->phydev->supported & SUPPORTED_Asym_Pause)) + return; + } + pause->autoneg = priv->phydev->autoneg; if (priv->flow_ctrl & FLOW_RX) @@ -473,10 +486,19 @@ stmmac_set_pauseparam(struct net_device *netdev, struct stmmac_priv *priv = netdev_priv(netdev); struct phy_device *phy = priv->phydev; int new_pause = FLOW_OFF; - int ret = 0; - if (priv->pcs) /* FIXME */ - return -EOPNOTSUPP; + if (priv->pcs && priv->hw->mac->pcs_get_adv_lp) { + struct rgmii_adv adv_lp; + + pause->autoneg = 1; + priv->hw->mac->pcs_get_adv_lp(priv->ioaddr, &adv_lp); + if (!adv_lp.pause) + return -EOPNOTSUPP; + } else { + if (!(phy->supported & SUPPORTED_Pause) || + !(phy->supported & SUPPORTED_Asym_Pause)) + return -EOPNOTSUPP; + } if (pause->rx_pause) new_pause |= FLOW_RX; @@ -485,14 +507,14 @@ stmmac_set_pauseparam(struct net_device *netdev, priv->flow_ctrl = new_pause; phy->autoneg = pause->autoneg; - if (phy->autoneg) { if (netif_running(netdev)) - ret = phy_start_aneg(phy); - } else - priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, - priv->flow_ctrl, priv->pause); - return ret; + return phy_start_aneg(phy); + } + + priv->hw->mac->flow_ctrl(priv->hw, phy->duplex, priv->flow_ctrl, + priv->pause); + return 0; } static void stmmac_get_ethtool_stats(struct net_device *dev, |