Commit 047a2d38 authored by Michael Chan's avatar Michael Chan Committed by Jakub Kicinski
Browse files

bnxt_en: Report the new ethtool link modes in the new firmware interface



Add new look up entries to convert the new supported speeds, advertised
speeds, etc to ethtool link modes.

Reviewed-by: default avatarDamodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Link: https://lore.kernel.org/r/20231201223924.26955-15-michael.chan@broadcom.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7b60cf2b
Loading
Loading
Loading
Loading
+151 −20
Original line number Diff line number Diff line
@@ -1577,6 +1577,22 @@ static const enum bnxt_media_type bnxt_phy_types[] = {
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR2] = BNXT_MEDIA_SR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR2] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER2] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASECR] = BNXT_MEDIA_CR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASESR] = BNXT_MEDIA_SR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASELR] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_100G_BASEER] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASECR2] = BNXT_MEDIA_CR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASESR2] = BNXT_MEDIA_SR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASELR2] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_200G_BASEER2] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR8] = BNXT_MEDIA_CR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR8] = BNXT_MEDIA_SR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR8] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER8] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASECR4] = BNXT_MEDIA_CR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASESR4] = BNXT_MEDIA_SR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASELR4] = BNXT_MEDIA_LR_ER_FR,
	[PORT_PHY_QCFG_RESP_PHY_TYPE_400G_BASEER4] = BNXT_MEDIA_LR_ER_FR,
};

static enum bnxt_media_type
@@ -1604,6 +1620,7 @@ enum bnxt_link_speed_indices {
	BNXT_LINK_SPEED_50GB_IDX,
	BNXT_LINK_SPEED_100GB_IDX,
	BNXT_LINK_SPEED_200GB_IDX,
	BNXT_LINK_SPEED_400GB_IDX,
	__BNXT_LINK_SPEED_END
};

@@ -1615,9 +1632,21 @@ static enum bnxt_link_speed_indices bnxt_fw_speed_idx(u16 speed)
	case BNXT_LINK_SPEED_10GB: return BNXT_LINK_SPEED_10GB_IDX;
	case BNXT_LINK_SPEED_25GB: return BNXT_LINK_SPEED_25GB_IDX;
	case BNXT_LINK_SPEED_40GB: return BNXT_LINK_SPEED_40GB_IDX;
	case BNXT_LINK_SPEED_50GB: return BNXT_LINK_SPEED_50GB_IDX;
	case BNXT_LINK_SPEED_100GB: return BNXT_LINK_SPEED_100GB_IDX;
	case BNXT_LINK_SPEED_200GB: return BNXT_LINK_SPEED_200GB_IDX;
	case BNXT_LINK_SPEED_50GB:
	case BNXT_LINK_SPEED_50GB_PAM4:
		return BNXT_LINK_SPEED_50GB_IDX;
	case BNXT_LINK_SPEED_100GB:
	case BNXT_LINK_SPEED_100GB_PAM4:
	case BNXT_LINK_SPEED_100GB_PAM4_112:
		return BNXT_LINK_SPEED_100GB_IDX;
	case BNXT_LINK_SPEED_200GB:
	case BNXT_LINK_SPEED_200GB_PAM4:
	case BNXT_LINK_SPEED_200GB_PAM4_112:
		return BNXT_LINK_SPEED_200GB_IDX;
	case BNXT_LINK_SPEED_400GB:
	case BNXT_LINK_SPEED_400GB_PAM4:
	case BNXT_LINK_SPEED_400GB_PAM4_112:
		return BNXT_LINK_SPEED_400GB_IDX;
	default: return BNXT_LINK_SPEED_UNKNOWN;
	}
}
@@ -1690,6 +1719,12 @@ bnxt_link_modes[__BNXT_LINK_SPEED_END][BNXT_SIG_MODE_MAX][__BNXT_MEDIA_END] = {
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT,
		},
		[BNXT_SIG_MODE_PAM4_112] = {
			[BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_100000baseCR_Full_BIT,
			[BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_100000baseSR_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_100000baseKR_Full_BIT,
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
		},
	},
	[BNXT_LINK_SPEED_200GB_IDX] = {
		[BNXT_SIG_MODE_PAM4] = {
@@ -1698,6 +1733,26 @@ bnxt_link_modes[__BNXT_LINK_SPEED_END][BNXT_SIG_MODE_MAX][__BNXT_MEDIA_END] = {
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT,
		},
		[BNXT_SIG_MODE_PAM4_112] = {
			[BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT,
			[BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT,
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
		},
	},
	[BNXT_LINK_SPEED_400GB_IDX] = {
		[BNXT_SIG_MODE_PAM4] = {
			[BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT,
			[BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT,
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
		},
		[BNXT_SIG_MODE_PAM4_112] = {
			[BNXT_MEDIA_CR] = ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT,
			[BNXT_MEDIA_KR] = ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT,
			[BNXT_MEDIA_SR] = ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT,
			[BNXT_MEDIA_LR_ER_FR] = ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
		},
	},
};

@@ -1762,7 +1817,8 @@ static void bnxt_get_ethtool_modes(struct bnxt_link_info *link_info,
				 lk_ksettings->link_modes.supported);
	}

	if (link_info->support_auto_speeds || link_info->support_pam4_auto_speeds)
	if (link_info->support_auto_speeds || link_info->support_auto_speeds2 ||
	    link_info->support_pam4_auto_speeds)
		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
				 lk_ksettings->link_modes.supported);

@@ -1798,6 +1854,30 @@ static const u16 bnxt_pam4_speed_masks[] = {
	[BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_50GB,
	[BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_100GB,
	[BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_PAM4_SPEED_MSK_200GB,
	[__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */
};

static const u16 bnxt_nrz_speeds2_masks[] = {
	[BNXT_LINK_SPEED_1GB_IDX] = BNXT_LINK_SPEEDS2_MSK_1GB,
	[BNXT_LINK_SPEED_10GB_IDX] = BNXT_LINK_SPEEDS2_MSK_10GB,
	[BNXT_LINK_SPEED_25GB_IDX] = BNXT_LINK_SPEEDS2_MSK_25GB,
	[BNXT_LINK_SPEED_40GB_IDX] = BNXT_LINK_SPEEDS2_MSK_40GB,
	[BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEEDS2_MSK_50GB,
	[BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB,
	[__BNXT_LINK_SPEED_END - 1] = 0 /* make any legal speed a valid index */
};

static const u16 bnxt_pam4_speeds2_masks[] = {
	[BNXT_LINK_SPEED_50GB_IDX] = BNXT_LINK_SPEEDS2_MSK_50GB_PAM4,
	[BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB_PAM4,
	[BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_SPEEDS2_MSK_200GB_PAM4,
	[BNXT_LINK_SPEED_400GB_IDX] = BNXT_LINK_SPEEDS2_MSK_400GB_PAM4,
};

static const u16 bnxt_pam4_112_speeds2_masks[] = {
	[BNXT_LINK_SPEED_100GB_IDX] = BNXT_LINK_SPEEDS2_MSK_100GB_PAM4_112,
	[BNXT_LINK_SPEED_200GB_IDX] = BNXT_LINK_SPEEDS2_MSK_200GB_PAM4_112,
	[BNXT_LINK_SPEED_400GB_IDX] = BNXT_LINK_SPEEDS2_MSK_400GB_PAM4_112,
};

static enum bnxt_link_speed_indices
@@ -1808,12 +1888,26 @@ bnxt_encoding_speed_idx(u8 sig_mode, u16 phy_flags, u16 speed_msk)

	switch (sig_mode) {
	case BNXT_SIG_MODE_NRZ:
		if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
			speeds = bnxt_nrz_speeds2_masks;
			len = ARRAY_SIZE(bnxt_nrz_speeds2_masks);
		} else {
			speeds = bnxt_nrz_speed_masks;
			len = ARRAY_SIZE(bnxt_nrz_speed_masks);
		}
		break;
	case BNXT_SIG_MODE_PAM4:
		if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
			speeds = bnxt_pam4_speeds2_masks;
			len = ARRAY_SIZE(bnxt_pam4_speeds2_masks);
		} else {
			speeds = bnxt_pam4_speed_masks;
			len = ARRAY_SIZE(bnxt_pam4_speed_masks);
		}
		break;
	case BNXT_SIG_MODE_PAM4_112:
		speeds = bnxt_pam4_112_speeds2_masks;
		len = ARRAY_SIZE(bnxt_pam4_112_speeds2_masks);
		break;
	default:
		return BNXT_LINK_SPEED_UNKNOWN;
@@ -1872,14 +1966,23 @@ bnxt_get_all_ethtool_support_speeds(struct bnxt_link_info *link_info,
				    struct ethtool_link_ksettings *lk_ksettings)
{
	struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
	u16 sp_nrz, sp_pam4, sp_pam4_112 = 0;
	u16 phy_flags = bp->phy_flags;

	bnxt_get_ethtool_speeds(link_info->support_speeds, media,
				BNXT_SIG_MODE_NRZ, phy_flags,
	if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
		sp_nrz = link_info->support_speeds2;
		sp_pam4 = link_info->support_speeds2;
		sp_pam4_112 = link_info->support_speeds2;
	} else {
		sp_nrz = link_info->support_speeds;
		sp_pam4 = link_info->support_pam4_speeds;
	}
	bnxt_get_ethtool_speeds(sp_nrz, media, BNXT_SIG_MODE_NRZ, phy_flags,
				lk_ksettings->link_modes.supported);
	bnxt_get_ethtool_speeds(link_info->support_pam4_speeds, media,
				BNXT_SIG_MODE_PAM4, phy_flags,
	bnxt_get_ethtool_speeds(sp_pam4, media, BNXT_SIG_MODE_PAM4, phy_flags,
				lk_ksettings->link_modes.supported);
	bnxt_get_ethtool_speeds(sp_pam4_112, media, BNXT_SIG_MODE_PAM4_112,
				phy_flags, lk_ksettings->link_modes.supported);
}

static void
@@ -1888,14 +1991,22 @@ bnxt_get_all_ethtool_adv_speeds(struct bnxt_link_info *link_info,
				struct ethtool_link_ksettings *lk_ksettings)
{
	struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
	u16 sp_nrz, sp_pam4, sp_pam4_112 = 0;
	u16 phy_flags = bp->phy_flags;

	bnxt_get_ethtool_speeds(link_info->advertising, media,
				BNXT_SIG_MODE_NRZ, phy_flags,
	sp_nrz = link_info->advertising;
	if (phy_flags & BNXT_PHY_FL_SPEEDS2) {
		sp_pam4 = link_info->advertising;
		sp_pam4_112 = link_info->advertising;
	} else {
		sp_pam4 = link_info->advertising_pam4;
	}
	bnxt_get_ethtool_speeds(sp_nrz, media, BNXT_SIG_MODE_NRZ, phy_flags,
				lk_ksettings->link_modes.advertising);
	bnxt_get_ethtool_speeds(link_info->advertising_pam4, media,
				BNXT_SIG_MODE_PAM4, phy_flags,
	bnxt_get_ethtool_speeds(sp_pam4, media, BNXT_SIG_MODE_PAM4, phy_flags,
				lk_ksettings->link_modes.advertising);
	bnxt_get_ethtool_speeds(sp_pam4_112, media, BNXT_SIG_MODE_PAM4_112,
				phy_flags, lk_ksettings->link_modes.advertising);
}

static void
@@ -1940,22 +2051,42 @@ static void bnxt_update_speed(u32 *delta, bool installed_media, u16 *speeds,
static void bnxt_set_ethtool_speeds(struct bnxt_link_info *link_info,
				    const unsigned long *et_mask)
{
	struct bnxt *bp = container_of(link_info, struct bnxt, link_info);
	u16 const *sp_msks, *sp_pam4_msks, *sp_pam4_112_msks;
	enum bnxt_media_type media = bnxt_get_media(link_info);
	u16 *adv, *adv_pam4, *adv_pam4_112 = NULL;
	u32 delta_pam4_112 = 0;
	u32 delta_pam4 = 0;
	u32 delta_nrz = 0;
	int i, m;

	adv = &link_info->advertising;
	if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) {
		adv_pam4 = &link_info->advertising;
		adv_pam4_112 = &link_info->advertising;
		sp_msks = bnxt_nrz_speeds2_masks;
		sp_pam4_msks = bnxt_pam4_speeds2_masks;
		sp_pam4_112_msks = bnxt_pam4_112_speeds2_masks;
	} else {
		adv_pam4 = &link_info->advertising_pam4;
		sp_msks = bnxt_nrz_speed_masks;
		sp_pam4_msks = bnxt_pam4_speed_masks;
	}
	for (i = 1; i < __BNXT_LINK_SPEED_END; i++) {
		/* accept any legal media from user */
		for (m = 1; m < __BNXT_MEDIA_END; m++) {
			bnxt_update_speed(&delta_nrz, m == media,
					  &link_info->advertising,
					  bnxt_nrz_speed_masks[i], et_mask,
					  adv, sp_msks[i], et_mask,
					  bnxt_link_modes[i][BNXT_SIG_MODE_NRZ][m]);
			bnxt_update_speed(&delta_pam4, m == media,
					  &link_info->advertising_pam4,
					  bnxt_pam4_speed_masks[i], et_mask,
					  adv_pam4, sp_pam4_msks[i], et_mask,
					  bnxt_link_modes[i][BNXT_SIG_MODE_PAM4][m]);
			if (!adv_pam4_112)
				continue;

			bnxt_update_speed(&delta_pam4_112, m == media,
					  adv_pam4_112, sp_pam4_112_msks[i], et_mask,
					  bnxt_link_modes[i][BNXT_SIG_MODE_PAM4_112][m]);
		}
	}
}