Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 07ce870b authored by Emil Tantilov's avatar Emil Tantilov Committed by Jeff Kirsher
Browse files

ixgbe: allow reading of SFF-8472 data over i2c



This patch adds functions needed for reading SFF-8472 diagnostic data
from SFP modules.

Based on original patch from Aurélien Guillaume <footplus@gmail.com>

CC: Aurélien Guillaume <footplus@gmail.com>
Signed-off-by: default avatarEmil Tantilov <emil.s.tantilov@intel.com>
Tested-by: default avatarPhil Schmitt <phillip.j.schmitt@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent a7a1d9da
Loading
Loading
Loading
Loading
+38 −7
Original line number Diff line number Diff line
@@ -1003,15 +1003,16 @@ static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
}

/**
 *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
 *  ixgbe_read_i2c_phy_82598 - Reads 8 bit word over I2C interface.
 *  @hw: pointer to hardware structure
 *  @byte_offset: EEPROM byte offset to read
 *  @dev_addr: address to read from
 *  @byte_offset: byte offset to read from dev_addr
 *  @eeprom_data: value read
 *
 *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
 *  Performs 8 byte read operation to SFP module's data over I2C interface.
 **/
static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
				       u8 *eeprom_data)
static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
				    u8 byte_offset, u8 *eeprom_data)
{
	s32 status = 0;
	u16 sfp_addr = 0;
@@ -1025,7 +1026,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
		 * 0xC30D.  These registers are used to talk to the SFP+
		 * module's EEPROM through the SDA/SCL (I2C) interface.
		 */
		sfp_addr = (IXGBE_I2C_EEPROM_DEV_ADDR << 8) + byte_offset;
		sfp_addr = (dev_addr << 8) + byte_offset;
		sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
		hw->phy.ops.write_reg(hw,
		                      IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
@@ -1057,13 +1058,42 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
		*eeprom_data = (u8)(sfp_data >> 8);
	} else {
		status = IXGBE_ERR_PHY;
		goto out;
	}

out:
	return status;
}

/**
 *  ixgbe_read_i2c_eeprom_82598 - Reads 8 bit word over I2C interface.
 *  @hw: pointer to hardware structure
 *  @byte_offset: EEPROM byte offset to read
 *  @eeprom_data: value read
 *
 *  Performs 8 byte read operation to SFP module's EEPROM over I2C interface.
 **/
static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
				       u8 *eeprom_data)
{
	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR,
					byte_offset, eeprom_data);
}

/**
 *  ixgbe_read_i2c_sff8472_82598 - Reads 8 bit word over I2C interface.
 *  @hw: pointer to hardware structure
 *  @byte_offset: byte offset at address 0xA2
 *  @eeprom_data: value read
 *
 *  Performs 8 byte read operation to SFP module's SFF-8472 data over I2C
 **/
static s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
				       u8 *sff8472_data)
{
	return ixgbe_read_i2c_phy_82598(hw, IXGBE_I2C_EEPROM_DEV_ADDR2,
					byte_offset, sff8472_data);
}

/**
 *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
 *  @hw: pointer to hardware structure
@@ -1297,6 +1327,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = {
	.write_reg		= &ixgbe_write_phy_reg_generic,
	.setup_link		= &ixgbe_setup_phy_link_generic,
	.setup_link_speed	= &ixgbe_setup_phy_link_speed_generic,
	.read_i2c_sff8472	= &ixgbe_read_i2c_sff8472_82598,
	.read_i2c_eeprom	= &ixgbe_read_i2c_eeprom_82598,
	.check_overtemp   = &ixgbe_tn_check_overtemp,
};
+1 −0
Original line number Diff line number Diff line
@@ -2241,6 +2241,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = {
	.setup_link_speed	= &ixgbe_setup_phy_link_speed_generic,
	.read_i2c_byte		= &ixgbe_read_i2c_byte_generic,
	.write_i2c_byte		= &ixgbe_write_i2c_byte_generic,
	.read_i2c_sff8472	= &ixgbe_read_i2c_sff8472_generic,
	.read_i2c_eeprom	= &ixgbe_read_i2c_eeprom_generic,
	.write_i2c_eeprom	= &ixgbe_write_i2c_eeprom_generic,
	.check_overtemp		= &ixgbe_tn_check_overtemp,
+16 −0
Original line number Diff line number Diff line
@@ -1203,6 +1203,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
	                                 eeprom_data);
}

/**
 *  ixgbe_read_i2c_sff8472_generic - Reads 8 bit word over I2C interface
 *  @hw: pointer to hardware structure
 *  @byte_offset: byte offset at address 0xA2
 *  @eeprom_data: value read
 *
 *  Performs byte read operation to SFP module's SFF-8472 data over I2C
 **/
s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
				   u8 *sff8472_data)
{
	return hw->phy.ops.read_i2c_byte(hw, byte_offset,
					 IXGBE_I2C_EEPROM_DEV_ADDR2,
					 sff8472_data);
}

/**
 *  ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
 *  @hw: pointer to hardware structure
+9 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include "ixgbe_type.h"
#define IXGBE_I2C_EEPROM_DEV_ADDR    0xA0
#define IXGBE_I2C_EEPROM_DEV_ADDR2   0xA2

/* EEPROM byte offsets */
#define IXGBE_SFF_IDENTIFIER         0x0
@@ -41,6 +42,8 @@
#define IXGBE_SFF_10GBE_COMP_CODES   0x3
#define IXGBE_SFF_CABLE_TECHNOLOGY   0x8
#define IXGBE_SFF_CABLE_SPEC_COMP    0x3C
#define IXGBE_SFF_SFF_8472_SWAP      0x5C
#define IXGBE_SFF_SFF_8472_COMP      0x5E

/* Bitmasks */
#define IXGBE_SFF_DA_PASSIVE_CABLE           0x4
@@ -51,6 +54,7 @@
#define IXGBE_SFF_1GBASET_CAPABLE            0x8
#define IXGBE_SFF_10GBASESR_CAPABLE          0x10
#define IXGBE_SFF_10GBASELR_CAPABLE          0x20
#define IXGBE_SFF_ADDRESSING_MODE	     0x4
#define IXGBE_I2C_EEPROM_READ_MASK           0x100
#define IXGBE_I2C_EEPROM_STATUS_MASK         0x3
#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
@@ -88,6 +92,9 @@
#define IXGBE_TN_LASI_STATUS_REG        0x9005
#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008

/* SFP+ SFF-8472 Compliance code */
#define IXGBE_SFF_SFF_8472_UNSUP      0x00

s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
@@ -125,6 +132,8 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                 u8 dev_addr, u8 data);
s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                  u8 *eeprom_data);
s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
				   u8 *sff8472_data);
s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
                                   u8 eeprom_data);
#endif /* _IXGBE_PHY_H_ */
+1 −0
Original line number Diff line number Diff line
@@ -2874,6 +2874,7 @@ struct ixgbe_phy_operations {
	s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
	s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
	s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
	s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *);
	s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
	s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
	s32 (*check_overtemp)(struct ixgbe_hw *);
Loading