From: Anatoly Burakov <anatoly.burakov@intel.com>
To: dev@dpdk.org
Subject: [PATCH v1 05/42] net/e1000/base: add NVM/EEPROM support for i225
Date: Fri, 31 Jan 2025 12:58:18 +0000 [thread overview]
Message-ID: <26e5f01f2f55270f3ec04dd8f452aae0cadb1462.1738328107.git.anatoly.burakov@intel.com> (raw)
In-Reply-To: <cover.1738328106.git.anatoly.burakov@intel.com>
Add support for NVM/EEPROM operations for i225 series NICs. This is
mostly identical to IGC driver, with some minor differences due to the
way IGC driver was originally generated.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
drivers/net/intel/e1000/base/e1000_defines.h | 40 +
drivers/net/intel/e1000/base/e1000_hw.h | 20 +
drivers/net/intel/e1000/base/e1000_i225.c | 736 +++++++++++++++++++
drivers/net/intel/e1000/base/e1000_i225.h | 26 +
drivers/net/intel/e1000/base/e1000_nvm.c | 1 +
drivers/net/intel/e1000/base/e1000_phy.c | 63 ++
drivers/net/intel/e1000/base/e1000_phy.h | 6 +
drivers/net/intel/e1000/base/e1000_regs.h | 9 +
8 files changed, 901 insertions(+)
diff --git a/drivers/net/intel/e1000/base/e1000_defines.h b/drivers/net/intel/e1000/base/e1000_defines.h
index 0e33f27c3f..49e4f6c7cc 100644
--- a/drivers/net/intel/e1000/base/e1000_defines.h
+++ b/drivers/net/intel/e1000/base/e1000_defines.h
@@ -1055,6 +1055,15 @@
/* Firmware code revision field word offset*/
#define E1000_I210_FW_VER_OFFSET 328
+#define E1000_EECD_FLUPD_I225 0x00800000 /* Update FLASH */
+#define E1000_EECD_FLUDONE_I225 0x04000000 /* Update FLASH done */
+#define E1000_EECD_FLASH_DETECTED_I225 0x00080000 /* FLASH detected */
+#define E1000_FLUDONE_ATTEMPTS 20000
+#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
+#define E1000_EECD_SEC1VAL_I225 0x02000000 /* Sector One Valid */
+#define E1000_FLSECU_BLK_SW_ACCESS_I225 0x00000004 /* Block SW access */
+#define E1000_FWSM_FW_VALID_I225 0x8000 /* FW valid bit */
+
#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
#define E1000_NVM_RW_REG_START 1 /* Start operation */
@@ -1482,6 +1491,37 @@
#define I210_RXPBSIZE_DEFAULT 0x000000A2 /* RXPBSIZE default */
#define I210_TXPBSIZE_DEFAULT 0x04000014 /* TXPBSIZE default */
+#define E1000_STM_OPCODE 0xDB00
+#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
+#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
+ (u8)((invm_dword) & 0x7)
+#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
+ (u8)(((invm_dword) & 0x0000FE00) >> 9)
+#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
+ (u16)(((invm_dword) & 0xFFFF0000) >> 16)
+#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
+#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
+#define E1000_INVM_ULT_BYTES_SIZE 8
+#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
+#define E1000_INVM_VER_FIELD_ONE 0x1FF8
+#define E1000_INVM_VER_FIELD_TWO 0x7FE000
+#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
+
+#define E1000_INVM_MAJOR_MASK 0x3F0
+#define E1000_INVM_MINOR_MASK 0xF
+#define E1000_INVM_MAJOR_SHIFT 4
+
+/* PLL Defines */
+#define E1000_PCI_PMCSR 0x44
+#define E1000_PCI_PMCSR_D3 0x03
+#define E1000_MAX_PLL_TRIES 5
+#define E1000_PHY_PLL_UNCONF 0xFF
+#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000
+#define E1000_PHY_PLL_FREQ_REG 0x000E
+#define E1000_INVM_DEFAULT_AL 0x202F
+#define E1000_INVM_AUTOLOAD 0x0A
+#define E1000_INVM_PLL_WO_VAL 0x0010
+
/* Proxy Filter Control */
#define E1000_PROXYFC_D0 0x00000001 /* Enable offload in D0 */
diff --git a/drivers/net/intel/e1000/base/e1000_hw.h b/drivers/net/intel/e1000/base/e1000_hw.h
index a21cb070e0..c16dd1cbf7 100644
--- a/drivers/net/intel/e1000/base/e1000_hw.h
+++ b/drivers/net/intel/e1000/base/e1000_hw.h
@@ -381,6 +381,15 @@ enum e1000_serdes_link_state {
e1000_serdes_link_forced_up
};
+enum e1000_invm_structure_type {
+ e1000_invm_unitialized_structure = 0x00,
+ e1000_invm_word_autoload_structure = 0x01,
+ e1000_invm_csr_autoload_structure = 0x02,
+ e1000_invm_phy_register_autoload_structure = 0x03,
+ e1000_invm_rsa_key_sha256_structure = 0x04,
+ e1000_invm_invalidated_structure = 0x0f,
+};
+
#define __le16 u16
#define __le32 u32
#define __le64 u64
@@ -996,6 +1005,16 @@ struct e1000_dev_spec_vf {
u32 v2p_mailbox;
};
+struct e1000_dev_spec_i225 {
+ bool global_device_reset;
+ bool eee_disable;
+ bool clear_semaphore_once;
+ bool module_plugged;
+ u8 media_port;
+ bool mas_capable;
+ u32 mtu;
+};
+
struct e1000_hw {
void *back;
@@ -1020,6 +1039,7 @@ struct e1000_hw {
struct e1000_dev_spec_ich8lan ich8lan;
struct e1000_dev_spec_82575 _82575;
struct e1000_dev_spec_vf vf;
+ struct e1000_dev_spec_i225 _i225;
} dev_spec;
u16 device_id;
diff --git a/drivers/net/intel/e1000/base/e1000_i225.c b/drivers/net/intel/e1000/base/e1000_i225.c
index a7a42e2f0e..7c8cf8552d 100644
--- a/drivers/net/intel/e1000/base/e1000_i225.c
+++ b/drivers/net/intel/e1000/base/e1000_i225.c
@@ -4,9 +4,75 @@
#include "e1000_api.h"
+STATIC s32 e1000_init_nvm_params_i225(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw);
STATIC s32 e1000_init_phy_params_i225(struct e1000_hw *hw);
STATIC s32 e1000_reset_hw_i225(struct e1000_hw *hw);
+STATIC s32 e1000_acquire_nvm_i225(struct e1000_hw *hw);
+STATIC void e1000_release_nvm_i225(struct e1000_hw *hw);
+STATIC s32 e1000_get_hw_semaphore_i225(struct e1000_hw *hw);
+STATIC s32 __e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data);
+STATIC s32 e1000_pool_flash_update_done_i225(struct e1000_hw *hw);
+STATIC s32 e1000_valid_led_default_i225(struct e1000_hw *hw, u16 *data);
+
+/**
+ * e1000_init_nvm_params_i225 - Init NVM func ptrs.
+ * @hw: pointer to the HW structure
+ **/
+STATIC s32 e1000_init_nvm_params_i225(struct e1000_hw *hw)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ u32 eecd = E1000_READ_REG(hw, E1000_EECD);
+ u16 size;
+
+ DEBUGFUNC("e1000_init_nvm_params_i225");
+
+ size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
+ E1000_EECD_SIZE_EX_SHIFT);
+ /*
+ * Added to a constant, "size" becomes the left-shift value
+ * for setting word_size.
+ */
+ size += NVM_WORD_SIZE_BASE_SHIFT;
+
+ /* Just in case size is out of range, cap it to the largest
+ * EEPROM size supported
+ */
+ if (size > 15)
+ size = 15;
+
+ nvm->word_size = 1 << size;
+ nvm->opcode_bits = 8;
+ nvm->delay_usec = 1;
+ nvm->type = e1000_nvm_eeprom_spi;
+
+
+ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
+ nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
+ 16 : 8;
+
+ if (nvm->word_size == (1 << 15))
+ nvm->page_size = 128;
+
+ nvm->ops.acquire = e1000_acquire_nvm_i225;
+ nvm->ops.release = e1000_release_nvm_i225;
+ nvm->ops.valid_led_default = e1000_valid_led_default_i225;
+ if (e1000_get_flash_presence_i225(hw)) {
+ hw->nvm.type = e1000_nvm_flash_hw;
+ nvm->ops.read = e1000_read_nvm_srrd_i225;
+ nvm->ops.write = e1000_write_nvm_srwr_i225;
+ nvm->ops.validate = e1000_validate_nvm_checksum_i225;
+ nvm->ops.update = e1000_update_nvm_checksum_i225;
+ } else {
+ hw->nvm.type = e1000_nvm_none;
+ nvm->ops.write = e1000_null_write_nvm;
+ nvm->ops.validate = e1000_null_ops_generic;
+ nvm->ops.update = e1000_null_ops_generic;
+ }
+
+ return E1000_SUCCESS;
+}
/**
* e1000_init_mac_params_i225 - Init MAC func ptrs.
@@ -15,6 +81,7 @@ STATIC s32 e1000_reset_hw_i225(struct e1000_hw *hw);
STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
+ struct e1000_dev_spec_i225 *dev_spec = &hw->dev_spec._i225;
DEBUGFUNC("e1000_init_mac_params_i225");
@@ -38,8 +105,13 @@ STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw)
mac->ops.check_for_link = e1000_check_for_copper_link_generic;
/* link info */
mac->ops.get_link_up_info = e1000_get_speed_and_duplex_copper_generic;
+ /* acquire SW_FW sync */
+ mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i225;
+ /* release SW_FW sync */
+ mac->ops.release_swfw_sync = e1000_release_swfw_sync_i225;
/* Allow a single clear of the SW semaphore on I225 */
+ dev_spec->clear_semaphore_once = true;
mac->ops.setup_physical_interface = e1000_setup_copper_link_i225;
/* Set if part includes ASF firmware */
@@ -103,6 +175,8 @@ STATIC s32 e1000_init_phy_params_i225(struct e1000_hw *hw)
goto out;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+ phy->ops.read_reg = e1000_read_phy_reg_gpy;
+ phy->ops.write_reg = e1000_write_phy_reg_gpy;
ret_val = e1000_get_phy_id(hw);
@@ -177,6 +251,118 @@ STATIC s32 e1000_reset_hw_i225(struct e1000_hw *hw)
return ret_val;
}
+/* e1000_acquire_nvm_i225 - Request for access to EEPROM
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the necessary semaphores for exclusive access to the EEPROM.
+ * Set the EEPROM access request bit and wait for EEPROM access grant bit.
+ * Return successful if access grant bit set, else clear the request for
+ * EEPROM access and return -E1000_ERR_NVM (-1).
+ */
+STATIC s32 e1000_acquire_nvm_i225(struct e1000_hw *hw)
+{
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_acquire_nvm_i225");
+
+ ret_val = e1000_acquire_swfw_sync_i225(hw, E1000_SWFW_EEP_SM);
+
+ return ret_val;
+}
+
+/* e1000_release_nvm_i225 - Release exclusive access to EEPROM
+ * @hw: pointer to the HW structure
+ *
+ * Stop any current commands to the EEPROM and clear the EEPROM request bit,
+ * then release the semaphores acquired.
+ */
+STATIC void e1000_release_nvm_i225(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_release_nvm_i225");
+
+ e1000_release_swfw_sync_i225(hw, E1000_SWFW_EEP_SM);
+}
+
+/* e1000_acquire_swfw_sync_i225 - Acquire SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Acquire the SW/FW semaphore to access the PHY or NVM. The mask
+ * will also specify which port we're acquiring the lock for.
+ */
+s32 e1000_acquire_swfw_sync_i225(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+ u32 swmask = mask;
+ u32 fwmask = mask << 16;
+ s32 ret_val = E1000_SUCCESS;
+ s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
+
+ DEBUGFUNC("e1000_acquire_swfw_sync_i225");
+
+ while (i < timeout) {
+ if (e1000_get_hw_semaphore_i225(hw)) {
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
+ if (!(swfw_sync & (fwmask | swmask)))
+ break;
+
+ /* Firmware currently using resource (fwmask)
+ * or other software thread using resource (swmask)
+ */
+ e1000_put_hw_semaphore_generic(hw);
+ msec_delay_irq(5);
+ i++;
+ }
+
+ if (i == timeout) {
+ DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
+ ret_val = -E1000_ERR_SWFW_SYNC;
+ goto out;
+ }
+
+ swfw_sync |= swmask;
+ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
+
+ e1000_put_hw_semaphore_generic(hw);
+
+out:
+ return ret_val;
+}
+
+/* e1000_release_swfw_sync_i225 - Release SW/FW semaphore
+ * @hw: pointer to the HW structure
+ * @mask: specifies which semaphore to acquire
+ *
+ * Release the SW/FW semaphore used to access the PHY or NVM. The mask
+ * will also specify which port we're releasing the lock for.
+ */
+void e1000_release_swfw_sync_i225(struct e1000_hw *hw, u16 mask)
+{
+ u32 swfw_sync;
+
+ DEBUGFUNC("e1000_release_swfw_sync_i225");
+
+ /* Releasing the resource requires first getting the HW semaphore.
+ * If we fail to get the semaphore, there is nothing we can do,
+ * except log an error and quit. We are not allowed to hang here
+ * indefinitely, as it may cause denial of service or system crash.
+ */
+ if (e1000_get_hw_semaphore_i225(hw) != E1000_SUCCESS) {
+ DEBUGOUT("Failed to release SW_FW_SYNC.\n");
+ return;
+ }
+
+ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
+ swfw_sync &= ~(u32)mask;
+ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
+
+ e1000_put_hw_semaphore_generic(hw);
+}
+
/*
* e1000_setup_copper_link_i225 - Configure copper link settings
* @hw: pointer to the HW structure
@@ -207,6 +393,520 @@ s32 e1000_setup_copper_link_i225(struct e1000_hw *hw)
return ret_val;
}
+/* e1000_get_hw_semaphore_i225 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore to access the PHY or NVM
+ */
+STATIC s32 e1000_get_hw_semaphore_i225(struct e1000_hw *hw)
+{
+ u32 swsm;
+ s32 timeout = E1000_SWSM_TIMEOUT;
+ s32 i = 0;
+
+ DEBUGFUNC("e1000_get_hw_semaphore_i225");
+
+ /* Get the SW semaphore */
+ while (i < timeout) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ if (!(swsm & E1000_SWSM_SMBI))
+ break;
+
+ usec_delay(50);
+ i++;
+ }
+
+ if (i == timeout) {
+ /* In rare circumstances, the SW semaphore may already be held
+ * unintentionally. Clear the semaphore once before giving up.
+ */
+ if (hw->dev_spec._i225.clear_semaphore_once) {
+ hw->dev_spec._i225.clear_semaphore_once = false;
+ e1000_put_hw_semaphore_generic(hw);
+ for (i = 0; i < timeout; i++) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ if (!(swsm & E1000_SWSM_SMBI))
+ break;
+
+ usec_delay(50);
+ }
+ }
+
+ /* If we do not have the semaphore here, we have to give up. */
+ if (i == timeout) {
+ DEBUGOUT("Driver can't access device -\n");
+ DEBUGOUT("SMBI bit is set.\n");
+ return -E1000_ERR_NVM;
+ }
+ }
+
+ /* Get the FW semaphore. */
+ for (i = 0; i < timeout; i++) {
+ swsm = E1000_READ_REG(hw, E1000_SWSM);
+ E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
+
+ /* Semaphore acquired if bit latched */
+ if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
+ break;
+
+ usec_delay(50);
+ }
+
+ if (i == timeout) {
+ /* Release semaphores */
+ e1000_put_hw_semaphore_generic(hw);
+ DEBUGOUT("Driver can't access the NVM\n");
+ return -E1000_ERR_NVM;
+ }
+
+ return E1000_SUCCESS;
+}
+
+/* e1000_read_nvm_srrd_i225 - Reads Shadow Ram using EERD register
+ * @hw: pointer to the HW structure
+ * @offset: offset of word in the Shadow Ram to read
+ * @words: number of words to read
+ * @data: word read from the Shadow Ram
+ *
+ * Reads a 16 bit word from the Shadow Ram using the EERD register.
+ * Uses necessary synchronization semaphores.
+ */
+s32 e1000_read_nvm_srrd_i225(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ s32 status = E1000_SUCCESS;
+ u16 i, count;
+
+ DEBUGFUNC("e1000_read_nvm_srrd_i225");
+
+ /* We cannot hold synchronization semaphores for too long,
+ * because of forceful takeover procedure. However it is more efficient
+ * to read in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
+ count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
+ E1000_EERD_EEWR_MAX_COUNT : (words - i);
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ status = e1000_read_nvm_eerd(hw, offset, count,
+ data + i);
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ if (status != E1000_SUCCESS)
+ break;
+ }
+
+ return status;
+}
+
+/* e1000_write_nvm_srwr_i225 - Write to Shadow RAM using EEWR
+ * @hw: pointer to the HW structure
+ * @offset: offset within the Shadow RAM to be written to
+ * @words: number of words to write
+ * @data: 16 bit word(s) to be written to the Shadow RAM
+ *
+ * Writes data to Shadow RAM at offset using EEWR register.
+ *
+ * If e1000_update_nvm_checksum is not called after this function , the
+ * data will not be committed to FLASH and also Shadow RAM will most likely
+ * contain an invalid checksum.
+ *
+ * If error code is returned, data and Shadow RAM may be inconsistent - buffer
+ * partially written.
+ */
+s32 e1000_write_nvm_srwr_i225(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ s32 status = E1000_SUCCESS;
+ u16 i, count;
+
+ DEBUGFUNC("e1000_write_nvm_srwr_i225");
+
+ /* We cannot hold synchronization semaphores for too long,
+ * because of forceful takeover procedure. However it is more efficient
+ * to write in bursts than synchronizing access for each word.
+ */
+ for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
+ count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
+ E1000_EERD_EEWR_MAX_COUNT : (words - i);
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ status = __e1000_write_nvm_srwr(hw, offset, count,
+ data + i);
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ if (status != E1000_SUCCESS)
+ break;
+ }
+
+ return status;
+}
+
+/* __e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
+ * @hw: pointer to the HW structure
+ * @offset: offset within the Shadow Ram to be written to
+ * @words: number of words to write
+ * @data: 16 bit word(s) to be written to the Shadow Ram
+ *
+ * Writes data to Shadow Ram at offset using EEWR register.
+ *
+ * If e1000_update_nvm_checksum is not called after this function , the
+ * Shadow Ram will most likely contain an invalid checksum.
+ */
+STATIC s32 __e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
+ u16 *data)
+{
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ u32 i, k, eewr = 0;
+ u32 attempts = 100000;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("__e1000_write_nvm_srwr");
+
+ /* A check for invalid values: offset too large, too many words,
+ * too many words for the offset, and not enough words.
+ */
+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
+ (words == 0)) {
+ DEBUGOUT("nvm parameter(s) out of bounds\n");
+ ret_val = -E1000_ERR_NVM;
+ goto out;
+ }
+
+ for (i = 0; i < words; i++) {
+ ret_val = -E1000_ERR_NVM;
+ eewr = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) |
+ (data[i] << E1000_NVM_RW_REG_DATA) |
+ E1000_NVM_RW_REG_START;
+
+ E1000_WRITE_REG(hw, E1000_SRWR, eewr);
+
+ for (k = 0; k < attempts; k++) {
+ if (E1000_NVM_RW_REG_DONE &
+ E1000_READ_REG(hw, E1000_SRWR)) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ usec_delay(5);
+ }
+
+ if (ret_val != E1000_SUCCESS) {
+ DEBUGOUT("Shadow RAM write EEWR timed out\n");
+ break;
+ }
+ }
+
+out:
+ return ret_val;
+}
+
+/* e1000_validate_nvm_checksum_i225 - Validate EEPROM checksum
+ * @hw: pointer to the HW structure
+ *
+ * Calculates the EEPROM checksum by reading/adding each word of the EEPROM
+ * and then verifies that the sum of the EEPROM is equal to 0xBABA.
+ */
+s32 e1000_validate_nvm_checksum_i225(struct e1000_hw *hw)
+{
+ s32 status = E1000_SUCCESS;
+ s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
+
+ DEBUGFUNC("e1000_validate_nvm_checksum_i225");
+
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ /* Replace the read function with semaphore grabbing with
+ * the one that skips this for a while.
+ * We have semaphore taken already here.
+ */
+ read_op_ptr = hw->nvm.ops.read;
+ hw->nvm.ops.read = e1000_read_nvm_eerd;
+
+ status = e1000_validate_nvm_checksum_generic(hw);
+
+ /* Revert original read operation. */
+ hw->nvm.ops.read = read_op_ptr;
+
+ hw->nvm.ops.release(hw);
+ } else {
+ status = E1000_ERR_SWFW_SYNC;
+ }
+
+ return status;
+}
+
+/* e1000_update_nvm_checksum_i225 - Update EEPROM checksum
+ * @hw: pointer to the HW structure
+ *
+ * Updates the EEPROM checksum by reading/adding each word of the EEPROM
+ * up to the checksum. Then calculates the EEPROM checksum and writes the
+ * value to the EEPROM. Next commit EEPROM data onto the Flash.
+ */
+s32 e1000_update_nvm_checksum_i225(struct e1000_hw *hw)
+{
+ s32 ret_val;
+ u16 checksum = 0;
+ u16 i, nvm_data;
+
+ DEBUGFUNC("e1000_update_nvm_checksum_i225");
+
+ /* Read the first word from the EEPROM. If this times out or fails, do
+ * not continue or we could be in for a very long wait while every
+ * EEPROM read fails
+ */
+ ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
+ if (ret_val != E1000_SUCCESS) {
+ DEBUGOUT("EEPROM read failed\n");
+ goto out;
+ }
+
+ if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
+ /* Do not use hw->nvm.ops.write, hw->nvm.ops.read
+ * because we do not want to take the synchronization
+ * semaphores twice here.
+ */
+
+ for (i = 0; i < NVM_CHECKSUM_REG; i++) {
+ ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
+ if (ret_val) {
+ hw->nvm.ops.release(hw);
+ DEBUGOUT("NVM Read Error while updating\n");
+ DEBUGOUT("checksum.\n");
+ goto out;
+ }
+ checksum += nvm_data;
+ }
+ checksum = (u16)NVM_SUM - checksum;
+ ret_val = __e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
+ &checksum);
+ if (ret_val != E1000_SUCCESS) {
+ hw->nvm.ops.release(hw);
+ DEBUGOUT("NVM Write Error while updating checksum.\n");
+ goto out;
+ }
+
+ hw->nvm.ops.release(hw);
+
+ ret_val = e1000_update_flash_i225(hw);
+ } else {
+ ret_val = E1000_ERR_SWFW_SYNC;
+ }
+out:
+ return ret_val;
+}
+
+/* e1000_get_flash_presence_i225 - Check if flash device is detected.
+ * @hw: pointer to the HW structure
+ */
+bool e1000_get_flash_presence_i225(struct e1000_hw *hw)
+{
+ u32 eec = 0;
+ bool ret_val = false;
+
+ DEBUGFUNC("e1000_get_flash_presence_i225");
+
+ eec = E1000_READ_REG(hw, E1000_EECD);
+
+ if (eec & E1000_EECD_FLASH_DETECTED_I225)
+ ret_val = true;
+
+ return ret_val;
+}
+
+/* e1000_set_flsw_flash_burst_counter_i225 - sets FLSW NVM Burst
+ * Counter in FLSWCNT register.
+ *
+ * @hw: pointer to the HW structure
+ * @burst_counter: size in bytes of the Flash burst to read or write
+ */
+s32 e1000_set_flsw_flash_burst_counter_i225(struct e1000_hw *hw,
+ u32 burst_counter)
+{
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_set_flsw_flash_burst_counter_i225");
+
+ /* Validate input data */
+ if (burst_counter < E1000_I225_SHADOW_RAM_SIZE) {
+ /* Write FLSWCNT - burst counter */
+ E1000_WRITE_REG(hw, E1000_I225_FLSWCNT, burst_counter);
+ } else {
+ ret_val = E1000_ERR_INVALID_ARGUMENT;
+ }
+
+ return ret_val;
+}
+
+/* e1000_write_erase_flash_command_i225 - write/erase to a sector
+ * region on a given address.
+ *
+ * @hw: pointer to the HW structure
+ * @opcode: opcode to be used for the write command
+ * @address: the offset to write into the FLASH image
+ */
+s32 e1000_write_erase_flash_command_i225(struct e1000_hw *hw, u32 opcode,
+ u32 address)
+{
+ u32 flswctl = 0;
+ s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_write_erase_flash_command_i225");
+
+ flswctl = E1000_READ_REG(hw, E1000_I225_FLSWCTL);
+ /* Polling done bit on FLSWCTL register */
+ while (timeout) {
+ if (flswctl & E1000_FLSWCTL_DONE)
+ break;
+ usec_delay(5);
+ flswctl = E1000_READ_REG(hw, E1000_I225_FLSWCTL);
+ timeout--;
+ }
+
+ if (!timeout) {
+ DEBUGOUT("Flash transaction was not done\n");
+ return -E1000_ERR_NVM;
+ }
+
+ /* Build and issue command on FLSWCTL register */
+ flswctl = address | opcode;
+ E1000_WRITE_REG(hw, E1000_I225_FLSWCTL, flswctl);
+
+ /* Check if issued command is valid on FLSWCTL register */
+ flswctl = E1000_READ_REG(hw, E1000_I225_FLSWCTL);
+ if (!(flswctl & E1000_FLSWCTL_CMDV)) {
+ DEBUGOUT("Write flash command failed\n");
+ ret_val = E1000_ERR_INVALID_ARGUMENT;
+ }
+
+ return ret_val;
+}
+
+/* e1000_update_flash_i225 - Commit EEPROM to the flash
+ * if fw_valid_bit is set, FW is active. setting FLUPD bit in EEC
+ * register makes the FW load the internal shadow RAM into the flash.
+ * Otherwise, fw_valid_bit is 0. if FL_SECU.block_prtotected_sw = 0
+ * then FW is not active so the SW is responsible shadow RAM dump.
+ *
+ * @hw: pointer to the HW structure
+ */
+s32 e1000_update_flash_i225(struct e1000_hw *hw)
+{
+ u16 current_offset_data = 0;
+ u32 block_sw_protect = 1;
+ u16 base_address = 0x0;
+ u32 i, fw_valid_bit;
+ u16 current_offset;
+ s32 ret_val = 0;
+ u32 flup;
+
+ DEBUGFUNC("e1000_update_flash_i225");
+
+ block_sw_protect = E1000_READ_REG(hw, E1000_I225_FLSECU) &
+ E1000_FLSECU_BLK_SW_ACCESS_I225;
+ fw_valid_bit = E1000_READ_REG(hw, E1000_FWSM) &
+ E1000_FWSM_FW_VALID_I225;
+ if (fw_valid_bit) {
+ ret_val = e1000_pool_flash_update_done_i225(hw);
+ if (ret_val == -E1000_ERR_NVM) {
+ DEBUGOUT("Flash update time out\n");
+ goto out;
+ }
+
+ flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I225;
+ E1000_WRITE_REG(hw, E1000_EECD, flup);
+
+ ret_val = e1000_pool_flash_update_done_i225(hw);
+ if (ret_val == E1000_SUCCESS)
+ DEBUGOUT("Flash update complete\n");
+ else
+ DEBUGOUT("Flash update time out\n");
+ } else if (!block_sw_protect) {
+ /* FW is not active and security protection is disabled.
+ * therefore, SW is in charge of shadow RAM dump.
+ * Check which sector is valid. if sector 0 is valid,
+ * base address remains 0x0. otherwise, sector 1 is
+ * valid and it's base address is 0x1000
+ */
+ if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL_I225)
+ base_address = 0x1000;
+
+ /* Valid sector erase */
+ ret_val = e1000_write_erase_flash_command_i225(hw,
+ E1000_I225_ERASE_CMD_OPCODE,
+ base_address);
+ if (!ret_val) {
+ DEBUGOUT("Sector erase failed\n");
+ goto out;
+ }
+
+ current_offset = base_address;
+
+ /* Write */
+ for (i = 0; i < E1000_I225_SHADOW_RAM_SIZE / 2; i++) {
+ /* Set burst write length */
+ ret_val = e1000_set_flsw_flash_burst_counter_i225(hw,
+ 0x2);
+ if (ret_val != E1000_SUCCESS)
+ break;
+
+ /* Set address and opcode */
+ ret_val = e1000_write_erase_flash_command_i225(hw,
+ E1000_I225_WRITE_CMD_OPCODE,
+ 2 * current_offset);
+ if (ret_val != E1000_SUCCESS)
+ break;
+
+ ret_val = e1000_read_nvm_eerd(hw, current_offset,
+ 1, ¤t_offset_data);
+ if (ret_val) {
+ DEBUGOUT("Failed to read from EEPROM\n");
+ goto out;
+ }
+
+ /* Write CurrentOffseData to FLSWDATA register */
+ E1000_WRITE_REG(hw, E1000_I225_FLSWDATA,
+ current_offset_data);
+ current_offset++;
+
+ /* Wait till operation has finished */
+ ret_val = e1000_poll_eerd_eewr_done(hw,
+ E1000_NVM_POLL_READ);
+ if (ret_val)
+ break;
+
+ usec_delay(1000);
+ }
+ }
+out:
+ return ret_val;
+}
+
+/* e1000_pool_flash_update_done_i225 - Pool FLUDONE status.
+ * @hw: pointer to the HW structure
+ */
+s32 e1000_pool_flash_update_done_i225(struct e1000_hw *hw)
+{
+ s32 ret_val = -E1000_ERR_NVM;
+ u32 i, reg;
+
+ DEBUGFUNC("e1000_pool_flash_update_done_i225");
+
+ for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
+ reg = E1000_READ_REG(hw, E1000_EECD);
+ if (reg & E1000_EECD_FLUDONE_I225) {
+ ret_val = E1000_SUCCESS;
+ break;
+ }
+ usec_delay(5);
+ }
+
+ return ret_val;
+}
+
/* e1000_init_function_pointers_i225 - Init func ptrs.
* @hw: pointer to the HW structure
*
@@ -216,10 +916,46 @@ void e1000_init_function_pointers_i225(struct e1000_hw *hw)
{
e1000_init_mac_ops_generic(hw);
e1000_init_phy_ops_generic(hw);
+ e1000_init_nvm_ops_generic(hw);
hw->mac.ops.init_params = e1000_init_mac_params_i225;
+ hw->nvm.ops.init_params = e1000_init_nvm_params_i225;
hw->phy.ops.init_params = e1000_init_phy_params_i225;
}
+/* e1000_valid_led_default_i225 - Verify a valid default LED config
+ * @hw: pointer to the HW structure
+ * @data: pointer to the NVM (EEPROM)
+ *
+ * Read the EEPROM for the current default LED configuration. If the
+ * LED configuration is not valid, set to a valid LED configuration.
+ */
+STATIC s32 e1000_valid_led_default_i225(struct e1000_hw *hw, u16 *data)
+{
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_valid_led_default_i225");
+
+ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ goto out;
+ }
+
+ if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
+ switch (hw->phy.media_type) {
+ case e1000_media_type_internal_serdes:
+ *data = ID_LED_DEFAULT_I225_SERDES;
+ break;
+ case e1000_media_type_copper:
+ default:
+ *data = ID_LED_DEFAULT_I225;
+ break;
+ }
+ }
+out:
+ return ret_val;
+}
+
/* e1000_get_cfg_done_i225 - Read config done bit
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/intel/e1000/base/e1000_i225.h b/drivers/net/intel/e1000/base/e1000_i225.h
index 03e0f4fb89..be3b1b76eb 100644
--- a/drivers/net/intel/e1000/base/e1000_i225.h
+++ b/drivers/net/intel/e1000/base/e1000_i225.h
@@ -5,8 +5,22 @@
#ifndef _E1000_I225_H_
#define _E1000_I225_H_
+bool e1000_get_flash_presence_i225(struct e1000_hw *hw);
+s32 e1000_update_flash_i225(struct e1000_hw *hw);
+s32 e1000_update_nvm_checksum_i225(struct e1000_hw *hw);
+s32 e1000_validate_nvm_checksum_i225(struct e1000_hw *hw);
+s32 e1000_write_nvm_srwr_i225(struct e1000_hw *hw, u16 offset,
+ u16 words, u16 *data);
+s32 e1000_read_nvm_srrd_i225(struct e1000_hw *hw, u16 offset,
+ u16 words, u16 *data);
+s32 e1000_set_flsw_flash_burst_counter_i225(struct e1000_hw *hw,
+ u32 burst_counter);
+s32 e1000_write_erase_flash_command_i225(struct e1000_hw *hw, u32 opcode,
+ u32 address);
s32 e1000_id_led_init_i225(struct e1000_hw *hw);
s32 e1000_blink_led_i225(struct e1000_hw *hw);
+s32 e1000_acquire_swfw_sync_i225(struct e1000_hw *hw, u16 mask);
+void e1000_release_swfw_sync_i225(struct e1000_hw *hw, u16 mask);
s32 e1000_init_hw_i225(struct e1000_hw *hw);
s32 e1000_setup_copper_link_i225(struct e1000_hw *hw);
s32 e1000_set_d0_lplu_state_i225(struct e1000_hw *hw, bool active);
@@ -19,6 +33,18 @@ s32 e1000_set_d3_lplu_state_i225(struct e1000_hw *hw, bool active);
(ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_OFF1_ON2))
+/* NVM offset defaults for I225 devices */
+#define NVM_INIT_CTRL_2_DEFAULT_I225 0X7243
+#define NVM_INIT_CTRL_4_DEFAULT_I225 0x00C1
+#define NVM_LED_1_CFG_DEFAULT_I225 0x0184
+#define NVM_LED_0_2_CFG_DEFAULT_I225 0x200C
+
+#define E1000_I225_SHADOW_RAM_SIZE 4096
+#define E1000_I225_ERASE_CMD_OPCODE 0x02000000
+#define E1000_I225_WRITE_CMD_OPCODE 0x01000000
+#define E1000_FLSWCTL_DONE 0x40000000
+#define E1000_FLSWCTL_CMDV 0x10000000
+
/* LED Control */
#define E1000_GLOBAL_BLINK_MODE 0x00000020 /*Blink at 200 ms on and 200 ms off.*/
#define E1000_LED1_MODE_MASK 0x00000F00
diff --git a/drivers/net/intel/e1000/base/e1000_nvm.c b/drivers/net/intel/e1000/base/e1000_nvm.c
index 430fecaf6d..aec5e80986 100644
--- a/drivers/net/intel/e1000/base/e1000_nvm.c
+++ b/drivers/net/intel/e1000/base/e1000_nvm.c
@@ -1295,6 +1295,7 @@ void e1000_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
return;
}
/* fall through */
+ case e1000_i225:
case e1000_i350:
hw->nvm.ops.read(hw, NVM_ETRACK_HIWORD, 1, &etrack_test);
/* find combo image version */
diff --git a/drivers/net/intel/e1000/base/e1000_phy.c b/drivers/net/intel/e1000/base/e1000_phy.c
index a7e73112e5..6fac341d71 100644
--- a/drivers/net/intel/e1000/base/e1000_phy.c
+++ b/drivers/net/intel/e1000/base/e1000_phy.c
@@ -4171,6 +4171,69 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
return ret_val;
}
+/**
+ * e1000_write_phy_reg_gpy - Write GPY PHY register
+ * @hw: pointer to the HW structure
+ * @offset: register offset to write to
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore, if necessary, then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ s32 ret_val;
+ u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
+
+ DEBUGFUNC("e1000_write_phy_reg_gpy");
+
+ offset = offset & GPY_REG_MASK;
+
+ if (!dev_addr) {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+ ret_val = e1000_write_phy_reg_mdic(hw, offset, data);
+ hw->phy.ops.release(hw);
+ } else {
+ ret_val = e1000_write_xmdio_reg(hw, (u16)offset, dev_addr,
+ data);
+ }
+ return ret_val;
+}
+
+/**
+ * e1000_read_phy_reg_gpy - Read GPY PHY register
+ * @hw: pointer to the HW structure
+ * @offset: lower half is register offset to read to
+ * upper half is MMD to use.
+ * @data: data to read at register offset
+ *
+ * Acquires semaphore, if necessary, then reads the data in the PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 e1000_read_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ s32 ret_val;
+ u8 dev_addr = (offset & GPY_MMD_MASK) >> GPY_MMD_SHIFT;
+
+ DEBUGFUNC("e1000_read_phy_reg_gpy");
+
+ offset = offset & GPY_REG_MASK;
+
+ if (!dev_addr) {
+ ret_val = hw->phy.ops.acquire(hw);
+ if (ret_val)
+ return ret_val;
+ ret_val = e1000_read_phy_reg_mdic(hw, offset, data);
+ hw->phy.ops.release(hw);
+ } else {
+ ret_val = e1000_read_xmdio_reg(hw, (u16)offset, dev_addr,
+ data);
+ }
+ return ret_val;
+}
+
/**
* e1000_read_phy_reg_mphy - Read mPHY control register
* @hw: pointer to the HW structure
diff --git a/drivers/net/intel/e1000/base/e1000_phy.h b/drivers/net/intel/e1000/base/e1000_phy.h
index 87b4d407e5..a7834240e0 100644
--- a/drivers/net/intel/e1000/base/e1000_phy.h
+++ b/drivers/net/intel/e1000/base/e1000_phy.h
@@ -86,6 +86,8 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
+s32 e1000_write_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 data);
+s32 e1000_read_phy_reg_gpy(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data);
s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
bool line_override);
@@ -131,6 +133,10 @@ s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
#define E1000_I225_PHPM_ULP 0x0400 /* Ultra Low-Power Mode */
#define E1000_I225_PHPM_DIS_2500 0x0800 /* Disable 2.5G globally */
#define E1000_I225_PHPM_DIS_2500_D3 0x1000 /* Disable 2.5G in D3 */
+/* GPY211 - I225 defines */
+#define GPY_MMD_MASK 0xFFFF0000
+#define GPY_MMD_SHIFT 16
+#define GPY_REG_MASK 0x0000FFFF
/* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE 769
#define BM_WUC_PAGE 800
diff --git a/drivers/net/intel/e1000/base/e1000_regs.h b/drivers/net/intel/e1000/base/e1000_regs.h
index 20abeeaa46..b9d2a4484b 100644
--- a/drivers/net/intel/e1000/base/e1000_regs.h
+++ b/drivers/net/intel/e1000/base/e1000_regs.h
@@ -10,6 +10,9 @@
#define E1000_STATUS 0x00008 /* Device Status - RO */
#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */
#define E1000_EERD 0x00014 /* EEPROM Read - RW */
+#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
+#define E1000_EERD_V2 0x12014 /* EEprom mode read - RW */
+#define E1000_EEWR_V2 0x12018 /* EEprom mode write - RW */
#define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
#define E1000_FLA 0x0001C /* Flash Access - RW */
#define E1000_MDIC 0x00020 /* MDI Control - RW */
@@ -30,6 +33,11 @@
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXT 0x0002C /* Future Extended - RW */
+#define E1000_I225_FLA 0x1201C /* FLASH access register */
+#define E1000_I225_FLSWCTL 0x12048 /* FLASH control register */
+#define E1000_I225_FLSWDATA 0x1204C /* FLASH data register */
+#define E1000_I225_FLSWCNT 0x12050 /* FLASH Access Counter */
+#define E1000_I225_FLSECU 0x12114 /* FLASH Security */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
@@ -90,6 +98,7 @@
#define E1000_EEMNGCTL_I225 0x01010 /* i225 MNG EEprom Mode Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_EEARBC_I210 0x12024 /* EEPROM Auto Read Bus Control */
+#define E1000_EEARBC_I225 0x12024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
#define E1000_FLSWCTL 0x01030 /* FLASH control register */
--
2.43.5
next prev parent reply other threads:[~2025-01-31 12:59 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-31 12:58 [PATCH v1 00/42] Merge Intel IGC and E1000 drivers, and update E1000 base code Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 01/42] net/e1000/base: fix semaphore timeout value Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 02/42] net/e1000/base: add initial support for i225 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 03/42] net/e1000/base: add link bringup " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 04/42] net/e1000/base: add LED blink " Anatoly Burakov
2025-01-31 12:58 ` Anatoly Burakov [this message]
2025-01-31 12:58 ` [PATCH v1 06/42] net/e1000/base: add LTR support in i225 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 07/42] net/e1000/base: add eee support for i225 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 08/42] net/e1000/base: add misc definitions " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 09/42] net/e1000: merge igc with e1000 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 10/42] net/e1000: add missing i225 devices Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 11/42] net/e1000: add missing hardware support Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 12/42] net/e1000: add support for more I219 devices Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 13/42] net/e1000/base: correct minor formatting issues Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 14/42] net/e1000/base: correct mPHY access logic Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 15/42] net/e1000/base: skip MANC check for 82575 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 16/42] net/e1000/base: correct disable k1 logic Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 17/42] net/e1000/base: workaround for packet loss Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 18/42] net/e1000/base: add EEE common API function Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 19/42] net/e1000/base: add queue select definitions Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 20/42] net/e1000/base: add profile information field Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 21/42] net/e1000/base: add LPI counters Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 22/42] net/e1000/base: improve code flow in ICH8LAN Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 23/42] net/e1000/base: add definition for EXFWSM register Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 24/42] net/e1000/base: use longer ULP exit timeout on more HW Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 25/42] net/e1000/base: make e1000_access_phy_wakeup_reg_bm non-static Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 26/42] net/e1000/base: make debug prints more informative Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 27/42] net/e1000/base: add WoL definitions Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 28/42] net/e1000/base: hardcode bus parameters for ICH8 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 29/42] net/e1000/base: improve NVM checksum handling Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 30/42] net/e1000/base: remove redundant access to RO register Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 31/42] net/e1000/base: remove non-inclusive language Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 32/42] net/e1000/base: introduce PHY ID retry mechanism Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 33/42] net/e1000/base: add PHY read/write " Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 34/42] net/e1000/base: fix iterator type Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 35/42] net/e1000/base: fix static analysis warnings Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 36/42] net/e1000/base: fix reset for 82580 Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 37/42] net/e1000/base: fix mac addr hash bit_shift Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 38/42] net/e1000/base: fix uninitialized variable usage Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 39/42] net/e1000/base: fix unchecked return Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 40/42] net/e1000/base: fix data type in MAC hash Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 41/42] net/e1000/base: rename NVM version variable Anatoly Burakov
2025-01-31 12:58 ` [PATCH v1 42/42] net/e1000/base: update readme Anatoly Burakov
2025-01-31 13:11 ` [PATCH v1 00/42] Merge Intel IGC and E1000 drivers, and update E1000 base code Bruce Richardson
2025-01-31 13:13 ` 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=26e5f01f2f55270f3ec04dd8f452aae0cadb1462.1738328107.git.anatoly.burakov@intel.com \
--to=anatoly.burakov@intel.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).