mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-21 17:25:09 +00:00
Updates for both the em and igb drivers, add support
for multiqueue tx, shared code updates, new device support, and some bug fixes.
This commit is contained in:
parent
3ae218fe9c
commit
9d81738f8f
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=194865
|
@ -57,6 +57,7 @@ static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw);
|
|||
static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw);
|
||||
static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw);
|
||||
static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw);
|
||||
static s32 e1000_read_mac_addr_82540(struct e1000_hw *hw);
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_82540 - Init PHY func ptrs.
|
||||
|
@ -229,6 +230,8 @@ static s32 e1000_init_mac_params_82540(struct e1000_hw *hw)
|
|||
mac->ops.clear_vfta = e1000_clear_vfta_generic;
|
||||
/* setting MTA */
|
||||
mac->ops.mta_set = e1000_mta_set_generic;
|
||||
/* read mac address */
|
||||
mac->ops.read_mac_addr = e1000_read_mac_addr_82540;
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000_id_led_init_generic;
|
||||
/* setup LED */
|
||||
|
@ -676,3 +679,45 @@ static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
|
|||
E1000_READ_REG(hw, E1000_MGTPTC);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_mac_addr_82540 - Read device MAC address
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Reads the device MAC address from the EEPROM and stores the value.
|
||||
* Since devices with two ports use the same EEPROM, we increment the
|
||||
* last bit in the MAC address for the second port.
|
||||
*
|
||||
* This version is being used over generic because of customer issues
|
||||
* with VmWare and Virtual Box when using generic. It seems in
|
||||
* the emulated 82545, RAR[0] does NOT have a valid address after a
|
||||
* reset, this older method works and using this breaks nothing for
|
||||
* these legacy adapters.
|
||||
**/
|
||||
s32 e1000_read_mac_addr_82540(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 offset, nvm_data, i;
|
||||
|
||||
DEBUGFUNC("e1000_read_mac_addr");
|
||||
|
||||
for (i = 0; i < ETH_ADDR_LEN; i += 2) {
|
||||
offset = i >> 1;
|
||||
ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("NVM Read Error\n");
|
||||
goto out;
|
||||
}
|
||||
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
|
||||
hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
|
||||
}
|
||||
|
||||
/* Flip last bit of mac address if we're on second port */
|
||||
if (hw->bus.func == E1000_FUNC_1)
|
||||
hw->mac.perm_addr[5] ^= 1;
|
||||
|
||||
for (i = 0; i < ETH_ADDR_LEN; i++)
|
||||
hw->mac.addr[i] = hw->mac.perm_addr[i];
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
|
|
@ -377,6 +377,7 @@ static s32 e1000_reset_hw_82541(struct e1000_hw *hw)
|
|||
static s32 e1000_init_hw_82541(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541;
|
||||
u32 i, txdctl;
|
||||
s32 ret_val;
|
||||
|
||||
|
@ -388,6 +389,13 @@ static s32 e1000_init_hw_82541(struct e1000_hw *hw)
|
|||
DEBUGOUT("Error initializing identification LED\n");
|
||||
/* This is not fatal and we should not stop init due to this */
|
||||
}
|
||||
|
||||
/* Storing the Speed Power Down value for later use */
|
||||
ret_val = hw->phy.ops.read_reg(hw,
|
||||
IGP01E1000_GMII_FIFO,
|
||||
&dev_spec->spd_default);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disabling VLAN filtering */
|
||||
DEBUGOUT("Initializing the IEEE VLAN\n");
|
||||
|
@ -425,6 +433,7 @@ static s32 e1000_init_hw_82541(struct e1000_hw *hw)
|
|||
*/
|
||||
e1000_clear_hw_cntrs_82541(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
* 82573L Gigabit Ethernet Controller
|
||||
* 82574L Gigabit Network Connection
|
||||
* 82574L Gigabit Network Connection
|
||||
* 82583V Gigabit Network Connection
|
||||
*/
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
@ -154,6 +155,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
|||
goto out;
|
||||
}
|
||||
break;
|
||||
case e1000_82583:
|
||||
case e1000_82574:
|
||||
phy->type = e1000_phy_bm;
|
||||
phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
|
||||
|
@ -215,6 +217,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
|
|||
switch (hw->mac.type) {
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
if (((eecd >> 15) & 0x3) == 0x3) {
|
||||
nvm->type = e1000_nvm_flash_hw;
|
||||
nvm->word_size = 2048;
|
||||
|
@ -264,6 +267,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 swsm = 0;
|
||||
u32 swsm2 = 0;
|
||||
bool force_clear_smbi = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_init_mac_params_82571");
|
||||
|
||||
|
@ -304,6 +310,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
switch (hw->mac.type) {
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
mac->ops.set_lan_id = e1000_set_lan_id_single_port;
|
||||
break;
|
||||
default:
|
||||
|
@ -339,6 +346,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
/* check management mode */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
mac->ops.check_mng_mode = e1000_check_mng_mode_82574;
|
||||
break;
|
||||
default:
|
||||
|
@ -366,6 +374,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
/* turn on/off LED */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
mac->ops.led_on = e1000_led_on_82574;
|
||||
break;
|
||||
default:
|
||||
|
@ -381,6 +390,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
|
|||
? e1000_get_speed_and_duplex_copper_generic
|
||||
: e1000_get_speed_and_duplex_fiber_serdes_generic;
|
||||
|
||||
/*
|
||||
* Ensure that the inter-port SWSM.SMBI lock bit is clear before
|
||||
* first NVM or PHY acess. This should be done for single-port
|
||||
* devices, and for one port only on dual-port devices so that
|
||||
* for those devices we can still use the SMBI lock to synchronize
|
||||
* inter-port accesses to the PHY & NVM.
|
||||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82571:
|
||||
case e1000_82572:
|
||||
swsm2 = E1000_READ_REG(hw, E1000_SWSM2);
|
||||
|
||||
if (!(swsm2 & E1000_SWSM2_LOCK)) {
|
||||
/* Only do this for the first interface on this card */
|
||||
E1000_WRITE_REG(hw, E1000_SWSM2,
|
||||
swsm2 | E1000_SWSM2_LOCK);
|
||||
force_clear_smbi = TRUE;
|
||||
} else
|
||||
force_clear_smbi = FALSE;
|
||||
break;
|
||||
default:
|
||||
force_clear_smbi = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (force_clear_smbi) {
|
||||
/* Make sure SWSM.SMBI is clear */
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
if (swsm & E1000_SWSM_SMBI) {
|
||||
/* This bit should not be set on a first interface, and
|
||||
* indicates that the bootagent or EFI code has
|
||||
* improperly left this bit enabled
|
||||
*/
|
||||
DEBUGOUT("Please update your 82571 Bootagent\n");
|
||||
}
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm & ~E1000_SWSM_SMBI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialze device specific counter of SMBI acquisition
|
||||
* timeouts.
|
||||
*/
|
||||
hw->dev_spec._82571.smb_counter = 0;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
@ -430,6 +483,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
|||
ret_val = e1000_get_phy_id(hw);
|
||||
break;
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
@ -458,17 +512,43 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
|
|||
*
|
||||
* Acquire the HW semaphore to access the PHY or NVM
|
||||
**/
|
||||
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
s32 timeout = hw->nvm.word_size + 1;
|
||||
s32 sw_timeout = hw->nvm.word_size + 1;
|
||||
s32 fw_timeout = hw->nvm.word_size + 1;
|
||||
s32 i = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_hw_semaphore_82571");
|
||||
|
||||
/*
|
||||
* If we have timedout 3 times on trying to acquire
|
||||
* the inter-port SMBI semaphore, there is old code
|
||||
* operating on the other port, and it is not
|
||||
* releasing SMBI. Modify the number of times that
|
||||
* we try for the semaphore to interwork with this
|
||||
* older code.
|
||||
*/
|
||||
if (hw->dev_spec._82571.smb_counter > 2)
|
||||
sw_timeout = 1;
|
||||
|
||||
/* Get the SW semaphore */
|
||||
while (i < sw_timeout) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
if (!(swsm & E1000_SWSM_SMBI))
|
||||
break;
|
||||
|
||||
usec_delay(50);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i == sw_timeout) {
|
||||
DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
|
||||
hw->dev_spec._82571.smb_counter++;
|
||||
}
|
||||
/* Get the FW semaphore. */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
for (i = 0; i < fw_timeout; i++) {
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI);
|
||||
|
||||
|
@ -479,9 +559,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
|||
usec_delay(50);
|
||||
}
|
||||
|
||||
if (i == timeout) {
|
||||
if (i == fw_timeout) {
|
||||
/* Release semaphores */
|
||||
e1000_put_hw_semaphore_generic(hw);
|
||||
e1000_put_hw_semaphore_82571(hw);
|
||||
DEBUGOUT("Driver can't access the NVM\n");
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
goto out;
|
||||
|
@ -497,15 +577,15 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
|
|||
*
|
||||
* Release hardware semaphore used to access the PHY or NVM
|
||||
**/
|
||||
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 swsm;
|
||||
|
||||
DEBUGFUNC("e1000_put_hw_semaphore_82571");
|
||||
DEBUGFUNC("e1000_put_hw_semaphore_generic");
|
||||
|
||||
swsm = E1000_READ_REG(hw, E1000_SWSM);
|
||||
|
||||
swsm &= ~E1000_SWSM_SWESMBI;
|
||||
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm);
|
||||
}
|
||||
|
@ -531,6 +611,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
break;
|
||||
default:
|
||||
|
@ -581,6 +662,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
|
|||
switch (hw->mac.type) {
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data);
|
||||
break;
|
||||
case e1000_82571:
|
||||
|
@ -885,6 +967,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
|||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
||||
|
@ -932,6 +1015,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
msec_delay(25);
|
||||
break;
|
||||
|
@ -1014,6 +1098,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
|
|||
/* ...for both queues. */
|
||||
switch (mac->type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
e1000_enable_tx_pkt_filtering_generic(hw);
|
||||
reg_data = E1000_READ_REG(hw, E1000_GCR);
|
||||
|
@ -1096,6 +1181,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL);
|
||||
reg &= ~(1 << 29);
|
||||
|
@ -1108,6 +1194,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
|||
/* Extended Device Control */
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
reg &= ~(1 << 23);
|
||||
|
@ -1141,6 +1228,7 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
reg = E1000_READ_REG(hw, E1000_GCR);
|
||||
reg |= (1 << 22);
|
||||
E1000_WRITE_REG(hw, E1000_GCR, reg);
|
||||
|
@ -1180,6 +1268,7 @@ static void e1000_clear_vfta_82571(struct e1000_hw *hw)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
if (hw->mng_cookie.vlan_id != 0) {
|
||||
/*
|
||||
|
@ -1281,6 +1370,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
|
|||
*/
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
if (hw->fc.requested_mode == e1000_fc_default)
|
||||
hw->fc.requested_mode = e1000_fc_full;
|
||||
|
@ -1301,7 +1391,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
|
|||
**/
|
||||
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl, led_ctrl;
|
||||
u32 ctrl;
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_setup_copper_link_82571");
|
||||
|
@ -1318,11 +1408,6 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw)
|
|||
break;
|
||||
case e1000_phy_igp_2:
|
||||
ret_val = e1000_copper_link_setup_igp(hw);
|
||||
/* Setup activity LED */
|
||||
led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL);
|
||||
led_ctrl &= IGP_ACTIVITY_LED_MASK;
|
||||
led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
|
||||
E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl);
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
|
@ -1372,8 +1457,20 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
|
|||
* e1000_check_for_serdes_link_82571 - Check for link (Serdes)
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Checks for link up on the hardware. If link is not up and we have
|
||||
* a signal, then we need to force link up.
|
||||
* Reports the link state as up or down.
|
||||
*
|
||||
* If autonegotiation is supported by the link partner, the link state is
|
||||
* determined by the result of autongotiation. This is the most likely case.
|
||||
* If autonegotiation is not supported by the link partner, and the link
|
||||
* has a valid signal, force the link up.
|
||||
*
|
||||
* The link state is represented internally here by 4 states:
|
||||
*
|
||||
* 1) down
|
||||
* 2) autoneg_progress
|
||||
* 3) autoneg_complete (the link sucessfully autonegotiated)
|
||||
* 4) forced_up (the link has been forced up, it did not autonegotiate)
|
||||
*
|
||||
**/
|
||||
s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
||||
{
|
||||
|
@ -1401,6 +1498,7 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
|||
*/
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_autoneg_progress;
|
||||
mac->serdes_has_link = FALSE;
|
||||
DEBUGOUT("AN_UP -> AN_PROG\n");
|
||||
}
|
||||
break;
|
||||
|
@ -1419,28 +1517,35 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
|||
(ctrl & ~E1000_CTRL_SLU));
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_autoneg_progress;
|
||||
mac->serdes_has_link = FALSE;
|
||||
DEBUGOUT("FORCED_UP -> AN_PROG\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case e1000_serdes_link_autoneg_progress:
|
||||
/*
|
||||
* If the LU bit is set in the STATUS register,
|
||||
* autoneg has completed sucessfully. If not,
|
||||
* try foring the link because the far end may be
|
||||
* available but not capable of autonegotiation.
|
||||
*/
|
||||
if (status & E1000_STATUS_LU) {
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_autoneg_complete;
|
||||
DEBUGOUT("AN_PROG -> AN_UP\n");
|
||||
if (rxcw & E1000_RXCW_C) {
|
||||
/* We received /C/ ordered sets, meaning the
|
||||
* link partner has autonegotiated, and we can
|
||||
* trust the Link Up (LU) status bit
|
||||
*/
|
||||
if (status & E1000_STATUS_LU) {
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_autoneg_complete;
|
||||
DEBUGOUT("AN_PROG -> AN_UP\n");
|
||||
mac->serdes_has_link = TRUE;
|
||||
} else {
|
||||
/* Autoneg completed, but failed */
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_down;
|
||||
DEBUGOUT("AN_PROG -> DOWN\n");
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Disable autoneg, force link up and
|
||||
* full duplex, and change state to forced
|
||||
/* The link partner did not autoneg.
|
||||
* Force link up and full duplex, and change
|
||||
* state to forced.
|
||||
*/
|
||||
E1000_WRITE_REG(hw, E1000_TXCW,
|
||||
(mac->txcw & ~E1000_TXCW_ANE));
|
||||
(mac->txcw & ~E1000_TXCW_ANE));
|
||||
ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
|
||||
|
||||
|
@ -1452,10 +1557,10 @@ s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
|
|||
break;
|
||||
}
|
||||
mac->serdes_link_state =
|
||||
e1000_serdes_link_forced_up;
|
||||
e1000_serdes_link_forced_up;
|
||||
mac->serdes_has_link = TRUE;
|
||||
DEBUGOUT("AN_PROG -> FORCED_UP\n");
|
||||
}
|
||||
mac->serdes_has_link = TRUE;
|
||||
break;
|
||||
|
||||
case e1000_serdes_link_down:
|
||||
|
@ -1517,6 +1622,7 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data)
|
|||
|
||||
switch (hw->mac.type) {
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
case e1000_82573:
|
||||
if(*data == ID_LED_RESERVED_F746)
|
||||
*data = ID_LED_DEFAULT_82573;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
* 82575GB Gigabit Network Connection
|
||||
* 82575GB Gigabit Network Connection
|
||||
* 82576 Gigabit Network Connection
|
||||
* 82576 Quad Port Gigabit Mezzanine Adapter
|
||||
*/
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
@ -77,6 +78,7 @@ static s32 e1000_reset_init_script_82575(struct e1000_hw *hw);
|
|||
static s32 e1000_read_mac_addr_82575(struct e1000_hw *hw);
|
||||
static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
|
||||
void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
|
||||
static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_82575 - Init PHY func ptrs.
|
||||
|
@ -326,11 +328,12 @@ void e1000_init_function_pointers_82575(struct e1000_hw *hw)
|
|||
**/
|
||||
static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u16 mask;
|
||||
u16 mask = E1000_SWFW_PHY0_SM;
|
||||
|
||||
DEBUGFUNC("e1000_acquire_phy_82575");
|
||||
|
||||
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
|
||||
if (hw->bus.func == E1000_FUNC_1)
|
||||
mask = E1000_SWFW_PHY1_SM;
|
||||
|
||||
return e1000_acquire_swfw_sync_82575(hw, mask);
|
||||
}
|
||||
|
@ -343,11 +346,13 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
|
|||
**/
|
||||
static void e1000_release_phy_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u16 mask;
|
||||
u16 mask = E1000_SWFW_PHY0_SM;
|
||||
|
||||
DEBUGFUNC("e1000_release_phy_82575");
|
||||
|
||||
mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
|
||||
if (hw->bus.func == E1000_FUNC_1)
|
||||
mask = E1000_SWFW_PHY1_SM;
|
||||
|
||||
e1000_release_swfw_sync_82575(hw, mask);
|
||||
}
|
||||
|
||||
|
@ -785,9 +790,8 @@ static s32 e1000_get_cfg_done_82575(struct e1000_hw *hw)
|
|||
|
||||
DEBUGFUNC("e1000_get_cfg_done_82575");
|
||||
|
||||
if (hw->bus.func == 1)
|
||||
if (hw->bus.func == E1000_FUNC_1)
|
||||
mask = E1000_NVM_CFG_DONE_PORT_1;
|
||||
|
||||
while (timeout) {
|
||||
if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask)
|
||||
break;
|
||||
|
@ -937,13 +941,13 @@ void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
|
|||
u32 reg;
|
||||
u16 eeprom_data = 0;
|
||||
|
||||
if (hw->mac.type != e1000_82576 ||
|
||||
(hw->phy.media_type != e1000_media_type_fiber &&
|
||||
hw->phy.media_type != e1000_media_type_internal_serdes))
|
||||
if (hw->phy.media_type != e1000_media_type_internal_serdes)
|
||||
return;
|
||||
|
||||
if (hw->bus.func == 0)
|
||||
if (hw->bus.func == E1000_FUNC_0)
|
||||
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
|
||||
else if (hw->bus.func == E1000_FUNC_1)
|
||||
hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
|
||||
|
||||
/*
|
||||
* If APM is not enabled in the EEPROM and management interface is
|
||||
|
@ -970,250 +974,42 @@ void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
|
|||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_loopback_enable_pf- Enables VM to VM queue loopback replication
|
||||
* e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
|
||||
* @hw: pointer to the HW structure
|
||||
* @enable: state to enter, either enabled or disabled
|
||||
*
|
||||
* enables/disables L2 switch loopback functionality
|
||||
**/
|
||||
void e1000_vmdq_loopback_enable_pf(struct e1000_hw *hw)
|
||||
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_DTXSWC);
|
||||
reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
if (enable)
|
||||
reg |= E1000_DTXSWC_VMDQ_LOOPBACK_EN;
|
||||
else
|
||||
reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN);
|
||||
E1000_WRITE_REG(hw, E1000_DTXSWC, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_loopback_disable_pf - Disable VM to VM queue loopbk replication
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
void e1000_vmdq_loopback_disable_pf(struct e1000_hw *hw)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_DTXSWC);
|
||||
reg &= ~(E1000_DTXSWC_VMDQ_LOOPBACK_EN);
|
||||
E1000_WRITE_REG(hw, E1000_DTXSWC, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_replication_enable_pf - Enable replication of brdcst & multicst
|
||||
* e1000_vmdq_set_replication_pf - enable or disable vmdq replication
|
||||
* @hw: pointer to the HW structure
|
||||
* @enable: state to enter, either enabled or disabled
|
||||
*
|
||||
* Enables replication of broadcast and multicast packets from the network
|
||||
* to VM's which have their respective broadcast and multicast accept
|
||||
* bits set in the VM Offload Register. This gives the PF driver per
|
||||
* VM granularity control over which VM's get replicated broadcast traffic.
|
||||
* enables/disables replication of packets across multiple pools
|
||||
**/
|
||||
void e1000_vmdq_replication_enable_pf(struct e1000_hw *hw, u32 enables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
if (enables & (1 << i)) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
reg |= (E1000_VMOLR_AUPE |
|
||||
E1000_VMOLR_BAM |
|
||||
E1000_VMOLR_MPME);
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
}
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_VT_CTL);
|
||||
reg |= E1000_VT_CTL_VM_REPL_EN;
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_replication_disable_pf - Disable replication of brdcst & multicst
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Disables replication of broadcast and multicast packets to the VM's.
|
||||
**/
|
||||
void e1000_vmdq_replication_disable_pf(struct e1000_hw *hw)
|
||||
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_VT_CTL);
|
||||
reg &= ~(E1000_VT_CTL_VM_REPL_EN);
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_enable_replication_mode_pf - Enables replication mode in the device
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
void e1000_vmdq_enable_replication_mode_pf(struct e1000_hw *hw)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = E1000_READ_REG(hw, E1000_VT_CTL);
|
||||
reg |= E1000_VT_CTL_VM_REPL_EN;
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_broadcast_replication_enable_pf - Enable replication of brdcst
|
||||
* @hw: pointer to the HW structure
|
||||
* @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Enables replication of broadcast packets from the network
|
||||
* to VM's which have their respective broadcast accept
|
||||
* bits set in the VM Offload Register. This gives the PF driver per
|
||||
* VM granularity control over which VM's get replicated broadcast traffic.
|
||||
**/
|
||||
void e1000_vmdq_broadcast_replication_enable_pf(struct e1000_hw *hw,
|
||||
u32 enables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
if ((enables == ALL_QUEUES) || (enables & (1 << i))) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
reg |= E1000_VMOLR_BAM;
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_broadcast_replication_disable_pf - Disable replication
|
||||
* of broadcast packets
|
||||
* @hw: pointer to the HW structure
|
||||
* @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Disables replication of broadcast packets for specific pools.
|
||||
* If bam/mpe is disabled on all pools then replication mode is
|
||||
* turned off.
|
||||
**/
|
||||
void e1000_vmdq_broadcast_replication_disable_pf(struct e1000_hw *hw,
|
||||
u32 disables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
u32 oneenabled = 0;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
if ((disables == ALL_QUEUES) || (disables & (1 << i))) {
|
||||
reg &= ~(E1000_VMOLR_BAM);
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
if (!oneenabled && (reg & (E1000_VMOLR_AUPE |
|
||||
E1000_VMOLR_BAM |
|
||||
E1000_VMOLR_MPME)))
|
||||
oneenabled = 1;
|
||||
}
|
||||
if (!oneenabled) {
|
||||
reg = E1000_READ_REG(hw, E1000_VT_CTL);
|
||||
if (enable)
|
||||
reg |= E1000_VT_CTL_VM_REPL_EN;
|
||||
else
|
||||
reg &= ~(E1000_VT_CTL_VM_REPL_EN);
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_multicast_promiscuous_enable_pf - Enable promiscuous reception
|
||||
* @hw: pointer to the HW structure
|
||||
* @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Enables promiscuous reception of multicast packets from the network
|
||||
* to VM's which have their respective multicast promiscuous mode enable
|
||||
* bits set in the VM Offload Register. This gives the PF driver per
|
||||
* VM granularity control over which VM's get all multicast traffic.
|
||||
**/
|
||||
void e1000_vmdq_multicast_promiscuous_enable_pf(struct e1000_hw *hw,
|
||||
u32 enables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
if ((enables == ALL_QUEUES) || (enables & (1 << i))) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
reg |= E1000_VMOLR_MPME;
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_multicast_promiscuous_disable_pf - Disable promiscuous
|
||||
* reception of multicast packets
|
||||
* @hw: pointer to the HW structure
|
||||
* @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Disables promiscuous reception of multicast packets for specific pools.
|
||||
* If bam/mpe is disabled on all pools then replication mode is
|
||||
* turned off.
|
||||
**/
|
||||
void e1000_vmdq_multicast_promiscuous_disable_pf(struct e1000_hw *hw,
|
||||
u32 disables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
u32 oneenabled = 0;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
if ((disables == ALL_QUEUES) || (disables & (1 << i))) {
|
||||
reg &= ~(E1000_VMOLR_MPME);
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
if (!oneenabled && (reg & (E1000_VMOLR_AUPE |
|
||||
E1000_VMOLR_BAM |
|
||||
E1000_VMOLR_MPME)))
|
||||
oneenabled = 1;
|
||||
}
|
||||
if (!oneenabled) {
|
||||
reg = E1000_READ_REG(hw, E1000_VT_CTL);
|
||||
reg &= ~(E1000_VT_CTL_VM_REPL_EN);
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_aupe_enable_pf - Enable acceptance of untagged packets
|
||||
* @hw: pointer to the HW structure
|
||||
* @enables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Enables acceptance of packets from the network which do not have
|
||||
* a VLAN tag but match the exact MAC filter of a given VM.
|
||||
**/
|
||||
void e1000_vmdq_aupe_enable_pf(struct e1000_hw *hw, u32 enables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
if ((enables == ALL_QUEUES) || (enables & (1 << i))) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
reg |= E1000_VMOLR_AUPE;
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_vmdq_aupe_disable_pf - Disable acceptance of untagged packets
|
||||
* @hw: pointer to the HW structure
|
||||
* @disables: PoolSet Bit - if set to ALL_QUEUES, apply to all pools.
|
||||
*
|
||||
* Disables acceptance of packets from the network which do not have
|
||||
* a VLAN tag but match the exact MAC filter of a given VM.
|
||||
**/
|
||||
void e1000_vmdq_aupe_disable_pf(struct e1000_hw *hw, u32 disables)
|
||||
{
|
||||
u32 reg;
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < MAX_NUM_VFS; i++) {
|
||||
if ((disables == ALL_QUEUES) || (disables & (1 << i))) {
|
||||
reg = E1000_READ_REG(hw, E1000_VMOLR(i));
|
||||
reg &= ~E1000_VMOLR_AUPE;
|
||||
E1000_WRITE_REG(hw, E1000_VMOLR(i), reg);
|
||||
}
|
||||
}
|
||||
E1000_WRITE_REG(hw, E1000_VT_CTL, reg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1238,6 +1034,12 @@ static s32 e1000_reset_hw_82575(struct e1000_hw *hw)
|
|||
DEBUGOUT("PCI-E Master disable polling has failed.\n");
|
||||
}
|
||||
|
||||
/* set the completion timeout for interface */
|
||||
ret_val = e1000_set_pcie_completion_timeout(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("PCI-E Set completion timeout has failed.\n");
|
||||
}
|
||||
|
||||
DEBUGOUT("Masking off all interrupts\n");
|
||||
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
|
||||
|
||||
|
@ -1333,7 +1135,7 @@ static s32 e1000_init_hw_82575(struct e1000_hw *hw)
|
|||
**/
|
||||
static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
{
|
||||
u32 ctrl, led_ctrl;
|
||||
u32 ctrl;
|
||||
s32 ret_val;
|
||||
bool link;
|
||||
|
||||
|
@ -1350,11 +1152,6 @@ static s32 e1000_setup_copper_link_82575(struct e1000_hw *hw)
|
|||
break;
|
||||
case e1000_phy_igp_3:
|
||||
ret_val = e1000_copper_link_setup_igp(hw);
|
||||
/* Setup activity LED */
|
||||
led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL);
|
||||
led_ctrl &= IGP_ACTIVITY_LED_MASK;
|
||||
led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
|
||||
E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl);
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
|
@ -1433,15 +1230,14 @@ static s32 e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
|
|||
*/
|
||||
E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
|
||||
|
||||
/* Force link up, set 1gb, set both sw defined pins */
|
||||
/* Force link up, set 1gb */
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL);
|
||||
reg |= E1000_CTRL_SLU |
|
||||
E1000_CTRL_SPD_1000 |
|
||||
E1000_CTRL_FRCSPD |
|
||||
E1000_CTRL_SWDPIN0 |
|
||||
E1000_CTRL_SWDPIN1;
|
||||
reg |= E1000_CTRL_SLU | E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD;
|
||||
if (hw->mac.type == e1000_82575 || hw->mac.type == e1000_82576) {
|
||||
/* set both sw defined pins */
|
||||
reg |= E1000_CTRL_SWDPIN0 | E1000_CTRL_SWDPIN1;
|
||||
}
|
||||
E1000_WRITE_REG(hw, E1000_CTRL, reg);
|
||||
|
||||
/* Power on phy for 82576 fiber adapters */
|
||||
if (hw->mac.type == e1000_82576) {
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
|
@ -1514,7 +1310,6 @@ static s32 e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data)
|
|||
|
||||
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
|
||||
switch(hw->phy.media_type) {
|
||||
case e1000_media_type_fiber:
|
||||
case e1000_media_type_internal_serdes:
|
||||
*data = ID_LED_DEFAULT_82575_SERDES;
|
||||
break;
|
||||
|
@ -1605,12 +1400,6 @@ static s32 e1000_configure_pcs_link_82575(struct e1000_hw *hw)
|
|||
static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
|
||||
|
||||
DEBUGFUNC("e1000_sgmii_active_82575");
|
||||
|
||||
if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
|
||||
return FALSE;
|
||||
|
||||
return dev_spec->sgmii_active;
|
||||
}
|
||||
|
||||
|
@ -1762,6 +1551,7 @@ static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
|
|||
if (hw->phy.media_type == e1000_media_type_internal_serdes)
|
||||
E1000_READ_REG(hw, E1000_SCVPC);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_rx_fifo_flush_82575 - Clean rx fifo after RX enable
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -1836,3 +1626,54 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
|
|||
E1000_READ_REG(hw, E1000_MPC);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_set_pcie_completion_timeout - set pci-e completion timeout
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* The defaults for 82575 and 82576 should be in the range of 50us to 50ms,
|
||||
* however the hardware default for these parts is 500us to 1ms which is less
|
||||
* than the 10ms recommended by the pci-e spec. To address this we need to
|
||||
* increase the value to either 10ms to 200ms for capability version 1 config,
|
||||
* or 16ms to 55ms for version 2.
|
||||
**/
|
||||
static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw)
|
||||
{
|
||||
u32 gcr = E1000_READ_REG(hw, E1000_GCR);
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 pcie_devctl2;
|
||||
|
||||
/* only take action if timeout value is defaulted to 0 */
|
||||
if (gcr & E1000_GCR_CMPL_TMOUT_MASK)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* if capababilities version is type 1 we can write the
|
||||
* timeout of 10ms to 200ms through the GCR register
|
||||
*/
|
||||
if (!(gcr & E1000_GCR_CAP_VER2)) {
|
||||
gcr |= E1000_GCR_CMPL_TMOUT_10ms;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* for version 2 capabilities we need to write the config space
|
||||
* directly in order to set the completion timeout value for
|
||||
* 16ms to 55ms
|
||||
*/
|
||||
ret_val = e1000_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
|
||||
&pcie_devctl2);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
|
||||
|
||||
ret_val = e1000_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
|
||||
&pcie_devctl2);
|
||||
out:
|
||||
/* disable completion timeout resend */
|
||||
gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_GCR, gcr);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ union e1000_adv_rx_desc {
|
|||
} wb; /* writeback */
|
||||
};
|
||||
|
||||
#define E1000_RXDADV_RSSTYPE_MASK 0x0000F000
|
||||
#define E1000_RXDADV_RSSTYPE_MASK 0x0000000F
|
||||
#define E1000_RXDADV_RSSTYPE_SHIFT 12
|
||||
#define E1000_RXDADV_HDRBUFLEN_MASK 0x7FE0
|
||||
#define E1000_RXDADV_HDRBUFLEN_SHIFT 5
|
||||
|
@ -421,21 +421,11 @@ struct e1000_adv_tx_context_desc {
|
|||
#define E1000_IOVCTL 0x05BBC
|
||||
#define E1000_IOVCTL_REUSE_VFQ 0x00000001
|
||||
|
||||
#define E1000_RPLOLR_STRVLAN 0x40000000
|
||||
#define E1000_RPLOLR_STRCRC 0x80000000
|
||||
|
||||
#define ALL_QUEUES 0xFFFF
|
||||
|
||||
void e1000_vmdq_loopback_enable_pf(struct e1000_hw *hw);
|
||||
void e1000_vmdq_loopback_disable_pf(struct e1000_hw *hw);
|
||||
void e1000_vmdq_replication_enable_pf(struct e1000_hw *hw, u32 enables);
|
||||
void e1000_vmdq_replication_disable_pf(struct e1000_hw *hw);
|
||||
void e1000_vmdq_enable_replication_mode_pf(struct e1000_hw *hw);
|
||||
void e1000_vmdq_broadcast_replication_enable_pf(struct e1000_hw *hw,
|
||||
u32 enables);
|
||||
void e1000_vmdq_multicast_promiscuous_enable_pf(struct e1000_hw *hw,
|
||||
u32 enables);
|
||||
void e1000_vmdq_broadcast_replication_disable_pf(struct e1000_hw *hw,
|
||||
u32 disables);
|
||||
void e1000_vmdq_multicast_promiscuous_disable_pf(struct e1000_hw *hw,
|
||||
u32 disables);
|
||||
void e1000_vmdq_aupe_enable_pf(struct e1000_hw *hw, u32 enables);
|
||||
void e1000_vmdq_aupe_disable_pf(struct e1000_hw *hw, u32 disables);
|
||||
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
|
||||
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
|
||||
#endif /* _E1000_82575_H_ */
|
||||
|
|
|
@ -213,8 +213,12 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
|||
mac->type = e1000_82573;
|
||||
break;
|
||||
case E1000_DEV_ID_82574L:
|
||||
case E1000_DEV_ID_82574LA:
|
||||
mac->type = e1000_82574;
|
||||
break;
|
||||
case E1000_DEV_ID_82583V:
|
||||
mac->type = e1000_82583;
|
||||
break;
|
||||
case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
|
||||
case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
|
||||
case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
|
||||
|
@ -248,6 +252,12 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
|||
case E1000_DEV_ID_ICH10_D_BM_LF:
|
||||
mac->type = e1000_ich10lan;
|
||||
break;
|
||||
case E1000_DEV_ID_PCH_D_HV_DM:
|
||||
case E1000_DEV_ID_PCH_D_HV_DC:
|
||||
case E1000_DEV_ID_PCH_M_HV_LM:
|
||||
case E1000_DEV_ID_PCH_M_HV_LC:
|
||||
mac->type = e1000_pchlan;
|
||||
break;
|
||||
case E1000_DEV_ID_82575EB_COPPER:
|
||||
case E1000_DEV_ID_82575EB_FIBER_SERDES:
|
||||
case E1000_DEV_ID_82575GB_QUAD_COPPER:
|
||||
|
@ -259,6 +269,7 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
|
|||
case E1000_DEV_ID_82576_SERDES:
|
||||
case E1000_DEV_ID_82576_QUAD_COPPER:
|
||||
case E1000_DEV_ID_82576_NS:
|
||||
case E1000_DEV_ID_82576_SERDES_QUAD:
|
||||
mac->type = e1000_82576;
|
||||
break;
|
||||
default:
|
||||
|
@ -337,6 +348,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
|||
case e1000_82572:
|
||||
case e1000_82573:
|
||||
case e1000_82574:
|
||||
case e1000_82583:
|
||||
e1000_init_function_pointers_82571(hw);
|
||||
break;
|
||||
case e1000_80003es2lan:
|
||||
|
@ -345,6 +357,7 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device)
|
|||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
e1000_init_function_pointers_ich8lan(hw);
|
||||
break;
|
||||
case e1000_82575:
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#define E1000_WUFC_FLX1_PHY 0x00002000 /* Flexible Filter 1 Enable */
|
||||
#define E1000_WUFC_FLX2_PHY 0x00004000 /* Flexible Filter 2 Enable */
|
||||
#define E1000_WUFC_FLX3_PHY 0x00008000 /* Flexible Filter 3 Enable */
|
||||
#define E1000_WUFC_FLX4_PHY 0x00000200 /* Flexible Filter 4 Enable */
|
||||
#define E1000_WUFC_FLX5_PHY 0x00000400 /* Flexible Filter 5 Enable */
|
||||
#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
|
||||
#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
|
||||
#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
|
||||
|
@ -74,9 +76,13 @@
|
|||
#define E1000_WUFC_ALL_FILTERS_PHY_4 0x0000F0FF /*Mask for all wakeup filters*/
|
||||
#define E1000_WUFC_FLX_OFFSET_PHY 12 /* Offset to the Flexible Filters bits */
|
||||
#define E1000_WUFC_FLX_FILTERS_PHY_4 0x0000F000 /*Mask for 4 flexible filters*/
|
||||
#define E1000_WUFC_ALL_FILTERS_PHY_6 0x0000F6FF /*Mask for 6 wakeup filters */
|
||||
#define E1000_WUFC_FLX_FILTERS_PHY_6 0x0000F600 /*Mask for 6 flexible filters*/
|
||||
#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
|
||||
#define E1000_WUFC_ALL_FILTERS_6 0x003F00FF /* Mask for all 6 wakeup filters*/
|
||||
#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */
|
||||
#define E1000_WUFC_FLX_FILTERS 0x000F0000 /*Mask for the 4 flexible filters */
|
||||
#define E1000_WUFC_FLX_FILTERS_6 0x003F0000 /* Mask for 6 flexible filters */
|
||||
/*
|
||||
* For 82576 to utilize Extended filter masks in addition to
|
||||
* existing (filter) masks
|
||||
|
@ -101,13 +107,21 @@
|
|||
#define E1000_WUS_FLX1 E1000_WUFC_FLX1
|
||||
#define E1000_WUS_FLX2 E1000_WUFC_FLX2
|
||||
#define E1000_WUS_FLX3 E1000_WUFC_FLX3
|
||||
#define E1000_WUS_FLX4 E1000_WUFC_FLX4
|
||||
#define E1000_WUS_FLX5 E1000_WUFC_FLX5
|
||||
#define E1000_WUS_FLX4_PHY E1000_WUFC_FLX4_PHY
|
||||
#define E1000_WUS_FLX5_PHY E1000_WUFC_FLX5_PHY
|
||||
#define E1000_WUS_FLX_FILTERS E1000_WUFC_FLX_FILTERS
|
||||
#define E1000_WUS_FLX_FILTERS_6 E1000_WUFC_FLX_FILTERS_6
|
||||
#define E1000_WUS_FLX_FILTERS_PHY_6 E1000_WUFC_FLX_FILTERS_PHY_6
|
||||
|
||||
/* Wake Up Packet Length */
|
||||
#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
|
||||
|
||||
/* Four Flexible Filters are supported */
|
||||
#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
|
||||
/* Six Flexible Filters are supported */
|
||||
#define E1000_FLEXIBLE_FILTER_COUNT_MAX_6 6
|
||||
/* Two Extended Flexible Filters are supported (82576) */
|
||||
#define E1000_EXT_FLEXIBLE_FILTER_COUNT_MAX 2
|
||||
#define E1000_FHFT_LENGTH_OFFSET 0xFC /* Length byte in FHFT */
|
||||
|
@ -117,6 +131,7 @@
|
|||
#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128
|
||||
|
||||
#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
|
||||
#define E1000_FFLT_SIZE_6 E1000_FLEXIBLE_FILTER_COUNT_MAX_6
|
||||
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
|
||||
#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
|
||||
|
||||
|
@ -162,7 +177,7 @@
|
|||
#define E1000_CTRL_EXT_CANC 0x04000000 /* Int delay cancellation */
|
||||
#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
|
||||
/* IAME enable bit (27) was removed in >= 82575 */
|
||||
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int acknowledge Auto-mask */
|
||||
#define E1000_CTRL_EXT_IAME 0x08000000 /* Int acknowledge Auto-mask */
|
||||
#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error
|
||||
* detection enabled */
|
||||
#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity
|
||||
|
@ -170,6 +185,7 @@
|
|||
#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
|
||||
#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */
|
||||
#define E1000_CTRL_EXT_LSECCK 0x00001000
|
||||
#define E1000_CTRL_EXT_PHYPDEN 0x00100000
|
||||
#define E1000_I2CCMD_REG_ADDR_SHIFT 16
|
||||
#define E1000_I2CCMD_REG_ADDR 0x00FF0000
|
||||
#define E1000_I2CCMD_PHY_ADDR_SHIFT 24
|
||||
|
@ -300,8 +316,8 @@
|
|||
#define E1000_RCTL_RST 0x00000001 /* Software reset */
|
||||
#define E1000_RCTL_EN 0x00000002 /* enable */
|
||||
#define E1000_RCTL_SBP 0x00000004 /* store bad packet */
|
||||
#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */
|
||||
#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */
|
||||
#define E1000_RCTL_UPE 0x00000008 /* unicast promisc enable */
|
||||
#define E1000_RCTL_MPE 0x00000010 /* multicast promisc enable */
|
||||
#define E1000_RCTL_LPE 0x00000020 /* long packet enable */
|
||||
#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */
|
||||
#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
|
||||
|
@ -309,9 +325,9 @@
|
|||
#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
|
||||
#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
|
||||
#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
|
||||
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
|
||||
#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
|
||||
#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
|
||||
#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min thresh size */
|
||||
#define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min thresh size */
|
||||
#define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min thresh size */
|
||||
#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */
|
||||
#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */
|
||||
#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */
|
||||
|
@ -366,10 +382,10 @@
|
|||
#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
|
||||
|
||||
/* SWFW_SYNC Definitions */
|
||||
#define E1000_SWFW_EEP_SM 0x1
|
||||
#define E1000_SWFW_PHY0_SM 0x2
|
||||
#define E1000_SWFW_PHY1_SM 0x4
|
||||
#define E1000_SWFW_CSR_SM 0x8
|
||||
#define E1000_SWFW_EEP_SM 0x01
|
||||
#define E1000_SWFW_PHY0_SM 0x02
|
||||
#define E1000_SWFW_PHY1_SM 0x04
|
||||
#define E1000_SWFW_CSR_SM 0x08
|
||||
|
||||
/* FACTPS Definitions */
|
||||
#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */
|
||||
|
@ -377,7 +393,7 @@
|
|||
#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
|
||||
#define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
|
||||
#define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
|
||||
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
|
||||
#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master reqs */
|
||||
#define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
|
||||
#define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
|
||||
#define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
|
||||
|
@ -475,8 +491,9 @@
|
|||
#define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
|
||||
#define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
|
||||
#define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
|
||||
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
|
||||
#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion by NVM */
|
||||
#define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
|
||||
#define E1000_STATUS_PHYRA 0x00000400 /* PHY Reset Asserted */
|
||||
#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state.
|
||||
* Clear on write '0'. */
|
||||
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Master request status */
|
||||
|
@ -498,9 +515,9 @@
|
|||
#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
|
||||
|
||||
/* Constants used to interpret the masked PCI-X bus speed. */
|
||||
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
|
||||
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
|
||||
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */
|
||||
#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
|
||||
#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */
|
||||
#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /*PCI-X bus speed 100-133 MHz*/
|
||||
|
||||
#define SPEED_10 10
|
||||
#define SPEED_100 100
|
||||
|
@ -532,6 +549,11 @@
|
|||
#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX
|
||||
|
||||
/* LED Control */
|
||||
#define E1000_PHY_LED0_MODE_MASK 0x00000007
|
||||
#define E1000_PHY_LED0_IVRT 0x00000008
|
||||
#define E1000_PHY_LED0_BLINK 0x00000010
|
||||
#define E1000_PHY_LED0_MASK 0x0000001F
|
||||
|
||||
#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
|
||||
#define E1000_LEDCTL_LED0_MODE_SHIFT 0
|
||||
#define E1000_LEDCTL_LED0_BLINK_RATE 0x00000020
|
||||
|
@ -690,7 +712,7 @@
|
|||
#define E1000_KABGTXD_BGSQLBIAS 0x00050000
|
||||
|
||||
/* PBA constants */
|
||||
#define E1000_PBA_6K 0x0006 /* 6KB */
|
||||
#define E1000_PBA_6K 0x0006 /* 6KB */
|
||||
#define E1000_PBA_8K 0x0008 /* 8KB */
|
||||
#define E1000_PBA_10K 0x000A /* 10KB */
|
||||
#define E1000_PBA_12K 0x000C /* 12KB */
|
||||
|
@ -725,6 +747,8 @@
|
|||
#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
|
||||
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
|
||||
|
||||
#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */
|
||||
|
||||
/* Interrupt Cause Read */
|
||||
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
|
||||
#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */
|
||||
|
@ -749,7 +773,7 @@
|
|||
* should claim the interrupt */
|
||||
#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* Q0 Rx desc FIFO parity error */
|
||||
#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* Q0 Tx desc FIFO parity error */
|
||||
#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity err */
|
||||
#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity err */
|
||||
#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
|
||||
#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* Q1 Rx desc FIFO parity error */
|
||||
#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* Q1 Tx desc FIFO parity error */
|
||||
|
@ -769,9 +793,9 @@
|
|||
/* PBA ECC Register */
|
||||
#define E1000_PBA_ECC_COUNTER_MASK 0xFFF00000 /* ECC counter mask */
|
||||
#define E1000_PBA_ECC_COUNTER_SHIFT 20 /* ECC counter shift value */
|
||||
#define E1000_PBA_ECC_CORR_EN 0x00000001 /* Enable ECC error correction */
|
||||
#define E1000_PBA_ECC_CORR_EN 0x00000001 /* Enable ECC error correction */
|
||||
#define E1000_PBA_ECC_STAT_CLR 0x00000002 /* Clear ECC error counter */
|
||||
#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 on ECC error */
|
||||
#define E1000_PBA_ECC_INT_EN 0x00000004 /* Enable ICR bit 5 on ECC error */
|
||||
|
||||
/* Extended Interrupt Cause Read */
|
||||
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
|
||||
|
@ -817,7 +841,7 @@
|
|||
E1000_IMS_LSC)
|
||||
|
||||
/* Interrupt Mask Set */
|
||||
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
|
||||
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Tx desc written back */
|
||||
#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
|
||||
#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */
|
||||
#define E1000_IMS_VMMB E1000_ICR_VMMB /* Mail box activity */
|
||||
|
@ -871,7 +895,7 @@
|
|||
#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */
|
||||
|
||||
/* Interrupt Cause Set */
|
||||
#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
|
||||
#define E1000_ICS_TXDW E1000_ICR_TXDW /* Tx desc written back */
|
||||
#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */
|
||||
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
|
||||
#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
|
||||
|
@ -1012,6 +1036,7 @@
|
|||
#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */
|
||||
#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */
|
||||
|
||||
|
||||
/* PCI Express Control */
|
||||
#define E1000_GCR_RXD_NO_SNOOP 0x00000001
|
||||
#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
|
||||
|
@ -1019,6 +1044,10 @@
|
|||
#define E1000_GCR_TXD_NO_SNOOP 0x00000008
|
||||
#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
|
||||
#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
|
||||
#define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000
|
||||
#define E1000_GCR_CMPL_TMOUT_10ms 0x00001000
|
||||
#define E1000_GCR_CMPL_TMOUT_RESEND 0x00010000
|
||||
#define E1000_GCR_CAP_VER2 0x00040000
|
||||
|
||||
#define PCIE_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
|
||||
E1000_GCR_RXDSCW_NO_SNOOP | \
|
||||
|
@ -1099,7 +1128,7 @@
|
|||
/* 0=DTE device */
|
||||
#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */
|
||||
/* 0=Configure PHY as Slave */
|
||||
#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
|
||||
#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */
|
||||
/* 0=Automatic Master/Slave config */
|
||||
#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
|
||||
#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */
|
||||
|
@ -1109,7 +1138,7 @@
|
|||
|
||||
/* 1000BASE-T Status Register */
|
||||
#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */
|
||||
#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
|
||||
#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */
|
||||
#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */
|
||||
#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */
|
||||
#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
|
||||
|
@ -1134,6 +1163,8 @@
|
|||
#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
|
||||
#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
|
||||
|
||||
#define PHY_CONTROL_LB 0x4000 /* PHY Loopback bit */
|
||||
|
||||
/* NVM Control */
|
||||
#define E1000_EECD_SK 0x00000001 /* NVM Clock */
|
||||
#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */
|
||||
|
@ -1168,7 +1199,7 @@
|
|||
|
||||
#define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */
|
||||
#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */
|
||||
#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */
|
||||
#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write regs */
|
||||
#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
|
||||
#define E1000_NVM_RW_REG_START 1 /* Start operation */
|
||||
#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
|
||||
|
@ -1194,8 +1225,8 @@
|
|||
#define NVM_ALT_MAC_ADDR_PTR 0x0037
|
||||
#define NVM_CHECKSUM_REG 0x003F
|
||||
|
||||
#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */
|
||||
#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */
|
||||
#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
|
||||
#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
|
||||
|
||||
/* Mask bits for fields in Word 0x0f of the NVM */
|
||||
#define NVM_WORD0F_PAUSE_MASK 0x3000
|
||||
|
@ -1273,6 +1304,7 @@
|
|||
#define PCIX_STATUS_REGISTER_HI 0xEA
|
||||
#define PCI_HEADER_TYPE_REGISTER 0x0E
|
||||
#define PCIE_LINK_STATUS 0x12
|
||||
#define PCIE_DEVICE_CONTROL2 0x28
|
||||
|
||||
#define PCIX_COMMAND_MMRBC_MASK 0x000C
|
||||
#define PCIX_COMMAND_MMRBC_SHIFT 0x2
|
||||
|
@ -1284,6 +1316,7 @@
|
|||
#define PCI_HEADER_TYPE_MULTIFUNC 0x80
|
||||
#define PCIE_LINK_WIDTH_MASK 0x3F0
|
||||
#define PCIE_LINK_WIDTH_SHIFT 4
|
||||
#define PCIE_DEVICE_CONTROL2_16ms 0x0005
|
||||
|
||||
#ifndef ETH_ADDR_LEN
|
||||
#define ETH_ADDR_LEN 6
|
||||
|
@ -1311,6 +1344,8 @@
|
|||
#define IFE_C_E_PHY_ID 0x02A80310
|
||||
#define BME1000_E_PHY_ID 0x01410CB0
|
||||
#define BME1000_E_PHY_ID_R2 0x01410CB1
|
||||
#define I82577_E_PHY_ID 0x01540050
|
||||
#define I82578_E_PHY_ID 0x004DD040
|
||||
#define IGP04E1000_E_PHY_ID 0x02A80391
|
||||
#define M88_VENDOR 0x0141
|
||||
|
||||
|
@ -1330,11 +1365,11 @@
|
|||
|
||||
/* M88E1000 PHY Specific Control Register */
|
||||
#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */
|
||||
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */
|
||||
#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reverse enabled */
|
||||
#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */
|
||||
/* 1=CLK125 low, 0=CLK125 toggling */
|
||||
#define M88E1000_PSCR_CLK125_DISABLE 0x0010
|
||||
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
|
||||
#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */
|
||||
/* Manual MDI configuration */
|
||||
#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */
|
||||
/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
|
||||
|
@ -1350,7 +1385,7 @@
|
|||
#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100
|
||||
#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */
|
||||
#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */
|
||||
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
|
||||
#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Tx */
|
||||
|
||||
/* M88E1000 PHY Specific Status Register */
|
||||
#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */
|
||||
|
@ -1418,6 +1453,9 @@
|
|||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00
|
||||
#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00
|
||||
|
||||
#define I82578_EPSCR_DOWNSHIFT_ENABLE 0x0020
|
||||
#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK 0x001C
|
||||
|
||||
/* BME1000 PHY Specific Control Register */
|
||||
#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */
|
||||
|
||||
|
@ -1536,4 +1574,6 @@
|
|||
#define E1000_LSECRXCTRL_RP 0x00000080
|
||||
#define E1000_LSECRXCTRL_RSV_MASK 0xFFFFFF33
|
||||
|
||||
|
||||
|
||||
#endif /* _E1000_DEFINES_H_ */
|
||||
|
|
|
@ -95,6 +95,7 @@ struct e1000_hw;
|
|||
#define E1000_DEV_ID_82573L 0x109A
|
||||
#define E1000_DEV_ID_82574L 0x10D3
|
||||
#define E1000_DEV_ID_82574LA 0x10F6
|
||||
#define E1000_DEV_ID_82583V 0x150C
|
||||
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
|
||||
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
|
||||
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
|
||||
|
@ -120,11 +121,16 @@ struct e1000_hw;
|
|||
#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE
|
||||
#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF
|
||||
#define E1000_DEV_ID_PCH_M_HV_LM 0x10EA
|
||||
#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_DC 0x10F0
|
||||
#define E1000_DEV_ID_82576 0x10C9
|
||||
#define E1000_DEV_ID_82576_FIBER 0x10E6
|
||||
#define E1000_DEV_ID_82576_SERDES 0x10E7
|
||||
#define E1000_DEV_ID_82576_QUAD_COPPER 0x10E8
|
||||
#define E1000_DEV_ID_82576_NS 0x150A
|
||||
#define E1000_DEV_ID_82576_SERDES_QUAD 0x150D
|
||||
#define E1000_DEV_ID_82575EB_COPPER 0x10A7
|
||||
#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9
|
||||
#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6
|
||||
|
@ -159,10 +165,12 @@ enum e1000_mac_type {
|
|||
e1000_82572,
|
||||
e1000_82573,
|
||||
e1000_82574,
|
||||
e1000_82583,
|
||||
e1000_80003es2lan,
|
||||
e1000_ich8lan,
|
||||
e1000_ich9lan,
|
||||
e1000_ich10lan,
|
||||
e1000_pchlan,
|
||||
e1000_82575,
|
||||
e1000_82576,
|
||||
e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */
|
||||
|
@ -203,6 +211,8 @@ enum e1000_phy_type {
|
|||
e1000_phy_igp_3,
|
||||
e1000_phy_ife,
|
||||
e1000_phy_bm,
|
||||
e1000_phy_82578,
|
||||
e1000_phy_82577,
|
||||
e1000_phy_vf,
|
||||
};
|
||||
|
||||
|
@ -647,9 +657,9 @@ struct e1000_mac_info {
|
|||
u16 ifs_ratio;
|
||||
u16 ifs_step_size;
|
||||
u16 mta_reg_count;
|
||||
#define MAX_MTA_REG 128 /* this must be the maximum size of the MTA register
|
||||
* table in all supported adapters
|
||||
*/
|
||||
|
||||
/* Maximum size of the MTA register table in all supported adapters */
|
||||
#define MAX_MTA_REG 128
|
||||
u32 mta_shadow[MAX_MTA_REG];
|
||||
u16 rar_entry_count;
|
||||
|
||||
|
@ -755,6 +765,7 @@ struct e1000_dev_spec_82543 {
|
|||
|
||||
struct e1000_dev_spec_82571 {
|
||||
bool laa_is_present;
|
||||
u32 smb_counter;
|
||||
};
|
||||
|
||||
struct e1000_shadow_ram {
|
||||
|
@ -823,6 +834,7 @@ struct e1000_hw {
|
|||
void e1000_pci_clear_mwi(struct e1000_hw *hw);
|
||||
void e1000_pci_set_mwi(struct e1000_hw *hw);
|
||||
s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
s32 e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
void e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value);
|
||||
|
||||
|
|
|
@ -54,19 +54,22 @@
|
|||
* 82567LF-3 Gigabit Network Connection
|
||||
* 82567LM-3 Gigabit Network Connection
|
||||
* 82567LM-4 Gigabit Network Connection
|
||||
* 82577LM Gigabit Network Connection
|
||||
* 82577LC Gigabit Network Connection
|
||||
* 82578DM Gigabit Network Connection
|
||||
* 82578DC Gigabit Network Connection
|
||||
*/
|
||||
|
||||
#include "e1000_api.h"
|
||||
|
||||
static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw);
|
||||
static void e1000_release_swflag_ich8lan(struct e1000_hw *hw);
|
||||
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw,
|
||||
|
@ -81,6 +84,7 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw);
|
|||
static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw,
|
||||
u16 *data);
|
||||
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw);
|
||||
|
@ -91,6 +95,10 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw,
|
|||
static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
|
||||
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank);
|
||||
static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout);
|
||||
|
@ -154,6 +162,55 @@ union ich8_hws_flash_regacc {
|
|||
u16 regval;
|
||||
};
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_pchlan - Initialize PHY function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Initialize family-specific PHY parameters and function pointers.
|
||||
**/
|
||||
static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
DEBUGFUNC("e1000_init_phy_params_pchlan");
|
||||
|
||||
phy->addr = 1;
|
||||
phy->reset_delay_us = 100;
|
||||
|
||||
phy->ops.acquire = e1000_acquire_swflag_ich8lan;
|
||||
phy->ops.check_polarity = e1000_check_polarity_ife;
|
||||
phy->ops.check_reset_block = e1000_check_reset_block_ich8lan;
|
||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
|
||||
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
|
||||
phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan;
|
||||
phy->ops.get_info = e1000_get_phy_info_ich8lan;
|
||||
phy->ops.read_reg = e1000_read_phy_reg_hv;
|
||||
phy->ops.release = e1000_release_swflag_ich8lan;
|
||||
phy->ops.reset = e1000_phy_hw_reset_ich8lan;
|
||||
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan;
|
||||
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan;
|
||||
phy->ops.write_reg = e1000_write_phy_reg_hv;
|
||||
phy->ops.power_up = e1000_power_up_phy_copper;
|
||||
phy->ops.power_down = e1000_power_down_phy_copper_ich8lan;
|
||||
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
|
||||
|
||||
phy->id = e1000_phy_unknown;
|
||||
e1000_get_phy_id(hw);
|
||||
phy->type = e1000_get_phy_type_from_id(phy->id);
|
||||
|
||||
if (phy->type == e1000_phy_82577) {
|
||||
phy->ops.check_polarity = e1000_check_polarity_82577;
|
||||
phy->ops.force_speed_duplex =
|
||||
e1000_phy_force_speed_duplex_82577;
|
||||
phy->ops.get_cable_length = e1000_get_cable_length_82577;
|
||||
phy->ops.get_info = e1000_get_phy_info_82577;
|
||||
phy->ops.commit = e1000_phy_sw_reset_generic;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_phy_params_ich8lan - Initialize PHY function pointers
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -172,9 +229,9 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
|
|||
phy->reset_delay_us = 100;
|
||||
|
||||
phy->ops.acquire = e1000_acquire_swflag_ich8lan;
|
||||
phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
|
||||
phy->ops.check_polarity = e1000_check_polarity_ife;
|
||||
phy->ops.check_reset_block = e1000_check_reset_block_ich8lan;
|
||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan;
|
||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ife;
|
||||
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
|
||||
phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan;
|
||||
phy->ops.get_info = e1000_get_phy_info_ich8lan;
|
||||
|
@ -250,6 +307,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
|
|||
{
|
||||
struct e1000_nvm_info *nvm = &hw->nvm;
|
||||
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
|
||||
union ich8_hws_flash_status hsfsts;
|
||||
u32 gfpreg, sector_base_addr, sector_end_addr;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 i;
|
||||
|
@ -288,6 +346,20 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
|
|||
/* Adjust to word count */
|
||||
nvm->flash_bank_size /= sizeof(u16);
|
||||
|
||||
/*
|
||||
* Make sure the flash bank size does not overwrite the 4k
|
||||
* sector ranges. We may have 64k allotted to us but we only care
|
||||
* about the first 2 4k sectors. Therefore, if we have anything less
|
||||
* than 64k set in the HSFSTS register, we will reduce the bank size
|
||||
* down to 4k and let the rest remain unused. If berasesz == 3, then
|
||||
* we are working in 64k mode. Otherwise we are not.
|
||||
*/
|
||||
if (nvm->flash_bank_size > E1000_SHADOW_RAM_WORDS) {
|
||||
hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS);
|
||||
if (hsfsts.hsf_status.berasesz != 3)
|
||||
nvm->flash_bank_size = E1000_SHADOW_RAM_WORDS;
|
||||
}
|
||||
|
||||
nvm->word_size = E1000_SHADOW_RAM_WORDS;
|
||||
|
||||
/* Clear shadow ram */
|
||||
|
@ -319,9 +391,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
|
|||
static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
#if defined(NAHUM4) && !defined(NO_PCH_A_SUPPORT)
|
||||
u16 pci_cfg;
|
||||
#endif
|
||||
|
||||
DEBUGFUNC("e1000_init_mac_params_ich8lan");
|
||||
|
||||
|
@ -383,6 +453,20 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw)
|
|||
mac->ops.led_on = e1000_led_on_ich8lan;
|
||||
mac->ops.led_off = e1000_led_off_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
/* save PCH revision_id */
|
||||
e1000_read_pci_cfg(hw, 0x2, &pci_cfg);
|
||||
hw->revision_id = (u8)(pci_cfg &= 0x000F);
|
||||
/* ID LED init */
|
||||
mac->ops.id_led_init = e1000_id_led_init_pchlan;
|
||||
/* setup LED */
|
||||
mac->ops.setup_led = e1000_setup_led_pchlan;
|
||||
/* cleanup LED */
|
||||
mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
|
||||
/* turn on/off LED */
|
||||
mac->ops.led_on = e1000_led_on_pchlan;
|
||||
mac->ops.led_off = e1000_led_off_pchlan;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -407,7 +491,18 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
hw->mac.ops.init_params = e1000_init_mac_params_ich8lan;
|
||||
hw->nvm.ops.init_params = e1000_init_nvm_params_ich8lan;
|
||||
hw->phy.ops.init_params = e1000_init_phy_params_ich8lan;
|
||||
switch (hw->mac.type) {
|
||||
case e1000_ich8lan:
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
hw->phy.ops.init_params = e1000_init_phy_params_ich8lan;
|
||||
break;
|
||||
case e1000_pchlan:
|
||||
hw->phy.ops.init_params = e1000_init_phy_params_pchlan;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -427,18 +522,21 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
while (timeout) {
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
|
||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
|
||||
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
|
||||
break;
|
||||
if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
|
||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
|
||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
|
||||
|
||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
|
||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
|
||||
break;
|
||||
}
|
||||
msec_delay_irq(1);
|
||||
timeout--;
|
||||
}
|
||||
|
||||
if (!timeout) {
|
||||
DEBUGOUT("FW or HW has locked the resource for too long.\n");
|
||||
DEBUGOUT("SW/FW/HW has locked the resource for too long.\n");
|
||||
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
|
||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
|
||||
ret_val = -E1000_ERR_CONFIG;
|
||||
|
@ -511,77 +609,152 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
|
|||
}
|
||||
|
||||
/**
|
||||
* e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex
|
||||
* e1000_hv_phy_powerdown_workaround_ich8lan - Power down workaround on Sx
|
||||
* @hw: pointer to the HW structure
|
||||
**/
|
||||
s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
if ((hw->phy.type != e1000_phy_82577) || (hw->revision_id > 2))
|
||||
return E1000_SUCCESS;
|
||||
|
||||
return hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0444);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
|
||||
* done after every PHY reset.
|
||||
**/
|
||||
static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
return ret_val;
|
||||
|
||||
/* Hanksville M Phy init for IEEE. */
|
||||
if ((hw->revision_id == 2) &&
|
||||
(hw->phy.type == e1000_phy_82577) &&
|
||||
((hw->phy.revision == 2) || (hw->phy.revision == 3))) {
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8823);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0018);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8824);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0016);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8825);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x001A);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x888C);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x888D);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x888E);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0007);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8827);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8835);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8834);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0001);
|
||||
hw->phy.ops.write_reg(hw, 0x10, 0x8833);
|
||||
hw->phy.ops.write_reg(hw, 0x11, 0x0002);
|
||||
}
|
||||
|
||||
if (((hw->phy.type == e1000_phy_82577) &&
|
||||
((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
|
||||
((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
|
||||
/* Disable generation of early preamble */
|
||||
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(769, 25), 0x4431);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Preamble tuning for SSC */
|
||||
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(770, 16), 0xA204);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
if (hw->revision_id < 3) {
|
||||
/* PHY config */
|
||||
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x29,
|
||||
0x66C0);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* PHY config */
|
||||
ret_val = hw->phy.ops.write_reg(hw, (1 << 6) | 0x1E,
|
||||
0xFFFF);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return registers to default by doing a soft reset then
|
||||
* writing 0x3140 to the control register.
|
||||
*/
|
||||
if (hw->phy.revision < 2) {
|
||||
e1000_phy_sw_reset_generic(hw);
|
||||
ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL,
|
||||
0x3140);
|
||||
}
|
||||
}
|
||||
|
||||
if ((hw->revision_id == 2) &&
|
||||
(hw->phy.type == e1000_phy_82577) &&
|
||||
((hw->phy.revision == 2) || (hw->phy.revision == 3))) {
|
||||
/*
|
||||
* Workaround for OEM (GbE) not operating after reset -
|
||||
* restart AN (twice)
|
||||
*/
|
||||
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
ret_val = hw->phy.ops.write_reg(hw, PHY_REG(768, 25), 0x0400);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Select page 0 */
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
hw->phy.addr = 1;
|
||||
e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
|
||||
hw->phy.ops.release(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_lan_init_done_ich8lan - Check for PHY config completion
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Forces the speed and duplex settings of the PHY.
|
||||
* This is a function pointer entry point only called by
|
||||
* PHY setup routines.
|
||||
* Check the appropriate indication the MAC has finished configuring the
|
||||
* PHY after a software reset.
|
||||
**/
|
||||
static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
|
||||
static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
bool link;
|
||||
u32 data, loop = E1000_ICH8_LAN_INIT_TIMEOUT;
|
||||
|
||||
DEBUGFUNC("e1000_phy_force_speed_duplex_ich8lan");
|
||||
DEBUGFUNC("e1000_lan_init_done_ich8lan");
|
||||
|
||||
if (phy->type != e1000_phy_ife) {
|
||||
ret_val = e1000_phy_force_speed_duplex_igp(hw);
|
||||
goto out;
|
||||
}
|
||||
/* Wait for basic configuration completes before proceeding */
|
||||
do {
|
||||
data = E1000_READ_REG(hw, E1000_STATUS);
|
||||
data &= E1000_STATUS_LAN_INIT_DONE;
|
||||
usec_delay(100);
|
||||
} while ((!data) && --loop);
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
/*
|
||||
* If basic configuration is incomplete before the above loop
|
||||
* count reaches 0, loading the configuration from NVM will
|
||||
* leave the PHY in a bad state possibly resulting in no link.
|
||||
*/
|
||||
if (loop == 0)
|
||||
DEBUGOUT("LAN_INIT_DONE not set, increase timeout\n");
|
||||
|
||||
e1000_phy_force_speed_duplex_setup(hw, &data);
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disable MDI-X support for 10/100 */
|
||||
ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
data &= ~IFE_PMC_AUTO_MDIX;
|
||||
data &= ~IFE_PMC_FORCE_MDIX;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
DEBUGOUT1("IFE PMC: %X\n", data);
|
||||
|
||||
usec_delay(1);
|
||||
|
||||
if (phy->autoneg_wait_to_complete) {
|
||||
DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
|
||||
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (!link)
|
||||
DEBUGOUT("Link taking longer than expected.\n");
|
||||
|
||||
/* Try once more */
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
/* Clear the Init Done bit for the next init event */
|
||||
data = E1000_READ_REG(hw, E1000_STATUS);
|
||||
data &= ~E1000_STATUS_LAN_INIT_DONE;
|
||||
E1000_WRITE_REG(hw, E1000_STATUS, data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -597,7 +770,6 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
|||
struct e1000_phy_info *phy = &hw->phy;
|
||||
u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
|
||||
s32 ret_val;
|
||||
u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT;
|
||||
u16 word_addr, reg_data, reg_addr, phy_page = 0;
|
||||
|
||||
DEBUGFUNC("e1000_phy_hw_reset_ich8lan");
|
||||
|
@ -606,6 +778,15 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
|||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Allow time for h/w to get to a quiescent state after reset */
|
||||
msec_delay(10);
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the PHY from the NVM on ICH platforms. This
|
||||
* is needed due to an issue where the NVM configuration is
|
||||
|
@ -625,25 +806,8 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
|||
if (!(data & sw_cfg_mask))
|
||||
goto out;
|
||||
|
||||
/* Wait for basic configuration completes before proceeding*/
|
||||
do {
|
||||
data = E1000_READ_REG(hw, E1000_STATUS);
|
||||
data &= E1000_STATUS_LAN_INIT_DONE;
|
||||
usec_delay(100);
|
||||
} while ((!data) && --loop);
|
||||
|
||||
/*
|
||||
* If basic configuration is incomplete before the above loop
|
||||
* count reaches 0, loading the configuration from NVM will
|
||||
* leave the PHY in a bad state possibly resulting in no link.
|
||||
*/
|
||||
if (loop == 0)
|
||||
DEBUGOUT("LAN_INIT_DONE not set, increase timeout\n");
|
||||
|
||||
/* Clear the Init Done bit for the next init event */
|
||||
data = E1000_READ_REG(hw, E1000_STATUS);
|
||||
data &= ~E1000_STATUS_LAN_INIT_DONE;
|
||||
E1000_WRITE_REG(hw, E1000_STATUS, data);
|
||||
/* Wait for basic configuration completes before proceeding */
|
||||
e1000_lan_init_done_ich8lan(hw);
|
||||
|
||||
/*
|
||||
* Make sure HW does not configure LCD from PHY
|
||||
|
@ -714,6 +878,8 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
|
|||
break;
|
||||
case e1000_phy_igp_3:
|
||||
case e1000_phy_bm:
|
||||
case e1000_phy_82578:
|
||||
case e1000_phy_82577:
|
||||
ret_val = e1000_get_phy_info_igp(hw);
|
||||
break;
|
||||
default:
|
||||
|
@ -757,7 +923,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
|
|||
? FALSE : TRUE;
|
||||
|
||||
if (phy->polarity_correction) {
|
||||
ret_val = e1000_check_polarity_ife_ich8lan(hw);
|
||||
ret_val = e1000_check_polarity_ife(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
} else {
|
||||
|
@ -782,43 +948,6 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Polarity is determined on the polarity reversal feature being enabled.
|
||||
* This function is only called by other family-specific
|
||||
* routines.
|
||||
**/
|
||||
static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data, offset, mask;
|
||||
|
||||
DEBUGFUNC("e1000_check_polarity_ife_ich8lan");
|
||||
|
||||
/*
|
||||
* Polarity is determined based on the reversal feature being enabled.
|
||||
*/
|
||||
if (phy->polarity_correction) {
|
||||
offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
|
||||
mask = IFE_PESC_POLARITY_REVERSED;
|
||||
} else {
|
||||
offset = IFE_PHY_SPECIAL_CONTROL;
|
||||
mask = IFE_PSC_FORCE_POLARITY;
|
||||
}
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, offset, &phy_data);
|
||||
|
||||
if (!ret_val)
|
||||
phy->cable_polarity = (phy_data & mask)
|
||||
? e1000_rev_polarity_reversed
|
||||
: e1000_rev_polarity_normal;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -850,12 +979,14 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
|
|||
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
|
||||
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
|
||||
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Call gig speed drop workaround on LPLU before accessing
|
||||
* any PHY registers
|
||||
*/
|
||||
if ((hw->mac.type == e1000_ich8lan) &&
|
||||
(hw->phy.type == e1000_phy_igp_3))
|
||||
if (hw->mac.type == e1000_ich8lan)
|
||||
e1000_gig_downshift_workaround_ich8lan(hw);
|
||||
|
||||
/* When LPLU is enabled, we should disable SmartSpeed */
|
||||
|
@ -872,6 +1003,9 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
|
|||
phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
|
||||
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
|
||||
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
* during Dx states where the power conservation is most
|
||||
|
@ -938,6 +1072,10 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
|
|||
if (!active) {
|
||||
phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
|
||||
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
|
||||
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* LPLU and SmartSpeed are mutually exclusive. LPLU is used
|
||||
* during Dx states where the power conservation is most
|
||||
|
@ -977,12 +1115,14 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
|
|||
phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
|
||||
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
|
||||
|
||||
if (phy->type != e1000_phy_igp_3)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Call gig speed drop workaround on LPLU before accessing
|
||||
* any PHY registers
|
||||
*/
|
||||
if ((hw->mac.type == e1000_ich8lan) &&
|
||||
(hw->phy.type == e1000_phy_igp_3))
|
||||
if (hw->mac.type == e1000_ich8lan)
|
||||
e1000_gig_downshift_workaround_ich8lan(hw);
|
||||
|
||||
/* When LPLU is enabled, we should disable SmartSpeed */
|
||||
|
@ -1818,7 +1958,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
|
|||
break;
|
||||
case 1:
|
||||
sector_size = ICH_FLASH_SEG_SIZE_4K;
|
||||
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K;
|
||||
iteration = 1;
|
||||
break;
|
||||
case 2:
|
||||
if (hw->mac.type == e1000_ich9lan) {
|
||||
|
@ -1831,7 +1971,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
|
|||
break;
|
||||
case 3:
|
||||
sector_size = ICH_FLASH_SEG_SIZE_64K;
|
||||
iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K;
|
||||
iteration = 1;
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_NVM;
|
||||
|
@ -1921,6 +2061,81 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_id_led_init_pchlan - store LED configurations
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* PCH does not control LEDs via the LEDCTL register, rather it uses
|
||||
* the PHY LED configuration register.
|
||||
*
|
||||
* PCH also does not have an "always on" or "always off" mode which
|
||||
* complicates the ID feature. Instead of using the "on" mode to indicate
|
||||
* in ledctl_mode2 the LEDs to use for ID (see e1000_id_led_init_generic()),
|
||||
* use "link_up" mode. The LEDs will still ID on request if there is no
|
||||
* link based on logic in e1000_led_[on|off]_pchlan().
|
||||
**/
|
||||
static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val;
|
||||
const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP;
|
||||
const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT;
|
||||
u16 data, i, temp, shift;
|
||||
|
||||
DEBUGFUNC("e1000_id_led_init_pchlan");
|
||||
|
||||
/* Get default ID LED modes */
|
||||
ret_val = hw->nvm.ops.valid_led_default(hw, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
mac->ledctl_default = E1000_READ_REG(hw, E1000_LEDCTL);
|
||||
mac->ledctl_mode1 = mac->ledctl_default;
|
||||
mac->ledctl_mode2 = mac->ledctl_default;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK;
|
||||
shift = (i * 5);
|
||||
switch (temp) {
|
||||
case ID_LED_ON1_DEF2:
|
||||
case ID_LED_ON1_ON2:
|
||||
case ID_LED_ON1_OFF2:
|
||||
mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode1 |= (ledctl_on << shift);
|
||||
break;
|
||||
case ID_LED_OFF1_DEF2:
|
||||
case ID_LED_OFF1_ON2:
|
||||
case ID_LED_OFF1_OFF2:
|
||||
mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode1 |= (ledctl_off << shift);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
switch (temp) {
|
||||
case ID_LED_DEF1_ON2:
|
||||
case ID_LED_ON1_ON2:
|
||||
case ID_LED_OFF1_ON2:
|
||||
mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode2 |= (ledctl_on << shift);
|
||||
break;
|
||||
case ID_LED_DEF1_OFF2:
|
||||
case ID_LED_ON1_OFF2:
|
||||
case ID_LED_OFF1_OFF2:
|
||||
mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
|
||||
mac->ledctl_mode2 |= (ledctl_off << shift);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_bus_info_ich8lan - Get/Set the bus type and width
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -1996,6 +2211,13 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
ctrl = E1000_READ_REG(hw, E1000_CTRL);
|
||||
|
||||
if (!hw->phy.ops.check_reset_block(hw) && !hw->phy.reset_disable) {
|
||||
/* Clear PHY Reset Asserted bit */
|
||||
if (hw->mac.type >= e1000_pchlan) {
|
||||
u32 status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
E1000_WRITE_REG(hw, E1000_STATUS, status &
|
||||
~E1000_STATUS_PHYRA);
|
||||
}
|
||||
|
||||
/*
|
||||
* PHY HW reset requires MAC CORE reset at the same
|
||||
* time to make sure the interface between MAC and the
|
||||
|
@ -2008,14 +2230,24 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST));
|
||||
msec_delay(20);
|
||||
|
||||
ret_val = e1000_get_auto_rd_done_generic(hw);
|
||||
if (ret_val) {
|
||||
/*
|
||||
* When auto config read does not complete, do not
|
||||
* return with an error. This can happen in situations
|
||||
* where there is no eeprom and prevents getting link.
|
||||
*/
|
||||
DEBUGOUT("Auto Read Done did not complete\n");
|
||||
if (!ret_val)
|
||||
e1000_release_swflag_ich8lan(hw);
|
||||
|
||||
if (ctrl & E1000_CTRL_PHY_RST)
|
||||
ret_val = hw->phy.ops.get_cfg_done(hw);
|
||||
|
||||
if (hw->mac.type >= e1000_ich10lan) {
|
||||
e1000_lan_init_done_ich8lan(hw);
|
||||
} else {
|
||||
ret_val = e1000_get_auto_rd_done_generic(hw);
|
||||
if (ret_val) {
|
||||
/*
|
||||
* When auto config read does not complete, do not
|
||||
* return with an error. This can happen in situations
|
||||
* where there is no eeprom and prevents getting link.
|
||||
*/
|
||||
DEBUGOUT("Auto Read Done did not complete\n");
|
||||
}
|
||||
}
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
|
||||
|
@ -2025,6 +2257,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
|||
kab |= E1000_KABGTXD_BGSQLBIAS;
|
||||
E1000_WRITE_REG(hw, E1000_KABGTXD, kab);
|
||||
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
@ -2065,6 +2300,18 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
|
|||
for (i = 0; i < mac->mta_reg_count; i++)
|
||||
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
|
||||
|
||||
/*
|
||||
* The 82578 Rx buffer will stall if wakeup is enabled in host and
|
||||
* the ME. Reading the BM_WUC register will clear the host wakeup bit.
|
||||
* Reset the phy after disabling host wakeup to reset the Rx buffer.
|
||||
*/
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
hw->phy.ops.read_reg(hw, BM_WUC, &i);
|
||||
ret_val = e1000_phy_hw_reset_ich8lan(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/* Setup link and flow control */
|
||||
ret_val = mac->ops.setup_link(hw);
|
||||
|
||||
|
@ -2122,6 +2369,9 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
|
|||
/* Extended Device Control */
|
||||
reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
reg |= (1 << 22);
|
||||
/* Enable PHY low-power state when MAC is at D3 w/o WoL */
|
||||
if (hw->mac.type >= e1000_pchlan)
|
||||
reg |= E1000_CTRL_EXT_PHYPDEN;
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
|
||||
|
||||
/* Transmit Descriptor Control 0 */
|
||||
|
@ -2202,6 +2452,14 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
|
|||
goto out;
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time);
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
ret_val = hw->phy.ops.write_reg(hw,
|
||||
PHY_REG(BM_PORT_CTRL_PAGE, 27),
|
||||
hw->fc.pause_time);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = e1000_set_fc_watermarks_generic(hw);
|
||||
|
||||
|
@ -2235,16 +2493,19 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
* and increase the max iterations when polling the phy;
|
||||
* this fixes erroneous timeouts at 10Mbps.
|
||||
*/
|
||||
ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 4),
|
||||
ret_val = e1000_write_kmrn_reg_generic(hw,
|
||||
E1000_KMRNCTRLSTA_TIMEOUTS,
|
||||
0xFFFF);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
ret_val = e1000_read_kmrn_reg_generic(hw, GG82563_REG(0x34, 9),
|
||||
ret_val = e1000_read_kmrn_reg_generic(hw,
|
||||
E1000_KMRNCTRLSTA_INBAND_PARAM,
|
||||
®_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
reg_data |= 0x3F;
|
||||
ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 9),
|
||||
ret_val = e1000_write_kmrn_reg_generic(hw,
|
||||
E1000_KMRNCTRLSTA_INBAND_PARAM,
|
||||
reg_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
@ -2256,10 +2517,16 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
|
|||
goto out;
|
||||
break;
|
||||
case e1000_phy_bm:
|
||||
case e1000_phy_82578:
|
||||
ret_val = e1000_copper_link_setup_m88(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
break;
|
||||
case e1000_phy_82577:
|
||||
ret_val = e1000_copper_link_setup_82577(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
break;
|
||||
case e1000_phy_ife:
|
||||
ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL,
|
||||
®_data);
|
||||
|
@ -2543,10 +2810,15 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw)
|
|||
switch (hw->mac.type) {
|
||||
case e1000_ich9lan:
|
||||
case e1000_ich10lan:
|
||||
case e1000_pchlan:
|
||||
phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL);
|
||||
phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
|
||||
E1000_PHY_CTRL_GBE_DISABLE;
|
||||
E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl);
|
||||
|
||||
/* Workaround SWFLAG unexpectedly set during S0->Sx */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
usec_delay(500);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2618,6 +2890,100 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_setup_led_pchlan - Configures SW controllable LED
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This prepares the SW controllable LED for use.
|
||||
**/
|
||||
static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_setup_led_pchlan");
|
||||
|
||||
return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
|
||||
(u16)hw->mac.ledctl_mode1);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_cleanup_led_pchlan - Restore the default LED operation
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Return the LED back to the default configuration.
|
||||
**/
|
||||
static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
DEBUGFUNC("e1000_cleanup_led_pchlan");
|
||||
|
||||
return hw->phy.ops.write_reg(hw, HV_LED_CONFIG,
|
||||
(u16)hw->mac.ledctl_default);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_led_on_pchlan - Turn LEDs on
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Turn on the LEDs.
|
||||
**/
|
||||
static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
u16 data = (u16)hw->mac.ledctl_mode2;
|
||||
u32 i, led;
|
||||
|
||||
DEBUGFUNC("e1000_led_on_pchlan");
|
||||
|
||||
/*
|
||||
* If no link, then turn LED on by setting the invert bit
|
||||
* for each LED that's mode is "link_up" in ledctl_mode2.
|
||||
*/
|
||||
if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
|
||||
if ((led & E1000_PHY_LED0_MODE_MASK) !=
|
||||
E1000_LEDCTL_MODE_LINK_UP)
|
||||
continue;
|
||||
if (led & E1000_PHY_LED0_IVRT)
|
||||
data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
|
||||
else
|
||||
data |= (E1000_PHY_LED0_IVRT << (i * 5));
|
||||
}
|
||||
}
|
||||
|
||||
return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_led_off_pchlan - Turn LEDs off
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Turn off the LEDs.
|
||||
**/
|
||||
static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
|
||||
{
|
||||
u16 data = (u16)hw->mac.ledctl_mode1;
|
||||
u32 i, led;
|
||||
|
||||
DEBUGFUNC("e1000_led_off_pchlan");
|
||||
|
||||
/*
|
||||
* If no link, then turn LED off by clearing the invert bit
|
||||
* for each LED that's mode is "link_up" in ledctl_mode1.
|
||||
*/
|
||||
if (!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
|
||||
if ((led & E1000_PHY_LED0_MODE_MASK) !=
|
||||
E1000_LEDCTL_MODE_LINK_UP)
|
||||
continue;
|
||||
if (led & E1000_PHY_LED0_IVRT)
|
||||
data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
|
||||
else
|
||||
data |= (E1000_PHY_LED0_IVRT << (i * 5));
|
||||
}
|
||||
}
|
||||
|
||||
return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_cfg_done_ich8lan - Read config done bit
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -2633,10 +2999,21 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
|
|||
s32 ret_val = E1000_SUCCESS;
|
||||
u32 bank = 0;
|
||||
|
||||
if (hw->mac.type >= e1000_pchlan) {
|
||||
u32 status = E1000_READ_REG(hw, E1000_STATUS);
|
||||
|
||||
if (status & E1000_STATUS_PHYRA) {
|
||||
E1000_WRITE_REG(hw, E1000_STATUS, status &
|
||||
~E1000_STATUS_PHYRA);
|
||||
} else
|
||||
DEBUGOUT("PHY Reset Asserted not set - needs delay\n");
|
||||
}
|
||||
|
||||
e1000_get_cfg_done_generic(hw);
|
||||
|
||||
/* If EEPROM is not marked present, init the IGP 3 PHY manually */
|
||||
if (hw->mac.type != e1000_ich10lan) {
|
||||
if ((hw->mac.type != e1000_ich10lan) &&
|
||||
(hw->mac.type != e1000_pchlan)) {
|
||||
if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) &&
|
||||
(hw->phy.type == e1000_phy_igp_3)) {
|
||||
e1000_phy_init_script_igp3(hw);
|
||||
|
@ -2678,6 +3055,8 @@ static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw)
|
|||
**/
|
||||
static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
u16 phy_data;
|
||||
|
||||
DEBUGFUNC("e1000_clear_hw_cntrs_ich8lan");
|
||||
|
||||
e1000_clear_hw_cntrs_base_generic(hw);
|
||||
|
@ -2695,5 +3074,24 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
|
|||
|
||||
E1000_READ_REG(hw, E1000_IAC);
|
||||
E1000_READ_REG(hw, E1000_ICRXOC);
|
||||
|
||||
/* Clear PHY statistics registers */
|
||||
if ((hw->phy.type == e1000_phy_82578) ||
|
||||
(hw->phy.type == e1000_phy_82577)) {
|
||||
hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_ECOL_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_ECOL_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_MCC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_MCC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_LATECOL_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_LATECOL_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_COLC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_COLC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_DC_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_DC_LOWER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_TNCRS_UPPER, &phy_data);
|
||||
hw->phy.ops.read_reg(hw, HV_TNCRS_LOWER, &phy_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,6 +121,25 @@
|
|||
#define BM_RCTL_PMCF 0x0040 /* Pass MAC Control Frames */
|
||||
#define BM_RCTL_RFCE 0x0080 /* Rx Flow Control Enable */
|
||||
|
||||
#define HV_LED_CONFIG PHY_REG(768, 30) /* LED Configuration */
|
||||
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
|
||||
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
|
||||
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
|
||||
#define HV_SCC_UPPER PHY_REG(778, 16) /* Single Collision Count */
|
||||
#define HV_SCC_LOWER PHY_REG(778, 17)
|
||||
#define HV_ECOL_UPPER PHY_REG(778, 18) /* Excessive Collision Count */
|
||||
#define HV_ECOL_LOWER PHY_REG(778, 19)
|
||||
#define HV_MCC_UPPER PHY_REG(778, 20) /* Multiple Collision Count */
|
||||
#define HV_MCC_LOWER PHY_REG(778, 21)
|
||||
#define HV_LATECOL_UPPER PHY_REG(778, 23) /* Late Collision Count */
|
||||
#define HV_LATECOL_LOWER PHY_REG(778, 24)
|
||||
#define HV_COLC_UPPER PHY_REG(778, 25) /* Collision Count */
|
||||
#define HV_COLC_LOWER PHY_REG(778, 26)
|
||||
#define HV_DC_UPPER PHY_REG(778, 27) /* Defer Count */
|
||||
#define HV_DC_LOWER PHY_REG(778, 28)
|
||||
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
|
||||
#define HV_TNCRS_LOWER PHY_REG(778, 30)
|
||||
|
||||
/*
|
||||
* Additional interrupts need to be handled for ICH family:
|
||||
* DSW = The FW changed the status of the DISSW bit in FWSM
|
||||
|
@ -150,8 +169,6 @@ void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
|
|||
void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
||||
void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
|
||||
void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw);
|
||||
#if defined(HANKSVILLE_HW) && !defined(NO_PCH_A_SUPPORT)
|
||||
s32 e1000_hv_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -750,6 +750,12 @@ s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw)
|
|||
|
||||
mac->get_link_status = FALSE;
|
||||
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
ret_val = e1000_link_stall_workaround_hv(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if there was DownShift, must be checked
|
||||
* immediately after link-up
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -41,13 +41,13 @@
|
|||
*/
|
||||
|
||||
void
|
||||
e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||||
e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
|
||||
{
|
||||
pci_write_config(((struct e1000_osdep *)hw->back)->dev, reg, *value, 2);
|
||||
}
|
||||
|
||||
void
|
||||
e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||||
e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value)
|
||||
{
|
||||
*value = pci_read_config(((struct e1000_osdep *)hw->back)->dev, reg, 2);
|
||||
}
|
||||
|
@ -70,12 +70,26 @@ e1000_pci_clear_mwi(struct e1000_hw *hw)
|
|||
* Read the PCI Express capabilities
|
||||
*/
|
||||
int32_t
|
||||
e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
|
||||
e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
|
||||
{
|
||||
u32 result;
|
||||
device_t dev = ((struct e1000_osdep *)hw->back)->dev;
|
||||
u32 offset;
|
||||
|
||||
pci_find_extcap(((struct e1000_osdep *)hw->back)->dev,
|
||||
reg, &result);
|
||||
*value = (u16)result;
|
||||
pci_find_extcap(dev, PCIY_EXPRESS, &offset);
|
||||
*value = pci_read_config(dev, offset + reg, 2);
|
||||
return (E1000_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the PCI Express capabilities
|
||||
*/
|
||||
int32_t
|
||||
e1000_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value)
|
||||
{
|
||||
device_t dev = ((struct e1000_osdep *)hw->back)->dev;
|
||||
u32 offset;
|
||||
|
||||
pci_find_extcap(dev, PCIY_EXPRESS, &offset);
|
||||
pci_write_config(dev, offset + reg, *value, 2);
|
||||
return (E1000_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
|
||||
static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read);
|
||||
static u32 e1000_get_phy_addr_for_hv_page(u32 page);
|
||||
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read);
|
||||
|
||||
/* Cable length tables */
|
||||
static const u16 e1000_m88_cable_length_table[] =
|
||||
{ 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED };
|
||||
|
@ -161,26 +165,46 @@ s32 e1000_get_phy_id(struct e1000_hw *hw)
|
|||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 phy_id;
|
||||
u16 retry_count = 0;
|
||||
|
||||
DEBUGFUNC("e1000_get_phy_id");
|
||||
|
||||
if (!(phy->ops.read_reg))
|
||||
goto out;
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
while (retry_count < 2) {
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy->id = (u32)(phy_id << 16);
|
||||
usec_delay(20);
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
phy->id = (u32)(phy_id << 16);
|
||||
usec_delay(20);
|
||||
ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
|
||||
phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
|
||||
phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
|
||||
phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
|
||||
|
||||
if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* If the PHY ID is still unknown, we may have an 82577 without link.
|
||||
* We will try again after setting Slow MDIC mode. No harm in trying
|
||||
* again in this case since the PHY ID is unknown at this point anyway
|
||||
*/
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
retry_count++;
|
||||
}
|
||||
out:
|
||||
/* Revert to MDIO fast mode, if applicable */
|
||||
if (retry_count)
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
@ -237,12 +261,10 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
|||
|
||||
E1000_WRITE_REG(hw, E1000_MDIC, mdic);
|
||||
|
||||
#if defined(HANKSVILLE_HW) && !defined(NO_PCH_A_SUPPORT)
|
||||
/* Workaround for Si errata */
|
||||
if ((hw->phy.type == e1000_phy_lsi) && (hw->revision_id <= 2 ))
|
||||
if ((hw->phy.type == e1000_phy_82577) && (hw->revision_id <= 2))
|
||||
msec_delay(10);
|
||||
|
||||
#endif /* HANKSVILLE_HW && !NO_PCH_A_SUPPORT */
|
||||
/*
|
||||
* Poll the ready bit to see if the MDI read completed
|
||||
* Increasing the time out as testing showed failures with
|
||||
|
@ -298,12 +320,10 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
|||
|
||||
E1000_WRITE_REG(hw, E1000_MDIC, mdic);
|
||||
|
||||
#if defined(HANKSVILLE_HW) && !defined(NO_PCH_A_SUPPORT)
|
||||
/* Workaround for Si errata */
|
||||
if ((hw->phy.type == e1000_phy_lsi) && (hw->revision_id <= 2))
|
||||
if ((hw->phy.type == e1000_phy_82577) && (hw->revision_id <= 2))
|
||||
msec_delay(10);
|
||||
|
||||
#endif /* HANKSVILLE_HW && !NO_PCH_A_SUPPORT */
|
||||
/*
|
||||
* Poll the ready bit to see if the MDI read completed
|
||||
* Increasing the time out as testing showed failures with
|
||||
|
@ -550,6 +570,50 @@ s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Sets up Carrier-sense on Transmit and downshift values.
|
||||
**/
|
||||
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data;
|
||||
|
||||
DEBUGFUNC("e1000_copper_link_setup_82577");
|
||||
|
||||
if (phy->reset_disable) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Enable CRS on TX. This must be set for half-duplex operation. */
|
||||
ret_val = phy->ops.read_reg(hw, I82577_CFG_REG, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
|
||||
|
||||
/* Enable downshift */
|
||||
phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, I82577_CFG_REG, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Set number of link attempts before downshift */
|
||||
ret_val = phy->ops.read_reg(hw, I82577_CTRL_REG, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
|
||||
ret_val = phy->ops.write_reg(hw, I82577_CTRL_REG, phy_data);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -675,6 +739,21 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (phy->type == e1000_phy_82578) {
|
||||
ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
|
||||
&phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* 82578 PHY - set the downshift count to 1x. */
|
||||
phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
|
||||
phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
|
||||
ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
|
||||
phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
@ -1297,6 +1376,80 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_phy_force_speed_duplex_ife - Force PHY speed & duplex
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Forces the speed and duplex settings of the PHY.
|
||||
* This is a function pointer entry point only called by
|
||||
* PHY setup routines.
|
||||
**/
|
||||
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
bool link;
|
||||
|
||||
DEBUGFUNC("e1000_phy_force_speed_duplex_ife");
|
||||
|
||||
if (phy->type != e1000_phy_ife) {
|
||||
ret_val = e1000_phy_force_speed_duplex_igp(hw);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
e1000_phy_force_speed_duplex_setup(hw, &data);
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disable MDI-X support for 10/100 */
|
||||
ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
data &= ~IFE_PMC_AUTO_MDIX;
|
||||
data &= ~IFE_PMC_FORCE_MDIX;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
DEBUGOUT1("IFE PMC: %X\n", data);
|
||||
|
||||
usec_delay(1);
|
||||
|
||||
if (phy->autoneg_wait_to_complete) {
|
||||
DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n");
|
||||
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (!link)
|
||||
DEBUGOUT("Link taking longer than expected.\n");
|
||||
|
||||
/* Try once more */
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -1471,6 +1624,8 @@ s32 e1000_check_downshift_generic(struct e1000_hw *hw)
|
|||
case e1000_phy_m88:
|
||||
case e1000_phy_gg82563:
|
||||
case e1000_phy_bm:
|
||||
case e1000_phy_82578:
|
||||
case e1000_phy_82577:
|
||||
offset = M88E1000_PHY_SPEC_STATUS;
|
||||
mask = M88E1000_PSSR_DOWNSHIFT;
|
||||
break;
|
||||
|
@ -1571,6 +1726,41 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw)
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_polarity_ife - Check cable polarity for IFE PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Polarity is determined on the polarity reversal feature being enabled.
|
||||
**/
|
||||
s32 e1000_check_polarity_ife(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data, offset, mask;
|
||||
|
||||
DEBUGFUNC("e1000_check_polarity_ife");
|
||||
|
||||
/*
|
||||
* Polarity is determined based on the reversal feature being enabled.
|
||||
*/
|
||||
if (phy->polarity_correction) {
|
||||
offset = IFE_PHY_EXTENDED_STATUS_CONTROL;
|
||||
mask = IFE_PESC_POLARITY_REVERSED;
|
||||
} else {
|
||||
offset = IFE_PHY_SPECIAL_CONTROL;
|
||||
mask = IFE_PSC_FORCE_POLARITY;
|
||||
}
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, offset, &phy_data);
|
||||
|
||||
if (!ret_val)
|
||||
phy->cable_polarity = (phy_data & mask)
|
||||
? e1000_rev_polarity_reversed
|
||||
: e1000_rev_polarity_normal;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_wait_autoneg_generic - Wait for auto-neg completion
|
||||
* @hw: pointer to the HW structure
|
||||
|
@ -1635,9 +1825,16 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
|
|||
* it across the board.
|
||||
*/
|
||||
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
|
||||
if (ret_val)
|
||||
break;
|
||||
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status);
|
||||
if (ret_val) {
|
||||
/*
|
||||
* If the first read fails, another entity may have
|
||||
* ownership of the resources, wait and try again to
|
||||
* see if they have relinquished the resources yet.
|
||||
*/
|
||||
usec_delay(usec_interval);
|
||||
ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS,
|
||||
&phy_status);
|
||||
}
|
||||
if (ret_val)
|
||||
break;
|
||||
if (phy_status & MII_SR_LINK_STATUS)
|
||||
|
@ -2130,6 +2327,12 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
|
|||
case BME1000_E_PHY_ID_R2:
|
||||
phy_type = e1000_phy_bm;
|
||||
break;
|
||||
case I82578_E_PHY_ID:
|
||||
phy_type = e1000_phy_82578;
|
||||
break;
|
||||
case I82577_E_PHY_ID:
|
||||
phy_type = e1000_phy_82577;
|
||||
break;
|
||||
default:
|
||||
phy_type = e1000_phy_unknown;
|
||||
break;
|
||||
|
@ -2447,6 +2650,11 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
|
|||
|
||||
DEBUGFUNC("e1000_access_phy_wakeup_reg_bm");
|
||||
|
||||
/* Gig must be disabled for MDIO accesses to page 800 */
|
||||
if ((hw->mac.type == e1000_pchlan) &&
|
||||
(!(E1000_READ_REG(hw, E1000_PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
|
||||
DEBUGOUT("Attempting to access page 800 while gig enabled.\n");
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Could not acquire PHY\n");
|
||||
|
@ -2566,3 +2774,545 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw)
|
|||
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
|
||||
msec_delay(1);
|
||||
}
|
||||
|
||||
s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 data = 0;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
|
||||
hw->phy.addr = 1;
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
|
||||
(BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
|
||||
if (ret_val) {
|
||||
hw->phy.ops.release(hw);
|
||||
return ret_val;
|
||||
}
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, BM_CS_CTRL1,
|
||||
(0x2180 | (slow << 10)));
|
||||
|
||||
/* dummy read when reverting to fast mode - throw away result */
|
||||
if (!slow)
|
||||
e1000_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
|
||||
|
||||
hw->phy.ops.release(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_phy_reg_hv - Read HV PHY register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to be read
|
||||
* @data: pointer to the read data
|
||||
*
|
||||
* Acquires semaphore, if necessary, then reads the PHY register at offset
|
||||
* and storing the retrieved information in data. Release any acquired
|
||||
* semaphore before exiting.
|
||||
**/
|
||||
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 page = BM_PHY_REG_PAGE(offset);
|
||||
u16 reg = BM_PHY_REG_NUM(offset);
|
||||
bool in_slow_mode = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_read_phy_reg_hv");
|
||||
|
||||
/* Workaround failure in MDIO access while cable is disconnected */
|
||||
if ((hw->phy.type == e1000_phy_82577) &&
|
||||
!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
in_slow_mode = TRUE;
|
||||
}
|
||||
|
||||
/* Page 800 works differently than the rest so it has its own func */
|
||||
if (page == BM_WUC_PAGE) {
|
||||
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
|
||||
data, TRUE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (page > 0 && page < HV_INTC_FC_PAGE_START) {
|
||||
ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
|
||||
data, TRUE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
|
||||
|
||||
if (page == HV_INTC_FC_PAGE_START)
|
||||
page = 0;
|
||||
|
||||
if (reg > MAX_PHY_MULTI_PAGE_REG) {
|
||||
if ((hw->phy.type != e1000_phy_82578) ||
|
||||
((reg != I82578_ADDR_REG) &&
|
||||
(reg != I82578_ADDR_REG + 1))) {
|
||||
u32 phy_addr = hw->phy.addr;
|
||||
|
||||
hw->phy.addr = 1;
|
||||
|
||||
/* Page is shifted left, PHY expects (page x 32) */
|
||||
ret_val = e1000_write_phy_reg_mdic(hw,
|
||||
IGP01E1000_PHY_PAGE_SELECT,
|
||||
(page << IGP_PAGE_SHIFT));
|
||||
if (ret_val) {
|
||||
hw->phy.ops.release(hw);
|
||||
goto out;
|
||||
}
|
||||
hw->phy.addr = phy_addr;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
|
||||
data);
|
||||
hw->phy.ops.release(hw);
|
||||
|
||||
out:
|
||||
/* Revert to MDIO fast mode, if applicable */
|
||||
if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_phy_reg_hv - Write HV PHY register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to write to
|
||||
* @data: data to write at register offset
|
||||
*
|
||||
* Acquires semaphore, if necessary, then writes the data to PHY register
|
||||
* at the offset. Release any acquired semaphores before exiting.
|
||||
**/
|
||||
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
{
|
||||
s32 ret_val;
|
||||
u16 page = BM_PHY_REG_PAGE(offset);
|
||||
u16 reg = BM_PHY_REG_NUM(offset);
|
||||
bool in_slow_mode = FALSE;
|
||||
|
||||
DEBUGFUNC("e1000_write_phy_reg_hv");
|
||||
|
||||
/* Workaround failure in MDIO access while cable is disconnected */
|
||||
if ((hw->phy.type == e1000_phy_82577) &&
|
||||
!(E1000_READ_REG(hw, E1000_STATUS) & E1000_STATUS_LU)) {
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, TRUE);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
in_slow_mode = TRUE;
|
||||
}
|
||||
|
||||
/* Page 800 works differently than the rest so it has its own func */
|
||||
if (page == BM_WUC_PAGE) {
|
||||
ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
|
||||
&data, FALSE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (page > 0 && page < HV_INTC_FC_PAGE_START) {
|
||||
ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
|
||||
&data, FALSE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
|
||||
|
||||
if (page == HV_INTC_FC_PAGE_START)
|
||||
page = 0;
|
||||
|
||||
/*
|
||||
* Workaround MDIO accesses being disabled after entering IEEE Power
|
||||
* Down (whenever bit 11 of the PHY Control register is set)
|
||||
*/
|
||||
if ((hw->phy.type == e1000_phy_82578) &&
|
||||
(hw->phy.revision >= 1) &&
|
||||
(hw->phy.addr == 2) &&
|
||||
((MAX_PHY_REG_ADDRESS & reg) == 0) &&
|
||||
(data & (1 << 11))) {
|
||||
u16 data2 = 0x7EFF;
|
||||
hw->phy.ops.release(hw);
|
||||
ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
|
||||
&data2, FALSE);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (reg > MAX_PHY_MULTI_PAGE_REG) {
|
||||
if ((hw->phy.type != e1000_phy_82578) ||
|
||||
((reg != I82578_ADDR_REG) &&
|
||||
(reg != I82578_ADDR_REG + 1))) {
|
||||
u32 phy_addr = hw->phy.addr;
|
||||
|
||||
hw->phy.addr = 1;
|
||||
|
||||
/* Page is shifted left, PHY expects (page x 32) */
|
||||
ret_val = e1000_write_phy_reg_mdic(hw,
|
||||
IGP01E1000_PHY_PAGE_SELECT,
|
||||
(page << IGP_PAGE_SHIFT));
|
||||
if (ret_val) {
|
||||
hw->phy.ops.release(hw);
|
||||
goto out;
|
||||
}
|
||||
hw->phy.addr = phy_addr;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
|
||||
data);
|
||||
hw->phy.ops.release(hw);
|
||||
|
||||
out:
|
||||
/* Revert to MDIO fast mode, if applicable */
|
||||
if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
|
||||
ret_val = e1000_set_mdio_slow_mode_hv(hw, FALSE);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
|
||||
* @page: page to be accessed
|
||||
**/
|
||||
static u32 e1000_get_phy_addr_for_hv_page(u32 page)
|
||||
{
|
||||
u32 phy_addr = 2;
|
||||
|
||||
if (page >= HV_INTC_FC_PAGE_START)
|
||||
phy_addr = 1;
|
||||
|
||||
return phy_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to be read or written
|
||||
* @data: pointer to the data to be read or written
|
||||
* @read: determines if operation is read or written
|
||||
*
|
||||
* Acquires semaphore, if necessary, then reads the PHY register at offset
|
||||
* and storing the retreived information in data. Release any acquired
|
||||
* semaphores before exiting. Note that the procedure to read these regs
|
||||
* uses the address port and data port to read/write.
|
||||
**/
|
||||
static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data, bool read)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 addr_reg = 0;
|
||||
u32 data_reg = 0;
|
||||
u8 phy_acquired = 1;
|
||||
|
||||
DEBUGFUNC("e1000_access_phy_debug_regs_hv");
|
||||
|
||||
/* This takes care of the difference with desktop vs mobile phy */
|
||||
addr_reg = (hw->phy.type == e1000_phy_82578) ?
|
||||
I82578_ADDR_REG : I82577_ADDR_REG;
|
||||
data_reg = addr_reg + 1;
|
||||
|
||||
ret_val = hw->phy.ops.acquire(hw);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Could not acquire PHY\n");
|
||||
phy_acquired = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* All operations in this function are phy address 2 */
|
||||
hw->phy.addr = 2;
|
||||
|
||||
/* masking with 0x3F to remove the page from offset */
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Could not write PHY the HV address register\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Read or write the data value next */
|
||||
if (read)
|
||||
ret_val = e1000_read_phy_reg_mdic(hw, data_reg, data);
|
||||
else
|
||||
ret_val = e1000_write_phy_reg_mdic(hw, data_reg, *data);
|
||||
|
||||
if (ret_val) {
|
||||
DEBUGOUT("Could not read data value from HV data register\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (phy_acquired == 1)
|
||||
hw->phy.ops.release(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_link_stall_workaround_hv - Si workaround
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* This function works around a Si bug where the link partner can get
|
||||
* a link up indication before the PHY does. If small packets are sent
|
||||
* by the link partner they can be placed in the packet buffer without
|
||||
* being properly accounted for by the PHY and will stall preventing
|
||||
* further packets from being received. The workaround is to clear the
|
||||
* packet buffer after the PHY detects link up.
|
||||
**/
|
||||
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val = E1000_SUCCESS;
|
||||
u16 data;
|
||||
|
||||
DEBUGFUNC("e1000_link_stall_workaround_hv");
|
||||
|
||||
if (hw->phy.type != e1000_phy_82578)
|
||||
goto out;
|
||||
|
||||
/* Do not apply workaround if in PHY loopback bit 14 set */
|
||||
hw->phy.ops.read_reg(hw, PHY_CONTROL, &data);
|
||||
if (data & PHY_CONTROL_LB)
|
||||
goto out;
|
||||
|
||||
/* check if link is up and at 1Gbps */
|
||||
ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
data &= BM_CS_STATUS_LINK_UP |
|
||||
BM_CS_STATUS_RESOLVED |
|
||||
BM_CS_STATUS_SPEED_MASK;
|
||||
|
||||
if (data != (BM_CS_STATUS_LINK_UP |
|
||||
BM_CS_STATUS_RESOLVED |
|
||||
BM_CS_STATUS_SPEED_1000))
|
||||
goto out;
|
||||
|
||||
msec_delay(200);
|
||||
|
||||
/* flush the packets in the fifo buffer */
|
||||
ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
|
||||
HV_MUX_DATA_CTRL_GEN_TO_MAC |
|
||||
HV_MUX_DATA_CTRL_FORCE_SPEED);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL,
|
||||
HV_MUX_DATA_CTRL_GEN_TO_MAC);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_check_polarity_82577 - Checks the polarity.
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Success returns 0, Failure returns -E1000_ERR_PHY (-2)
|
||||
*
|
||||
* Polarity is determined based on the PHY specific status register.
|
||||
**/
|
||||
s32 e1000_check_polarity_82577(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
|
||||
DEBUGFUNC("e1000_check_polarity_82577");
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
|
||||
|
||||
if (!ret_val)
|
||||
phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
|
||||
? e1000_rev_polarity_reversed
|
||||
: e1000_rev_polarity_normal;
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Calls the PHY setup function to force speed and duplex. Clears the
|
||||
* auto-crossover to force MDI manually. Waits for link and returns
|
||||
* successful if link up is successful, else -E1000_ERR_PHY (-2).
|
||||
**/
|
||||
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data;
|
||||
bool link;
|
||||
|
||||
DEBUGFUNC("e1000_phy_force_speed_duplex_82577");
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
e1000_phy_force_speed_duplex_setup(hw, &phy_data);
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Clear Auto-Crossover to force MDI manually. 82577 requires MDI
|
||||
* forced whenever speed and duplex are forced.
|
||||
*/
|
||||
ret_val = phy->ops.read_reg(hw, I82577_PHY_CTRL_2, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
|
||||
phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
|
||||
|
||||
ret_val = phy->ops.write_reg(hw, I82577_PHY_CTRL_2, phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
DEBUGOUT1("I82577_PHY_CTRL_2: %X\n", phy_data);
|
||||
|
||||
usec_delay(1);
|
||||
|
||||
if (phy->autoneg_wait_to_complete) {
|
||||
DEBUGOUT("Waiting for forced speed/duplex link on 82577 phy\n");
|
||||
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (!link)
|
||||
DEBUGOUT("Link taking longer than expected.\n");
|
||||
|
||||
/* Try once more */
|
||||
ret_val = e1000_phy_has_link_generic(hw,
|
||||
PHY_FORCE_LIMIT,
|
||||
100000,
|
||||
&link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_phy_info_82577 - Retrieve I82577 PHY information
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Read PHY status to determine if link is up. If link is up, then
|
||||
* set/determine 10base-T extended distance and polarity correction. Read
|
||||
* PHY port status to determine MDI/MDIx and speed. Based on the speed,
|
||||
* determine on the cable length, local and remote receiver.
|
||||
**/
|
||||
s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 data;
|
||||
bool link;
|
||||
|
||||
DEBUGFUNC("e1000_get_phy_info_82577");
|
||||
|
||||
ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (!link) {
|
||||
DEBUGOUT("Phy info is only valid if link is up\n");
|
||||
ret_val = -E1000_ERR_CONFIG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
phy->polarity_correction = TRUE;
|
||||
|
||||
ret_val = e1000_check_polarity_82577(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? TRUE : FALSE;
|
||||
|
||||
if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
|
||||
I82577_PHY_STATUS2_SPEED_1000MBPS) {
|
||||
ret_val = hw->phy.ops.get_cable_length(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
|
||||
? e1000_1000t_rx_status_ok
|
||||
: e1000_1000t_rx_status_not_ok;
|
||||
|
||||
phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
|
||||
? e1000_1000t_rx_status_ok
|
||||
: e1000_1000t_rx_status_not_ok;
|
||||
} else {
|
||||
phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
|
||||
phy->local_rx = e1000_1000t_rx_status_undefined;
|
||||
phy->remote_rx = e1000_1000t_rx_status_undefined;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Reads the diagnostic status register and verifies result is valid before
|
||||
* placing it in the phy_cable_length field.
|
||||
**/
|
||||
s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
s32 ret_val;
|
||||
u16 phy_data, length;
|
||||
|
||||
DEBUGFUNC("e1000_get_cable_length_82577");
|
||||
|
||||
ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
|
||||
I82577_DSTATUS_CABLE_LENGTH_SHIFT;
|
||||
|
||||
if (length == E1000_CABLE_LENGTH_UNDEFINED)
|
||||
ret_val = E1000_ERR_PHY;
|
||||
|
||||
phy->cable_length = length;
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
|
|
@ -43,12 +43,14 @@ s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data);
|
|||
s32 e1000_check_downshift_generic(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_m88(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_igp(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_ife(struct e1000_hw *hw);
|
||||
s32 e1000_check_reset_block_generic(struct e1000_hw *hw);
|
||||
s32 e1000_copper_link_autoneg(struct e1000_hw *hw);
|
||||
s32 e1000_copper_link_setup_igp(struct e1000_hw *hw);
|
||||
s32 e1000_copper_link_setup_m88(struct e1000_hw *hw);
|
||||
s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw);
|
||||
s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw);
|
||||
s32 e1000_phy_force_speed_duplex_ife(struct e1000_hw *hw);
|
||||
s32 e1000_get_cable_length_m88(struct e1000_hw *hw);
|
||||
s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw);
|
||||
s32 e1000_get_cfg_done_generic(struct e1000_hw *hw);
|
||||
|
@ -74,15 +76,24 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
|
|||
u32 usec_interval, bool *success);
|
||||
s32 e1000_phy_init_script_igp3(struct e1000_hw *hw);
|
||||
enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id);
|
||||
s32 e1000_determine_phy_address(struct e1000_hw *hw);
|
||||
s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_determine_phy_address(struct e1000_hw *hw);
|
||||
s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
void e1000_power_up_phy_copper(struct e1000_hw *hw);
|
||||
void e1000_power_down_phy_copper(struct e1000_hw *hw);
|
||||
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
|
||||
s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
|
||||
s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
|
||||
s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
|
||||
s32 e1000_check_polarity_82577(struct e1000_hw *hw);
|
||||
s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
|
||||
s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
|
||||
s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
|
||||
|
||||
#define E1000_MAX_PHY_ADDR 4
|
||||
|
||||
|
@ -122,13 +133,47 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
|||
(((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
|
||||
~MAX_PHY_REG_ADDRESS)))
|
||||
|
||||
#define HV_INTC_FC_PAGE_START 768
|
||||
#define I82578_ADDR_REG 29
|
||||
#define I82577_ADDR_REG 16
|
||||
#define I82577_CFG_REG 22
|
||||
#define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15)
|
||||
#define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */
|
||||
#define I82577_CTRL_REG 23
|
||||
#define I82577_CTRL_DOWNSHIFT_MASK (7 << 10)
|
||||
|
||||
/* 82577 specific PHY registers */
|
||||
#define I82577_PHY_CTRL_2 18
|
||||
#define I82577_PHY_LBK_CTRL 19
|
||||
#define I82577_PHY_STATUS_2 26
|
||||
#define I82577_PHY_DIAG_STATUS 31
|
||||
|
||||
/* I82577 PHY Status 2 */
|
||||
#define I82577_PHY_STATUS2_REV_POLARITY 0x0400
|
||||
#define I82577_PHY_STATUS2_MDIX 0x0800
|
||||
#define I82577_PHY_STATUS2_SPEED_MASK 0x0300
|
||||
#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
|
||||
#define I82577_PHY_STATUS2_SPEED_100MBPS 0x0100
|
||||
|
||||
/* I82577 PHY Control 2 */
|
||||
#define I82577_PHY_CTRL2_AUTO_MDIX 0x0400
|
||||
#define I82577_PHY_CTRL2_FORCE_MDI_MDIX 0x0200
|
||||
|
||||
/* I82577 PHY Diagnostics Status */
|
||||
#define I82577_DSTATUS_CABLE_LENGTH 0x03FC
|
||||
#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
|
||||
|
||||
/* BM PHY Copper Specific Control 1 */
|
||||
#define BM_CS_CTRL1 16
|
||||
#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */
|
||||
|
||||
/* BM PHY Copper Specific States */
|
||||
/* BM PHY Copper Specific Status */
|
||||
#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_RESOLVED 0x0800
|
||||
#define BM_CS_STATUS_SPEED_MASK 0xC000
|
||||
#define BM_CS_STATUS_SPEED_1000 0x8000
|
||||
|
||||
#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4
|
||||
#define IGP01E1000_PHY_POLARITY_MASK 0x0078
|
||||
|
@ -149,7 +194,7 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
|||
#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000
|
||||
|
||||
#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
|
||||
#define IGP01E1000_PSSR_MDIX 0x0008
|
||||
#define IGP01E1000_PSSR_MDIX 0x0800
|
||||
#define IGP01E1000_PSSR_SPEED_MASK 0xC000
|
||||
#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000
|
||||
|
||||
|
@ -172,6 +217,8 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
|
|||
#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16
|
||||
#define E1000_KMRNCTRLSTA_REN 0x00200000
|
||||
#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */
|
||||
#define E1000_KMRNCTRLSTA_TIMEOUTS 0x4 /* Kumeran Timeouts */
|
||||
#define E1000_KMRNCTRLSTA_INBAND_PARAM 0x9 /* Kumeran InBand Parameters */
|
||||
#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */
|
||||
|
||||
#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
#define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
|
||||
#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
|
||||
#define E1000_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */
|
||||
#define E1000_SVCR 0x000F0
|
||||
#define E1000_SVT 0x000F4
|
||||
#define E1000_RCTL 0x00100 /* Rx Control - RW */
|
||||
#define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
|
||||
#define E1000_TXCW 0x00178 /* Tx Configuration Word - RW */
|
||||
|
@ -387,6 +389,7 @@
|
|||
#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
|
||||
#define E1000_SWSM 0x05B50 /* SW Semaphore */
|
||||
#define E1000_FWSM 0x05B54 /* FW Semaphore */
|
||||
#define E1000_SWSM2 0x05B58 /* Driver-only SW semaphore (not used by BOOT agents) */
|
||||
#define E1000_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */
|
||||
#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */
|
||||
#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
|
||||
|
@ -455,6 +458,7 @@
|
|||
#define E1000_DAQF(_n) (0x059A0 + (4 * (_n))) /* Dest Address Queue Fltr */
|
||||
#define E1000_SPQF(_n) (0x059C0 + (4 * (_n))) /* Source Port Queue Fltr */
|
||||
#define E1000_FTQF(_n) (0x059E0 + (4 * (_n))) /* 5-tuple Queue Fltr */
|
||||
#define E1000_TTQF(_n) (0x059E0 + (4 * (_n))) /* 2-tuple Queue Fltr */
|
||||
#define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
|
||||
#define E1000_ETQF(_n) (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
/******************************************************************************
|
||||
|
||||
Copyright (c) 2001-2008, Intel Corporation
|
||||
Copyright (c) 2001-2009, Intel Corporation
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
@ -36,7 +36,7 @@
|
|||
#ifndef _EM_H_DEFINED_
|
||||
#define _EM_H_DEFINED_
|
||||
|
||||
#define IFNET_BUF_RING
|
||||
|
||||
/* Tunables */
|
||||
|
||||
/*
|
||||
|
@ -232,6 +232,7 @@
|
|||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define EM_MAX_SCATTER 64
|
||||
#define EM_VFTA_SIZE 128
|
||||
#define EM_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define EM_TSO_SEG_SIZE 4096 /* Max dma segment size */
|
||||
#define EM_MSIX_MASK 0x01F00000 /* For 82574 use */
|
||||
|
@ -254,38 +255,11 @@
|
|||
#define EM_FIFO_HDR 0x10
|
||||
#define EM_82547_PKT_THRESH 0x3e0
|
||||
|
||||
#ifdef EM_TIMESYNC
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
/* TIMESYNC IOCTL defines */
|
||||
#define EM_TIMESYNC_READTS _IOWR('i', 127, struct em_tsync_read)
|
||||
|
||||
/* Used in the READTS IOCTL */
|
||||
struct em_tsync_read {
|
||||
int read_current_time;
|
||||
struct timespec system_time;
|
||||
u64 network_time;
|
||||
u64 rx_stamp;
|
||||
u64 tx_stamp;
|
||||
u16 seqid;
|
||||
unsigned char srcid[6];
|
||||
int rx_valid;
|
||||
int tx_valid;
|
||||
};
|
||||
|
||||
#endif /* EM_TIMESYNC */
|
||||
|
||||
struct adapter;
|
||||
|
||||
struct em_int_delay_info {
|
||||
struct adapter *adapter; /* Back-pointer to the adapter struct */
|
||||
int offset; /* Register offset to read/write */
|
||||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
|
@ -299,13 +273,19 @@ struct em_dma_alloc {
|
|||
int dma_nseg;
|
||||
};
|
||||
|
||||
struct adapter;
|
||||
|
||||
struct em_int_delay_info {
|
||||
struct adapter *adapter; /* Back-pointer to the adapter struct */
|
||||
int offset; /* Register offset to read/write */
|
||||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/* Our adapter structure */
|
||||
struct adapter {
|
||||
struct ifnet *ifp;
|
||||
#ifdef IFNET_BUF_RING
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#else
|
||||
void *br;
|
||||
#endif
|
||||
struct e1000_hw hw;
|
||||
|
||||
|
@ -320,7 +300,7 @@ struct adapter {
|
|||
struct resource *ioport;
|
||||
int io_rid;
|
||||
|
||||
/* 82574 uses 3 int vectors */
|
||||
/* 82574 may use 3 int vectors */
|
||||
struct resource *res[3];
|
||||
void *tag[3];
|
||||
int rid[3];
|
||||
|
@ -345,8 +325,11 @@ struct adapter {
|
|||
struct task tx_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
|
||||
#if __FreeBSD_version >= 700029
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
#endif
|
||||
|
||||
/* Management and WOL features */
|
||||
int wol;
|
||||
|
@ -377,6 +360,7 @@ struct adapter {
|
|||
uint32_t next_tx_to_clean;
|
||||
volatile uint16_t num_tx_desc_avail;
|
||||
uint16_t num_tx_desc;
|
||||
uint16_t last_hw_offload;
|
||||
uint32_t txd_cmd;
|
||||
struct em_buffer *tx_buffer_area;
|
||||
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||
|
@ -433,11 +417,6 @@ struct adapter {
|
|||
boolean_t pcix_82544;
|
||||
boolean_t in_detach;
|
||||
|
||||
#ifdef EM_TIMESYNC
|
||||
u64 last_stamp;
|
||||
u64 last_sec;
|
||||
u32 last_ns;
|
||||
#endif
|
||||
|
||||
struct e1000_hw_stats stats;
|
||||
};
|
||||
|
@ -457,7 +436,6 @@ typedef struct _em_vendor_info_t {
|
|||
unsigned int index;
|
||||
} em_vendor_info_t;
|
||||
|
||||
|
||||
struct em_buffer {
|
||||
int next_eop; /* Index of the desc to watch */
|
||||
struct mbuf *m_head;
|
||||
|
@ -496,27 +474,4 @@ typedef struct _DESCRIPTOR_PAIR
|
|||
#define EM_CORE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->core_mtx, MA_OWNED)
|
||||
#define EM_TX_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->tx_mtx, MA_OWNED)
|
||||
|
||||
#ifdef IFNET_BUF_RING
|
||||
#define ADAPTER_RING_EMPTY(adapter) drbr_empty((adapter)->ifp, (adapter)->br)
|
||||
#define em_dequeue drbr_dequeue
|
||||
|
||||
#else
|
||||
#define ADAPTER_RING_EMPTY(adapter) IFQ_DRV_IS_EMPTY(&((adapter)->ifp->if_snd))
|
||||
#define drbr_free(br, type)
|
||||
static __inline struct mbuf *
|
||||
em_dequeue(struct ifnet *ifp, struct buf_ring *br)
|
||||
{
|
||||
struct mbuf *m;
|
||||
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
||||
return (m);
|
||||
}
|
||||
#ifdef BUF_RING_UNDEFINED
|
||||
|
||||
struct buf_ring {
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* _EM_H_DEFINED_ */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -184,18 +184,6 @@
|
|||
#define IGB_FC_PAUSE_TIME 0x0680
|
||||
#define IGB_EEPROM_APME 0x400;
|
||||
|
||||
/* Code compatilbility between 6 and 7 */
|
||||
#ifndef ETHER_BPF_MTAP
|
||||
#define ETHER_BPF_MTAP BPF_MTAP
|
||||
#endif
|
||||
|
||||
#if __FreeBSD_version < 700000
|
||||
#define CSUM_TSO 0
|
||||
#define IFCAP_TSO4 0
|
||||
#define FILTER_STRAY
|
||||
#define FILTER_HANDLED
|
||||
#endif
|
||||
|
||||
/*
|
||||
* TDBA/RDBA should be aligned on 16 byte boundary. But TDLEN/RDLEN should be
|
||||
* multiple of 128 bytes. So we align TDBA/RDBA on 128 byte boundary. This will
|
||||
|
@ -232,6 +220,8 @@
|
|||
#define HW_DEBUGOUT2(S, A, B) if (DEBUG_HW) printf(S "\n", A, B)
|
||||
|
||||
#define IGB_MAX_SCATTER 64
|
||||
#define IGB_VFTA_SIZE 128
|
||||
#define IGB_BR_SIZE 4096 /* ring buf size */
|
||||
#define IGB_TSO_SIZE (65535 + sizeof(struct ether_vlan_header))
|
||||
#define IGB_TSO_SEG_SIZE 4096 /* Max dma segment size */
|
||||
#define IGB_HDR_BUF 128
|
||||
|
@ -258,39 +248,11 @@
|
|||
#define IGB_BULK_LATENCY 1200
|
||||
#define IGB_LINK_ITR 2000
|
||||
|
||||
#ifdef IGB_TIMESYNC
|
||||
/* Precision Time Sync (IEEE 1588) defines */
|
||||
#define ETHERTYPE_IEEE1588 0x88F7
|
||||
#define PICOSECS_PER_TICK 20833
|
||||
#define TSYNC_PORT 319 /* UDP port for the protocol */
|
||||
|
||||
/* TIMESYNC IOCTL defines */
|
||||
#define IGB_TIMESYNC_READTS _IOWR('i', 127, struct igb_tsync_read)
|
||||
#define IGB_TIMESTAMP 5 /* A unique return value */
|
||||
|
||||
/* Used in the READTS IOCTL */
|
||||
struct igb_tsync_read {
|
||||
int read_current_time;
|
||||
struct timespec system_time;
|
||||
u64 network_time;
|
||||
u64 rx_stamp;
|
||||
u64 tx_stamp;
|
||||
u16 seqid;
|
||||
unsigned char srcid[6];
|
||||
int rx_valid;
|
||||
int tx_valid;
|
||||
};
|
||||
|
||||
#endif /* IGB_TIMESYNC */
|
||||
|
||||
struct adapter; /* forward reference */
|
||||
|
||||
struct igb_int_delay_info {
|
||||
struct adapter *adapter; /* Back-pointer to the adapter struct */
|
||||
int offset; /* Register offset to read/write */
|
||||
int value; /* Current value in usecs */
|
||||
};
|
||||
|
||||
/*
|
||||
* Bus dma allocation structure used by
|
||||
* e1000_dma_malloc and e1000_dma_free.
|
||||
|
@ -322,7 +284,13 @@ struct tx_ring {
|
|||
u32 next_to_clean;
|
||||
volatile u16 tx_avail;
|
||||
struct igb_tx_buffer *tx_buffers;
|
||||
#if __FreeBSD_version >= 800000
|
||||
struct buf_ring *br;
|
||||
#endif
|
||||
bus_dma_tag_t txtag; /* dma tag for tx */
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
|
||||
u32 watchdog_timer;
|
||||
u64 no_desc_avail;
|
||||
u64 tx_irq;
|
||||
|
@ -340,6 +308,8 @@ struct rx_ring {
|
|||
struct igb_dma_alloc rxdma; /* bus_dma glue for tx desc */
|
||||
union e1000_adv_rx_desc *rx_base;
|
||||
struct lro_ctrl lro;
|
||||
bool lro_enabled;
|
||||
bool hdr_split;
|
||||
struct task rx_task; /* cleanup tasklet */
|
||||
struct mtx rx_mtx;
|
||||
char mtx_name[16];
|
||||
|
@ -358,6 +328,9 @@ struct rx_ring {
|
|||
u32 bytes;
|
||||
u32 eitr_setting;
|
||||
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
|
||||
/* Soft stats */
|
||||
u64 rx_irq;
|
||||
u64 rx_split_packets;
|
||||
|
@ -375,9 +348,8 @@ struct adapter {
|
|||
|
||||
struct resource *pci_mem;
|
||||
struct resource *msix_mem;
|
||||
struct resource *res[IGB_MSIX_VEC];
|
||||
void *tag[IGB_MSIX_VEC];
|
||||
int rid[IGB_MSIX_VEC];
|
||||
struct resource *res;
|
||||
void *tag;
|
||||
u32 eims_mask;
|
||||
|
||||
int linkvec;
|
||||
|
@ -395,8 +367,11 @@ struct adapter {
|
|||
struct task link_task;
|
||||
struct task rxtx_task;
|
||||
struct taskqueue *tq; /* private task queue */
|
||||
u16 num_queues;
|
||||
|
||||
eventhandler_tag vlan_attach;
|
||||
eventhandler_tag vlan_detach;
|
||||
u32 num_vlans;
|
||||
|
||||
/* Management and WOL features */
|
||||
int wol;
|
||||
|
@ -413,7 +388,6 @@ struct adapter {
|
|||
*/
|
||||
struct tx_ring *tx_rings;
|
||||
u16 num_tx_desc;
|
||||
u16 num_tx_queues;
|
||||
u32 txd_cmd;
|
||||
|
||||
/*
|
||||
|
@ -422,7 +396,6 @@ struct adapter {
|
|||
struct rx_ring *rx_rings;
|
||||
bool rx_hdr_split;
|
||||
u16 num_rx_desc;
|
||||
u16 num_rx_queues;
|
||||
int rx_process_limit;
|
||||
u32 rx_mbuf_sz;
|
||||
u32 rx_mask;
|
||||
|
@ -439,10 +412,12 @@ struct adapter {
|
|||
|
||||
boolean_t in_detach;
|
||||
|
||||
#ifdef IGB_TIMESYNC
|
||||
u64 last_stamp;
|
||||
u64 last_sec;
|
||||
u32 last_ns;
|
||||
#ifdef IGB_IEEE1588
|
||||
/* IEEE 1588 precision time support */
|
||||
struct cyclecounter cycles;
|
||||
struct nettimer clock;
|
||||
struct nettime_compare compare;
|
||||
struct hwtstamp_ctrl hwtstamp;
|
||||
#endif
|
||||
|
||||
struct e1000_hw_stats stats;
|
||||
|
@ -483,6 +458,7 @@ struct igb_rx_buffer {
|
|||
#define IGB_RX_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->rx_mtx)
|
||||
#define IGB_CORE_LOCK(_sc) mtx_lock(&(_sc)->core_mtx)
|
||||
#define IGB_TX_LOCK(_sc) mtx_lock(&(_sc)->tx_mtx)
|
||||
#define IGB_TX_TRYLOCK(_sc) mtx_trylock(&(_sc)->tx_mtx)
|
||||
#define IGB_RX_LOCK(_sc) mtx_lock(&(_sc)->rx_mtx)
|
||||
#define IGB_CORE_UNLOCK(_sc) mtx_unlock(&(_sc)->core_mtx)
|
||||
#define IGB_TX_UNLOCK(_sc) mtx_unlock(&(_sc)->tx_mtx)
|
||||
|
|
|
@ -8,7 +8,7 @@ SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c
|
|||
SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c
|
||||
SHARED_SRCS += e1000_82575.c
|
||||
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000
|
||||
CFLAGS += -I${.CURDIR}/../../dev/e1000 -DSMP
|
||||
|
||||
# DEVICE_POLLING gives you non-interrupt handling
|
||||
# not advisable since MSIX gives better results
|
||||
|
|
Loading…
Reference in a new issue