]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
net: hns3: add update ethtool advertised link modes for FIBRE port when autoneg off
authorGuangbin Huang <huangguangbin2@huawei.com>
Sun, 24 Oct 2021 09:41:13 +0000 (17:41 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Oct 2021 13:00:59 +0000 (14:00 +0100)
Currently, the ethtool advertised link modes of FIBRE port is cleared to
zero when autoneg is off, so user can not get the advertised link modes
info directly from "ethtool <dev>" command.

In order to ameliorate this situation, update data of speeds, fec and pause
of advertised link modes when autoneg is off.

Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c

index 4159c27b99cb2d2f8f6de1dc9cd75a52ab283e13..f1db6699f81fe95f03f449da80d90f1cedd7b95b 100644 (file)
@@ -3051,6 +3051,82 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
        clear_bit(HCLGE_STATE_LINK_UPDATING, &hdev->state);
 }
 
+static void hclge_update_speed_advertising(struct hclge_mac *mac)
+{
+       u32 speed_ability;
+
+       if (hclge_get_speed_bit(mac->speed, &speed_ability))
+               return;
+
+       switch (mac->module_type) {
+       case HNAE3_MODULE_TYPE_FIBRE_LR:
+               hclge_convert_setting_lr(speed_ability, mac->advertising);
+               break;
+       case HNAE3_MODULE_TYPE_FIBRE_SR:
+       case HNAE3_MODULE_TYPE_AOC:
+               hclge_convert_setting_sr(speed_ability, mac->advertising);
+               break;
+       case HNAE3_MODULE_TYPE_CR:
+               hclge_convert_setting_cr(speed_ability, mac->advertising);
+               break;
+       case HNAE3_MODULE_TYPE_KR:
+               hclge_convert_setting_kr(speed_ability, mac->advertising);
+               break;
+       default:
+               break;
+       }
+}
+
+static void hclge_update_fec_advertising(struct hclge_mac *mac)
+{
+       if (mac->fec_mode & BIT(HNAE3_FEC_RS))
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT,
+                                mac->advertising);
+       else if (mac->fec_mode & BIT(HNAE3_FEC_BASER))
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT,
+                                mac->advertising);
+       else
+               linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT,
+                                mac->advertising);
+}
+
+static void hclge_update_pause_advertising(struct hclge_dev *hdev)
+{
+       struct hclge_mac *mac = &hdev->hw.mac;
+       bool rx_en, tx_en;
+
+       switch (hdev->fc_mode_last_time) {
+       case HCLGE_FC_RX_PAUSE:
+               rx_en = true;
+               tx_en = false;
+               break;
+       case HCLGE_FC_TX_PAUSE:
+               rx_en = false;
+               tx_en = true;
+               break;
+       case HCLGE_FC_FULL:
+               rx_en = true;
+               tx_en = true;
+               break;
+       default:
+               rx_en = false;
+               tx_en = false;
+               break;
+       }
+
+       linkmode_set_pause(mac->advertising, tx_en, rx_en);
+}
+
+static void hclge_update_advertising(struct hclge_dev *hdev)
+{
+       struct hclge_mac *mac = &hdev->hw.mac;
+
+       linkmode_zero(mac->advertising);
+       hclge_update_speed_advertising(mac);
+       hclge_update_fec_advertising(mac);
+       hclge_update_pause_advertising(hdev);
+}
+
 static void hclge_update_port_capability(struct hclge_dev *hdev,
                                         struct hclge_mac *mac)
 {
@@ -3073,7 +3149,7 @@ static void hclge_update_port_capability(struct hclge_dev *hdev,
        } else {
                linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
                                   mac->supported);
-               linkmode_zero(mac->advertising);
+               hclge_update_advertising(hdev);
        }
 }