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:
Jack F Vogel 2012-07-05 20:26:57 +00:00
parent 6e50170633
commit ab5d036272
22 changed files with 2264 additions and 1083 deletions

View File

@ -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 \

View File

@ -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.

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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:
*

View File

@ -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 */

View File

@ -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
View 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;
}

View 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

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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