diff mbox series

[Disco,SRU,Cosmic,SRU,Bionic] net: hns3: Config NIC port speed same as that of optical module

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

Commit Message

dann frazier Feb. 28, 2019, 2:29 a.m. UTC
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(-)

Comments

Stefan Bader Feb. 28, 2019, 2:46 p.m. UTC | #1
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
>
Marcelo Henrique Cerri Feb. 28, 2019, 3:22 p.m. UTC | #2
Acked-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
Khalid Elmously Feb. 28, 2019, 5:43 p.m. UTC | #3
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
Seth Forshee March 4, 2019, 1:22 p.m. UTC | #4
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 mbox series

Patch

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