summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBhargava Marreddy <bhargava.marreddy@broadcom.com>2026-04-06 21:04:14 +0300
committerJakub Kicinski <kuba@kernel.org>2026-04-12 21:09:36 +0300
commitdc85e8a51f5a6b8f8a3a8de0f89467ae797b5cd8 (patch)
tree2404ef5479558648b7923e664a23b9ecfaf89ae1
parent169f6e8dd14957bbb66bf5bab40bf251a3950fc2 (diff)
downloadlinux-dc85e8a51f5a6b8f8a3a8de0f89467ae797b5cd8.tar.xz
bng_en: implement ethtool pauseparam operations
Implement .get_pauseparam and .set_pauseparam to support flow control configuration. This allows reporting and setting of autoneg, RX pause, and TX pause states. Signed-off-by: Bhargava Marreddy <bhargava.marreddy@broadcom.com> Reviewed-by: Vikas Gupta <vikas.gupta@broadcom.com> Link: https://patch.msgid.link/20260406180420.279470-5-bhargava.marreddy@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r--drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c b/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c
index 6bb74a84ea03..424bf2d6721c 100644
--- a/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnge/bnge_ethtool.c
@@ -46,6 +46,67 @@ static void bnge_get_drvinfo(struct net_device *dev,
strscpy(info->bus_info, pci_name(bd->pdev), sizeof(info->bus_info));
}
+static void bnge_get_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnge_net *bn = netdev_priv(dev);
+ struct bnge_dev *bd = bn->bd;
+
+ if (bd->phy_flags & BNGE_PHY_FL_NO_PAUSE) {
+ epause->autoneg = 0;
+ epause->rx_pause = 0;
+ epause->tx_pause = 0;
+ return;
+ }
+
+ epause->autoneg = !!(bn->eth_link_info.autoneg &
+ BNGE_AUTONEG_FLOW_CTRL);
+ epause->rx_pause = !!(bn->eth_link_info.req_flow_ctrl &
+ BNGE_LINK_PAUSE_RX);
+ epause->tx_pause = !!(bn->eth_link_info.req_flow_ctrl &
+ BNGE_LINK_PAUSE_TX);
+}
+
+static int bnge_set_pauseparam(struct net_device *dev,
+ struct ethtool_pauseparam *epause)
+{
+ struct bnge_ethtool_link_info old_elink_info, *elink_info;
+ struct bnge_net *bn = netdev_priv(dev);
+ struct bnge_dev *bd = bn->bd;
+ int rc = 0;
+
+ if (!BNGE_PHY_CFG_ABLE(bd) || (bd->phy_flags & BNGE_PHY_FL_NO_PAUSE))
+ return -EOPNOTSUPP;
+
+ elink_info = &bn->eth_link_info;
+ old_elink_info = *elink_info;
+
+ if (epause->autoneg) {
+ if (!(elink_info->autoneg & BNGE_AUTONEG_SPEED))
+ return -EINVAL;
+
+ elink_info->autoneg |= BNGE_AUTONEG_FLOW_CTRL;
+ } else {
+ if (elink_info->autoneg & BNGE_AUTONEG_FLOW_CTRL)
+ elink_info->force_link_chng = true;
+ elink_info->autoneg &= ~BNGE_AUTONEG_FLOW_CTRL;
+ }
+
+ elink_info->req_flow_ctrl = 0;
+ if (epause->rx_pause)
+ elink_info->req_flow_ctrl |= BNGE_LINK_PAUSE_RX;
+ if (epause->tx_pause)
+ elink_info->req_flow_ctrl |= BNGE_LINK_PAUSE_TX;
+
+ if (netif_running(dev)) {
+ rc = bnge_hwrm_set_pause(bn);
+ if (rc)
+ *elink_info = old_elink_info;
+ }
+
+ return rc;
+}
+
static const struct ethtool_ops bnge_ethtool_ops = {
.cap_link_lanes_supported = 1,
.get_link_ksettings = bnge_get_link_ksettings,
@@ -53,6 +114,8 @@ static const struct ethtool_ops bnge_ethtool_ops = {
.get_drvinfo = bnge_get_drvinfo,
.get_link = bnge_get_link,
.nway_reset = bnge_nway_reset,
+ .get_pauseparam = bnge_get_pauseparam,
+ .set_pauseparam = bnge_set_pauseparam,
};
void bnge_set_ethtool_ops(struct net_device *dev)