[PATCH v1 02/42] net/e1000/base: add initial support for i225
Anatoly Burakov
anatoly.burakov at intel.com
Fri Jan 31 13:58:15 CET 2025
Add basic init, and PHY/MAC type support 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 at intel.com>
---
drivers/net/intel/e1000/base/e1000_api.c | 20 ++
drivers/net/intel/e1000/base/e1000_api.h | 1 +
drivers/net/intel/e1000/base/e1000_defines.h | 2 +
drivers/net/intel/e1000/base/e1000_hw.h | 19 ++
drivers/net/intel/e1000/base/e1000_i225.c | 211 +++++++++++++++++++
drivers/net/intel/e1000/base/e1000_i225.h | 10 +
drivers/net/intel/e1000/base/e1000_phy.c | 4 +
drivers/net/intel/e1000/base/e1000_regs.h | 1 +
drivers/net/intel/e1000/base/meson.build | 1 +
9 files changed, 269 insertions(+)
create mode 100644 drivers/net/intel/e1000/base/e1000_i225.c
create mode 100644 drivers/net/intel/e1000/base/e1000_i225.h
diff --git a/drivers/net/intel/e1000/base/e1000_api.c b/drivers/net/intel/e1000/base/e1000_api.c
index 6697b4b64f..1a7a737637 100644
--- a/drivers/net/intel/e1000/base/e1000_api.c
+++ b/drivers/net/intel/e1000/base/e1000_api.c
@@ -354,6 +354,23 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_82576_VF_HV:
mac->type = e1000_vfadapt;
break;
+ case E1000_DEV_ID_I225_LM:
+ case E1000_DEV_ID_I225_LMVP:
+ case E1000_DEV_ID_I225_V:
+ case E1000_DEV_ID_I225_K:
+ case E1000_DEV_ID_I225_I:
+ case E1000_DEV_ID_I225_IT:
+ case E1000_DEV_ID_I220_V:
+ case E1000_DEV_ID_I225_BLANK_NVM:
+ case E1000_DEV_ID_I226_LM:
+ case E1000_DEV_ID_I226_V:
+ case E1000_DEV_ID_I226_IT:
+ case E1000_DEV_ID_I226_K:
+ case E1000_DEV_ID_I221_V:
+ case E1000_DEV_ID_I226_LMVP:
+ case E1000_DEV_ID_I226_BLANK_NVM:
+ mac->type = e1000_i225;
+ break;
case E1000_DEV_ID_I350_VF:
case E1000_DEV_ID_I350_VF_HV:
mac->type = e1000_vfadapt_i350;
@@ -470,6 +487,9 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_i211:
e1000_init_function_pointers_i210(hw);
break;
+ case e1000_i225:
+ e1000_init_function_pointers_i225(hw);
+ break;
case e1000_vfadapt:
e1000_init_function_pointers_vf(hw);
break;
diff --git a/drivers/net/intel/e1000/base/e1000_api.h b/drivers/net/intel/e1000/base/e1000_api.h
index 6b38e2b7bb..2466c2fd48 100644
--- a/drivers/net/intel/e1000/base/e1000_api.h
+++ b/drivers/net/intel/e1000/base/e1000_api.h
@@ -19,6 +19,7 @@ extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
extern void e1000_power_up_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_shutdown_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
+extern void e1000_init_function_pointers_i225(struct e1000_hw *hw);
s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr);
s32 e1000_set_mac_type(struct e1000_hw *hw);
diff --git a/drivers/net/intel/e1000/base/e1000_defines.h b/drivers/net/intel/e1000/base/e1000_defines.h
index 97cc2797b2..cdc0703582 100644
--- a/drivers/net/intel/e1000/base/e1000_defines.h
+++ b/drivers/net/intel/e1000/base/e1000_defines.h
@@ -1257,6 +1257,8 @@
#define IGP04E1000_E_PHY_ID 0x02A80391
#define BCM54616_E_PHY_ID 0x03625D10
#define M88_VENDOR 0x0141
+#define I225_I_PHY_ID 0x67C9DC00
+#define I226_LM_PHY_ID 0x67C9DC10
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Reg */
diff --git a/drivers/net/intel/e1000/base/e1000_hw.h b/drivers/net/intel/e1000/base/e1000_hw.h
index c7e6903ecc..a21cb070e0 100644
--- a/drivers/net/intel/e1000/base/e1000_hw.h
+++ b/drivers/net/intel/e1000/base/e1000_hw.h
@@ -168,6 +168,22 @@ struct e1000_hw;
#define E1000_DEV_ID_I210_SERDES_FLASHLESS 0x157C
#define E1000_DEV_ID_I210_SGMII_FLASHLESS 0x15F6
#define E1000_DEV_ID_I211_COPPER 0x1539
+#define E1000_DEV_ID_I225_LM 0x15F2
+#define E1000_DEV_ID_I225_V 0x15F3
+#define E1000_DEV_ID_I225_K 0x3100
+#define E1000_DEV_ID_I225_K2 0x3101
+#define E1000_DEV_ID_I225_LMVP 0x5502
+#define E1000_DEV_ID_I225_IT 0x0D9F
+#define E1000_DEV_ID_I225_I 0x15F8
+#define E1000_DEV_ID_I220_V 0x15F7
+#define E1000_DEV_ID_I225_BLANK_NVM 0x15FD
+#define E1000_DEV_ID_I226_LM 0x125B
+#define E1000_DEV_ID_I226_V 0x125C
+#define E1000_DEV_ID_I226_IT 0x125D
+#define E1000_DEV_ID_I226_K 0x3102
+#define E1000_DEV_ID_I221_V 0x125E
+#define E1000_DEV_ID_I226_LMVP 0x5503
+#define E1000_DEV_ID_I226_BLANK_NVM 0x125F
#define E1000_DEV_ID_I354_BACKPLANE_1GBPS 0x1F40
#define E1000_DEV_ID_I354_SGMII 0x1F41
#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS 0x1F45
@@ -229,6 +245,7 @@ enum e1000_mac_type {
e1000_i354,
e1000_i210,
e1000_i211,
+ e1000_i225,
e1000_vfadapt,
e1000_vfadapt_i350,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
@@ -277,6 +294,7 @@ enum e1000_phy_type {
e1000_phy_82580,
e1000_phy_vf,
e1000_phy_i210,
+ e1000_phy_i225,
};
enum e1000_bus_type {
@@ -1019,6 +1037,7 @@ struct e1000_hw {
#include "e1000_ich8lan.h"
#include "e1000_82575.h"
#include "e1000_i210.h"
+#include "e1000_i225.h"
#include "e1000_base.h"
/* These functions must be implemented by drivers */
diff --git a/drivers/net/intel/e1000/base/e1000_i225.c b/drivers/net/intel/e1000/base/e1000_i225.c
new file mode 100644
index 0000000000..37acb29034
--- /dev/null
+++ b/drivers/net/intel/e1000/base/e1000_i225.c
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2024 Intel Corporation
+ */
+
+#include "e1000_api.h"
+
+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);
+
+/**
+ * e1000_init_mac_params_i225 - Init MAC func ptrs.
+ * @hw: pointer to the HW structure
+ **/
+STATIC s32 e1000_init_mac_params_i225(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+
+ DEBUGFUNC("e1000_init_mac_params_i225");
+
+ /* Initialize function pointer */
+ e1000_init_mac_ops_generic(hw);
+
+ /* Set media type */
+ hw->phy.media_type = e1000_media_type_copper;
+ /* Set mta register count */
+ mac->mta_reg_count = 128;
+ /* Set rar entry count */
+ mac->rar_entry_count = E1000_RAR_ENTRIES_BASE;
+ /* bus type/speed/width */
+ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
+ /* reset */
+ mac->ops.reset_hw = e1000_reset_hw_i225;
+ /* hw initialization */
+ mac->ops.init_hw = e1000_init_hw_i225;
+ /* link setup */
+ mac->ops.setup_link = e1000_setup_link_generic;
+ 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;
+
+ /* Set if part includes ASF firmware */
+ mac->asf_firmware_present = true;
+
+ /* multicast address update */
+ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
+
+ mac->ops.write_vfta = e1000_write_vfta_generic;
+
+ return E1000_SUCCESS;
+}
+
+/**
+ * e1000_init_phy_params_i225 - Init PHY func ptrs.
+ * @hw: pointer to the HW structure
+ **/
+STATIC s32 e1000_init_phy_params_i225(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+ s32 ret_val = E1000_SUCCESS;
+ u32 ctrl_ext;
+
+ DEBUGFUNC("e1000_init_phy_params_i225");
+
+ phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
+ phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
+
+ if (hw->phy.media_type != e1000_media_type_copper) {
+ phy->type = e1000_phy_none;
+ goto out;
+ }
+
+ phy->ops.power_up = e1000_power_up_phy_copper;
+ phy->ops.power_down = e1000_power_down_phy_copper_base;
+
+ phy->reset_delay_us = 100;
+
+ phy->ops.acquire = e1000_acquire_phy_base;
+ phy->ops.check_reset_block = e1000_check_reset_block_generic;
+ phy->ops.commit = e1000_phy_sw_reset_generic;
+ phy->ops.release = e1000_release_phy_base;
+ phy->ops.reset = e1000_phy_hw_reset_generic;
+
+ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
+
+ /* Make sure the PHY is in a good state. Several people have reported
+ * firmware leaving the PHY's page select register set to something
+ * other than the default of zero, which causes the PHY ID read to
+ * access something other than the intended register.
+ */
+ ret_val = hw->phy.ops.reset(hw);
+ if (ret_val)
+ goto out;
+
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_reset_hw_i225 - Reset hardware
+ * @hw: pointer to the HW structure
+ *
+ * This resets the hardware into a known state.
+ **/
+STATIC s32 e1000_reset_hw_i225(struct e1000_hw *hw)
+{
+ u32 ctrl;
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_reset_hw_i225");
+
+ /*
+ * Prevent the PCI-E bus from sticking if there is no TLP connection
+ * on the last TLP read/write transaction when MAC is reset.
+ */
+ ret_val = e1000_disable_pcie_master_generic(hw);
+ if (ret_val)
+ DEBUGOUT("PCI-E Master disable polling has failed.\n");
+
+ DEBUGOUT("Masking off all interrupts\n");
+ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
+
+ E1000_WRITE_REG(hw, E1000_RCTL, 0);
+ E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP);
+ E1000_WRITE_FLUSH(hw);
+
+ msec_delay(10);
+
+ ctrl = E1000_READ_REG(hw, E1000_CTRL);
+
+ DEBUGOUT("Issuing a global reset to MAC\n");
+ E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
+
+ ret_val = e1000_get_auto_rd_done_generic(hw);
+ if (ret_val) {
+ /*
+ * When auto config read does not complete, do not
+ * return with an error. This can happen in situations
+ * where there is no eeprom and prevents getting link.
+ */
+ DEBUGOUT("Auto Read Done did not complete\n");
+ }
+
+ /* Clear any pending interrupt events. */
+ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
+ E1000_READ_REG(hw, E1000_ICR);
+
+ /* Install any alternate MAC address into RAR0 */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+
+ return ret_val;
+}
+
+/* e1000_init_function_pointers_i225 - Init func ptrs.
+ * @hw: pointer to the HW structure
+ *
+ * Called to initialize all function pointers and parameters.
+ */
+void e1000_init_function_pointers_i225(struct e1000_hw *hw)
+{
+ e1000_init_mac_ops_generic(hw);
+ e1000_init_phy_ops_generic(hw);
+ hw->mac.ops.init_params = e1000_init_mac_params_i225;
+ hw->phy.ops.init_params = e1000_init_phy_params_i225;
+}
+
+/* e1000_get_cfg_done_i225 - Read config done bit
+ * @hw: pointer to the HW structure
+ *
+ * Read the management control register for the config done bit for
+ * completion status. NOTE: silicon which is EEPROM-less will fail trying
+ * to read the config done bit, so an error is *ONLY* logged and returns
+ * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon
+ * would not be able to be reset or change link.
+ */
+STATIC s32 e1000_get_cfg_done_i225(struct e1000_hw *hw)
+{
+ s32 timeout = PHY_CFG_TIMEOUT;
+ u32 mask = E1000_NVM_CFG_DONE_PORT_0;
+
+ DEBUGFUNC("e1000_get_cfg_done_i225");
+
+ while (timeout) {
+ if (E1000_READ_REG(hw, E1000_EEMNGCTL_I225) & mask)
+ break;
+ msec_delay(1);
+ timeout--;
+ }
+ if (!timeout)
+ DEBUGOUT("MNG configuration cycle has not completed.\n");
+
+ return E1000_SUCCESS;
+}
+
+/* e1000_init_hw_i225 - Init hw for I225
+ * @hw: pointer to the HW structure
+ *
+ * Called to initialize hw for i225 hw family.
+ */
+s32 e1000_init_hw_i225(struct e1000_hw *hw)
+{
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_init_hw_i225");
+
+ hw->phy.ops.get_cfg_done = e1000_get_cfg_done_i225;
+ ret_val = e1000_init_hw_base(hw);
+ return ret_val;
+}
diff --git a/drivers/net/intel/e1000/base/e1000_i225.h b/drivers/net/intel/e1000/base/e1000_i225.h
new file mode 100644
index 0000000000..8e38b75670
--- /dev/null
+++ b/drivers/net/intel/e1000/base/e1000_i225.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2001-2024 Intel Corporation
+ */
+
+#ifndef _E1000_I225_H_
+#define _E1000_I225_H_
+
+s32 e1000_init_hw_i225(struct e1000_hw *hw);
+
+#endif
diff --git a/drivers/net/intel/e1000/base/e1000_phy.c b/drivers/net/intel/e1000/base/e1000_phy.c
index 62d0be5080..4840094066 100644
--- a/drivers/net/intel/e1000/base/e1000_phy.c
+++ b/drivers/net/intel/e1000/base/e1000_phy.c
@@ -3023,6 +3023,10 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
case I210_I_PHY_ID:
phy_type = e1000_phy_i210;
break;
+ case I225_I_PHY_ID:
+ case I226_LM_PHY_ID:
+ phy_type = e1000_phy_i225;
+ break;
default:
phy_type = e1000_phy_unknown;
break;
diff --git a/drivers/net/intel/e1000/base/e1000_regs.h b/drivers/net/intel/e1000/base/e1000_regs.h
index 092d9d71e6..20abeeaa46 100644
--- a/drivers/net/intel/e1000/base/e1000_regs.h
+++ b/drivers/net/intel/e1000/base/e1000_regs.h
@@ -87,6 +87,7 @@
#define E1000_IOSFPC 0x00F28 /* TX corrupted data */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEMNGCTL_I210 0x01010 /* i210 MNG EEprom Mode Control */
+#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_FLASHT 0x01028 /* FLASH Timer Register */
diff --git a/drivers/net/intel/e1000/base/meson.build b/drivers/net/intel/e1000/base/meson.build
index e73f3d6d55..033b3af2e2 100644
--- a/drivers/net/intel/e1000/base/meson.build
+++ b/drivers/net/intel/e1000/base/meson.build
@@ -12,6 +12,7 @@ sources = [
'e1000_82575.c',
'e1000_api.c',
'e1000_i210.c',
+ 'e1000_i225.c',
'e1000_ich8lan.c',
'e1000_mac.c',
'e1000_manage.c',
--
2.43.5
More information about the dev
mailing list