}
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 &&
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;
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",
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;
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();
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;
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,
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;
}
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);
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
/* 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
*/
#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;
/*
#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 \
*/
#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 \
#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 \
/* 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. */
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) */
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;
#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)
#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;
/* 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
/* 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)
#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)
/* 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. */
* 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'
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;
/* 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.
/* 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.
#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'
* 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;
/****************************