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

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
...@@ -1003,15 +1003,16 @@ static s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) ...@@ -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 * @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 * @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, static s32 ixgbe_read_i2c_phy_82598(struct ixgbe_hw *hw, u8 dev_addr,
u8 *eeprom_data) u8 byte_offset, u8 *eeprom_data)
{ {
s32 status = 0; s32 status = 0;
u16 sfp_addr = 0; u16 sfp_addr = 0;
...@@ -1025,7 +1026,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -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+ * 0xC30D. These registers are used to talk to the SFP+
* module's EEPROM through the SDA/SCL (I2C) interface. * 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); sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
hw->phy.ops.write_reg(hw, hw->phy.ops.write_reg(hw,
IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR, 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, ...@@ -1057,13 +1058,42 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
*eeprom_data = (u8)(sfp_data >> 8); *eeprom_data = (u8)(sfp_data >> 8);
} else { } else {
status = IXGBE_ERR_PHY; status = IXGBE_ERR_PHY;
goto out;
} }
out: out:
return status; 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 * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -1297,6 +1327,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = { ...@@ -1297,6 +1327,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = {
.write_reg = &ixgbe_write_phy_reg_generic, .write_reg = &ixgbe_write_phy_reg_generic,
.setup_link = &ixgbe_setup_phy_link_generic, .setup_link = &ixgbe_setup_phy_link_generic,
.setup_link_speed = &ixgbe_setup_phy_link_speed_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, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598,
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
}; };
......
...@@ -2241,6 +2241,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = { ...@@ -2241,6 +2241,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = {
.setup_link_speed = &ixgbe_setup_phy_link_speed_generic, .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
.read_i2c_byte = &ixgbe_read_i2c_byte_generic, .read_i2c_byte = &ixgbe_read_i2c_byte_generic,
.write_i2c_byte = &ixgbe_write_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, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
......
...@@ -1203,6 +1203,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -1203,6 +1203,22 @@ s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
eeprom_data); 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 * ixgbe_write_i2c_eeprom_generic - Writes 8 bit EEPROM word over I2C interface
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "ixgbe_type.h" #include "ixgbe_type.h"
#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0 #define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0
#define IXGBE_I2C_EEPROM_DEV_ADDR2 0xA2
/* EEPROM byte offsets */ /* EEPROM byte offsets */
#define IXGBE_SFF_IDENTIFIER 0x0 #define IXGBE_SFF_IDENTIFIER 0x0
...@@ -41,6 +42,8 @@ ...@@ -41,6 +42,8 @@
#define IXGBE_SFF_10GBE_COMP_CODES 0x3 #define IXGBE_SFF_10GBE_COMP_CODES 0x3
#define IXGBE_SFF_CABLE_TECHNOLOGY 0x8 #define IXGBE_SFF_CABLE_TECHNOLOGY 0x8
#define IXGBE_SFF_CABLE_SPEC_COMP 0x3C #define IXGBE_SFF_CABLE_SPEC_COMP 0x3C
#define IXGBE_SFF_SFF_8472_SWAP 0x5C
#define IXGBE_SFF_SFF_8472_COMP 0x5E
/* Bitmasks */ /* Bitmasks */
#define IXGBE_SFF_DA_PASSIVE_CABLE 0x4 #define IXGBE_SFF_DA_PASSIVE_CABLE 0x4
...@@ -51,6 +54,7 @@ ...@@ -51,6 +54,7 @@
#define IXGBE_SFF_1GBASET_CAPABLE 0x8 #define IXGBE_SFF_1GBASET_CAPABLE 0x8
#define IXGBE_SFF_10GBASESR_CAPABLE 0x10 #define IXGBE_SFF_10GBASESR_CAPABLE 0x10
#define IXGBE_SFF_10GBASELR_CAPABLE 0x20 #define IXGBE_SFF_10GBASELR_CAPABLE 0x20
#define IXGBE_SFF_ADDRESSING_MODE 0x4
#define IXGBE_I2C_EEPROM_READ_MASK 0x100 #define IXGBE_I2C_EEPROM_READ_MASK 0x100
#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 #define IXGBE_I2C_EEPROM_STATUS_MASK 0x3
#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 #define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
...@@ -88,6 +92,9 @@ ...@@ -88,6 +92,9 @@
#define IXGBE_TN_LASI_STATUS_REG 0x9005 #define IXGBE_TN_LASI_STATUS_REG 0x9005
#define IXGBE_TN_LASI_STATUS_TEMP_ALARM 0x0008 #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_init_phy_ops_generic(struct ixgbe_hw *hw);
s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
s32 ixgbe_reset_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, ...@@ -125,6 +132,8 @@ s32 ixgbe_write_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 dev_addr, u8 data); u8 dev_addr, u8 data);
s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset, s32 ixgbe_read_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 *eeprom_data); 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, s32 ixgbe_write_i2c_eeprom_generic(struct ixgbe_hw *hw, u8 byte_offset,
u8 eeprom_data); u8 eeprom_data);
#endif /* _IXGBE_PHY_H_ */ #endif /* _IXGBE_PHY_H_ */
...@@ -2874,6 +2874,7 @@ struct ixgbe_phy_operations { ...@@ -2874,6 +2874,7 @@ struct ixgbe_phy_operations {
s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *); s32 (*get_firmware_version)(struct ixgbe_hw *, u16 *);
s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *); s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
s32 (*write_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 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
s32 (*check_overtemp)(struct ixgbe_hw *); s32 (*check_overtemp)(struct ixgbe_hw *);
......
...@@ -878,6 +878,7 @@ static struct ixgbe_phy_operations phy_ops_X540 = { ...@@ -878,6 +878,7 @@ static struct ixgbe_phy_operations phy_ops_X540 = {
.setup_link_speed = &ixgbe_setup_phy_link_speed_generic, .setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
.read_i2c_byte = &ixgbe_read_i2c_byte_generic, .read_i2c_byte = &ixgbe_read_i2c_byte_generic,
.write_i2c_byte = &ixgbe_write_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, .read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic, .write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment