Sync with Intel internal source:
shared code update and small changes in core required Add support for new i210/i211 devices Improve queue calculation based on mac type MFC after:5 days
This commit is contained in:
parent
6e50170633
commit
ab5d036272
@ -1196,6 +1196,8 @@ dev/e1000/e1000_82575.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_ich8lan.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_i210.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_api.c optional em | igb \
|
||||
compile-with "${NORMAL_C} -I$S/dev/e1000"
|
||||
dev/e1000/e1000_mac.c optional em | igb \
|
||||
|
@ -642,7 +642,7 @@ static s32 e1000_check_for_link_82541(struct e1000_hw *hw)
|
||||
* of MAC speed/duplex configuration. So we only need to
|
||||
* configure Collision Distance in the MAC.
|
||||
*/
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
mac->ops.config_collision_dist(hw);
|
||||
|
||||
/*
|
||||
* Configure Flow Control now that Auto-Neg has completed.
|
||||
|
@ -1126,7 +1126,7 @@ static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw)
|
||||
DEBUGOUT("Valid link established!!!\n");
|
||||
/* Config the MAC and PHY after link is up */
|
||||
if (hw->mac.type == e1000_82544) {
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
hw->mac.ops.config_collision_dist(hw);
|
||||
} else {
|
||||
ret_val = e1000_config_mac_to_phy_82543(hw);
|
||||
if (ret_val)
|
||||
@ -1160,7 +1160,7 @@ static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw)
|
||||
/* Take the link out of reset */
|
||||
ctrl &= ~E1000_CTRL_LRST;
|
||||
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
hw->mac.ops.config_collision_dist(hw);
|
||||
|
||||
ret_val = e1000_commit_fc_settings_generic(hw);
|
||||
if (ret_val)
|
||||
@ -1259,7 +1259,7 @@ static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw)
|
||||
* settings.
|
||||
*/
|
||||
if (mac->type == e1000_82544)
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
hw->mac.ops.config_collision_dist(hw);
|
||||
else {
|
||||
ret_val = e1000_config_mac_to_phy_82543(hw);
|
||||
if (ret_val) {
|
||||
@ -1433,7 +1433,7 @@ static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw)
|
||||
if (phy_data & M88E1000_PSSR_DPLX)
|
||||
ctrl |= E1000_CTRL_FD;
|
||||
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
hw->mac.ops.config_collision_dist(hw);
|
||||
|
||||
/*
|
||||
* Set up speed in the Device Control register depending on
|
||||
|
@ -1907,7 +1907,7 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
|
||||
* incoming packets directed to this port are dropped.
|
||||
* Eventually the LAA will be in RAR[0] and RAR[14].
|
||||
*/
|
||||
e1000_rar_set_generic(hw, hw->mac.addr,
|
||||
hw->mac.ops.rar_set(hw, hw->mac.addr,
|
||||
hw->mac.rar_entry_count - 1);
|
||||
return;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -38,9 +38,12 @@
|
||||
* 82575GB Gigabit Network Connection
|
||||
* 82576 Gigabit Network Connection
|
||||
* 82576 Quad Port Gigabit Mezzanine Adapter
|
||||
* 82580 Gigabit Network Connection
|
||||
* I350 Gigabit Network Connection
|
||||
*/
|
||||
|
||||
#include "e1000_api.h"
|
||||
#include "e1000_i210.h"
|
||||
|
||||
static s32 e1000_init_phy_params_82575(struct e1000_hw *hw);
|
||||
static s32 e1000_init_mac_params_82575(struct e1000_hw *hw);
|
||||
@ -162,6 +165,9 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
|
||||
|
||||
DEBUGFUNC("e1000_init_phy_params_82575");
|
||||
|
||||
phy->ops.read_i2c_byte = e1000_read_i2c_byte_generic;
|
||||
phy->ops.write_i2c_byte = e1000_write_i2c_byte_generic;
|
||||
|
||||
if (hw->phy.media_type != e1000_media_type_copper) {
|
||||
phy->type = e1000_phy_none;
|
||||
goto out;
|
||||
@ -195,12 +201,22 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
|
||||
if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
|
||||
phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
|
||||
} else if (hw->mac.type >= e1000_82580) {
|
||||
phy->ops.read_reg = e1000_read_phy_reg_82580;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_82580;
|
||||
} else {
|
||||
phy->ops.read_reg = e1000_read_phy_reg_igp;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_igp;
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
phy->ops.read_reg = e1000_read_phy_reg_82580;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_82580;
|
||||
break;
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
phy->ops.read_reg = e1000_read_phy_reg_gs40g;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_gs40g;
|
||||
break;
|
||||
default:
|
||||
phy->ops.read_reg = e1000_read_phy_reg_igp;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_igp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set phy->phy_addr and phy->id. */
|
||||
@ -245,6 +261,15 @@ static s32 e1000_init_phy_params_82575(struct e1000_hw *hw)
|
||||
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82580;
|
||||
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82580;
|
||||
break;
|
||||
case I210_I_PHY_ID:
|
||||
phy->type = e1000_phy_i210;
|
||||
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.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_m88;
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
goto out;
|
||||
@ -281,28 +306,32 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
|
||||
size = 15;
|
||||
|
||||
nvm->word_size = 1 << size;
|
||||
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 (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;
|
||||
}
|
||||
|
||||
nvm->type = e1000_nvm_eeprom_spi;
|
||||
|
||||
if (nvm->word_size == (1 << 15))
|
||||
nvm->page_size = 128;
|
||||
|
||||
/* Function Pointers */
|
||||
nvm->ops.acquire = e1000_acquire_nvm_82575;
|
||||
nvm->ops.release = e1000_release_nvm_82575;
|
||||
@ -316,7 +345,7 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
|
||||
nvm->ops.update = e1000_update_nvm_checksum_generic;
|
||||
nvm->ops.valid_led_default = e1000_valid_led_default_82575;
|
||||
|
||||
/* override genric family function pointers for specific descendants */
|
||||
/* override generic family function pointers for specific descendants */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82580:
|
||||
nvm->ops.validate = e1000_validate_nvm_checksum_82580;
|
||||
@ -368,8 +397,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
mac->has_fwsm = TRUE;
|
||||
/* ARC supported; valid only if manageability features are enabled. */
|
||||
mac->arc_subsystem_valid =
|
||||
(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
|
||||
? TRUE : FALSE;
|
||||
!!(E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK);
|
||||
|
||||
/* Function pointers */
|
||||
|
||||
@ -394,8 +422,6 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
mac->ops.power_up_serdes = e1000_power_up_serdes_link_82575;
|
||||
/* check for link */
|
||||
mac->ops.check_for_link = e1000_check_for_link_82575;
|
||||
/* receive address register setting */
|
||||
mac->ops.rar_set = e1000_rar_set_generic;
|
||||
/* read mac address */
|
||||
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
|
||||
/* configure collision distance */
|
||||
@ -428,6 +454,13 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
|
||||
/* link info */
|
||||
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_82575;
|
||||
mac->ops.release_swfw_sync = e1000_release_swfw_sync_82575;
|
||||
if (mac->type >= e1000_i210) {
|
||||
mac->ops.acquire_swfw_sync = e1000_acquire_swfw_sync_i210;
|
||||
mac->ops.release_swfw_sync = e1000_release_swfw_sync_i210;
|
||||
}
|
||||
|
||||
/* set lan id for port to determine which phy lock to use */
|
||||
hw->mac.ops.set_lan_id(hw);
|
||||
@ -470,7 +503,7 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
|
||||
else if (hw->bus.func == E1000_FUNC_3)
|
||||
mask = E1000_SWFW_PHY3_SM;
|
||||
|
||||
return e1000_acquire_swfw_sync_82575(hw, mask);
|
||||
return hw->mac.ops.acquire_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -492,7 +525,7 @@ static void e1000_release_phy_82575(struct e1000_hw *hw)
|
||||
else if (hw->bus.func == E1000_FUNC_3)
|
||||
mask = E1000_SWFW_PHY3_SM;
|
||||
|
||||
e1000_release_swfw_sync_82575(hw, mask);
|
||||
hw->mac.ops.release_swfw_sync(hw, mask);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -796,7 +829,7 @@ static s32 e1000_set_d0_lplu_state_82580(struct e1000_hw *hw, bool active)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 data;
|
||||
u32 data;
|
||||
|
||||
DEBUGFUNC("e1000_set_d0_lplu_state_82580");
|
||||
|
||||
@ -844,7 +877,7 @@ s32 e1000_set_d3_lplu_state_82580(struct e1000_hw *hw, bool active)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 data;
|
||||
u32 data;
|
||||
|
||||
DEBUGFUNC("e1000_set_d3_lplu_state_82580");
|
||||
|
||||
@ -918,11 +951,7 @@ static s32 e1000_acquire_nvm_82575(struct e1000_hw *hw)
|
||||
}
|
||||
|
||||
|
||||
switch (hw->mac.type) {
|
||||
default:
|
||||
ret_val = e1000_acquire_nvm_generic(hw);
|
||||
}
|
||||
|
||||
ret_val = e1000_acquire_nvm_generic(hw);
|
||||
if (ret_val)
|
||||
e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
|
||||
|
||||
@ -941,10 +970,8 @@ static void e1000_release_nvm_82575(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_release_nvm_82575");
|
||||
|
||||
switch (hw->mac.type) {
|
||||
default:
|
||||
e1000_release_nvm_generic(hw);
|
||||
}
|
||||
e1000_release_nvm_generic(hw);
|
||||
|
||||
e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM);
|
||||
}
|
||||
|
||||
@ -1058,7 +1085,7 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
|
||||
DEBUGOUT("MNG configuration cycle has not completed.\n");
|
||||
|
||||
/* If EEPROM is not marked present, init the PHY manually */
|
||||
if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
|
||||
if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) &&
|
||||
(hw->phy.type == e1000_phy_igp_3))
|
||||
e1000_phy_init_script_igp3(hw);
|
||||
|
||||
@ -1115,6 +1142,7 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
|
||||
* continue to check for link.
|
||||
*/
|
||||
hw->mac.get_link_status = !hw->mac.serdes_has_link;
|
||||
|
||||
} else {
|
||||
ret_val = e1000_check_for_copper_link_generic(hw);
|
||||
}
|
||||
@ -1168,11 +1196,6 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
|
||||
|
||||
DEBUGFUNC("e1000_get_pcs_speed_and_duplex_82575");
|
||||
|
||||
/* Set up defaults for the return values of this function */
|
||||
mac->serdes_has_link = FALSE;
|
||||
*speed = 0;
|
||||
*duplex = 0;
|
||||
|
||||
/*
|
||||
* Read the PCS Status register for link state. For non-copper mode,
|
||||
* the status register is not accurate. The PCS status register is
|
||||
@ -1181,11 +1204,9 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
|
||||
pcs = E1000_READ_REG(hw, E1000_PCS_LSTAT);
|
||||
|
||||
/*
|
||||
* The link up bit determines when link is up on autoneg. The sync ok
|
||||
* gets set once both sides sync up and agree upon link. Stable link
|
||||
* can be determined by checking for both link up and link sync ok
|
||||
* The link up bit determines when link is up on autoneg.
|
||||
*/
|
||||
if ((pcs & E1000_PCS_LSTS_LINK_OK) && (pcs & E1000_PCS_LSTS_SYNK_OK)) {
|
||||
if (pcs & E1000_PCS_LSTS_LINK_OK) {
|
||||
mac->serdes_has_link = TRUE;
|
||||
|
||||
/* Detect and store PCS speed */
|
||||
@ -1201,6 +1222,10 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
|
||||
*duplex = FULL_DUPLEX;
|
||||
else
|
||||
*duplex = HALF_DUPLEX;
|
||||
} else {
|
||||
mac->serdes_has_link = FALSE;
|
||||
*speed = 0;
|
||||
*duplex = 0;
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
@ -1293,7 +1318,7 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
|
||||
}
|
||||
|
||||
/* If EEPROM is not present, run manual init scripts */
|
||||
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
|
||||
if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
|
||||
e1000_reset_init_script_82575(hw);
|
||||
|
||||
/* Clear any pending interrupt events. */
|
||||
@ -1396,6 +1421,7 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
}
|
||||
}
|
||||
switch (hw->phy.type) {
|
||||
case e1000_phy_i210:
|
||||
case e1000_phy_m88:
|
||||
if (hw->phy.id == I347AT4_E_PHY_ID ||
|
||||
hw->phy.id == M88E1112_E_PHY_ID ||
|
||||
@ -1605,31 +1631,28 @@ static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
|
||||
}
|
||||
/* Read Init Control Word #3*/
|
||||
hw->nvm.ops.read(hw, init_ctrl_wd_3_offset, 1, &init_ctrl_wd_3);
|
||||
|
||||
/*
|
||||
* Align link mode bits to
|
||||
* their CTRL_EXT location.
|
||||
*/
|
||||
current_link_mode = init_ctrl_wd_3;
|
||||
current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET -
|
||||
init_ctrl_wd_3_bit_offset);
|
||||
current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
|
||||
/*
|
||||
* Switch to CSR for all but internal PHY.
|
||||
*/
|
||||
if ((init_ctrl_wd_3 << (E1000_CTRL_EXT_LINK_MODE_OFFSET -
|
||||
init_ctrl_wd_3_bit_offset)) !=
|
||||
E1000_CTRL_EXT_LINK_MODE_GMII) {
|
||||
current_link_mode = ctrl_ext;
|
||||
init_ctrl_wd_3_bit_offset =
|
||||
E1000_CTRL_EXT_LINK_MODE_OFFSET;
|
||||
}
|
||||
if (current_link_mode != E1000_CTRL_EXT_LINK_MODE_GMII)
|
||||
/* Take link mode from CSR */
|
||||
current_link_mode = ctrl_ext &
|
||||
E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
} else {
|
||||
/* Take link mode from CSR */
|
||||
current_link_mode = ctrl_ext;
|
||||
init_ctrl_wd_3_bit_offset = E1000_CTRL_EXT_LINK_MODE_OFFSET;
|
||||
current_link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Align link mode bits to
|
||||
* their CTRL_EXT location.
|
||||
*/
|
||||
current_link_mode <<= (E1000_CTRL_EXT_LINK_MODE_OFFSET -
|
||||
init_ctrl_wd_3_bit_offset);
|
||||
current_link_mode &= E1000_CTRL_EXT_LINK_MODE_MASK;
|
||||
|
||||
switch (current_link_mode) {
|
||||
|
||||
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
|
||||
@ -2331,7 +2354,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
|
||||
msec_delay(10);
|
||||
|
||||
/* Determine whether or not a global dev reset is requested */
|
||||
if (global_device_reset && e1000_acquire_swfw_sync_82575(hw,
|
||||
if (global_device_reset && hw->mac.ops.acquire_swfw_sync(hw,
|
||||
swmbsw_mask))
|
||||
global_device_reset = FALSE;
|
||||
|
||||
@ -2359,7 +2382,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
|
||||
}
|
||||
|
||||
/* If EEPROM is not present, run manual init scripts */
|
||||
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0)
|
||||
if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES))
|
||||
e1000_reset_init_script_82575(hw);
|
||||
|
||||
/* clear global device reset status bit */
|
||||
@ -2378,7 +2401,7 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
|
||||
|
||||
/* Release semaphore */
|
||||
if (global_device_reset)
|
||||
e1000_release_swfw_sync_82575(hw, swmbsw_mask);
|
||||
hw->mac.ops.release_swfw_sync(hw, swmbsw_mask);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
@ -2538,7 +2561,7 @@ static s32 e1000_update_nvm_checksum_82580(struct e1000_hw *hw)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((nvm_data & NVM_COMPATIBILITY_BIT_MASK) == 0) {
|
||||
if (!(nvm_data & NVM_COMPATIBILITY_BIT_MASK)) {
|
||||
/* set compatibility bit to validate checksums appropriately */
|
||||
nvm_data = nvm_data | NVM_COMPATIBILITY_BIT_MASK;
|
||||
ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
|
||||
@ -2737,6 +2760,7 @@ s32 e1000_set_i2c_bb(struct e1000_hw *hw)
|
||||
* e1000_read_i2c_byte_generic - Reads 8 bit word over I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to read
|
||||
* @dev_addr: device address
|
||||
* @data: value read
|
||||
*
|
||||
* Performs byte read operation over I2C interface at
|
||||
@ -2750,14 +2774,14 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
u32 retry = 1;
|
||||
u16 swfw_mask = 0;
|
||||
|
||||
bool nack = 1;
|
||||
bool nack = TRUE;
|
||||
|
||||
DEBUGFUNC("e1000_read_i2c_byte_generic");
|
||||
|
||||
swfw_mask = E1000_SWFW_PHY0_SM;
|
||||
|
||||
do {
|
||||
if (e1000_acquire_swfw_sync_82575(hw, swfw_mask)
|
||||
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)
|
||||
!= E1000_SUCCESS) {
|
||||
status = E1000_ERR_SWFW_SYNC;
|
||||
goto read_byte_out;
|
||||
@ -2805,7 +2829,7 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
break;
|
||||
|
||||
fail:
|
||||
e1000_release_swfw_sync_82575(hw, swfw_mask);
|
||||
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||
msec_delay(100);
|
||||
e1000_i2c_bus_clear(hw);
|
||||
retry++;
|
||||
@ -2816,7 +2840,7 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
|
||||
} while (retry < max_retry);
|
||||
|
||||
e1000_release_swfw_sync_82575(hw, swfw_mask);
|
||||
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||
|
||||
read_byte_out:
|
||||
|
||||
@ -2827,6 +2851,7 @@ s32 e1000_read_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
* e1000_write_i2c_byte_generic - Writes 8 bit word over I2C
|
||||
* @hw: pointer to hardware structure
|
||||
* @byte_offset: byte offset to write
|
||||
* @dev_addr: device address
|
||||
* @data: value to write
|
||||
*
|
||||
* Performs byte write operation over I2C interface at
|
||||
@ -2844,7 +2869,7 @@ s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
|
||||
swfw_mask = E1000_SWFW_PHY0_SM;
|
||||
|
||||
if (e1000_acquire_swfw_sync_82575(hw, swfw_mask) != E1000_SUCCESS) {
|
||||
if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) {
|
||||
status = E1000_ERR_SWFW_SYNC;
|
||||
goto write_byte_out;
|
||||
}
|
||||
@ -2888,7 +2913,7 @@ s32 e1000_write_i2c_byte_generic(struct e1000_hw *hw, u8 byte_offset,
|
||||
DEBUGOUT("I2C byte write error.\n");
|
||||
} while (retry < max_retry);
|
||||
|
||||
e1000_release_swfw_sync_82575(hw, swfw_mask);
|
||||
hw->mac.ops.release_swfw_sync(hw, swfw_mask);
|
||||
|
||||
write_byte_out:
|
||||
|
||||
@ -3020,7 +3045,7 @@ static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
|
||||
u32 i = 0;
|
||||
u32 i2cctl = E1000_READ_REG(hw, E1000_I2CPARAMS);
|
||||
u32 timeout = 10;
|
||||
bool ack = 1;
|
||||
bool ack = TRUE;
|
||||
|
||||
DEBUGFUNC("e1000_get_i2c_ack");
|
||||
|
||||
@ -3040,7 +3065,7 @@ static s32 e1000_get_i2c_ack(struct e1000_hw *hw)
|
||||
return E1000_ERR_I2C;
|
||||
|
||||
ack = e1000_get_i2c_data(&i2cctl);
|
||||
if (ack == 1) {
|
||||
if (ack) {
|
||||
DEBUGOUT("I2C ack was not received.\n");
|
||||
status = E1000_ERR_I2C;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -323,6 +323,17 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
||||
case E1000_DEV_ID_I350_DA4:
|
||||
mac->type = e1000_i350;
|
||||
break;
|
||||
case E1000_DEV_ID_I210_COPPER:
|
||||
case E1000_DEV_ID_I210_COPPER_OEM1:
|
||||
case E1000_DEV_ID_I210_COPPER_IT:
|
||||
case E1000_DEV_ID_I210_FIBER:
|
||||
case E1000_DEV_ID_I210_SERDES:
|
||||
case E1000_DEV_ID_I210_SGMII:
|
||||
mac->type = e1000_i210;
|
||||
break;
|
||||
case E1000_DEV_ID_I211_COPPER:
|
||||
mac->type = e1000_i211;
|
||||
break;
|
||||
case E1000_DEV_ID_82576_VF:
|
||||
mac->type = e1000_vfadapt;
|
||||
break;
|
||||
@ -425,6 +436,10 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
||||
case e1000_i350:
|
||||
e1000_init_function_pointers_82575(hw);
|
||||
break;
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
e1000_init_function_pointers_i210(hw);
|
||||
break;
|
||||
case e1000_vfadapt:
|
||||
e1000_init_function_pointers_vf(hw);
|
||||
break;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -49,6 +49,7 @@ 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);
|
||||
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
|
||||
|
||||
s32 e1000_set_mac_type(struct e1000_hw *hw);
|
||||
s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
|
||||
@ -118,6 +119,7 @@ s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length);
|
||||
u32 e1000_translate_register_82542(u32 reg);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TBI_ACCEPT macro definition:
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -1344,6 +1344,16 @@
|
||||
#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
|
||||
#define E1000_EECD_SECVAL_SHIFT 22
|
||||
#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
|
||||
#define E1000_EECD_FLUPD_I210 0x00800000 /* Update FLASH */
|
||||
#define E1000_EECD_FLUDONE_I210 0x04000000 /* Update FLASH done */
|
||||
#define E1000_EECD_FLASH_DETECTED_I210 0x00080000 /* FLASH detected */
|
||||
#define E1000_FLUDONE_ATTEMPTS 20000
|
||||
#define E1000_EERD_EEWR_MAX_COUNT 512 /* buffered EEPROM words rw */
|
||||
#define E1000_I210_FIFO_SEL_RX 0x00
|
||||
#define E1000_I210_FIFO_SEL_TX_QAV(_i) (0x02 + (_i))
|
||||
#define E1000_I210_FIFO_SEL_TX_LEGACY E1000_I210_FIFO_SEL_TX_QAV(0)
|
||||
#define E1000_I210_FIFO_SEL_BMC2OS_TX 0x06
|
||||
#define E1000_I210_FIFO_SEL_BMC2OS_RX 0x01
|
||||
|
||||
#define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */
|
||||
#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */
|
||||
@ -1361,6 +1371,20 @@
|
||||
#define NVM_VERSION 0x0005
|
||||
#define NVM_SERDES_AMPLITUDE 0x0006 /* SERDES output amplitude */
|
||||
#define NVM_PHY_CLASS_WORD 0x0007
|
||||
#define NVM_ETRACK_WORD 0x0042
|
||||
#define NVM_COMB_VER_OFF 0x0083
|
||||
#define NVM_COMB_VER_PTR 0x003d
|
||||
|
||||
#define NVM_MAC_ADDR 0x0000
|
||||
#define NVM_SUB_DEV_ID 0x000B
|
||||
#define NVM_SUB_VEN_ID 0x000C
|
||||
#define NVM_DEV_ID 0x000D
|
||||
#define NVM_VEN_ID 0x000E
|
||||
#define NVM_INIT_CTRL_2 0x000F
|
||||
#define NVM_INIT_CTRL_4 0x0013
|
||||
#define NVM_LED_1_CFG 0x001C
|
||||
#define NVM_LED_0_2_CFG 0x001F
|
||||
|
||||
#define NVM_INIT_CONTROL1_REG 0x000A
|
||||
#define NVM_INIT_CONTROL2_REG 0x000F
|
||||
#define NVM_SWDEF_PINS_CTRL_PORT_1 0x0010
|
||||
@ -1380,12 +1404,12 @@
|
||||
#define E1000_NVM_CFG_DONE_PORT_2 0x100000 /* ...for third port */
|
||||
#define E1000_NVM_CFG_DONE_PORT_3 0x200000 /* ...for fourth port */
|
||||
|
||||
#define NVM_82580_LAN_FUNC_OFFSET(a) (a ? (0x40 + (0x40 * a)) : 0)
|
||||
#define NVM_82580_LAN_FUNC_OFFSET(a) ((a) ? (0x40 + (0x40 * (a))) : 0)
|
||||
|
||||
/* Mask bits for fields in Word 0x24 of the NVM */
|
||||
#define NVM_WORD24_COM_MDIO 0x0008 /* MDIO interface shared */
|
||||
#define NVM_WORD24_EXT_MDIO 0x0004 /* MDIO accesses routed extrnl */
|
||||
/* Offset of Link Mode bits for 82575 up to Kawela */
|
||||
/* Offset of Link Mode bits for 82575/82576 */
|
||||
#define NVM_WORD24_LNK_MODE_OFFSET 8
|
||||
/* Offset of Link Mode bits for 82580 up */
|
||||
#define NVM_WORD24_82580_LNK_MODE_OFFSET 4
|
||||
@ -1525,6 +1549,7 @@
|
||||
#define I82579_E_PHY_ID 0x01540090
|
||||
#define I82580_I_PHY_ID 0x015403A0
|
||||
#define I350_I_PHY_ID 0x015403B0
|
||||
#define I210_I_PHY_ID 0x01410C00
|
||||
#define IGP04E1000_E_PHY_ID 0x02A80391
|
||||
#define M88_VENDOR 0x0141
|
||||
|
||||
@ -1787,6 +1812,8 @@
|
||||
#define E1000_DMACR_DMAC_LX_MASK 0x30000000
|
||||
#define E1000_DMACR_DMAC_LX_SHIFT 28
|
||||
#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
|
||||
/* DMA Coalescing BMC-to-OS Watchdog Enable */
|
||||
#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000
|
||||
|
||||
/* DMA Coalescing Transmit Threshold */
|
||||
#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF
|
||||
@ -1807,8 +1834,9 @@
|
||||
/* Lx power decision based on DMA coal */
|
||||
#define E1000_PCIEMISC_LX_DECISION 0x00000080
|
||||
|
||||
#define E1000_LTRC_EEEMS_EN 0x00000005 /* Enable EEE LTR max send */
|
||||
#define E1000_RXPBS_SIZE_I210_MASK 0x0000003F /* Rx packet buffer size */
|
||||
#define E1000_TXPB0S_SIZE_I210_MASK 0x0000003F /* Tx packet buffer 0 size */
|
||||
#define E1000_LTRC_EEEMS_EN 0x00000020 /* Enable EEE LTR max send */
|
||||
/* Minimum time for 1000BASE-T where no data will be transmit following move out
|
||||
* of EEE LPI Tx state
|
||||
*/
|
||||
@ -1826,12 +1854,14 @@
|
||||
#define E1000_LTRMINV_SCALE_1024 2
|
||||
/* Reg val to set scale to 32768 nsec */
|
||||
#define E1000_LTRMINV_SCALE_32768 3
|
||||
#define E1000_LTRMINV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
|
||||
#define E1000_LTRMAXV_SCALE_MASK 0x00001C00 /* LTR maximum scale */
|
||||
#define E1000_LTRMAXV_SCALE_SHIFT 10
|
||||
/* Reg val to set scale to 1024 nsec */
|
||||
#define E1000_LTRMAXV_SCALE_1024 2
|
||||
/* Reg val to set scale to 32768 nsec */
|
||||
#define E1000_LTRMAXV_SCALE_32768 3
|
||||
#define E1000_LTRMAXV_LSNP_REQ 0x00008000 /* LTR Snoop Requirement */
|
||||
#define E1000_DOBFFCTL_OBFFTHR_MASK 0x000000FF /* OBFF threshold */
|
||||
#define E1000_DOBFFCTL_EXIT_ACT_MASK 0x01000000 /* Exit active CB */
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -154,6 +154,13 @@ struct e1000_hw;
|
||||
#define E1000_DEV_ID_I350_SERDES 0x1523
|
||||
#define E1000_DEV_ID_I350_SGMII 0x1524
|
||||
#define E1000_DEV_ID_I350_DA4 0x1546
|
||||
#define E1000_DEV_ID_I210_COPPER 0x1533
|
||||
#define E1000_DEV_ID_I210_COPPER_OEM1 0x1534
|
||||
#define E1000_DEV_ID_I210_COPPER_IT 0x1535
|
||||
#define E1000_DEV_ID_I210_FIBER 0x1536
|
||||
#define E1000_DEV_ID_I210_SERDES 0x1537
|
||||
#define E1000_DEV_ID_I210_SGMII 0x1538
|
||||
#define E1000_DEV_ID_I211_COPPER 0x1539
|
||||
#define E1000_DEV_ID_DH89XXCC_SGMII 0x0438
|
||||
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
|
||||
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
|
||||
@ -203,6 +210,8 @@ enum e1000_mac_type {
|
||||
e1000_82576,
|
||||
e1000_82580,
|
||||
e1000_i350,
|
||||
e1000_i210,
|
||||
e1000_i211,
|
||||
e1000_vfadapt,
|
||||
e1000_vfadapt_i350,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */
|
||||
@ -248,6 +257,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_82579,
|
||||
e1000_phy_82580,
|
||||
e1000_phy_vf,
|
||||
e1000_phy_i210,
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
@ -674,6 +684,8 @@ struct e1000_mac_operations {
|
||||
struct e1000_host_mng_command_header*);
|
||||
s32 (*mng_enable_host_if)(struct e1000_hw *);
|
||||
s32 (*wait_autoneg)(struct e1000_hw *);
|
||||
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
|
||||
void (*release_swfw_sync)(struct e1000_hw *, u16);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -911,13 +923,13 @@ struct e1000_dev_spec_ich8lan {
|
||||
E1000_MUTEX nvm_mutex;
|
||||
E1000_MUTEX swflag_mutex;
|
||||
bool nvm_k1_enabled;
|
||||
int eee_disable;
|
||||
bool eee_disable;
|
||||
};
|
||||
|
||||
struct e1000_dev_spec_82575 {
|
||||
bool sgmii_active;
|
||||
bool global_device_reset;
|
||||
int eee_disable;
|
||||
bool eee_disable;
|
||||
bool module_plugged;
|
||||
u32 mtu;
|
||||
};
|
||||
@ -967,6 +979,7 @@ struct e1000_hw {
|
||||
#include "e1000_80003es2lan.h"
|
||||
#include "e1000_ich8lan.h"
|
||||
#include "e1000_82575.h"
|
||||
#include "e1000_i210.h"
|
||||
|
||||
/* These functions must be implemented by drivers */
|
||||
void e1000_pci_clear_mwi(struct e1000_hw *hw);
|
||||
|
740
sys/dev/e1000/e1000_i210.c
Normal file
740
sys/dev/e1000/e1000_i210.c
Normal file
@ -0,0 +1,740 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, 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_api.h"
|
||||
|
||||
|
||||
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
|
||||
static void e1000_release_nvm_i210(struct e1000_hw *hw);
|
||||
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw);
|
||||
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw);
|
||||
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data);
|
||||
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
|
||||
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data);
|
||||
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data);
|
||||
|
||||
/**
|
||||
* e1000_acquire_nvm_i210 - Request for access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Acquire the necessary semaphores for exclusive access to the EEPROM.
|
||||
* Set the EEPROM access request bit and wait for EEPROM access grant bit.
|
||||
* Return successful if access grant bit set, else clear the request for
|
||||
* EEPROM access and return -E1000_ERR_NVM (-1).
|
||||
**/
|
||||
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_acquire_nvm_i210");
|
||||
|
||||
ret_val = e1000_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_release_nvm_i210 - Release exclusive access to EEPROM
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Stop any current commands to the EEPROM and clear the EEPROM request bit,
|
||||
* then release the semaphores acquired.
|
||||
**/
|
||||
static void e1000_release_nvm_i210(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_release_nvm_i210");
|
||||
|
||||
e1000_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
|
||||
* @hw: pointer to the HW structure
|
||||
* @mask: specifies which semaphore to acquire
|
||||
*
|
||||
* Acquire the SW/FW semaphore to access the PHY or NVM. The mask
|
||||
* will also specify which port we're acquiring the lock for.
|
||||
**/
|
||||
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
{
|
||||
u32 swfw_sync;
|
||||
u32 swmask = mask;
|
||||
u32 fwmask = mask << 16;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 i = 0, timeout = 200; /* FIXME: find real value to use here */
|
||||
|
||||
DEBUGFUNC("e1000_acquire_swfw_sync_i210");
|
||||
|
||||
while (i < timeout) {
|
||||
if (e1000_get_hw_semaphore_i210(hw)) {
|
||||
ret_val = -E1000_ERR_SWFW_SYNC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
|
||||
if (!(swfw_sync & fwmask))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Firmware currently using resource (fwmask)
|
||||
*/
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
msec_delay_irq(5);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
|
||||
ret_val = -E1000_ERR_SWFW_SYNC;
|
||||
goto out;
|
||||
}
|
||||
|
||||
swfw_sync |= swmask;
|
||||
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
|
||||
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_release_swfw_sync_i210 - Release SW/FW semaphore
|
||||
* @hw: pointer to the HW structure
|
||||
* @mask: specifies which semaphore to acquire
|
||||
*
|
||||
* Release the SW/FW semaphore used to access the PHY or NVM. The mask
|
||||
* will also specify which port we're releasing the lock for.
|
||||
**/
|
||||
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
|
||||
{
|
||||
u32 swfw_sync;
|
||||
|
||||
DEBUGFUNC("e1000_release_swfw_sync_i210");
|
||||
|
||||
while (e1000_get_hw_semaphore_i210(hw) != E1000_SUCCESS)
|
||||
; /* Empty */
|
||||
|
||||
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
|
||||
swfw_sync &= ~mask;
|
||||
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
|
||||
|
||||
e1000_put_hw_semaphore_i210(hw);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_hw_semaphore_i210 - Acquire hardware semaphore
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Acquire the HW semaphore to access the PHY or NVM
|
||||
**/
|
||||
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 timeout = hw->nvm.word_size + 1;
|
||||
s32 i = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_i210");
|
||||
|
||||
/* Get the FW semaphore. */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
|
||||
|
||||
/* Semaphore acquired if bit latched */
|
||||
if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI)
|
||||
break;
|
||||
|
||||
usec_delay(50);
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
/* Release semaphores */
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
DEBUGOUT("Driver can't access the NVM\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_put_hw_semaphore_i210 - Release hardware semaphore
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Release hardware semaphore used to access the PHY or NVM
|
||||
**/
|
||||
static void e1000_put_hw_semaphore_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
|
||||
DEBUGFUNC("e1000_put_hw_semaphore_i210");
|
||||
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
|
||||
swsm &= ~E1000_SWSM_SWESMBI;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset of word in the Shadow Ram to read
|
||||
* @words: number of words to read
|
||||
* @data: word read from the Shadow Ram
|
||||
*
|
||||
* Reads a 16 bit word from the Shadow Ram using the EERD register.
|
||||
* Uses necessary synchronization semaphores.
|
||||
**/
|
||||
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
{
|
||||
s32 status = E1000_SUCCESS;
|
||||
u16 i, count;
|
||||
|
||||
DEBUGFUNC("e1000_read_nvm_srrd_i210");
|
||||
|
||||
/* We cannot hold synchronization semaphores for too long,
|
||||
* because of forceful takeover procedure. However it is more efficient
|
||||
* to read in bursts than synchronizing access for each word. */
|
||||
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
|
||||
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
|
||||
E1000_EERD_EEWR_MAX_COUNT : (words - i);
|
||||
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
|
||||
status = e1000_read_nvm_eerd(hw, offset, count,
|
||||
data + i);
|
||||
hw->nvm.ops.release(hw);
|
||||
} else {
|
||||
status = E1000_ERR_SWFW_SYNC;
|
||||
}
|
||||
|
||||
if (status != E1000_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset within the Shadow RAM to be written to
|
||||
* @words: number of words to write
|
||||
* @data: 16 bit word(s) to be written to the Shadow RAM
|
||||
*
|
||||
* Writes data to Shadow RAM at offset using EEWR register.
|
||||
*
|
||||
* If e1000_update_nvm_checksum is not called after this function , the
|
||||
* data will not be committed to FLASH and also Shadow RAM will most likely
|
||||
* contain an invalid checksum.
|
||||
*
|
||||
* If error code is returned, data and Shadow RAM may be inconsistent - buffer
|
||||
* partially written.
|
||||
**/
|
||||
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
{
|
||||
s32 status = E1000_SUCCESS;
|
||||
u16 i, count;
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_srwr_i210");
|
||||
|
||||
/* We cannot hold synchronization semaphores for too long,
|
||||
* because of forceful takeover procedure. However it is more efficient
|
||||
* to write in bursts than synchronizing access for each word. */
|
||||
for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
|
||||
count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
|
||||
E1000_EERD_EEWR_MAX_COUNT : (words - i);
|
||||
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
|
||||
status = e1000_write_nvm_srwr(hw, offset, count,
|
||||
data + i);
|
||||
hw->nvm.ops.release(hw);
|
||||
} else {
|
||||
status = E1000_ERR_SWFW_SYNC;
|
||||
}
|
||||
|
||||
if (status != E1000_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_nvm_srwr - Write to Shadow Ram using EEWR
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: offset within the Shadow Ram to be written to
|
||||
* @words: number of words to write
|
||||
* @data: 16 bit word(s) to be written to the Shadow Ram
|
||||
*
|
||||
* Writes data to Shadow Ram at offset using EEWR register.
|
||||
*
|
||||
* If e1000_update_nvm_checksum is not called after this function , the
|
||||
* Shadow Ram will most likely contain an invalid checksum.
|
||||
**/
|
||||
static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
{
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
u32 i, k, eewr = 0;
|
||||
u32 attempts = 100000;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_write_nvm_srwr");
|
||||
|
||||
/*
|
||||
* A check for invalid values: offset too large, too many words,
|
||||
* too many words for the offset, and not enough words.
|
||||
*/
|
||||
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
|
||||
(words == 0)) {
|
||||
DEBUGOUT("nvm parameter(s) out of bounds\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < words; i++) {
|
||||
eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
|
||||
(data[i] << E1000_NVM_RW_REG_DATA) |
|
||||
E1000_NVM_RW_REG_START;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_SRWR, eewr);
|
||||
|
||||
for (k = 0; k < attempts; k++) {
|
||||
if (E1000_NVM_RW_REG_DONE &
|
||||
E1000_READ_REG(hw, E1000_SRWR)) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
break;
|
||||
}
|
||||
usec_delay(5);
|
||||
}
|
||||
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
DEBUGOUT("Shadow RAM write EEWR timed out\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_nvm_i211 - Read NVM wrapper function for I211
|
||||
* @hw: pointer to the HW structure
|
||||
* @address: the word address (aka eeprom offset) to read
|
||||
* @data: pointer to the data read
|
||||
*
|
||||
* Wrapper function to return data formerly found in the NVM.
|
||||
**/
|
||||
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
|
||||
u16 *data)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_read_nvm_i211");
|
||||
|
||||
/* Only the MAC addr is required to be present in the iNVM */
|
||||
switch (offset) {
|
||||
case NVM_MAC_ADDR:
|
||||
ret_val = e1000_read_invm_i211(hw, (u8)offset, &data[0]);
|
||||
ret_val |= e1000_read_invm_i211(hw, (u8)offset+1, &data[1]);
|
||||
ret_val |= e1000_read_invm_i211(hw, (u8)offset+2, &data[2]);
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
DEBUGOUT("MAC Addr not found in iNVM\n");
|
||||
break;
|
||||
case NVM_ID_LED_SETTINGS:
|
||||
case NVM_INIT_CTRL_2:
|
||||
case NVM_INIT_CTRL_4:
|
||||
case NVM_LED_1_CFG:
|
||||
case NVM_LED_0_2_CFG:
|
||||
e1000_read_invm_i211(hw, (u8)offset, data);
|
||||
break;
|
||||
case NVM_COMPAT:
|
||||
*data = ID_LED_DEFAULT_I210;
|
||||
break;
|
||||
case NVM_SUB_DEV_ID:
|
||||
*data = hw->subsystem_device_id;
|
||||
break;
|
||||
case NVM_SUB_VEN_ID:
|
||||
*data = hw->subsystem_vendor_id;
|
||||
break;
|
||||
case NVM_DEV_ID:
|
||||
*data = hw->device_id;
|
||||
break;
|
||||
case NVM_VEN_ID:
|
||||
*data = hw->vendor_id;
|
||||
break;
|
||||
default:
|
||||
DEBUGOUT1("NVM word 0x%02x is not mapped.\n", offset);
|
||||
*data = NVM_RESERVED_WORD;
|
||||
break;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_invm_i211 - Reads OTP
|
||||
* @hw: pointer to the HW structure
|
||||
* @address: the word address (aka eeprom offset) to read
|
||||
* @data: pointer to the data read
|
||||
*
|
||||
* Reads 16-bit words from the OTP. Return error when the word is not
|
||||
* stored in OTP.
|
||||
**/
|
||||
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data)
|
||||
{
|
||||
s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
|
||||
u32 invm_dword;
|
||||
u16 i;
|
||||
u8 record_type, word_address;
|
||||
|
||||
DEBUGFUNC("e1000_read_invm_i211");
|
||||
|
||||
for (i = 0; i < E1000_INVM_SIZE; i++) {
|
||||
invm_dword = E1000_READ_REG(hw, E1000_INVM_DATA_REG(i));
|
||||
/* Get record type */
|
||||
record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
|
||||
if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
|
||||
break;
|
||||
if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
|
||||
i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
|
||||
if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
|
||||
i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
|
||||
if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
|
||||
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
|
||||
if (word_address == address) {
|
||||
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
|
||||
DEBUGOUT2("Read INVM Word 0x%02x = %x",
|
||||
address, *data);
|
||||
status = E1000_SUCCESS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status != E1000_SUCCESS)
|
||||
DEBUGOUT1("Requested word 0x%02x not found in OTP\n", address);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_validate_nvm_checksum_i210 - Validate EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Calculates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* and then verifies that the sum of the EEPROM is equal to 0xBABA.
|
||||
**/
|
||||
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 status = E1000_SUCCESS;
|
||||
s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);
|
||||
|
||||
DEBUGFUNC("e1000_validate_nvm_checksum_i210");
|
||||
|
||||
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
|
||||
|
||||
/*
|
||||
* Replace the read function with semaphore grabbing with
|
||||
* the one that skips this for a while.
|
||||
* We have semaphore taken already here.
|
||||
*/
|
||||
read_op_ptr = hw->nvm.ops.read;
|
||||
hw->nvm.ops.read = e1000_read_nvm_eerd;
|
||||
|
||||
status = e1000_validate_nvm_checksum_generic(hw);
|
||||
|
||||
/* Revert original read operation. */
|
||||
hw->nvm.ops.read = read_op_ptr;
|
||||
|
||||
hw->nvm.ops.release(hw);
|
||||
} else {
|
||||
status = E1000_ERR_SWFW_SYNC;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* e1000_update_nvm_checksum_i210 - Update EEPROM checksum
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Updates the EEPROM checksum by reading/adding each word of the EEPROM
|
||||
* up to the checksum. Then calculates the EEPROM checksum and writes the
|
||||
* value to the EEPROM. Next commit EEPROM data onto the Flash.
|
||||
**/
|
||||
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 checksum = 0;
|
||||
u16 i, nvm_data;
|
||||
|
||||
DEBUGFUNC("e1000_update_nvm_checksum_i210");
|
||||
|
||||
/*
|
||||
* Read the first word from the EEPROM. If this times out or fails, do
|
||||
* not continue or we could be in for a very long wait while every
|
||||
* EEPROM read fails
|
||||
*/
|
||||
ret_val = e1000_read_nvm_eerd(hw, 0, 1, &nvm_data);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
DEBUGOUT("EEPROM read failed\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hw->nvm.ops.acquire(hw) == E1000_SUCCESS) {
|
||||
/*
|
||||
* Do not use hw->nvm.ops.write, hw->nvm.ops.read
|
||||
* because we do not want to take the synchronization
|
||||
* semaphores twice here.
|
||||
*/
|
||||
|
||||
for (i = 0; i < NVM_CHECKSUM_REG; i++) {
|
||||
ret_val = e1000_read_nvm_eerd(hw, i, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
hw->nvm.ops.release(hw);
|
||||
DEBUGOUT("NVM Read Error while updating checksum.\n");
|
||||
goto out;
|
||||
}
|
||||
checksum += nvm_data;
|
||||
}
|
||||
checksum = (u16) NVM_SUM - checksum;
|
||||
ret_val = e1000_write_nvm_srwr(hw, NVM_CHECKSUM_REG, 1,
|
||||
&checksum);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
hw->nvm.ops.release(hw);
|
||||
DEBUGOUT("NVM Write Error while updating checksum.\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
hw->nvm.ops.release(hw);
|
||||
|
||||
ret_val = e1000_update_flash_i210(hw);
|
||||
} else {
|
||||
ret_val = E1000_ERR_SWFW_SYNC;
|
||||
}
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_flash_presence_i210 - Check if flash device is detected.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
**/
|
||||
static bool e1000_get_flash_presence_i210(struct e1000_hw *hw)
|
||||
{
|
||||
u32 eec = 0;
|
||||
bool ret_val = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_get_flash_presence_i210");
|
||||
|
||||
eec = E1000_READ_REG(hw, E1000_EECD);
|
||||
|
||||
if (eec & E1000_EECD_FLASH_DETECTED_I210)
|
||||
ret_val = TRUE;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_update_flash_i210 - Commit EEPROM to the flash
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
**/
|
||||
s32 e1000_update_flash_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 flup;
|
||||
|
||||
DEBUGFUNC("e1000_update_flash_i210");
|
||||
|
||||
ret_val = e1000_pool_flash_update_done_i210(hw);
|
||||
if (ret_val == -E1000_ERR_NVM) {
|
||||
DEBUGOUT("Flash update time out\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
flup = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD_I210;
|
||||
E1000_WRITE_REG(hw, E1000_EECD, flup);
|
||||
|
||||
ret_val = e1000_pool_flash_update_done_i210(hw);
|
||||
if (ret_val == E1000_SUCCESS)
|
||||
DEBUGOUT("Flash update complete\n");
|
||||
else
|
||||
DEBUGOUT("Flash update time out\n");
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_pool_flash_update_done_i210 - Pool FLUDONE status.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
**/
|
||||
s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = -E1000_ERR_NVM;
|
||||
u32 i, reg;
|
||||
|
||||
DEBUGFUNC("e1000_pool_flash_update_done_i210");
|
||||
|
||||
for (i = 0; i < E1000_FLUDONE_ATTEMPTS; i++) {
|
||||
reg = E1000_READ_REG(hw, E1000_EECD);
|
||||
if (reg & E1000_EECD_FLUDONE_I210) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
break;
|
||||
}
|
||||
usec_delay(5);
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_nvm_params_i210 - Initialize i210 NVM function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initialize the i210 NVM parameters and function pointers.
|
||||
**/
|
||||
static s32 e1000_init_nvm_params_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
|
||||
DEBUGFUNC("e1000_init_nvm_params_i210");
|
||||
|
||||
ret_val = e1000_init_nvm_params_82575(hw);
|
||||
|
||||
nvm->ops.acquire = e1000_acquire_nvm_i210;
|
||||
nvm->ops.release = e1000_release_nvm_i210;
|
||||
nvm->ops.read = e1000_read_nvm_srrd_i210;
|
||||
nvm->ops.write = e1000_write_nvm_srwr_i210;
|
||||
nvm->ops.valid_led_default = e1000_valid_led_default_i210;
|
||||
nvm->ops.validate = e1000_validate_nvm_checksum_i210;
|
||||
nvm->ops.update = e1000_update_nvm_checksum_i210;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_nvm_params_i211 - Initialize i211 NVM function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initialize the NVM parameters and function pointers for i211.
|
||||
**/
|
||||
static s32 e1000_init_nvm_params_i211(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
|
||||
DEBUGFUNC("e1000_init_nvm_params_i211");
|
||||
|
||||
nvm->ops.acquire = e1000_acquire_nvm_i210;
|
||||
nvm->ops.release = e1000_release_nvm_i210;
|
||||
nvm->ops.read = e1000_read_nvm_i211;
|
||||
nvm->ops.valid_led_default = e1000_valid_led_default_i210;
|
||||
nvm->ops.write = e1000_null_write_nvm;
|
||||
nvm->ops.validate = e1000_null_ops_generic;
|
||||
nvm->ops.update = e1000_null_ops_generic;
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_function_pointers_i210 - Init func ptrs.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Called to initialize all function pointers and parameters.
|
||||
**/
|
||||
void e1000_init_function_pointers_i210(struct e1000_hw *hw)
|
||||
{
|
||||
e1000_init_function_pointers_82575(hw);
|
||||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_i210:
|
||||
if (e1000_get_flash_presence_i210(hw))
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
|
||||
else
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
|
||||
break;
|
||||
case e1000_i211:
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_valid_led_default_i210 - Verify a valid default LED config
|
||||
* @hw: pointer to the HW structure
|
||||
* @data: pointer to the NVM (EEPROM)
|
||||
*
|
||||
* Read the EEPROM for the current default LED configuration. If the
|
||||
* LED configuration is not valid, set to a valid LED configuration.
|
||||
**/
|
||||
static s32 e1000_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_valid_led_default_i210");
|
||||
|
||||
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
|
||||
switch (hw->phy.media_type) {
|
||||
case e1000_media_type_internal_serdes:
|
||||
*data = ID_LED_DEFAULT_I210_SERDES;
|
||||
break;
|
||||
case e1000_media_type_copper:
|
||||
default:
|
||||
*data = ID_LED_DEFAULT_I210;
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
80
sys/dev/e1000/e1000_i210.h
Normal file
80
sys/dev/e1000/e1000_i210.h
Normal file
@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2012, 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_I210_H_
|
||||
#define _E1000_I210_H_
|
||||
|
||||
s32 e1000_update_flash_i210(struct e1000_hw *hw);
|
||||
s32 e1000_update_nvm_checksum_i210(struct e1000_hw *hw);
|
||||
s32 e1000_validate_nvm_checksum_i210(struct e1000_hw *hw);
|
||||
s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
|
||||
u16 words, u16 *data);
|
||||
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
|
||||
u16 words, u16 *data);
|
||||
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, u16 *data);
|
||||
s32 e1000_check_for_copper_link_i210(struct e1000_hw *hw);
|
||||
s32 e1000_set_ltr_i210(struct e1000_hw *hw, bool link);
|
||||
s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
|
||||
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
|
||||
|
||||
#define E1000_STM_OPCODE 0xDB00
|
||||
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
|
||||
|
||||
#define INVM_DWORD_TO_RECORD_TYPE(invm_dword) \
|
||||
(u8)((invm_dword) & 0x7)
|
||||
#define INVM_DWORD_TO_WORD_ADDRESS(invm_dword) \
|
||||
(u8)(((invm_dword) & 0x0000FE00) >> 9)
|
||||
#define INVM_DWORD_TO_WORD_DATA(invm_dword) \
|
||||
(u16)(((invm_dword) & 0xFFFF0000) >> 16)
|
||||
|
||||
enum E1000_INVM_STRUCTURE_TYPE {
|
||||
E1000_INVM_UNINITIALIZED_STRUCTURE = 0x00,
|
||||
E1000_INVM_WORD_AUTOLOAD_STRUCTURE = 0x01,
|
||||
E1000_INVM_CSR_AUTOLOAD_STRUCTURE = 0x02,
|
||||
E1000_INVM_PHY_REGISTER_AUTOLOAD_STRUCTURE = 0x03,
|
||||
E1000_INVM_RSA_KEY_SHA256_STRUCTURE = 0x04,
|
||||
E1000_INVM_INVALIDATED_STRUCTURE = 0x0F,
|
||||
};
|
||||
|
||||
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
|
||||
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
|
||||
|
||||
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
|
||||
(ID_LED_DEF1_DEF2 << 4) | \
|
||||
(ID_LED_OFF1_OFF2))
|
||||
#define ID_LED_DEFAULT_I210_SERDES ((ID_LED_DEF1_DEF2 << 8) | \
|
||||
(ID_LED_DEF1_DEF2 << 4) | \
|
||||
(ID_LED_DEF1_DEF2))
|
||||
|
||||
#endif
|
@ -738,7 +738,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
||||
* of MAC speed/duplex configuration. So we only need to
|
||||
* configure Collision Distance in the MAC.
|
||||
*/
|
||||
e1000_config_collision_dist_generic(hw);
|
||||
hw->mac.ops.config_collision_dist(hw);
|
||||
|
||||
/*
|
||||
* Configure Flow Control now that Auto-Neg has completed.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -64,31 +64,29 @@ void e1000_set_lan_id_single_port(struct e1000_hw *hw);
|
||||
void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw);
|
||||
s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw);
|
||||
s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
u16 *duplex);
|
||||
s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw,
|
||||
u16 *speed, u16 *duplex);
|
||||
u16 *speed, u16 *duplex);
|
||||
s32 e1000_id_led_init_generic(struct e1000_hw *hw);
|
||||
s32 e1000_led_on_generic(struct e1000_hw *hw);
|
||||
s32 e1000_led_off_generic(struct e1000_hw *hw);
|
||||
void e1000_update_mc_addr_list_generic(struct e1000_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count);
|
||||
u8 *mc_addr_list, u32 mc_addr_count);
|
||||
s32 e1000_set_default_fc_generic(struct e1000_hw *hw);
|
||||
s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
|
||||
s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw);
|
||||
s32 e1000_setup_led_generic(struct e1000_hw *hw);
|
||||
s32 e1000_setup_link_generic(struct e1000_hw *hw);
|
||||
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
|
||||
u32 offset, u8 data);
|
||||
u32 offset, u8 data);
|
||||
|
||||
u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr);
|
||||
|
||||
void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw);
|
||||
void e1000_clear_vfta_generic(struct e1000_hw *hw);
|
||||
void e1000_config_collision_dist_generic(struct e1000_hw *hw);
|
||||
void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count);
|
||||
void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw);
|
||||
void e1000_put_hw_semaphore_generic(struct e1000_hw *hw);
|
||||
void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
|
||||
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
|
||||
void e1000_reset_adaptive_generic(struct e1000_hw *hw);
|
||||
void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -71,23 +71,20 @@ u8 e1000_calculate_checksum(u8 *buffer, u32 length)
|
||||
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
|
||||
{
|
||||
u32 hicr;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u8 i;
|
||||
|
||||
DEBUGFUNC("e1000_mng_enable_host_if_generic");
|
||||
|
||||
if (!(hw->mac.arc_subsystem_valid)) {
|
||||
if (!hw->mac.arc_subsystem_valid) {
|
||||
DEBUGOUT("ARC subsystem not valid.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Check that the host interface is enabled. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
if ((hicr & E1000_HICR_EN) == 0) {
|
||||
if (!(hicr & E1000_HICR_EN)) {
|
||||
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
/* check the previous command is completed */
|
||||
for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
|
||||
@ -99,12 +96,10 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw)
|
||||
|
||||
if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
|
||||
DEBUGOUT("Previous command timeout failed .\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,7 +117,7 @@ bool e1000_check_mng_mode_generic(struct e1000_hw *hw)
|
||||
|
||||
|
||||
return (fwsm & E1000_FWSM_MODE_MASK) ==
|
||||
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
|
||||
(E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -147,7 +142,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
/* No manageability, no filtering */
|
||||
if (!hw->mac.ops.check_mng_mode(hw)) {
|
||||
hw->mac.tx_pkt_filtering = FALSE;
|
||||
goto out;
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -157,7 +152,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
ret_val = hw->mac.ops.mng_enable_host_if(hw);
|
||||
if (ret_val != E1000_SUCCESS) {
|
||||
hw->mac.tx_pkt_filtering = FALSE;
|
||||
goto out;
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
}
|
||||
|
||||
/* Read in the header. Length and offset are in dwords. */
|
||||
@ -165,11 +160,11 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2;
|
||||
for (i = 0; i < len; i++)
|
||||
*(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
|
||||
offset + i);
|
||||
offset + i);
|
||||
hdr_csum = hdr->checksum;
|
||||
hdr->checksum = 0;
|
||||
csum = e1000_calculate_checksum((u8 *)hdr,
|
||||
E1000_MNG_DHCP_COOKIE_LENGTH);
|
||||
E1000_MNG_DHCP_COOKIE_LENGTH);
|
||||
/*
|
||||
* If either the checksums or signature don't match, then
|
||||
* the cookie area isn't considered valid, in which case we
|
||||
@ -177,66 +172,16 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
|
||||
*/
|
||||
if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) {
|
||||
hw->mac.tx_pkt_filtering = TRUE;
|
||||
goto out;
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
}
|
||||
|
||||
/* Cookie area is valid, make the final check for filtering. */
|
||||
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) {
|
||||
if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING))
|
||||
hw->mac.tx_pkt_filtering = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return hw->mac.tx_pkt_filtering;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
|
||||
* @hw: pointer to the HW structure
|
||||
* @buffer: pointer to the host interface
|
||||
* @length: size of the buffer
|
||||
*
|
||||
* Writes the DHCP information to the host interface.
|
||||
**/
|
||||
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
u16 length)
|
||||
{
|
||||
struct e1000_host_mng_command_header hdr;
|
||||
s32 ret_val;
|
||||
u32 hicr;
|
||||
|
||||
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
|
||||
|
||||
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
|
||||
hdr.command_length = length;
|
||||
hdr.reserved1 = 0;
|
||||
hdr.reserved2 = 0;
|
||||
hdr.checksum = 0;
|
||||
|
||||
/* Enable the host interface */
|
||||
ret_val = hw->mac.ops.mng_enable_host_if(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Populate the host interface with the contents of "buffer". */
|
||||
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
|
||||
sizeof(hdr), &(hdr.checksum));
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Write the manageability command header */
|
||||
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Tell the ARC a new command is pending. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_mng_write_cmd_header_generic - Writes manageability command header
|
||||
* @hw: pointer to the HW structure
|
||||
@ -245,7 +190,7 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
* Writes the command header after does the checksum calculation.
|
||||
**/
|
||||
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
|
||||
struct e1000_host_mng_command_header *hdr)
|
||||
struct e1000_host_mng_command_header *hdr)
|
||||
{
|
||||
u16 i, length = sizeof(struct e1000_host_mng_command_header);
|
||||
|
||||
@ -259,7 +204,7 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
|
||||
/* Write the relevant command block into the ram area. */
|
||||
for (i = 0; i < length; i++) {
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
|
||||
*((u32 *) hdr + i));
|
||||
*((u32 *) hdr + i));
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
}
|
||||
|
||||
@ -279,22 +224,19 @@ s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
|
||||
* way. Also fills up the sum of the buffer in *buffer parameter.
|
||||
**/
|
||||
s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
u16 length, u16 offset, u8 *sum)
|
||||
u16 length, u16 offset, u8 *sum)
|
||||
{
|
||||
u8 *tmp;
|
||||
u8 *bufptr = buffer;
|
||||
u32 data = 0;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 remaining, i, j, prev_bytes;
|
||||
|
||||
DEBUGFUNC("e1000_mng_host_if_write_generic");
|
||||
|
||||
/* sum = only sum of the data and it is not checksum */
|
||||
|
||||
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
|
||||
ret_val = -E1000_ERR_PARAM;
|
||||
goto out;
|
||||
}
|
||||
if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH)
|
||||
return -E1000_ERR_PARAM;
|
||||
|
||||
tmp = (u8 *)&data;
|
||||
prev_bytes = offset & 0x3;
|
||||
@ -328,7 +270,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
}
|
||||
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
|
||||
data);
|
||||
data);
|
||||
}
|
||||
if (remaining) {
|
||||
for (j = 0; j < sizeof(u32); j++) {
|
||||
@ -339,11 +281,57 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
|
||||
*sum += *(tmp + j);
|
||||
}
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data);
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i,
|
||||
data);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface
|
||||
* @hw: pointer to the HW structure
|
||||
* @buffer: pointer to the host interface
|
||||
* @length: size of the buffer
|
||||
*
|
||||
* Writes the DHCP information to the host interface.
|
||||
**/
|
||||
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
u16 length)
|
||||
{
|
||||
struct e1000_host_mng_command_header hdr;
|
||||
s32 ret_val;
|
||||
u32 hicr;
|
||||
|
||||
DEBUGFUNC("e1000_mng_write_dhcp_info_generic");
|
||||
|
||||
hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
|
||||
hdr.command_length = length;
|
||||
hdr.reserved1 = 0;
|
||||
hdr.reserved2 = 0;
|
||||
hdr.checksum = 0;
|
||||
|
||||
/* Enable the host interface */
|
||||
ret_val = hw->mac.ops.mng_enable_host_if(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Populate the host interface with the contents of "buffer". */
|
||||
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length,
|
||||
sizeof(hdr), &(hdr.checksum));
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Write the manageability command header */
|
||||
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Tell the ARC a new command is pending. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,17 +345,16 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
||||
{
|
||||
u32 manc;
|
||||
u32 fwsm, factps;
|
||||
bool ret_val = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_enable_mng_pass_thru");
|
||||
|
||||
if (!hw->mac.asf_firmware_present)
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
manc = E1000_READ_REG(hw, E1000_MANC);
|
||||
|
||||
if (!(manc & E1000_MANC_RCV_TCO_EN))
|
||||
goto out;
|
||||
return FALSE;
|
||||
|
||||
if (hw->mac.has_fwsm) {
|
||||
fwsm = E1000_READ_REG(hw, E1000_FWSM);
|
||||
@ -375,10 +362,8 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
||||
|
||||
if (!(factps & E1000_FACTPS_MNGCG) &&
|
||||
((fwsm & E1000_FWSM_MODE_MASK) ==
|
||||
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) {
|
||||
ret_val = TRUE;
|
||||
goto out;
|
||||
}
|
||||
(e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)))
|
||||
return TRUE;
|
||||
} else if ((hw->mac.type == e1000_82574) ||
|
||||
(hw->mac.type == e1000_82583)) {
|
||||
u16 data;
|
||||
@ -388,18 +373,14 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
||||
|
||||
if (!(factps & E1000_FACTPS_MNGCG) &&
|
||||
((data & E1000_NVM_INIT_CTRL2_MNGM) ==
|
||||
(e1000_mng_mode_pt << 13))) {
|
||||
ret_val = TRUE;
|
||||
goto out;
|
||||
}
|
||||
(e1000_mng_mode_pt << 13)))
|
||||
return TRUE;
|
||||
} else if ((manc & E1000_MANC_SMBUS_EN) &&
|
||||
!(manc & E1000_MANC_ASF_EN)) {
|
||||
ret_val = TRUE;
|
||||
goto out;
|
||||
!(manc & E1000_MANC_ASF_EN)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -414,33 +395,30 @@ bool e1000_enable_mng_pass_thru(struct e1000_hw *hw)
|
||||
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
{
|
||||
u32 hicr, i;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_host_interface_command");
|
||||
|
||||
if (!(hw->mac.arc_subsystem_valid)) {
|
||||
DEBUGOUT("Hardware doesn't support host interface command.\n");
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
if (!hw->mac.asf_firmware_present) {
|
||||
DEBUGOUT("Firmware is not present.\n");
|
||||
goto out;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
if (length == 0 || length & 0x3 ||
|
||||
length > E1000_HI_MAX_BLOCK_BYTE_LENGTH) {
|
||||
DEBUGOUT("Buffer length failure.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Check that the host interface is enabled. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
if ((hicr & E1000_HICR_EN) == 0) {
|
||||
if (!(hicr & E1000_HICR_EN)) {
|
||||
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Calculate length in DWORDs */
|
||||
@ -451,10 +429,8 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
* into the ram area.
|
||||
*/
|
||||
for (i = 0; i < length; i++)
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw,
|
||||
E1000_HOST_IF,
|
||||
i,
|
||||
*((u32 *)buffer + i));
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i,
|
||||
*((u32 *)buffer + i));
|
||||
|
||||
/* Setting this bit tells the ARC that a new command is pending. */
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
|
||||
@ -470,16 +446,134 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
if (i == E1000_HI_COMMAND_TIMEOUT ||
|
||||
(!(E1000_READ_REG(hw, E1000_HICR) & E1000_HICR_SV))) {
|
||||
DEBUGOUT("Command has failed with no status valid.\n");
|
||||
ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
goto out;
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
*((u32 *)buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw,
|
||||
E1000_HOST_IF,
|
||||
i);
|
||||
E1000_HOST_IF,
|
||||
i);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
/**
|
||||
* e1000_load_firmware - Writes proxy FW code buffer to host interface
|
||||
* and execute.
|
||||
* @hw: pointer to the HW structure
|
||||
* @buffer: contains a firmware to write
|
||||
* @length: the byte length of the buffer, must be multiple of 4 bytes
|
||||
*
|
||||
* Upon success returns E1000_SUCCESS, returns E1000_ERR_CONFIG if not enabled
|
||||
* in HW else returns E1000_ERR_HOST_INTERFACE_COMMAND.
|
||||
**/
|
||||
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
|
||||
{
|
||||
u32 hicr, hibba, fwsm, icr, i;
|
||||
|
||||
DEBUGFUNC("e1000_load_firmware");
|
||||
|
||||
if (hw->mac.type < e1000_i210) {
|
||||
DEBUGOUT("Hardware doesn't support loading FW by the driver\n");
|
||||
return -E1000_ERR_CONFIG;
|
||||
}
|
||||
|
||||
/* Check that the host interface is enabled. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
if (!(hicr & E1000_HICR_EN)) {
|
||||
DEBUGOUT("E1000_HOST_EN bit disabled.\n");
|
||||
return -E1000_ERR_CONFIG;
|
||||
}
|
||||
if (!(hicr & E1000_HICR_MEMORY_BASE_EN)) {
|
||||
DEBUGOUT("E1000_HICR_MEMORY_BASE_EN bit disabled.\n");
|
||||
return -E1000_ERR_CONFIG;
|
||||
}
|
||||
|
||||
if (length == 0 || length & 0x3 || length > E1000_HI_FW_MAX_LENGTH) {
|
||||
DEBUGOUT("Buffer length failure.\n");
|
||||
return -E1000_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
/* Clear notification from ROM-FW by reading ICR register */
|
||||
icr = E1000_READ_REG(hw, E1000_ICR_V2);
|
||||
|
||||
/* Reset ROM-FW */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
hicr |= E1000_HICR_FW_RESET_ENABLE;
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr);
|
||||
hicr |= E1000_HICR_FW_RESET;
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr);
|
||||
E1000_WRITE_FLUSH(hw);
|
||||
|
||||
/* Wait till MAC notifies about its readiness after ROM-FW reset */
|
||||
for (i = 0; i < (E1000_HI_COMMAND_TIMEOUT * 2); i++) {
|
||||
icr = E1000_READ_REG(hw, E1000_ICR_V2);
|
||||
if (icr & E1000_ICR_MNG)
|
||||
break;
|
||||
msec_delay(1);
|
||||
}
|
||||
|
||||
/* Check for timeout */
|
||||
if (i == E1000_HI_COMMAND_TIMEOUT) {
|
||||
DEBUGOUT("FW reset failed.\n");
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Wait till MAC is ready to accept new FW code */
|
||||
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
|
||||
fwsm = E1000_READ_REG(hw, E1000_FWSM);
|
||||
if ((fwsm & E1000_FWSM_FW_VALID) &&
|
||||
((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT ==
|
||||
E1000_FWSM_HI_EN_ONLY_MODE))
|
||||
break;
|
||||
msec_delay(1);
|
||||
}
|
||||
|
||||
/* Check for timeout */
|
||||
if (i == E1000_HI_COMMAND_TIMEOUT) {
|
||||
DEBUGOUT("FW reset failed.\n");
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
/* Calculate length in DWORDs */
|
||||
length >>= 2;
|
||||
|
||||
/*
|
||||
* The device driver writes the relevant FW code block
|
||||
* into the ram area in DWORDs via 1kB ram addressing window.
|
||||
*/
|
||||
for (i = 0; i < length; i++) {
|
||||
if (!(i % E1000_HI_FW_BLOCK_DWORD_LENGTH)) {
|
||||
/* Point to correct 1kB ram window */
|
||||
hibba = E1000_HI_FW_BASE_ADDRESS +
|
||||
((E1000_HI_FW_BLOCK_DWORD_LENGTH << 2) *
|
||||
(i / E1000_HI_FW_BLOCK_DWORD_LENGTH));
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_HIBBA, hibba);
|
||||
}
|
||||
|
||||
E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF,
|
||||
i % E1000_HI_FW_BLOCK_DWORD_LENGTH,
|
||||
*((u32 *)buffer + i));
|
||||
}
|
||||
|
||||
/* Setting this bit tells the ARC that a new FW is ready to execute. */
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C);
|
||||
|
||||
for (i = 0; i < E1000_HI_COMMAND_TIMEOUT; i++) {
|
||||
hicr = E1000_READ_REG(hw, E1000_HICR);
|
||||
if (!(hicr & E1000_HICR_C))
|
||||
break;
|
||||
msec_delay(1);
|
||||
}
|
||||
|
||||
/* Check for successful FW start. */
|
||||
if (i == E1000_HI_COMMAND_TIMEOUT) {
|
||||
DEBUGOUT("New FW did not start within timeout period.\n");
|
||||
return -E1000_ERR_HOST_INTERFACE_COMMAND;
|
||||
}
|
||||
|
||||
return E1000_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2010, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -39,14 +39,15 @@ bool e1000_check_mng_mode_generic(struct e1000_hw *hw);
|
||||
bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw);
|
||||
s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw);
|
||||
s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
|
||||
u16 length, u16 offset, u8 *sum);
|
||||
u16 length, u16 offset, u8 *sum);
|
||||
s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw,
|
||||
struct e1000_host_mng_command_header *hdr);
|
||||
struct e1000_host_mng_command_header *hdr);
|
||||
s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw,
|
||||
u8 *buffer, u16 length);
|
||||
u8 *buffer, u16 length);
|
||||
bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
|
||||
u8 e1000_calculate_checksum(u8 *buffer, u32 length);
|
||||
s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length);
|
||||
s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length);
|
||||
|
||||
enum e1000_mng_mode {
|
||||
e1000_mng_mode_none = 0,
|
||||
@ -56,35 +57,40 @@ enum e1000_mng_mode {
|
||||
e1000_mng_mode_host_if_only
|
||||
};
|
||||
|
||||
#define E1000_FACTPS_MNGCG 0x20000000
|
||||
#define E1000_FACTPS_MNGCG 0x20000000
|
||||
|
||||
#define E1000_FWSM_MODE_MASK 0xE
|
||||
#define E1000_FWSM_MODE_SHIFT 1
|
||||
#define E1000_FWSM_MODE_MASK 0xE
|
||||
#define E1000_FWSM_MODE_SHIFT 1
|
||||
#define E1000_FWSM_FW_VALID 0x00008000
|
||||
#define E1000_FWSM_HI_EN_ONLY_MODE 0x4
|
||||
|
||||
#define E1000_MNG_IAMT_MODE 0x3
|
||||
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
|
||||
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
|
||||
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
|
||||
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
|
||||
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
|
||||
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
|
||||
#define E1000_MNG_IAMT_MODE 0x3
|
||||
#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10
|
||||
#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0
|
||||
#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10
|
||||
#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
|
||||
#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1
|
||||
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
|
||||
|
||||
#define E1000_VFTA_ENTRY_SHIFT 5
|
||||
#define E1000_VFTA_ENTRY_MASK 0x7F
|
||||
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
|
||||
#define E1000_VFTA_ENTRY_SHIFT 5
|
||||
#define E1000_VFTA_ENTRY_MASK 0x7F
|
||||
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
|
||||
|
||||
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
|
||||
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
|
||||
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
|
||||
|
||||
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
|
||||
#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
|
||||
#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
|
||||
#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI cmd limit */
|
||||
#define E1000_HI_FW_BASE_ADDRESS 0x10000
|
||||
#define E1000_HI_FW_MAX_LENGTH (64 * 1024) /* Num of bytes */
|
||||
#define E1000_HI_FW_BLOCK_DWORD_LENGTH 256 /* Num of DWORDs per page */
|
||||
#define E1000_HICR_MEMORY_BASE_EN 0x200 /* MB Enable bit - RO */
|
||||
#define E1000_HICR_EN 0x01 /* Enable bit - RO */
|
||||
/* Driver sets this bit when done to put command in RAM */
|
||||
#define E1000_HICR_C 0x02
|
||||
#define E1000_HICR_SV 0x04 /* Status Validity */
|
||||
#define E1000_HICR_FW_RESET_ENABLE 0x40
|
||||
#define E1000_HICR_FW_RESET 0x80
|
||||
#define E1000_HICR_C 0x02
|
||||
#define E1000_HICR_SV 0x04 /* Status Validity */
|
||||
#define E1000_HICR_FW_RESET_ENABLE 0x40
|
||||
#define E1000_HICR_FW_RESET 0x80
|
||||
|
||||
/* Intel(R) Active Management Technology signature */
|
||||
#define E1000_IAMT_SIGNATURE 0x544D4149
|
||||
#define E1000_IAMT_SIGNATURE 0x544D4149
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -41,6 +41,10 @@ void e1000_null_phy_generic(struct e1000_hw *hw);
|
||||
s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active);
|
||||
s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_null_set_page(struct e1000_hw *hw, u16 data);
|
||||
s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 *data);
|
||||
s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
|
||||
u8 dev_addr, u8 data);
|
||||
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
|
||||
@ -112,6 +116,8 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw);
|
||||
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
|
||||
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
|
||||
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
|
||||
s32 e1000_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
|
||||
#define E1000_MAX_PHY_ADDR 8
|
||||
|
||||
@ -128,6 +134,17 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
|
||||
#define IGP_PAGE_SHIFT 5
|
||||
#define PHY_REG_MASK 0x1F
|
||||
|
||||
/* GS40G - I210 PHY defines */
|
||||
#define GS40G_PAGE_SELECT 0x16
|
||||
#define GS40G_PAGE_SHIFT 16
|
||||
#define GS40G_OFFSET_MASK 0xFFFF
|
||||
#define GS40G_PAGE_2 0x20000
|
||||
#define GS40G_MAC_REG2 0x15
|
||||
#define GS40G_MAC_LB 0x4140
|
||||
#define GS40G_MAC_SPEED_1G 0X0006
|
||||
#define GS40G_COPPER_SPEC 0x0010
|
||||
#define GS40G_CS_POWER_DOWN 0x0002
|
||||
|
||||
/* BM/HV Specific Registers */
|
||||
#define BM_PORT_CTRL_PAGE 769
|
||||
#define BM_PCIE_PAGE 770
|
||||
@ -174,8 +191,9 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
|
||||
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
|
||||
|
||||
/* I82577 PHY Control 2 */
|
||||
#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
|
||||
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
|
||||
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
|
||||
#define I82577_PHY_CTRL2_AUTO_MDI_MDIX 0x0400
|
||||
#define I82577_PHY_CTRL2_MDIX_CFG_MASK 0x0600
|
||||
|
||||
/* I82577 PHY Diagnostics Status */
|
||||
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -51,6 +51,7 @@
|
||||
#define E1000_BARCTRL_FLSIZE 0x0700 /* BAR ctrl Flsize */
|
||||
#define E1000_BARCTRL_CSRSIZE 0x2000 /* BAR ctrl CSR size */
|
||||
#define E1000_I350_BARCTRL 0x5BFC /* BAR ctrl reg */
|
||||
#define E1000_I350_DTXMXPKTSZ 0x355C /* Maximum sent packet size reg*/
|
||||
#define E1000_SCTL 0x00024 /* SerDes Control - RW */
|
||||
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
|
||||
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
|
||||
@ -143,6 +144,62 @@
|
||||
#define E1000_PBRWAC 0x024E8 /* Rx packet buffer wrap around counter - RO */
|
||||
#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */
|
||||
#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */
|
||||
#define E1000_SRWR 0x12018 /* Shadow Ram Write Register - RW */
|
||||
#define E1000_I210_FLMNGCTL 0x12038
|
||||
#define E1000_I210_FLMNGDATA 0x1203C
|
||||
#define E1000_I210_FLMNGCNT 0x12040
|
||||
|
||||
#define E1000_I210_FLSWCTL 0x12048
|
||||
#define E1000_I210_FLSWDATA 0x1204C
|
||||
#define E1000_I210_FLSWCNT 0x12050
|
||||
|
||||
#define E1000_I210_FLA 0x1201C
|
||||
|
||||
#define E1000_INVM_DATA_REG(_n) (0x12120 + 4*(_n))
|
||||
#define E1000_INVM_SIZE 64 /* Number of INVM Data Registers */
|
||||
|
||||
/* QAV Tx mode control register */
|
||||
#define E1000_I210_TQAVCTRL 0x3570
|
||||
|
||||
/* QAV Tx mode control register bitfields masks */
|
||||
/* QAV enable */
|
||||
#define E1000_TQAVCTRL_MODE (1 << 0)
|
||||
/* Fetching arbitration type */
|
||||
#define E1000_TQAVCTRL_FETCH_ARB (1 << 4)
|
||||
/* Fetching timer enable */
|
||||
#define E1000_TQAVCTRL_FETCH_TIMER_ENABLE (1 << 5)
|
||||
/* Launch arbitration type */
|
||||
#define E1000_TQAVCTRL_LAUNCH_ARB (1 << 8)
|
||||
/* Launch timer enable */
|
||||
#define E1000_TQAVCTRL_LAUNCH_TIMER_ENABLE (1 << 9)
|
||||
/* SP waits for SR enable */
|
||||
#define E1000_TQAVCTRL_SP_WAIT_SR (1 << 10)
|
||||
/* Fetching timer correction */
|
||||
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET 16
|
||||
#define E1000_TQAVCTRL_FETCH_TIMER_DELTA \
|
||||
(0xFFFF << E1000_TQAVCTRL_FETCH_TIMER_DELTA_OFFSET)
|
||||
|
||||
/* High credit registers where _n can be 0 or 1. */
|
||||
#define E1000_I210_TQAVHC(_n) (0x300C + 0x40 * (_n))
|
||||
|
||||
/* Queues fetch arbitration priority control register */
|
||||
#define E1000_I210_TQAVARBCTRL 0x3574
|
||||
/* Queues priority masks where _n and _p can be 0-3. */
|
||||
#define E1000_TQAVARBCTRL_QUEUE_PRI(_n, _p) ((_p) << (2 * _n))
|
||||
/* QAV Tx mode control registers where _n can be 0 or 1. */
|
||||
#define E1000_I210_TQAVCC(_n) (0x3004 + 0x40 * (_n))
|
||||
|
||||
/* QAV Tx mode control register bitfields masks */
|
||||
#define E1000_TQAVCC_IDLE_SLOPE 0xFFFF /* Idle slope */
|
||||
#define E1000_TQAVCC_KEEP_CREDITS (1 << 30) /* Keep credits opt enable */
|
||||
#define E1000_TQAVCC_QUEUE_MODE (1 << 31) /* SP vs. SR Tx mode */
|
||||
|
||||
/* Good transmitted packets counter registers */
|
||||
#define E1000_PQGPTC(_n) (0x010014 + (0x100 * (_n)))
|
||||
|
||||
/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */
|
||||
#define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
|
||||
|
||||
/*
|
||||
* Convenience macros
|
||||
*
|
||||
@ -424,10 +481,11 @@
|
||||
#define E1000_HOST_IF 0x08800 /* Host Interface */
|
||||
#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
|
||||
#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
|
||||
#define E1000_HIBBA 0x8F40 /* Host Interface Buffer Base Address */
|
||||
/* Flexible Host Filter Table */
|
||||
#define E1000_FHFT(_n) (0x09000 + (_n * 0x100))
|
||||
#define E1000_FHFT(_n) (0x09000 + ((_n) * 0x100))
|
||||
/* Ext Flexible Host Filter Table */
|
||||
#define E1000_FHFT_EXT(_n) (0x09A00 + (_n * 0x100))
|
||||
#define E1000_FHFT_EXT(_n) (0x09A00 + ((_n) * 0x100))
|
||||
|
||||
|
||||
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
|
||||
@ -590,10 +648,6 @@
|
||||
/* PCIe Parity Status Register */
|
||||
#define E1000_PCIEERRSTS 0x05BA8
|
||||
|
||||
#define E1000_LTRMINV 0x5BB0 /* LTR Minimum Value */
|
||||
#define E1000_LTRMAXV 0x5BB4 /* LTR Maximum Value */
|
||||
#define E1000_DOBFFCTL 0x3F24 /* DMA OBFF Control Register */
|
||||
|
||||
#define E1000_PROXYS 0x5F64 /* Proxying Status */
|
||||
#define E1000_PROXYFC 0x5F60 /* Proxying Filter Control */
|
||||
/* Thermal sensor configuration and status registers */
|
||||
@ -603,7 +657,7 @@
|
||||
#define E1000_THHIGHTC 0x0810C /* High Threshold Control */
|
||||
#define E1000_THSTAT 0x08110 /* Thermal Sensor Status */
|
||||
|
||||
/*Energy Efficient Ethernet "EEE" registers */
|
||||
/* Energy Efficient Ethernet "EEE" registers */
|
||||
#define E1000_IPCNFG 0x0E38 /* Internal PHY Configuration */
|
||||
#define E1000_LTRC 0x01A0 /* Latency Tolerance Reporting Control */
|
||||
#define E1000_EEER 0x0E30 /* Energy Efficient Ethernet "EEE"*/
|
||||
@ -617,4 +671,9 @@
|
||||
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
|
||||
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */
|
||||
|
||||
#define E1000_LTRMINV 0x5BB0 /* LTR Minimum Value */
|
||||
#define E1000_LTRMAXV 0x5BB4 /* LTR Maximum Value */
|
||||
#define E1000_DOBFFCTL 0x3F24 /* DMA OBFF Control Register */
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -638,7 +638,7 @@ em_attach(device_t dev)
|
||||
/* Sysctl for setting Energy Efficient Ethernet */
|
||||
em_set_sysctl_value(adapter, "eee_control",
|
||||
"enable Energy Efficient Ethernet",
|
||||
&hw->dev_spec.ich8lan.eee_disable, eee_setting);
|
||||
(int *)&hw->dev_spec.ich8lan.eee_disable, eee_setting);
|
||||
|
||||
/*
|
||||
** Start from a known state, this is
|
||||
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2011, Intel Corporation
|
||||
Copyright (c) 2001-2012, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -100,7 +100,7 @@ int igb_display_debug_stats = 0;
|
||||
/*********************************************************************
|
||||
* Driver version:
|
||||
*********************************************************************/
|
||||
char igb_driver_version[] = "version - 2.3.1";
|
||||
char igb_driver_version[] = "version - 2.3.4";
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
@ -150,6 +150,14 @@ static igb_vendor_info_t igb_vendor_info_array[] =
|
||||
{ 0x8086, E1000_DEV_ID_I350_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I350_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I350_VF, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_COPPER_IT, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_COPPER_OEM1,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_FIBER, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_SERDES, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I210_SGMII, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
{ 0x8086, E1000_DEV_ID_I211_COPPER, PCI_ANY_ID, PCI_ANY_ID, 0},
|
||||
/* required last entry */
|
||||
{ 0, 0, 0, 0, 0}
|
||||
};
|
||||
@ -580,9 +588,10 @@ igb_attach(device_t dev)
|
||||
adapter, 0, igb_sysctl_dmac, "I", "DMA Coalesce");
|
||||
igb_set_sysctl_value(adapter, "eee_disabled",
|
||||
"enable Energy Efficient Ethernet",
|
||||
&adapter->hw.dev_spec._82575.eee_disable,
|
||||
(int *)&adapter->hw.dev_spec._82575.eee_disable,
|
||||
TRUE);
|
||||
e1000_set_eee_i350(&adapter->hw);
|
||||
if (adapter->hw.phy.media_type == e1000_media_type_copper)
|
||||
e1000_set_eee_i350(&adapter->hw);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -593,7 +602,9 @@ igb_attach(device_t dev)
|
||||
e1000_reset_hw(&adapter->hw);
|
||||
|
||||
/* Make sure we have a good EEPROM before we read from it */
|
||||
if (e1000_validate_nvm_checksum(&adapter->hw) < 0) {
|
||||
if (((adapter->hw.mac.type != e1000_i210) &&
|
||||
(adapter->hw.mac.type != e1000_i211)) &&
|
||||
(e1000_validate_nvm_checksum(&adapter->hw) < 0)) {
|
||||
/*
|
||||
** Some PCI-E parts fail the first check due to
|
||||
** the link being in sleep state, call it again,
|
||||
@ -756,6 +767,8 @@ igb_detach(device_t dev)
|
||||
if (adapter->vlan_detach != NULL)
|
||||
EVENTHANDLER_DEREGISTER(vlan_unconfig, adapter->vlan_detach);
|
||||
|
||||
ether_ifdetach(adapter->ifp);
|
||||
|
||||
callout_drain(&adapter->timer);
|
||||
|
||||
#ifdef DEV_NETMAP
|
||||
@ -924,7 +937,8 @@ igb_start(struct ifnet *ifp)
|
||||
return;
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* __FreeBSD_version >= 800000 */
|
||||
|
||||
/*
|
||||
** Multiqueue Transmit driver
|
||||
**
|
||||
@ -936,13 +950,11 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
|
||||
struct igb_queue *que;
|
||||
struct tx_ring *txr;
|
||||
int i, err = 0;
|
||||
bool moveable = TRUE;
|
||||
|
||||
/* Which queue to use */
|
||||
if ((m->m_flags & M_FLOWID) != 0) {
|
||||
if ((m->m_flags & M_FLOWID) != 0)
|
||||
i = m->m_pkthdr.flowid % adapter->num_queues;
|
||||
moveable = FALSE;
|
||||
} else
|
||||
else
|
||||
i = curcpu % adapter->num_queues;
|
||||
|
||||
txr = &adapter->tx_rings[i];
|
||||
@ -953,7 +965,7 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
|
||||
IGB_TX_UNLOCK(txr);
|
||||
} else {
|
||||
err = drbr_enqueue(ifp, txr->br, m);
|
||||
taskqueue_enqueue(que->tq, &txr->txq_task);
|
||||
taskqueue_enqueue(que->tq, &que->que_task);
|
||||
}
|
||||
|
||||
return (err);
|
||||
@ -1342,8 +1354,8 @@ igb_init_locked(struct adapter *adapter)
|
||||
}
|
||||
|
||||
/* Set Energy Efficient Ethernet */
|
||||
|
||||
e1000_set_eee_i350(&adapter->hw);
|
||||
if (adapter->hw.phy.media_type == e1000_media_type_copper)
|
||||
e1000_set_eee_i350(&adapter->hw);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2566,6 +2578,8 @@ igb_configure_queues(struct adapter *adapter)
|
||||
switch (adapter->hw.mac.type) {
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
case e1000_vfadapt:
|
||||
case e1000_vfadapt_i350:
|
||||
/* RX entries */
|
||||
@ -2764,7 +2778,7 @@ static int
|
||||
igb_setup_msix(struct adapter *adapter)
|
||||
{
|
||||
device_t dev = adapter->dev;
|
||||
int rid, want, queues, msgs;
|
||||
int rid, want, queues, msgs, maxqueues;
|
||||
|
||||
/* tuneable override */
|
||||
if (igb_enable_msix == 0)
|
||||
@ -2795,16 +2809,29 @@ igb_setup_msix(struct adapter *adapter)
|
||||
/* Manual override */
|
||||
if (igb_num_queues != 0)
|
||||
queues = igb_num_queues;
|
||||
if (queues > 8) /* max queues */
|
||||
queues = 8;
|
||||
|
||||
/* Can have max of 4 queues on 82575 */
|
||||
if ((adapter->hw.mac.type == e1000_82575) && (queues > 4))
|
||||
queues = 4;
|
||||
|
||||
/* Limit the VF devices to one queue */
|
||||
if (adapter->vf_ifp)
|
||||
queues = 1;
|
||||
/* Sanity check based on HW */
|
||||
switch (adapter->hw.mac.type) {
|
||||
case e1000_82575:
|
||||
maxqueues = 4;
|
||||
break;
|
||||
case e1000_82576:
|
||||
case e1000_82580:
|
||||
case e1000_i350:
|
||||
maxqueues = 8;
|
||||
break;
|
||||
case e1000_i210:
|
||||
maxqueues = 4;
|
||||
break;
|
||||
case e1000_i211:
|
||||
maxqueues = 2;
|
||||
break;
|
||||
default: /* VF interfaces */
|
||||
maxqueues = 1;
|
||||
break;
|
||||
}
|
||||
if (queues > maxqueues)
|
||||
queues = maxqueues;
|
||||
|
||||
/*
|
||||
** One vector (RX/TX pair) per queue
|
||||
@ -2875,6 +2902,9 @@ igb_reset(struct adapter *adapter)
|
||||
pba = E1000_READ_REG(hw, E1000_RXPBS);
|
||||
pba = e1000_rxpbs_adjust_82580(pba);
|
||||
break;
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
pba = E1000_PBA_34K;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2942,7 +2972,9 @@ igb_reset(struct adapter *adapter)
|
||||
device_printf(dev, "Hardware Initialization Failed\n");
|
||||
|
||||
/* Setup DMA Coalescing */
|
||||
if (hw->mac.type == e1000_i350) {
|
||||
if ((hw->mac.type > e1000_82580) &&
|
||||
(hw->mac.type != e1000_i211)) {
|
||||
u32 dmac;
|
||||
u32 reg = ~E1000_DMACR_DMAC_EN;
|
||||
|
||||
if (adapter->dmac == 0) { /* Disabling it */
|
||||
@ -2950,26 +2982,36 @@ igb_reset(struct adapter *adapter)
|
||||
goto reset_out;
|
||||
}
|
||||
|
||||
hwm = (pba - 4) << 10;
|
||||
reg = (((pba-6) << E1000_DMACR_DMACTHR_SHIFT)
|
||||
& E1000_DMACR_DMACTHR_MASK);
|
||||
/* Set starting thresholds */
|
||||
E1000_WRITE_REG(hw, E1000_DMCTXTH, 0);
|
||||
E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
|
||||
|
||||
hwm = 64 * pba - adapter->max_frame_size / 16;
|
||||
if (hwm < 64 * (pba - 6))
|
||||
hwm = 64 * (pba - 6);
|
||||
reg = E1000_READ_REG(hw, E1000_FCRTC);
|
||||
reg &= ~E1000_FCRTC_RTH_COAL_MASK;
|
||||
reg |= ((hwm << E1000_FCRTC_RTH_COAL_SHIFT)
|
||||
& E1000_FCRTC_RTH_COAL_MASK);
|
||||
E1000_WRITE_REG(hw, E1000_FCRTC, reg);
|
||||
|
||||
|
||||
dmac = pba - adapter->max_frame_size / 512;
|
||||
if (dmac < pba - 10)
|
||||
dmac = pba - 10;
|
||||
reg = E1000_READ_REG(hw, E1000_DMACR);
|
||||
reg &= ~E1000_DMACR_DMACTHR_MASK;
|
||||
reg = ((dmac << E1000_DMACR_DMACTHR_SHIFT)
|
||||
& E1000_DMACR_DMACTHR_MASK);
|
||||
/* transition to L0x or L1 if available..*/
|
||||
reg |= (E1000_DMACR_DMAC_EN | E1000_DMACR_DMAC_LX_MASK);
|
||||
|
||||
/* timer = value in adapter->dmac in 32usec intervals */
|
||||
reg |= (adapter->dmac >> 5);
|
||||
E1000_WRITE_REG(hw, E1000_DMACR, reg);
|
||||
|
||||
/* No lower threshold */
|
||||
E1000_WRITE_REG(hw, E1000_DMCRTRH, 0);
|
||||
|
||||
/* set hwm to PBA - 2 * max frame size */
|
||||
E1000_WRITE_REG(hw, E1000_FCRTC, hwm);
|
||||
|
||||
/* Set the interval before transition */
|
||||
reg = E1000_READ_REG(hw, E1000_DMCTLX);
|
||||
reg |= 0x800000FF; /* 255 usec */
|
||||
reg |= 0x80000004;
|
||||
E1000_WRITE_REG(hw, E1000_DMCTLX, reg);
|
||||
|
||||
/* free space in tx packet buffer to wake from DMA coal */
|
||||
@ -2978,9 +3020,15 @@ igb_reset(struct adapter *adapter)
|
||||
|
||||
/* make low power state decision controlled by DMA coal */
|
||||
reg = E1000_READ_REG(hw, E1000_PCIEMISC);
|
||||
E1000_WRITE_REG(hw, E1000_PCIEMISC,
|
||||
reg | E1000_PCIEMISC_LX_DECISION);
|
||||
reg &= ~E1000_PCIEMISC_LX_DECISION;
|
||||
E1000_WRITE_REG(hw, E1000_PCIEMISC, reg);
|
||||
device_printf(dev, "DMA Coalescing enabled\n");
|
||||
|
||||
} else if (hw->mac.type == e1000_82580) {
|
||||
u32 reg = E1000_READ_REG(hw, E1000_PCIEMISC);
|
||||
E1000_WRITE_REG(hw, E1000_DMACR, 0);
|
||||
E1000_WRITE_REG(hw, E1000_PCIEMISC,
|
||||
reg & ~E1000_PCIEMISC_LX_DECISION);
|
||||
}
|
||||
|
||||
reset_out:
|
||||
|
@ -6,7 +6,7 @@ SRCS += if_igb.c $(SHARED_SRCS)
|
||||
SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c
|
||||
SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
|
||||
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
|
||||
SHARED_SRCS += e1000_82575.c e1000_vf.c e1000_mbx.c
|
||||
SHARED_SRCS += e1000_82575.c e1000_vf.c e1000_mbx.c e1000_i210.c
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000 -DSMP
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user