which represents EEPROM defaults. If AUTOC value has not diff --git a/sys/dev/ixgbe/ixgbe_phy.c b/sys/dev/ixgbe/ixgbe_phy.c index a614ffe50c0d..99bfebd3acf1 100644 --- a/sys/dev/ixgbe/ixgbe_phy.c +++ b/sys/dev/ixgbe/ixgbe_phy.c @@ -1299,8 +1299,12 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) u8 oui_bytes[3] = {0, 0, 0}; u8 cable_tech = 0; u8 cable_spec = 0; + u8 bitrate_nominal = 0; + u8 sm_length_100m = 0; + u8 sm_length_km = 0; u8 retries; u16 enforce_sfp = 0; + bool is_10g_bx = false; static bool warned_once = false; DEBUGFUNC("ixgbe_identify_sfp_module_generic"); @@ -1358,6 +1362,37 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) if (status != IXGBE_SUCCESS) goto err_read_i2c_eeprom; + /* + * SFF-8472 identifies 10G-BX by an empty 10G compliance + * byte, a nominal 10.3 GBd rate, and at least 1 km of + * single-mode fiber reach. Resolve that strong signature + * before falling back to the permissive 1G-BX check below. + */ + if (hw->mac.type != ixgbe_mac_82598EB && + comp_codes_10g == 0 && + (comp_codes_1g & (IXGBE_SFF_1GBASET_CAPABLE | + IXGBE_SFF_1GBASESX_CAPABLE | + IXGBE_SFF_1GBASELX_CAPABLE)) == 0 && + (cable_tech & (IXGBE_SFF_DA_PASSIVE_CABLE | + IXGBE_SFF_DA_ACTIVE_CABLE)) == 0) { + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_BITRATE_NOMINAL, &bitrate_nominal); + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + if (bitrate_nominal == IXGBE_SFF_10G_BX_BITRATE) { + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_SM_LENGTH_KM, &sm_length_km); + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + status = hw->phy.ops.read_i2c_eeprom(hw, + IXGBE_SFF_SM_LENGTH_100M, &sm_length_100m); + if (status != IXGBE_SUCCESS) + goto err_read_i2c_eeprom; + } + is_10g_bx = bitrate_nominal == IXGBE_SFF_10G_BX_BITRATE && + (sm_length_km > 0 || sm_length_100m >= 10); + } + /* ID Module * ========= * 0 SFP_DA_CU @@ -1437,6 +1472,13 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) else hw->phy.sfp_type = ixgbe_sfp_type_1g_lx_core1; + } else if (is_10g_bx) { + if (hw->bus.lan_id == 0) + hw->phy.sfp_type = + ixgbe_sfp_type_10g_bx_core0; + else + hw->phy.sfp_type = + ixgbe_sfp_type_10g_bx_core1; } else if (comp_codes_1g & IXGBE_SFF_BASEBX10_CAPABLE) { if (hw->bus.lan_id == 0) hw->phy.sfp_type = @@ -1536,7 +1578,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core0 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1)) { + hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; status = IXGBE_ERR_SFP_NOT_SUPPORTED; goto out; @@ -1557,7 +1601,9 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 || hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core0 || - hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1)) { + hw->phy.sfp_type == ixgbe_sfp_type_1g_bx_core1 || + hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core1)) { /* Make sure we're a supported PHY type */ if (hw->phy.type == ixgbe_phy_sfp_intel) { status = IXGBE_SUCCESS; @@ -1612,6 +1658,9 @@ u64 ixgbe_get_supported_phy_sfp_layer_generic(struct ixgbe_hw *hw) hw->phy.ops.identify_sfp(hw); if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) return physical_layer; + if (hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core0 || + hw->phy.sfp_type == ixgbe_sfp_type_10g_bx_core1) + return IXGBE_PHYSICAL_LAYER_10GBASE_BX; switch (hw->phy.type) { case ixgbe_phy_sfp_passive_tyco: @@ -1884,20 +1933,22 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, return IXGBE_ERR_SFP_NOT_SUPPORTED; /* - * Limiting active cables and 1G Phys must be initialized as + * Limiting active cables, 10G-BX, and 1G PHYs must be initialized as * SR modules */ if (sfp_type == ixgbe_sfp_type_da_act_lmt_core0 || sfp_type == ixgbe_sfp_type_1g_lx_core0 || sfp_type == ixgbe_sfp_type_1g_cu_core0 || sfp_type == ixgbe_sfp_type_1g_sx_core0 || - sfp_type == ixgbe_sfp_type_1g_bx_core0) + sfp_type == ixgbe_sfp_type_1g_bx_core0 || + sfp_type == ixgbe_sfp_type_10g_bx_core0) sfp_type = ixgbe_sfp_type_srlr_core0; else if (sfp_type == ixgbe_sfp_type_da_act_lmt_core1 || sfp_type == ixgbe_sfp_type_1g_lx_core1 || sfp_type == ixgbe_sfp_type_1g_cu_core1 || sfp_type == ixgbe_sfp_type_1g_sx_core1 || - sfp_type == ixgbe_sfp_type_1g_bx_core1) + sfp_type == ixgbe_sfp_type_1g_bx_core1 || + sfp_type == ixgbe_sfp_type_10g_bx_core1) sfp_type = ixgbe_sfp_type_srlr_core1; /* Read offset to PHY init contents */ diff --git a/sys/dev/ixgbe/ixgbe_phy.h b/sys/dev/ixgbe/ixgbe_phy.h index c1ba73851397..8768267a383a 100644 --- a/sys/dev/ixgbe/ixgbe_phy.h +++ b/sys/dev/ixgbe/ixgbe_phy.h @@ -50,6 +50,8 @@ #define IXGBE_SFF_10GBE_COMP_CODES 0x3 #define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 #define IXGBE_SFF_BITRATE_NOMINAL 0xC +#define IXGBE_SFF_SM_LENGTH_KM 0xE +#define IXGBE_SFF_SM_LENGTH_100M 0xF #define IXGBE_SFF_CABLE_SPEC_COMP 0x3C #define IXGBE_SFF_SFF_8472_SWAP 0x5C #define IXGBE_SFF_SFF_8472_COMP 0x5E @@ -75,6 +77,7 @@ #define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_SFF_BASEBX10_CAPABLE 0x40 +#define IXGBE_SFF_10G_BX_BITRATE 0x67 #define IXGBE_SFF_SOFT_RS_SELECT_MASK 0x8 #define IXGBE_SFF_SOFT_RS_SELECT_10G 0x8 #define IXGBE_SFF_SOFT_RS_SELECT_1G 0x0 diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index 648f790194db..4986673b65c4 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -3551,6 +3551,7 @@ typedef u64 ixgbe_physical_layer; #define IXGBE_PHYSICAL_LAYER_2500BASE_KX 0x10000 #define IXGBE_PHYSICAL_LAYER_2500BASE_T 0x20000 #define IXGBE_PHYSICAL_LAYER_5000BASE_T 0x40000 +#define IXGBE_PHYSICAL_LAYER_10GBASE_BX 0x80000 /* Flow Control Data Sheet defined values * Calculation and defines taken from 802.1bb Annex O @@ -3827,6 +3828,8 @@ enum ixgbe_sfp_type { ixgbe_sfp_type_1g_lx_core1 = 14, ixgbe_sfp_type_1g_bx_core0 = 15, ixgbe_sfp_type_1g_bx_core1 = 16, + ixgbe_sfp_type_10g_bx_core0 = 17, + ixgbe_sfp_type_10g_bx_core1 = 18, ixgbe_sfp_type_not_present = 0xFFFE, ixgbe_sfp_type_unknown = 0xFFFF }; diff --git a/sys/dev/ixgbe/ixgbe_x550.c b/sys/dev/ixgbe/ixgbe_x550.c index 2891bc258db8..4f708e03b00e 100644 --- a/sys/dev/ixgbe/ixgbe_x550.c +++ b/sys/dev/ixgbe/ixgbe_x550.c @@ -1508,6 +1508,8 @@ static s32 ixgbe_supported_sfp_modules_X550em(struct ixgbe_hw *hw, bool *linear) case ixgbe_sfp_type_1g_lx_core1: case ixgbe_sfp_type_1g_bx_core0: case ixgbe_sfp_type_1g_bx_core1: + case ixgbe_sfp_type_10g_bx_core0: + case ixgbe_sfp_type_10g_bx_core1: *linear = false; break; case ixgbe_sfp_type_unknown: