net/bnxt: add support for 200G PAM4 link
diff mbox series

Message ID 20200924044819.96792-1-ajit.khaparde@broadcom.com
State Superseded
Delegated to: Ajit Khaparde
Headers show
Series
  • net/bnxt: add support for 200G PAM4 link
Related show

Checks

Context Check Description
ci/travis-robot success Travis build: passed
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Ajit Khaparde Sept. 24, 2020, 4:48 a.m. UTC
Thor based NICs can support PAM4 as wells as NRZ link negotiation.
With this patch we are adding support for 200G link speeds based on
PAM4 signaling. While PAM4 can negotiate speeds for 50G and 100G as
well, the PMD will use NRZ signalling for these speeds.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   7 ++
 drivers/net/bnxt/bnxt_ethdev.c         |   6 +-
 drivers/net/bnxt/bnxt_hwrm.c           |  77 +++++++++---
 drivers/net/bnxt/bnxt_hwrm.h           |   7 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 168 +++++++++++++++++++------
 5 files changed, 214 insertions(+), 51 deletions(-)

Patch
diff mbox series

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 3dded37bb..19d4774c5 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -292,6 +292,13 @@  struct bnxt_link_info {
 	uint32_t		preemphasis;
 	uint8_t			phy_type;
 	uint8_t			media_type;
+	uint16_t		support_auto_speeds;
+	uint8_t			link_signal_mode;
+	uint16_t		force_pam4_link_speed;
+	uint16_t		support_pam4_speeds;
+	uint16_t		auto_pam4_link_speeds;
+	uint16_t		support_pam4_auto_speeds;
+	uint8_t			req_signal_mode;
 };
 
 #define BNXT_COS_QUEUE_COUNT	8
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index b0718c145..60de6ff6d 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -864,7 +864,11 @@  uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
 		speed_capa |= ETH_LINK_SPEED_50G;
 	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB)
 		speed_capa |= ETH_LINK_SPEED_100G;
-	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_200GB)
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G)
+		speed_capa |= ETH_LINK_SPEED_50G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G)
+		speed_capa |= ETH_LINK_SPEED_100G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G)
 		speed_capa |= ETH_LINK_SPEED_200G;
 
 	if (bp->link_info->auto_mode ==
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index f25cdf05c..a9d5fd77e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1260,16 +1260,24 @@  static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 		}
 
 		req.flags = rte_cpu_to_le_32(conf->phy_flags);
-		req.force_link_speed = rte_cpu_to_le_16(conf->link_speed);
-		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
 		/*
 		 * Note, ChiMP FW 20.2.1 and 20.2.2 return an error when we set
 		 * any auto mode, even "none".
 		 */
 		if (!conf->link_speed) {
 			/* No speeds specified. Enable AutoNeg - all speeds */
+			enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
 			req.auto_mode =
 				HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS;
+		} else {
+			if (bp->link_info->link_signal_mode) {
+				enables |=
+				HWRM_PORT_PHY_CFG_IN_EN_FORCE_PAM4_LINK_SPEED;
+				req.force_pam4_link_speed =
+					rte_cpu_to_le_16(conf->link_speed);
+			}
+			req.force_link_speed =
+					rte_cpu_to_le_16(conf->link_speed);
 		}
 		/* AutoNeg - Advertise speeds specified. */
 		if (conf->auto_link_speed_mask &&
@@ -1278,9 +1286,20 @@  static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 				HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
 			req.auto_link_speed_mask =
 				conf->auto_link_speed_mask;
-			enables |=
-			HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
+			if (conf->auto_pam4_link_speeds) {
+				enables |=
+				HWRM_PORT_PHY_CFG_IN_EN_AUTO_PAM4_LINK_SPD_MASK;
+				req.auto_link_pam4_speed_mask =
+					conf->auto_pam4_link_speeds;
+			} else {
+				enables |=
+				HWRM_PORT_PHY_CFG_IN_EN_AUTO_LINK_SPEED_MASK;
+			}
 		}
+		if (conf->auto_link_speed &&
+		!(conf->phy_flags & HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE))
+			enables |=
+				HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED;
 
 		req.auto_duplex = conf->duplex;
 		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
