Message ID | 20190228022910.23863-1-dann.frazier@canonical.com |
---|---|
State | New |
Headers | show |
Series | [Disco,SRU,Cosmic,SRU,Bionic] net: hns3: Config NIC port speed same as that of optical module | expand |
On 28.02.19 03:29, dann frazier wrote: > From: Peng Li <lipeng321@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1817969 > > 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: Peng Li <lipeng321@huawei.com> > Signed-off-by: Salil Mehta <salil.mehta@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5d497936756fa2a917643ca688585d721dc6d31e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- I guess hns3 cannot get worse... > .../hisilicon/hns3/hns3pf/hclge_cmd.h | 23 ++--- > .../hisilicon/hns3/hns3pf/hclge_main.c | 84 +++++++++---------- > .../hisilicon/hns3/hns3pf/hclge_main.h | 2 + > 3 files changed, 49 insertions(+), 60 deletions(-) > > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > index ceb3ec0adfc5d..f23042b24c094 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > @@ -104,7 +104,6 @@ enum hclge_opcode_type { > /* MAC command */ > HCLGE_OPC_CONFIG_MAC_MODE = 0x0301, > HCLGE_OPC_CONFIG_AN_MODE = 0x0304, > - HCLGE_OPC_QUERY_AN_RESULT = 0x0306, > HCLGE_OPC_QUERY_LINK_STATUS = 0x0307, > HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, > HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309, > @@ -236,6 +235,9 @@ enum hclge_opcode_type { > /* Led command */ > HCLGE_OPC_LED_STATUS_CFG = 0xB000, > > + /* SFP command */ > + HCLGE_OPC_SFP_GET_SPEED = 0x7104, > + > /* Error INT commands */ > HCLGE_MAC_COMMON_INT_EN = 0x030E, > HCLGE_TM_SCH_ECC_INT_EN = 0x0829, > @@ -574,20 +576,6 @@ struct hclge_config_mac_speed_dup_cmd { > 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_TQP_ENABLE_B 0 > > @@ -604,6 +592,11 @@ struct hclge_config_auto_neg_cmd { > u8 rsv[20]; > }; > > +struct hclge_sfp_speed_cmd { > + __le32 sfp_speed; > + u32 rsv[5]; > +}; > + > #define HCLGE_MAC_UPLINK_PORT 0x100 > > struct hclge_config_max_frm_size_cmd { > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > index 620fa96313cec..338b9c2210e72 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > @@ -1983,37 +1983,6 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed, > 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) > { > struct hclge_config_auto_neg_cmd *req; > @@ -2060,6 +2029,7 @@ static int hclge_mac_init(struct hclge_dev *hdev) > struct hclge_mac *mac = &hdev->hw.mac; > int ret; > > + hdev->support_sfp_query = true; > hdev->hw.mac.duplex = HCLGE_MAC_FULL; > ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, > hdev->hw.mac.duplex); > @@ -2169,34 +2139,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) > { > struct hclge_mac mac = hdev->hw.mac; > - u8 duplex; > int speed; > 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. > */ > - if (mac.phydev || !mac.autoneg) > + if (mac.phydev) > return 0; > > - ret = hclge_query_mac_an_speed_dup(hdev, &speed, &duplex); > - if (ret) { > - dev_err(&hdev->pdev->dev, > - "mac autoneg/speed/duplex query failed %d\n", ret); > - return ret; > - } > + /* if IMP does not support get SFP/qSFP speed, return directly */ > + if (!hdev->support_sfp_query) > + return 0; > > - ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); > - if (ret) { > - dev_err(&hdev->pdev->dev, > - "mac speed/duplex config failed %d\n", ret); > + ret = hclge_get_sfp_speed(hdev, &speed); > + if (ret == -EOPNOTSUPP) { > + hdev->support_sfp_query = false; > + return ret; > + } else if (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) > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > index 47a05c7465a21..6615b85a1c527 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > @@ -212,6 +212,7 @@ enum hclge_evt_cause { > #define HCLGE_MPF_ENBALE 1 > > enum HCLGE_MAC_SPEED { > + HCLGE_MAC_SPEED_UNKNOWN = 0, /* unknown */ > HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */ > HCLGE_MAC_SPEED_100M = 100, /* 100 Mbps */ > HCLGE_MAC_SPEED_1G = 1000, /* 1000 Mbps = 1 Gbps */ > @@ -681,6 +682,7 @@ struct hclge_dev { > u8 hw_tc_map; > u8 tc_num_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_VNET_BASE_SCH_MODE 2 >
Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
On 2019-02-27 19:29:10 , dann frazier wrote: > From: Peng Li <lipeng321@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1817969 > > 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: Peng Li <lipeng321@huawei.com> > Signed-off-by: Salil Mehta <salil.mehta@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5d497936756fa2a917643ca688585d721dc6d31e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> > --- > .../hisilicon/hns3/hns3pf/hclge_cmd.h | 23 ++--- > .../hisilicon/hns3/hns3pf/hclge_main.c | 84 +++++++++---------- > .../hisilicon/hns3/hns3pf/hclge_main.h | 2 + > 3 files changed, 49 insertions(+), 60 deletions(-) > > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > index ceb3ec0adfc5d..f23042b24c094 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h > @@ -104,7 +104,6 @@ enum hclge_opcode_type { > /* MAC command */ > HCLGE_OPC_CONFIG_MAC_MODE = 0x0301, > HCLGE_OPC_CONFIG_AN_MODE = 0x0304, > - HCLGE_OPC_QUERY_AN_RESULT = 0x0306, > HCLGE_OPC_QUERY_LINK_STATUS = 0x0307, > HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, > HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309, > @@ -236,6 +235,9 @@ enum hclge_opcode_type { > /* Led command */ > HCLGE_OPC_LED_STATUS_CFG = 0xB000, > > + /* SFP command */ > + HCLGE_OPC_SFP_GET_SPEED = 0x7104, > + > /* Error INT commands */ > HCLGE_MAC_COMMON_INT_EN = 0x030E, > HCLGE_TM_SCH_ECC_INT_EN = 0x0829, > @@ -574,20 +576,6 @@ struct hclge_config_mac_speed_dup_cmd { > 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_TQP_ENABLE_B 0 > > @@ -604,6 +592,11 @@ struct hclge_config_auto_neg_cmd { > u8 rsv[20]; > }; > > +struct hclge_sfp_speed_cmd { > + __le32 sfp_speed; > + u32 rsv[5]; > +}; > + > #define HCLGE_MAC_UPLINK_PORT 0x100 > > struct hclge_config_max_frm_size_cmd { > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > index 620fa96313cec..338b9c2210e72 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c > @@ -1983,37 +1983,6 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed, > 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) > { > struct hclge_config_auto_neg_cmd *req; > @@ -2060,6 +2029,7 @@ static int hclge_mac_init(struct hclge_dev *hdev) > struct hclge_mac *mac = &hdev->hw.mac; > int ret; > > + hdev->support_sfp_query = true; > hdev->hw.mac.duplex = HCLGE_MAC_FULL; > ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, > hdev->hw.mac.duplex); > @@ -2169,34 +2139,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) > { > struct hclge_mac mac = hdev->hw.mac; > - u8 duplex; > int speed; > 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. > */ > - if (mac.phydev || !mac.autoneg) > + if (mac.phydev) > return 0; > > - ret = hclge_query_mac_an_speed_dup(hdev, &speed, &duplex); > - if (ret) { > - dev_err(&hdev->pdev->dev, > - "mac autoneg/speed/duplex query failed %d\n", ret); > - return ret; > - } > + /* if IMP does not support get SFP/qSFP speed, return directly */ > + if (!hdev->support_sfp_query) > + return 0; > > - ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); > - if (ret) { > - dev_err(&hdev->pdev->dev, > - "mac speed/duplex config failed %d\n", ret); > + ret = hclge_get_sfp_speed(hdev, &speed); > + if (ret == -EOPNOTSUPP) { > + hdev->support_sfp_query = false; > + return ret; > + } else if (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) > diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > index 47a05c7465a21..6615b85a1c527 100644 > --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h > @@ -212,6 +212,7 @@ enum hclge_evt_cause { > #define HCLGE_MPF_ENBALE 1 > > enum HCLGE_MAC_SPEED { > + HCLGE_MAC_SPEED_UNKNOWN = 0, /* unknown */ > HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */ > HCLGE_MAC_SPEED_100M = 100, /* 100 Mbps */ > HCLGE_MAC_SPEED_1G = 1000, /* 1000 Mbps = 1 Gbps */ > @@ -681,6 +682,7 @@ struct hclge_dev { > u8 hw_tc_map; > u8 tc_num_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_VNET_BASE_SCH_MODE 2 > -- > 2.20.1 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
On Wed, Feb 27, 2019 at 07:29:10PM -0700, dann frazier wrote: > From: Peng Li <lipeng321@huawei.com> > > BugLink: https://bugs.launchpad.net/bugs/1817969 > > 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: Peng Li <lipeng321@huawei.com> > Signed-off-by: Salil Mehta <salil.mehta@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 5d497936756fa2a917643ca688585d721dc6d31e) > Signed-off-by: dann frazier <dann.frazier@canonical.com> Applied to disco/master-next, thanks!
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h index ceb3ec0adfc5d..f23042b24c094 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h @@ -104,7 +104,6 @@ enum hclge_opcode_type { /* MAC command */ HCLGE_OPC_CONFIG_MAC_MODE = 0x0301, HCLGE_OPC_CONFIG_AN_MODE = 0x0304, - HCLGE_OPC_QUERY_AN_RESULT = 0x0306, HCLGE_OPC_QUERY_LINK_STATUS = 0x0307, HCLGE_OPC_CONFIG_MAX_FRM_SIZE = 0x0308, HCLGE_OPC_CONFIG_SPEED_DUP = 0x0309, @@ -236,6 +235,9 @@ enum hclge_opcode_type { /* Led command */ HCLGE_OPC_LED_STATUS_CFG = 0xB000, + /* SFP command */ + HCLGE_OPC_SFP_GET_SPEED = 0x7104, + /* Error INT commands */ HCLGE_MAC_COMMON_INT_EN = 0x030E, HCLGE_TM_SCH_ECC_INT_EN = 0x0829, @@ -574,20 +576,6 @@ struct hclge_config_mac_speed_dup_cmd { 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_TQP_ENABLE_B 0 @@ -604,6 +592,11 @@ struct hclge_config_auto_neg_cmd { u8 rsv[20]; }; +struct hclge_sfp_speed_cmd { + __le32 sfp_speed; + u32 rsv[5]; +}; + #define HCLGE_MAC_UPLINK_PORT 0x100 struct hclge_config_max_frm_size_cmd { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index 620fa96313cec..338b9c2210e72 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -1983,37 +1983,6 @@ static int hclge_cfg_mac_speed_dup_h(struct hnae3_handle *handle, int speed, 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) { struct hclge_config_auto_neg_cmd *req; @@ -2060,6 +2029,7 @@ static int hclge_mac_init(struct hclge_dev *hdev) struct hclge_mac *mac = &hdev->hw.mac; int ret; + hdev->support_sfp_query = true; hdev->hw.mac.duplex = HCLGE_MAC_FULL; ret = hclge_cfg_mac_speed_dup_hw(hdev, hdev->hw.mac.speed, hdev->hw.mac.duplex); @@ -2169,34 +2139,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) { struct hclge_mac mac = hdev->hw.mac; - u8 duplex; int speed; 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. */ - if (mac.phydev || !mac.autoneg) + if (mac.phydev) return 0; - ret = hclge_query_mac_an_speed_dup(hdev, &speed, &duplex); - if (ret) { - dev_err(&hdev->pdev->dev, - "mac autoneg/speed/duplex query failed %d\n", ret); - return ret; - } + /* if IMP does not support get SFP/qSFP speed, return directly */ + if (!hdev->support_sfp_query) + return 0; - ret = hclge_cfg_mac_speed_dup(hdev, speed, duplex); - if (ret) { - dev_err(&hdev->pdev->dev, - "mac speed/duplex config failed %d\n", ret); + ret = hclge_get_sfp_speed(hdev, &speed); + if (ret == -EOPNOTSUPP) { + hdev->support_sfp_query = false; + return ret; + } else if (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) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h index 47a05c7465a21..6615b85a1c527 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -212,6 +212,7 @@ enum hclge_evt_cause { #define HCLGE_MPF_ENBALE 1 enum HCLGE_MAC_SPEED { + HCLGE_MAC_SPEED_UNKNOWN = 0, /* unknown */ HCLGE_MAC_SPEED_10M = 10, /* 10 Mbps */ HCLGE_MAC_SPEED_100M = 100, /* 100 Mbps */ HCLGE_MAC_SPEED_1G = 1000, /* 1000 Mbps = 1 Gbps */ @@ -681,6 +682,7 @@ struct hclge_dev { u8 hw_tc_map; u8 tc_num_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_VNET_BASE_SCH_MODE 2