The branch main has been updated by ssaxena:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c63d67e137f353f4bc4d0d56bd793f83204a3e1e

commit c63d67e137f353f4bc4d0d56bd793f83204a3e1e
Author:     Chandrakanth Patil <[email protected]>
AuthorDate: 2024-03-06 13:21:52 +0000
Commit:     Sumit Saxena <[email protected]>
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);
 }

Reply via email to