@@ -1340,7 +1359,13 @@  static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
 	link_info->phy_ver[0] = resp->phy_maj;
 	link_info->phy_ver[1] = resp->phy_min;
 	link_info->phy_ver[2] = resp->phy_bld;
-
+	link_info->link_signal_mode = rte_le_to_cpu_16(resp->link_signal_mode);
+	link_info->force_pam4_link_speed =
+			rte_le_to_cpu_16(resp->force_pam4_link_speed);
+	link_info->support_pam4_speeds =
+			rte_le_to_cpu_16(resp->support_pam4_speeds);
+	link_info->auto_pam4_link_speeds =
+			rte_le_to_cpu_16(resp->auto_pam4_link_speed_mask);
 	HWRM_UNLOCK();
 
 	PMD_DRV_LOG(DEBUG, "Link Speed:%d,Auto:%d:%x:%x,Support:%x,Force:%x\n",
@@ -1355,6 +1380,7 @@  int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp)
 	int rc = 0;
 	struct hwrm_port_phy_qcaps_input req = {0};
 	struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_link_info *link_info = bp->link_info;
 
 	if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp))
 		return 0;
@@ -1366,6 +1392,12 @@  int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp)
 	HWRM_CHECK_RESULT();
 
 	bp->port_cnt = resp->port_cnt;
+	if (resp->supported_speeds_auto_mode)
+		link_info->support_auto_speeds =
+			rte_le_to_cpu_16(resp->supported_speeds_auto_mode);
+	if (resp->supported_pam4_speeds_auto_mode)
+		link_info->support_pam4_auto_speeds =
+			rte_le_to_cpu_16(resp->supported_pam4_speeds_auto_mode);
 
 	HWRM_UNLOCK();
 
@@ -2773,10 +2805,11 @@  static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
 
 static uint16_t bnxt_check_eth_link_autoneg(uint32_t conf_link)
 {
-	return (conf_link & ETH_LINK_SPEED_FIXED) ? 0 : 1;
+	return !conf_link;
 }
 
-static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
+static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
+					  uint16_t pam4_link)
 {
 	uint16_t eth_link_speed = 0;
 
@@ -2815,16 +2848,18 @@  static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
 			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB;
 		break;
 	case ETH_LINK_SPEED_50G:
-		eth_link_speed =
+		eth_link_speed = pam4_link ?
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_50GB :
 			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
 		break;
 	case ETH_LINK_SPEED_100G:
-		eth_link_speed =
+		eth_link_speed = pam4_link ?
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_100GB :
 			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB;
 		break;
 	case ETH_LINK_SPEED_200G:
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_200GB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_200GB;
 		break;
 	default:
 		PMD_DRV_LOG(ERR,
@@ -2911,7 +2946,7 @@  bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed)
 	if (link_speed & ETH_LINK_SPEED_100G)
 		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100GB;
 	if (link_speed & ETH_LINK_SPEED_200G)
-		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_200GB;
+		ret |= HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_200GB;
 	return ret;
 }
 
@@ -2985,12 +3020,16 @@  int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link)
 	int rc = 0;
 	struct bnxt_link_info *link_info = bp->link_info;
 
+	rc = bnxt_hwrm_port_phy_qcaps(bp);
+	if (rc)
+		PMD_DRV_LOG(ERR, "Get link config failed with rc %d\n", rc);
+
 	rc = bnxt_hwrm_port_phy_qcfg(bp, link_info);
 	if (rc) {
-		PMD_DRV_LOG(ERR,
-			"Get link config failed with rc %d\n", rc);
+		PMD_DRV_LOG(ERR, "Get link config failed with rc %d\n", rc);
 		goto exit;
 	}
+
 	if (link_info->link_speed)
 		link->link_speed =
 			bnxt_parse_hw_link_speed(link_info->link_speed);
@@ -3035,7 +3074,8 @@  int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 		autoneg = 0;
 	}
 
-	speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
+	speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds,
+					  bp->link_info->link_signal_mode);
 	link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
 	/* Autoneg can be done only when the FW allows.
 	 * When user configures fixed speed of 40G and later changes to
@@ -3066,6 +3106,15 @@  int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 		/* If user wants a particular speed try that first. */
 		if (speed)
 			link_req.link_speed = speed;
+		else if (bp->link_info->force_pam4_link_speed)
+			link_req.link_speed =
+				bp->link_info->force_pam4_link_speed;
+		else if (bp->link_info->auto_pam4_link_speeds)
+			link_req.link_speed =
+				bp->link_info->auto_pam4_link_speeds;
+		else if (bp->link_info->support_pam4_speeds)
+			link_req.link_speed =
+				bp->link_info->support_pam4_speeds;
 		else if (bp->link_info->force_link_speed)
 			link_req.link_speed = bp->link_info->force_link_speed;
 		else
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 77ae0b7f0..e98b1fe41 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -48,6 +48,13 @@  struct hwrm_func_qstats_output;
 #define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MAXIMAL \
 	HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MAXIMAL
 
+#define HWRM_PORT_PHY_CFG_IN_EN_FORCE_PAM4_LINK_SPEED \
+	HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAM4_LINK_SPEED
+#define HWRM_PORT_PHY_CFG_IN_EN_AUTO_PAM4_LINK_SPD_MASK \
+	HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAM4_LINK_SPEED_MASK
+#define HWRM_PORT_PHY_CFG_IN_EN_AUTO_LINK_SPEED_MASK \
+	HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK
+
 #define HWRM_CFA_ADV_FLOW_MGNT_QCAPS_L2_HDR_SRC_FILTER_EN \
 HWRM_CFA_ADV_FLOW_MGNT_QCAPS_OUTPUT_FLAGS_L2_HEADER_SOURCE_FIELDS_SUPPORTED
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 6ac49ee5e..dec02e710 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -15531,6 +15531,18 @@  struct hwrm_port_phy_cfg_input {
 	 */
 	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_TX_LPI_TIMER \
 		UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the force_pam4_link_speed field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAM4_LINK_SPEED \
+		UINT32_C(0x800)
+	/*
+	 * This bit must be '1' for the auto_pam4_link_speed_mask field to
+	 * be configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAM4_LINK_SPEED_MASK \
+		UINT32_C(0x1000)
 	/* Port ID of port that is to be configured. */
 	uint16_t	port_id;
 	/*
@@ -15559,8 +15571,6 @@  struct hwrm_port_phy_cfg_input {
 	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB  UINT32_C(0x1f4)
 	/* 100Gb link speed */
 	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_200GB UINT32_C(0x7d0)
 	/* 10Mb link speed */
 	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB  UINT32_C(0xffff)
 	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_LAST \
@@ -15585,8 +15595,9 @@  struct hwrm_port_phy_cfg_input {
 	 */
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW UINT32_C(0x3)
 	/*
-	 * Select the speeds based on the corresponding link speed mask value
-	 * that is provided.
+	 * Select the speeds based on the corresponding link speed mask values
+	 * that are provided. The included speeds are specified in the
+	 * auto_link_speed and auto_pam4_link_speed fields.
 	 */
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK   UINT32_C(0x4)
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_LAST \
@@ -15665,8 +15676,6 @@  struct hwrm_port_phy_cfg_input {
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB  UINT32_C(0x1f4)
 	/* 100Gb link speed */
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_200GB UINT32_C(0x7d0)
 	/* 10Mb link speed */
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB  UINT32_C(0xffff)
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_LAST \
@@ -15719,9 +15728,6 @@  struct hwrm_port_phy_cfg_input {
 	/* 10Mb link speed (Full-duplex) */
 	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB \
 		UINT32_C(0x2000)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_200GB \
-		UINT32_C(0x4000)
 	/* This value controls the wirespeed feature. */
 	uint8_t	wirespeed;
 	/* Wirespeed feature is disabled. */
@@ -15832,7 +15838,15 @@  struct hwrm_port_phy_cfg_input {
 	uint32_t	tx_lpi_timer;
 	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK UINT32_C(0xffffff)
 	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT 0
-	uint32_t	unused_3;
+	/* This field specifies which PAM4 speeds are enabled for auto mode. */
+	uint16_t	auto_link_pam4_speed_mask;
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_PAM4_SPEED_MASK_50G \
+		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_PAM4_SPEED_MASK_100G \
+		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_PAM4_SPEED_MASK_200G \
+		UINT32_C(0x4)
+	uint8_t	unused_2[2];
 } __rte_packed;
 
 /* hwrm_port_phy_cfg_output (size:128b/16B) */
@@ -15925,7 +15939,7 @@  struct hwrm_port_phy_qcfg_input {
 	uint8_t	unused_0[6];
 } __rte_packed;
 
-/* hwrm_port_phy_qcfg_output (size:768b/96B) */
+/* hwrm_port_phy_qcfg_output (size:832b/104B) */
 struct hwrm_port_phy_qcfg_output {
 	/* The specific error status for the command. */
 	uint16_t	error_code;
@@ -15945,8 +15959,22 @@  struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK    UINT32_C(0x2)
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LAST \
 		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK
-	uint8_t	unused_0;
-	/* This value indicates the current link speed of the connection. */
+	/*
+	 * This value indicates the current link signaling mode of the
+	 * connection.
+	 */
+	uint8_t	link_signal_mode;
+	/* NRZ signaling */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL_MODE_NRZ  UINT32_C(0x0)
+	/* PAM4 signaling */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL_MODE_PAM4 UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL_MODE_LAST \
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL_MODE_PAM4
+	/*
+	 * This value indicates the current link speed of the connection.
+	 * The link_signal_mode field indicates if the link is using
+	 * NRZ or PAM4 signaling.
+	 */
 	uint16_t	link_speed;
 	/* 100Mb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB UINT32_C(0x1)
@@ -16003,7 +16031,7 @@  struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX     UINT32_C(0x2)
 	/*
 	 * The supported speeds for the port. This is a bit mask.
-	 * For each speed that is supported, the corrresponding
+	 * For each speed that is supported, the corresponding
 	 * bit will be set to '1'.
 	 */
 	uint16_t	support_speeds;
@@ -16049,9 +16077,6 @@  struct hwrm_port_phy_qcfg_output {
 	/* 10Mb link speed (Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB \
 		UINT32_C(0x2000)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_200GB \
-		UINT32_C(0x4000)
 	/*
 	 * Current setting of forced link speed.
 	 * When the link speed is not being forced, this
@@ -16081,9 +16106,6 @@  struct hwrm_port_phy_qcfg_output {
 	/* 100Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB \
 		UINT32_C(0x3e8)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_200GB \
-		UINT32_C(0x7d0)
 	/* 10Mb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB \
 		UINT32_C(0xffff)
@@ -16170,8 +16192,6 @@  struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB  UINT32_C(0x1f4)
 	/* 100Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_200GB UINT32_C(0x7d0)
 	/* 10Mb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB \
 		UINT32_C(0xffff)
@@ -16227,9 +16247,6 @@  struct hwrm_port_phy_qcfg_output {
 	/* 10Mb link speed (Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MB \
 		UINT32_C(0x2000)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_200GB \
-		UINT32_C(0x4000)
 	/* Current setting for wirespeed. */
 	uint8_t	wirespeed;
 	/* Wirespeed feature is disabled. */
@@ -16836,7 +16853,64 @@  struct hwrm_port_phy_qcfg_output {
 	 * part number is not available.
 	 */
 	char	phy_vendor_partnumber[16];
-	uint8_t	unused_2[7];
+	/*
+	 * The supported PAM4 speeds for the port. This is a bit mask.
+	 * For each speed that is supported, the corresponding
+	 * bit will be set to '1'.
+	 */
+	uint16_t	support_pam4_speeds;
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G \
+		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G \
+		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_200G \
+		UINT32_C(0x4)
+	/*
+	 * Current setting of forced PAM4 link speed.
+	 * When the link speed is not being forced, this
+	 * value shall be set to 0.
+	 */
+	uint16_t	force_pam4_link_speed;
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAM4_LINK_SPEED_50GB \
+		UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAM4_LINK_SPEED_100GB \
+		UINT32_C(0x3e8)
+	/* 200Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAM4_LINK_SPEED_200GB \
+		UINT32_C(0x7d0)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAM4_LINK_SPEED_LAST \
+		HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAM4_LINK_SPEED_200GB
+	/*
+	 * Current setting for auto_pam4_link_speed_mask that is used to
+	 * advertise speeds during autonegotiation.
+	 * This field is only valid when auto_mode is set to "mask".
+	 * The speeds specified in this field shall be a subset of
+	 * supported speeds on this port.
+	 */
+	uint16_t	auto_pam4_link_speed_mask;
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAM4_LINK_SPEED_MASK_50G \
+		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAM4_LINK_SPEED_MASK_100G \
+		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAM4_LINK_SPEED_MASK_200G \
+		UINT32_C(0x4)
+	/*
+	 * The advertised PAM4 speeds for the port by the link partner.
+	 * Each advertised speed will be set to '1'.
+	 */
+	uint16_t	link_partner_pam4_adv_speeds;
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_PAM4_ADV_SPEEDS_50GB \
+		UINT32_C(0x1)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_PAM4_ADV_SPEEDS_100GB \
+		UINT32_C(0x2)
+	/* 200Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_PAM4_ADV_SPEEDS_200GB \
+		UINT32_C(0x4)
+	uint8_t	unused_0[7];
 	/*
 	 * This field is used in Output records to indicate that the output
 	 * is completely written to RAM.  This field should be read as '1'
@@ -19228,7 +19302,7 @@  struct hwrm_port_phy_qcaps_input {
 	uint8_t	unused_0[6];
 } __rte_packed;
 
-/* hwrm_port_phy_qcaps_output (size:192b/24B) */
+/* hwrm_port_phy_qcaps_output (size:256b/32B) */
 struct hwrm_port_phy_qcaps_output {
 	/* The specific error status for the command. */
 	uint16_t	error_code;
@@ -19348,9 +19422,6 @@  struct hwrm_port_phy_qcaps_output {
 	/* 10Mb link speed (Full-duplex) */
 	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_10MB \
 		UINT32_C(0x2000)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_FORCE_MODE_200GB \
-		UINT32_C(0x4000)
 	/*
 	 * This is a bit mask to indicate what speeds are supported
 	 * for autonegotiation on this link.
@@ -19400,9 +19471,6 @@  struct hwrm_port_phy_qcaps_output {
 	/* 10Mb link speed (Full-duplex) */
 	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_10MB \
 		UINT32_C(0x2000)
-	/* 200Gb link speed */
-	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_SPEEDS_AUTO_MODE_200GB \
-		UINT32_C(0x4000)
 	/*
 	 * This is a bit mask to indicate what speeds are supported
 	 * for EEE on this link.
@@ -19457,6 +19525,36 @@  struct hwrm_port_phy_qcaps_output {
 	#define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_MASK \
 		UINT32_C(0xffffff)
 	#define HWRM_PORT_PHY_QCAPS_OUTPUT_TX_LPI_TIMER_HIGH_SFT 0
+	/*
+	 * Reserved field. The HWRM shall set this field to 0.
+	 * An HWRM client shall ignore this field.
+	 */
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_RSVD_MASK \
+		UINT32_C(0xff000000)
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_RSVD_SFT              24
+	/*
+	 * This field is used to advertise which PAM4 speeds are supported
+	 * in auto mode.
+	 */
+	uint16_t	supported_pam4_speeds_auto_mode;
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_50G \
+		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_100G \
+		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_AUTO_MODE_200G \
+		UINT32_C(0x4)
+	/*
+	 * This field is used to advertise which PAM4 speeds are supported
+	 * in forced mode.
+	 */
+	uint16_t	supported_pam4_speeds_force_mode;
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_50G \
+		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_100G \
+		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_QCAPS_OUTPUT_SUPPORTED_PAM4_SPEEDS_FORCE_MODE_200G \
+		UINT32_C(0x4)
+	uint8_t	unused_0[3];
 	/*
 	 * This field is used in Output records to indicate that the output
 	 * is completely written to RAM.  This field should be read as '1'
@@ -19464,9 +19562,7 @@  struct hwrm_port_phy_qcaps_output {
 	 * When writing a command completion or response to an internal processor,
 	 * the order of writes has to be such that this field is written last.
 	 */
-	#define HWRM_PORT_PHY_QCAPS_OUTPUT_VALID_MASK \
-		UINT32_C(0xff000000)
-	#define HWRM_PORT_PHY_QCAPS_OUTPUT_VALID_SFT             24
+	uint8_t	valid;
 } __rte_packed;
 
 /****************************