src/dpdk/drivers/net/txgbe/base/txgbe_phy.c
s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
{
	s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
	u32 vendor_oui = 0;
	enum txgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
	u8 identifier = 0;
	u8 comp_codes_1g = 0;
	u8 comp_codes_10g = 0;
	u8 oui_bytes[3] = {0, 0, 0};
	u16 enforce_sfp = 0;
	u8 connector = 0;
	u8 cable_length = 0;
	u8 device_tech = 0;
	bool active_cable = false;

	DEBUGFUNC("txgbe_identify_qsfp_module");

	if (hw->phy.media_type != txgbe_media_type_fiber_qsfp) {
		hw->phy.sfp_type = txgbe_sfp_type_not_present;
		err = TXGBE_ERR_SFP_NOT_PRESENT;
		goto out;
	}

	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
					     &identifier);
ERR_I2C:
	if (err != 0) {
		hw->phy.sfp_type = txgbe_sfp_type_not_present;
		hw->phy.id = 0;
		hw->phy.type = txgbe_phy_unknown;
		return TXGBE_ERR_SFP_NOT_PRESENT;
	}
	if (identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
		hw->phy.type = txgbe_phy_sfp_unsupported;
		err = TXGBE_ERR_SFP_NOT_SUPPORTED;
		goto out;
	}

	hw->phy.id = identifier;

	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_10GBE_COMP,
					     &comp_codes_10g);

	if (err != 0)
		goto ERR_I2C;

	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_1GBE_COMP,
					     &comp_codes_1g);

	if (err != 0)
		goto ERR_I2C;

	if (comp_codes_10g & TXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
		hw->phy.type = txgbe_phy_qsfp_unknown_passive;
		if (hw->bus.lan_id == 0)
			hw->phy.sfp_type = txgbe_sfp_type_da_cu_core0;
		else
			hw->phy.sfp_type = txgbe_sfp_type_da_cu_core1;
	} else if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
				     TXGBE_SFF_10GBASELR_CAPABLE)) {
		if (hw->bus.lan_id == 0)
			hw->phy.sfp_type = txgbe_sfp_type_srlr_core0;
		else
			hw->phy.sfp_type = txgbe_sfp_type_srlr_core1;
	} else {
		if (comp_codes_10g & TXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
			active_cable = true;

		if (!active_cable) {
			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_CONNECTOR,
					&connector);

			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_CABLE_LENGTH,
					&cable_length);

			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_DEVICE_TECH,
					&device_tech);

			if (connector ==
				     TXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE &&
			    cable_length > 0 &&
			    ((device_tech >> 4) ==
				     TXGBE_SFF_QSFP_TRANSMITTER_850NM_VCSEL))
				active_cable = true;
		}

		if (active_cable) {
			hw->phy.type = txgbe_phy_qsfp_unknown_active;
			if (hw->bus.lan_id == 0)
				hw->phy.sfp_type =
					txgbe_sfp_type_da_act_lmt_core0;
			else
				hw->phy.sfp_type =
					txgbe_sfp_type_da_act_lmt_core1;
		} else {
			/* unsupported module type */
			hw->phy.type = txgbe_phy_sfp_unsupported;
			err = TXGBE_ERR_SFP_NOT_SUPPORTED;
			goto out;
		}
	}

	if (hw->phy.sfp_type != stored_sfp_type)
		hw->phy.sfp_setup_needed = true;

	/* Determine if the QSFP+ PHY is dual speed or not. */
	hw->phy.multispeed_fiber = false;
	if (((comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) &&
	   (comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE)) ||
	   ((comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) &&
	   (comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE)))
		hw->phy.multispeed_fiber = true;

	/* Determine PHY vendor for optical modules */
	if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
			      TXGBE_SFF_10GBASELR_CAPABLE))  {
		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
					    &oui_bytes[0]);

		if (err != 0)
			goto ERR_I2C;

		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
					    &oui_bytes[1]);

		if (err != 0)
			goto ERR_I2C;

		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
					    &oui_bytes[2]);

		if (err != 0)
			goto ERR_I2C;

		vendor_oui =
		  ((oui_bytes[0] << 24) |
		   (oui_bytes[1] << 16) |
		   (oui_bytes[2] << 8));

		if (vendor_oui == TXGBE_SFF_VENDOR_OUI_INTEL)
			hw->phy.type = txgbe_phy_qsfp_intel;
		else
			hw->phy.type = txgbe_phy_qsfp_unknown;

		hw->mac.get_device_caps(hw, &enforce_sfp);
		if (!(enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
			/* Make sure we're a supported PHY type */
			if (hw->phy.type == txgbe_phy_qsfp_intel) {
				err = 0;
			} else {
				if (hw->allow_unsupported_sfp) {
					DEBUGOUT("WARNING: Wangxun (R) Network Connections are quality tested using Wangxun (R) Ethernet Optics. "
						"Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. "
						"Wangxun Corporation is not responsible for any harm caused by using untested modules.\n");
					err = 0;
				} else {
					DEBUGOUT("QSFP module not supported\n");
					hw->phy.type =
						txgbe_phy_sfp_unsupported;
					err = TXGBE_ERR_SFP_NOT_SUPPORTED;
				}
			}
		} else {
			err = 0;
		}
	}

