From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [dpdk-dev] [PATCH v4 10/58] net/txgbe: add module identify
Date: Mon, 19 Oct 2020 16:53:27 +0800 [thread overview]
Message-ID: <20201019085415.82207-11-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20201019085415.82207-1-jiawenwu@trustnetic.com>
Add sfp anf qsfp module identify, i2c start and stop.
Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
drivers/net/txgbe/base/txgbe_eeprom.h | 1 +
drivers/net/txgbe/base/txgbe_hw.c | 4 +
drivers/net/txgbe/base/txgbe_phy.c | 588 +++++++++++++++++++++++++-
drivers/net/txgbe/base/txgbe_phy.h | 12 +
drivers/net/txgbe/base/txgbe_type.h | 1 +
5 files changed, 603 insertions(+), 3 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_eeprom.h b/drivers/net/txgbe/base/txgbe_eeprom.h
index 137fb1c30..25d03421c 100644
--- a/drivers/net/txgbe/base/txgbe_eeprom.h
+++ b/drivers/net/txgbe/base/txgbe_eeprom.h
@@ -23,6 +23,7 @@
#define TXGBE_EEPROM_VERSION_H 0x1E
#define TXGBE_ISCSI_BOOT_CONFIG 0x07
+#define TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP 0x1
s32 txgbe_init_eeprom_params(struct txgbe_hw *hw);
s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw);
diff --git a/drivers/net/txgbe/base/txgbe_hw.c b/drivers/net/txgbe/base/txgbe_hw.c
index a067192fa..d2d12a929 100644
--- a/drivers/net/txgbe/base/txgbe_hw.c
+++ b/drivers/net/txgbe/base/txgbe_hw.c
@@ -291,6 +291,10 @@ s32 txgbe_init_ops_pf(struct txgbe_hw *hw)
/* PHY */
phy->identify = txgbe_identify_phy;
phy->init = txgbe_init_phy_raptor;
+ phy->read_i2c_byte = txgbe_read_i2c_byte;
+ phy->write_i2c_byte = txgbe_write_i2c_byte;
+ phy->read_i2c_eeprom = txgbe_read_i2c_eeprom;
+ phy->write_i2c_eeprom = txgbe_write_i2c_eeprom;
/* MAC */
mac->init_hw = txgbe_init_hw;
diff --git a/drivers/net/txgbe/base/txgbe_phy.c b/drivers/net/txgbe/base/txgbe_phy.c
index 2ed497c48..b36bffcac 100644
--- a/drivers/net/txgbe/base/txgbe_phy.c
+++ b/drivers/net/txgbe/base/txgbe_phy.c
@@ -7,6 +7,9 @@
#include "txgbe_mng.h"
#include "txgbe_phy.h"
+static void txgbe_i2c_start(struct txgbe_hw *hw);
+static void txgbe_i2c_stop(struct txgbe_hw *hw);
+
/**
* txgbe_identify_extphy - Identify a single address for a PHY
* @hw: pointer to hardware structure
@@ -234,8 +237,204 @@ s32 txgbe_identify_module(struct txgbe_hw *hw)
**/
s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
{
- RTE_SET_USED(hw);
- return 0;
+ 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};
+ u8 cable_tech = 0;
+ u8 cable_spec = 0;
+ u16 enforce_sfp = 0;
+
+ DEBUGFUNC("txgbe_identify_sfp_module");
+
+ if (hw->phy.media_type != txgbe_media_type_fiber) {
+ hw->phy.sfp_type = txgbe_sfp_type_not_present;
+ return TXGBE_ERR_SFP_NOT_PRESENT;
+ }
+
+ err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_IDENTIFIER,
+ &identifier);
+ if (err != 0) {
+ERR_I2C:
+ hw->phy.sfp_type = txgbe_sfp_type_not_present;
+ if (hw->phy.type != txgbe_phy_nl) {
+ hw->phy.id = 0;
+ hw->phy.type = txgbe_phy_unknown;
+ }
+ return TXGBE_ERR_SFP_NOT_PRESENT;
+ }
+
+ if (identifier != TXGBE_SFF_IDENTIFIER_SFP) {
+ hw->phy.type = txgbe_phy_sfp_unsupported;
+ return TXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+
+ err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_1GBE_COMP_CODES,
+ &comp_codes_1g);
+ if (err != 0)
+ goto ERR_I2C;
+
+ err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_10GBE_COMP_CODES,
+ &comp_codes_10g);
+ if (err != 0)
+ goto ERR_I2C;
+
+ err = hw->phy.read_i2c_eeprom(hw, TXGBE_SFF_CABLE_TECHNOLOGY,
+ &cable_tech);
+ if (err != 0)
+ goto ERR_I2C;
+
+ /* ID Module
+ * =========
+ * 0 SFP_DA_CU
+ * 1 SFP_SR
+ * 2 SFP_LR
+ * 3 SFP_DA_CORE0 - chip-specific
+ * 4 SFP_DA_CORE1 - chip-specific
+ * 5 SFP_SR/LR_CORE0 - chip-specific
+ * 6 SFP_SR/LR_CORE1 - chip-specific
+ * 7 SFP_act_lmt_DA_CORE0 - chip-specific
+ * 8 SFP_act_lmt_DA_CORE1 - chip-specific
+ * 9 SFP_1g_cu_CORE0 - chip-specific
+ * 10 SFP_1g_cu_CORE1 - chip-specific
+ * 11 SFP_1g_sx_CORE0 - chip-specific
+ * 12 SFP_1g_sx_CORE1 - chip-specific
+ */
+ if (cable_tech & TXGBE_SFF_CABLE_DA_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 (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE) {
+ err = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_CABLE_SPEC_COMP, &cable_spec);
+ if (err != 0)
+ goto ERR_I2C;
+ if (cable_spec & TXGBE_SFF_DA_SPEC_ACTIVE_LIMITING) {
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_da_act_lmt_core0
+ : txgbe_sfp_type_da_act_lmt_core1);
+ } else {
+ hw->phy.sfp_type = txgbe_sfp_type_unknown;
+ }
+ } else if (comp_codes_10g &
+ (TXGBE_SFF_10GBASESR_CAPABLE |
+ TXGBE_SFF_10GBASELR_CAPABLE)) {
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_srlr_core0
+ : txgbe_sfp_type_srlr_core1);
+ } else if (comp_codes_1g & TXGBE_SFF_1GBASET_CAPABLE) {
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_1g_cu_core0
+ : txgbe_sfp_type_1g_cu_core1);
+ } else if (comp_codes_1g & TXGBE_SFF_1GBASESX_CAPABLE) {
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_1g_sx_core0
+ : txgbe_sfp_type_1g_sx_core1);
+ } else if (comp_codes_1g & TXGBE_SFF_1GBASELX_CAPABLE) {
+ hw->phy.sfp_type = (hw->bus.lan_id == 0
+ ? txgbe_sfp_type_1g_lx_core0
+ : txgbe_sfp_type_1g_lx_core1);
+ } else {
+ hw->phy.sfp_type = txgbe_sfp_type_unknown;
+ }
+
+ if (hw->phy.sfp_type != stored_sfp_type)
+ hw->phy.sfp_setup_needed = true;
+
+ /* Determine if the SFP+ 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 */
+ if (hw->phy.type != txgbe_phy_nl) {
+ hw->phy.id = identifier;
+ err = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_VENDOR_OUI_BYTE0, &oui_bytes[0]);
+ if (err != 0)
+ goto ERR_I2C;
+
+ err = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_VENDOR_OUI_BYTE1, &oui_bytes[1]);
+ if (err != 0)
+ goto ERR_I2C;
+
+ err = hw->phy.read_i2c_eeprom(hw,
+ TXGBE_SFF_VENDOR_OUI_BYTE2, &oui_bytes[2]);
+ if (err != 0)
+ goto ERR_I2C;
+
+ vendor_oui = ((u32)oui_bytes[0] << 24) |
+ ((u32)oui_bytes[1] << 16) |
+ ((u32)oui_bytes[2] << 8);
+ switch (vendor_oui) {
+ case TXGBE_SFF_VENDOR_OUI_TYCO:
+ if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE)
+ hw->phy.type = txgbe_phy_sfp_tyco_passive;
+ break;
+ case TXGBE_SFF_VENDOR_OUI_FTL:
+ if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE)
+ hw->phy.type = txgbe_phy_sfp_ftl_active;
+ else
+ hw->phy.type = txgbe_phy_sfp_ftl;
+ break;
+ case TXGBE_SFF_VENDOR_OUI_AVAGO:
+ hw->phy.type = txgbe_phy_sfp_avago;
+ break;
+ case TXGBE_SFF_VENDOR_OUI_INTEL:
+ hw->phy.type = txgbe_phy_sfp_intel;
+ break;
+ default:
+ if (cable_tech & TXGBE_SFF_CABLE_DA_PASSIVE)
+ hw->phy.type = txgbe_phy_sfp_unknown_passive;
+ else if (cable_tech & TXGBE_SFF_CABLE_DA_ACTIVE)
+ hw->phy.type = txgbe_phy_sfp_unknown_active;
+ else
+ hw->phy.type = txgbe_phy_sfp_unknown;
+ break;
+ }
+ }
+
+ /* Allow any DA cable vendor */
+ if (cable_tech & (TXGBE_SFF_CABLE_DA_PASSIVE |
+ TXGBE_SFF_CABLE_DA_ACTIVE)) {
+ return 0;
+ }
+
+ /* Verify supported 1G SFP modules */
+ if (comp_codes_10g == 0 &&
+ !(hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core1 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
+ hw->phy.type = txgbe_phy_sfp_unsupported;
+ return TXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+
+ hw->mac.get_device_caps(hw, &enforce_sfp);
+ if (!(enforce_sfp & TXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
+ !hw->allow_unsupported_sfp &&
+ !(hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_lx_core1 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_1g_sx_core1)) {
+ DEBUGOUT("SFP+ module not supported\n");
+ hw->phy.type = txgbe_phy_sfp_unsupported;
+ return TXGBE_ERR_SFP_NOT_SUPPORTED;
+ }
+
+ return err;
}
/**
@@ -246,7 +445,390 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw)
**/
s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
{
- RTE_SET_USED(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_read_i2c_eeprom - Reads 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to read
+ * @eeprom_data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 txgbe_read_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data)
+{
+ DEBUGFUNC("txgbe_read_i2c_eeprom");
+
+ return hw->phy.read_i2c_byte(hw, byte_offset,
+ TXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * txgbe_write_i2c_eeprom - Writes 8 bit EEPROM word over I2C interface
+ * @hw: pointer to hardware structure
+ * @byte_offset: EEPROM byte offset to write
+ * @eeprom_data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface.
+ **/
+s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data)
+{
+ DEBUGFUNC("txgbe_write_i2c_eeprom");
+
+ return hw->phy.write_i2c_byte(hw, byte_offset,
+ TXGBE_I2C_EEPROM_DEV_ADDR,
+ eeprom_data);
+}
+
+/**
+ * txgbe_read_i2c_byte_unlocked - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @dev_addr: address to read from
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 txgbe_read_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ UNREFERENCED_PARAMETER(dev_addr);
+
+ DEBUGFUNC("txgbe_read_i2c_byte");
+
+ txgbe_i2c_start(hw);
+
+ /* wait tx empty */
+ if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_TXEMPTY,
+ TXGBE_I2CICR_TXEMPTY, NULL, 100, 100)) {
+ return -TERR_TIMEOUT;
+ }
+
+ /* read data */
+ wr32(hw, TXGBE_I2CDATA,
+ byte_offset | TXGBE_I2CDATA_STOP);
+ wr32(hw, TXGBE_I2CDATA, TXGBE_I2CDATA_READ);
+
+ /* wait for read complete */
+ if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_RXFULL,
+ TXGBE_I2CICR_RXFULL, NULL, 100, 100)) {
+ return -TERR_TIMEOUT;
+ }
+
+ txgbe_i2c_stop(hw);
+
+ *data = 0xFF & rd32(hw, TXGBE_I2CDATA);
+
+ return 0;
+}
+
+/**
+ * txgbe_read_i2c_byte - Reads 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to read
+ * @dev_addr: address to read from
+ * @data: value read
+ *
+ * Performs byte read operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ int err = 0;
+
+ if (hw->mac.acquire_swfw_sync(hw, swfw_mask))
+ return TXGBE_ERR_SWFW_SYNC;
+ err = txgbe_read_i2c_byte_unlocked(hw, byte_offset, dev_addr, data);
+ hw->mac.release_swfw_sync(hw, swfw_mask);
+ return err;
+}
+
+/**
+ * txgbe_write_i2c_byte_unlocked - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @dev_addr: address to write to
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 txgbe_write_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ UNREFERENCED_PARAMETER(dev_addr);
+
+ DEBUGFUNC("txgbe_write_i2c_byte");
+
+ txgbe_i2c_start(hw);
+
+ /* wait tx empty */
+ if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_TXEMPTY,
+ TXGBE_I2CICR_TXEMPTY, NULL, 100, 100)) {
+ return -TERR_TIMEOUT;
+ }
+
+ wr32(hw, TXGBE_I2CDATA, byte_offset | TXGBE_I2CDATA_STOP);
+ wr32(hw, TXGBE_I2CDATA, data | TXGBE_I2CDATA_WRITE);
+
+ /* wait for write complete */
+ if (!po32m(hw, TXGBE_I2CICR, TXGBE_I2CICR_RXFULL,
+ TXGBE_I2CICR_RXFULL, NULL, 100, 100)) {
+ return -TERR_TIMEOUT;
+ }
+ txgbe_i2c_stop(hw);
+
return 0;
}
+/**
+ * txgbe_write_i2c_byte - Writes 8 bit word over I2C
+ * @hw: pointer to hardware structure
+ * @byte_offset: byte offset to write
+ * @dev_addr: address to write to
+ * @data: value to write
+ *
+ * Performs byte write operation to SFP module's EEPROM over I2C interface at
+ * a specified device address.
+ **/
+s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data)
+{
+ u32 swfw_mask = hw->phy.phy_semaphore_mask;
+ int err = 0;
+
+ if (hw->mac.acquire_swfw_sync(hw, swfw_mask))
+ return TXGBE_ERR_SWFW_SYNC;
+ err = txgbe_write_i2c_byte_unlocked(hw, byte_offset, dev_addr, data);
+ hw->mac.release_swfw_sync(hw, swfw_mask);
+
+ return err;
+}
+
+/**
+ * txgbe_i2c_start - Sets I2C start condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C start condition (High -> Low on SDA while SCL is High)
+ **/
+static void txgbe_i2c_start(struct txgbe_hw *hw)
+{
+ DEBUGFUNC("txgbe_i2c_start");
+
+ wr32(hw, TXGBE_I2CENA, 0);
+
+ wr32(hw, TXGBE_I2CCON,
+ (TXGBE_I2CCON_MENA |
+ TXGBE_I2CCON_SPEED(1) |
+ TXGBE_I2CCON_RESTART |
+ TXGBE_I2CCON_SDIA));
+ wr32(hw, TXGBE_I2CTAR, TXGBE_I2C_SLAVEADDR);
+ wr32(hw, TXGBE_I2CSSSCLHCNT, 600);
+ wr32(hw, TXGBE_I2CSSSCLLCNT, 600);
+ wr32(hw, TXGBE_I2CRXTL, 0); /* 1byte for rx full signal */
+ wr32(hw, TXGBE_I2CTXTL, 4);
+ wr32(hw, TXGBE_I2CSCLTMOUT, 0xFFFFFF);
+ wr32(hw, TXGBE_I2CSDATMOUT, 0xFFFFFF);
+
+ wr32(hw, TXGBE_I2CICM, 0);
+ wr32(hw, TXGBE_I2CENA, 1);
+}
+
+/**
+ * txgbe_i2c_stop - Sets I2C stop condition
+ * @hw: pointer to hardware structure
+ *
+ * Sets I2C stop condition (Low -> High on SDA while SCL is High)
+ **/
+static void txgbe_i2c_stop(struct txgbe_hw *hw)
+{
+ DEBUGFUNC("txgbe_i2c_stop");
+
+ /* wait for completion */
+ if (!po32m(hw, TXGBE_I2CSTAT, TXGBE_I2CSTAT_MST,
+ 0, NULL, 100, 100)) {
+ DEBUGFUNC("i2c stop timeout.");
+ }
+
+ wr32(hw, TXGBE_I2CENA, 0);
+}
+
diff --git a/drivers/net/txgbe/base/txgbe_phy.h b/drivers/net/txgbe/base/txgbe_phy.h
index 544ab064e..3c3f2914a 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -332,5 +332,17 @@ s32 txgbe_identify_phy(struct txgbe_hw *hw);
s32 txgbe_identify_module(struct txgbe_hw *hw);
s32 txgbe_identify_sfp_module(struct txgbe_hw *hw);
s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw);
+s32 txgbe_read_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
+s32 txgbe_read_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 *data);
+s32 txgbe_write_i2c_byte(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
+s32 txgbe_write_i2c_byte_unlocked(struct txgbe_hw *hw, u8 byte_offset,
+ u8 dev_addr, u8 data);
+s32 txgbe_read_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
+ u8 *eeprom_data);
+s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset,
+ u8 eeprom_data);
#endif /* _TXGBE_PHY_H_ */
diff --git a/drivers/net/txgbe/base/txgbe_type.h b/drivers/net/txgbe/base/txgbe_type.h
index b8e85063a..438734f8c 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -358,6 +358,7 @@ struct txgbe_phy_info {
u32 media_type;
u32 phy_semaphore_mask;
bool reset_disable;
+ bool multispeed_fiber;
bool qsfp_shared_i2c_bus;
u32 nw_mng_if_sel;
};
--
2.18.4
next prev parent reply other threads:[~2020-10-19 8:59 UTC|newest]
Thread overview: 84+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-19 8:53 [dpdk-dev] [PATCH v4 00/58] net: txgbe PMD Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 01/58] net/txgbe: add build and doc infrastructure Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 02/58] net/txgbe: add ethdev probe and remove Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 03/58] net/txgbe: add device init and uninit Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 04/58] net/txgbe: add error types and registers Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 05/58] net/txgbe: add MAC type and bus lan id Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 06/58] net/txgbe: add HW infrastructure and dummy function Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 07/58] net/txgbe: add EEPROM functions Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 08/58] net/txgbe: add HW init and reset operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 09/58] net/txgbe: add PHY init Jiawen Wu
2020-10-19 8:53 ` Jiawen Wu [this message]
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 11/58] net/txgbe: add PHY reset Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 12/58] net/txgbe: add info get operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 13/58] net/txgbe: add interrupt operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 14/58] net/txgbe: add device configure operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 15/58] net/txgbe: add link status change Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 16/58] net/txgbe: add multi-speed link setup Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 17/58] net/txgbe: add autoc read and write Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 18/58] net/txgbe: add MAC address operations Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 19/58] net/txgbe: add unicast hash bitmap Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 20/58] net/txgbe: add Rx and Tx init Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 21/58] net/txgbe: add Rx and Tx queues setup and release Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 22/58] net/txgbe: add Rx and Tx start and stop Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 23/58] net/txgbe: add packet type Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 24/58] net/txgbe: fill simple transmit function Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 25/58] net/txgbe: fill transmit function with hardware offload Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 26/58] net/txgbe: fill Tx prepare function Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 27/58] net/txgbe: fill receive functions Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 28/58] net/txgbe: add device start operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 29/58] net/txgbe: add Rx and Tx data path start and stop Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 30/58] net/txgbe: add device stop and close operations Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 31/58] net/txgbe: support Rx interrupt Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 32/58] net/txgbe: add Rx and Tx queue info get Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 33/58] net/txgbe: add device stats get Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 34/58] net/txgbe: add device xstats get Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 35/58] net/txgbe: add queue stats mapping Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 36/58] net/txgbe: add VLAN handle support Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 37/58] net/txgbe: add SWFW semaphore and lock Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 38/58] net/txgbe: add PF module init and uninit for SRIOV Jiawen Wu
2020-10-26 14:54 ` Ferruh Yigit
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 39/58] net/txgbe: add process mailbox operation Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 40/58] net/txgbe: add PF module configure for SRIOV Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 41/58] net/txgbe: add VMDq configure Jiawen Wu
2020-10-19 8:53 ` [dpdk-dev] [PATCH v4 42/58] net/txgbe: add RSS support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 43/58] net/txgbe: add DCB support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 44/58] net/txgbe: add flow control support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 45/58] net/txgbe: add FC auto negotiation support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 46/58] net/txgbe: add priority flow control support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 47/58] net/txgbe: add device promiscuous and allmulticast mode Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 48/58] net/txgbe: add MTU set operation Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 49/58] net/txgbe: add FW version get operation Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 50/58] net/txgbe: add EEPROM info " Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 51/58] net/txgbe: add register dump support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 52/58] net/txgbe: support device LED on and off Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 53/58] net/txgbe: add mirror rule operations Jiawen Wu
2020-10-26 14:54 ` Ferruh Yigit
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 54/58] net/txgbe: add PTP support Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 55/58] net/txgbe: add DCB info get operation Jiawen Wu
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 56/58] net/txgbe: add Rx and Tx descriptor status Jiawen Wu
2020-10-26 14:54 ` Ferruh Yigit
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 57/58] net/txgbe: change stop operation callback to return int Jiawen Wu
2020-10-26 14:55 ` Ferruh Yigit
2020-10-19 8:54 ` [dpdk-dev] [PATCH v4 58/58] net/txgbe: introduce log type in the driver documentation Jiawen Wu
2020-10-26 14:55 ` Ferruh Yigit
2020-10-22 11:23 ` [dpdk-dev] [PATCH v4 00/58] net: txgbe PMD Jiawen Wu
2020-10-22 11:44 ` Ferruh Yigit
2020-10-26 14:55 ` Ferruh Yigit
2020-10-27 2:39 ` Jiawen Wu
2020-10-27 11:37 ` Ferruh Yigit
2020-11-03 23:08 ` Thomas Monjalon
2020-11-04 17:24 ` Ferruh Yigit
2020-11-05 1:55 ` Jiawen Wu
2020-11-05 8:55 ` Jiawen Wu
2020-11-05 9:28 ` Thomas Monjalon
2020-11-06 6:28 ` Honnappa Nagarahalli
2020-11-06 9:22 ` Jiawen Wu
2020-11-06 17:36 ` Honnappa Nagarahalli
2020-11-06 18:21 ` Honnappa Nagarahalli
2020-11-06 19:00 ` Thomas Monjalon
2020-11-06 19:56 ` Honnappa Nagarahalli
2020-11-07 9:55 ` Thomas Monjalon
2020-10-27 8:48 ` David Marchand
2020-10-27 11:36 ` Ferruh Yigit
2020-10-27 11:39 ` David Marchand
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201019085415.82207-11-jiawenwu@trustnetic.com \
--to=jiawenwu@trustnetic.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).