diff options
author | Guinan Sun <guinanx.sun@intel.com> | 2020-07-06 08:12:05 +0000 |
---|---|---|
committer | Kevin Bowling <kbowling@FreeBSD.org> | 2021-09-24 01:21:34 +0000 |
commit | e4a16771e8f3307effe78ec64db35a09319b655a (patch) | |
tree | 6168eeb1550e1829ce06e36e901a1c0618db69e8 | |
parent | 412d4675bbadb36135373272a298fd67d9c75df2 (diff) | |
download | src-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/files | 2 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_82575.c | 471 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_82575.h | 93 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_api.h | 1 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_base.c | 221 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_base.h | 158 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_defines.h | 14 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_hw.h | 1 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_i210.c | 2 | ||||
-rw-r--r-- | sys/dev/e1000/e1000_regs.h | 23 | ||||
-rw-r--r-- | sys/dev/e1000/if_em.c | 2 | ||||
-rw-r--r-- | sys/dev/e1000/igb_txrx.c | 4 | ||||
-rw-r--r-- | sys/modules/em/Makefile | 6 |
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 |