Commit 5d497936 authored by Peng Li's avatar Peng Li Committed by David S. Miller

net: hns3: Config NIC port speed same as that of optical module

Port 0/1 of HiP08 supports 10G and 25G. This patch adds a
change to configure NIC port speed same as that of  optical
module(SFP/QFSP). Driver gets the optical module speed and
sets NIC port speed accordingly.
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarSalil Mehta <salil.mehta@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cc3ec656
...@@ -90,7 +90,6 @@ enum hclge_opcode_type { ...@@ -90,7 +90,6 @@ enum hclge_opcode_type {
/* MAC command */ /* MAC command */
HCLGE_OPC_CONFIG_MAC_MODE = 0x0301, HCLGE_OPC_CONFIG_MAC_MODE = 0x0301,
HCLGE_OPC_CONFIG_AN_MODE = 0x0304, HCLGE_OPC_CONFIG_AN_MODE = 0x0304,
HCLGE_OPC_QUERY_AN_RESULT = 0x0306,
HCLGE_OPC_QUERY_LINK_STATUS = 0x0307, HCLGE_OPC_QUERY_LINK_STATUS = 0x0307,
HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308,
HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309, HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309,
...@@ -212,6 +211,9 @@ enum hclge_opcode_type { ...@@ -212,6 +211,9 @@ enum hclge_opcode_type {
/* Led command */ /* Led command */
HCLGE_OPC_LED_STATUS_CFG = 0xB000, HCLGE_OPC_LED_STATUS_CFG = 0xB000,
/* SFP command */
HCLGE_OPC_SFP_GET_SPEED = 0x7104,
/* Error INT commands */ /* Error INT commands */
HCLGE_TM_SCH_ECC_INT_EN = 0x0829, HCLGE_TM_SCH_ECC_INT_EN = 0x0829,
HCLGE_TM_SCH_ECC_ERR_RINT_CMD = 0x082d, HCLGE_TM_SCH_ECC_ERR_RINT_CMD = 0x082d,
...@@ -544,20 +546,6 @@ struct hclge_config_mac_speed_dup_cmd { ...@@ -544,20 +546,6 @@ struct hclge_config_mac_speed_dup_cmd {
u8 rsv[22]; u8 rsv[22];
}; };
#define HCLGE_QUERY_SPEED_S 3
#define HCLGE_QUERY_AN_B 0
#define HCLGE_QUERY_DUPLEX_B 2
#define HCLGE_QUERY_SPEED_M GENMASK(4, 0)
#define HCLGE_QUERY_AN_M BIT(HCLGE_QUERY_AN_B)
#define HCLGE_QUERY_DUPLEX_M BIT(HCLGE_QUERY_DUPLEX_B)
struct hclge_query_an_speed_dup_cmd {
u8 an_syn_dup_speed;
u8 pause;
u8 rsv[23];
};
#define HCLGE_RING_ID_MASK GENMASK(9, 0) #define HCLGE_RING_ID_MASK GENMASK(9, 0)
#define HCLGE_TQP_ENABLE_B 0 #define HCLGE_TQP_ENABLE_B 0
...@@ -574,6 +562,11 @@ struct hclge_config_auto_neg_cmd { ...@@ -574,6 +562,11 @@ struct hclge_config_auto_neg_cmd {
u8 rsv[20]; u8 rsv[20];
}; };
struct hclge_sfp_speed_cmd {
__le32 sfp_speed;
u32 rsv[5];
};
#define HCLGE_MAC_UPLINK_PORT 0x100 #define HCLGE_MAC_UPLINK_PORT 0x100
struct hclge_config_max_frm_size_cmd { struct hclge_config_max_frm_size_cmd {
......
...@@ -1896,37 +1896,6 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed, ...@@ -1896,37 +1896,6 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed,
return hclge_cfg_mac_speed_dup(hdev, speed, duplex); return hclge_cfg_mac_speed_dup(hdev, speed, duplex);
} }
static int hclge_query_mac_an_speed_dup(struct hclge_dev *hdev, int *speed,
u8 *duplex)
{
struct hclge_query_an_speed_dup_cmd *req;
struct hclge_desc desc;
int speed_tmp;
int ret;
req = (struct hclge_query_an_speed_dup_cmd *)desc.data;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QUERY_AN_RESULT, true);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"mac speed/autoneg/duplex query cmd failed %d\n",
ret);
return ret;
}
*duplex = hnae3_get_bit(req->an_syn_dup_speed, HCLGE_QUERY_DUPLEX_B);
speed_tmp = hnae3_get_field(req->an_syn_dup_speed, HCLGE_QUERY_SPEED_M,
HCLGE_QUERY_SPEED_S);
ret = hclge_parse_speed(speed_tmp, speed);
if (ret)
dev_err(&hdev->pdev->dev,
"could not parse speed(=%d), %d\n", speed_tmp, ret);
return ret;
}
static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable) static int hclge_set_autoneg_en(struct hclge_dev *hdev, bool enable)
{ {
struct hclge_config_auto_neg_cmd *req; struct hclge_config_auto_neg_cmd *req;
...@@ -1973,6 +1942,7 @@ static int hclge_mac_init(struct hclge_dev *hdev) ...@@ -1973,6 +1942,7 @@ static int hclge_mac_init(struct hclge_dev *hdev)
struct hclge_mac *mac = &hdev->hw.mac; struct hclge_mac *mac = &hdev->hw.mac;
int ret; int ret;
hdev->support_sfp_query = true;
hdev->hw.mac.duplex = HCLGE_MAC_FULL; hdev->hw.mac.duplex = HCLGE_MAC_FULL;
ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed,
hdev->hw.mac.duplex); hdev->hw.mac.duplex);
...@@ -2082,34 +2052,58 @@ static void hclge_update_link_status(struct hclge_dev *hdev) ...@@ -2082,34 +2052,58 @@ static void hclge_update_link_status(struct hclge_dev *hdev)
} }
} }
static int hclge_get_sfp_speed(struct hclge_dev *hdev, u32 *speed)
{
struct hclge_sfp_speed_cmd *resp = NULL;
struct hclge_desc desc;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SFP_GET_SPEED, true);
resp = (struct hclge_sfp_speed_cmd *)desc.data;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret == -EOPNOTSUPP) {
dev_warn(&hdev->pdev->dev,
"IMP do not support get SFP speed %d\n", ret);
return ret;
} else if (ret) {
dev_err(&hdev->pdev->dev, "get sfp speed failed %d\n", ret);
return ret;
}
*speed = resp->sfp_speed;
return 0;
}
static int hclge_update_speed_duplex(struct hclge_dev *hdev) static int hclge_update_speed_duplex(struct hclge_dev *hdev)
{ {
struct hclge_mac mac = hdev->hw.mac; struct hclge_mac mac = hdev->hw.mac;
u8 duplex;
int speed; int speed;
int ret; int ret;
/* get the speed and duplex as autoneg'result from mac cmd when phy /* get the speed from SFP cmd when phy
* doesn't exit. * doesn't exit.
*/ */
if (mac.phydev || !mac.autoneg) if (mac.phydev)
return 0; return 0;
ret = hclge_query_mac_an_speed_dup(hdev, &speed, &duplex); /* if IMP does not support get SFP/qSFP speed, return directly */
if (ret) { if (!hdev->support_sfp_query)
dev_err(&hdev->pdev->dev, return 0;
"mac autoneg/speed/duplex query failed %d\n", ret);
return ret;
}
ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); ret = hclge_get_sfp_speed(hdev, &speed);
if (ret) { if (ret == -EOPNOTSUPP) {
dev_err(&hdev->pdev->dev, hdev->support_sfp_query = false;
"mac speed/duplex config failed %d\n", ret); return ret;
} else if (ret) {
return ret; return ret;
} }
return 0; if (speed == HCLGE_MAC_SPEED_UNKNOWN)
return 0; /* do nothing if no SFP */
/* must config full duplex for SFP */
return hclge_cfg_mac_speed_dup(hdev, speed, HCLGE_MAC_FULL);
} }
static int hclge_update_speed_duplex_h(struct hnae3_handle *handle) static int hclge_update_speed_duplex_h(struct hnae3_handle *handle)
......
...@@ -155,6 +155,7 @@ enum hclge_evt_cause { ...@@ -155,6 +155,7 @@ enum hclge_evt_cause {
#define HCLGE_MPF_ENBALE 1 #define HCLGE_MPF_ENBALE 1
enum HCLGE_MAC_SPEED { enum HCLGE_MAC_SPEED {
HCLGE_MAC_SPEED_UNKNOWN = 0, /* unknown */
HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */ HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */
HCLGE_MAC_SPEED_100M = 100, /* 100 Mbps */ HCLGE_MAC_SPEED_100M = 100, /* 100 Mbps */
HCLGE_MAC_SPEED_1G = 1000, /* 1000 Mbps = 1 Gbps */ HCLGE_MAC_SPEED_1G = 1000, /* 1000 Mbps = 1 Gbps */
...@@ -624,6 +625,7 @@ struct hclge_dev { ...@@ -624,6 +625,7 @@ struct hclge_dev {
u8 hw_tc_map; u8 hw_tc_map;
u8 tc_num_last_time; u8 tc_num_last_time;
enum hclge_fc_mode fc_mode_last_time; enum hclge_fc_mode fc_mode_last_time;
u8 support_sfp_query;
#define HCLGE_FLAG_TC_BASE_SCH_MODE 1 #define HCLGE_FLAG_TC_BASE_SCH_MODE 1
#define HCLGE_FLAG_VNET_BASE_SCH_MODE 2 #define HCLGE_FLAG_VNET_BASE_SCH_MODE 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment