Add pause get and set functions
Signed-off-by: Raju Lakkaraju <[email protected]>
---
.../net/ethernet/microchip/lan743x_ethtool.c | 46 +++++++++++++++++++
drivers/net/ethernet/microchip/lan743x_main.c | 4 +-
drivers/net/ethernet/microchip/lan743x_main.h | 2 +
3 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_ethtool.c b/drivers/net/ethernet/microchip/lan743x_ethtool.c
index c739d60ee17d..44c98715eb17 100644
--- a/drivers/net/ethernet/microchip/lan743x_ethtool.c
+++ b/drivers/net/ethernet/microchip/lan743x_ethtool.c
@@ -1233,6 +1233,50 @@ static void lan743x_get_regs(struct net_device *dev,
lan743x_common_regs(dev, regs, p);
}
+static void lan743x_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *pause)
+{
+ struct lan743x_adapter *adapter = netdev_priv(dev);
+ struct lan743x_phy *phy = &adapter->phy;
+
+ if (phy->fc_request_control & FLOW_CTRL_TX)
+ pause->tx_pause = 1;
+ if (phy->fc_request_control & FLOW_CTRL_RX)
+ pause->rx_pause = 1;
+ pause->autoneg = phy->fc_autoneg;
+}
+
+static int lan743x_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *pause)
+{
+ struct lan743x_adapter *adapter = netdev_priv(dev);
+ struct phy_device *phydev = dev->phydev;
+ struct lan743x_phy *phy = &adapter->phy;
+
+ if (!phydev)
+ return -ENODEV;
+
+ if (!phy_validate_pause(phydev, pause))
+ return -EINVAL;
+
+ phy->fc_request_control = 0;
+ if (pause->rx_pause)
+ phy->fc_request_control |= FLOW_CTRL_RX;
+
+ if (pause->tx_pause)
+ phy->fc_request_control |= FLOW_CTRL_TX;
+
+ phy->fc_autoneg = pause->autoneg;
+
+ phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause);
+
+ if (pause->autoneg == AUTONEG_DISABLE)
+ lan743x_mac_flow_ctrl_set_enables(adapter, pause->tx_pause,
+ pause->rx_pause);
+
+ return 0;
+}
+
const struct ethtool_ops lan743x_ethtool_ops = {
.get_drvinfo = lan743x_ethtool_get_drvinfo,
.get_msglevel = lan743x_ethtool_get_msglevel,
@@ -1259,6 +1303,8 @@ const struct ethtool_ops lan743x_ethtool_ops = {
.set_link_ksettings = phy_ethtool_set_link_ksettings,
.get_regs_len = lan743x_get_regs_len,
.get_regs = lan743x_get_regs,
+ .get_pauseparam = lan743x_get_pauseparam,
+ .set_pauseparam = lan743x_set_pauseparam,
#ifdef CONFIG_PM
.get_wol = lan743x_ethtool_get_wol,
.set_wol = lan743x_ethtool_set_wol,
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 50eeecba1f18..c0f8ba601c01 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -1326,8 +1326,8 @@ static void lan743x_mac_close(struct lan743x_adapter *adapter)
1, 1000, 20000, 100);
}
-static void lan743x_mac_flow_ctrl_set_enables(struct lan743x_adapter *adapter,
- bool tx_enable, bool rx_enable)
+void lan743x_mac_flow_ctrl_set_enables(struct lan743x_adapter *adapter,
+ bool tx_enable, bool rx_enable)
{
u32 flow_setting = 0;
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 67877d3b6dd9..bc5eea4c7b40 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -1159,5 +1159,7 @@ u32 lan743x_csr_read(struct lan743x_adapter *adapter, int offset);
void lan743x_csr_write(struct lan743x_adapter *adapter, int offset, u32 data);
int lan743x_hs_syslock_acquire(struct lan743x_adapter *adapter, u16 timeout);
void lan743x_hs_syslock_release(struct lan743x_adapter *adapter);
+void lan743x_mac_flow_ctrl_set_enables(struct lan743x_adapter *adapter,
+ bool tx_enable, bool rx_enable);
#endif /* _LAN743X_H */
--
2.25.1
> +static int lan743x_set_pauseparam(struct net_device *dev,
> + struct ethtool_pauseparam *pause)
> +{
> + struct lan743x_adapter *adapter = netdev_priv(dev);
> + struct phy_device *phydev = dev->phydev;
> + struct lan743x_phy *phy = &adapter->phy;
> +
> + if (!phydev)
> + return -ENODEV;
> +
> + if (!phy_validate_pause(phydev, pause))
> + return -EINVAL;
> +
> + phy->fc_request_control = 0;
> + if (pause->rx_pause)
> + phy->fc_request_control |= FLOW_CTRL_RX;
> +
> + if (pause->tx_pause)
> + phy->fc_request_control |= FLOW_CTRL_TX;
> +
> + phy->fc_autoneg = pause->autoneg;
> +
> + phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause);
> +
> + if (pause->autoneg == AUTONEG_DISABLE)
> + lan743x_mac_flow_ctrl_set_enables(adapter, pause->tx_pause,
> + pause->rx_pause);
pause is not too well defined. But i think phy_set_asym_pause() should
be in an else clause. If pause autoneg is off, you directly set it in
the MAC and ignore what is negotiated. If it is enabled, you
negotiate. As far as i understand, you don't modify your negotiation
when pause autoneg is off.
Andrew
Hi Andrew,
Thank you for review comments.
The 10/21/2022 15:46, Andrew Lunn wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> > +static int lan743x_set_pauseparam(struct net_device *dev,
> > + struct ethtool_pauseparam *pause)
> > +{
> > + struct lan743x_adapter *adapter = netdev_priv(dev);
> > + struct phy_device *phydev = dev->phydev;
> > + struct lan743x_phy *phy = &adapter->phy;
> > +
> > + if (!phydev)
> > + return -ENODEV;
> > +
> > + if (!phy_validate_pause(phydev, pause))
> > + return -EINVAL;
> > +
> > + phy->fc_request_control = 0;
> > + if (pause->rx_pause)
> > + phy->fc_request_control |= FLOW_CTRL_RX;
> > +
> > + if (pause->tx_pause)
> > + phy->fc_request_control |= FLOW_CTRL_TX;
> > +
> > + phy->fc_autoneg = pause->autoneg;
> > +
> > + phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause);
> > +
> > + if (pause->autoneg == AUTONEG_DISABLE)
> > + lan743x_mac_flow_ctrl_set_enables(adapter, pause->tx_pause,
> > + pause->rx_pause);
>
> pause is not too well defined. But i think phy_set_asym_pause() should
> be in an else clause. If pause autoneg is off, you directly set it in
> the MAC and ignore what is negotiated. If it is enabled, you
> negotiate. As far as i understand, you don't modify your negotiation
> when pause autoneg is off.
O.K. I will change.
>
> Andrew
--------
Thanks,
Raju