APPLIED(B,C): [PATCH][Disco][SRU Cosmic][SRU Bionic] net: hns3: Config NIC port speed same as that of optical module
Khaled Elmously
khalid.elmously at canonical.com
Thu Feb 28 17:43:16 UTC 2019
On 2019-02-27 19:29:10 , dann frazier wrote:
> From: Peng Li <lipeng321 at 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 at huawei.com>
> Signed-off-by: Salil Mehta <salil.mehta at huawei.com>
> Signed-off-by: David S. Miller <davem at davemloft.net>
> (cherry picked from commit 5d497936756fa2a917643ca688585d721dc6d31e)
> Signed-off-by: dann frazier <dann.frazier at 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 at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
More information about the kernel-team
mailing list