git: c63d67e137f3 - main - if_bnxt: 50G, 100G and 200G PAM4 support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 07 Mar 2024 19:27:17 UTC
The branch main has been updated by ssaxena:
URL: https://cgit.FreeBSD.org/src/commit/?id=c63d67e137f353f4bc4d0d56bd793f83204a3e1e
commit c63d67e137f353f4bc4d0d56bd793f83204a3e1e
Author: Chandrakanth Patil <chandrakanth.patil@broadcom.com>
AuthorDate: 2024-03-06 13:21:52 +0000
Commit: Sumit Saxena <ssaxena@FreeBSD.org>
CommitDate: 2024-03-07 19:16:39 +0000
if_bnxt: 50G, 100G and 200G PAM4 support
Add support for 50G, 100G and 200G PAM4 support
Reviewed by: imp
Approved by: imp
Differential revision: https://reviews.freebsd.org/D42959
---
sys/dev/bnxt/bnxt.h | 31 ++++++-
sys/dev/bnxt/bnxt_hwrm.c | 78 ++++++++++++++++-
sys/dev/bnxt/bnxt_hwrm.h | 1 +
sys/dev/bnxt/if_bnxt.c | 213 +++++++++++++++++++++++++++++++++++++++--------
4 files changed, 284 insertions(+), 39 deletions(-)
diff --git a/sys/dev/bnxt/bnxt.h b/sys/dev/bnxt/bnxt.h
index 4397e0478a0c..204284d45428 100644
--- a/sys/dev/bnxt/bnxt.h
+++ b/sys/dev/bnxt/bnxt.h
@@ -306,12 +306,33 @@ struct bnxt_link_info {
#define PHY_VER_LEN 3
uint8_t phy_ver[PHY_VER_LEN];
uint8_t phy_type;
+#define BNXT_PHY_STATE_ENABLED 0
+#define BNXT_PHY_STATE_DISABLED 1
+ uint8_t phy_state;
+
uint16_t link_speed;
uint16_t support_speeds;
+ uint16_t support_pam4_speeds;
uint16_t auto_link_speeds;
- uint16_t auto_link_speed;
+ uint16_t auto_pam4_link_speeds;
uint16_t force_link_speed;
+ uint16_t force_pam4_link_speed;
+ bool force_pam4_speed_set_by_user;
+
+ uint16_t advertising;
+ uint16_t advertising_pam4;
+
uint32_t preemphasis;
+ uint16_t support_auto_speeds;
+ uint16_t support_force_speeds;
+ uint16_t support_pam4_auto_speeds;
+ uint16_t support_pam4_force_speeds;
+#define BNXT_SIG_MODE_NRZ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_NRZ
+#define BNXT_SIG_MODE_PAM4 HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4
+ uint8_t req_signal_mode;
+
+ uint8_t active_fec_sig_mode;
+ uint8_t sig_mode;
/* copy of requested setting */
uint8_t autoneg;
@@ -323,6 +344,14 @@ struct bnxt_link_info {
struct hwrm_port_phy_qcfg_output phy_qcfg_resp;
};
+enum bnxt_phy_type {
+ BNXT_MEDIA_CR = 0,
+ BNXT_MEDIA_LR,
+ BNXT_MEDIA_SR,
+ BNXT_MEDIA_KR,
+ BNXT_MEDIA_END
+};
+
enum bnxt_cp_type {
BNXT_DEFAULT,
BNXT_TX,
diff --git a/sys/dev/bnxt/bnxt_hwrm.c b/sys/dev/bnxt/bnxt_hwrm.c
index 97574c768235..481d45350488 100644
--- a/sys/dev/bnxt/bnxt_hwrm.c
+++ b/sys/dev/bnxt/bnxt_hwrm.c
@@ -857,6 +857,7 @@ static void
bnxt_hwrm_set_link_common(struct bnxt_softc *softc,
struct hwrm_port_phy_cfg_input *req)
{
+ struct bnxt_link_info *link_info = &softc->link_info;
uint8_t autoneg = softc->link_info.autoneg;
uint16_t fw_link_speed = softc->link_info.req_link_speed;
@@ -869,8 +870,15 @@ bnxt_hwrm_set_link_common(struct bnxt_softc *softc,
req->flags |=
htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG);
} else {
- req->force_link_speed = htole16(fw_link_speed);
req->flags |= htole32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE);
+
+ if (link_info->force_pam4_speed_set_by_user) {
+ req->force_pam4_link_speed = htole16(fw_link_speed);
+ req->enables |= htole32(HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAM4_LINK_SPEED);
+ link_info->force_pam4_speed_set_by_user = false;
+ } else {
+ req->force_link_speed = htole16(fw_link_speed);
+ }
}
/* tell chimp that the setting takes effect immediately */
@@ -2284,7 +2292,7 @@ bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc)
else
link_info->link_speed = 0;
link_info->force_link_speed = le16toh(resp->force_link_speed);
- link_info->auto_link_speed = le16toh(resp->auto_link_speed);
+ link_info->auto_link_speeds = le16toh(resp->auto_link_speed);
link_info->support_speeds = le16toh(resp->support_speeds);
link_info->auto_link_speeds = le16toh(resp->auto_link_speed_mask);
link_info->preemphasis = le32toh(resp->preemphasis);
@@ -2304,6 +2312,72 @@ bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc)
link_info->phy_addr = resp->eee_config_phy_addr &
HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK;
link_info->module_status = resp->module_status;
+ link_info->support_pam4_speeds = le16toh(resp->support_pam4_speeds);
+ link_info->auto_pam4_link_speeds = le16toh(resp->auto_pam4_link_speed_mask);
+ link_info->force_pam4_link_speed = le16toh(resp->force_pam4_link_speed);
+
+ if (softc->hwrm_spec_code >= 0x10504)
+ link_info->active_fec_sig_mode = resp->active_fec_signal_mode;
+
+exit:
+ BNXT_HWRM_UNLOCK(softc);
+ return rc;
+}
+
+static bool
+bnxt_phy_qcaps_no_speed(struct hwrm_port_phy_qcaps_output *resp)
+{
+ if (!resp->supported_speeds_auto_mode &&
+ !resp->supported_speeds_force_mode &&
+ !resp->supported_pam4_speeds_auto_mode &&
+ !resp->supported_pam4_speeds_force_mode)
+ return true;
+
+ return false;
+}
+
+int bnxt_hwrm_phy_qcaps(struct bnxt_softc *softc)
+{
+ struct bnxt_link_info *link_info = &softc->link_info;
+ struct hwrm_port_phy_qcaps_output *resp =
+ (void *)softc->hwrm_cmd_resp.idi_vaddr;
+ struct hwrm_port_phy_qcaps_input req = {};
+ int rc;
+
+ if (softc->hwrm_spec_code < 0x10201)
+ return 0;
+
+ bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_PORT_PHY_QCAPS);
+
+ BNXT_HWRM_LOCK(softc);
+ rc = _hwrm_send_message(softc, &req, sizeof(req));
+ if (rc)
+ goto exit;
+
+ if (softc->hwrm_spec_code >= 0x10a01) {
+ if (bnxt_phy_qcaps_no_speed(resp)) {
+ link_info->phy_state = BNXT_PHY_STATE_DISABLED;
+ device_printf(softc->dev, "Ethernet link disabled\n");
+ } else if (link_info->phy_state == BNXT_PHY_STATE_DISABLED) {
+ link_info->phy_state = BNXT_PHY_STATE_ENABLED;
+ device_printf(softc->dev, "Ethernet link enabled\n");
+ /* Phy re-enabled, reprobe the speeds */
+ link_info->support_auto_speeds = 0;
+ link_info->support_pam4_auto_speeds = 0;
+ }
+ }
+ if (resp->supported_speeds_auto_mode)
+ link_info->support_auto_speeds =
+ le16toh(resp->supported_speeds_auto_mode);
+ if (resp->supported_speeds_force_mode)
+ link_info->support_force_speeds =
+ le16toh(resp->supported_speeds_force_mode);
+ if (resp->supported_pam4_speeds_auto_mode)
+ link_info->support_pam4_auto_speeds =
+ le16toh(resp->supported_pam4_speeds_auto_mode);
+ if (resp->supported_pam4_speeds_force_mode)
+ link_info->support_pam4_force_speeds =
+ le16toh(resp->supported_pam4_speeds_force_mode);
exit:
BNXT_HWRM_UNLOCK(softc);
diff --git a/sys/dev/bnxt/bnxt_hwrm.h b/sys/dev/bnxt/bnxt_hwrm.h
index 6dd015a15d40..930ff424ecb8 100644
--- a/sys/dev/bnxt/bnxt_hwrm.h
+++ b/sys/dev/bnxt/bnxt_hwrm.h
@@ -116,6 +116,7 @@ int bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year,
uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second,
uint16_t millisecond, uint16_t zone);
int bnxt_hwrm_port_phy_qcfg(struct bnxt_softc *softc);
+int bnxt_hwrm_phy_qcaps(struct bnxt_softc *softc);
uint16_t bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle);
int bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc);
int bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc);
diff --git a/sys/dev/bnxt/if_bnxt.c b/sys/dev/bnxt/if_bnxt.c
index f82d32c3ff5b..4abd8b425444 100644
--- a/sys/dev/bnxt/if_bnxt.c
+++ b/sys/dev/bnxt/if_bnxt.c
@@ -2134,6 +2134,9 @@ bnxt_media_change(if_ctx_t ctx)
if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
return EINVAL;
+ softc->link_info.req_signal_mode =
+ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4;
+
switch (IFM_SUBTYPE(ifm->ifm_media)) {
case IFM_100_T:
softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED;
@@ -2189,10 +2192,22 @@ bnxt_media_change(if_ctx_t ctx)
break;
case IFM_50G_CR2:
case IFM_50G_KR2:
+ case IFM_50G_SR2:
softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED;
softc->link_info.req_link_speed =
HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
break;
+ case IFM_50G_CP:
+ case IFM_50G_LR:
+ case IFM_50G_SR:
+ case IFM_50G_KR_PAM4:
+ softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED;
+ softc->link_info.req_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_50GB;
+ softc->link_info.req_signal_mode =
+ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4;
+ softc->link_info.force_pam4_speed_set_by_user = true;
+ break;
case IFM_100G_CR4:
case IFM_100G_KR4:
case IFM_100G_LR4:
@@ -2201,6 +2216,30 @@ bnxt_media_change(if_ctx_t ctx)
softc->link_info.req_link_speed =
HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB;
break;
+ case IFM_100G_CP2:
+ case IFM_100G_SR2:
+ case IFM_100G_KR_PAM4:
+ case IFM_100G_KR2_PAM4:
+ softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED;
+ softc->link_info.req_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_100GB;
+ softc->link_info.req_signal_mode =
+ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4;
+ softc->link_info.force_pam4_speed_set_by_user = true;
+ break;
+ case IFM_200G_SR4:
+ case IFM_200G_FR4:
+ case IFM_200G_LR4:
+ case IFM_200G_DR4:
+ case IFM_200G_CR4_PAM4:
+ case IFM_200G_KR4_PAM4:
+ softc->link_info.autoneg &= ~BNXT_AUTONEG_SPEED;
+ softc->link_info.req_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_200GB;
+ softc->link_info.force_pam4_speed_set_by_user = true;
+ softc->link_info.req_signal_mode =
+ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4;
+ break;
default:
device_printf(softc->dev,
"Unsupported media type! Using auto\n");
@@ -2941,6 +2980,13 @@ bnxt_probe_phy(struct bnxt_softc *softc)
struct bnxt_link_info *link_info = &softc->link_info;
int rc = 0;
+ rc = bnxt_hwrm_phy_qcaps(softc);
+ if (rc) {
+ device_printf(softc->dev,
+ "Probe phy can't get phy capabilities (rc: %x)\n", rc);
+ return rc;
+ }
+
rc = bnxt_update_link(softc, false);
if (rc) {
device_printf(softc->dev,
@@ -2949,26 +2995,99 @@ bnxt_probe_phy(struct bnxt_softc *softc)
}
bnxt_get_port_module_status(softc);
+
/*initialize the ethool setting copy with NVM settings */
if (link_info->auto_mode != HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
link_info->autoneg |= BNXT_AUTONEG_SPEED;
link_info->req_duplex = link_info->duplex_setting;
+
+ /* NRZ link speed */
if (link_info->autoneg & BNXT_AUTONEG_SPEED)
- link_info->req_link_speed = link_info->auto_link_speed;
+ link_info->req_link_speed = link_info->auto_link_speeds;
else
link_info->req_link_speed = link_info->force_link_speed;
+
+ /* PAM4 link speed */
+ if (link_info->auto_pam4_link_speeds)
+ link_info->req_link_speed = link_info->auto_pam4_link_speeds;
+ if (link_info->force_pam4_link_speed)
+ link_info->req_link_speed = link_info->force_pam4_link_speed;
+
return (rc);
}
+static void
+add_media(struct bnxt_softc *softc, uint8_t media_type, uint16_t supported,
+ uint16_t supported_pam4)
+{
+ switch (media_type) {
+ case BNXT_MEDIA_CR:
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_50G, IFM_50G_CP);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_100G, IFM_100G_CP2);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_200G, IFM_200G_CR4_PAM4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_CR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_CR2);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_CR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_CR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_CR1);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_CX);
+ break;
+
+ case BNXT_MEDIA_LR:
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_50G, IFM_50G_LR);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_200G, IFM_200G_LR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_LR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_LR2);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_LR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_LR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_LR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_LX);
+ break;
+
+ case BNXT_MEDIA_SR:
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_50G, IFM_50G_SR);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_100G, IFM_100G_SR2);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_200G, IFM_200G_SR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_SR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_SR2);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_SR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_SR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_SR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_SX);
+ break;
+
+ case BNXT_MEDIA_KR:
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_50G, IFM_50G_KR_PAM4);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_100G, IFM_100G_KR2_PAM4);
+ BNXT_IFMEDIA_ADD(supported_pam4, PAM4_SPEEDS_200G, IFM_200G_KR4_PAM4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_KR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_KR2);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_KR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_KR4);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_KR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_20GB, IFM_20G_KR2);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_KR);
+ BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_KX);
+ break;
+
+ default:
+ break;
+
+ }
+ return;
+
+}
+
static void
bnxt_add_media_types(struct bnxt_softc *softc)
{
struct bnxt_link_info *link_info = &softc->link_info;
- uint16_t supported;
- uint8_t phy_type = get_phy_type(softc);
+ uint16_t supported = 0, supported_pam4 = 0;
+ uint8_t phy_type = get_phy_type(softc), media_type;
supported = link_info->support_speeds;
+ supported_pam4 = link_info->support_pam4_speeds;
/* Auto is always supported */
ifmedia_add(softc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
@@ -2977,55 +3096,44 @@ bnxt_add_media_types(struct bnxt_softc *softc)
return;
switch (phy_type) {
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASECR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR2:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASECR:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR:
- BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_CR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_CR2);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_CR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_CR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_CR1);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_CX);
+ media_type = BNXT_MEDIA_CR;
break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASELR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASELR:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR:
- BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_LR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_LR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_LR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_LR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_LX);
+ media_type = BNXT_MEDIA_LR;
break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASESR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_50G_BASESR:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4:
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_200G_BASEER4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASESX:
- BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_SR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_SR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_SR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_SR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_SX);
+ media_type = BNXT_MEDIA_SR;
break;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR:
- BNXT_IFMEDIA_ADD(supported, SPEEDS_100GB, IFM_100G_KR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_50GB, IFM_50G_KR2);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_KR4);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_25GB, IFM_25G_KR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_20GB, IFM_20G_KR2);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_KR);
- BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_KX);
+ media_type = BNXT_MEDIA_KR;
break;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE:
@@ -3033,11 +3141,11 @@ bnxt_add_media_types(struct bnxt_softc *softc)
BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_AOC);
BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_XLAUI);
BNXT_IFMEDIA_ADD(supported, SPEEDS_40GB, IFM_40G_XLAUI_AC);
- break;
+ return;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASECX:
BNXT_IFMEDIA_ADD(supported, SPEEDS_1GBHD, IFM_1000_CX);
- break;
+ return;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_1G_BASET:
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET:
@@ -3047,27 +3155,39 @@ bnxt_add_media_types(struct bnxt_softc *softc)
BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_T);
BNXT_IFMEDIA_ADD(supported, SPEEDS_100MB, IFM_100_T);
BNXT_IFMEDIA_ADD(supported, SPEEDS_10MB, IFM_10_T);
- break;
+ return;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX:
BNXT_IFMEDIA_ADD(supported, SPEEDS_10GB, IFM_10G_KR);
BNXT_IFMEDIA_ADD(supported, SPEEDS_2_5GB, IFM_2500_KX);
BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_KX);
- break;
+ return;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY:
BNXT_IFMEDIA_ADD(supported, SPEEDS_1GB, IFM_1000_SGMII);
- break;
+ return;
case HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN:
/* Only Autoneg is supported for TYPE_UNKNOWN */
- device_printf(softc->dev, "Unknown phy type\n");
- break;
+ return;
default:
/* Only Autoneg is supported for new phy type values */
device_printf(softc->dev, "phy type %d not supported by driver\n", phy_type);
- break;
+ return;
+ }
+
+ /* add_media is invoked twice, once with a firmware speed mask of 0 and a valid
+ * value for both NRZ and PAM4 sig mode. This ensures accurate display of all
+ * supported medias and currently configured media in the "ifconfig -m" output
+ */
+
+ if (link_info->sig_mode == BNXT_SIG_MODE_PAM4) {
+ add_media(softc, media_type, supported, 0);
+ add_media(softc, media_type, 0, supported_pam4);
+ } else {
+ add_media(softc, media_type, 0, supported_pam4);
+ add_media(softc, media_type, supported, 0);
}
return;
@@ -3166,6 +3286,7 @@ bnxt_report_link(struct bnxt_softc *softc)
{
struct bnxt_link_info *link_info = &softc->link_info;
const char *duplex = NULL, *flow_ctrl = NULL;
+ const char *signal_mode = "";
if (link_info->link_up == link_info->last_link_up) {
if (!link_info->link_up)
@@ -3190,9 +3311,27 @@ bnxt_report_link(struct bnxt_softc *softc)
flow_ctrl = "FC - receive";
else
flow_ctrl = "FC - none";
+
+ if (softc->link_info.phy_qcfg_resp.option_flags &
+ HWRM_PORT_PHY_QCFG_OUTPUT_OPTION_FLAGS_SIGNAL_MODE_KNOWN) {
+ uint8_t sig_mode = softc->link_info.active_fec_sig_mode &
+ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_MASK;
+ switch (sig_mode) {
+ case BNXT_SIG_MODE_NRZ:
+ signal_mode = "(NRZ) ";
+ break;
+ case BNXT_SIG_MODE_PAM4:
+ signal_mode = "(PAM4) ";
+ break;
+ default:
+ break;
+ }
+ link_info->sig_mode = sig_mode;
+ }
+
iflib_link_state_change(softc->ctx, LINK_STATE_UP,
IF_Gbps(100));
- device_printf(softc->dev, "Link is UP %s, %s - %d Mbps \n", duplex,
+ device_printf(softc->dev, "Link is UP %s %s, %s - %d Mbps \n", duplex, signal_mode,
flow_ctrl, (link_info->link_speed * 100));
} else {
iflib_link_state_change(softc->ctx, LINK_STATE_DOWN,
@@ -3378,7 +3517,7 @@ bnxt_def_cp_task(void *context)
softc->db_ops.bnxt_db_rx_cq(cpr, 1);
}
-static uint8_t
+uint8_t
get_phy_type(struct bnxt_softc *softc)
{
struct bnxt_link_info *link_info = &softc->link_info;
@@ -3471,6 +3610,8 @@ bnxt_get_baudrate(struct bnxt_link_info *link)
return IF_Gbps(100);
case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB:
return IF_Mbps(10);
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB:
+ return IF_Gbps(200);
}
return IF_Gbps(100);
}