out:
	return err;
}
/**
 *  txgbe_identify_qsfp_module - Identifies QSFP modules
 *  @hw: pointer to hardware structure
 *
 *  Searches for and identifies the QSFP module and assigns appropriate PHY type
 **/
Identifies QSFP modules
@hw: pointer to hardware structure

Searches for and identifies the QSFP module and assigns appropriate PHY type
Identifies QSFP modules @hw : pointer to hardware structure Searches for and identifies the QSFP module and assigns appropriate PHY type
s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
{
	s32 err = TXGBE_ERR_PHY_ADDR_INVALID;
	u32 vendor_oui = 0;
	enum txgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
	u8 identifier = 0;
	u8 comp_codes_1g = 0;
	u8 comp_codes_10g = 0;
	u8 oui_bytes[3] = {0, 0, 0};
	u16 enforce_sfp = 0;
	u8 connector = 0;
	u8 cable_length = 0;
	u8 device_tech = 0;
	bool active_cable = false;
	DEBUGFUNC("txgbe_identify_qsfp_module");
	if (hw->phy.media_type != txgbe_media_type_fiber_qsfp) {
		hw->phy.sfp_type = txgbe_sfp_type_not_present;
		err = TXGBE_ERR_SFP_NOT_PRESENT;
		goto out;
	}
	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
					     &identifier);
ERR_I2C:
	if (err != 0) {
		hw->phy.sfp_type = txgbe_sfp_type_not_present;
		hw->phy.id = 0;
		hw->phy.type = txgbe_phy_unknown;
		return TXGBE_ERR_SFP_NOT_PRESENT;
	}
	if (identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS) {
		hw->phy.type = txgbe_phy_sfp_unsupported;
		err = TXGBE_ERR_SFP_NOT_SUPPORTED;
		goto out;
	}
	hw->phy.id = identifier;
	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_10GBE_COMP,
					     &comp_codes_10g);
	if (err != 0)
		goto ERR_I2C;
	err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_QSFP_1GBE_COMP,
					     &comp_codes_1g);
	if (err != 0)
		goto ERR_I2C;
	if (comp_codes_10g & TXGBE_SFF_QSFP_DA_PASSIVE_CABLE) {
		hw->phy.type = txgbe_phy_qsfp_unknown_passive;
		if (hw->bus.lan_id == 0)
			hw->phy.sfp_type = txgbe_sfp_type_da_cu_core0;
		else
			hw->phy.sfp_type = txgbe_sfp_type_da_cu_core1;
	} else if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
				     TXGBE_SFF_10GBASELR_CAPABLE)) {
		if (hw->bus.lan_id == 0)
			hw->phy.sfp_type = txgbe_sfp_type_srlr_core0;
		else
			hw->phy.sfp_type = txgbe_sfp_type_srlr_core1;
	} else {
		if (comp_codes_10g & TXGBE_SFF_QSFP_DA_ACTIVE_CABLE)
			active_cable = true;
		if (!active_cable) {
			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_CONNECTOR,
					&connector);
			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_CABLE_LENGTH,
					&cable_length);
			hw->phy.read_i2c_eeprom(hw,
					TXGBE_SFF_QSFP_DEVICE_TECH,
					&device_tech);
			if (connector ==
				     TXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE &&
			    cable_length > 0 &&
			    ((device_tech >> 4) ==
				     TXGBE_SFF_QSFP_TRANSMITTER_850NM_VCSEL))
				active_cable = true;
		}
		if (active_cable) {
			hw->phy.type = txgbe_phy_qsfp_unknown_active;
			if (hw->bus.lan_id == 0)
				hw->phy.sfp_type =
					txgbe_sfp_type_da_act_lmt_core0;
			else
				hw->phy.sfp_type =
					txgbe_sfp_type_da_act_lmt_core1;
		} else {
			hw->phy.type = txgbe_phy_sfp_unsupported;
			err = TXGBE_ERR_SFP_NOT_SUPPORTED;
			goto out;
		}
	}
	if (hw->phy.sfp_type != stored_sfp_type)
		hw->phy.sfp_setup_needed = true;
	hw->phy.multispeed_fiber = false;
	if (((comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) &&
	   (comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE)) ||
	   ((comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) &&
	   (comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE)))
		hw->phy.multispeed_fiber = true;
	if (comp_codes_10g & (TXGBE_SFF_10GBASESR_CAPABLE |
			      TXGBE_SFF_10GBASELR_CAPABLE))  {
		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE0,
					    &oui_bytes[0]);
		if (err != 0)
			goto ERR_I2C;
		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE1,
					    &oui_bytes[1]);
		if (err != 0)
			goto ERR_I2C;
		err = hw->phy.read_i2c_eeprom(hw,
					    TXGBE_SFF_QSFP_VENDOR_OUI_BYTE2,
					    &oui_bytes[2]);
		if (err != 0)
			goto ERR_I2C;
		vendor_oui =
		  ((oui_bytes[0] << 24) |
		   (oui_bytes[1] << 16) |
		   (oui_bytes[2] << 8));
		if (vendor_oui == TXGBE_SFF_VENDOR_OUI_INTEL)
			hw->phy.type = txgbe_phy_qsfp_intel;
		else
			hw->phy.type = txgbe_phy_qsfp_unknown;
		hw->mac.get_device_caps(hw, &enforce_sfp);
		if (!(enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
			if (hw->phy.type == txgbe_phy_qsfp_intel) {
				err = 0;
			} else {
				if (hw->allow_unsupported_sfp) {
					DEBUGOUT("WARNING: Wangxun (R) Network Connections are quality tested using Wangxun (R) Ethernet Optics. "
						"Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. "
						"Wangxun Corporation is not responsible for any harm caused by using untested modules.\n");
					err = 0;
				} else {
					DEBUGOUT("QSFP module not supported\n");
					hw->phy.type =
						txgbe_phy_sfp_unsupported;
					err = TXGBE_ERR_SFP_NOT_SUPPORTED;
				}
			}
		} else {
			err = 0;
		}
	}
out:
	return err;
}
s32 txgbe_identify_qsfp_module ( struct txgbe_hw * hw ) { s32 err = TXGBE_ERR_PHY_ADDR_INVALID ; u32 vendor_oui = 0 ; enum txgbe_sfp_type stored_sfp_type = hw -> phy . sfp_type ; u8 identifier = 0 ; u8 comp_codes_1g = 0 ; u8 comp_codes_10g = 0 ; u8 oui_bytes [ 3 ] = { 0 , 0 , 0 } ; u16 enforce_sfp = 0 ; u8 connector = 0 ; u8 cable_length = 0 ; u8 device_tech = 0 ; bool active_cable = false ; DEBUGFUNC ( " " ) ; if ( hw -> phy . media_type != txgbe_media_type_fiber_qsfp ) { hw -> phy . sfp_type = txgbe_sfp_type_not_present ; err = TXGBE_ERR_SFP_NOT_PRESENT ; goto out ; } err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_IDENTIFIER , & identifier ) ; ERR_I2C : if ( err != 0 ) { hw -> phy . sfp_type = txgbe_sfp_type_not_present ; hw -> phy . id = 0 ; hw -> phy . type = txgbe_phy_unknown ; return TXGBE_ERR_SFP_NOT_PRESENT ; } if ( identifier != TXGBE_SFF_IDENTIFIER_QSFP_PLUS ) { hw -> phy . type = txgbe_phy_sfp_unsupported ; err = TXGBE_ERR_SFP_NOT_SUPPORTED ; goto out ; } hw -> phy . id = identifier ; err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_10GBE_COMP , & comp_codes_10g ) ; if ( err != 0 ) goto ERR_I2C ; err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_1GBE_COMP , & comp_codes_1g ) ; if ( err != 0 ) goto ERR_I2C ; if ( comp_codes_10g & TXGBE_SFF_QSFP_DA_PASSIVE_CABLE ) { hw -> phy . type = txgbe_phy_qsfp_unknown_passive ; if ( hw -> bus . lan_id == 0 ) hw -> phy . sfp_type = txgbe_sfp_type_da_cu_core0 ; else hw -> phy . sfp_type = txgbe_sfp_type_da_cu_core1 ; } else if ( comp_codes_10g & ( TXGBE_SFF_10GBASESR_CAPABLE | TXGBE_SFF_10GBASELR_CAPABLE ) ) { if ( hw -> bus . lan_id == 0 ) hw -> phy . sfp_type = txgbe_sfp_type_srlr_core0 ; else hw -> phy . sfp_type = txgbe_sfp_type_srlr_core1 ; } else { if ( comp_codes_10g & TXGBE_SFF_QSFP_DA_ACTIVE_CABLE ) active_cable = true ; if ( ! active_cable ) { hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_CONNECTOR , & connector ) ; hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_CABLE_LENGTH , & cable_length ) ; hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_DEVICE_TECH , & device_tech ) ; if ( connector == TXGBE_SFF_QSFP_CONNECTOR_NOT_SEPARABLE && cable_length > 0 && ( ( device_tech >> 4 ) == TXGBE_SFF_QSFP_TRANSMITTER_850NM_VCSEL ) ) active_cable = true ; } if ( active_cable ) { hw -> phy . type = txgbe_phy_qsfp_unknown_active ; if ( hw -> bus . lan_id == 0 ) hw -> phy . sfp_type = txgbe_sfp_type_da_act_lmt_core0 ; else hw -> phy . sfp_type = txgbe_sfp_type_da_act_lmt_core1 ; } else { hw -> phy . type = txgbe_phy_sfp_unsupported ; err = TXGBE_ERR_SFP_NOT_SUPPORTED ; goto out ; } } if ( hw -> phy . sfp_type != stored_sfp_type ) hw -> phy . sfp_setup_needed = true ; hw -> phy . multispeed_fiber = false ; if ( ( ( comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE ) && ( comp_codes_10g & TXGBE_SFF_10GBASESR_CAPABLE ) ) || ( ( comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE ) && ( comp_codes_10g & TXGBE_SFF_10GBASELR_CAPABLE ) ) ) hw -> phy . multispeed_fiber = true ; if ( comp_codes_10g & ( TXGBE_SFF_10GBASESR_CAPABLE | TXGBE_SFF_10GBASELR_CAPABLE ) ) { err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_VENDOR_OUI_BYTE0 , & oui_bytes [ 0 ] ) ; if ( err != 0 ) goto ERR_I2C ; err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_VENDOR_OUI_BYTE1 , & oui_bytes [ 1 ] ) ; if ( err != 0 ) goto ERR_I2C ; err = hw -> phy . read_i2c_eeprom ( hw , TXGBE_SFF_QSFP_VENDOR_OUI_BYTE2 , & oui_bytes [ 2 ] ) ; if ( err != 0 ) goto ERR_I2C ; vendor_oui = ( ( oui_bytes [ 0 ] << 24 ) | ( oui_bytes [ 1 ] << 16 ) | ( oui_bytes [ 2 ] << 8 ) ) ; if ( vendor_oui == TXGBE_SFF_VENDOR_OUI_INTEL ) hw -> phy . type = txgbe_phy_qsfp_intel ; else hw -> phy . type = txgbe_phy_qsfp_unknown ; hw -> mac . get_device_caps ( hw , & enforce_sfp ) ; if ( ! ( enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP ) ) { if ( hw -> phy . type == txgbe_phy_qsfp_intel ) { err = 0 ; } else { if ( hw -> allow_unsupported_sfp ) { DEBUGOUT ( " " " " " \n " ) ; err = 0 ; } else { DEBUGOUT ( " \n " ) ; hw -> phy . type = txgbe_phy_sfp_unsupported ; err = TXGBE_ERR_SFP_NOT_SUPPORTED ; } } } else { err = 0 ; } } out : return err ; }
txgbe_identify_qsfp_module - Identifies QSFP modules
  @hw: pointer to hardware structure
txgbe_identify_qsfp_module - Identifies QSFP modules @hw : pointer to hardware structure
/* unsupported module type */ /* Determine if the QSFP+ PHY is dual speed or not. */ /* Determine PHY vendor for optical modules */ /* Make sure we're a supported PHY type */