aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuinan Sun <guinanx.sun@intel.com>2020-07-06 08:12:05 +0000
committerKevin Bowling <kbowling@FreeBSD.org>2021-09-24 01:21:34 +0000
commite4a16771e8f3307effe78ec64db35a09319b655a (patch)
tree6168eeb1550e1829ce06e36e901a1c0618db69e8
parent412d4675bbadb36135373272a298fd67d9c75df2 (diff)
downloadsrc-e4a16771e8f3307effe78ec64db35a09319b655a.tar.gz
src-e4a16771e8f3307effe78ec64db35a09319b655a.zip
e1000: remove duplicated phy codes
Add two files base.c and base.h to reduce the redundancy in the silicon family code. Remove the code duplication from e1000_82575 files. Clean family specific functions from base. Fix up a stray and duplicate function declaration. Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Sasha Neftin <sasha.neftin@intel.com> Signed-off-by: Guinan Sun <guinanx.sun@intel.com> Reviewed-by: Wei Zhao <wei.zhao1@intel.com> Approved by: imp Obtained from: DPDK (44dddd14059f151f39f7e075b887decfc9a10f11) MFC after: 1 week (cherry picked from commit 6b9d35fac12bf657cd1df8f1521c70704ff62b61)
-rw-r--r--sys/conf/files2
-rw-r--r--sys/dev/e1000/e1000_82575.c471
-rw-r--r--sys/dev/e1000/e1000_82575.h93
-rw-r--r--sys/dev/e1000/e1000_api.h1
-rw-r--r--sys/dev/e1000/e1000_base.c221
-rw-r--r--sys/dev/e1000/e1000_base.h158
-rw-r--r--sys/dev/e1000/e1000_defines.h14
-rw-r--r--sys/dev/e1000/e1000_hw.h1
-rw-r--r--sys/dev/e1000/e1000_i210.c2
-rw-r--r--sys/dev/e1000/e1000_regs.h23
-rw-r--r--sys/dev/e1000/if_em.c2
-rw-r--r--sys/dev/e1000/igb_txrx.c4
-rw-r--r--sys/modules/em/Makefile6
13 files changed, 578 insertions, 420 deletions
diff --git a/sys/conf/files b/sys/conf/files
index 5f6ec9a5c546..21239c31e83f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1677,6 +1677,8 @@ dev/e1000/e1000_i210.c optional em \
compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_api.c optional em \
compile-with "${NORMAL_C} -I$S/dev/e1000"
+dev/e1000/e1000_base.c optional em \
+ compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_mac.c optional em \
compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_manage.c optional em \
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index b252a4c7ff1d..172e99b02d5c 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -48,8 +48,6 @@
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
-static s32 e1000_acquire_phy_82575(struct e1000_hw *hw);
-static void e1000_release_phy_82575(struct e1000_hw *hw);
static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw);
static void e1000_release_nvm_82575(struct e1000_hw *hw);
static s32 e1000_check_for_link_82575(struct e1000_hw *hw);
@@ -61,6 +59,7 @@ static s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
static s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
u16 *data);
static s32 e1000_reset_hw_82575(struct e1000_hw *hw);
+static s32 e1000_init_hw_82575(struct e1000_hw *hw);
static s32 e1000_reset_hw_82580(struct e1000_hw *hw);
static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw,
u32 offset, u16 *data);
@@ -84,10 +83,8 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
u16 *speed, u16 *duplex);
static s32 e1000_get_phy_id_82575(struct e1000_hw *hw);
static bool e1000_sgmii_active_82575(struct e1000_hw *hw);
-static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
static void e1000_config_collision_dist_82575(struct e1000_hw *hw);
-static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
@@ -156,8 +153,8 @@ static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
}
/**
- * e1000_init_phy_params_82575 - Init PHY func ptrs.
- * @hw: pointer to the HW structure
+ * e1000_init_phy_params_82575 - Initialize PHY function ptrs
+ * @hw: pointer to the HW structure
**/
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
{
@@ -175,17 +172,17 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
goto out;
}
- phy->ops.power_up = e1000_power_up_phy_copper;
- phy->ops.power_down = e1000_power_down_phy_copper_82575;
+ phy->ops.power_up = e1000_power_up_phy_copper;
+ phy->ops.power_down = e1000_power_down_phy_copper_base;
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 100;
- phy->ops.acquire = e1000_acquire_phy_82575;
+ 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.get_cfg_done = e1000_get_cfg_done_82575;
- phy->ops.release = e1000_release_phy_82575;
+ phy->ops.release = e1000_release_phy_base;
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
@@ -232,76 +229,39 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID:
case M88E1340M_E_PHY_ID:
+ phy->type = e1000_phy_m88;
+ phy->ops.check_polarity = e1000_check_polarity_m88;
+ phy->ops.get_info = e1000_get_phy_info_m88;
+ phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2;
+ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
+ break;
case M88E1111_I_PHY_ID:
phy->type = e1000_phy_m88;
phy->ops.check_polarity = e1000_check_polarity_m88;
phy->ops.get_info = e1000_get_phy_info_m88;
- if (phy->id == I347AT4_E_PHY_ID ||
- phy->id == M88E1112_E_PHY_ID ||
- phy->id == M88E1340M_E_PHY_ID)
- phy->ops.get_cable_length =
- e1000_get_cable_length_m88_gen2;
- else if (phy->id == M88E1543_E_PHY_ID ||
- phy->id == M88E1512_E_PHY_ID)
- phy->ops.get_cable_length =
- e1000_get_cable_length_m88_gen2;
- else
- phy->ops.get_cable_length = e1000_get_cable_length_m88;
+ phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
- /* Check if this PHY is confgured for media swap. */
- if (phy->id == M88E1112_E_PHY_ID) {
- u16 data;
-
- ret_val = phy->ops.write_reg(hw,
- E1000_M88E1112_PAGE_ADDR,
- 2);
- if (ret_val)
- goto out;
-
- ret_val = phy->ops.read_reg(hw,
- E1000_M88E1112_MAC_CTRL_1,
- &data);
- if (ret_val)
- goto out;
-
- data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
- E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
- if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
- data == E1000_M88E1112_AUTO_COPPER_BASEX)
- hw->mac.ops.check_for_link =
- e1000_check_for_link_media_swap;
- }
- if (phy->id == M88E1512_E_PHY_ID) {
- ret_val = e1000_initialize_M88E1512_phy(hw);
- if (ret_val)
- goto out;
- }
- if (phy->id == M88E1543_E_PHY_ID) {
- ret_val = e1000_initialize_M88E1543_phy(hw);
- if (ret_val)
- goto out;
- }
break;
case IGP03E1000_E_PHY_ID:
case IGP04E1000_E_PHY_ID:
- phy->type = e1000_phy_igp_3;
- phy->ops.check_polarity = e1000_check_polarity_igp;
- phy->ops.get_info = e1000_get_phy_info_igp;
+ phy->type = e1000_phy_igp_3;
+ phy->ops.check_polarity = e1000_check_polarity_igp;
+ phy->ops.get_info = e1000_get_phy_info_igp;
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
- phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82575;
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
+ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
break;
case I82580_I_PHY_ID:
case I350_I_PHY_ID:
- phy->type = e1000_phy_82580;
- phy->ops.check_polarity = e1000_check_polarity_82577;
- phy->ops.force_speed_duplex =
- e1000_phy_force_speed_duplex_82577;
+ phy->type = e1000_phy_82580;
+ phy->ops.check_polarity = e1000_check_polarity_82577;
+ phy->ops.get_info = e1000_get_phy_info_82577;
phy->ops.get_cable_length = e1000_get_cable_length_82577;
- phy->ops.get_info = e1000_get_phy_info_82577;
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
+ phy->ops.force_speed_duplex =
+ e1000_phy_force_speed_duplex_82577;
break;
case I210_I_PHY_ID:
phy->type = e1000_phy_i210;
@@ -317,98 +277,49 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
goto out;
}
-out:
- return ret_val;
-}
-
-/**
- * e1000_init_nvm_params_82575 - Init NVM func ptrs.
- * @hw: pointer to the HW structure
- **/
-s32 e1000_init_nvm_params_82575(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_82575");
-
- 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;
- if (hw->mac.type < e1000_i210) {
- nvm->opcode_bits = 8;
- nvm->delay_usec = 1;
+ /* Check if this PHY is configured for media swap. */
+ switch (phy->id) {
+ case M88E1112_E_PHY_ID:
+ {
+ u16 data;
- switch (nvm->override) {
- case e1000_nvm_override_spi_large:
- nvm->page_size = 32;
- nvm->address_bits = 16;
- break;
- case e1000_nvm_override_spi_small:
- nvm->page_size = 8;
- nvm->address_bits = 8;
- break;
- default:
- nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
- nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
- 16 : 8;
- break;
- }
- if (nvm->word_size == (1 << 15))
- nvm->page_size = 128;
+ ret_val = phy->ops.write_reg(hw, E1000_M88E1112_PAGE_ADDR, 2);
+ if (ret_val)
+ goto out;
+ ret_val = phy->ops.read_reg(hw, E1000_M88E1112_MAC_CTRL_1,
+ &data);
+ if (ret_val)
+ goto out;
- nvm->type = e1000_nvm_eeprom_spi;
- } else {
- nvm->type = e1000_nvm_flash_hw;
+ data = (data & E1000_M88E1112_MAC_CTRL_1_MODE_MASK) >>
+ E1000_M88E1112_MAC_CTRL_1_MODE_SHIFT;
+ if (data == E1000_M88E1112_AUTO_COPPER_SGMII ||
+ data == E1000_M88E1112_AUTO_COPPER_BASEX)
+ hw->mac.ops.check_for_link =
+ e1000_check_for_link_media_swap;
+ break;
}
-
- /* Function Pointers */
- nvm->ops.acquire = e1000_acquire_nvm_82575;
- nvm->ops.release = e1000_release_nvm_82575;
- if (nvm->word_size < (1 << 15))
- nvm->ops.read = e1000_read_nvm_eerd;
- else
- nvm->ops.read = e1000_read_nvm_spi;
-
- nvm->ops.write = e1000_write_nvm_spi;
- nvm->ops.validate = e1000_validate_nvm_checksum_generic;
- nvm->ops.update = e1000_update_nvm_checksum_generic;
- nvm->ops.valid_led_default = e1000_valid_led_default_82575;
-
- /* override generic family function pointers for specific descendants */
- switch (hw->mac.type) {
- case e1000_82580:
- nvm->ops.validate = e1000_validate_nvm_checksum_82580;
- nvm->ops.update = e1000_update_nvm_checksum_82580;
+ case M88E1512_E_PHY_ID:
+ {
+ ret_val = e1000_initialize_M88E1512_phy(hw);
break;
- case e1000_i350:
- case e1000_i354:
- nvm->ops.validate = e1000_validate_nvm_checksum_i350;
- nvm->ops.update = e1000_update_nvm_checksum_i350;
+ }
+ case M88E1543_E_PHY_ID:
+ {
+ ret_val = e1000_initialize_M88E1543_phy(hw);
break;
+ }
default:
- break;
+ goto out;
}
- return E1000_SUCCESS;
+out:
+ return ret_val;
}
/**
- * e1000_init_mac_params_82575 - Init MAC func ptrs.
- * @hw: pointer to the HW structure
+ * e1000_init_mac_params_82575 - Init MAC func ptrs.
+ * @hw: pointer to the HW structure
**/
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
{
@@ -417,13 +328,16 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
DEBUGFUNC("e1000_init_mac_params_82575");
+ /* Initialize function pointer */
+ e1000_init_mac_ops_generic(hw);
+
/* Derives media type */
e1000_get_media_type_82575(hw);
- /* Set mta register count */
+ /* Set MTA register count */
mac->mta_reg_count = 128;
- /* Set uta register count */
+ /* Set UTA register count */
mac->uta_reg_count = (hw->mac.type == e1000_82575) ? 0 : 128;
- /* Set rar entry count */
+ /* Set RAR entry count */
mac->rar_entry_count = E1000_RAR_ENTRIES_82575;
if (mac->type == e1000_82576)
mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
@@ -456,8 +370,8 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
if (mac->type >= e1000_82580)
mac->ops.reset_hw = e1000_reset_hw_82580;
else
- mac->ops.reset_hw = e1000_reset_hw_82575;
- /* hw initialization */
+ mac->ops.reset_hw = e1000_reset_hw_82575;
+ /* HW initialization */
if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
mac->ops.init_hw = e1000_init_hw_i210;
else
@@ -493,7 +407,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
}
if (hw->mac.type >= e1000_82580)
mac->ops.validate_mdi_setting =
- e1000_validate_mdi_setting_crossover_generic;
+ e1000_validate_mdi_setting_crossover_generic;
/* ID LED init */
mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */
@@ -511,6 +425,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
/* acquire SW_FW sync */
mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync;
+ /* release SW_FW sync */
mac->ops.release_swfw_sync = e1000_release_swfw_sync;
/* set lan id for port to determine which phy lock to use */
@@ -520,63 +435,102 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
}
/**
- * e1000_init_function_pointers_82575 - Init func ptrs.
- * @hw: pointer to the HW structure
- *
- * Called to initialize all function pointers and parameters.
+ * e1000_init_nvm_params_82575 - Initialize NVM function ptrs
+ * @hw: pointer to the HW structure
**/
-void e1000_init_function_pointers_82575(struct e1000_hw *hw)
+s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
{
- DEBUGFUNC("e1000_init_function_pointers_82575");
+ struct e1000_nvm_info *nvm = &hw->nvm;
+ u32 eecd = E1000_READ_REG(hw, E1000_EECD);
+ u16 size;
- hw->mac.ops.init_params = e1000_init_mac_params_82575;
- hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
- hw->phy.ops.init_params = e1000_init_phy_params_82575;
- hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
-}
+ DEBUGFUNC("e1000_init_nvm_params_82575");
-/**
- * e1000_acquire_phy_82575 - Acquire rights to access PHY
- * @hw: pointer to the HW structure
- *
- * Acquire access rights to the correct PHY.
- **/
-static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
-{
- u16 mask = E1000_SWFW_PHY0_SM;
+ 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;
- DEBUGFUNC("e1000_acquire_phy_82575");
+ /* Just in case size is out of range, cap it to the largest
+ * EEPROM size supported
+ */
+ if (size > 15)
+ size = 15;
- if (hw->bus.func == E1000_FUNC_1)
- mask = E1000_SWFW_PHY1_SM;
- else if (hw->bus.func == E1000_FUNC_2)
- mask = E1000_SWFW_PHY2_SM;
- else if (hw->bus.func == E1000_FUNC_3)
- mask = E1000_SWFW_PHY3_SM;
+ nvm->word_size = 1 << size;
+ if (hw->mac.type < e1000_i210) {
+ nvm->opcode_bits = 8;
+ nvm->delay_usec = 1;
+
+ switch (nvm->override) {
+ case e1000_nvm_override_spi_large:
+ nvm->page_size = 32;
+ nvm->address_bits = 16;
+ break;
+ case e1000_nvm_override_spi_small:
+ nvm->page_size = 8;
+ nvm->address_bits = 8;
+ break;
+ default:
+ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8;
+ nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ?
+ 16 : 8;
+ break;
+ }
+ if (nvm->word_size == (1 << 15))
+ nvm->page_size = 128;
+
+ nvm->type = e1000_nvm_eeprom_spi;
+ } else {
+ nvm->type = e1000_nvm_flash_hw;
+ }
+
+ /* Function Pointers */
+ nvm->ops.acquire = e1000_acquire_nvm_82575;
+ nvm->ops.release = e1000_release_nvm_82575;
+ if (nvm->word_size < (1 << 15))
+ nvm->ops.read = e1000_read_nvm_eerd;
+ else
+ nvm->ops.read = e1000_read_nvm_spi;
+
+ nvm->ops.write = e1000_write_nvm_spi;
+ nvm->ops.validate = e1000_validate_nvm_checksum_generic;
+ nvm->ops.update = e1000_update_nvm_checksum_generic;
+ nvm->ops.valid_led_default = e1000_valid_led_default_82575;
+
+ /* override generic family function pointers for specific descendants */
+ switch (hw->mac.type) {
+ case e1000_82580:
+ nvm->ops.validate = e1000_validate_nvm_checksum_82580;
+ nvm->ops.update = e1000_update_nvm_checksum_82580;
+ break;
+ case e1000_i350:
+ nvm->ops.validate = e1000_validate_nvm_checksum_i350;
+ nvm->ops.update = e1000_update_nvm_checksum_i350;
+ break;
+ default:
+ break;
+ }
- return hw->mac.ops.acquire_swfw_sync(hw, mask);
+ return E1000_SUCCESS;
}
/**
- * e1000_release_phy_82575 - Release rights to access PHY
+ * e1000_init_function_pointers_82575 - Init func ptrs.
* @hw: pointer to the HW structure
*
- * A wrapper to release access rights to the correct PHY.
+ * Called to initialize all function pointers and parameters.
**/
-static void e1000_release_phy_82575(struct e1000_hw *hw)
+void e1000_init_function_pointers_82575(struct e1000_hw *hw)
{
- u16 mask = E1000_SWFW_PHY0_SM;
-
- DEBUGFUNC("e1000_release_phy_82575");
-
- if (hw->bus.func == E1000_FUNC_1)
- mask = E1000_SWFW_PHY1_SM;
- else if (hw->bus.func == E1000_FUNC_2)
- mask = E1000_SWFW_PHY2_SM;
- else if (hw->bus.func == E1000_FUNC_3)
- mask = E1000_SWFW_PHY3_SM;
+ DEBUGFUNC("e1000_init_function_pointers_82575");
- hw->mac.ops.release_swfw_sync(hw, mask);
+ hw->mac.ops.init_params = e1000_init_mac_params_82575;
+ hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
+ hw->phy.ops.init_params = e1000_init_phy_params_82575;
+ hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
}
/**
@@ -1401,16 +1355,15 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
}
/**
- * e1000_init_hw_82575 - Initialize hardware
- * @hw: pointer to the HW structure
+ * e1000_init_hw_82575 - Initialize hardware
+ * @hw: pointer to the HW structure
*
- * This inits the hardware readying it for operation.
+ * This inits the hardware readying it for operation.
**/
-s32 e1000_init_hw_82575(struct e1000_hw *hw)
+STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
s32 ret_val;
- u16 i, rar_count = mac->rar_entry_count;
DEBUGFUNC("e1000_init_hw_82575");
@@ -1425,27 +1378,12 @@ s32 e1000_init_hw_82575(struct e1000_hw *hw)
DEBUGOUT("Initializing the IEEE VLAN\n");
mac->ops.clear_vfta(hw);
- /* Setup the receive address */
- e1000_init_rx_addrs_generic(hw, rar_count);
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
- for (i = 0; i < mac->mta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
-
- /* Zero out the Unicast HASH table */
- DEBUGOUT("Zeroing the UTA\n");
- for (i = 0; i < mac->uta_reg_count; i++)
- E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
-
- /* Setup link and flow control */
- ret_val = mac->ops.setup_link(hw);
+ ret_val = e1000_init_hw_base(hw);
/* Set the default MTU size */
hw->dev_spec._82575.mtu = 1500;
- /*
- * Clear all of the statistics registers (clear on read). It is
+ /* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there
* is no link.
@@ -1454,7 +1392,6 @@ s32 e1000_init_hw_82575(struct e1000_hw *hw)
return ret_val;
}
-
/**
* e1000_setup_copper_link_82575 - Configure copper link settings
* @hw: pointer to the HW structure
@@ -1465,9 +1402,9 @@ s32 e1000_init_hw_82575(struct e1000_hw *hw)
**/
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
{
+ u32 phpm_reg;
u32 ctrl;
s32 ret_val;
- u32 phpm_reg;
DEBUGFUNC("e1000_setup_copper_link_82575");
@@ -1889,7 +1826,7 @@ static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
* Inits recommended HW defaults after a reset when there is no EEPROM
* detected. This is only for the 82575.
**/
-static s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
+s32 e1000_reset_init_script_82575(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_reset_init_script_82575");
@@ -1968,27 +1905,6 @@ static void e1000_config_collision_dist_82575(struct e1000_hw *hw)
}
/**
- * e1000_power_down_phy_copper_82575 - Remove link during PHY power down
- * @hw: pointer to the HW structure
- *
- * In the case of a PHY power down to save power, or to turn off link during a
- * driver unload, or wake on lan is not enabled, remove the link.
- **/
-static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
-{
- struct e1000_phy_info *phy = &hw->phy;
-
- if (!(phy->ops.check_reset_block))
- return;
-
- /* If the management interface is not enabled, then power down */
- if (!(e1000_enable_mng_pass_thru(hw) || phy->ops.check_reset_block(hw)))
- e1000_power_down_phy_copper(hw);
-
- return;
-}
-
-/**
* e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
@@ -2054,85 +1970,6 @@ static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
}
/**
- * e1000_rx_fifo_flush_82575 - Clean rx fifo after Rx enable
- * @hw: pointer to the HW structure
- *
- * After Rx enable, if manageability is enabled then there is likely some
- * bad data at the start of the fifo and possibly in the DMA fifo. This
- * function clears the fifos and flushes any packets that came in as rx was
- * being enabled.
- **/
-void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
-{
- u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
- int i, ms_wait;
-
- DEBUGFUNC("e1000_rx_fifo_flush_82575");
-
- /* disable IPv6 options as per hardware errata */
- rfctl = E1000_READ_REG(hw, E1000_RFCTL);
- rfctl |= E1000_RFCTL_IPV6_EX_DIS;
- E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
-
- if (hw->mac.type != e1000_82575 ||
- !(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
- return;
-
- /* Disable all Rx queues */
- for (i = 0; i < 4; i++) {
- rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
- E1000_WRITE_REG(hw, E1000_RXDCTL(i),
- rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
- }
- /* Poll all queues to verify they have shut down */
- for (ms_wait = 0; ms_wait < 10; ms_wait++) {
- msec_delay(1);
- rx_enabled = 0;
- for (i = 0; i < 4; i++)
- rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
- if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
- break;
- }
-
- if (ms_wait == 10)
- DEBUGOUT("Queue disable timed out after 10ms\n");
-
- /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
- * incoming packets are rejected. Set enable and wait 2ms so that
- * any packet that was coming in as RCTL.EN was set is flushed
- */
- E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
-
- rlpml = E1000_READ_REG(hw, E1000_RLPML);
- E1000_WRITE_REG(hw, E1000_RLPML, 0);
-
- rctl = E1000_READ_REG(hw, E1000_RCTL);
- temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
- temp_rctl |= E1000_RCTL_LPE;
-
- E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
- E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
- E1000_WRITE_FLUSH(hw);
- msec_delay(2);
-
- /* Enable Rx queues that were previously enabled and restore our
- * previous state
- */
- for (i = 0; i < 4; i++)
- E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
- E1000_WRITE_REG(hw, E1000_RCTL, rctl);
- E1000_WRITE_FLUSH(hw);
-
- E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
- E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
-
- /* Flush receive errors generated by workaround */
- E1000_READ_REG(hw, E1000_ROC);
- E1000_READ_REG(hw, E1000_RNBC);
- E1000_READ_REG(hw, E1000_MPC);
-}
-
-/**
* e1000_set_pcie_completion_timeout - set pci-e completion timeout
* @hw: pointer to the HW structure
*
diff --git a/sys/dev/e1000/e1000_82575.h b/sys/dev/e1000/e1000_82575.h
index 22c2f8c4a2f5..d6665bfe64dd 100644
--- a/sys/dev/e1000/e1000_82575.h
+++ b/sys/dev/e1000/e1000_82575.h
@@ -56,9 +56,7 @@
#define E1000_RAR_ENTRIES_I350 32
#define E1000_SW_SYNCH_MB 0x00000100
#define E1000_STAT_DEV_RST_SET 0x00100000
-#define E1000_CTRL_DEV_RST 0x20000000
-#ifdef E1000_BIT_FIELDS
struct e1000_adv_data_desc {
__le64 buffer_addr; /* Address of the descriptor's data buffer */
union {
@@ -121,7 +119,6 @@ struct e1000_adv_context_desc {
} fields;
} l4_setup;
};
-#endif
/* SRRCTL bit definitions */
#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
@@ -181,46 +178,12 @@ struct e1000_adv_context_desc {
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define E1000_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */
#define E1000_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */
-#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
#define E1000_IMIREXT_CTRL_URG 0x00002000 /* Check URG bit in header */
#define E1000_IMIREXT_CTRL_ACK 0x00004000 /* Check ACK bit in header */
#define E1000_IMIREXT_CTRL_PSH 0x00008000 /* Check PSH bit in header */
#define E1000_IMIREXT_CTRL_RST 0x00010000 /* Check RST bit in header */
#define E1000_IMIREXT_CTRL_SYN 0x00020000 /* Check SYN bit in header */
#define E1000_IMIREXT_CTRL_FIN 0x00040000 /* Check FIN bit in header */
-#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
-
-/* Receive Descriptor - Advanced */
-union e1000_adv_rx_desc {
- struct {
- __le64 pkt_addr; /* Packet buffer address */
- __le64 hdr_addr; /* Header buffer address */
- } read;
- struct {
- struct {
- union {
- __le32 data;
- struct {
- __le16 pkt_info; /*RSS type, Pkt type*/
- /* Split Header, header buffer len */
- __le16 hdr_info;
- } hs_rss;
- } lo_dword;
- union {
- __le32 rss; /* RSS Hash */
- struct {
- __le16 ip_id; /* IP id */
- __le16 csum; /* Packet Checksum */
- } csum_ip;
- } hi_dword;
- } lower;
- struct {
- __le32 status_error; /* ext status/error */
- __le16 length; /* Packet length */
- __le16 vlan; /* VLAN tag */
- } upper;
- } wb; /* writeback */
-};
#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F
#define E1000_RXDADV_RSSTYPE_SHIFT 12
@@ -229,7 +192,6 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_SPLITHEADER_EN 0x00001000
#define E1000_RXDADV_SPH 0x8000
#define E1000_RXDADV_STAT_TS 0x10000 /* Pkt was time stamped */
-#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
#define E1000_RXDADV_ERR_HBO 0x00800000
/* RSS Hash results */
@@ -278,20 +240,6 @@ union e1000_adv_rx_desc {
#define E1000_RXDADV_IPSEC_ERROR_INVALID_LENGTH 0x10000000
#define E1000_RXDADV_IPSEC_ERROR_AUTHENTICATION_FAILED 0x18000000
-/* Transmit Descriptor - Advanced */
-union e1000_adv_tx_desc {
- struct {
- __le64 buffer_addr; /* Address of descriptor's data buf */
- __le32 cmd_type_len;
- __le32 olinfo_status;
- } read;
- struct {
- __le64 rsvd; /* Reserved */
- __le32 nxtseq_seed;
- __le32 status;
- } wb;
-};
-
/* Adv Transmit Descriptor Config Masks */
#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
@@ -314,33 +262,6 @@ union e1000_adv_tx_desc {
#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
-/* Context descriptors */
-struct e1000_adv_tx_context_desc {
- __le32 vlan_macip_lens;
- __le32 seqnum_seed;
- __le32 type_tucmd_mlhl;
- __le32 mss_l4len_idx;
-};
-
-#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
-#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
-#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
-#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
-#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
-#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
-#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
-#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
-/* IPSec Encrypt Enable for ESP */
-#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
-/* Req requires Markers and CRC */
-#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000
-#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
-#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
-/* Adv ctxt IPSec SA IDX mask */
-#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF
-/* Adv ctxt IPSec ESP len mask */
-#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
-
/* Additional Transmit Descriptor Control definitions */
#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
#define E1000_TXDCTL_SWFLSH 0x04000000 /* Tx Desc. wbk flushing */
@@ -380,11 +301,6 @@ struct e1000_adv_tx_context_desc {
#define E1000_IMS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
#define E1000_ICS_LSECPNS E1000_ICR_LSECPNS /* PN threshold - server */
-/* ETQF register bit definitions */
-#define E1000_ETQF_FILTER_ENABLE (1 << 26)
-#define E1000_ETQF_IMM_INT (1 << 29)
-#define E1000_ETQF_1588 (1 << 30)
-#define E1000_ETQF_QUEUE_ENABLE (1U << 31)
/*
* ETQF filter list: one static filter per filter consumer. This is
* to avoid filter collisions later. Add new filters
@@ -395,10 +311,6 @@ struct e1000_adv_tx_context_desc {
*/
#define E1000_ETQF_FILTER_EAPOL 0
-#define E1000_FTQF_VF_BP 0x00008000
-#define E1000_FTQF_1588_TIME_STAMP 0x08000000
-#define E1000_FTQF_MASK 0xF0000000
-#define E1000_FTQF_MASK_PROTO_BP 0x10000000
#define E1000_FTQF_MASK_SOURCE_ADDR_BP 0x20000000
#define E1000_FTQF_MASK_DEST_ADDR_BP 0x40000000
#define E1000_FTQF_MASK_SOURCE_PORT_BP 0x80000000
@@ -474,13 +386,14 @@ struct e1000_adv_tx_context_desc {
#define ALL_QUEUES 0xFFFF
+s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
+s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
+
/* Rx packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
-s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
-s32 e1000_init_hw_82575(struct e1000_hw *hw);
enum e1000_promisc_type {
e1000_promisc_disabled = 0, /* all promisc modes disabled */
diff --git a/sys/dev/e1000/e1000_api.h b/sys/dev/e1000/e1000_api.h
index 7e052910e7d0..db4caac37e97 100644
--- a/sys/dev/e1000/e1000_api.h
+++ b/sys/dev/e1000/e1000_api.h
@@ -46,7 +46,6 @@ extern void e1000_init_function_pointers_82541(struct e1000_hw *hw);
extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw);
extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
-extern void e1000_rx_fifo_flush_82575(struct e1000_hw *hw);
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);
diff --git a/sys/dev/e1000/e1000_base.c b/sys/dev/e1000/e1000_base.c
new file mode 100644
index 000000000000..e12a5fbecf25
--- /dev/null
+++ b/sys/dev/e1000/e1000_base.c
@@ -0,0 +1,221 @@
+/******************************************************************************
+ SPDX-License-Identifier: BSD-3-Clause
+
+ Copyright (c) 2001-2020, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+/*$FreeBSD$*/
+
+#include "e1000_hw.h"
+#include "e1000_82575.h"
+#include "e1000_mac.h"
+#include "e1000_base.h"
+#include "e1000_manage.h"
+
+/**
+ * e1000_acquire_phy_base - Acquire rights to access PHY
+ * @hw: pointer to the HW structure
+ *
+ * Acquire access rights to the correct PHY.
+ **/
+s32 e1000_acquire_phy_base(struct e1000_hw *hw)
+{
+ u16 mask = E1000_SWFW_PHY0_SM;
+
+ DEBUGFUNC("e1000_acquire_phy_base");
+
+ if (hw->bus.func == E1000_FUNC_1)
+ mask = E1000_SWFW_PHY1_SM;
+ else if (hw->bus.func == E1000_FUNC_2)
+ mask = E1000_SWFW_PHY2_SM;
+ else if (hw->bus.func == E1000_FUNC_3)
+ mask = E1000_SWFW_PHY3_SM;
+
+ return hw->mac.ops.acquire_swfw_sync(hw, mask);
+}
+
+/**
+ * e1000_release_phy_base - Release rights to access PHY
+ * @hw: pointer to the HW structure
+ *
+ * A wrapper to release access rights to the correct PHY.
+ **/
+void e1000_release_phy_base(struct e1000_hw *hw)
+{
+ u16 mask = E1000_SWFW_PHY0_SM;
+
+ DEBUGFUNC("e1000_release_phy_base");
+
+ if (hw->bus.func == E1000_FUNC_1)
+ mask = E1000_SWFW_PHY1_SM;
+ else if (hw->bus.func == E1000_FUNC_2)
+ mask = E1000_SWFW_PHY2_SM;
+ else if (hw->bus.func == E1000_FUNC_3)
+ mask = E1000_SWFW_PHY3_SM;
+
+ hw->mac.ops.release_swfw_sync(hw, mask);
+}
+
+/**
+ * e1000_init_hw_base - Initialize hardware
+ * @hw: pointer to the HW structure
+ *
+ * This inits the hardware readying it for operation.
+ **/
+s32 e1000_init_hw_base(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ s32 ret_val;
+ u16 i, rar_count = mac->rar_entry_count;
+
+ DEBUGFUNC("e1000_init_hw_base");
+
+ /* Setup the receive address */
+ e1000_init_rx_addrs_generic(hw, rar_count);
+
+ /* Zero out the Multicast HASH table */
+ DEBUGOUT("Zeroing the MTA\n");
+ for (i = 0; i < mac->mta_reg_count; i++)
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
+
+ /* Zero out the Unicast HASH table */
+ DEBUGOUT("Zeroing the UTA\n");
+ for (i = 0; i < mac->uta_reg_count; i++)
+ E1000_WRITE_REG_ARRAY(hw, E1000_UTA, i, 0);
+
+ /* Setup link and flow control */
+ ret_val = mac->ops.setup_link(hw);
+
+ /* Clear all of the statistics registers (clear on read). It is
+ * important that we do this after we have tried to establish link
+ * because the symbol error count will increment wildly if there
+ * is no link.
+ */
+ e1000_clear_hw_cntrs_base_generic(hw);
+
+ return ret_val;
+}
+
+/**
+ * e1000_power_down_phy_copper_base - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+void e1000_power_down_phy_copper_base(struct e1000_hw *hw)
+{
+ struct e1000_phy_info *phy = &hw->phy;
+
+ if (!(phy->ops.check_reset_block))
+ return;
+
+ /* If the management interface is not enabled, then power down */
+ if (phy->ops.check_reset_block(hw))
+ e1000_power_down_phy_copper(hw);
+}
+
+/**
+ * e1000_rx_fifo_flush_base - Clean Rx FIFO after Rx enable
+ * @hw: pointer to the HW structure
+ *
+ * After Rx enable, if manageability is enabled then there is likely some
+ * bad data at the start of the FIFO and possibly in the DMA FIFO. This
+ * function clears the FIFOs and flushes any packets that came in as Rx was
+ * being enabled.
+ **/
+void e1000_rx_fifo_flush_base(struct e1000_hw *hw)
+{
+ u32 rctl, rlpml, rxdctl[4], rfctl, temp_rctl, rx_enabled;
+ int i, ms_wait;
+
+ DEBUGFUNC("e1000_rx_fifo_flush_base");
+
+ /* disable IPv6 options as per hardware errata */
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ rfctl |= E1000_RFCTL_IPV6_EX_DIS;
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
+ if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_RCV_TCO_EN))
+ return;
+
+ /* Disable all Rx queues */
+ for (i = 0; i < 4; i++) {
+ rxdctl[i] = E1000_READ_REG(hw, E1000_RXDCTL(i));
+ E1000_WRITE_REG(hw, E1000_RXDCTL(i),
+ rxdctl[i] & ~E1000_RXDCTL_QUEUE_ENABLE);
+ }
+ /* Poll all queues to verify they have shut down */
+ for (ms_wait = 0; ms_wait < 10; ms_wait++) {
+ msec_delay(1);
+ rx_enabled = 0;
+ for (i = 0; i < 4; i++)
+ rx_enabled |= E1000_READ_REG(hw, E1000_RXDCTL(i));
+ if (!(rx_enabled & E1000_RXDCTL_QUEUE_ENABLE))
+ break;
+ }
+
+ if (ms_wait == 10)
+ DEBUGOUT("Queue disable timed out after 10ms\n");
+
+ /* Clear RLPML, RCTL.SBP, RFCTL.LEF, and set RCTL.LPE so that all
+ * incoming packets are rejected. Set enable and wait 2ms so that
+ * any packet that was coming in as RCTL.EN was set is flushed
+ */
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl & ~E1000_RFCTL_LEF);
+
+ rlpml = E1000_READ_REG(hw, E1000_RLPML);
+ E1000_WRITE_REG(hw, E1000_RLPML, 0);
+
+ rctl = E1000_READ_REG(hw, E1000_RCTL);
+ temp_rctl = rctl & ~(E1000_RCTL_EN | E1000_RCTL_SBP);
+ temp_rctl |= E1000_RCTL_LPE;
+
+ E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl);
+ E1000_WRITE_REG(hw, E1000_RCTL, temp_rctl | E1000_RCTL_EN);
+ E1000_WRITE_FLUSH(hw);
+ msec_delay(2);
+
+ /* Enable Rx queues that were previously enabled and restore our
+ * previous state
+ */
+ for (i = 0; i < 4; i++)
+ E1000_WRITE_REG(hw, E1000_RXDCTL(i), rxdctl[i]);
+ E1000_WRITE_REG(hw, E1000_RCTL, rctl);
+ E1000_WRITE_FLUSH(hw);
+
+ E1000_WRITE_REG(hw, E1000_RLPML, rlpml);
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+
+ /* Flush receive errors generated by workaround */
+ E1000_READ_REG(hw, E1000_ROC);
+ E1000_READ_REG(hw, E1000_RNBC);
+ E1000_READ_REG(hw, E1000_MPC);
+}
diff --git a/sys/dev/e1000/e1000_base.h b/sys/dev/e1000/e1000_base.h
new file mode 100644
index 000000000000..dca16cd3cfcc
--- /dev/null
+++ b/sys/dev/e1000/e1000_base.h
@@ -0,0 +1,158 @@
+/******************************************************************************
+ SPDX-License-Identifier: BSD-3-Clause
+
+ Copyright (c) 2001-2020, Intel Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+******************************************************************************/
+/*$FreeBSD$*/
+
+#ifndef _E1000_BASE_H_
+#define _E1000_BASE_H_
+
+/* forward declaration */
+s32 e1000_init_hw_base(struct e1000_hw *hw);
+void e1000_power_down_phy_copper_base(struct e1000_hw *hw);
+extern void e1000_rx_fifo_flush_base(struct e1000_hw *hw);
+s32 e1000_acquire_phy_base(struct e1000_hw *hw);
+void e1000_release_phy_base(struct e1000_hw *hw);
+
+/* Transmit Descriptor - Advanced */
+union e1000_adv_tx_desc {
+ struct {
+ __le64 buffer_addr; /* Address of descriptor's data buf */
+ __le32 cmd_type_len;
+ __le32 olinfo_status;
+ } read;
+ struct {
+ __le64 rsvd; /* Reserved */
+ __le32 nxtseq_seed;
+ __le32 status;
+ } wb;
+};
+
+/* Context descriptors */
+struct e1000_adv_tx_context_desc {
+ __le32 vlan_macip_lens;
+ union {
+ __le32 launch_time;
+ __le32 seqnum_seed;
+ } u;
+ __le32 type_tucmd_mlhl;
+ __le32 mss_l4len_idx;
+};
+
+/* Adv Transmit Descriptor Config Masks */
+#define E1000_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Descriptor */
+#define E1000_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */
+#define E1000_ADVTXD_DCMD_EOP 0x01000000 /* End of Packet */
+#define E1000_ADVTXD_DCMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_ADVTXD_DCMD_RS 0x08000000 /* Report Status */
+#define E1000_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */
+#define E1000_ADVTXD_DCMD_DEXT 0x20000000 /* Descriptor extension (1=Adv) */
+#define E1000_ADVTXD_DCMD_VLE 0x40000000 /* VLAN pkt enable */
+#define E1000_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */
+#define E1000_ADVTXD_MAC_LINKSEC 0x00040000 /* Apply LinkSec on pkt */
+#define E1000_ADVTXD_MAC_TSTAMP 0x00080000 /* IEEE1588 Timestamp pkt */
+#define E1000_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED prsnt in WB */
+#define E1000_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */
+#define E1000_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */
+#define E1000_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */
+#define E1000_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
+/* 1st & Last TSO-full iSCSI PDU*/
+#define E1000_ADVTXD_POPTS_ISCO_FULL 0x00001800
+#define E1000_ADVTXD_POPTS_IPSEC 0x00000400 /* IPSec offload request */
+#define E1000_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */
+
+/* Advanced Transmit Context Descriptor Config */
+#define E1000_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */
+#define E1000_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */
+#define E1000_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */
+#define E1000_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */
+#define E1000_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */
+#define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */
+#define E1000_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
+/* IPSec Encrypt Enable for ESP */
+#define E1000_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000
+/* Req requires Markers and CRC */
+#define E1000_ADVTXD_TUCMD_MKRREQ 0x00002000
+#define E1000_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */
+#define E1000_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */
+/* Adv ctxt IPSec SA IDX mask */
+#define E1000_ADVTXD_IPSEC_SA_INDEX_MASK 0x000000FF
+/* Adv ctxt IPSec ESP len mask */
+#define E1000_ADVTXD_IPSEC_ESP_LEN_MASK 0x000000FF
+
+#define E1000_RAR_ENTRIES_BASE 16
+
+/* Receive Descriptor - Advanced */
+union e1000_adv_rx_desc {
+ struct {
+ __le64 pkt_addr; /* Packet buffer address */
+ __le64 hdr_addr; /* Header buffer address */
+ } read;
+ struct {
+ struct {
+ union {
+ __le32 data;
+ struct {
+ __le16 pkt_info; /*RSS type, Pkt type*/
+ /* Split Header, header buffer len */
+ __le16 hdr_info;
+ } hs_rss;
+ } lo_dword;
+ union {
+ __le32 rss; /* RSS Hash */
+ struct {
+ __le16 ip_id; /* IP id */
+ __le16 csum; /* Packet Checksum */
+ } csum_ip;
+ } hi_dword;
+ } lower;
+ struct {
+ __le32 status_error; /* ext status/error */
+ __le16 length; /* Packet length */
+ __le16 vlan; /* VLAN tag */
+ } upper;
+ } wb; /* writeback */
+};
+
+/* Additional Transmit Descriptor Control definitions */
+#define E1000_TXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Tx Queue */
+
+/* Additional Receive Descriptor Control definitions */
+#define E1000_RXDCTL_QUEUE_ENABLE 0x02000000 /* Ena specific Rx Queue */
+
+/* SRRCTL bit definitions */
+#define E1000_SRRCTL_BSIZEPKT_SHIFT 10 /* Shift _right_ */
+#define E1000_SRRCTL_BSIZEHDRSIZE_SHIFT 2 /* Shift _left_ */
+#define E1000_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
+
+#endif /* _E1000_BASE_H_ */
diff --git a/sys/dev/e1000/e1000_defines.h b/sys/dev/e1000/e1000_defines.h
index ecf68dd0341d..4bd575a81671 100644
--- a/sys/dev/e1000/e1000_defines.h
+++ b/sys/dev/e1000/e1000_defines.h
@@ -281,6 +281,7 @@
#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */
#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */
#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */
+#define E1000_CTRL_DEV_RST 0x20000000 /* Device reset */
#define E1000_CTRL_RST 0x04000000 /* Global reset */
#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */
#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */
@@ -445,8 +446,8 @@
#define E1000_RFCTL_LEF 0x00040000
/* Collision related configuration parameters */
-#define E1000_COLLISION_THRESHOLD 15
#define E1000_CT_SHIFT 4
+#define E1000_COLLISION_THRESHOLD 15
#define E1000_COLLISION_DISTANCE 63
#define E1000_COLD_SHIFT 12
@@ -804,6 +805,17 @@
#define E1000_TIMINCA_INCPERIOD_SHIFT 24
#define E1000_TIMINCA_INCVALUE_MASK 0x00FFFFFF
+/* ETQF register bit definitions */
+#define E1000_ETQF_1588 (1 << 30)
+#define E1000_FTQF_VF_BP 0x00008000
+#define E1000_FTQF_1588_TIME_STAMP 0x08000000
+#define E1000_FTQF_MASK 0xF0000000
+#define E1000_FTQF_MASK_PROTO_BP 0x10000000
+/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
+#define E1000_IMIREXT_CTRL_BP 0x00080000 /* Bypass check of ctrl bits */
+#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
+
+#define E1000_RXDADV_STAT_TSIP 0x08000 /* timestamp in packet */
#define E1000_TSICR_TXTS 0x00000002
#define E1000_TSIM_TXTS 0x00000002
/* TUPLE Filtering Configuration */
diff --git a/sys/dev/e1000/e1000_hw.h b/sys/dev/e1000/e1000_hw.h
index 95973e29dbf0..59e51e5c322f 100644
--- a/sys/dev/e1000/e1000_hw.h
+++ b/sys/dev/e1000/e1000_hw.h
@@ -1059,6 +1059,7 @@ struct e1000_hw {
#include "e1000_ich8lan.h"
#include "e1000_82575.h"
#include "e1000_i210.h"
+#include "e1000_base.h"
/* These functions must be implemented by drivers */
void e1000_pci_clear_mwi(struct e1000_hw *hw);
diff --git a/sys/dev/e1000/e1000_i210.c b/sys/dev/e1000/e1000_i210.c
index c6ca38f0f917..0bdad37e56d3 100644
--- a/sys/dev/e1000/e1000_i210.c
+++ b/sys/dev/e1000/e1000_i210.c
@@ -716,6 +716,6 @@ s32 e1000_init_hw_i210(struct e1000_hw *hw)
/* Initialize identification LED */
mac->ops.id_led_init(hw);
- ret_val = e1000_init_hw_82575(hw);
+ ret_val = e1000_init_hw_base(hw);
return ret_val;
}
diff --git a/sys/dev/e1000/e1000_regs.h b/sys/dev/e1000/e1000_regs.h
index b3ced9c39505..2b7696ddea62 100644
--- a/sys/dev/e1000/e1000_regs.h
+++ b/sys/dev/e1000/e1000_regs.h
@@ -167,7 +167,8 @@
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
#define E1000_EMIADD 0x10 /* Extended Memory Indirect Address */
#define E1000_EMIDATA 0x11 /* Extended Memory Indirect Data */
-#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
+/* Shadow Ram Write Register - RW */
+#define E1000_SRWR 0x12018
#define E1000_I210_FLMNGCTL 0x12038
#define E1000_I210_FLMNGDATA 0x1203C
#define E1000_I210_FLMNGCNT 0x12040
@@ -312,6 +313,7 @@
#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */
#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */
#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
+/* Statistics Register Descriptions */
#define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
#define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
#define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
@@ -513,17 +515,20 @@
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
/* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
+/* Semaphore registers */
#define E1000_SW_FW_SYNC 0x05B5C /* SW-FW Synchronization - RW */
#define E1000_CCMCTL 0x05B48 /* CCM Control Register */
#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */
#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */
+/* PCIe Register Description */
#define E1000_GCR 0x05B00 /* PCI-Ex Control */
#define E1000_GCR2 0x05B64 /* PCI-Ex Control #2 */
#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
+/* Function Active and Power State to MNG */
+#define E1000_FACTPS 0x05B30
#define E1000_SWSM 0x05B50 /* SW Semaphore */
#define E1000_FWSM 0x05B54 /* FW Semaphore */
/* Driver-only SW semaphore (not used by BOOT agents) */
@@ -542,8 +547,10 @@
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
-#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
-#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
+/* Redirection Table - RW Array */
+#define E1000_RETA(_i) (0x05C00 + ((_i) * 4))
+/* RSS Random Key - RW Array */
+#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4))
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
/* VT Registers */
@@ -613,6 +620,14 @@
#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
+/* ETQF register bit definitions */
+#define E1000_ETQF_FILTER_ENABLE (1 << 26)
+#define E1000_ETQF_IMM_INT (1 << 29)
+#define E1000_ETQF_QUEUE_ENABLE (1 << 31)
+#define E1000_ETQF_QUEUE_SHIFT 16
+#define E1000_ETQF_QUEUE_MASK 0x00070000
+#define E1000_ETQF_ETYPE_MASK 0x0000FFFF
+
#define E1000_RTTDCS 0x3600 /* Reedtown Tx Desc plane control and status */
#define E1000_RTTPCS 0x3474 /* Reedtown Tx Packet Plane control and status */
#define E1000_RTRPCS 0x2474 /* Rx packet plane control and status */
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index f09e8dd79b0c..5b7437fc5a58 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1324,7 +1324,7 @@ em_if_init(if_ctx_t ctx)
/* Clear bad data from Rx FIFOs */
if (adapter->hw.mac.type >= igb_mac_min)
- e1000_rx_fifo_flush_82575(&adapter->hw);
+ e1000_rx_fifo_flush_base(&adapter->hw);
/* Configure for OS presence */
em_init_manageability(adapter);
diff --git a/sys/dev/e1000/igb_txrx.c b/sys/dev/e1000/igb_txrx.c
index 2252270fa5ea..f7c55137d1f8 100644
--- a/sys/dev/e1000/igb_txrx.c
+++ b/sys/dev/e1000/igb_txrx.c
@@ -136,7 +136,7 @@ igb_tso_setup(struct tx_ring *txr, if_pkt_info_t pi, uint32_t *cmd_type_len,
mss_l4len_idx |= txr->me << 4;
TXD->mss_l4len_idx = htole32(mss_l4len_idx);
- TXD->seqnum_seed = htole32(0);
+ TXD->u.seqnum_seed = htole32(0);
*cmd_type_len |= E1000_ADVTXD_DCMD_TSE;
*olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
*olinfo_status |= paylen << E1000_ADVTXD_PAYLEN_SHIFT;
@@ -227,7 +227,7 @@ igb_tx_ctx_setup(struct tx_ring *txr, if_pkt_info_t pi, uint32_t *cmd_type_len,
/* Now copy bits into descriptor */
TXD->vlan_macip_lens = htole32(vlan_macip_lens);
TXD->type_tucmd_mlhl = htole32(type_tucmd_mlhl);
- TXD->seqnum_seed = htole32(0);
+ TXD->u.seqnum_seed = htole32(0);
TXD->mss_l4len_idx = htole32(mss_l4len_idx);
return (1);
diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile
index 92aa093f986c..d22d5a2fd7b7 100644
--- a/sys/modules/em/Makefile
+++ b/sys/modules/em/Makefile
@@ -9,11 +9,11 @@ SRCS += $(CORE_SRC) $(LEGACY_SRC)
SRCS += $(COMMON_SHARED) $(LEGACY_SHARED) $(PCIE_SHARED)
CORE_SRC = if_em.c em_txrx.c e1000_osdep.c
CORE_SRC += igb_txrx.c
-# This is the Legacy, pre-PCIE source, it can be
-# undefined when using modular driver if not needed
-COMMON_SHARED = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c \
+COMMON_SHARED = e1000_api.c e1000_base.c e1000_phy.c e1000_nvm.c e1000_mac.c \
e1000_manage.c e1000_vf.c e1000_mbx.c e1000_i210.c
PCIE_SHARED = e1000_80003es2lan.c e1000_ich8lan.c e1000_82571.c e1000_82575.c
+# This is the Legacy, pre-PCIE source, it can be
+# undefined when using modular driver if not needed
LEGACY_SHARED = e1000_82540.c e1000_82542.c e1000_82541.c e1000_82543.c