Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+8 −15
Original line number Diff line number Diff line
@@ -90,7 +90,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,
@@ -212,6 +211,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_TM_SCH_ECC_INT_EN		= 0x0829,
	HCLGE_TM_SCH_ECC_ERR_RINT_CMD	= 0x082d,
@@ -544,20 +546,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

@@ -574,6 +562,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 {
+39 −45
Original line number Diff line number Diff line
@@ -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);
}

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;
@@ -1973,6 +1942,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);
@@ -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)
{
	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)
+2 −0
Original line number Diff line number Diff line
@@ -155,6 +155,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 */
@@ -624,6 +625,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