lkml.org 
[lkml]   [2017]   [Dec]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V5 net-next 12/17] net: hns3: add support for set_pauseparam
    Date
    This patch adds set_pauseparam support for ethtool cmd.

    Signed-off-by: Peng Li <lipeng321@huawei.com>
    Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
    ---
    drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 13 ++++
    .../ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 83 ++++++++++++++++++++++
    .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 2 +-
    .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 1 +
    4 files changed, 98 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
    index 2fd2656..b829ec7 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
    @@ -559,6 +559,18 @@ static void hns3_get_pauseparam(struct net_device *netdev,
    &param->rx_pause, &param->tx_pause);
    }

    +static int hns3_set_pauseparam(struct net_device *netdev,
    + struct ethtool_pauseparam *param)
    +{
    + struct hnae3_handle *h = hns3_get_handle(netdev);
    +
    + if (h->ae_algo->ops->set_pauseparam)
    + return h->ae_algo->ops->set_pauseparam(h, param->autoneg,
    + param->rx_pause,
    + param->tx_pause);
    + return -EOPNOTSUPP;
    +}
    +
    static int hns3_get_link_ksettings(struct net_device *netdev,
    struct ethtool_link_ksettings *cmd)
    {
    @@ -880,6 +892,7 @@ void hns3_get_channels(struct net_device *netdev,
    .get_ringparam = hns3_get_ringparam,
    .set_ringparam = hns3_set_ringparam,
    .get_pauseparam = hns3_get_pauseparam,
    + .set_pauseparam = hns3_set_pauseparam,
    .get_strings = hns3_get_strings,
    .get_ethtool_stats = hns3_get_stats,
    .get_sset_count = hns3_get_sset_count,
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    index 14e1054..0f55ee6 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
    @@ -4660,6 +4660,53 @@ static u32 hclge_get_fw_version(struct hnae3_handle *handle)
    return hdev->fw_version;
    }

    +static void hclge_set_flowctrl_adv(struct hclge_dev *hdev, u32 rx_en, u32 tx_en)
    +{
    + struct phy_device *phydev = hdev->hw.mac.phydev;
    +
    + if (!phydev)
    + return;
    +
    + phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause);
    +
    + if (rx_en)
    + phydev->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
    +
    + if (tx_en)
    + phydev->advertising ^= ADVERTISED_Asym_Pause;
    +}
    +
    +static int hclge_cfg_pauseparam(struct hclge_dev *hdev, u32 rx_en, u32 tx_en)
    +{
    + enum hclge_fc_mode fc_mode;
    + int ret;
    +
    + if (rx_en && tx_en)
    + fc_mode = HCLGE_FC_FULL;
    + else if (rx_en && !tx_en)
    + fc_mode = HCLGE_FC_RX_PAUSE;
    + else if (!rx_en && tx_en)
    + fc_mode = HCLGE_FC_TX_PAUSE;
    + else
    + fc_mode = HCLGE_FC_NONE;
    +
    + if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) {
    + hdev->fc_mode_last_time = fc_mode;
    + return 0;
    + }
    +
    + ret = hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
    + if (ret) {
    + dev_err(&hdev->pdev->dev, "configure pauseparam error, ret = %d.\n",
    + ret);
    + return ret;
    + }
    +
    + hdev->tm_info.fc_mode = fc_mode;
    +
    + return 0;
    +}
    +
    static void hclge_get_pauseparam(struct hnae3_handle *handle, u32 *auto_neg,
    u32 *rx_en, u32 *tx_en)
    {
    @@ -4689,6 +4736,41 @@ static void hclge_get_pauseparam(struct hnae3_handle *handle, u32 *auto_neg,
    }
    }

    +static int hclge_set_pauseparam(struct hnae3_handle *handle, u32 auto_neg,
    + u32 rx_en, u32 tx_en)
    +{
    + struct hclge_vport *vport = hclge_get_vport(handle);
    + struct hclge_dev *hdev = vport->back;
    + struct phy_device *phydev = hdev->hw.mac.phydev;
    + u32 fc_autoneg;
    +
    + /* Only support flow control negotiation for netdev with
    + * phy attached for now.
    + */
    + if (!phydev)
    + return -EOPNOTSUPP;
    +
    + fc_autoneg = hclge_get_autoneg(handle);
    + if (auto_neg != fc_autoneg) {
    + dev_info(&hdev->pdev->dev,
    + "To change autoneg please use: ethtool -s <dev> autoneg <on|off>\n");
    + return -EOPNOTSUPP;
    + }
    +
    + if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) {
    + dev_info(&hdev->pdev->dev,
    + "Priority flow control enabled. Cannot set link flow control.\n");
    + return -EOPNOTSUPP;
    + }
    +
    + hclge_set_flowctrl_adv(hdev, rx_en, tx_en);
    +
    + if (!fc_autoneg)
    + return hclge_cfg_pauseparam(hdev, rx_en, tx_en);
    +
    + return phy_start_aneg(phydev);
    +}
    +
    static void hclge_get_ksettings_an_result(struct hnae3_handle *handle,
    u8 *auto_neg, u32 *speed, u8 *duplex)
    {
    @@ -5344,6 +5426,7 @@ static int hclge_set_channels(struct hnae3_handle *handle, u32 new_tqps_num)
    .set_autoneg = hclge_set_autoneg,
    .get_autoneg = hclge_get_autoneg,
    .get_pauseparam = hclge_get_pauseparam,
    + .set_pauseparam = hclge_set_pauseparam,
    .set_mtu = hclge_set_mtu,
    .reset_queue = hclge_reset_tqp,
    .get_stats = hclge_get_stats,
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    index 7bfa2e5..7cfe1eb 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c
    @@ -112,7 +112,7 @@ static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
    return 0;
    }

    -static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
    +int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
    {
    struct hclge_desc desc;

    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    index bf59961..16f4139 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h
    @@ -118,4 +118,5 @@ struct hclge_port_shapping_cmd {
    int hclge_tm_dwrr_cfg(struct hclge_dev *hdev);
    int hclge_tm_map_cfg(struct hclge_dev *hdev);
    int hclge_tm_init_hw(struct hclge_dev *hdev);
    +int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx);
    #endif
    --
    1.9.1
    \
     
     \ /
      Last update: 2017-12-22 04:53    [W:2.495 / U:0.184 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site