Index: sys/dev/bnxt/bnxt_en/bnxt.h =================================================================== --- sys/dev/bnxt/bnxt_en/bnxt.h +++ sys/dev/bnxt/bnxt_en/bnxt.h @@ -466,6 +466,12 @@ struct hwrm_port_phy_qcfg_output phy_qcfg_resp; }; +struct port_speeds { + uint16_t nrz_speeds; + uint16_t pam4_56_speeds; + uint16_t pam4_112_speeds; +}; + enum bnxt_phy_type { BNXT_MEDIA_CR = 0, BNXT_MEDIA_LR, @@ -1449,5 +1455,6 @@ int bnxt_hwrm_reserve_rings(struct bnxt_softc *softc); void bnxt_set_flags_by_devid(struct bnxt_softc *softc); static inline bool bnxt_is_vf_device(uint16_t device_id); +void populate_port_speeds(uint16_t support_speeds2, struct port_speeds *speeds); #endif /* _BNXT_H */ Index: sys/dev/bnxt/bnxt_en/if_bnxt.c =================================================================== --- sys/dev/bnxt/bnxt_en/if_bnxt.c +++ sys/dev/bnxt/bnxt_en/if_bnxt.c @@ -4730,16 +4730,49 @@ } +void populate_port_speeds(uint16_t support_speeds2, struct port_speeds *speeds) +{ + speeds->nrz_speeds = 0; + speeds->pam4_56_speeds = 0; + speeds->pam4_112_speeds = 0; + + speeds->nrz_speeds |= (support_speeds2 & ( + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_1GB | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_10GB | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_25GB | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_40GB | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB + )); + + speeds->pam4_56_speeds |= (support_speeds2 & ( + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB_PAM4_56 | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_56 | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_56 | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_56 + )); + + speeds->pam4_112_speeds |= (support_speeds2 & ( + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_112 | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_112 | + HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_112 + )); +} + static void bnxt_add_media_types(struct bnxt_softc *softc) { struct bnxt_link_info *link_info = &softc->link_info; uint16_t supported_NRZ_speeds = 0, supported_pam4_speeds = 0, supported_speeds2 = 0; uint8_t phy_type = get_phy_type(softc), media_type; + struct port_speeds *speeds = NULL; + + speeds = (struct port_speeds *)malloc(sizeof(struct port_speeds), M_DEVBUF, M_NOWAIT | M_ZERO); supported_NRZ_speeds = link_info->support_speeds; supported_speeds2 = link_info->support_speeds2; supported_pam4_speeds = link_info->support_pam4_speeds; + populate_port_speeds(supported_speeds2, speeds); /* Auto is always supported */ ifmedia_add(softc->media, IFM_ETHER | IFM_AUTO, 0, NULL); @@ -4854,24 +4887,36 @@ device_printf(softc->dev, "phy type %d not supported by driver\n", phy_type); break; } - - switch (link_info->sig_mode) { - case BNXT_SIG_MODE_NRZ: - if (supported_NRZ_speeds != 0) + if (!BNXT_CHIP_P7(softc)) { + if (link_info->sig_mode == BNXT_SIG_MODE_PAM4) { add_media(softc, media_type, supported_NRZ_speeds, 0, 0); - else - add_media(softc, media_type, 0, 0, supported_speeds2); - break; - case BNXT_SIG_MODE_PAM4: - if (supported_pam4_speeds != 0) add_media(softc, media_type, 0, supported_pam4_speeds, 0); - else - add_media(softc, media_type, 0, 0, supported_speeds2); - break; - case BNXT_SIG_MODE_PAM4_112: - add_media(softc, media_type, 0, 0, supported_speeds2); - break; + } else { + add_media(softc, media_type, 0, supported_pam4_speeds, 0); + add_media(softc, media_type, supported_NRZ_speeds, 0, 0); + } + } + + if (BNXT_CHIP_P7(softc)) { + switch (link_info->sig_mode) { + case BNXT_SIG_MODE_NRZ: + add_media(softc, media_type, 0, 0, speeds->pam4_56_speeds); + add_media(softc, media_type, 0, 0, speeds->pam4_112_speeds); + add_media(softc, media_type, 0, 0, speeds->nrz_speeds); + break; + case BNXT_SIG_MODE_PAM4: + add_media(softc, media_type, 0, 0, speeds->nrz_speeds); + add_media(softc, media_type, 0, 0, speeds->pam4_112_speeds); + add_media(softc, media_type, 0, 0, speeds->pam4_56_speeds); + break; + case BNXT_SIG_MODE_PAM4_112: + add_media(softc, media_type, 0, 0, speeds->nrz_speeds); + add_media(softc, media_type, 0, 0, speeds->pam4_56_speeds); + add_media(softc, media_type, 0, 0, speeds->pam4_112_speeds); + break; + } } + free(speeds, M_DEVBUF); return; }