Refresh on the shared code for the E1000 drivers.

- bear with me, there are lots of white space changes, I would not
    do them, but I am a mere consumer of this stuff and if these drivers
    are to stay in shape they need to be taken.

em driver changes: support for the new i217/i218 interfaces

igb driver changes:
  - TX mq start has a quick turnaround to the stack
  - Link/media handling improvement
  - When link status changes happen the current flow control state
    will now be displayed.
  - A few white space/style changes.

lem driver changes:
  - the shared code uncovered a bogus write to the RLPML register
    (which does not exist in this hardware) in the vlan code,this
    is removed.
This commit is contained in:
Jack F Vogel 2013-02-21 00:25:45 +00:00
parent b85313804d
commit 6ab6bfe32f
23 changed files with 2529 additions and 2097 deletions

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2011, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -32,8 +32,7 @@
******************************************************************************/ ******************************************************************************/
/*$FreeBSD$*/ /*$FreeBSD$*/
/* /* 82571EB Gigabit Ethernet Controller
* 82571EB Gigabit Ethernet Controller
* 82571EB Gigabit Ethernet Controller (Copper) * 82571EB Gigabit Ethernet Controller (Copper)
* 82571EB Gigabit Ethernet Controller (Fiber) * 82571EB Gigabit Ethernet Controller (Fiber)
* 82571EB Dual Port Gigabit Mezzanine Adapter * 82571EB Dual Port Gigabit Mezzanine Adapter
@ -51,9 +50,6 @@
#include "e1000_api.h" #include "e1000_api.h"
static s32 e1000_init_phy_params_82571(struct e1000_hw *hw);
static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw);
static s32 e1000_init_mac_params_82571(struct e1000_hw *hw);
static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw); static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw);
static void e1000_release_nvm_82571(struct e1000_hw *hw); static void e1000_release_nvm_82571(struct e1000_hw *hw);
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset,
@ -78,7 +74,6 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw);
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
@ -99,13 +94,13 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
{ {
struct e1000_phy_info *phy = &hw->phy; struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS; s32 ret_val;
DEBUGFUNC("e1000_init_phy_params_82571"); DEBUGFUNC("e1000_init_phy_params_82571");
if (hw->phy.media_type != e1000_media_type_copper) { if (hw->phy.media_type != e1000_media_type_copper) {
phy->type = e1000_phy_none; phy->type = e1000_phy_none;
goto out; return E1000_SUCCESS;
} }
phy->addr = 1; phy->addr = 1;
@ -165,8 +160,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574; phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574;
break; break;
default: default:
ret_val = -E1000_ERR_PHY; return -E1000_ERR_PHY;
goto out;
break; break;
} }
@ -174,7 +168,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
ret_val = e1000_get_phy_id_82571(hw); ret_val = e1000_get_phy_id_82571(hw);
if (ret_val) { if (ret_val) {
DEBUGOUT("Error getting PHY ID\n"); DEBUGOUT("Error getting PHY ID\n");
goto out; return ret_val;
} }
/* Verify phy id */ /* Verify phy id */
@ -201,7 +195,6 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
if (ret_val) if (ret_val)
DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id);
out:
return ret_val; return ret_val;
} }
@ -241,8 +234,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
if (((eecd >> 15) & 0x3) == 0x3) { if (((eecd >> 15) & 0x3) == 0x3) {
nvm->type = e1000_nvm_flash_hw; nvm->type = e1000_nvm_flash_hw;
nvm->word_size = 2048; nvm->word_size = 2048;
/* /* Autonomous Flash update bit must be cleared due
* Autonomous Flash update bit must be cleared due
* to Flash update issue. * to Flash update issue.
*/ */
eecd &= ~E1000_EECD_AUPDEN; eecd &= ~E1000_EECD_AUPDEN;
@ -254,8 +246,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
nvm->type = e1000_nvm_eeprom_spi; nvm->type = e1000_nvm_eeprom_spi;
size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
E1000_EECD_SIZE_EX_SHIFT); E1000_EECD_SIZE_EX_SHIFT);
/* /* Added to a constant, "size" becomes the left-shift value
* Added to a constant, "size" becomes the left-shift value
* for setting word_size. * for setting word_size.
*/ */
size += NVM_WORD_SIZE_BASE_SHIFT; size += NVM_WORD_SIZE_BASE_SHIFT;
@ -382,12 +373,11 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
/* FWSM register */ /* FWSM register */
mac->has_fwsm = TRUE; mac->has_fwsm = TRUE;
/* /* ARC supported; valid only if manageability features are
* ARC supported; valid only if manageability features are
* enabled. * enabled.
*/ */
mac->arc_subsystem_valid = (E1000_READ_REG(hw, E1000_FWSM) & mac->arc_subsystem_valid = !!(E1000_READ_REG(hw, E1000_FWSM) &
E1000_FWSM_MODE_MASK) ? TRUE : FALSE; E1000_FWSM_MODE_MASK);
break; break;
case e1000_82574: case e1000_82574:
case e1000_82583: case e1000_82583:
@ -405,8 +395,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
break; break;
} }
/* /* Ensure that the inter-port SWSM.SMBI lock bit is clear before
* Ensure that the inter-port SWSM.SMBI lock bit is clear before
* first NVM or PHY acess. This should be done for single-port * first NVM or PHY acess. This should be done for single-port
* devices, and for one port only on dual-port devices so that * devices, and for one port only on dual-port devices so that
* for those devices we can still use the SMBI lock to synchronize * for those devices we can still use the SMBI lock to synchronize
@ -422,8 +411,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_SWSM2, swsm2 | E1000_WRITE_REG(hw, E1000_SWSM2, swsm2 |
E1000_SWSM2_LOCK); E1000_SWSM2_LOCK);
force_clear_smbi = TRUE; force_clear_smbi = TRUE;
} else } else {
force_clear_smbi = FALSE; force_clear_smbi = FALSE;
}
break; break;
default: default:
force_clear_smbi = TRUE; force_clear_smbi = TRUE;
@ -443,10 +433,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_SWSM, swsm & ~E1000_SWSM_SMBI); E1000_WRITE_REG(hw, E1000_SWSM, swsm & ~E1000_SWSM_SMBI);
} }
/* /* Initialze device specific counter of SMBI acquisition timeouts. */
* Initialze device specific counter of SMBI acquisition
* timeouts.
*/
hw->dev_spec._82571.smb_counter = 0; hw->dev_spec._82571.smb_counter = 0;
return E1000_SUCCESS; return E1000_SUCCESS;
@ -477,7 +464,7 @@ void e1000_init_function_pointers_82571(struct e1000_hw *hw)
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
{ {
struct e1000_phy_info *phy = &hw->phy; struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS; s32 ret_val;
u16 phy_id = 0; u16 phy_id = 0;
DEBUGFUNC("e1000_get_phy_id_82571"); DEBUGFUNC("e1000_get_phy_id_82571");
@ -485,8 +472,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82571: case e1000_82571:
case e1000_82572: case e1000_82572:
/* /* The 82571 firmware may still be configuring the PHY.
* The 82571 firmware may still be configuring the PHY.
* In this case, we cannot access the PHY until the * In this case, we cannot access the PHY until the
* configuration is done. So we explicitly set the * configuration is done. So we explicitly set the
* PHY ID. * PHY ID.
@ -494,29 +480,29 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
phy->id = IGP01E1000_I_PHY_ID; phy->id = IGP01E1000_I_PHY_ID;
break; break;
case e1000_82573: case e1000_82573:
ret_val = e1000_get_phy_id(hw); return e1000_get_phy_id(hw);
break; break;
case e1000_82574: case e1000_82574:
case e1000_82583: case e1000_82583:
ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
if (ret_val) if (ret_val)
goto out; return ret_val;
phy->id = (u32)(phy_id << 16); phy->id = (u32)(phy_id << 16);
usec_delay(20); usec_delay(20);
ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
if (ret_val) if (ret_val)
goto out; return ret_val;
phy->id |= (u32)(phy_id); phy->id |= (u32)(phy_id);
phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
break; break;
default: default:
ret_val = -E1000_ERR_PHY; return -E1000_ERR_PHY;
break; break;
} }
out:
return ret_val; return E1000_SUCCESS;
} }
/** /**
@ -528,15 +514,13 @@ out:
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
{ {
u32 swsm; u32 swsm;
s32 ret_val = E1000_SUCCESS;
s32 sw_timeout = hw->nvm.word_size + 1; s32 sw_timeout = hw->nvm.word_size + 1;
s32 fw_timeout = hw->nvm.word_size + 1; s32 fw_timeout = hw->nvm.word_size + 1;
s32 i = 0; s32 i = 0;
DEBUGFUNC("e1000_get_hw_semaphore_82571"); DEBUGFUNC("e1000_get_hw_semaphore_82571");
/* /* If we have timedout 3 times on trying to acquire
* If we have timedout 3 times on trying to acquire
* the inter-port SMBI semaphore, there is old code * the inter-port SMBI semaphore, there is old code
* operating on the other port, and it is not * operating on the other port, and it is not
* releasing SMBI. Modify the number of times that * releasing SMBI. Modify the number of times that
@ -576,12 +560,10 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
/* Release semaphores */ /* Release semaphores */
e1000_put_hw_semaphore_82571(hw); e1000_put_hw_semaphore_82571(hw);
DEBUGOUT("Driver can't access the NVM\n"); DEBUGOUT("Driver can't access the NVM\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -613,22 +595,19 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
{ {
u32 extcnf_ctrl; u32 extcnf_ctrl;
s32 ret_val = E1000_SUCCESS;
s32 i = 0; s32 i = 0;
DEBUGFUNC("e1000_get_hw_semaphore_82573"); DEBUGFUNC("e1000_get_hw_semaphore_82573");
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
do { do {
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
break; break;
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
msec_delay(2); msec_delay(2);
i++; i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT); } while (i < MDIO_OWNERSHIP_TIMEOUT);
@ -637,12 +616,10 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
/* Release semaphores */ /* Release semaphores */
e1000_put_hw_semaphore_82573(hw); e1000_put_hw_semaphore_82573(hw);
DEBUGOUT("Driver can't access the PHY\n"); DEBUGOUT("Driver can't access the PHY\n");
ret_val = -E1000_ERR_PHY; return -E1000_ERR_PHY;
goto out;
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -712,7 +689,7 @@ static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
**/ **/
static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active) static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active)
{ {
u16 data = E1000_READ_REG(hw, E1000_POEMB); u32 data = E1000_READ_REG(hw, E1000_POEMB);
DEBUGFUNC("e1000_set_d0_lplu_state_82574"); DEBUGFUNC("e1000_set_d0_lplu_state_82574");
@ -738,7 +715,7 @@ static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active)
**/ **/
static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active) static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active)
{ {
u16 data = E1000_READ_REG(hw, E1000_POEMB); u32 data = E1000_READ_REG(hw, E1000_POEMB);
DEBUGFUNC("e1000_set_d3_lplu_state_82574"); DEBUGFUNC("e1000_set_d3_lplu_state_82574");
@ -771,7 +748,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
ret_val = e1000_get_hw_semaphore_82571(hw); ret_val = e1000_get_hw_semaphore_82571(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82573: case e1000_82573:
@ -784,7 +761,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
if (ret_val) if (ret_val)
e1000_put_hw_semaphore_82571(hw); e1000_put_hw_semaphore_82571(hw);
out:
return ret_val; return ret_val;
} }
@ -817,7 +793,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data) u16 *data)
{ {
s32 ret_val = E1000_SUCCESS; s32 ret_val;
DEBUGFUNC("e1000_write_nvm_82571"); DEBUGFUNC("e1000_write_nvm_82571");
@ -857,31 +833,27 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
ret_val = e1000_update_nvm_checksum_generic(hw); ret_val = e1000_update_nvm_checksum_generic(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
/* /* If our nvm is an EEPROM, then we're done
* If our nvm is an EEPROM, then we're done
* otherwise, commit the checksum to the flash NVM. * otherwise, commit the checksum to the flash NVM.
*/ */
if (hw->nvm.type != e1000_nvm_flash_hw) if (hw->nvm.type != e1000_nvm_flash_hw)
goto out; return E1000_SUCCESS;
/* Check for pending operations. */ /* Check for pending operations. */
for (i = 0; i < E1000_FLASH_UPDATES; i++) { for (i = 0; i < E1000_FLASH_UPDATES; i++) {
msec_delay(1); msec_delay(1);
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD))
break; break;
} }
if (i == E1000_FLASH_UPDATES) { if (i == E1000_FLASH_UPDATES)
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
}
/* Reset the firmware if using STM opcode. */ /* Reset the firmware if using STM opcode. */
if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) { if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) {
/* /* The enabling of and the actual reset must be done
* The enabling of and the actual reset must be done
* in two write cycles. * in two write cycles.
*/ */
E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE); E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE);
@ -895,17 +867,14 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
for (i = 0; i < E1000_FLASH_UPDATES; i++) { for (i = 0; i < E1000_FLASH_UPDATES; i++) {
msec_delay(1); msec_delay(1);
if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) if (!(E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD))
break; break;
} }
if (i == E1000_FLASH_UPDATES) { if (i == E1000_FLASH_UPDATES)
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
}
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -944,19 +913,17 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
{ {
struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_nvm_info *nvm = &hw->nvm;
u32 i, eewr = 0; u32 i, eewr = 0;
s32 ret_val = 0; s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_write_nvm_eewr_82571"); DEBUGFUNC("e1000_write_nvm_eewr_82571");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* and not enough words. * and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
for (i = 0; i < words; i++) { for (i = 0; i < words; i++) {
@ -975,7 +942,6 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
break; break;
} }
out:
return ret_val; return ret_val;
} }
@ -988,7 +954,6 @@ out:
static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
{ {
s32 timeout = PHY_CFG_TIMEOUT; s32 timeout = PHY_CFG_TIMEOUT;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_get_cfg_done_82571"); DEBUGFUNC("e1000_get_cfg_done_82571");
@ -1001,12 +966,10 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
} }
if (!timeout) { if (!timeout) {
DEBUGOUT("MNG configuration cycle has not completed.\n"); DEBUGOUT("MNG configuration cycle has not completed.\n");
ret_val = -E1000_ERR_RESET; return -E1000_ERR_RESET;
goto out;
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -1023,39 +986,40 @@ out:
static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
{ {
struct e1000_phy_info *phy = &hw->phy; struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS; s32 ret_val;
u16 data; u16 data;
DEBUGFUNC("e1000_set_d0_lplu_state_82571"); DEBUGFUNC("e1000_set_d0_lplu_state_82571");
if (!(phy->ops.read_reg)) if (!(phy->ops.read_reg))
goto out; return E1000_SUCCESS;
ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
if (active) { if (active) {
data |= IGP02E1000_PM_D0_LPLU; data |= IGP02E1000_PM_D0_LPLU;
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data); data);
if (ret_val) if (ret_val)
goto out; return ret_val;
/* When LPLU is enabled, we should disable SmartSpeed */ /* When LPLU is enabled, we should disable SmartSpeed */
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
&data); &data);
if (ret_val)
return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED; data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
data); data);
if (ret_val) if (ret_val)
goto out; return ret_val;
} else { } else {
data &= ~IGP02E1000_PM_D0_LPLU; data &= ~IGP02E1000_PM_D0_LPLU;
ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT,
data); data);
/* /* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most * during Dx states where the power conservation is most
* important. During driver activity we should enable * important. During driver activity we should enable
* SmartSpeed, so performance is maintained. * SmartSpeed, so performance is maintained.
@ -1065,32 +1029,31 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
IGP01E1000_PHY_PORT_CONFIG, IGP01E1000_PHY_PORT_CONFIG,
&data); &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
data |= IGP01E1000_PSCFR_SMART_SPEED; data |= IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw, ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, IGP01E1000_PHY_PORT_CONFIG,
data); data);
if (ret_val) if (ret_val)
goto out; return ret_val;
} else if (phy->smart_speed == e1000_smart_speed_off) { } else if (phy->smart_speed == e1000_smart_speed_off) {
ret_val = phy->ops.read_reg(hw, ret_val = phy->ops.read_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, IGP01E1000_PHY_PORT_CONFIG,
&data); &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
data &= ~IGP01E1000_PSCFR_SMART_SPEED; data &= ~IGP01E1000_PSCFR_SMART_SPEED;
ret_val = phy->ops.write_reg(hw, ret_val = phy->ops.write_reg(hw,
IGP01E1000_PHY_PORT_CONFIG, IGP01E1000_PHY_PORT_CONFIG,
data); data);
if (ret_val) if (ret_val)
goto out; return ret_val;
} }
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -1101,13 +1064,12 @@ out:
**/ **/
static s32 e1000_reset_hw_82571(struct e1000_hw *hw) static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
{ {
u32 ctrl, ctrl_ext; u32 ctrl, ctrl_ext, eecd, tctl;
s32 ret_val; s32 ret_val;
DEBUGFUNC("e1000_reset_hw_82571"); DEBUGFUNC("e1000_reset_hw_82571");
/* /* Prevent the PCI-E bus from sticking if there is no TLP connection
* Prevent the PCI-E bus from sticking if there is no TLP connection
* on the last TLP read/write transaction when MAC is reset. * on the last TLP read/write transaction when MAC is reset.
*/ */
ret_val = e1000_disable_pcie_master_generic(hw); ret_val = e1000_disable_pcie_master_generic(hw);
@ -1118,13 +1080,14 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
E1000_WRITE_REG(hw, E1000_RCTL, 0); E1000_WRITE_REG(hw, E1000_RCTL, 0);
E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); tctl = E1000_READ_REG(hw, E1000_TCTL);
tctl &= ~E1000_TCTL_EN;
E1000_WRITE_REG(hw, E1000_TCTL, tctl);
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
msec_delay(10); msec_delay(10);
/* /* Must acquire the MDIO ownership before MAC reset.
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset. * Ownership defaults to firmware after a reset.
*/ */
switch (hw->mac.type) { switch (hw->mac.type) {
@ -1167,15 +1130,23 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ret_val = e1000_get_auto_rd_done_generic(hw); ret_val = e1000_get_auto_rd_done_generic(hw);
if (ret_val) if (ret_val)
/* We don't want to continue accessing MAC registers. */ /* We don't want to continue accessing MAC registers. */
goto out; return ret_val;
/* /* Phy configuration from NVM just starts after EECD_AUTO_RD is set.
* Phy configuration from NVM just starts after EECD_AUTO_RD is set.
* Need to wait for Phy configuration completion before accessing * Need to wait for Phy configuration completion before accessing
* NVM and Phy. * NVM and Phy.
*/ */
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82571:
case e1000_82572:
/* REQ and GNT bits need to be cleared when using AUTO_RD
* to access the EEPROM.
*/
eecd = E1000_READ_REG(hw, E1000_EECD);
eecd &= ~(E1000_EECD_REQ | E1000_EECD_GNT);
E1000_WRITE_REG(hw, E1000_EECD, eecd);
break;
case e1000_82573: case e1000_82573:
case e1000_82574: case e1000_82574:
case e1000_82583: case e1000_82583:
@ -1193,7 +1164,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
/* Install any alternate MAC address into RAR0 */ /* Install any alternate MAC address into RAR0 */
ret_val = e1000_check_alt_mac_addr_generic(hw); ret_val = e1000_check_alt_mac_addr_generic(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
e1000_set_laa_state_82571(hw, TRUE); e1000_set_laa_state_82571(hw, TRUE);
} }
@ -1202,8 +1173,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
if (hw->phy.media_type == e1000_media_type_internal_serdes) if (hw->phy.media_type == e1000_media_type_internal_serdes)
hw->mac.serdes_link_state = e1000_serdes_link_down; hw->mac.serdes_link_state = e1000_serdes_link_down;
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -1225,16 +1195,15 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
/* Initialize identification LED */ /* Initialize identification LED */
ret_val = mac->ops.id_led_init(hw); ret_val = mac->ops.id_led_init(hw);
/* An error is not fatal and we should not stop init due to this */
if (ret_val) if (ret_val)
DEBUGOUT("Error initializing identification LED\n"); DEBUGOUT("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
/* Disabling VLAN filtering */ /* Disabling VLAN filtering */
DEBUGOUT("Initializing the IEEE VLAN\n"); DEBUGOUT("Initializing the IEEE VLAN\n");
mac->ops.clear_vfta(hw); mac->ops.clear_vfta(hw);
/* Setup the receive address. */ /* Setup the receive address.
/*
* If, however, a locally administered address was assigned to the * If, however, a locally administered address was assigned to the
* 82571, we must reserve a RAR for it to work around an issue where * 82571, we must reserve a RAR for it to work around an issue where
* resetting one port will reload the MAC on the other port. * resetting one port will reload the MAC on the other port.
@ -1277,8 +1246,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
break; break;
} }
/* /* Clear all of the statistics registers (clear on read). It is
* Clear all of the statistics registers (clear on read). It is
* important that we do this after we have tried to establish link * important that we do this after we have tried to establish link
* because the symbol error count will increment wildly if there * because the symbol error count will increment wildly if there
* is no link. * is no link.
@ -1377,8 +1345,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_PBA_ECC, reg); E1000_WRITE_REG(hw, E1000_PBA_ECC, reg);
} }
/* /* Workaround for hardware errata.
* Workaround for hardware errata.
* Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572 * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
*/ */
if ((hw->mac.type == e1000_82571) || if ((hw->mac.type == e1000_82571) ||
@ -1388,6 +1355,15 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
} }
/* Disable IPv6 extension header parsing because some malformed
* IPv6 headers can hang the Rx.
*/
if (hw->mac.type <= e1000_82573) {
reg = E1000_READ_REG(hw, E1000_RFCTL);
reg |= (E1000_RFCTL_IPV6_EX_DIS | E1000_RFCTL_NEW_IPV6_EXT_DIS);
E1000_WRITE_REG(hw, E1000_RFCTL, reg);
}
/* PCI-Ex Control Registers */ /* PCI-Ex Control Registers */
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82574: case e1000_82574:
@ -1396,8 +1372,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
reg |= (1 << 22); reg |= (1 << 22);
E1000_WRITE_REG(hw, E1000_GCR, reg); E1000_WRITE_REG(hw, E1000_GCR, reg);
/* /* Workaround for hardware errata.
* Workaround for hardware errata.
* apply workaround for hardware errata documented in errata * apply workaround for hardware errata documented in errata
* docs Fixes issue where some error prone or unreliable PCIe * docs Fixes issue where some error prone or unreliable PCIe
* completions are occurring, particularly with ASPM enabled. * completions are occurring, particularly with ASPM enabled.
@ -1435,25 +1410,25 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw)
case e1000_82574: case e1000_82574:
case e1000_82583: case e1000_82583:
if (hw->mng_cookie.vlan_id != 0) { if (hw->mng_cookie.vlan_id != 0) {
/* /* The VFTA is a 4096b bit-field, each identifying
* The VFTA is a 4096b bit-field, each identifying
* a single VLAN ID. The following operations * a single VLAN ID. The following operations
* determine which 32b entry (i.e. offset) into the * determine which 32b entry (i.e. offset) into the
* array we want to set the VLAN ID (i.e. bit) of * array we want to set the VLAN ID (i.e. bit) of
* the manageability unit. * the manageability unit.
*/ */
vfta_offset = (hw->mng_cookie.vlan_id >> vfta_offset = (hw->mng_cookie.vlan_id >>
E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK; E1000_VFTA_ENTRY_SHIFT) &
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id & E1000_VFTA_ENTRY_MASK;
E1000_VFTA_ENTRY_BIT_SHIFT_MASK); vfta_bit_in_reg =
1 << (hw->mng_cookie.vlan_id &
E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
} }
break; break;
default: default:
break; break;
} }
for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
/* /* If the offset we want to clear is the same offset of the
* If the offset we want to clear is the same offset of the
* manageability VLAN ID, then clear all bits except that of * manageability VLAN ID, then clear all bits except that of
* the manageability unit. * the manageability unit.
*/ */
@ -1495,8 +1470,7 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw)
ctrl = hw->mac.ledctl_mode2; ctrl = hw->mac.ledctl_mode2;
if (!(E1000_STATUS_LU & E1000_READ_REG(hw, E1000_STATUS))) { if (!(E1000_STATUS_LU & E1000_READ_REG(hw, E1000_STATUS))) {
/* /* If no link, then turn LED on by setting the invert bit
* If no link, then turn LED on by setting the invert bit
* for each LED that's "on" (0x0E) in ledctl_mode2. * for each LED that's "on" (0x0E) in ledctl_mode2.
*/ */
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
@ -1519,30 +1493,28 @@ bool e1000_check_phy_82574(struct e1000_hw *hw)
{ {
u16 status_1kbt = 0; u16 status_1kbt = 0;
u16 receive_errors = 0; u16 receive_errors = 0;
bool phy_hung = FALSE; s32 ret_val;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_check_phy_82574"); DEBUGFUNC("e1000_check_phy_82574");
/* /* Read PHY Receive Error counter first, if its is max - all F's then
* Read PHY Receive Error counter first, if its is max - all F's then
* read the Base1000T status register If both are max then PHY is hung. * read the Base1000T status register If both are max then PHY is hung.
*/ */
ret_val = hw->phy.ops.read_reg(hw, E1000_RECEIVE_ERROR_COUNTER, ret_val = hw->phy.ops.read_reg(hw, E1000_RECEIVE_ERROR_COUNTER,
&receive_errors); &receive_errors);
if (ret_val) if (ret_val)
goto out; return FALSE;
if (receive_errors == E1000_RECEIVE_ERROR_MAX) { if (receive_errors == E1000_RECEIVE_ERROR_MAX) {
ret_val = hw->phy.ops.read_reg(hw, E1000_BASE1000T_STATUS, ret_val = hw->phy.ops.read_reg(hw, E1000_BASE1000T_STATUS,
&status_1kbt); &status_1kbt);
if (ret_val) if (ret_val)
goto out; return FALSE;
if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) == if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) ==
E1000_IDLE_ERROR_COUNT_MASK) E1000_IDLE_ERROR_COUNT_MASK)
phy_hung = TRUE; return TRUE;
} }
out:
return phy_hung; return FALSE;
} }
@ -1560,8 +1532,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
{ {
DEBUGFUNC("e1000_setup_link_82571"); DEBUGFUNC("e1000_setup_link_82571");
/* /* 82573 does not have a word in the NVM to determine
* 82573 does not have a word in the NVM to determine
* the default flow control setting, so we explicitly * the default flow control setting, so we explicitly
* set it to full. * set it to full.
*/ */
@ -1608,17 +1579,14 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
ret_val = e1000_copper_link_setup_igp(hw); ret_val = e1000_copper_link_setup_igp(hw);
break; break;
default: default:
ret_val = -E1000_ERR_PHY; return -E1000_ERR_PHY;
break; break;
} }
if (ret_val) if (ret_val)
goto out; return ret_val;
ret_val = e1000_setup_copper_link_generic(hw); return e1000_setup_copper_link_generic(hw);
out:
return ret_val;
} }
/** /**
@ -1635,8 +1603,7 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_82571: case e1000_82571:
case e1000_82572: case e1000_82572:
/* /* If SerDes loopback mode is entered, there is no form
* If SerDes loopback mode is entered, there is no form
* of reset to take the adapter out of that mode. So we * of reset to take the adapter out of that mode. So we
* have to explicitly take the adapter out of loopback * have to explicitly take the adapter out of loopback
* mode. This prevents drivers from twiddling their thumbs * mode. This prevents drivers from twiddling their thumbs
@ -1685,16 +1652,17 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl = E1000_READ_REG(hw, E1000_CTRL);
status = E1000_READ_REG(hw, E1000_STATUS); status = E1000_READ_REG(hw, E1000_STATUS);
E1000_READ_REG(hw, E1000_RXCW);
/* SYNCH bit and IV bit are sticky */
usec_delay(10);
rxcw = E1000_READ_REG(hw, E1000_RXCW); rxcw = E1000_READ_REG(hw, E1000_RXCW);
if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) { if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
/* Receiver is synchronized with no invalid bits. */ /* Receiver is synchronized with no invalid bits. */
switch (mac->serdes_link_state) { switch (mac->serdes_link_state) {
case e1000_serdes_link_autoneg_complete: case e1000_serdes_link_autoneg_complete:
if (!(status & E1000_STATUS_LU)) { if (!(status & E1000_STATUS_LU)) {
/* /* We have lost link, retry autoneg before
* We have lost link, retry autoneg before
* reporting link failure * reporting link failure
*/ */
mac->serdes_link_state = mac->serdes_link_state =
@ -1707,15 +1675,12 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
break; break;
case e1000_serdes_link_forced_up: case e1000_serdes_link_forced_up:
/* /* If we are receiving /C/ ordered sets, re-enable
* If we are receiving /C/ ordered sets, re-enable
* auto-negotiation in the TXCW register and disable * auto-negotiation in the TXCW register and disable
* forced link in the Device Control register in an * forced link in the Device Control register in an
* attempt to auto-negotiate with our link partner. * attempt to auto-negotiate with our link partner.
* If the partner code word is null, stop forcing
* and restart auto negotiation.
*/ */
if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { if (rxcw & E1000_RXCW_C) {
/* Enable autoneg, and unforce link up */ /* Enable autoneg, and unforce link up */
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw); E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
E1000_WRITE_REG(hw, E1000_CTRL, E1000_WRITE_REG(hw, E1000_CTRL,
@ -1731,8 +1696,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
case e1000_serdes_link_autoneg_progress: case e1000_serdes_link_autoneg_progress:
if (rxcw & E1000_RXCW_C) { if (rxcw & E1000_RXCW_C) {
/* /* We received /C/ ordered sets, meaning the
* We received /C/ ordered sets, meaning the
* link partner has autonegotiated, and we can * link partner has autonegotiated, and we can
* trust the Link Up (LU) status bit. * trust the Link Up (LU) status bit.
*/ */
@ -1748,8 +1712,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
DEBUGOUT("AN_PROG -> DOWN\n"); DEBUGOUT("AN_PROG -> DOWN\n");
} }
} else { } else {
/* /* The link partner did not autoneg.
* The link partner did not autoneg.
* Force link up and full duplex, and change * Force link up and full duplex, and change
* state to forced. * state to forced.
*/ */
@ -1774,8 +1737,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
case e1000_serdes_link_down: case e1000_serdes_link_down:
default: default:
/* /* The link was down but the receiver has now gained
* The link was down but the receiver has now gained
* valid sync, so lets see if we can bring the link * valid sync, so lets see if we can bring the link
* up. * up.
*/ */
@ -1794,17 +1756,18 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
mac->serdes_link_state = e1000_serdes_link_down; mac->serdes_link_state = e1000_serdes_link_down;
DEBUGOUT("ANYSTATE -> DOWN\n"); DEBUGOUT("ANYSTATE -> DOWN\n");
} else { } else {
/* /* Check several times, if SYNCH bit and CONFIG
* Check several times, if Sync and Config * bit both are consistently 1 then simply ignore
* both are consistently 1 then simply ignore * the IV bit and restart Autoneg
* the Invalid bit and restart Autoneg
*/ */
for (i = 0; i < AN_RETRY_COUNT; i++) { for (i = 0; i < AN_RETRY_COUNT; i++) {
usec_delay(10); usec_delay(10);
rxcw = E1000_READ_REG(hw, E1000_RXCW); rxcw = E1000_READ_REG(hw, E1000_RXCW);
if ((rxcw & E1000_RXCW_IV) && if ((rxcw & E1000_RXCW_SYNCH) &&
!((rxcw & E1000_RXCW_SYNCH) && (rxcw & E1000_RXCW_C))
(rxcw & E1000_RXCW_C))) { continue;
if (rxcw & E1000_RXCW_IV) {
mac->serdes_has_link = FALSE; mac->serdes_has_link = FALSE;
mac->serdes_link_state = mac->serdes_link_state =
e1000_serdes_link_down; e1000_serdes_link_down;
@ -1845,7 +1808,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
switch (hw->mac.type) { switch (hw->mac.type) {
@ -1862,8 +1825,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
break; break;
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -1900,15 +1862,14 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
/* If workaround is activated... */ /* If workaround is activated... */
if (state) if (state)
/* /* Hold a copy of the LAA in RAR[14] This is done so that
* Hold a copy of the LAA in RAR[14] This is done so that
* between the time RAR[0] gets clobbered and the time it * between the time RAR[0] gets clobbered and the time it
* gets fixed, the actual LAA is in one of the RARs and no * gets fixed, the actual LAA is in one of the RARs and no
* incoming packets directed to this port are dropped. * incoming packets directed to this port are dropped.
* Eventually the LAA will be in RAR[0] and RAR[14]. * Eventually the LAA will be in RAR[0] and RAR[14].
*/ */
hw->mac.ops.rar_set(hw, hw->mac.addr, hw->mac.ops.rar_set(hw, hw->mac.addr,
hw->mac.rar_entry_count - 1); hw->mac.rar_entry_count - 1);
return; return;
} }
@ -1925,25 +1886,23 @@ void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state)
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
{ {
struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val = E1000_SUCCESS; s32 ret_val;
u16 data; u16 data;
DEBUGFUNC("e1000_fix_nvm_checksum_82571"); DEBUGFUNC("e1000_fix_nvm_checksum_82571");
if (nvm->type != e1000_nvm_flash_hw) if (nvm->type != e1000_nvm_flash_hw)
goto out; return E1000_SUCCESS;
/* /* Check bit 4 of word 10h. If it is 0, firmware is done updating
* Check bit 4 of word 10h. If it is 0, firmware is done updating
* 10h-12h. Checksum may need to be fixed. * 10h-12h. Checksum may need to be fixed.
*/ */
ret_val = nvm->ops.read(hw, 0x10, 1, &data); ret_val = nvm->ops.read(hw, 0x10, 1, &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
if (!(data & 0x10)) { if (!(data & 0x10)) {
/* /* Read 0x23 and check bit 15. This bit is a 1
* Read 0x23 and check bit 15. This bit is a 1
* when the checksum has already been fixed. If * when the checksum has already been fixed. If
* the checksum is still wrong and this bit is a * the checksum is still wrong and this bit is a
* 1, we need to return bad checksum. Otherwise, * 1, we need to return bad checksum. Otherwise,
@ -1952,19 +1911,20 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
*/ */
ret_val = nvm->ops.read(hw, 0x23, 1, &data); ret_val = nvm->ops.read(hw, 0x23, 1, &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
if (!(data & 0x8000)) { if (!(data & 0x8000)) {
data |= 0x8000; data |= 0x8000;
ret_val = nvm->ops.write(hw, 0x23, 1, &data); ret_val = nvm->ops.write(hw, 0x23, 1, &data);
if (ret_val) if (ret_val)
goto out; return ret_val;
ret_val = nvm->ops.update(hw); ret_val = nvm->ops.update(hw);
if (ret_val)
return ret_val;
} }
} }
out: return E1000_SUCCESS;
return ret_val;
} }
@ -1974,25 +1934,21 @@ out:
**/ **/
static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
{ {
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_mac_addr_82571"); DEBUGFUNC("e1000_read_mac_addr_82571");
if (hw->mac.type == e1000_82571) { if (hw->mac.type == e1000_82571) {
/* s32 ret_val;
* If there's an alternate MAC address place it in RAR0
/* If there's an alternate MAC address place it in RAR0
* so that it will override the Si installed default perm * so that it will override the Si installed default perm
* address. * address.
*/ */
ret_val = e1000_check_alt_mac_addr_generic(hw); ret_val = e1000_check_alt_mac_addr_generic(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
} }
ret_val = e1000_read_mac_addr_generic(hw); return e1000_read_mac_addr_generic(hw);
out:
return ret_val;
} }
/** /**
@ -2007,7 +1963,7 @@ static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw)
struct e1000_phy_info *phy = &hw->phy; struct e1000_phy_info *phy = &hw->phy;
struct e1000_mac_info *mac = &hw->mac; struct e1000_mac_info *mac = &hw->mac;
if (!(phy->ops.check_reset_block)) if (!phy->ops.check_reset_block)
return; return;
/* If the management interface is not enabled, then power down */ /* If the management interface is not enabled, then power down */

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -144,6 +144,8 @@ static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
break; break;
case e1000_82580: case e1000_82580:
case e1000_i350: case e1000_i350:
case e1000_i210:
case e1000_i211:
reg = E1000_READ_REG(hw, E1000_MDICNFG); reg = E1000_READ_REG(hw, E1000_MDICNFG);
ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
break; break;
@ -332,6 +334,7 @@ s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
} else { } else {
nvm->type = e1000_nvm_flash_hw; nvm->type = e1000_nvm_flash_hw;
} }
/* Function Pointers */ /* Function Pointers */
nvm->ops.acquire = e1000_acquire_nvm_82575; nvm->ops.acquire = e1000_acquire_nvm_82575;
nvm->ops.release = e1000_release_nvm_82575; nvm->ops.release = e1000_release_nvm_82575;
@ -385,11 +388,16 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->rar_entry_count = E1000_RAR_ENTRIES_82576; mac->rar_entry_count = E1000_RAR_ENTRIES_82576;
if (mac->type == e1000_82580) if (mac->type == e1000_82580)
mac->rar_entry_count = E1000_RAR_ENTRIES_82580; mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
if (mac->type == e1000_i350) { if (mac->type == e1000_i350)
mac->rar_entry_count = E1000_RAR_ENTRIES_I350; mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
/* Enable EEE default settings for i350 */
/* Enable EEE default settings for EEE supported devices */
if (mac->type >= e1000_i350)
dev_spec->eee_disable = FALSE; dev_spec->eee_disable = FALSE;
}
/* Allow a single clear of the SW semaphore on I210 and newer */
if (mac->type >= e1000_i210)
dev_spec->clear_semaphore_once = TRUE;
/* Set if part includes ASF firmware */ /* Set if part includes ASF firmware */
mac->asf_firmware_present = TRUE; mac->asf_firmware_present = TRUE;
@ -428,7 +436,7 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
mac->ops.config_collision_dist = e1000_config_collision_dist_82575; mac->ops.config_collision_dist = e1000_config_collision_dist_82575;
/* multicast address update */ /* multicast address update */
mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
if (hw->mac.type == e1000_i350) { if (mac->type == e1000_i350) {
/* writing VFTA */ /* writing VFTA */
mac->ops.write_vfta = e1000_write_vfta_i350; mac->ops.write_vfta = e1000_write_vfta_i350;
/* clearing VFTA */ /* clearing VFTA */
@ -439,6 +447,9 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
/* clearing VFTA */ /* clearing VFTA */
mac->ops.clear_vfta = e1000_clear_vfta_generic; mac->ops.clear_vfta = e1000_clear_vfta_generic;
} }
if (hw->mac.type >= e1000_82580)
mac->ops.validate_mdi_setting =
e1000_validate_mdi_setting_crossover_generic;
/* ID LED init */ /* ID LED init */
mac->ops.id_led_init = e1000_id_led_init_generic; mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */ /* blink LED */
@ -634,6 +645,8 @@ static s32 e1000_get_phy_id_82575(struct e1000_hw *hw)
break; break;
case e1000_82580: case e1000_82580:
case e1000_i350: case e1000_i350:
case e1000_i210:
case e1000_i211:
mdic = E1000_READ_REG(hw, E1000_MDICNFG); mdic = E1000_READ_REG(hw, E1000_MDICNFG);
mdic &= E1000_MDICNFG_PHY_MASK; mdic &= E1000_MDICNFG_PHY_MASK;
phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
@ -1143,6 +1156,15 @@ static s32 e1000_check_for_link_82575(struct e1000_hw *hw)
*/ */
hw->mac.get_link_status = !hw->mac.serdes_has_link; hw->mac.get_link_status = !hw->mac.serdes_has_link;
/*
* Configure Flow Control now that Auto-Neg has completed.
* First, we need to restore the desired flow control
* settings because we may have had to re-autoneg with a
* different link partner.
*/
ret_val = e1000_config_fc_after_link_up_generic(hw);
if (ret_val)
DEBUGOUT("Error configuring flow control\n");
} else { } else {
ret_val = e1000_check_for_copper_link_generic(hw); ret_val = e1000_check_for_copper_link_generic(hw);
} }
@ -1222,6 +1244,7 @@ static s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
*duplex = FULL_DUPLEX; *duplex = FULL_DUPLEX;
else else
*duplex = HALF_DUPLEX; *duplex = HALF_DUPLEX;
} else { } else {
mac->serdes_has_link = FALSE; mac->serdes_has_link = FALSE;
*speed = 0; *speed = 0;
@ -1397,7 +1420,8 @@ static s32 e1000_init_hw_82575(struct e1000_hw *hw)
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw) static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
{ {
u32 ctrl; u32 ctrl;
s32 ret_val; s32 ret_val;
u32 phpm_reg;
DEBUGFUNC("e1000_setup_copper_link_82575"); DEBUGFUNC("e1000_setup_copper_link_82575");
@ -1406,6 +1430,13 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
E1000_WRITE_REG(hw, E1000_CTRL, ctrl); E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
/* Clear Go Link Disconnect bit */
if (hw->mac.type >= e1000_82580) {
phpm_reg = E1000_READ_REG(hw, E1000_82580_PHY_POWER_MGMT);
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
E1000_WRITE_REG(hw, E1000_82580_PHY_POWER_MGMT, phpm_reg);
}
ret_val = e1000_setup_serdes_link_82575(hw); ret_val = e1000_setup_serdes_link_82575(hw);
if (ret_val) if (ret_val)
goto out; goto out;
@ -1423,12 +1454,17 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
switch (hw->phy.type) { switch (hw->phy.type) {
case e1000_phy_i210: case e1000_phy_i210:
case e1000_phy_m88: case e1000_phy_m88:
if (hw->phy.id == I347AT4_E_PHY_ID || switch (hw->phy.id) {
hw->phy.id == M88E1112_E_PHY_ID || case I347AT4_E_PHY_ID:
hw->phy.id == M88E1340M_E_PHY_ID) case M88E1112_E_PHY_ID:
case M88E1340M_E_PHY_ID:
case I210_I_PHY_ID:
ret_val = e1000_copper_link_setup_m88_gen2(hw); ret_val = e1000_copper_link_setup_m88_gen2(hw);
else break;
default:
ret_val = e1000_copper_link_setup_m88(hw); ret_val = e1000_copper_link_setup_m88(hw);
break;
}
break; break;
case e1000_phy_igp_3: case e1000_phy_igp_3:
ret_val = e1000_copper_link_setup_igp(hw); ret_val = e1000_copper_link_setup_igp(hw);
@ -1460,7 +1496,7 @@ out:
**/ **/
static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw) static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
{ {
u32 ctrl_ext, ctrl_reg, reg; u32 ctrl_ext, ctrl_reg, reg, anadv_reg;
bool pcs_autoneg; bool pcs_autoneg;
s32 ret_val = E1000_SUCCESS; s32 ret_val = E1000_SUCCESS;
u16 data; u16 data;
@ -1544,26 +1580,47 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP | reg &= ~(E1000_PCS_LCTL_AN_ENABLE | E1000_PCS_LCTL_FLV_LINK_UP |
E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK); E1000_PCS_LCTL_FSD | E1000_PCS_LCTL_FORCE_LINK);
/*
* We force flow control to prevent the CTRL register values from being
* overwritten by the autonegotiated flow control values
*/
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
if (pcs_autoneg) { if (pcs_autoneg) {
/* Set PCS register for autoneg */ /* Set PCS register for autoneg */
reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */ reg |= E1000_PCS_LCTL_AN_ENABLE | /* Enable Autoneg */
E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */ E1000_PCS_LCTL_AN_RESTART; /* Restart autoneg */
/* Disable force flow control for autoneg */
reg &= ~E1000_PCS_LCTL_FORCE_FCTRL;
/* Configure flow control advertisement for autoneg */
anadv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
anadv_reg &= ~(E1000_TXCW_ASM_DIR | E1000_TXCW_PAUSE);
switch (hw->fc.requested_mode) {
case e1000_fc_full:
case e1000_fc_rx_pause:
anadv_reg |= E1000_TXCW_ASM_DIR;
anadv_reg |= E1000_TXCW_PAUSE;
break;
case e1000_fc_tx_pause:
anadv_reg |= E1000_TXCW_ASM_DIR;
break;
default:
break;
}
E1000_WRITE_REG(hw, E1000_PCS_ANADV, anadv_reg);
DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg); DEBUGOUT1("Configuring Autoneg:PCS_LCTL=0x%08X\n", reg);
} else { } else {
/* Set PCS register for forced link */ /* Set PCS register for forced link */
reg |= E1000_PCS_LCTL_FSD; /* Force Speed */ reg |= E1000_PCS_LCTL_FSD; /* Force Speed */
/* Force flow control for forced link */
reg |= E1000_PCS_LCTL_FORCE_FCTRL;
DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg); DEBUGOUT1("Configuring Forced Link:PCS_LCTL=0x%08X\n", reg);
} }
E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg); E1000_WRITE_REG(hw, E1000_PCS_LCTL, reg);
if (!e1000_sgmii_active_82575(hw)) if (!pcs_autoneg && !e1000_sgmii_active_82575(hw))
e1000_force_mac_fc_generic(hw); e1000_force_mac_fc_generic(hw);
return ret_val; return ret_val;
@ -1582,137 +1639,70 @@ static s32 e1000_setup_serdes_link_82575(struct e1000_hw *hw)
**/ **/
static s32 e1000_get_media_type_82575(struct e1000_hw *hw) static s32 e1000_get_media_type_82575(struct e1000_hw *hw)
{ {
u32 lan_id = 0;
s32 ret_val = E1000_ERR_CONFIG;
struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
s32 ret_val = E1000_SUCCESS;
u32 ctrl_ext = 0; u32 ctrl_ext = 0;
u32 current_link_mode = 0; u32 link_mode = 0;
u16 init_ctrl_wd_3 = 0;
u8 init_ctrl_wd_3_offset = 0;
u8 init_ctrl_wd_3_bit_offset = 0;
/* Set internal phy as default */ /* Set internal phy as default */
dev_spec->sgmii_active = FALSE; dev_spec->sgmii_active = FALSE;
dev_spec->module_plugged = FALSE; dev_spec->module_plugged = FALSE;
/*
* Check if NVM access method is attached already.
* If it is then Init Control Word #3 is considered
* otherwise runtime CSR register content is taken.
*/
/* Get CSR setting */ /* Get CSR setting */
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
/* Get link mode setting */ /* extract link mode setting */
if ((hw->nvm.ops.read) && (hw->nvm.ops.read != e1000_null_read_nvm)) { link_mode = ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK;
/* Take link mode from EEPROM */
/*
* Get LAN port ID to derive its
* adequate Init Control Word #3
*/
lan_id = ((E1000_READ_REG(hw, E1000_STATUS) &
E1000_STATUS_LAN_ID_MASK) >> E1000_STATUS_LAN_ID_OFFSET);
/*
* Derive Init Control Word #3 offset
* and mask to pick up link mode setting.
*/
if (hw->mac.type < e1000_82580) {
init_ctrl_wd_3_offset = lan_id ?
NVM_INIT_CONTROL3_PORT_A : NVM_INIT_CONTROL3_PORT_B;
init_ctrl_wd_3_bit_offset = NVM_WORD24_LNK_MODE_OFFSET;
} else {
init_ctrl_wd_3_offset =
NVM_82580_LAN_FUNC_OFFSET(lan_id) +
NVM_INIT_CONTROL3_PORT_A;
init_ctrl_wd_3_bit_offset =
NVM_WORD24_82580_LNK_MODE_OFFSET;
}
/* 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 (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 & E1000_CTRL_EXT_LINK_MODE_MASK;
}
switch (current_link_mode) {
switch (link_mode) {
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX: case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
hw->phy.media_type = e1000_media_type_internal_serdes; hw->phy.media_type = e1000_media_type_internal_serdes;
current_link_mode = E1000_CTRL_EXT_LINK_MODE_1000BASE_KX;
break; break;
case E1000_CTRL_EXT_LINK_MODE_GMII: case E1000_CTRL_EXT_LINK_MODE_GMII:
hw->phy.media_type = e1000_media_type_copper; hw->phy.media_type = e1000_media_type_copper;
current_link_mode = E1000_CTRL_EXT_LINK_MODE_GMII;
break; break;
case E1000_CTRL_EXT_LINK_MODE_SGMII: case E1000_CTRL_EXT_LINK_MODE_SGMII:
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
/* Get phy control interface type set (MDIO vs. I2C)*/ /* Get phy control interface type set (MDIO vs. I2C)*/
if (e1000_sgmii_uses_mdio_82575(hw)) { if (e1000_sgmii_uses_mdio_82575(hw)) {
hw->phy.media_type = e1000_media_type_copper; hw->phy.media_type = e1000_media_type_copper;
dev_spec->sgmii_active = TRUE; dev_spec->sgmii_active = TRUE;
current_link_mode = E1000_CTRL_EXT_LINK_MODE_SGMII; break;
} else {
ret_val = e1000_set_sfp_media_type_82575(hw);
if (ret_val != E1000_SUCCESS)
goto out;
if (hw->phy.media_type ==
e1000_media_type_internal_serdes) {
current_link_mode =
E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
} else if (hw->phy.media_type ==
e1000_media_type_copper) {
current_link_mode =
E1000_CTRL_EXT_LINK_MODE_SGMII;
}
} }
break; /* fall through for I2C based SGMII */
default: case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
DEBUGOUT("Link mode mask doesn't fit bit field size\n"); /* read media type from SFP EEPROM */
goto out; ret_val = e1000_set_sfp_media_type_82575(hw);
} if ((ret_val != E1000_SUCCESS) ||
/* (hw->phy.media_type == e1000_media_type_unknown)) {
* Do not change current link mode setting /*
* if media type is fibre or has not been * If media type was not identified then return media
* recognized. * type defined by the CTRL_EXT settings.
*/ */
if ((hw->phy.media_type != e1000_media_type_unknown) &&
(hw->phy.media_type != e1000_media_type_fiber)) {
/* Update link mode */
ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext |
current_link_mode);
}
ret_val = E1000_SUCCESS;
out:
/*
* If media type was not identified then return media type
* defined by the CTRL_EXT settings.
*/
if (hw->phy.media_type == e1000_media_type_unknown) {
if (current_link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII)
hw->phy.media_type = e1000_media_type_copper;
else
hw->phy.media_type = e1000_media_type_internal_serdes; hw->phy.media_type = e1000_media_type_internal_serdes;
if (link_mode == E1000_CTRL_EXT_LINK_MODE_SGMII) {
hw->phy.media_type = e1000_media_type_copper;
dev_spec->sgmii_active = TRUE;
}
break;
}
/* do not change link mode for 100BaseFX */
if (dev_spec->eth_flags.e100_base_fx)
break;
/* change current link mode setting */
ctrl_ext &= ~E1000_CTRL_EXT_LINK_MODE_MASK;
if (hw->phy.media_type == e1000_media_type_copper)
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_SGMII;
else
ctrl_ext |= E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
break;
} }
return ret_val; return ret_val;
@ -1730,40 +1720,52 @@ static s32 e1000_set_sfp_media_type_82575(struct e1000_hw *hw)
s32 ret_val = E1000_ERR_CONFIG; s32 ret_val = E1000_ERR_CONFIG;
u32 ctrl_ext = 0; u32 ctrl_ext = 0;
struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575; struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
struct sfp_e1000_flags eth_flags = {0}; struct sfp_e1000_flags *eth_flags = &dev_spec->eth_flags;
u8 tranceiver_type = 0; u8 tranceiver_type = 0;
s32 timeout = 3;
/* Turn I2C interface ON */ /* Turn I2C interface ON and power on sfp cage */
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
ctrl_ext &= ~E1000_CTRL_EXT_SDP3_DATA;
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA); E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext | E1000_CTRL_I2C_ENA);
E1000_WRITE_FLUSH(hw);
/* Read SFP module data */ /* Read SFP module data */
ret_val = e1000_read_sfp_data_byte(hw, while (timeout) {
ret_val = e1000_read_sfp_data_byte(hw,
E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET), E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_IDENTIFIER_OFFSET),
&tranceiver_type); &tranceiver_type);
if (ret_val == E1000_SUCCESS)
break;
msec_delay(100);
timeout--;
}
if (ret_val != E1000_SUCCESS) if (ret_val != E1000_SUCCESS)
goto out; goto out;
ret_val = e1000_read_sfp_data_byte(hw, ret_val = e1000_read_sfp_data_byte(hw,
E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET), E1000_I2CCMD_SFP_DATA_ADDR(E1000_SFF_ETH_FLAGS_OFFSET),
(u8 *)&eth_flags); (u8 *)eth_flags);
if (ret_val != E1000_SUCCESS) if (ret_val != E1000_SUCCESS)
goto out; goto out;
/*
* Check if there is some SFP /* Check if there is some SFP module plugged and powered */
* module plugged and powered
*/
if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) || if ((tranceiver_type == E1000_SFF_IDENTIFIER_SFP) ||
(tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) { (tranceiver_type == E1000_SFF_IDENTIFIER_SFF)) {
dev_spec->module_plugged = TRUE; dev_spec->module_plugged = TRUE;
if (eth_flags.e1000_base_lx || eth_flags.e1000_base_sx) { if (eth_flags->e1000_base_lx || eth_flags->e1000_base_sx) {
hw->phy.media_type = e1000_media_type_internal_serdes; hw->phy.media_type = e1000_media_type_internal_serdes;
} else if (eth_flags.e1000_base_t) { } else if (eth_flags->e100_base_fx) {
dev_spec->sgmii_active = TRUE;
hw->phy.media_type = e1000_media_type_internal_serdes;
} else if (eth_flags->e1000_base_t) {
dev_spec->sgmii_active = TRUE; dev_spec->sgmii_active = TRUE;
hw->phy.media_type = e1000_media_type_copper; hw->phy.media_type = e1000_media_type_copper;
} else { } else {
hw->phy.media_type = e1000_media_type_unknown; hw->phy.media_type = e1000_media_type_unknown;
DEBUGOUT("PHY module has not been recognized\n"); DEBUGOUT("PHY module has not been recognized\n");
goto out; goto out;
} }
} else { } else {
hw->phy.media_type = e1000_media_type_unknown; hw->phy.media_type = e1000_media_type_unknown;
@ -2280,7 +2282,7 @@ out:
* e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits * e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* *
* This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on * This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
* the values found in the EEPROM. This addresses an issue in which these * the values found in the EEPROM. This addresses an issue in which these
* bits are not restored from EEPROM after reset. * bits are not restored from EEPROM after reset.
**/ **/
@ -2334,6 +2336,10 @@ static s32 e1000_reset_hw_82580(struct e1000_hw *hw)
hw->dev_spec._82575.global_device_reset = FALSE; hw->dev_spec._82575.global_device_reset = FALSE;
/* 82580 does not reliably do global_device_reset due to hw errata */
if (hw->mac.type == e1000_82580)
global_device_reset = FALSE;
/* Get current control state. */ /* Get current control state. */
ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl = E1000_READ_REG(hw, E1000_CTRL);
@ -2660,10 +2666,15 @@ s32 e1000_set_eee_i350(struct e1000_hw *hw)
/* enable or disable per user setting */ /* enable or disable per user setting */
if (!(hw->dev_spec._82575.eee_disable)) { if (!(hw->dev_spec._82575.eee_disable)) {
u32 eee_su = E1000_READ_REG(hw, E1000_EEE_SU);
ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); ipcnfg |= (E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | eeer |= (E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
E1000_EEER_LPI_FC); E1000_EEER_LPI_FC);
/* This bit should not be set in normal operation. */
if (eee_su & E1000_EEE_SU_LPI_CLK_STP)
DEBUGOUT("LPI Clock Stop Bit should not be set!\n");
} else { } else {
ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN); ipcnfg &= ~(E1000_IPCNFG_EEE_1G_AN | E1000_IPCNFG_EEE_100M_AN);
eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN | eeer &= ~(E1000_EEER_TX_LPI_EN | E1000_EEER_RX_LPI_EN |
@ -3275,3 +3286,4 @@ void e1000_i2c_bus_clear(struct e1000_hw *hw)
e1000_i2c_stop(hw); e1000_i2c_stop(hw);
} }

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2011, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -360,10 +360,13 @@ struct e1000_adv_tx_context_desc {
#define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */ #define E1000_DCA_RXCTRL_DESC_DCA_EN (1 << 5) /* DCA Rx Desc enable */
#define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header ena */ #define E1000_DCA_RXCTRL_HEAD_DCA_EN (1 << 6) /* DCA Rx Desc header ena */
#define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */ #define E1000_DCA_RXCTRL_DATA_DCA_EN (1 << 7) /* DCA Rx Desc payload ena */
#define E1000_DCA_RXCTRL_DESC_RRO_EN (1 << 9) /* DCA Rx Desc Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ #define E1000_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
#define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ #define E1000_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
#define E1000_DCA_TXCTRL_DESC_RRO_EN (1 << 9) /* Tx rd Desc Relax Order */
#define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ #define E1000_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
#define E1000_DCA_TXCTRL_DATA_RRO_EN (1 << 13) /* Tx rd data Relax Order */
#define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */ #define E1000_DCA_TXCTRL_CPUID_MASK_82576 0xFF000000 /* Tx CPUID Mask */
#define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */ #define E1000_DCA_RXCTRL_CPUID_MASK_82576 0xFF000000 /* Rx CPUID Mask */

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -289,6 +289,12 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH2_LV_V: case E1000_DEV_ID_PCH2_LV_V:
mac->type = e1000_pch2lan; mac->type = e1000_pch2lan;
break; break;
case E1000_DEV_ID_PCH_LPT_I217_LM:
case E1000_DEV_ID_PCH_LPT_I217_V:
case E1000_DEV_ID_PCH_LPTLP_I218_LM:
case E1000_DEV_ID_PCH_LPTLP_I218_V:
mac->type = e1000_pch_lpt;
break;
case E1000_DEV_ID_82575EB_COPPER: case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES: case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER: case E1000_DEV_ID_82575GB_QUAD_COPPER:
@ -323,6 +329,9 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_I350_DA4: case E1000_DEV_ID_I350_DA4:
mac->type = e1000_i350; mac->type = e1000_i350;
break; break;
#if defined(QV_RELEASE) && defined(SPRINGVILLE_FLASHLESS_HW)
case E1000_DEV_ID_I210_NVMLESS:
#endif /* QV_RELEASE && SPRINGVILLE_FLASHLESS_HW */
case E1000_DEV_ID_I210_COPPER: case E1000_DEV_ID_I210_COPPER:
case E1000_DEV_ID_I210_COPPER_OEM1: case E1000_DEV_ID_I210_COPPER_OEM1:
case E1000_DEV_ID_I210_COPPER_IT: case E1000_DEV_ID_I210_COPPER_IT:
@ -332,14 +341,17 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
mac->type = e1000_i210; mac->type = e1000_i210;
break; break;
case E1000_DEV_ID_I211_COPPER: case E1000_DEV_ID_I211_COPPER:
mac->type = e1000_i211; mac->type = e1000_i211;
break; break;
case E1000_DEV_ID_82576_VF: case E1000_DEV_ID_82576_VF:
case E1000_DEV_ID_82576_VF_HV:
mac->type = e1000_vfadapt; mac->type = e1000_vfadapt;
break; break;
case E1000_DEV_ID_I350_VF: case E1000_DEV_ID_I350_VF:
case E1000_DEV_ID_I350_VF_HV:
mac->type = e1000_vfadapt_i350; mac->type = e1000_vfadapt_i350;
break; break;
default: default:
/* Should never have loaded on this device */ /* Should never have loaded on this device */
ret_val = -E1000_ERR_MAC_INIT; ret_val = -E1000_ERR_MAC_INIT;
@ -428,6 +440,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
case e1000_ich10lan: case e1000_ich10lan:
case e1000_pchlan: case e1000_pchlan:
case e1000_pch2lan: case e1000_pch2lan:
case e1000_pch_lpt:
e1000_init_function_pointers_ich8lan(hw); e1000_init_function_pointers_ich8lan(hw);
break; break;
case e1000_82575: case e1000_82575:
@ -873,11 +886,7 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length, s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
u16 offset, u8 *sum) u16 offset, u8 *sum)
{ {
if (hw->mac.ops.mng_host_if_write) return e1000_mng_host_if_write_generic(hw, buffer, length, offset, sum);
return hw->mac.ops.mng_host_if_write(hw, buffer, length,
offset, sum);
return E1000_NOT_IMPLEMENTED;
} }
/** /**
@ -890,10 +899,7 @@ s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
struct e1000_host_mng_command_header *hdr) struct e1000_host_mng_command_header *hdr)
{ {
if (hw->mac.ops.mng_write_cmd_header) return e1000_mng_write_cmd_header_generic(hw, hdr);
return hw->mac.ops.mng_write_cmd_header(hw, hdr);
return E1000_NOT_IMPLEMENTED;
} }
/** /**
@ -908,23 +914,20 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
**/ **/
s32 e1000_mng_enable_host_if(struct e1000_hw *hw) s32 e1000_mng_enable_host_if(struct e1000_hw *hw)
{ {
if (hw->mac.ops.mng_enable_host_if) return e1000_mng_enable_host_if_generic(hw);
return hw->mac.ops.mng_enable_host_if(hw);
return E1000_NOT_IMPLEMENTED;
} }
/** /**
* e1000_wait_autoneg - Waits for autonegotiation completion * e1000_set_obff_timer - Set Optimized Buffer Flush/Fill timer
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* @itr: u32 indicating itr value
* *
* Waits for autoneg to complete. Currently no func pointer exists and all * Set the OBFF timer based on the given interrupt rate.
* implementations are handled in the generic version of this function.
**/ **/
s32 e1000_wait_autoneg(struct e1000_hw *hw) s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr)
{ {
if (hw->mac.ops.wait_autoneg) if (hw->mac.ops.set_obff_timer)
return hw->mac.ops.wait_autoneg(hw); return hw->mac.ops.set_obff_timer(hw, itr);
return E1000_SUCCESS; return E1000_SUCCESS;
} }

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -51,6 +51,7 @@ 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_shutdown_fiber_serdes_link(struct e1000_hw *hw);
extern void e1000_init_function_pointers_i210(struct e1000_hw *hw); extern void e1000_init_function_pointers_i210(struct e1000_hw *hw);
s32 e1000_set_obff_timer(struct e1000_hw *hw, u32 itr);
s32 e1000_set_mac_type(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); s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device);
s32 e1000_init_mac_params(struct e1000_hw *hw); s32 e1000_init_mac_params(struct e1000_hw *hw);
@ -105,7 +106,6 @@ s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_wait_autoneg(struct e1000_hw *hw);
s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active); s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active);
s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
bool e1000_check_mng_mode(struct e1000_hw *hw); bool e1000_check_mng_mode(struct e1000_hw *hw);
@ -162,4 +162,6 @@ u32 e1000_translate_register_82542(u32 reg);
(((length) > min_frame_size) && \ (((length) > min_frame_size) && \
((length) <= (max_frame_size + VLAN_TAG_SIZE + 1))))) ((length) <= (max_frame_size + VLAN_TAG_SIZE + 1)))))
#endif #define E1000_MAX(a, b) ((a) > (b) ? (a) : (b))
#define E1000_DIVIDE_ROUND_UP(a, b) (((a) + (b) - 1) / (b)) /* ceil(a/b) */
#endif /* _E1000_API_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -123,13 +123,16 @@ struct e1000_hw;
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE #define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF #define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
#define E1000_DEV_ID_ICH10_D_BM_V 0x1525 #define E1000_DEV_ID_ICH10_D_BM_V 0x1525
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA #define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
#define E1000_DEV_ID_PCH_M_HV_LC 0x10EB #define E1000_DEV_ID_PCH_M_HV_LC 0x10EB
#define E1000_DEV_ID_PCH_D_HV_DM 0x10EF #define E1000_DEV_ID_PCH_D_HV_DM 0x10EF
#define E1000_DEV_ID_PCH_D_HV_DC 0x10F0 #define E1000_DEV_ID_PCH_D_HV_DC 0x10F0
#define E1000_DEV_ID_PCH2_LV_LM 0x1502 #define E1000_DEV_ID_PCH2_LV_LM 0x1502
#define E1000_DEV_ID_PCH2_LV_V 0x1503 #define E1000_DEV_ID_PCH2_LV_V 0x1503
#define E1000_DEV_ID_PCH_LPT_I217_LM 0x153A
#define E1000_DEV_ID_PCH_LPT_I217_V 0x153B
#define E1000_DEV_ID_PCH_LPTLP_I218_LM 0x155A
#define E1000_DEV_ID_PCH_LPTLP_I218_V 0x1559
#define E1000_DEV_ID_82576 0x10C9 #define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6 #define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7 #define E1000_DEV_ID_82576_SERDES 0x10E7
@ -139,7 +142,9 @@ struct e1000_hw;
#define E1000_DEV_ID_82576_NS_SERDES 0x1518 #define E1000_DEV_ID_82576_NS_SERDES 0x1518
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D #define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
#define E1000_DEV_ID_82576_VF 0x10CA #define E1000_DEV_ID_82576_VF 0x10CA
#define E1000_DEV_ID_82576_VF_HV 0x152D
#define E1000_DEV_ID_I350_VF 0x1520 #define E1000_DEV_ID_I350_VF 0x1520
#define E1000_DEV_ID_I350_VF_HV 0x152F
#define E1000_DEV_ID_82575EB_COPPER 0x10A7 #define E1000_DEV_ID_82575EB_COPPER 0x10A7
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 #define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6 #define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
@ -165,6 +170,7 @@ struct e1000_hw;
#define E1000_DEV_ID_DH89XXCC_SERDES 0x043A #define E1000_DEV_ID_DH89XXCC_SERDES 0x043A
#define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C #define E1000_DEV_ID_DH89XXCC_BACKPLANE 0x043C
#define E1000_DEV_ID_DH89XXCC_SFP 0x0440 #define E1000_DEV_ID_DH89XXCC_SFP 0x0440
#define E1000_REVISION_0 0 #define E1000_REVISION_0 0
#define E1000_REVISION_1 1 #define E1000_REVISION_1 1
#define E1000_REVISION_2 2 #define E1000_REVISION_2 2
@ -206,6 +212,7 @@ enum e1000_mac_type {
e1000_ich10lan, e1000_ich10lan,
e1000_pchlan, e1000_pchlan,
e1000_pch2lan, e1000_pch2lan,
e1000_pch_lpt,
e1000_82575, e1000_82575,
e1000_82576, e1000_82576,
e1000_82580, e1000_82580,
@ -255,6 +262,7 @@ enum e1000_phy_type {
e1000_phy_82578, e1000_phy_82578,
e1000_phy_82577, e1000_phy_82577,
e1000_phy_82579, e1000_phy_82579,
e1000_phy_i217,
e1000_phy_82580, e1000_phy_82580,
e1000_phy_vf, e1000_phy_vf,
e1000_phy_i210, e1000_phy_i210,
@ -651,13 +659,13 @@ struct e1000_host_mng_command_info {
#include "e1000_manage.h" #include "e1000_manage.h"
#include "e1000_mbx.h" #include "e1000_mbx.h"
/* Function pointers for the MAC. */
struct e1000_mac_operations { struct e1000_mac_operations {
/* Function pointers for the MAC. */
s32 (*init_params)(struct e1000_hw *); s32 (*init_params)(struct e1000_hw *);
s32 (*id_led_init)(struct e1000_hw *); s32 (*id_led_init)(struct e1000_hw *);
s32 (*blink_led)(struct e1000_hw *); s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *); s32 (*check_for_link)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *hw);
s32 (*cleanup_led)(struct e1000_hw *); s32 (*cleanup_led)(struct e1000_hw *);
void (*clear_hw_cntrs)(struct e1000_hw *); void (*clear_hw_cntrs)(struct e1000_hw *);
void (*clear_vfta)(struct e1000_hw *); void (*clear_vfta)(struct e1000_hw *);
@ -679,17 +687,12 @@ struct e1000_mac_operations {
void (*rar_set)(struct e1000_hw *, u8*, u32); void (*rar_set)(struct e1000_hw *, u8*, u32);
s32 (*read_mac_addr)(struct e1000_hw *); s32 (*read_mac_addr)(struct e1000_hw *);
s32 (*validate_mdi_setting)(struct e1000_hw *); s32 (*validate_mdi_setting)(struct e1000_hw *);
s32 (*mng_host_if_write)(struct e1000_hw *, u8*, u16, u16, u8*); s32 (*set_obff_timer)(struct e1000_hw *, u32);
s32 (*mng_write_cmd_header)(struct e1000_hw *hw,
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); s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16); void (*release_swfw_sync)(struct e1000_hw *, u16);
}; };
/* /* When to use various PHY register access functions:
* When to use various PHY register access functions:
* *
* Func Caller * Func Caller
* Function Does Does When to use * Function Does Does When to use
@ -731,6 +734,7 @@ struct e1000_phy_operations {
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8); s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
}; };
/* Function pointers for the NVM. */
struct e1000_nvm_operations { struct e1000_nvm_operations {
s32 (*init_params)(struct e1000_hw *); s32 (*init_params)(struct e1000_hw *);
s32 (*acquire)(struct e1000_hw *); s32 (*acquire)(struct e1000_hw *);
@ -785,6 +789,7 @@ struct e1000_mac_info {
enum e1000_serdes_link_state serdes_link_state; enum e1000_serdes_link_state serdes_link_state;
bool serdes_has_link; bool serdes_has_link;
bool tx_pkt_filtering; bool tx_pkt_filtering;
u32 max_frame_size;
}; };
struct e1000_phy_info { struct e1000_phy_info {
@ -915,7 +920,7 @@ struct e1000_shadow_ram {
bool modified; bool modified;
}; };
#define E1000_SHADOW_RAM_WORDS 2048 #define E1000_SHADOW_RAM_WORDS 2048
struct e1000_dev_spec_ich8lan { struct e1000_dev_spec_ich8lan {
bool kmrn_lock_loss_workaround_enabled; bool kmrn_lock_loss_workaround_enabled;
@ -924,6 +929,7 @@ struct e1000_dev_spec_ich8lan {
E1000_MUTEX swflag_mutex; E1000_MUTEX swflag_mutex;
bool nvm_k1_enabled; bool nvm_k1_enabled;
bool eee_disable; bool eee_disable;
u16 eee_lp_ability;
}; };
struct e1000_dev_spec_82575 { struct e1000_dev_spec_82575 {
@ -931,7 +937,9 @@ struct e1000_dev_spec_82575 {
bool global_device_reset; bool global_device_reset;
bool eee_disable; bool eee_disable;
bool module_plugged; bool module_plugged;
bool clear_semaphore_once;
u32 mtu; u32 mtu;
struct sfp_e1000_flags eth_flags;
}; };
struct e1000_dev_spec_vf { struct e1000_dev_spec_vf {

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -38,7 +38,6 @@
static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw); static s32 e1000_acquire_nvm_i210(struct e1000_hw *hw);
static void e1000_release_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 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, static s32 e1000_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
u16 *data); u16 *data);
static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw); static s32 e1000_pool_flash_update_done_i210(struct e1000_hw *hw);
@ -105,13 +104,14 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
} }
swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
if (!(swfw_sync & fwmask)) if (!(swfw_sync & (fwmask | swmask)))
break; break;
/* /*
* Firmware currently using resource (fwmask) * Firmware currently using resource (fwmask)
* or other software thread using resource (swmask)
*/ */
e1000_put_hw_semaphore_i210(hw); e1000_put_hw_semaphore_generic(hw);
msec_delay_irq(5); msec_delay_irq(5);
i++; i++;
} }
@ -125,7 +125,7 @@ s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
swfw_sync |= swmask; swfw_sync |= swmask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_i210(hw); e1000_put_hw_semaphore_generic(hw);
out: out:
return ret_val; return ret_val;
@ -152,7 +152,7 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
swfw_sync &= ~mask; swfw_sync &= ~mask;
E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync);
e1000_put_hw_semaphore_i210(hw); e1000_put_hw_semaphore_generic(hw);
} }
/** /**
@ -164,12 +164,45 @@ void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw) static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
{ {
u32 swsm; u32 swsm;
s32 ret_val = E1000_SUCCESS;
s32 timeout = hw->nvm.word_size + 1; s32 timeout = hw->nvm.word_size + 1;
s32 i = 0; s32 i = 0;
DEBUGFUNC("e1000_get_hw_semaphore_i210"); DEBUGFUNC("e1000_get_hw_semaphore_i210");
/* Get the SW semaphore */
while (i < timeout) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
usec_delay(50);
i++;
}
if (i == timeout) {
/*
* In rare circumstances, the driver may not have released the
* SW semaphore. Clear the semaphore once before giving up.
*/
if (hw->dev_spec._82575.clear_semaphore_once) {
hw->dev_spec._82575.clear_semaphore_once = FALSE;
e1000_put_hw_semaphore_generic(hw);
for (i = 0; i < timeout; i++) {
swsm = E1000_READ_REG(hw, E1000_SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;
usec_delay(50);
}
}
/* If we do not have the semaphore here, we have to give up. */
if (i == timeout) {
DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
return -E1000_ERR_NVM;
}
}
/* Get the FW semaphore. */ /* Get the FW semaphore. */
for (i = 0; i < timeout; i++) { for (i = 0; i < timeout; i++) {
swsm = E1000_READ_REG(hw, E1000_SWSM); swsm = E1000_READ_REG(hw, E1000_SWSM);
@ -186,31 +219,10 @@ static s32 e1000_get_hw_semaphore_i210(struct e1000_hw *hw)
/* Release semaphores */ /* Release semaphores */
e1000_put_hw_semaphore_generic(hw); e1000_put_hw_semaphore_generic(hw);
DEBUGOUT("Driver can't access the NVM\n"); DEBUGOUT("Driver can't access the NVM\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
out: return E1000_SUCCESS;
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);
} }
/** /**
@ -364,8 +376,8 @@ out:
* *
* Wrapper function to return data formerly found in the NVM. * Wrapper function to return data formerly found in the NVM.
**/ **/
static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words, static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset,
u16 *data) u16 words, u16 *data)
{ {
s32 ret_val = E1000_SUCCESS; s32 ret_val = E1000_SUCCESS;
@ -380,15 +392,40 @@ static s32 e1000_read_nvm_i211(struct e1000_hw *hw, u16 offset, u16 words,
if (ret_val != E1000_SUCCESS) if (ret_val != E1000_SUCCESS)
DEBUGOUT("MAC Addr not found in iNVM\n"); DEBUGOUT("MAC Addr not found in iNVM\n");
break; break;
case NVM_ID_LED_SETTINGS:
case NVM_INIT_CTRL_2: case NVM_INIT_CTRL_2:
case NVM_INIT_CTRL_4: ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
case NVM_LED_1_CFG: if (ret_val != E1000_SUCCESS) {
case NVM_LED_0_2_CFG: *data = NVM_INIT_CTRL_2_DEFAULT_I211;
e1000_read_invm_i211(hw, (u8)offset, data); ret_val = E1000_SUCCESS;
}
break; break;
case NVM_COMPAT: case NVM_INIT_CTRL_4:
*data = ID_LED_DEFAULT_I210; ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_INIT_CTRL_4_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_LED_1_CFG:
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_LED_1_CFG_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_LED_0_2_CFG:
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = NVM_LED_0_2_CFG_DEFAULT_I211;
ret_val = E1000_SUCCESS;
}
break;
case NVM_ID_LED_SETTINGS:
ret_val = e1000_read_invm_i211(hw, (u8)offset, data);
if (ret_val != E1000_SUCCESS) {
*data = ID_LED_RESERVED_FFFF;
ret_val = E1000_SUCCESS;
}
break; break;
case NVM_SUB_DEV_ID: case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id; *data = hw->subsystem_device_id;
@ -554,26 +591,6 @@ out:
return ret_val; 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 * e1000_update_flash_i210 - Commit EEPROM to the flash
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
@ -690,10 +707,7 @@ void e1000_init_function_pointers_i210(struct e1000_hw *hw)
switch (hw->mac.type) { switch (hw->mac.type) {
case e1000_i210: case e1000_i210:
if (e1000_get_flash_presence_i210(hw)) hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
hw->nvm.ops.init_params = e1000_init_nvm_params_i210;
else
hw->nvm.ops.init_params = e1000_init_nvm_params_i211;
break; break;
case e1000_i211: case e1000_i211:
hw->nvm.ops.init_params = e1000_init_nvm_params_i211; hw->nvm.ops.init_params = e1000_init_nvm_params_i211;

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -43,8 +43,6 @@ s32 e1000_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset,
s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, s32 e1000_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data); u16 words, u16 *data);
s32 e1000_read_invm_i211(struct e1000_hw *hw, u8 address, 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); s32 e1000_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask); void e1000_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask);
@ -69,6 +67,15 @@ enum E1000_INVM_STRUCTURE_TYPE {
#define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8 #define E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS 8
#define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1 #define E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS 1
#define E1000_INVM_ULT_BYTES_SIZE 8
#define E1000_INVM_RECORD_SIZE_IN_BYTES 4
#define E1000_INVM_VER_FIELD_ONE 0x1FF8
#define E1000_INVM_VER_FIELD_TWO 0x7FE000
#define E1000_INVM_IMGTYPE_FIELD 0x1F800000
#define E1000_INVM_MAJOR_MASK 0x3F0
#define E1000_INVM_MINOR_MASK 0xF
#define E1000_INVM_MAJOR_SHIFT 4
#define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \ #define ID_LED_DEFAULT_I210 ((ID_LED_OFF1_ON2 << 8) | \
(ID_LED_DEF1_DEF2 << 4) | \ (ID_LED_DEF1_DEF2 << 4) | \
@ -77,4 +84,9 @@ enum E1000_INVM_STRUCTURE_TYPE {
(ID_LED_DEF1_DEF2 << 4) | \ (ID_LED_DEF1_DEF2 << 4) | \
(ID_LED_DEF1_DEF2)) (ID_LED_DEF1_DEF2))
/* NVM offset defaults for I211 devices */
#define NVM_INIT_CTRL_2_DEFAULT_I211 0X7243
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
#endif #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-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -59,12 +59,8 @@
#define ICH_FLASH_SEG_SIZE_4K 4096 #define ICH_FLASH_SEG_SIZE_4K 4096
#define ICH_FLASH_SEG_SIZE_8K 8192 #define ICH_FLASH_SEG_SIZE_8K 8192
#define ICH_FLASH_SEG_SIZE_64K 65536 #define ICH_FLASH_SEG_SIZE_64K 65536
#define ICH_FLASH_SECTOR_SIZE 4096
#define ICH_FLASH_REG_MAPSIZE 0x00A0
#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ #define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */
#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */
/* FW established a valid mode */ /* FW established a valid mode */
#define E1000_ICH_FWSM_FW_VALID 0x00008000 #define E1000_ICH_FWSM_FW_VALID 0x00008000
#define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */ #define E1000_ICH_FWSM_PCIM2PCI 0x01000000 /* ME PCIm-to-PCI active */
@ -72,23 +68,12 @@
#define E1000_ICH_MNG_IAMT_MODE 0x2 #define E1000_ICH_MNG_IAMT_MODE 0x2
#define E1000_FWSM_PROXY_MODE 0x00000008 /* FW is in proxy mode */ #define E1000_FWSM_WLOCK_MAC_MASK 0x0380
#define E1000_FWSM_MEMC 0x00000010 /* ME Messaging capable */ #define E1000_FWSM_WLOCK_MAC_SHIFT 7
/* Shared Receive Address Registers */ /* Shared Receive Address Registers */
#define E1000_SHRAL(_i) (0x05438 + ((_i) * 8)) #define E1000_SHRAL_PCH_LPT(_i) (0x05408 + ((_i) * 8))
#define E1000_SHRAH(_i) (0x0543C + ((_i) * 8)) #define E1000_SHRAH_PCH_LPT(_i) (0x0540C + ((_i) * 8))
#define E1000_SHRAH_AV 0x80000000 /* Addr Valid bit */
#define E1000_SHRAH_MAV 0x40000000 /* Multicast Addr Valid bit */
#define E1000_H2ME 0x05B50 /* Host to ME */
#define E1000_H2ME_LSECREQ 0x00000001 /* Linksec Request */
#define E1000_H2ME_LSECA 0x00000002 /* Linksec Active */
#define E1000_H2ME_LSECSF 0x00000004 /* Linksec Failed */
#define E1000_H2ME_LSECD 0x00000008 /* Linksec Disabled */
#define E1000_H2ME_SLCAPD 0x00000010 /* Start LCAPD */
#define E1000_H2ME_IPV4_ARP_EN 0x00000020 /* Arp Offload enable bit */
#define E1000_H2ME_IPV6_NS_EN 0x00000040 /* NS Offload enable bit */
#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ #define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
(ID_LED_OFF1_OFF2 << 8) | \ (ID_LED_OFF1_OFF2 << 8) | \
@ -105,27 +90,30 @@
#define E1000_FEXTNVM_SW_CONFIG 1 #define E1000_FEXTNVM_SW_CONFIG 1
#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */ #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_MASK 0x0C000000
#define E1000_FEXTNVM3_PHY_CFG_COUNTER_50MSEC 0x08000000
#define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7 #define E1000_FEXTNVM4_BEACON_DURATION_MASK 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 #define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7
#define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3
#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100
#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL
#define E1000_ICH_RAR_ENTRIES 7 #define E1000_ICH_RAR_ENTRIES 7
#define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */ #define E1000_PCH2_RAR_ENTRIES 5 /* RAR[0], SHRA[0-3] */
#define E1000_PCH_LPT_RAR_ENTRIES 12 /* RAR[0], SHRA[0-10] */
#define PHY_PAGE_SHIFT 5 #define PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ #define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
((reg) & MAX_PHY_REG_ADDRESS)) ((reg) & MAX_PHY_REG_ADDRESS))
#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ #define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */
#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ #define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */
#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */
#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */
#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 #define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002
#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 #define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 #define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200
#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020
/* PHY Wakeup Registers and defines */ /* PHY Wakeup Registers and defines */
#define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17) #define BM_PORT_GEN_CFG PHY_REG(BM_PORT_CTRL_PAGE, 17)
@ -138,14 +126,6 @@
#define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2))) #define BM_RAR_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2))) #define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
#define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1))) #define BM_MTA(_i) (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
#define BM_IPAV (BM_PHY_REG(BM_WUC_PAGE, 64))
#define BM_IP4AT_L(_i) (BM_PHY_REG(BM_WUC_PAGE, 82 + ((_i) * 2)))
#define BM_IP4AT_H(_i) (BM_PHY_REG(BM_WUC_PAGE, 83 + ((_i) * 2)))
#define BM_SHRAL_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 44 + ((_i) * 4)))
#define BM_SHRAL_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 45 + ((_i) * 4)))
#define BM_SHRAH_LOWER(_i) (BM_PHY_REG(BM_WUC_PAGE, 46 + ((_i) * 4)))
#define BM_SHRAH_UPPER(_i) (BM_PHY_REG(BM_WUC_PAGE, 47 + ((_i) * 4)))
#define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */ #define BM_RCTL_UPE 0x0001 /* Unicast Promiscuous Mode */
#define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */ #define BM_RCTL_MPE 0x0002 /* Multicast Promiscuous Mode */
@ -177,28 +157,28 @@
#define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */
/*
* For ICH, the name used for NVM word 17h is LED1 Config.
* For PCH, the word was re-named to OEM Config.
*/
#define E1000_NVM_LED1_CONFIG 0x17 /* NVM LED1/LPLU Config Word */
#define E1000_NVM_LED1_CONFIG_LPLU_NONDOA 0x0400 /* NVM LPLU in non-D0a Bit */
#define E1000_NVM_OEM_CONFIG E1000_NVM_LED1_CONFIG
#define E1000_NVM_OEM_CONFIG_LPLU_NONDOA E1000_NVM_LED1_CONFIG_LPLU_NONDOA
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
/* SMBus Control Phy Register */
#define CV_SMB_CTRL PHY_REG(769, 23)
#define CV_SMB_CTRL_FORCE_SMBUS 0x0001
/* SMBus Address Phy Register */ /* SMBus Address Phy Register */
#define HV_SMB_ADDR PHY_REG(768, 26) #define HV_SMB_ADDR PHY_REG(768, 26)
#define HV_SMB_ADDR_MASK 0x007F #define HV_SMB_ADDR_MASK 0x007F
#define HV_SMB_ADDR_PEC_EN 0x0200 #define HV_SMB_ADDR_PEC_EN 0x0200
#define HV_SMB_ADDR_VALID 0x0080 #define HV_SMB_ADDR_VALID 0x0080
#define HV_SMB_ADDR_FREQ_MASK 0x1100
#define HV_SMB_ADDR_FREQ_LOW_SHIFT 8
#define HV_SMB_ADDR_FREQ_HIGH_SHIFT 12
/* Strapping Option Register - RO */ /* Strapping Option Register - RO */
#define E1000_STRAP 0x0000C #define E1000_STRAP 0x0000C
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000 #define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17 #define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
#define E1000_STRAP_SMT_FREQ_MASK 0x00003000
#define E1000_STRAP_SMT_FREQ_SHIFT 12
/* OEM Bits Phy Register */ /* OEM Bits Phy Register */
#define HV_OEM_BITS PHY_REG(768, 25) #define HV_OEM_BITS PHY_REG(768, 25)
@ -206,8 +186,6 @@
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */ #define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */ #define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
#define LCD_CFG_PHY_ADDR_BIT 0x0020 /* Phy addr bit from LCD Config word */
/* KMRN Mode Control */ /* KMRN Mode Control */
#define HV_KMRN_MODE_CTRL PHY_REG(769, 16) #define HV_KMRN_MODE_CTRL PHY_REG(769, 16)
#define HV_KMRN_MDIO_SLOW 0x0400 #define HV_KMRN_MDIO_SLOW 0x0400
@ -219,47 +197,73 @@
/* PHY Power Management Control */ /* PHY Power Management Control */
#define HV_PM_CTRL PHY_REG(770, 17) #define HV_PM_CTRL PHY_REG(770, 17)
#define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */ #define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in ms */
/* PHY Low Power Idle Control */ /* PHY Low Power Idle Control */
#define I82579_LPI_CTRL PHY_REG(772, 20) #define I82579_LPI_CTRL PHY_REG(772, 20)
#define I82579_LPI_CTRL_100_ENABLE 0x2000
#define I82579_LPI_CTRL_1000_ENABLE 0x4000
#define I82579_LPI_CTRL_ENABLE_MASK 0x6000 #define I82579_LPI_CTRL_ENABLE_MASK 0x6000
#define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80 #define I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT 0x80
/* EMI Registers */ /* Extended Management Interface (EMI) Registers */
#define I82579_EMI_ADDR 0x10 #define I82579_EMI_ADDR 0x10
#define I82579_EMI_DATA 0x11 #define I82579_EMI_DATA 0x11
#define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */ #define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */
#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */ #define I82579_MSE_THRESHOLD 0x084F /* 82579 Mean Square Error Threshold */
#define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */
#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ #define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */
#define I82579_RX_CONFIG 0x3412 /* Receive configuration */
#define I82579_EEE_PCS_STATUS 0x182D /* IEEE MMD Register 3.1 >> 8 */
#define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */
#define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */
#define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */
#define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE supported */
#define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE supported */
#define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */
#define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */
#define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */
#define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */
/* #define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */
* Additional interrupts need to be handled for ICH family: #define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */
* DSW = The FW changed the status of the DISSW bit in FWSM
* PHYINT = The LAN connected device generates an interrupt
* EPRST = Manageability reset event
*/
#define IMS_ICH_ENABLE_MASK (\
E1000_IMS_DSW | \
E1000_IMS_PHYINT | \
E1000_IMS_EPRST)
/* Additional interrupt register bit definitions */ /* Intel Rapid Start Technology Support */
#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */ #define I217_PROXY_CTRL BM_PHY_REG(BM_WUC_PAGE, 70)
#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ #define I217_PROXY_CTRL_AUTO_DISABLE 0x0080
#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ #define I217_SxCTRL PHY_REG(BM_PORT_CTRL_PAGE, 28)
#define I217_SxCTRL_ENABLE_LPI_RESET 0x1000
/* Security Processing bit Indication */ #define I217_CGFREG PHY_REG(772, 29)
#define E1000_RXDEXT_LINKSEC_STATUS_LSECH 0x01000000 #define I217_CGFREG_ENABLE_MTA_RESET 0x0002
#define E1000_RXDEXT_LINKSEC_ERROR_BIT_MASK 0x60000000 #define I217_MEMPWR PHY_REG(772, 26)
#define E1000_RXDEXT_LINKSEC_ERROR_NO_SA_MATCH 0x20000000 #define I217_MEMPWR_DISABLE_SMB_RELEASE 0x0010
#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000
#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000
/* Receive Address Initial CRC Calculation */ /* Receive Address Initial CRC Calculation */
#define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4)) #define E1000_PCH_RAICC(_n) (0x05F50 + ((_n) * 4))
/* Latency Tolerance Reporting */
#define E1000_LTRV 0x000F8
#define E1000_LTRV_VALUE_MASK 0x000003FF
#define E1000_LTRV_SCALE_MAX 5
#define E1000_LTRV_SCALE_FACTOR 5
#define E1000_LTRV_SCALE_SHIFT 10
#define E1000_LTRV_SCALE_MASK 0x00001C00
#define E1000_LTRV_REQ_SHIFT 15
#define E1000_LTRV_NOSNOOP_SHIFT 16
#define E1000_LTRV_SEND (1 << 30)
/* Proprietary Latency Tolerance Reporting PCI Capability */
#define E1000_PCI_LTR_CAP_LPT 0xA8
/* OBFF Control & Threshold Defines */
#define E1000_SVCR_OFF_EN 0x00000001
#define E1000_SVCR_OFF_MASKINT 0x00001000
#define E1000_SVCR_OFF_TIMER_MASK 0xFFFF0000
#define E1000_SVCR_OFF_TIMER_SHIFT 16
#define E1000_SVT_OFF_HWM_MASK 0x0000001F
void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
bool state); bool state);
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
@ -269,4 +273,5 @@ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw);
s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable); s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw); void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw);
s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable); s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable);
#endif s32 e1000_read_emi_reg_locked(struct e1000_hw *hw, u16 addr, u16 *data);
#endif /* _E1000_ICH8LAN_H_ */

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -70,12 +70,9 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw)
mac->ops.setup_link = e1000_null_ops_generic; mac->ops.setup_link = e1000_null_ops_generic;
mac->ops.get_link_up_info = e1000_null_link_info; mac->ops.get_link_up_info = e1000_null_link_info;
mac->ops.check_for_link = e1000_null_ops_generic; mac->ops.check_for_link = e1000_null_ops_generic;
mac->ops.wait_autoneg = e1000_wait_autoneg_generic; mac->ops.set_obff_timer = e1000_null_set_obff_timer;
/* Management */ /* Management */
mac->ops.check_mng_mode = e1000_null_mng_mode; mac->ops.check_mng_mode = e1000_null_mng_mode;
mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic;
mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;
mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic;
/* VLAN, MC, etc. */ /* VLAN, MC, etc. */
mac->ops.update_mc_addr_list = e1000_null_update_mc; mac->ops.update_mc_addr_list = e1000_null_update_mc;
mac->ops.clear_vfta = e1000_null_mac_generic; mac->ops.clear_vfta = e1000_null_mac_generic;
@ -118,8 +115,7 @@ s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d)
* e1000_null_mng_mode - No-op function, return FALSE * e1000_null_mng_mode - No-op function, return FALSE
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
**/ **/
bool e1000_null_mng_mode(struct e1000_hw *hw) bool e1000_null_mng_mode(struct e1000_hw *hw) {
{
DEBUGFUNC("e1000_null_mng_mode"); DEBUGFUNC("e1000_null_mng_mode");
return FALSE; return FALSE;
} }
@ -154,6 +150,16 @@ void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a)
return; return;
} }
/**
* e1000_null_set_obff_timer - No-op function, return 0
* @hw: pointer to the HW structure
**/
s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a)
{
DEBUGFUNC("e1000_null_set_obff_timer");
return E1000_SUCCESS;
}
/** /**
* e1000_get_bus_info_pci_generic - Get PCI(x) bus information * e1000_get_bus_info_pci_generic - Get PCI(x) bus information
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
@ -268,8 +274,7 @@ static void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw)
struct e1000_bus_info *bus = &hw->bus; struct e1000_bus_info *bus = &hw->bus;
u32 reg; u32 reg;
/* /* The status register reports the correct function number
* The status register reports the correct function number
* for the device regardless of function swap state. * for the device regardless of function swap state.
*/ */
reg = E1000_READ_REG(hw, E1000_STATUS); reg = E1000_READ_REG(hw, E1000_STATUS);
@ -389,7 +394,7 @@ void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count)
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
{ {
u32 i; u32 i;
s32 ret_val = E1000_SUCCESS; s32 ret_val;
u16 offset, nvm_alt_mac_addr_offset, nvm_data; u16 offset, nvm_alt_mac_addr_offset, nvm_data;
u8 alt_mac_addr[ETH_ADDR_LEN]; u8 alt_mac_addr[ETH_ADDR_LEN];
@ -403,8 +408,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573))
return E1000_SUCCESS; return E1000_SUCCESS;
/* /* Alternate MAC address is handled by the option ROM for 82580
* Alternate MAC address is handled by the option ROM for 82580
* and newer. SW support not required. * and newer. SW support not required.
*/ */
if (hw->mac.type >= e1000_82580) if (hw->mac.type >= e1000_82580)
@ -447,8 +451,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/* /* We have a valid alternate MAC address, and we want to treat it the
* We have a valid alternate MAC address, and we want to treat it the
* same as the normal permanent MAC address stored by the HW into the * same as the normal permanent MAC address stored by the HW into the
* RAR. Do this by mapping this address into RAR0. * RAR. Do this by mapping this address into RAR0.
*/ */
@ -472,8 +475,7 @@ static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
DEBUGFUNC("e1000_rar_set_generic"); DEBUGFUNC("e1000_rar_set_generic");
/* /* HW expects these in little endian so we reverse the byte order
* HW expects these in little endian so we reverse the byte order
* from network order (big endian) to little endian * from network order (big endian) to little endian
*/ */
rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) | rar_low = ((u32) addr[0] | ((u32) addr[1] << 8) |
@ -485,8 +487,7 @@ static void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
if (rar_low || rar_high) if (rar_low || rar_high)
rar_high |= E1000_RAH_AV; rar_high |= E1000_RAH_AV;
/* /* Some bridges will combine consecutive 32-bit writes into
* Some bridges will combine consecutive 32-bit writes into
* a single burst write, which will malfunction on some parts. * a single burst write, which will malfunction on some parts.
* The flushes avoid this. * The flushes avoid this.
*/ */
@ -514,15 +515,13 @@ u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr)
/* Register count multiplied by bits per register */ /* Register count multiplied by bits per register */
hash_mask = (hw->mac.mta_reg_count * 32) - 1; hash_mask = (hw->mac.mta_reg_count * 32) - 1;
/* /* For a mc_filter_type of 0, bit_shift is the number of left-shifts
* For a mc_filter_type of 0, bit_shift is the number of left-shifts
* where 0xFF would still fall within the hash mask. * where 0xFF would still fall within the hash mask.
*/ */
while (hash_mask >> bit_shift != 0xFF) while (hash_mask >> bit_shift != 0xFF)
bit_shift++; bit_shift++;
/* /* The portion of the address that is used for the hash table
* The portion of the address that is used for the hash table
* is determined by the mc_filter_type setting. * is determined by the mc_filter_type setting.
* The algorithm is such that there is a total of 8 bits of shifting. * The algorithm is such that there is a total of 8 bits of shifting.
* The bit_shift for a mc_filter_type of 0 represents the number of * The bit_shift for a mc_filter_type of 0 represents the number of
@ -707,8 +706,7 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_for_copper_link"); DEBUGFUNC("e1000_check_for_copper_link");
/* /* We only want to go out to the PHY registers to see if Auto-Neg
* We only want to go out to the PHY registers to see if Auto-Neg
* has completed and/or if our link status has changed. The * has completed and/or if our link status has changed. The
* get_link_status flag is set upon receiving a Link Status * get_link_status flag is set upon receiving a Link Status
* Change or Rx Sequence Error interrupt. * Change or Rx Sequence Error interrupt.
@ -716,8 +714,7 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
if (!mac->get_link_status) if (!mac->get_link_status)
return E1000_SUCCESS; return E1000_SUCCESS;
/* /* First we want to see if the MII Status Register reports
* First we want to see if the MII Status Register reports
* link. If so, then we want to get the current speed/duplex * link. If so, then we want to get the current speed/duplex
* of the PHY. * of the PHY.
*/ */
@ -730,28 +727,24 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
mac->get_link_status = FALSE; mac->get_link_status = FALSE;
/* /* Check if there was DownShift, must be checked
* Check if there was DownShift, must be checked
* immediately after link-up * immediately after link-up
*/ */
e1000_check_downshift_generic(hw); e1000_check_downshift_generic(hw);
/* /* If we are forcing speed/duplex, then we simply return since
* If we are forcing speed/duplex, then we simply return since
* we have already determined whether we have link or not. * we have already determined whether we have link or not.
*/ */
if (!mac->autoneg) if (!mac->autoneg)
return -E1000_ERR_CONFIG; return -E1000_ERR_CONFIG;
/* /* Auto-Neg is enabled. Auto Speed Detection takes care
* Auto-Neg is enabled. Auto Speed Detection takes care
* of MAC speed/duplex configuration. So we only need to * of MAC speed/duplex configuration. So we only need to
* configure Collision Distance in the MAC. * configure Collision Distance in the MAC.
*/ */
mac->ops.config_collision_dist(hw); mac->ops.config_collision_dist(hw);
/* /* Configure Flow Control now that Auto-Neg has completed.
* Configure Flow Control now that Auto-Neg has completed.
* First, we need to restore the desired flow control * First, we need to restore the desired flow control
* settings because we may have had to re-autoneg with a * settings because we may have had to re-autoneg with a
* different link partner. * different link partner.
@ -784,8 +777,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
status = E1000_READ_REG(hw, E1000_STATUS); status = E1000_READ_REG(hw, E1000_STATUS);
rxcw = E1000_READ_REG(hw, E1000_RXCW); rxcw = E1000_READ_REG(hw, E1000_RXCW);
/* /* If we don't have link (auto-negotiation failed or link partner
* If we don't have link (auto-negotiation failed or link partner
* cannot auto-negotiate), the cable is plugged in (we have signal), * cannot auto-negotiate), the cable is plugged in (we have signal),
* and our link partner is not trying to auto-negotiate with us (we * and our link partner is not trying to auto-negotiate with us (we
* are receiving idles or data), we need to force link up. We also * are receiving idles or data), we need to force link up. We also
@ -816,8 +808,7 @@ s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
/* /* If we are forcing link and we are receiving /C/ ordered
* If we are forcing link and we are receiving /C/ ordered
* sets, re-enable auto-negotiation in the TXCW register * sets, re-enable auto-negotiation in the TXCW register
* and disable forced link in the Device Control register * and disable forced link in the Device Control register
* in an attempt to auto-negotiate with our link partner. * in an attempt to auto-negotiate with our link partner.
@ -853,8 +844,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
status = E1000_READ_REG(hw, E1000_STATUS); status = E1000_READ_REG(hw, E1000_STATUS);
rxcw = E1000_READ_REG(hw, E1000_RXCW); rxcw = E1000_READ_REG(hw, E1000_RXCW);
/* /* If we don't have link (auto-negotiation failed or link partner
* If we don't have link (auto-negotiation failed or link partner
* cannot auto-negotiate), and our link partner is not trying to * cannot auto-negotiate), and our link partner is not trying to
* auto-negotiate with us (we are receiving idles or data), * auto-negotiate with us (we are receiving idles or data),
* we need to force link up. We also need to give auto-negotiation * we need to force link up. We also need to give auto-negotiation
@ -883,8 +873,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
/* /* If we are forcing link and we are receiving /C/ ordered
* If we are forcing link and we are receiving /C/ ordered
* sets, re-enable auto-negotiation in the TXCW register * sets, re-enable auto-negotiation in the TXCW register
* and disable forced link in the Device Control register * and disable forced link in the Device Control register
* in an attempt to auto-negotiate with our link partner. * in an attempt to auto-negotiate with our link partner.
@ -895,8 +884,7 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
mac->serdes_has_link = TRUE; mac->serdes_has_link = TRUE;
} else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) { } else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) {
/* /* If we force link for non-auto-negotiation switch, check
* If we force link for non-auto-negotiation switch, check
* link status based on MAC synchronization for internal * link status based on MAC synchronization for internal
* serdes media type. * serdes media type.
*/ */
@ -955,8 +943,7 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_set_default_fc_generic"); DEBUGFUNC("e1000_set_default_fc_generic");
/* /* Read and store word 0x0F of the EEPROM. This word contains bits
* Read and store word 0x0F of the EEPROM. This word contains bits
* that determine the hardware's default PAUSE (flow control) mode, * that determine the hardware's default PAUSE (flow control) mode,
* a bit that determines whether the HW defaults to enabling or * a bit that determines whether the HW defaults to enabling or
* disabling auto-negotiation, and the direction of the * disabling auto-negotiation, and the direction of the
@ -998,15 +985,13 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_link_generic"); DEBUGFUNC("e1000_setup_link_generic");
/* /* In the case of the phy reset being blocked, we already have a link.
* In the case of the phy reset being blocked, we already have a link.
* We do not need to set it up again. * We do not need to set it up again.
*/ */
if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw)) if (hw->phy.ops.check_reset_block && hw->phy.ops.check_reset_block(hw))
return E1000_SUCCESS; return E1000_SUCCESS;
/* /* If requested flow control is set to default, set flow control
* If requested flow control is set to default, set flow control
* based on the EEPROM flow control settings. * based on the EEPROM flow control settings.
*/ */
if (hw->fc.requested_mode == e1000_fc_default) { if (hw->fc.requested_mode == e1000_fc_default) {
@ -1015,8 +1000,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* /* Save off the requested flow control mode for use later. Depending
* Save off the requested flow control mode for use later. Depending
* on the link partner's capabilities, we may or may not use this mode. * on the link partner's capabilities, we may or may not use this mode.
*/ */
hw->fc.current_mode = hw->fc.requested_mode; hw->fc.current_mode = hw->fc.requested_mode;
@ -1029,8 +1013,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Initialize the flow control address, type, and PAUSE timer
* Initialize the flow control address, type, and PAUSE timer
* registers to their default values. This is done even if flow * registers to their default values. This is done even if flow
* control is disabled, because it does not hurt anything to * control is disabled, because it does not hurt anything to
* initialize these registers. * initialize these registers.
@ -1059,8 +1042,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_commit_fc_settings_generic"); DEBUGFUNC("e1000_commit_fc_settings_generic");
/* /* Check for a software override of the flow control settings, and
* Check for a software override of the flow control settings, and
* setup the device accordingly. If auto-negotiation is enabled, then * setup the device accordingly. If auto-negotiation is enabled, then
* software will have to set the "PAUSE" bits to the correct value in * software will have to set the "PAUSE" bits to the correct value in
* the Transmit Config Word Register (TXCW) and re-start auto- * the Transmit Config Word Register (TXCW) and re-start auto-
@ -1082,8 +1064,7 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
break; break;
case e1000_fc_rx_pause: case e1000_fc_rx_pause:
/* /* Rx Flow control is enabled and Tx Flow control is disabled
* Rx Flow control is enabled and Tx Flow control is disabled
* by a software over-ride. Since there really isn't a way to * by a software over-ride. Since there really isn't a way to
* advertise that we are capable of Rx Pause ONLY, we will * advertise that we are capable of Rx Pause ONLY, we will
* advertise that we support both symmetric and asymmetric Rx * advertise that we support both symmetric and asymmetric Rx
@ -1093,15 +1074,13 @@ s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
break; break;
case e1000_fc_tx_pause: case e1000_fc_tx_pause:
/* /* Tx Flow control is enabled, and Rx Flow control is disabled,
* Tx Flow control is enabled, and Rx Flow control is disabled,
* by a software over-ride. * by a software over-ride.
*/ */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
break; break;
case e1000_fc_full: case e1000_fc_full:
/* /* Flow control (both Rx and Tx) is enabled by a software
* Flow control (both Rx and Tx) is enabled by a software
* over-ride. * over-ride.
*/ */
txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
@ -1133,8 +1112,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); DEBUGFUNC("e1000_poll_fiber_serdes_link_generic");
/* /* If we have a signal (the cable is plugged in, or assumed TRUE for
* If we have a signal (the cable is plugged in, or assumed TRUE for
* serdes media) then poll for a "Link-Up" indication in the Device * serdes media) then poll for a "Link-Up" indication in the Device
* Status Register. Time-out if a link isn't seen in 500 milliseconds * Status Register. Time-out if a link isn't seen in 500 milliseconds
* seconds (Auto-negotiation should complete in less than 500 * seconds (Auto-negotiation should complete in less than 500
@ -1149,8 +1127,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
if (i == FIBER_LINK_UP_LIMIT) { if (i == FIBER_LINK_UP_LIMIT) {
DEBUGOUT("Never got a valid link from auto-neg!!!\n"); DEBUGOUT("Never got a valid link from auto-neg!!!\n");
mac->autoneg_failed = TRUE; mac->autoneg_failed = TRUE;
/* /* AutoNeg failed to achieve a link, so we'll call
* AutoNeg failed to achieve a link, so we'll call
* mac->check_for_link. This routine will force the * mac->check_for_link. This routine will force the
* link up if we detect a signal. This will allow us to * link up if we detect a signal. This will allow us to
* communicate with non-autonegotiating link partners. * communicate with non-autonegotiating link partners.
@ -1194,8 +1171,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Since auto-negotiation is enabled, take the link out of reset (the
* Since auto-negotiation is enabled, take the link out of reset (the
* link will be in reset, because we previously reset the chip). This * link will be in reset, because we previously reset the chip). This
* will restart auto-negotiation. If auto-negotiation is successful * will restart auto-negotiation. If auto-negotiation is successful
* then the link-up status bit will be set and the flow control enable * then the link-up status bit will be set and the flow control enable
@ -1207,8 +1183,7 @@ s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
msec_delay(1); msec_delay(1);
/* /* For these adapters, the SW definable pin 1 is set when the optics
* For these adapters, the SW definable pin 1 is set when the optics
* detect a signal. If we have a signal, then poll for a "Link-Up" * detect a signal. If we have a signal, then poll for a "Link-Up"
* indication. * indication.
*/ */
@ -1258,16 +1233,14 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_set_fc_watermarks_generic"); DEBUGFUNC("e1000_set_fc_watermarks_generic");
/* /* Set the flow control receive threshold registers. Normally,
* Set the flow control receive threshold registers. Normally,
* these registers will be set to a default threshold that may be * these registers will be set to a default threshold that may be
* adjusted later by the driver's runtime code. However, if the * adjusted later by the driver's runtime code. However, if the
* ability to transmit pause frames is not enabled, then these * ability to transmit pause frames is not enabled, then these
* registers will be set to 0. * registers will be set to 0.
*/ */
if (hw->fc.current_mode & e1000_fc_tx_pause) { if (hw->fc.current_mode & e1000_fc_tx_pause) {
/* /* We need to set up the Receive Threshold high and low water
* We need to set up the Receive Threshold high and low water
* marks as well as (optionally) enabling the transmission of * marks as well as (optionally) enabling the transmission of
* XON frames. * XON frames.
*/ */
@ -1301,8 +1274,7 @@ s32 e1000_force_mac_fc_generic(struct e1000_hw *hw)
ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl = E1000_READ_REG(hw, E1000_CTRL);
/* /* Because we didn't get link via the internal auto-negotiation
* Because we didn't get link via the internal auto-negotiation
* mechanism (we either forced link or we got link via PHY * mechanism (we either forced link or we got link via PHY
* auto-neg), we have to manually enable/disable transmit an * auto-neg), we have to manually enable/disable transmit an
* receive flow control. * receive flow control.
@ -1360,13 +1332,13 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
{ {
struct e1000_mac_info *mac = &hw->mac; struct e1000_mac_info *mac = &hw->mac;
s32 ret_val = E1000_SUCCESS; s32 ret_val = E1000_SUCCESS;
u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg;
u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
u16 speed, duplex; u16 speed, duplex;
DEBUGFUNC("e1000_config_fc_after_link_up_generic"); DEBUGFUNC("e1000_config_fc_after_link_up_generic");
/* /* Check for the case where we have fiber media and auto-neg failed
* Check for the case where we have fiber media and auto-neg failed
* so we had to force link. In this case, we need to force the * so we had to force link. In this case, we need to force the
* configuration of the MAC to match the "fc" parameter. * configuration of the MAC to match the "fc" parameter.
*/ */
@ -1384,15 +1356,13 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* /* Check for the case where we have copper media and auto-neg is
* Check for the case where we have copper media and auto-neg is
* enabled. In this case, we need to check and see if Auto-Neg * enabled. In this case, we need to check and see if Auto-Neg
* has completed, and if so, how the PHY and link partner has * has completed, and if so, how the PHY and link partner has
* flow control configured. * flow control configured.
*/ */
if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
/* /* Read the MII Status Register and check to see if AutoNeg
* Read the MII Status Register and check to see if AutoNeg
* has completed. We read this twice because this reg has * has completed. We read this twice because this reg has
* some "sticky" (latched) bits. * some "sticky" (latched) bits.
*/ */
@ -1408,8 +1378,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* /* The AutoNeg process has completed, so we now need to
* The AutoNeg process has completed, so we now need to
* read both the Auto Negotiation Advertisement * read both the Auto Negotiation Advertisement
* Register (Address 4) and the Auto_Negotiation Base * Register (Address 4) and the Auto_Negotiation Base
* Page Ability Register (Address 5) to determine how * Page Ability Register (Address 5) to determine how
@ -1424,8 +1393,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Two bits in the Auto Negotiation Advertisement Register
* Two bits in the Auto Negotiation Advertisement Register
* (Address 4) and two bits in the Auto Negotiation Base * (Address 4) and two bits in the Auto Negotiation Base
* Page Ability Register (Address 5) determine flow control * Page Ability Register (Address 5) determine flow control
* for both the PHY and the link partner. The following * for both the PHY and the link partner. The following
@ -1460,8 +1428,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
*/ */
if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
/* /* Now we need to check if the user selected Rx ONLY
* Now we need to check if the user selected Rx ONLY
* of pause frames. In this case, we had to advertise * of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise Rx * FULL flow control because we could not advertise Rx
* ONLY. Hence, we must now check to see if we need to * ONLY. Hence, we must now check to see if we need to
@ -1475,8 +1442,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n"); DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
} }
} }
/* /* For receiving PAUSE frames ONLY.
* For receiving PAUSE frames ONLY.
* *
* LOCAL DEVICE | LINK PARTNER * LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
@ -1490,8 +1456,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
hw->fc.current_mode = e1000_fc_tx_pause; hw->fc.current_mode = e1000_fc_tx_pause;
DEBUGOUT("Flow Control = Tx PAUSE frames only.\n"); DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
} }
/* /* For transmitting PAUSE frames ONLY.
* For transmitting PAUSE frames ONLY.
* *
* LOCAL DEVICE | LINK PARTNER * LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
@ -1505,16 +1470,14 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
hw->fc.current_mode = e1000_fc_rx_pause; hw->fc.current_mode = e1000_fc_rx_pause;
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n"); DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
} else { } else {
/* /* Per the IEEE spec, at this point flow control
* Per the IEEE spec, at this point flow control
* should be disabled. * should be disabled.
*/ */
hw->fc.current_mode = e1000_fc_none; hw->fc.current_mode = e1000_fc_none;
DEBUGOUT("Flow Control = NONE.\n"); DEBUGOUT("Flow Control = NONE.\n");
} }
/* /* Now we need to do one last check... If we auto-
* Now we need to do one last check... If we auto-
* negotiated to HALF DUPLEX, flow control should not be * negotiated to HALF DUPLEX, flow control should not be
* enabled per IEEE 802.3 spec. * enabled per IEEE 802.3 spec.
*/ */
@ -1527,8 +1490,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
if (duplex == HALF_DUPLEX) if (duplex == HALF_DUPLEX)
hw->fc.current_mode = e1000_fc_none; hw->fc.current_mode = e1000_fc_none;
/* /* Now we call a subroutine to actually force the MAC
* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings. * controller to use the correct flow control settings.
*/ */
ret_val = e1000_force_mac_fc_generic(hw); ret_val = e1000_force_mac_fc_generic(hw);
@ -1538,6 +1500,130 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw)
} }
} }
/* Check for the case where we have SerDes media and auto-neg is
* enabled. In this case, we need to check and see if Auto-Neg
* has completed, and if so, how the PHY and link partner has
* flow control configured.
*/
if ((hw->phy.media_type == e1000_media_type_internal_serdes) &&
mac->autoneg) {
/* Read the PCS_LSTS and check to see if AutoNeg
* has completed.
*/
pcs_status_reg = E1000_READ_REG(hw, E1000_PCS_LSTAT);
if (!(pcs_status_reg & E1000_PCS_LSTS_AN_COMPLETE)) {
DEBUGOUT("PCS Auto Neg has not completed.\n");
return ret_val;
}
/* The AutoNeg process has completed, so we now need to
* read both the Auto Negotiation Advertisement
* Register (PCS_ANADV) and the Auto_Negotiation Base
* Page Ability Register (PCS_LPAB) to determine how
* flow control was negotiated.
*/
pcs_adv_reg = E1000_READ_REG(hw, E1000_PCS_ANADV);
pcs_lp_ability_reg = E1000_READ_REG(hw, E1000_PCS_LPAB);
/* Two bits in the Auto Negotiation Advertisement Register
* (PCS_ANADV) and two bits in the Auto Negotiation Base
* Page Ability Register (PCS_LPAB) determine flow control
* for both the PHY and the link partner. The following
* table, taken out of the IEEE 802.3ab/D6.0 dated March 25,
* 1999, describes these PAUSE resolution bits and how flow
* control is determined based upon these settings.
* NOTE: DC = Don't Care
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
*-------|---------|-------|---------|--------------------
* 0 | 0 | DC | DC | e1000_fc_none
* 0 | 1 | 0 | DC | e1000_fc_none
* 0 | 1 | 1 | 0 | e1000_fc_none
* 0 | 1 | 1 | 1 | e1000_fc_tx_pause
* 1 | 0 | 0 | DC | e1000_fc_none
* 1 | DC | 1 | DC | e1000_fc_full
* 1 | 1 | 0 | 0 | e1000_fc_none
* 1 | 1 | 0 | 1 | e1000_fc_rx_pause
*
* Are both PAUSE bits set to 1? If so, this implies
* Symmetric Flow Control is enabled at both ends. The
* ASM_DIR bits are irrelevant per the spec.
*
* For Symmetric Flow Control:
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | DC | 1 | DC | e1000_fc_full
*
*/
if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_PAUSE)) {
/* Now we need to check if the user selected Rx ONLY
* of pause frames. In this case, we had to advertise
* FULL flow control because we could not advertise Rx
* ONLY. Hence, we must now check to see if we need to
* turn OFF the TRANSMISSION of PAUSE frames.
*/
if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
DEBUGOUT("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
}
}
/* For receiving PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 0 | 1 | 1 | 1 | e1000_fc_tx_pause
*/
else if (!(pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_tx_pause;
DEBUGOUT("Flow Control = Tx PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
* LOCAL DEVICE | LINK PARTNER
* PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
*-------|---------|-------|---------|--------------------
* 1 | 1 | 0 | 1 | e1000_fc_rx_pause
*/
else if ((pcs_adv_reg & E1000_TXCW_PAUSE) &&
(pcs_adv_reg & E1000_TXCW_ASM_DIR) &&
!(pcs_lp_ability_reg & E1000_TXCW_PAUSE) &&
(pcs_lp_ability_reg & E1000_TXCW_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_rx_pause;
DEBUGOUT("Flow Control = Rx PAUSE frames only.\n");
} else {
/* Per the IEEE spec, at this point flow control
* should be disabled.
*/
hw->fc.current_mode = e1000_fc_none;
DEBUGOUT("Flow Control = NONE.\n");
}
/* Now we call a subroutine to actually force the MAC
* controller to use the correct flow control settings.
*/
pcs_ctrl_reg = E1000_READ_REG(hw, E1000_PCS_LCTL);
pcs_ctrl_reg |= E1000_PCS_LCTL_FORCE_FCTRL;
E1000_WRITE_REG(hw, E1000_PCS_LCTL, pcs_ctrl_reg);
ret_val = e1000_force_mac_fc_generic(hw);
if (ret_val) {
DEBUGOUT("Error forcing flow control settings\n");
return ret_val;
}
}
return E1000_SUCCESS; return E1000_SUCCESS;
} }
@ -1854,16 +1940,28 @@ s32 e1000_blink_led_generic(struct e1000_hw *hw)
ledctl_blink = E1000_LEDCTL_LED0_BLINK | ledctl_blink = E1000_LEDCTL_LED0_BLINK |
(E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
} else { } else {
/* /* Set the blink bit for each LED that's "on" (0x0E)
* set the blink bit for each LED that's "on" (0x0E) * (or "off" if inverted) in ledctl_mode2. The blink
* in ledctl_mode2 * logic in hardware only works when mode is set to "on"
* so it must be changed accordingly when the mode is
* "off" and inverted.
*/ */
ledctl_blink = hw->mac.ledctl_mode2; ledctl_blink = hw->mac.ledctl_mode2;
for (i = 0; i < 4; i++) for (i = 0; i < 32; i += 8) {
if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == u32 mode = (hw->mac.ledctl_mode2 >> i) &
E1000_LEDCTL_MODE_LED_ON) E1000_LEDCTL_LED0_MODE_MASK;
ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << u32 led_default = hw->mac.ledctl_default >> i;
(i * 8));
if ((!(led_default & E1000_LEDCTL_LED0_IVRT) &&
(mode == E1000_LEDCTL_MODE_LED_ON)) ||
((led_default & E1000_LEDCTL_LED0_IVRT) &&
(mode == E1000_LEDCTL_MODE_LED_OFF))) {
ledctl_blink &=
~(E1000_LEDCTL_LED0_MODE_MASK << i);
ledctl_blink |= (E1000_LEDCTL_LED0_BLINK |
E1000_LEDCTL_MODE_LED_ON) << i;
}
}
} }
E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink); E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink);
@ -2082,6 +2180,20 @@ static s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw)
return E1000_SUCCESS; return E1000_SUCCESS;
} }
/**
* e1000_validate_mdi_setting_crossover_generic - Verify MDI/MDIx settings
* @hw: pointer to the HW structure
*
* Validate the MDI/MDIx setting, allowing for auto-crossover during forced
* operation.
**/
s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw)
{
DEBUGFUNC("e1000_validate_mdi_setting_crossover_generic");
return E1000_SUCCESS;
}
/** /**
* e1000_write_8bit_ctrl_reg_generic - Write a 8bit CTRL register * e1000_write_8bit_ctrl_reg_generic - Write a 8bit CTRL register
* @hw: pointer to the HW structure * @hw: pointer to the HW structure

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -35,10 +35,6 @@
#ifndef _E1000_MAC_H_ #ifndef _E1000_MAC_H_
#define _E1000_MAC_H_ #define _E1000_MAC_H_
/*
* Functions that should not be called directly from drivers but can be used
* by other files in this 'shared code'
*/
void e1000_init_mac_ops_generic(struct e1000_hw *hw); void e1000_init_mac_ops_generic(struct e1000_hw *hw);
void e1000_null_mac_generic(struct e1000_hw *hw); void e1000_null_mac_generic(struct e1000_hw *hw);
s32 e1000_null_ops_generic(struct e1000_hw *hw); s32 e1000_null_ops_generic(struct e1000_hw *hw);
@ -47,6 +43,7 @@ bool e1000_null_mng_mode(struct e1000_hw *hw);
void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a); void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a);
void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b); void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b);
void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a); void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a);
s32 e1000_null_set_obff_timer(struct e1000_hw *hw, u32 a);
s32 e1000_blink_led_generic(struct e1000_hw *hw); s32 e1000_blink_led_generic(struct e1000_hw *hw);
s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw); s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw);
s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw); s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw);
@ -77,6 +74,7 @@ s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw);
s32 e1000_setup_fiber_serdes_link_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_led_generic(struct e1000_hw *hw);
s32 e1000_setup_link_generic(struct e1000_hw *hw); s32 e1000_setup_link_generic(struct e1000_hw *hw);
s32 e1000_validate_mdi_setting_crossover_generic(struct e1000_hw *hw);
s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg,
u32 offset, u8 data); u32 offset, u8 data);

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -145,11 +145,10 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
return hw->mac.tx_pkt_filtering; return hw->mac.tx_pkt_filtering;
} }
/* /* If we can't read from the host interface for whatever
* If we can't read from the host interface for whatever
* reason, disable filtering. * reason, disable filtering.
*/ */
ret_val = hw->mac.ops.mng_enable_host_if(hw); ret_val = e1000_mng_enable_host_if_generic(hw);
if (ret_val != E1000_SUCCESS) { if (ret_val != E1000_SUCCESS) {
hw->mac.tx_pkt_filtering = FALSE; hw->mac.tx_pkt_filtering = FALSE;
return hw->mac.tx_pkt_filtering; return hw->mac.tx_pkt_filtering;
@ -165,8 +164,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw)
hdr->checksum = 0; hdr->checksum = 0;
csum = e1000_calculate_checksum((u8 *)hdr, 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
* If either the checksums or signature don't match, then
* the cookie area isn't considered valid, in which case we * the cookie area isn't considered valid, in which case we
* take the safe route of assuming Tx filtering is enabled. * take the safe route of assuming Tx filtering is enabled.
*/ */
@ -259,8 +257,7 @@ s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer,
/* Calculate length in DWORDs */ /* Calculate length in DWORDs */
length >>= 2; length >>= 2;
/* /* The device driver writes the relevant command block into the
* The device driver writes the relevant command block into the
* ram area. * ram area.
*/ */
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
@ -312,18 +309,18 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, u8 *buffer,
hdr.checksum = 0; hdr.checksum = 0;
/* Enable the host interface */ /* Enable the host interface */
ret_val = hw->mac.ops.mng_enable_host_if(hw); ret_val = e1000_mng_enable_host_if_generic(hw);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* Populate the host interface with the contents of "buffer". */ /* Populate the host interface with the contents of "buffer". */
ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, ret_val = e1000_mng_host_if_write_generic(hw, buffer, length,
sizeof(hdr), &(hdr.checksum)); sizeof(hdr), &(hdr.checksum));
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* Write the manageability command header */ /* Write the manageability command header */
ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); ret_val = e1000_mng_write_cmd_header_generic(hw, &hdr);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
@ -424,8 +421,7 @@ s32 e1000_host_interface_command(struct e1000_hw *hw, u8 *buffer, u32 length)
/* Calculate length in DWORDs */ /* Calculate length in DWORDs */
length >>= 2; length >>= 2;
/* /* The device driver writes the relevant command block
* The device driver writes the relevant command block
* into the ram area. * into the ram area.
*/ */
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
@ -537,8 +533,7 @@ s32 e1000_load_firmware(struct e1000_hw *hw, u8 *buffer, u32 length)
/* Calculate length in DWORDs */ /* Calculate length in DWORDs */
length >>= 2; length >>= 2;
/* /* The device driver writes the relevant FW code block
* The device driver writes the relevant FW code block
* into the ram area in DWORDs via 1kB ram addressing window. * into the ram area in DWORDs via 1kB ram addressing window.
*/ */
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2011, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -227,7 +227,6 @@ s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
{ {
u32 attempts = 100000; u32 attempts = 100000;
u32 i, reg = 0; u32 i, reg = 0;
s32 ret_val = -E1000_ERR_NVM;
DEBUGFUNC("e1000_poll_eerd_eewr_done"); DEBUGFUNC("e1000_poll_eerd_eewr_done");
@ -237,15 +236,13 @@ s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg)
else else
reg = E1000_READ_REG(hw, E1000_EEWR); reg = E1000_READ_REG(hw, E1000_EEWR);
if (reg & E1000_NVM_RW_REG_DONE) { if (reg & E1000_NVM_RW_REG_DONE)
ret_val = E1000_SUCCESS; return E1000_SUCCESS;
break;
}
usec_delay(5); usec_delay(5);
} }
return ret_val; return -E1000_ERR_NVM;
} }
/** /**
@ -260,7 +257,6 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
{ {
u32 eecd = E1000_READ_REG(hw, E1000_EECD); u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 timeout = E1000_NVM_GRANT_ATTEMPTS; s32 timeout = E1000_NVM_GRANT_ATTEMPTS;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_acquire_nvm_generic"); DEBUGFUNC("e1000_acquire_nvm_generic");
@ -279,10 +275,10 @@ s32 e1000_acquire_nvm_generic(struct e1000_hw *hw)
eecd &= ~E1000_EECD_REQ; eecd &= ~E1000_EECD_REQ;
E1000_WRITE_REG(hw, E1000_EECD, eecd); E1000_WRITE_REG(hw, E1000_EECD, eecd);
DEBUGOUT("Could not acquire NVM grant\n"); DEBUGOUT("Could not acquire NVM grant\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
} }
return ret_val; return E1000_SUCCESS;
} }
/** /**
@ -381,7 +377,6 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
{ {
struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_nvm_info *nvm = &hw->nvm;
u32 eecd = E1000_READ_REG(hw, E1000_EECD); u32 eecd = E1000_READ_REG(hw, E1000_EECD);
s32 ret_val = E1000_SUCCESS;
u8 spi_stat_reg; u8 spi_stat_reg;
DEBUGFUNC("e1000_ready_nvm_eeprom"); DEBUGFUNC("e1000_ready_nvm_eeprom");
@ -402,8 +397,7 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
usec_delay(1); usec_delay(1);
/* /* Read "Status Register" repeatedly until the LSB is cleared.
* Read "Status Register" repeatedly until the LSB is cleared.
* The EEPROM will signal that the command has been completed * The EEPROM will signal that the command has been completed
* by clearing bit 0 of the internal status register. If it's * by clearing bit 0 of the internal status register. If it's
* not cleared within 'timeout', then error out. * not cleared within 'timeout', then error out.
@ -422,13 +416,11 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
if (!timeout) { if (!timeout) {
DEBUGOUT("SPI NVM Status error\n"); DEBUGOUT("SPI NVM Status error\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -450,20 +442,18 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
DEBUGFUNC("e1000_read_nvm_spi"); DEBUGFUNC("e1000_read_nvm_spi");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* and not enough words. * and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
ret_val = nvm->ops.acquire(hw); ret_val = nvm->ops.acquire(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw); ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) if (ret_val)
@ -478,8 +468,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits);
e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits);
/* /* Read the data. SPI NVMs increment the address with each byte
* Read the data. SPI NVMs increment the address with each byte
* read and will roll over if reading beyond the end. This allows * read and will roll over if reading beyond the end. This allows
* us to read the whole NVM from any offset * us to read the whole NVM from any offset
*/ */
@ -491,7 +480,6 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
release: release:
nvm->ops.release(hw); nvm->ops.release(hw);
out:
return ret_val; return ret_val;
} }
@ -514,20 +502,18 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
DEBUGFUNC("e1000_read_nvm_microwire"); DEBUGFUNC("e1000_read_nvm_microwire");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* and not enough words. * and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
ret_val = nvm->ops.acquire(hw); ret_val = nvm->ops.acquire(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw); ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) if (ret_val)
@ -539,8 +525,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
e1000_shift_out_eec_bits(hw, (u16)(offset + i), e1000_shift_out_eec_bits(hw, (u16)(offset + i),
nvm->address_bits); nvm->address_bits);
/* /* Read the data. For microwire, each word requires the
* Read the data. For microwire, each word requires the
* overhead of setup and tear-down. * overhead of setup and tear-down.
*/ */
data[i] = e1000_shift_in_eec_bits(hw, 16); data[i] = e1000_shift_in_eec_bits(hw, 16);
@ -550,7 +535,6 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
release: release:
nvm->ops.release(hw); nvm->ops.release(hw);
out:
return ret_val; return ret_val;
} }
@ -571,15 +555,13 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
DEBUGFUNC("e1000_read_nvm_eerd"); DEBUGFUNC("e1000_read_nvm_eerd");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* too many words for the offset, and not enough words. * too many words for the offset, and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
for (i = 0; i < words; i++) { for (i = 0; i < words; i++) {
@ -595,7 +577,6 @@ s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
E1000_NVM_RW_REG_DATA); E1000_NVM_RW_REG_DATA);
} }
out:
return ret_val; return ret_val;
} }
@ -614,32 +595,32 @@ out:
s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
{ {
struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_nvm_info *nvm = &hw->nvm;
s32 ret_val; s32 ret_val = -E1000_ERR_NVM;
u16 widx = 0; u16 widx = 0;
DEBUGFUNC("e1000_write_nvm_spi"); DEBUGFUNC("e1000_write_nvm_spi");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* and not enough words. * and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
ret_val = nvm->ops.acquire(hw);
if (ret_val)
goto out;
while (widx < words) { while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI; u8 write_opcode = NVM_WRITE_OPCODE_SPI;
ret_val = e1000_ready_nvm_eeprom(hw); ret_val = nvm->ops.acquire(hw);
if (ret_val) if (ret_val)
goto release; return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) {
nvm->ops.release(hw);
return ret_val;
}
e1000_standby_nvm(hw); e1000_standby_nvm(hw);
@ -649,8 +630,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
e1000_standby_nvm(hw); e1000_standby_nvm(hw);
/* /* Some SPI eeproms use the 8th address bit embedded in the
* Some SPI eeproms use the 8th address bit embedded in the
* opcode * opcode
*/ */
if ((nvm->address_bits == 8) && (offset >= 128)) if ((nvm->address_bits == 8) && (offset >= 128))
@ -673,13 +653,10 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
break; break;
} }
} }
msec_delay(10);
nvm->ops.release(hw);
} }
msec_delay(10);
release:
nvm->ops.release(hw);
out:
return ret_val; return ret_val;
} }
@ -706,20 +683,18 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
DEBUGFUNC("e1000_write_nvm_microwire"); DEBUGFUNC("e1000_write_nvm_microwire");
/* /* A check for invalid values: offset too large, too many words,
* A check for invalid values: offset too large, too many words,
* and not enough words. * and not enough words.
*/ */
if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
(words == 0)) { (words == 0)) {
DEBUGOUT("nvm parameter(s) out of bounds\n"); DEBUGOUT("nvm parameter(s) out of bounds\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
ret_val = nvm->ops.acquire(hw); ret_val = nvm->ops.acquire(hw);
if (ret_val) if (ret_val)
goto out; return ret_val;
ret_val = e1000_ready_nvm_eeprom(hw); ret_val = e1000_ready_nvm_eeprom(hw);
if (ret_val) if (ret_val)
@ -769,7 +744,6 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words,
release: release:
nvm->ops.release(hw); nvm->ops.release(hw);
out:
return ret_val; return ret_val;
} }
@ -795,32 +769,30 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
if (pba_num == NULL) { if (pba_num == NULL) {
DEBUGOUT("PBA string buffer was null\n"); DEBUGOUT("PBA string buffer was null\n");
ret_val = E1000_ERR_INVALID_ARGUMENT; return -E1000_ERR_INVALID_ARGUMENT;
goto out;
} }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
/* /* if nvm_data is not ptr guard the PBA must be in legacy format which
* if nvm_data is not ptr guard the PBA must be in legacy format which
* means pba_ptr is actually our second data word for the PBA number * means pba_ptr is actually our second data word for the PBA number
* and we can decode it into an ascii string * and we can decode it into an ascii string
*/ */
if (nvm_data != NVM_PBA_PTR_GUARD) { if (nvm_data != NVM_PBA_PTR_GUARD) {
DEBUGOUT("NVM PBA number is not stored as string\n"); DEBUGOUT("NVM PBA number is not stored as string\n");
/* we will need 11 characters to store the PBA */ /* make sure callers buffer is big enough to store the PBA */
if (pba_num_size < 11) { if (pba_num_size < E1000_PBANUM_LENGTH) {
DEBUGOUT("PBA string buffer too small\n"); DEBUGOUT("PBA string buffer too small\n");
return E1000_ERR_NO_SPACE; return E1000_ERR_NO_SPACE;
} }
@ -848,25 +820,23 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
pba_num[offset] += 'A' - 0xA; pba_num[offset] += 'A' - 0xA;
} }
goto out; return E1000_SUCCESS;
} }
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
if (length == 0xFFFF || length == 0) { if (length == 0xFFFF || length == 0) {
DEBUGOUT("NVM PBA number section invalid length\n"); DEBUGOUT("NVM PBA number section invalid length\n");
ret_val = E1000_ERR_NVM_PBA_SECTION; return -E1000_ERR_NVM_PBA_SECTION;
goto out;
} }
/* check if pba_num buffer is big enough */ /* check if pba_num buffer is big enough */
if (pba_num_size < (((u32)length * 2) - 1)) { if (pba_num_size < (((u32)length * 2) - 1)) {
DEBUGOUT("PBA string buffer too small\n"); DEBUGOUT("PBA string buffer too small\n");
ret_val = E1000_ERR_NO_SPACE; return -E1000_ERR_NO_SPACE;
goto out;
} }
/* trim pba length from start of string */ /* trim pba length from start of string */
@ -877,15 +847,14 @@ s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data); ret_val = hw->nvm.ops.read(hw, pba_ptr + offset, 1, &nvm_data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
pba_num[offset * 2] = (u8)(nvm_data >> 8); pba_num[offset * 2] = (u8)(nvm_data >> 8);
pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF);
} }
pba_num[offset * 2] = '\0'; pba_num[offset * 2] = '\0';
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -907,48 +876,233 @@ s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size)
if (pba_num_size == NULL) { if (pba_num_size == NULL) {
DEBUGOUT("PBA buffer size was null\n"); DEBUGOUT("PBA buffer size was null\n");
ret_val = E1000_ERR_INVALID_ARGUMENT; return -E1000_ERR_INVALID_ARGUMENT;
goto out;
} }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
/* if data is not ptr guard the PBA must be in legacy format */ /* if data is not ptr guard the PBA must be in legacy format */
if (nvm_data != NVM_PBA_PTR_GUARD) { if (nvm_data != NVM_PBA_PTR_GUARD) {
*pba_num_size = 11; *pba_num_size = E1000_PBANUM_LENGTH;
goto out; return E1000_SUCCESS;
} }
ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length); ret_val = hw->nvm.ops.read(hw, pba_ptr, 1, &length);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
if (length == 0xFFFF || length == 0) { if (length == 0xFFFF || length == 0) {
DEBUGOUT("NVM PBA number section invalid length\n"); DEBUGOUT("NVM PBA number section invalid length\n");
ret_val = E1000_ERR_NVM_PBA_SECTION; return -E1000_ERR_NVM_PBA_SECTION;
goto out;
} }
/* /* Convert from length in u16 values to u8 chars, add 1 for NULL,
* Convert from length in u16 values to u8 chars, add 1 for NULL,
* and subtract 2 because length field is included in length. * and subtract 2 because length field is included in length.
*/ */
*pba_num_size = ((u32)length * 2) - 1; *pba_num_size = ((u32)length * 2) - 1;
out: return E1000_SUCCESS;
return ret_val; }
/**
* e1000_read_pba_raw
* @hw: pointer to the HW structure
* @eeprom_buf: optional pointer to EEPROM image
* @eeprom_buf_size: size of EEPROM image in words
* @max_pba_block_size: PBA block size limit
* @pba: pointer to output PBA structure
*
* Reads PBA from EEPROM image when eeprom_buf is not NULL.
* Reads PBA from physical EEPROM device when eeprom_buf is NULL.
*
**/
s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, u16 max_pba_block_size,
struct e1000_pba *pba)
{
s32 ret_val;
u16 pba_block_size;
if (pba == NULL)
return -E1000_ERR_PARAM;
if (eeprom_buf == NULL) {
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2,
&pba->word[0]);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
pba->word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
pba->word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
} else {
return -E1000_ERR_PARAM;
}
}
if (pba->word[0] == NVM_PBA_PTR_GUARD) {
if (pba->pba_block == NULL)
return -E1000_ERR_PARAM;
ret_val = e1000_get_pba_block_size(hw, eeprom_buf,
eeprom_buf_size,
&pba_block_size);
if (ret_val)
return ret_val;
if (pba_block_size > max_pba_block_size)
return -E1000_ERR_PARAM;
if (eeprom_buf == NULL) {
ret_val = e1000_read_nvm(hw, pba->word[1],
pba_block_size,
pba->pba_block);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > (u32)(pba->word[1] +
pba->pba_block[0])) {
memcpy(pba->pba_block,
&eeprom_buf[pba->word[1]],
pba_block_size * sizeof(u16));
} else {
return -E1000_ERR_PARAM;
}
}
}
return E1000_SUCCESS;
}
/**
* e1000_write_pba_raw
* @hw: pointer to the HW structure
* @eeprom_buf: optional pointer to EEPROM image
* @eeprom_buf_size: size of EEPROM image in words
* @pba: pointer to PBA structure
*
* Writes PBA to EEPROM image when eeprom_buf is not NULL.
* Writes PBA to physical EEPROM device when eeprom_buf is NULL.
*
**/
s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, struct e1000_pba *pba)
{
s32 ret_val;
if (pba == NULL)
return -E1000_ERR_PARAM;
if (eeprom_buf == NULL) {
ret_val = e1000_write_nvm(hw, NVM_PBA_OFFSET_0, 2,
&pba->word[0]);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
eeprom_buf[NVM_PBA_OFFSET_0] = pba->word[0];
eeprom_buf[NVM_PBA_OFFSET_1] = pba->word[1];
} else {
return -E1000_ERR_PARAM;
}
}
if (pba->word[0] == NVM_PBA_PTR_GUARD) {
if (pba->pba_block == NULL)
return -E1000_ERR_PARAM;
if (eeprom_buf == NULL) {
ret_val = e1000_write_nvm(hw, pba->word[1],
pba->pba_block[0],
pba->pba_block);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > (u32)(pba->word[1] +
pba->pba_block[0])) {
memcpy(&eeprom_buf[pba->word[1]],
pba->pba_block,
pba->pba_block[0] * sizeof(u16));
} else {
return -E1000_ERR_PARAM;
}
}
}
return E1000_SUCCESS;
}
/**
* e1000_get_pba_block_size
* @hw: pointer to the HW structure
* @eeprom_buf: optional pointer to EEPROM image
* @eeprom_buf_size: size of EEPROM image in words
* @pba_data_size: pointer to output variable
*
* Returns the size of the PBA block in words. Function operates on EEPROM
* image if the eeprom_buf pointer is not NULL otherwise it accesses physical
* EEPROM device.
*
**/
s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, u16 *pba_block_size)
{
s32 ret_val;
u16 pba_word[2];
u16 length;
DEBUGFUNC("e1000_get_pba_block_size");
if (eeprom_buf == NULL) {
ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 2, &pba_word[0]);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > NVM_PBA_OFFSET_1) {
pba_word[0] = eeprom_buf[NVM_PBA_OFFSET_0];
pba_word[1] = eeprom_buf[NVM_PBA_OFFSET_1];
} else {
return -E1000_ERR_PARAM;
}
}
if (pba_word[0] == NVM_PBA_PTR_GUARD) {
if (eeprom_buf == NULL) {
ret_val = e1000_read_nvm(hw, pba_word[1] + 0, 1,
&length);
if (ret_val)
return ret_val;
} else {
if (eeprom_buf_size > pba_word[1])
length = eeprom_buf[pba_word[1] + 0];
else
return -E1000_ERR_PARAM;
}
if (length == 0xFFFF || length == 0)
return -E1000_ERR_NVM_PBA_SECTION;
} else {
/* PBA number in legacy format, there is no PBA Block. */
length = 0;
}
if (pba_block_size != NULL)
*pba_block_size = length;
return E1000_SUCCESS;
} }
/** /**
@ -989,7 +1143,7 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw)
**/ **/
s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
{ {
s32 ret_val = E1000_SUCCESS; s32 ret_val;
u16 checksum = 0; u16 checksum = 0;
u16 i, nvm_data; u16 i, nvm_data;
@ -999,19 +1153,17 @@ s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error\n"); DEBUGOUT("NVM Read Error\n");
goto out; return ret_val;
} }
checksum += nvm_data; checksum += nvm_data;
} }
if (checksum != (u16) NVM_SUM) { if (checksum != (u16) NVM_SUM) {
DEBUGOUT("NVM Checksum Invalid\n"); DEBUGOUT("NVM Checksum Invalid\n");
ret_val = -E1000_ERR_NVM; return -E1000_ERR_NVM;
goto out;
} }
out: return E1000_SUCCESS;
return ret_val;
} }
/** /**
@ -1034,7 +1186,7 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data);
if (ret_val) { if (ret_val) {
DEBUGOUT("NVM Read Error while updating checksum.\n"); DEBUGOUT("NVM Read Error while updating checksum.\n");
goto out; return ret_val;
} }
checksum += nvm_data; checksum += nvm_data;
} }
@ -1043,7 +1195,6 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw)
if (ret_val) if (ret_val)
DEBUGOUT("NVM Write Error while updating checksum.\n"); DEBUGOUT("NVM Write Error while updating checksum.\n");
out:
return ret_val; return ret_val;
} }
@ -1067,3 +1218,4 @@ static void e1000_reload_nvm_generic(struct e1000_hw *hw)
E1000_WRITE_FLUSH(hw); E1000_WRITE_FLUSH(hw);
} }

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2011, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -35,6 +35,14 @@
#ifndef _E1000_NVM_H_ #ifndef _E1000_NVM_H_
#define _E1000_NVM_H_ #define _E1000_NVM_H_
#if !defined(NO_READ_PBA_RAW) || !defined(NO_WRITE_PBA_RAW)
struct e1000_pba {
u16 word[2];
u16 *pba_block;
};
#endif
void e1000_init_nvm_ops_generic(struct e1000_hw *hw); void e1000_init_nvm_ops_generic(struct e1000_hw *hw);
s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c); s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c);
void e1000_null_nvm_generic(struct e1000_hw *hw); void e1000_null_nvm_generic(struct e1000_hw *hw);
@ -47,6 +55,13 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);
s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num,
u32 pba_num_size); u32 pba_num_size);
s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size); s32 e1000_read_pba_length_generic(struct e1000_hw *hw, u32 *pba_num_size);
s32 e1000_read_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, u16 max_pba_block_size,
struct e1000_pba *pba);
s32 e1000_write_pba_raw(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, struct e1000_pba *pba);
s32 e1000_get_pba_block_size(struct e1000_hw *hw, u16 *eeprom_buf,
u32 eeprom_buf_size, u16 *pba_block_size);
s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data); u16 words, u16 *data);

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2010, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -66,7 +66,8 @@
#define MSGOUT(S, A, B) printf(S "\n", A, B) #define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F); #define DEBUGFUNC(F) DEBUGOUT(F);
#define DEBUGOUT(S) do {} while (0) #define DEBUGOUT(S) do {} while (0)
#define DEBUGOUT1(S,A) do {} while (0) /* This define is needed or shared code will not build */
#define DEBUGOUT1(S,A) if (0) printf(S,A);
#define DEBUGOUT2(S,A,B) do {} while (0) #define DEBUGOUT2(S,A,B) do {} while (0)
#define DEBUGOUT3(S,A,B,C) do {} while (0) #define DEBUGOUT3(S,A,B,C) do {} while (0)
#define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0) #define DEBUGOUT7(S,A,B,C,D,E,F,G) do {} while (0)

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -34,7 +34,7 @@
#include "e1000_api.h" #include "e1000_api.h"
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); static s32 e1000_wait_autoneg(struct e1000_hw *hw);
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
u16 *data, bool read, bool page_set); u16 *data, bool read, bool page_set);
static u32 e1000_get_phy_addr_for_hv_page(u32 page); static u32 e1000_get_phy_addr_for_hv_page(u32 page);
@ -173,8 +173,10 @@ s32 e1000_read_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset,
* @data: data value to write * @data: data value to write
* *
**/ **/
s32 e1000_write_i2c_byte_null(struct e1000_hw *hw, u8 byte_offset, s32 e1000_write_i2c_byte_null(struct e1000_hw *hw,
u8 dev_addr, u8 data) u8 byte_offset,
u8 dev_addr,
u8 data)
{ {
DEBUGFUNC("e1000_write_i2c_byte_null"); DEBUGFUNC("e1000_write_i2c_byte_null");
return E1000_SUCCESS; return E1000_SUCCESS;
@ -285,8 +287,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
return -E1000_ERR_PARAM; return -E1000_ERR_PARAM;
} }
/* /* Set up Op-code, Phy Address, and register offset in the MDI
* Set up Op-code, Phy Address, and register offset in the MDI
* Control register. The MAC will take care of interfacing with the * Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data. * PHY to retrieve the desired data.
*/ */
@ -296,8 +297,7 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
E1000_WRITE_REG(hw, E1000_MDIC, mdic); E1000_WRITE_REG(hw, E1000_MDIC, mdic);
/* /* Poll the ready bit to see if the MDI read completed
* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with * Increasing the time out as testing showed failures with
* the lower time out * the lower time out
*/ */
@ -315,10 +315,15 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
DEBUGOUT("MDI Error\n"); DEBUGOUT("MDI Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
DEBUGOUT2("MDI Read offset error - requested %d, returned %d\n",
offset,
(mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
return -E1000_ERR_PHY;
}
*data = (u16) mdic; *data = (u16) mdic;
/* /* Allow some time after each MDIC transaction to avoid
* Allow some time after each MDIC transaction to avoid
* reading duplicate data in the next MDIC transaction. * reading duplicate data in the next MDIC transaction.
*/ */
if (hw->mac.type == e1000_pch2lan) if (hw->mac.type == e1000_pch2lan)
@ -347,8 +352,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
return -E1000_ERR_PARAM; return -E1000_ERR_PARAM;
} }
/* /* Set up Op-code, Phy Address, and register offset in the MDI
* Set up Op-code, Phy Address, and register offset in the MDI
* Control register. The MAC will take care of interfacing with the * Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data. * PHY to retrieve the desired data.
*/ */
@ -359,8 +363,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
E1000_WRITE_REG(hw, E1000_MDIC, mdic); E1000_WRITE_REG(hw, E1000_MDIC, mdic);
/* /* Poll the ready bit to see if the MDI read completed
* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with * Increasing the time out as testing showed failures with
* the lower time out * the lower time out
*/ */
@ -378,9 +381,14 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
DEBUGOUT("MDI Error\n"); DEBUGOUT("MDI Error\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
if (((mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT) != offset) {
DEBUGOUT2("MDI Write offset error - requested %d, returned %d\n",
offset,
(mdic & E1000_MDIC_REG_MASK) >> E1000_MDIC_REG_SHIFT);
return -E1000_ERR_PHY;
}
/* /* Allow some time after each MDIC transaction to avoid
* Allow some time after each MDIC transaction to avoid
* reading duplicate data in the next MDIC transaction. * reading duplicate data in the next MDIC transaction.
*/ */
if (hw->mac.type == e1000_pch2lan) if (hw->mac.type == e1000_pch2lan)
@ -405,8 +413,7 @@ s32 e1000_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data)
DEBUGFUNC("e1000_read_phy_reg_i2c"); DEBUGFUNC("e1000_read_phy_reg_i2c");
/* /* Set up Op-code, Phy Address, and register address in the I2CCMD
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the * register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data. * PHY to retrieve the desired data.
*/ */
@ -464,8 +471,7 @@ s32 e1000_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data)
/* Swap the data bytes for the I2C interface */ /* Swap the data bytes for the I2C interface */
phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00); phy_data_swapped = ((data >> 8) & 0x00FF) | ((data << 8) & 0xFF00);
/* /* Set up Op-code, Phy Address, and register address in the I2CCMD
* Set up Op-code, Phy Address, and register address in the I2CCMD
* register. The MAC will take care of interfacing with the * register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data. * PHY to retrieve the desired data.
*/ */
@ -521,8 +527,7 @@ s32 e1000_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data)
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
/* /* Set up Op-code, EEPROM Address,in the I2CCMD
* Set up Op-code, EEPROM Address,in the I2CCMD
* register. The MAC will take care of interfacing with the * register. The MAC will take care of interfacing with the
* EEPROM to retrieve the desired data. * EEPROM to retrieve the desired data.
*/ */
@ -576,14 +581,12 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
DEBUGOUT("I2CCMD command address exceeds upper limit\n"); DEBUGOUT("I2CCMD command address exceeds upper limit\n");
return -E1000_ERR_PHY; return -E1000_ERR_PHY;
} }
/* /* The programming interface is 16 bits wide
* The programming interface is 16 bits wide
* so we need to read the whole word first * so we need to read the whole word first
* then update appropriate byte lane and write * then update appropriate byte lane and write
* the updated word back. * the updated word back.
*/ */
/* /* Set up Op-code, EEPROM Address,in the I2CCMD
* Set up Op-code, EEPROM Address,in the I2CCMD
* register. The MAC will take care of interfacing * register. The MAC will take care of interfacing
* with an EEPROM to write the data given. * with an EEPROM to write the data given.
*/ */
@ -593,8 +596,7 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd); E1000_WRITE_REG(hw, E1000_I2CCMD, i2ccmd);
for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) { for (i = 0; i < E1000_I2CCMD_PHY_TIMEOUT; i++) {
usec_delay(50); usec_delay(50);
/* /* Poll the ready bit to see if lastly
* Poll the ready bit to see if lastly
* launched I2C operation completed * launched I2C operation completed
*/ */
i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD); i2ccmd = E1000_READ_REG(hw, E1000_I2CCMD);
@ -602,8 +604,7 @@ s32 e1000_write_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 data)
/* Check if this is READ or WRITE phase */ /* Check if this is READ or WRITE phase */
if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) == if ((i2ccmd & E1000_I2CCMD_OPCODE_READ) ==
E1000_I2CCMD_OPCODE_READ) { E1000_I2CCMD_OPCODE_READ) {
/* /* Write the selected byte
* Write the selected byte
* lane and update whole word * lane and update whole word
*/ */
data_local = i2ccmd & 0xFF00; data_local = i2ccmd & 0xFF00;
@ -1053,12 +1054,16 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
} }
} }
/* Enable CRS on Tx. This must be set for half-duplex operation. */ /* Enable CRS on Tx. This must be set for half-duplex operation.
* Not required on some PHYs.
*/
ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data); ret_val = hw->phy.ops.read_reg(hw, I82577_CFG_REG, &phy_data);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
phy_data |= I82577_CFG_ASSERT_CRS_ON_TX; if ((hw->phy.type != e1000_phy_82579) &&
(hw->phy.type != e1000_phy_i217))
phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
/* Enable downshift */ /* Enable downshift */
phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
@ -1072,8 +1077,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK; phy_data &= ~I82577_PHY_CTRL2_MDIX_CFG_MASK;
/* /* Options:
* Options:
* 0 - Auto (default) * 0 - Auto (default)
* 1 - MDI mode * 1 - MDI mode
* 2 - MDI-X mode * 2 - MDI-X mode
@ -1121,8 +1125,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
if (phy->type != e1000_phy_bm) if (phy->type != e1000_phy_bm)
phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
/* /* Options:
* Options:
* MDI/MDI-X = 0 (default) * MDI/MDI-X = 0 (default)
* 0 - Auto for all speeds * 0 - Auto for all speeds
* 1 - MDI mode * 1 - MDI mode
@ -1147,8 +1150,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
break; break;
} }
/* /* Options:
* Options:
* disable_polarity_correction = 0 (default) * disable_polarity_correction = 0 (default)
* Automatic Correction for Reversed Cable Polarity * Automatic Correction for Reversed Cable Polarity
* 0 - Disabled * 0 - Disabled
@ -1185,8 +1187,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
if ((phy->type == e1000_phy_m88) && if ((phy->type == e1000_phy_m88) &&
(phy->revision < E1000_REVISION_4) && (phy->revision < E1000_REVISION_4) &&
(phy->id != BME1000_E_PHY_ID_R2)) { (phy->id != BME1000_E_PHY_ID_R2)) {
/* /* Force TX_CLK in the Extended PHY Specific Control Register
* Force TX_CLK in the Extended PHY Specific Control Register
* to 25MHz clock. * to 25MHz clock.
*/ */
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
@ -1278,8 +1279,7 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Options:
* Options:
* MDI/MDI-X = 0 (default) * MDI/MDI-X = 0 (default)
* 0 - Auto for all speeds * 0 - Auto for all speeds
* 1 - MDI mode * 1 - MDI mode
@ -1307,8 +1307,7 @@ s32 e1000_copper_link_setup_m88_gen2(struct e1000_hw *hw)
break; break;
} }
/* /* Options:
* Options:
* disable_polarity_correction = 0 (default) * disable_polarity_correction = 0 (default)
* Automatic Correction for Reversed Cable Polarity * Automatic Correction for Reversed Cable Polarity
* 0 - Disabled * 0 - Disabled
@ -1359,14 +1358,12 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* /* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
* Wait 100ms for MAC to configure PHY from NVM settings, to avoid
* timeout issues when LFS is enabled. * timeout issues when LFS is enabled.
*/ */
msec_delay(100); msec_delay(100);
/* /* The NVM settings will configure LPLU in D3 for
* The NVM settings will configure LPLU in D3 for
* non-IGP1 PHYs. * non-IGP1 PHYs.
*/ */
if (phy->type == e1000_phy_igp) { if (phy->type == e1000_phy_igp) {
@ -1411,8 +1408,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw)
/* set auto-master slave resolution settings */ /* set auto-master slave resolution settings */
if (hw->mac.autoneg) { if (hw->mac.autoneg) {
/* /* when autonegotiation advertisement is only 1000Mbps then we
* when autonegotiation advertisement is only 1000Mbps then we
* should disable SmartSpeed and enable Auto MasterSlave * should disable SmartSpeed and enable Auto MasterSlave
* resolution as hardware default. * resolution as hardware default.
*/ */
@ -1481,16 +1477,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
return ret_val; return ret_val;
} }
/* /* Need to parse both autoneg_advertised and fc and set up
* Need to parse both autoneg_advertised and fc and set up
* the appropriate PHY registers. First we will parse for * the appropriate PHY registers. First we will parse for
* autoneg_advertised software override. Since we can advertise * autoneg_advertised software override. Since we can advertise
* a plethora of combinations, we need to check each bit * a plethora of combinations, we need to check each bit
* individually. * individually.
*/ */
/* /* First we clear all the 10/100 mb speed bits in the Auto-Neg
* First we clear all the 10/100 mb speed bits in the Auto-Neg
* Advertisement Register (Address 4) and the 1000 mb speed bits in * Advertisement Register (Address 4) and the 1000 mb speed bits in
* the 1000Base-T Control Register (Address 9). * the 1000Base-T Control Register (Address 9).
*/ */
@ -1536,8 +1530,7 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
} }
/* /* Check for a software override of the flow control settings, and
* Check for a software override of the flow control settings, and
* setup the PHY advertisement registers accordingly. If * setup the PHY advertisement registers accordingly. If
* auto-negotiation is enabled, then software will have to set the * auto-negotiation is enabled, then software will have to set the
* "PAUSE" bits to the correct value in the Auto-Negotiation * "PAUSE" bits to the correct value in the Auto-Negotiation
@ -1556,15 +1549,13 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
*/ */
switch (hw->fc.current_mode) { switch (hw->fc.current_mode) {
case e1000_fc_none: case e1000_fc_none:
/* /* Flow control (Rx & Tx) is completely disabled by a
* Flow control (Rx & Tx) is completely disabled by a
* software over-ride. * software over-ride.
*/ */
mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break; break;
case e1000_fc_rx_pause: case e1000_fc_rx_pause:
/* /* Rx Flow control is enabled, and Tx Flow control is
* Rx Flow control is enabled, and Tx Flow control is
* disabled, by a software over-ride. * disabled, by a software over-ride.
* *
* Since there really isn't a way to advertise that we are * Since there really isn't a way to advertise that we are
@ -1576,16 +1567,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
break; break;
case e1000_fc_tx_pause: case e1000_fc_tx_pause:
/* /* Tx Flow control is enabled, and Rx Flow control is
* Tx Flow control is enabled, and Rx Flow control is
* disabled, by a software over-ride. * disabled, by a software over-ride.
*/ */
mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
break; break;
case e1000_fc_full: case e1000_fc_full:
/* /* Flow control (both Rx and Tx) is enabled by a software
* Flow control (both Rx and Tx) is enabled by a software
* over-ride. * over-ride.
*/ */
mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
@ -1625,14 +1614,12 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
DEBUGFUNC("e1000_copper_link_autoneg"); DEBUGFUNC("e1000_copper_link_autoneg");
/* /* Perform some bounds checking on the autoneg advertisement
* Perform some bounds checking on the autoneg advertisement
* parameter. * parameter.
*/ */
phy->autoneg_advertised &= phy->autoneg_mask; phy->autoneg_advertised &= phy->autoneg_mask;
/* /* If autoneg_advertised is zero, we assume it was not defaulted
* If autoneg_advertised is zero, we assume it was not defaulted
* by the calling code so we set to advertise full capability. * by the calling code so we set to advertise full capability.
*/ */
if (!phy->autoneg_advertised) if (!phy->autoneg_advertised)
@ -1646,8 +1633,7 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
} }
DEBUGOUT("Restarting Auto-Neg\n"); DEBUGOUT("Restarting Auto-Neg\n");
/* /* Restart auto-negotiation by setting the Auto Neg Enable bit and
* Restart auto-negotiation by setting the Auto Neg Enable bit and
* the Auto Neg Restart bit in the PHY control register. * the Auto Neg Restart bit in the PHY control register.
*/ */
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl);
@ -1659,12 +1645,11 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Does the user want to wait for Auto-Neg to complete here, or
* Does the user want to wait for Auto-Neg to complete here, or
* check at a later time (for example, callback routine). * check at a later time (for example, callback routine).
*/ */
if (phy->autoneg_wait_to_complete) { if (phy->autoneg_wait_to_complete) {
ret_val = hw->mac.ops.wait_autoneg(hw); ret_val = e1000_wait_autoneg(hw);
if (ret_val) { if (ret_val) {
DEBUGOUT("Error while waiting for autoneg to complete\n"); DEBUGOUT("Error while waiting for autoneg to complete\n");
return ret_val; return ret_val;
@ -1693,16 +1678,14 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
DEBUGFUNC("e1000_setup_copper_link_generic"); DEBUGFUNC("e1000_setup_copper_link_generic");
if (hw->mac.autoneg) { if (hw->mac.autoneg) {
/* /* Setup autoneg and flow control advertisement and perform
* Setup autoneg and flow control advertisement and perform
* autonegotiation. * autonegotiation.
*/ */
ret_val = e1000_copper_link_autoneg(hw); ret_val = e1000_copper_link_autoneg(hw);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
} else { } else {
/* /* PHY will be set to 10H, 10F, 100H or 100F
* PHY will be set to 10H, 10F, 100H or 100F
* depending on user settings. * depending on user settings.
*/ */
DEBUGOUT("Forcing Speed and Duplex\n"); DEBUGOUT("Forcing Speed and Duplex\n");
@ -1713,8 +1696,7 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw)
} }
} }
/* /* Check link status. Wait up to 100 microseconds for link to become
* Check link status. Wait up to 100 microseconds for link to become
* valid. * valid.
*/ */
ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10, ret_val = e1000_phy_has_link_generic(hw, COPPER_LINK_UP_LIMIT, 10,
@ -1760,8 +1742,7 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* Clear Auto-Crossover to force MDI manually. IGP requires MDI
* forced whenever speed and duplex are forced. * forced whenever speed and duplex are forced.
*/ */
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
@ -1817,18 +1798,22 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
DEBUGFUNC("e1000_phy_force_speed_duplex_m88"); DEBUGFUNC("e1000_phy_force_speed_duplex_m88");
/* /* I210 and I211 devices support Auto-Crossover in forced operation. */
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI if (phy->type != e1000_phy_i210) {
* forced whenever speed and duplex are forced. /* Clear Auto-Crossover to force MDI manually. M88E1000
*/ * requires MDI forced whenever speed and duplex are forced.
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); */
if (ret_val) ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
return ret_val; &phy_data);
if (ret_val)
return ret_val;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
if (ret_val) phy_data);
return ret_val; if (ret_val)
return ret_val;
}
DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data); DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data);
@ -1874,8 +1859,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
if (!reset_dsp) { if (!reset_dsp) {
DEBUGOUT("Link taking longer than expected.\n"); DEBUGOUT("Link taking longer than expected.\n");
} else { } else {
/* /* We didn't get link.
* We didn't get link.
* Reset the DSP and cross our fingers. * Reset the DSP and cross our fingers.
*/ */
ret_val = phy->ops.write_reg(hw, ret_val = phy->ops.write_reg(hw,
@ -1909,8 +1893,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Resetting the phy means we need to re-force TX_CLK in the
* Resetting the phy means we need to re-force TX_CLK in the
* Extended PHY Specific Control Register to 25MHz clock from * Extended PHY Specific Control Register to 25MHz clock from
* the reset value of 2.5MHz. * the reset value of 2.5MHz.
*/ */
@ -1919,8 +1902,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* In addition, we must re-enable CRS on Tx for both half and full
* In addition, we must re-enable CRS on Tx for both half and full
* duplex. * duplex.
*/ */
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
@ -2045,11 +2027,10 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) { if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) {
ctrl |= E1000_CTRL_SPD_100; ctrl |= E1000_CTRL_SPD_100;
*phy_ctrl |= MII_CR_SPEED_100; *phy_ctrl |= MII_CR_SPEED_100;
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10); *phy_ctrl &= ~MII_CR_SPEED_1000;
DEBUGOUT("Forcing 100mb\n"); DEBUGOUT("Forcing 100mb\n");
} else { } else {
ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
*phy_ctrl |= MII_CR_SPEED_10;
*phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100); *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100);
DEBUGOUT("Forcing 10mb\n"); DEBUGOUT("Forcing 10mb\n");
} }
@ -2094,8 +2075,7 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active)
data); data);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
* during Dx states where the power conservation is most * during Dx states where the power conservation is most
* important. During driver activity we should enable * important. During driver activity we should enable
* SmartSpeed, so performance is maintained. * SmartSpeed, so performance is maintained.
@ -2238,8 +2218,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_polarity_igp"); DEBUGFUNC("e1000_check_polarity_igp");
/* /* Polarity is determined based on the speed of
* Polarity is determined based on the speed of
* our connection. * our connection.
*/ */
ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data);
@ -2251,8 +2230,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
offset = IGP01E1000_PHY_PCS_INIT_REG; offset = IGP01E1000_PHY_PCS_INIT_REG;
mask = IGP01E1000_PHY_POLARITY_MASK; mask = IGP01E1000_PHY_POLARITY_MASK;
} else { } else {
/* /* This really only applies to 10Mbps since
* This really only applies to 10Mbps since
* there is no polarity for 100Mbps (always 0). * there is no polarity for 100Mbps (always 0).
*/ */
offset = IGP01E1000_PHY_PORT_STATUS; offset = IGP01E1000_PHY_PORT_STATUS;
@ -2283,8 +2261,7 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw)
DEBUGFUNC("e1000_check_polarity_ife"); DEBUGFUNC("e1000_check_polarity_ife");
/* /* Polarity is determined based on the reversal feature being enabled.
* Polarity is determined based on the reversal feature being enabled.
*/ */
if (phy->polarity_correction) { if (phy->polarity_correction) {
offset = IFE_PHY_EXTENDED_STATUS_CONTROL; offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
@ -2305,18 +2282,18 @@ s32 e1000_check_polarity_ife(struct e1000_hw *hw)
} }
/** /**
* e1000_wait_autoneg_generic - Wait for auto-neg completion * e1000_wait_autoneg - Wait for auto-neg completion
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* *
* Waits for auto-negotiation to complete or for the auto-negotiation time * Waits for auto-negotiation to complete or for the auto-negotiation time
* limit to expire, which ever happens first. * limit to expire, which ever happens first.
**/ **/
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) static s32 e1000_wait_autoneg(struct e1000_hw *hw)
{ {
s32 ret_val = E1000_SUCCESS; s32 ret_val = E1000_SUCCESS;
u16 i, phy_status; u16 i, phy_status;
DEBUGFUNC("e1000_wait_autoneg_generic"); DEBUGFUNC("e1000_wait_autoneg");
if (!hw->phy.ops.read_reg) if (!hw->phy.ops.read_reg)
return E1000_SUCCESS; return E1000_SUCCESS;
@ -2334,8 +2311,7 @@ s32 e1000_wait_autoneg_generic(struct e1000_hw *hw)
msec_delay(100); msec_delay(100);
} }
/* /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
* has completed. * has completed.
*/ */
return ret_val; return ret_val;
@ -2362,15 +2338,13 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
return E1000_SUCCESS; return E1000_SUCCESS;
for (i = 0; i < iterations; i++) { for (i = 0; i < iterations; i++) {
/* /* Some PHYs require the PHY_STATUS register to be read
* Some PHYs require the PHY_STATUS register to be read
* twice due to the link bit being sticky. No harm doing * twice due to the link bit being sticky. No harm doing
* it across the board. * it across the board.
*/ */
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
if (ret_val) if (ret_val)
/* /* If the first read fails, another entity may have
* If the first read fails, another entity may have
* ownership of the resources, wait and try again to * ownership of the resources, wait and try again to
* see if they have relinquished the resources yet. * see if they have relinquished the resources yet.
*/ */
@ -2436,7 +2410,8 @@ s32 e1000_get_cable_length_m88_gen2(struct e1000_hw *hw)
{ {
struct e1000_phy_info *phy = &hw->phy; struct e1000_phy_info *phy = &hw->phy;
s32 ret_val; s32 ret_val;
u16 phy_data, phy_data2, index, default_page, is_cm; u16 phy_data, phy_data2, is_cm;
u16 index, default_page;
DEBUGFUNC("e1000_get_cable_length_m88_gen2"); DEBUGFUNC("e1000_get_cable_length_m88_gen2");
@ -2574,8 +2549,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* /* Getting bits 15:9, which represent the combination of
* Getting bits 15:9, which represent the combination of
* coarse and fine gain values. The result is a number * coarse and fine gain values. The result is a number
* that can be put into the lookup table to obtain the * that can be put into the lookup table to obtain the
* approximate cable length. * approximate cable length.
@ -2961,15 +2935,13 @@ s32 e1000_phy_init_script_igp3(struct e1000_hw *hw)
hw->phy.ops.write_reg(hw, 0x1796, 0x0008); hw->phy.ops.write_reg(hw, 0x1796, 0x0008);
/* Change cg_icount + enable integbp for channels BCD */ /* Change cg_icount + enable integbp for channels BCD */
hw->phy.ops.write_reg(hw, 0x1798, 0xD008); hw->phy.ops.write_reg(hw, 0x1798, 0xD008);
/* /* Change cg_icount + enable integbp + change prop_factor_master
* Change cg_icount + enable integbp + change prop_factor_master
* to 8 for channel A * to 8 for channel A
*/ */
hw->phy.ops.write_reg(hw, 0x1898, 0xD918); hw->phy.ops.write_reg(hw, 0x1898, 0xD918);
/* Disable AHT in Slave mode on channel A */ /* Disable AHT in Slave mode on channel A */
hw->phy.ops.write_reg(hw, 0x187A, 0x0800); hw->phy.ops.write_reg(hw, 0x187A, 0x0800);
/* /* Enable LPLU and disable AN to 1000 in non-D0a states,
* Enable LPLU and disable AN to 1000 in non-D0a states,
* Enable SPD+B2B * Enable SPD+B2B
*/ */
hw->phy.ops.write_reg(hw, 0x0019, 0x008D); hw->phy.ops.write_reg(hw, 0x0019, 0x008D);
@ -3030,6 +3002,9 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
case I82579_E_PHY_ID: case I82579_E_PHY_ID:
phy_type = e1000_phy_82579; phy_type = e1000_phy_82579;
break; break;
case I217_E_PHY_ID:
phy_type = e1000_phy_i217;
break;
case I82580_I_PHY_ID: case I82580_I_PHY_ID:
phy_type = e1000_phy_82580; phy_type = e1000_phy_82580;
break; break;
@ -3067,8 +3042,7 @@ s32 e1000_determine_phy_address(struct e1000_hw *hw)
e1000_get_phy_id(hw); e1000_get_phy_id(hw);
phy_type = e1000_get_phy_type_from_id(hw->phy.id); phy_type = e1000_get_phy_type_from_id(hw->phy.id);
/* /* If phy_type is valid, break - we found our
* If phy_type is valid, break - we found our
* PHY address * PHY address
*/ */
if (phy_type != e1000_phy_unknown) if (phy_type != e1000_phy_unknown)
@ -3130,8 +3104,7 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
if (offset > MAX_PHY_MULTI_PAGE_REG) { if (offset > MAX_PHY_MULTI_PAGE_REG) {
u32 page_shift, page_select; u32 page_shift, page_select;
/* /* Page select is register 31 for phy address 1 and 22 for
* Page select is register 31 for phy address 1 and 22 for
* phy address 2 and 3. Page select is shifted only for * phy address 2 and 3. Page select is shifted only for
* phy address 1. * phy address 1.
*/ */
@ -3191,8 +3164,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
if (offset > MAX_PHY_MULTI_PAGE_REG) { if (offset > MAX_PHY_MULTI_PAGE_REG) {
u32 page_shift, page_select; u32 page_shift, page_select;
/* /* Page select is register 31 for phy address 1 and 22 for
* Page select is register 31 for phy address 1 and 22 for
* phy address 2 and 3. Page select is shifted only for * phy address 2 and 3. Page select is shifted only for
* phy address 1. * phy address 1.
*/ */
@ -3249,7 +3221,6 @@ s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data)
hw->phy.addr = 1; hw->phy.addr = 1;
if (offset > MAX_PHY_MULTI_PAGE_REG) { if (offset > MAX_PHY_MULTI_PAGE_REG) {
/* Page is shifted left, PHY expects (page x 32) */ /* Page is shifted left, PHY expects (page x 32) */
ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT,
page); page);
@ -3346,8 +3317,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
return ret_val; return ret_val;
} }
/* /* Enable both PHY wakeup mode and Wakeup register page writes.
* Enable both PHY wakeup mode and Wakeup register page writes.
* Prevent a power state change by disabling ME and Host PHY wakeup. * Prevent a power state change by disabling ME and Host PHY wakeup.
*/ */
temp = *phy_reg; temp = *phy_reg;
@ -3361,8 +3331,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
return ret_val; return ret_val;
} }
/* /* Select Host Wakeup Registers page - caller now able to write
* Select Host Wakeup Registers page - caller now able to write
* registers on the Wakeup registers page * registers on the Wakeup registers page
*/ */
return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT)); return e1000_set_page_igp(hw, (BM_WUC_PAGE << IGP_PAGE_SHIFT));
@ -3381,7 +3350,7 @@ s32 e1000_enable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
**/ **/
s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg) s32 e1000_disable_phy_wakeup_reg_access_bm(struct e1000_hw *hw, u16 *phy_reg)
{ {
s32 ret_val = E1000_SUCCESS; s32 ret_val;
DEBUGFUNC("e1000_disable_phy_wakeup_reg_access_bm"); DEBUGFUNC("e1000_disable_phy_wakeup_reg_access_bm");
@ -3434,6 +3403,7 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
{ {
s32 ret_val; s32 ret_val;
u16 reg = BM_PHY_REG_NUM(offset); u16 reg = BM_PHY_REG_NUM(offset);
u16 page = BM_PHY_REG_PAGE(offset);
u16 phy_reg = 0; u16 phy_reg = 0;
DEBUGFUNC("e1000_access_phy_wakeup_reg_bm"); DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
@ -3687,8 +3657,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
if (page == HV_INTC_FC_PAGE_START) if (page == HV_INTC_FC_PAGE_START)
page = 0; page = 0;
/* /* Workaround MDIO accesses being disabled after entering IEEE
* Workaround MDIO accesses being disabled after entering IEEE
* Power Down (when bit 11 of the PHY Control register is set) * Power Down (when bit 11 of the PHY Control register is set)
*/ */
if ((hw->phy.type == e1000_phy_82578) && if ((hw->phy.type == e1000_phy_82578) &&
@ -3801,8 +3770,8 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
u16 *data, bool read) u16 *data, bool read)
{ {
s32 ret_val; s32 ret_val;
u32 addr_reg = 0; u32 addr_reg;
u32 data_reg = 0; u32 data_reg;
DEBUGFUNC("e1000_access_phy_debug_regs_hv"); DEBUGFUNC("e1000_access_phy_debug_regs_hv");
@ -3875,8 +3844,8 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
/* flush the packets in the fifo buffer */ /* flush the packets in the fifo buffer */
ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
HV_MUX_DATA_CTRL_GEN_TO_MAC | (HV_MUX_DATA_CTRL_GEN_TO_MAC |
HV_MUX_DATA_CTRL_FORCE_SPEED); HV_MUX_DATA_CTRL_FORCE_SPEED));
if (ret_val) if (ret_val)
return ret_val; return ret_val;
@ -4044,7 +4013,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
I82577_DSTATUS_CABLE_LENGTH_SHIFT; I82577_DSTATUS_CABLE_LENGTH_SHIFT;
if (length == E1000_CABLE_LENGTH_UNDEFINED) if (length == E1000_CABLE_LENGTH_UNDEFINED)
ret_val = -E1000_ERR_PHY; return -E1000_ERR_PHY;
phy->cable_length = length; phy->cable_length = length;
@ -4113,3 +4082,4 @@ release:
hw->phy.ops.release(hw); hw->phy.ops.release(hw);
return ret_val; return ret_val;
} }

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -78,13 +78,11 @@ s32 e1000_read_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active); s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active);
s32 e1000_setup_copper_link_generic(struct e1000_hw *hw); s32 e1000_setup_copper_link_generic(struct e1000_hw *hw);
s32 e1000_wait_autoneg_generic(struct e1000_hw *hw);
s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_igp_locked(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success); u32 usec_interval, bool *success);
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw); s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
@ -127,7 +125,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ #define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */
#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */
#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */ #define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */
#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */
#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ #define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */
#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */
#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ #define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */
@ -147,7 +144,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
/* BM/HV Specific Registers */ /* BM/HV Specific Registers */
#define BM_PORT_CTRL_PAGE 769 #define BM_PORT_CTRL_PAGE 769
#define BM_PCIE_PAGE 770
#define BM_WUC_PAGE 800 #define BM_WUC_PAGE 800
#define BM_WUC_ADDRESS_OPCODE 0x11 #define BM_WUC_ADDRESS_OPCODE 0x11
#define BM_WUC_DATA_OPCODE 0x12 #define BM_WUC_DATA_OPCODE 0x12
@ -188,7 +184,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define I82577_PHY_STATUS2_MDIX 0x0800 #define I82577_PHY_STATUS2_MDIX 0x0800
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300 #define I82577_PHY_STATUS2_SPEED_MASK 0x0300
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200 #define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
/* I82577 PHY Control 2 */ /* I82577 PHY Control 2 */
#define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200 #define I82577_PHY_CTRL2_MANUAL_MDIX 0x0200
@ -204,14 +199,13 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */ #define E1000_82580_PM_SPD 0x0001 /* Smart Power Down */
#define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */ #define E1000_82580_PM_D0_LPLU 0x0002 /* For D0a states */
#define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */ #define E1000_82580_PM_D3_LPLU 0x0004 /* For all other states */
#define E1000_82580_PM_GO_LINKD 0x0020 /* Go Link Disconnect */
/* BM PHY Copper Specific Control 1 */ /* BM PHY Copper Specific Control 1 */
#define BM_CS_CTRL1 16 #define BM_CS_CTRL1 16
#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */
/* BM PHY Copper Specific Status */ /* BM PHY Copper Specific Status */
#define BM_CS_STATUS 17 #define BM_CS_STATUS 17
#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */
#define BM_CS_STATUS_LINK_UP 0x0400 #define BM_CS_STATUS_LINK_UP 0x0400
#define BM_CS_STATUS_RESOLVED 0x0800 #define BM_CS_STATUS_RESOLVED 0x0800
#define BM_CS_STATUS_SPEED_MASK 0xC000 #define BM_CS_STATUS_SPEED_MASK 0xC000
@ -257,9 +251,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define IGP02E1000_AGC_LENGTH_MASK 0x7F #define IGP02E1000_AGC_LENGTH_MASK 0x7F
#define IGP02E1000_AGC_RANGE 15 #define IGP02E1000_AGC_RANGE 15
#define IGP03E1000_PHY_MISC_CTRL 0x1B
#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */
#define E1000_CABLE_LENGTH_UNDEFINED 0xFF #define E1000_CABLE_LENGTH_UNDEFINED 0xFF
#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000 #define E1000_KMRNCTRLSTA_OFFSET 0x001F0000
@ -272,7 +263,7 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
#define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */ #define E1000_KMRNCTRLSTA_IBIST_DISABLE 0x0200 /* Kumeran IBIST Disable */
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ #define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
#define E1000_KMRNCTRLSTA_K1_CONFIG 0x7 #define E1000_KMRNCTRLSTA_K1_CONFIG 0x7
#define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 #define E1000_KMRNCTRLSTA_K1_ENABLE 0x0002 /* enable K1 */
#define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */ #define E1000_KMRNCTRLSTA_HD_CTRL 0x10 /* Kumeran HD Control */
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 #define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
@ -286,7 +277,6 @@ s32 e1000_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
/* IFE PHY Special Control */ /* IFE PHY Special Control */
#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 #define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010
#define IFE_PSC_FORCE_POLARITY 0x0020 #define IFE_PSC_FORCE_POLARITY 0x0020
#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100
/* IFE PHY Special Control and LED Control */ /* IFE PHY Special Control and LED Control */
#define IFE_PSCL_PROBE_MODE 0x0020 #define IFE_PSCL_PROBE_MODE 0x0020

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -55,9 +55,11 @@
#define E1000_SCTL 0x00024 /* SerDes Control - RW */ #define E1000_SCTL 0x00024 /* SerDes Control - RW */
#define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */ #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
#define E1000_FEXT 0x0002C /* Future Extended - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */
#define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */
#define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */
#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */
#define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */
#define E1000_FCT 0x00030 /* Flow Control Type - RW */ #define E1000_FCT 0x00030 /* Flow Control Type - RW */
#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */ #define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */
#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ #define E1000_VET 0x00038 /* VLAN Ether Type - RW */
@ -70,6 +72,7 @@
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */ #define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
#define E1000_SVCR 0x000F0 #define E1000_SVCR 0x000F0
#define E1000_SVT 0x000F4 #define E1000_SVT 0x000F4
#define E1000_LPIC 0x000FC /* Low Power IDLE control */
#define E1000_RCTL 0x00100 /* Rx Control - RW */ #define E1000_RCTL 0x00100 /* Rx Control - RW */
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */ #define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
@ -97,6 +100,7 @@
#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ #define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */ #define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_PBECCSTS 0x0100C /* Packet Buffer ECC Status - RW */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ #define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ #define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ #define E1000_FLASHT 0x01028 /* FLASH Timer Register */
@ -129,7 +133,11 @@
#define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
#define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ #define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
#define E1000_RDFPCQ(_n) (0x02430 + (0x4 * (_n))) #define E1000_RDFH 0x02410 /* Rx Data FIFO Head - RW */
#define E1000_RDFT 0x02418 /* Rx Data FIFO Tail - RW */
#define E1000_RDFHS 0x02420 /* Rx Data FIFO Head Saved - RW */
#define E1000_RDFTS 0x02428 /* Rx Data FIFO Tail Saved - RW */
#define E1000_RDFPC 0x02430 /* Rx Data FIFO Packet Count - RW */
#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */ #define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */
#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ #define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */
/* Split and Replication Rx Control - RW */ /* Split and Replication Rx Control - RW */
@ -200,8 +208,7 @@
/* Queues packet buffer size masks where _n can be 0-3 and _s 0-63 [kB] */ /* 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)) #define E1000_I210_TXPBS_SIZE(_n, _s) ((_s) << (6 * _n))
/* /* Convenience macros
* Convenience macros
* *
* Note: "_n" is the queue number of the register to be written to. * Note: "_n" is the queue number of the register to be written to.
* *
@ -413,8 +420,7 @@
#define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n))) #define E1000_LSECTXKEY1(_n) (0x0B030 + (0x04 * (_n)))
#define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */ #define E1000_LSECRXSA(_n) (0x0B310 + (0x04 * (_n))) /* Rx SAs - RW */
#define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */ #define E1000_LSECRXPN(_n) (0x0B330 + (0x04 * (_n))) /* Rx SAs - RW */
/* /* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
* LinkSec Rx Keys - where _n is the SA no. and _m the 4 dwords of the 128 bit
* key - RW. * key - RW.
*/ */
#define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m))) #define E1000_LSECRXKEY(_n, _m) (0x0B350 + (0x10 * (_n)) + (0x04 * (_m)))
@ -454,7 +460,6 @@
#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */ #define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */
#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */ #define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */
#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Pg - RW */ #define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Pg - RW */
#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Pkt Cnt - RW */
#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */ #define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */
#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */ #define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */
#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ #define E1000_RFCTL 0x05008 /* Receive Filter Control*/
@ -489,7 +494,6 @@
#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */ #define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */
#define E1000_MDPHYA 0x0003C /* PHY address - RW */
#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ #define E1000_MANC2H 0x05860 /* Management Control To Host - RW */
/* Management Decision Filters */ /* Management Decision Filters */
#define E1000_MDEF(_n) (0x05890 + (4 * (_n))) #define E1000_MDEF(_n) (0x05890 + (4 * (_n)))
@ -522,15 +526,6 @@
#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/ #define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate INTR Ext*/
#define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */ #define E1000_IMIRVP 0x05AC0 /* Immediate INT Rx VLAN Priority -RW */
#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */ #define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Alloc Reg -RW */
/* MSI-X Table entry addr low reg - RW */
#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10))
/* MSI-X Table entry addr upper reg - RW */
#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10))
/* MSI-X Table entry message reg - RW */
#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10))
/* MSI-X Table entry vector ctrl reg - RW */
#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10))
#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */
#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */ #define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW */
#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */ #define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW */
#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ #define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
@ -580,8 +575,12 @@
#define E1000_SYSTIML 0x0B600 /* System time register Low - RO */ #define E1000_SYSTIML 0x0B600 /* System time register Low - RO */
#define E1000_SYSTIMH 0x0B604 /* System time register High - RO */ #define E1000_SYSTIMH 0x0B604 /* System time register High - RO */
#define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */ #define E1000_TIMINCA 0x0B608 /* Increment attributes register - RW */
#define E1000_TIMADJL 0x0B60C /* Time sync time adjustment offset Low - RW */
#define E1000_TIMADJH 0x0B610 /* Time sync time adjustment offset High - RW */
#define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */ #define E1000_TSAUXC 0x0B640 /* Timesync Auxiliary Control register */
#define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */ #define E1000_SYSTIMR 0x0B6F8 /* System time register Residue */
#define E1000_TSICR 0x0B66C /* Interrupt Cause Register */
#define E1000_TSIM 0x0B674 /* Interrupt Mask Register */
#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */ #define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Msg Type - RW */
#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ #define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */
@ -671,8 +670,6 @@
#define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */ #define E1000_O2BGPTC 0x08FE4 /* OS2BMC packets received by BMC */
#define E1000_O2BSPC 0x0415C /* OS2BMC packets transmitted by host */ #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 */ #define E1000_DOBFFCTL 0x3F24 /* DMA OBFF Control Register */

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2011, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -94,7 +94,7 @@ int em_display_debug_stats = 0;
/********************************************************************* /*********************************************************************
* Driver version: * Driver version:
*********************************************************************/ *********************************************************************/
char em_driver_version[] = "7.3.2"; char em_driver_version[] = "7.3.7";
/********************************************************************* /*********************************************************************
* PCI Device ID Table * PCI Device ID Table
@ -172,6 +172,12 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_PCH_D_HV_DC, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_PCH_D_HV_DC, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH2_LV_LM, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_PCH2_LV_LM, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH2_LV_V, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_PCH2_LV_V, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_LPT_I217_LM, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_LPT_I217_V, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_LPTLP_I218_LM,
PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_LPTLP_I218_V,
PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */ /* required last entry */
{ 0, 0, 0, 0, 0} { 0, 0, 0, 0, 0}
}; };
@ -520,7 +526,8 @@ em_attach(device_t dev)
(hw->mac.type == e1000_ich9lan) || (hw->mac.type == e1000_ich9lan) ||
(hw->mac.type == e1000_ich10lan) || (hw->mac.type == e1000_ich10lan) ||
(hw->mac.type == e1000_pchlan) || (hw->mac.type == e1000_pchlan) ||
(hw->mac.type == e1000_pch2lan)) { (hw->mac.type == e1000_pch2lan) ||
(hw->mac.type == e1000_pch_lpt)) {
int rid = EM_BAR_TYPE_FLASH; int rid = EM_BAR_TYPE_FLASH;
adapter->flash = bus_alloc_resource_any(dev, adapter->flash = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE); SYS_RES_MEMORY, &rid, RF_ACTIVE);
@ -605,8 +612,8 @@ em_attach(device_t dev)
* Set the frame limits assuming * Set the frame limits assuming
* standard ethernet sized frames. * standard ethernet sized frames.
*/ */
adapter->max_frame_size = ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE; adapter->hw.mac.max_frame_size =
adapter->min_frame_size = ETH_ZLEN + ETHERNET_FCS_SIZE; ETHERMTU + ETHER_HDR_LEN + ETHERNET_FCS_SIZE;
/* /*
* This controls when hardware reports transmit completion * This controls when hardware reports transmit completion
@ -907,19 +914,17 @@ em_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr, struct mbuf *m)
enq = 0; enq = 0;
if (m != NULL) { if (m != NULL) {
err = drbr_enqueue(ifp, txr->br, m); err = drbr_enqueue(ifp, txr->br, m);
if (err) { if (err)
return (err); return (err);
}
} }
/* Process the queue */ /* Process the queue */
while ((next = drbr_peek(ifp, txr->br)) != NULL) { while ((next = drbr_peek(ifp, txr->br)) != NULL) {
if ((err = em_xmit(txr, &next)) != 0) { if ((err = em_xmit(txr, &next)) != 0) {
if (next == NULL) { if (next == NULL)
drbr_advance(ifp, txr->br); drbr_advance(ifp, txr->br);
} else { else
drbr_putback(ifp, txr->br, next); drbr_putback(ifp, txr->br, next);
}
break; break;
} }
drbr_advance(ifp, txr->br); drbr_advance(ifp, txr->br);
@ -1108,6 +1113,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
case e1000_ich9lan: case e1000_ich9lan:
case e1000_ich10lan: case e1000_ich10lan:
case e1000_pch2lan: case e1000_pch2lan:
case e1000_pch_lpt:
case e1000_82574: case e1000_82574:
case e1000_82583: case e1000_82583:
case e1000_80003es2lan: /* 9K Jumbo Frame size */ case e1000_80003es2lan: /* 9K Jumbo Frame size */
@ -1131,7 +1137,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
} }
ifp->if_mtu = ifr->ifr_mtu; ifp->if_mtu = ifr->ifr_mtu;
adapter->max_frame_size = adapter->hw.mac.max_frame_size =
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN; ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
em_init_locked(adapter); em_init_locked(adapter);
EM_CORE_UNLOCK(adapter); EM_CORE_UNLOCK(adapter);
@ -1326,9 +1332,9 @@ em_init_locked(struct adapter *adapter)
** Figure out the desired mbuf ** Figure out the desired mbuf
** pool for doing jumbos ** pool for doing jumbos
*/ */
if (adapter->max_frame_size <= 2048) if (adapter->hw.mac.max_frame_size <= 2048)
adapter->rx_mbuf_sz = MCLBYTES; adapter->rx_mbuf_sz = MCLBYTES;
else if (adapter->max_frame_size <= 4096) else if (adapter->hw.mac.max_frame_size <= 4096)
adapter->rx_mbuf_sz = MJUMPAGESIZE; adapter->rx_mbuf_sz = MJUMPAGESIZE;
else else
adapter->rx_mbuf_sz = MJUM9BYTES; adapter->rx_mbuf_sz = MJUM9BYTES;
@ -2817,17 +2823,18 @@ em_reset(struct adapter *adapter)
case e1000_ich9lan: case e1000_ich9lan:
case e1000_ich10lan: case e1000_ich10lan:
/* Boost Receive side for jumbo frames */ /* Boost Receive side for jumbo frames */
if (adapter->max_frame_size > 4096) if (adapter->hw.mac.max_frame_size > 4096)
pba = E1000_PBA_14K; pba = E1000_PBA_14K;
else else
pba = E1000_PBA_10K; pba = E1000_PBA_10K;
break; break;
case e1000_pchlan: case e1000_pchlan:
case e1000_pch2lan: case e1000_pch2lan:
case e1000_pch_lpt:
pba = E1000_PBA_26K; pba = E1000_PBA_26K;
break; break;
default: default:
if (adapter->max_frame_size > 8192) if (adapter->hw.mac.max_frame_size > 8192)
pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */ pba = E1000_PBA_40K; /* 40K for Rx, 24K for Tx */
else else
pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */ pba = E1000_PBA_48K; /* 48K for Rx, 16K for Tx */
@ -2850,7 +2857,7 @@ em_reset(struct adapter *adapter)
*/ */
rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 ); rx_buffer_size = ((E1000_READ_REG(hw, E1000_PBA) & 0xffff) << 10 );
hw->fc.high_water = rx_buffer_size - hw->fc.high_water = rx_buffer_size -
roundup2(adapter->max_frame_size, 1024); roundup2(adapter->hw.mac.max_frame_size, 1024);
hw->fc.low_water = hw->fc.high_water - 1500; hw->fc.low_water = hw->fc.high_water - 1500;
if (adapter->fc) /* locally set flow control value? */ if (adapter->fc) /* locally set flow control value? */
@ -2881,6 +2888,7 @@ em_reset(struct adapter *adapter)
hw->fc.refresh_time = 0x1000; hw->fc.refresh_time = 0x1000;
break; break;
case e1000_pch2lan: case e1000_pch2lan:
case e1000_pch_lpt:
hw->fc.high_water = 0x5C20; hw->fc.high_water = 0x5C20;
hw->fc.low_water = 0x5048; hw->fc.low_water = 0x5048;
hw->fc.pause_time = 0x0650; hw->fc.pause_time = 0x0650;
@ -4341,7 +4349,7 @@ em_initialize_receive_unit(struct adapter *adapter)
E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3); E1000_WRITE_REG(hw, E1000_RXDCTL(0), rxdctl | 3);
} }
if (adapter->hw.mac.type == e1000_pch2lan) { if (adapter->hw.mac.type >= e1000_pch2lan) {
if (ifp->if_mtu > ETHERMTU) if (ifp->if_mtu > ETHERMTU)
e1000_lv_jumbo_workaround_ich8lan(hw, TRUE); e1000_lv_jumbo_workaround_ich8lan(hw, TRUE);
else else
@ -4475,7 +4483,7 @@ em_rxeof(struct rx_ring *rxr, int count, int *done)
ifp->if_ipackets++; ifp->if_ipackets++;
em_receive_checksum(cur, sendmp); em_receive_checksum(cur, sendmp);
#ifndef __NO_STRICT_ALIGNMENT #ifndef __NO_STRICT_ALIGNMENT
if (adapter->max_frame_size > if (adapter->hw.mac.max_frame_size >
(MCLBYTES - ETHER_ALIGN) && (MCLBYTES - ETHER_ALIGN) &&
em_fixup_rx(rxr) != 0) em_fixup_rx(rxr) != 0)
goto skip; goto skip;

View File

@ -1,6 +1,6 @@
/****************************************************************************** /******************************************************************************
Copyright (c) 2001-2012, Intel Corporation Copyright (c) 2001-2013, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
@ -100,7 +100,7 @@ int igb_display_debug_stats = 0;
/********************************************************************* /*********************************************************************
* Driver version: * Driver version:
*********************************************************************/ *********************************************************************/
char igb_driver_version[] = "version - 2.3.5"; char igb_driver_version[] = "version - 2.3.9";
/********************************************************************* /*********************************************************************
@ -949,7 +949,8 @@ igb_start(struct ifnet *ifp)
#else /* __FreeBSD_version >= 800000 */ #else /* __FreeBSD_version >= 800000 */
/* /*
** Multiqueue Transmit driver ** Multiqueue Transmit Entry:
** quick turnaround to the stack
** **
*/ */
static int static int
@ -965,25 +966,11 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
i = m->m_pkthdr.flowid % adapter->num_queues; i = m->m_pkthdr.flowid % adapter->num_queues;
else else
i = curcpu % adapter->num_queues; i = curcpu % adapter->num_queues;
txr = &adapter->tx_rings[i]; txr = &adapter->tx_rings[i];
que = &adapter->queues[i]; que = &adapter->queues[i];
if (((txr->queue_status & IGB_QUEUE_DEPLETED) == 0) &&
IGB_TX_TRYLOCK(txr)) { err = drbr_enqueue(ifp, txr->br, m);
/* taskqueue_enqueue(que->tq, &txr->txq_task);
** Try to queue first to avoid
** out-of-order delivery, but
** settle for it if that fails
*/
if (m != NULL)
drbr_enqueue(ifp, txr->br, m);
err = igb_mq_start_locked(ifp, txr);
IGB_TX_UNLOCK(txr);
} else {
if (m != NULL)
err = drbr_enqueue(ifp, txr->br, m);
taskqueue_enqueue(que->tq, &txr->txq_task);
}
return (err); return (err);
} }
@ -998,9 +985,8 @@ igb_mq_start_locked(struct ifnet *ifp, struct tx_ring *txr)
IGB_TX_LOCK_ASSERT(txr); IGB_TX_LOCK_ASSERT(txr);
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) || if (((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) ||
(txr->queue_status & IGB_QUEUE_DEPLETED) ||
adapter->link_active == 0) adapter->link_active == 0)
return (err); return (ENETDOWN);
enq = 0; enq = 0;
@ -1702,7 +1688,6 @@ static void
igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
{ {
struct adapter *adapter = ifp->if_softc; struct adapter *adapter = ifp->if_softc;
u_char fiber_type = IFM_1000_SX;
INIT_DEBUGOUT("igb_media_status: begin"); INIT_DEBUGOUT("igb_media_status: begin");
@ -1719,26 +1704,31 @@ igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
ifmr->ifm_status |= IFM_ACTIVE; ifmr->ifm_status |= IFM_ACTIVE;
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) || switch (adapter->link_speed) {
(adapter->hw.phy.media_type == e1000_media_type_internal_serdes)) case 10:
ifmr->ifm_active |= fiber_type | IFM_FDX; ifmr->ifm_active |= IFM_10_T;
else { break;
switch (adapter->link_speed) { case 100:
case 10: /*
ifmr->ifm_active |= IFM_10_T; ** Support for 100Mb SFP - these are Fiber
break; ** but the media type appears as serdes
case 100: */
ifmr->ifm_active |= IFM_100_TX; if (adapter->hw.phy.media_type ==
break; e1000_media_type_internal_serdes)
case 1000: ifmr->ifm_active |= IFM_100_FX;
ifmr->ifm_active |= IFM_1000_T;
break;
}
if (adapter->link_duplex == FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
else else
ifmr->ifm_active |= IFM_HDX; ifmr->ifm_active |= IFM_100_TX;
break;
case 1000:
ifmr->ifm_active |= IFM_1000_T;
break;
} }
if (adapter->link_duplex == FULL_DUPLEX)
ifmr->ifm_active |= IFM_FDX;
else
ifmr->ifm_active |= IFM_HDX;
IGB_CORE_UNLOCK(adapter); IGB_CORE_UNLOCK(adapter);
} }
@ -2241,11 +2231,13 @@ timeout:
static void static void
igb_update_link_status(struct adapter *adapter) igb_update_link_status(struct adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
struct ifnet *ifp = adapter->ifp; struct e1000_fc_info *fc = &hw->fc;
device_t dev = adapter->dev; struct ifnet *ifp = adapter->ifp;
struct tx_ring *txr = adapter->tx_rings; device_t dev = adapter->dev;
u32 link_check, thstat, ctrl; struct tx_ring *txr = adapter->tx_rings;
u32 link_check, thstat, ctrl;
char *flowctl = NULL;
link_check = thstat = ctrl = 0; link_check = thstat = ctrl = 0;
@ -2283,15 +2275,33 @@ igb_update_link_status(struct adapter *adapter)
ctrl = E1000_READ_REG(hw, E1000_CTRL_EXT); ctrl = E1000_READ_REG(hw, E1000_CTRL_EXT);
} }
/* Get the flow control for display */
switch (fc->current_mode) {
case e1000_fc_rx_pause:
flowctl = "RX";
break;
case e1000_fc_tx_pause:
flowctl = "TX";
break;
case e1000_fc_full:
flowctl = "Full";
break;
case e1000_fc_none:
default:
flowctl = "None";
break;
}
/* Now we check if a transition has happened */ /* Now we check if a transition has happened */
if (link_check && (adapter->link_active == 0)) { if (link_check && (adapter->link_active == 0)) {
e1000_get_speed_and_duplex(&adapter->hw, e1000_get_speed_and_duplex(&adapter->hw,
&adapter->link_speed, &adapter->link_duplex); &adapter->link_speed, &adapter->link_duplex);
if (bootverbose) if (bootverbose)
device_printf(dev, "Link is up %d Mbps %s\n", device_printf(dev, "Link is up %d Mbps %s,"
" Flow Control: %s\n",
adapter->link_speed, adapter->link_speed,
((adapter->link_duplex == FULL_DUPLEX) ? ((adapter->link_duplex == FULL_DUPLEX) ?
"Full Duplex" : "Half Duplex")); "Full Duplex" : "Half Duplex"), flowctl);
adapter->link_active = 1; adapter->link_active = 1;
ifp->if_baudrate = adapter->link_speed * 1000000; ifp->if_baudrate = adapter->link_speed * 1000000;
if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) && if ((ctrl & E1000_CTRL_EXT_LINK_MODE_GMII) &&

View File

@ -3782,10 +3782,6 @@ lem_setup_vlan_hw_support(struct adapter *adapter)
reg &= ~E1000_RCTL_CFIEN; reg &= ~E1000_RCTL_CFIEN;
reg |= E1000_RCTL_VFE; reg |= E1000_RCTL_VFE;
E1000_WRITE_REG(hw, E1000_RCTL, reg); E1000_WRITE_REG(hw, E1000_RCTL, reg);
/* Update the frame size */
E1000_WRITE_REG(&adapter->hw, E1000_RLPML,
adapter->max_frame_size + VLAN_TAG_SIZE);
} }
static void static void