This commit adds port pause ops to the hinic3 driver. It implements the .get_pauseparam and .set_pauseparam callbacks so these can be read and write with ethtool -a/A. Co-developed-by: Wu Di Signed-off-by: Wu Di Co-developed-by: Teng Peisen Signed-off-by: Teng Peisen Signed-off-by: Fan Gong --- .../ethernet/huawei/hinic3/hinic3_ethtool.c | 41 +++++++++++++++++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.c | 7 ++++ .../ethernet/huawei/hinic3/hinic3_nic_cfg.h | 2 + 3 files changed, 50 insertions(+) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c index e1f23e2477fa..3005441056f9 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_ethtool.c @@ -869,6 +869,45 @@ static void hinic3_get_pause_stats(struct net_device *netdev, kfree(ps); } +static void hinic3_get_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); + struct hinic3_nic_pause_config nic_pause = {}; + int err; + + err = hinic3_get_pause_info(nic_dev, &nic_pause); + if (err) { + netdev_err_once(netdev, "Failed to get pauseparam\n"); + } else { + pause->autoneg = AUTONEG_DISABLE; + pause->rx_pause = nic_pause.rx_pause; + pause->tx_pause = nic_pause.tx_pause; + } +} + +static int hinic3_set_pauseparam(struct net_device *netdev, + struct ethtool_pauseparam *pause) +{ + struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); + struct hinic3_nic_pause_config nic_pause = {}; + int err; + + if (HINIC3_IS_VF(nic_dev->hwdev)) + return -EOPNOTSUPP; + + if (pause->autoneg) + return -EOPNOTSUPP; + + nic_pause.rx_pause = (u8)pause->rx_pause; + nic_pause.tx_pause = (u8)pause->tx_pause; + + err = hinic3_set_pause_info(nic_dev, &nic_pause); + if (err) + netdev_err_once(netdev, "Failed to set pauseparam\n"); + return err; +} + static const struct ethtool_ops hinic3_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS | ETHTOOL_COALESCE_PKT_RATE_RX_USECS, @@ -885,6 +924,8 @@ static const struct ethtool_ops hinic3_ethtool_ops = { .get_eth_ctrl_stats = hinic3_get_eth_ctrl_stats, .get_rmon_stats = hinic3_get_rmon_stats, .get_pause_stats = hinic3_get_pause_stats, + .get_pauseparam = hinic3_get_pauseparam, + .set_pauseparam = hinic3_set_pauseparam, }; void hinic3_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c index e4a3fa6fb8db..b5c696fe6cdf 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.c @@ -739,6 +739,13 @@ int hinic3_get_pause_info(struct hinic3_nic_dev *nic_dev, nic_pause); } +int hinic3_set_pause_info(struct hinic3_nic_dev *nic_dev, + struct hinic3_nic_pause_config *nic_pause) +{ + return hinic3_cfg_hw_pause(nic_dev->hwdev, MGMT_MSG_CMD_OP_SET, + nic_pause); +} + int hinic3_get_vport_stats(struct hinic3_hwdev *hwdev, u16 func_id, struct l2nic_vport_stats *stats) { diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h index 63382191446d..beb491d66738 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_cfg.h @@ -318,6 +318,8 @@ int hinic3_del_vlan(struct hinic3_hwdev *hwdev, u16 vlan_id, u16 func_id); int hinic3_get_pause_info(struct hinic3_nic_dev *nic_dev, struct hinic3_nic_pause_config *nic_pause); +int hinic3_set_pause_info(struct hinic3_nic_dev *nic_dev, + struct hinic3_nic_pause_config *nic_pause); int hinic3_get_vport_stats(struct hinic3_hwdev *hwdev, u16 func_id, struct l2nic_vport_stats *stats); -- 2.43.0