ixgbe/base: allow to read in sff8472
authorJijiang Liu <jijiang.liu@intel.com>
Wed, 18 Jun 2014 18:34:56 +0000 (20:34 +0200)
committerThomas Monjalon <thomas.monjalon@6wind.com>
Wed, 18 Jun 2014 21:31:55 +0000 (23:31 +0200)
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
[Thomas: split code drop]

lib/librte_pmd_ixgbe/ixgbe/ixgbe_82598.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.c
lib/librte_pmd_ixgbe/ixgbe/ixgbe_phy.h
lib/librte_pmd_ixgbe/ixgbe/ixgbe_type.h

index edbec95..be6a6d4 100644 (file)
@@ -65,7 +65,8 @@ STATIC s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq);
 STATIC s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw);
 STATIC void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
                                  u32 headroom, int strategy);
-
+STATIC s32 ixgbe_read_i2c_sff8472_82598(struct ixgbe_hw *hw, u8 byte_offset,
+                                       u8 *sff8472_data);
 /**
  *  ixgbe_set_pcie_completion_timeout - set pci-e completion timeout
  *  @hw: pointer to the HW structure
@@ -161,6 +162,7 @@ s32 ixgbe_init_ops_82598(struct ixgbe_hw *hw)
 
        /* SFP+ Module */
        phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598;
+       phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_82598;
 
        /* Link */
        mac->ops.check_link = &ixgbe_check_mac_link_82598;
@@ -1108,15 +1110,16 @@ 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.
  **/
-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 = IXGBE_SUCCESS;
        u16 sfp_addr = 0;
@@ -1125,7 +1128,7 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
        u16 gssr;
        u32 i;
 
-       DEBUGFUNC("ixgbe_read_i2c_eeprom_82598");
+       DEBUGFUNC("ixgbe_read_i2c_phy_82598");
 
        if (IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)
                gssr = IXGBE_GSSR_PHY1_SM;
@@ -1141,19 +1144,19 @@ 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,
-                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                                     sfp_addr);
+               hw->phy.ops.write_reg_mdi(hw,
+                                         IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
+                                         IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                         sfp_addr);
 
                /* Poll status */
                for (i = 0; i < 100; i++) {
-                       hw->phy.ops.read_reg(hw,
-                                            IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
-                                            IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                                            &sfp_stat);
+                       hw->phy.ops.read_reg_mdi(hw,
+                                               IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
+                                               IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                               &sfp_stat);
                        sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
                        if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
                                break;
@@ -1167,13 +1170,12 @@ s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
                }
 
                /* Read data */
-               hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
-                                    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
+               hw->phy.ops.read_reg_mdi(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
+                                       IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
 
                *eeprom_data = (u8)(sfp_data >> 8);
        } else {
                status = IXGBE_ERR_PHY;
-               goto out;
        }
 
 out:
@@ -1181,6 +1183,36 @@ 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.
+ **/
+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
index 382b0ed..06d3d50 100644 (file)
@@ -47,6 +47,8 @@ STATIC void ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
 STATIC void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
 STATIC s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
 STATIC bool ixgbe_get_i2c_data(u32 *i2cctl);
+STATIC s32 ixgbe_read_i2c_sff8472_generic(struct ixgbe_hw *hw, u8 byte_offset,
+                                         u8 *sff8472_data);
 
 /**
  *  ixgbe_init_phy_ops_generic - Inits PHY function ptrs
@@ -73,6 +75,7 @@ s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw)
        phy->ops.get_firmware_version = ixgbe_get_phy_firmware_version_generic;
        phy->ops.read_i2c_byte = &ixgbe_read_i2c_byte_generic;
        phy->ops.write_i2c_byte = &ixgbe_write_i2c_byte_generic;
+       phy->ops.read_i2c_sff8472 = &ixgbe_read_i2c_sff8472_generic;
        phy->ops.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic;
        phy->ops.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic;
        phy->ops.i2c_bus_clear = &ixgbe_i2c_bus_clear;
@@ -1461,6 +1464,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
+ **/
+STATIC 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
index 67c02b4..26c08c7 100644 (file)
@@ -35,7 +35,9 @@ POSSIBILITY OF SUCH DAMAGE.
 #define _IXGBE_PHY_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
+#define IXGBE_I2C_EEPROM_BANK_LEN      0xFF
 
 /* EEPROM byte offsets */
 #define IXGBE_SFF_IDENTIFIER           0x0
@@ -47,6 +49,8 @@ POSSIBILITY OF SUCH DAMAGE.
 #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
@@ -98,6 +102,9 @@ POSSIBILITY OF SUCH DAMAGE.
 #define IXGBE_TN_LASI_STATUS_REG       0x9005
 #define IXGBE_TN_LASI_STATUS_TEMP_ALARM        0x0008
 
+/* SFP+ SFF-8472 Compliance */
+#define IXGBE_SFF_SFF_8472_UNSUP       0x00
+
 #ident "$Id: ixgbe_phy.h,v 1.48 2012/01/04 01:49:02 jtkirshe Exp $"
 
 s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
index 88be058..1d3b60a 100644 (file)
@@ -3115,6 +3115,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);
        void (*i2c_bus_clear)(struct ixgbe_hw *);