svn commit: r215922 - in stable/7/sys: conf dev/e1000 modules/em
modules/igb
Jack F Vogel
jfv at FreeBSD.org
Sat Nov 27 01:09:55 UTC 2010
Author: jfv
Date: Sat Nov 27 01:09:54 2010
New Revision: 215922
URL: http://svn.freebsd.org/changeset/base/215922
Log:
MFC: r214646, r215781, r215789, 215808
Brings 7.4 e1000 drivers to the same level as 8.2
Modified:
stable/7/sys/conf/files
stable/7/sys/dev/e1000/e1000_82571.c
stable/7/sys/dev/e1000/e1000_82571.h
stable/7/sys/dev/e1000/e1000_82575.c
stable/7/sys/dev/e1000/e1000_82575.h
stable/7/sys/dev/e1000/e1000_api.c
stable/7/sys/dev/e1000/e1000_api.h
stable/7/sys/dev/e1000/e1000_defines.h
stable/7/sys/dev/e1000/e1000_hw.h
stable/7/sys/dev/e1000/e1000_ich8lan.c
stable/7/sys/dev/e1000/e1000_ich8lan.h
stable/7/sys/dev/e1000/e1000_mac.c
stable/7/sys/dev/e1000/e1000_nvm.c
stable/7/sys/dev/e1000/e1000_nvm.h
stable/7/sys/dev/e1000/e1000_osdep.h
stable/7/sys/dev/e1000/e1000_phy.c
stable/7/sys/dev/e1000/e1000_phy.h
stable/7/sys/dev/e1000/e1000_regs.h
stable/7/sys/dev/e1000/if_em.c
stable/7/sys/dev/e1000/if_em.h
stable/7/sys/dev/e1000/if_igb.c
stable/7/sys/dev/e1000/if_igb.h
stable/7/sys/dev/e1000/if_lem.c
stable/7/sys/dev/e1000/if_lem.h
stable/7/sys/modules/em/Makefile
stable/7/sys/modules/igb/Makefile
Directory Properties:
stable/7/ (props changed)
Modified: stable/7/sys/conf/files
==============================================================================
--- stable/7/sys/conf/files Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/conf/files Sat Nov 27 01:09:54 2010 (r215922)
@@ -812,6 +812,10 @@ dev/e1000/e1000_nvm.c optional em | igb
compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_phy.c optional em | igb \
compile-with "${NORMAL_C} -I$S/dev/e1000"
+dev/e1000/e1000_vf.c optional em | igb \
+ compile-with "${NORMAL_C} -I$S/dev/e1000"
+dev/e1000/e1000_mbx.c optional em | igb \
+ compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/e1000/e1000_osdep.c optional em | igb \
compile-with "${NORMAL_C} -I$S/dev/e1000"
dev/et/if_et.c optional et
Modified: stable/7/sys/dev/e1000/e1000_82571.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82571.c Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_82571.c Sat Nov 27 01:09:54 2010 (r215922)
@@ -78,6 +78,10 @@ static s32 e1000_get_hw_semaphore_82571
static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
+static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
u16 words, u16 *data);
@@ -91,6 +95,7 @@ static void e1000_power_down_phy_copper_
static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
{
struct e1000_phy_info *phy = &hw->phy;
+ struct e1000_dev_spec_82571 *dev_spec = &hw->dev_spec._82571;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_phy_params_82571");
@@ -104,9 +109,7 @@ static s32 e1000_init_phy_params_82571(s
phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
phy->reset_delay_us = 100;
- phy->ops.acquire = e1000_get_hw_semaphore_82571;
phy->ops.check_reset_block = e1000_check_reset_block_generic;
- phy->ops.release = e1000_put_hw_semaphore_82571;
phy->ops.reset = e1000_phy_hw_reset_generic;
phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82571;
phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic;
@@ -124,6 +127,8 @@ static s32 e1000_init_phy_params_82571(s
phy->ops.get_cable_length = e1000_get_cable_length_igp_2;
phy->ops.read_reg = e1000_read_phy_reg_igp;
phy->ops.write_reg = e1000_write_phy_reg_igp;
+ phy->ops.acquire = e1000_get_hw_semaphore_82571;
+ phy->ops.release = e1000_put_hw_semaphore_82571;
/* This uses above function pointers */
ret_val = e1000_get_phy_id_82571(hw);
@@ -145,6 +150,8 @@ static s32 e1000_init_phy_params_82571(s
phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.read_reg = e1000_read_phy_reg_m88;
phy->ops.write_reg = e1000_write_phy_reg_m88;
+ phy->ops.acquire = e1000_get_hw_semaphore_82571;
+ phy->ops.release = e1000_put_hw_semaphore_82571;
/* This uses above function pointers */
ret_val = e1000_get_phy_id_82571(hw);
@@ -158,6 +165,8 @@ static s32 e1000_init_phy_params_82571(s
break;
case e1000_82574:
case e1000_82583:
+ E1000_MUTEX_INIT(&dev_spec->swflag_mutex);
+
phy->type = e1000_phy_bm;
phy->ops.get_cfg_done = e1000_get_cfg_done_generic;
phy->ops.get_info = e1000_get_phy_info_m88;
@@ -167,6 +176,8 @@ static s32 e1000_init_phy_params_82571(s
phy->ops.get_cable_length = e1000_get_cable_length_m88;
phy->ops.read_reg = e1000_read_phy_reg_bm2;
phy->ops.write_reg = e1000_write_phy_reg_bm2;
+ phy->ops.acquire = e1000_get_hw_semaphore_82574;
+ phy->ops.release = e1000_put_hw_semaphore_82574;
/* This uses above function pointers */
ret_val = e1000_get_phy_id_82571(hw);
@@ -250,9 +261,18 @@ static s32 e1000_init_nvm_params_82571(s
}
/* Function Pointers */
- nvm->ops.acquire = e1000_acquire_nvm_82571;
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
+ nvm->ops.acquire = e1000_get_hw_semaphore_82574;
+ nvm->ops.release = e1000_put_hw_semaphore_82574;
+ break;
+ default:
+ nvm->ops.acquire = e1000_acquire_nvm_82571;
+ nvm->ops.release = e1000_release_nvm_82571;
+ break;
+ }
nvm->ops.read = e1000_read_nvm_eerd;
- nvm->ops.release = e1000_release_nvm_82571;
nvm->ops.update = e1000_update_nvm_checksum_82571;
nvm->ops.validate = e1000_validate_nvm_checksum_82571;
nvm->ops.valid_led_default = e1000_valid_led_default_82571;
@@ -578,6 +598,101 @@ static void e1000_put_hw_semaphore_82571
}
/**
+ * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore during reset.
+ *
+ **/
+static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
+{
+ u32 extcnf_ctrl;
+ s32 ret_val = E1000_SUCCESS;
+ s32 i = 0;
+
+ DEBUGFUNC("e1000_get_hw_semaphore_82573");
+
+ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+ do {
+ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
+ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
+
+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
+ break;
+
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+
+ msec_delay(2);
+ i++;
+ } while (i < MDIO_OWNERSHIP_TIMEOUT);
+
+ if (i == MDIO_OWNERSHIP_TIMEOUT) {
+ /* Release semaphores */
+ e1000_put_hw_semaphore_82573(hw);
+ DEBUGOUT("Driver can't access the PHY\n");
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ }
+
+out:
+ return ret_val;
+}
+
+/**
+ * e1000_put_hw_semaphore_82573 - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used during reset.
+ *
+ **/
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
+{
+ u32 extcnf_ctrl;
+
+ DEBUGFUNC("e1000_put_hw_semaphore_82573");
+
+ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
+ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
+}
+
+/**
+ * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Acquire the HW semaphore to access the PHY or NVM.
+ *
+ **/
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
+{
+ s32 ret_val;
+
+ DEBUGFUNC("e1000_get_hw_semaphore_82574");
+
+ E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex);
+ ret_val = e1000_get_hw_semaphore_82573(hw);
+ if (ret_val)
+ E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
+ return ret_val;
+}
+
+/**
+ * e1000_put_hw_semaphore_82574 - Release hardware semaphore
+ * @hw: pointer to the HW structure
+ *
+ * Release hardware semaphore used to access the PHY or NVM
+ *
+ **/
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
+{
+ DEBUGFUNC("e1000_put_hw_semaphore_82574");
+
+ e1000_put_hw_semaphore_82573(hw);
+ E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex);
+}
+
+/**
* e1000_acquire_nvm_82571 - Request for access to the EEPROM
* @hw: pointer to the HW structure
*
@@ -598,8 +713,6 @@ static s32 e1000_acquire_nvm_82571(struc
switch (hw->mac.type) {
case e1000_82573:
- case e1000_82574:
- case e1000_82583:
break;
default:
ret_val = e1000_acquire_nvm_generic(hw);
@@ -926,9 +1039,8 @@ out:
**/
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
{
- u32 ctrl, extcnf_ctrl, ctrl_ext, icr;
+ u32 ctrl, ctrl_ext, icr;
s32 ret_val;
- u16 i = 0;
DEBUGFUNC("e1000_reset_hw_82571");
@@ -955,33 +1067,33 @@ static s32 e1000_reset_hw_82571(struct e
*/
switch (hw->mac.type) {
case e1000_82573:
+ ret_val = e1000_get_hw_semaphore_82573(hw);
+ break;
case e1000_82574:
case e1000_82583:
- extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- do {
- E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl);
- extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
-
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
- break;
-
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-
- msec_delay(2);
- i++;
- } while (i < MDIO_OWNERSHIP_TIMEOUT);
+ ret_val = e1000_get_hw_semaphore_82574(hw);
break;
default:
break;
}
+ if (ret_val)
+ DEBUGOUT("Cannot acquire MDIO ownership\n");
ctrl = E1000_READ_REG(hw, E1000_CTRL);
DEBUGOUT("Issuing a global reset to MAC\n");
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
+ /* Must release MDIO ownership and mutex after MAC reset. */
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82583:
+ e1000_put_hw_semaphore_82574(hw);
+ break;
+ default:
+ break;
+ }
+
if (hw->nvm.type == e1000_nvm_flash_hw) {
usec_delay(10);
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
@@ -1015,12 +1127,14 @@ static s32 e1000_reset_hw_82571(struct e
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
- /* Install any alternate MAC address into RAR0 */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
- if (ret_val)
- goto out;
+ if (hw->mac.type == e1000_82571) {
+ /* Install any alternate MAC address into RAR0 */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
- e1000_set_laa_state_82571(hw, TRUE);
+ e1000_set_laa_state_82571(hw, TRUE);
+ }
/* Reinitialize the 82571 serdes link state machine */
if (hw->phy.media_type == e1000_media_type_internal_serdes)
@@ -1330,6 +1444,42 @@ static s32 e1000_led_on_82574(struct e10
return E1000_SUCCESS;
}
+/**
+ * e1000_check_phy_82574 - check 82574 phy hung state
+ * @hw: pointer to the HW structure
+ *
+ * Returns whether phy is hung or not
+ **/
+bool e1000_check_phy_82574(struct e1000_hw *hw)
+{
+ u16 status_1kbt = 0;
+ u16 receive_errors = 0;
+ bool phy_hung = FALSE;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_check_phy_82574");
+
+ /*
+ * Read PHY Receive Error counter first, if its is max - all F's then
+ * read the Base1000T status register If both are max then PHY is hung.
+ */
+ ret_val = hw->phy.ops.read_reg(hw, E1000_RECEIVE_ERROR_COUNTER,
+ &receive_errors);
+ if (ret_val)
+ goto out;
+ if (receive_errors == E1000_RECEIVE_ERROR_MAX) {
+ ret_val = hw->phy.ops.read_reg(hw, E1000_BASE1000T_STATUS,
+ &status_1kbt);
+ if (ret_val)
+ goto out;
+ if ((status_1kbt & E1000_IDLE_ERROR_COUNT_MASK) ==
+ E1000_IDLE_ERROR_COUNT_MASK)
+ phy_hung = TRUE;
+ }
+out:
+ return phy_hung;
+}
+
/**
* e1000_setup_link_82571 - Setup flow control and link settings
@@ -1460,6 +1610,8 @@ static s32 e1000_check_for_serdes_link_8
u32 rxcw;
u32 ctrl;
u32 status;
+ u32 txcw;
+ u32 i;
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_check_for_serdes_link_82571");
@@ -1482,8 +1634,10 @@ static s32 e1000_check_for_serdes_link_8
e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = FALSE;
DEBUGOUT("AN_UP -> AN_PROG\n");
+ } else {
+ mac->serdes_has_link = TRUE;
}
- break;
+ break;
case e1000_serdes_link_forced_up:
/*
@@ -1491,8 +1645,10 @@ static s32 e1000_check_for_serdes_link_8
* auto-negotiation in the TXCW register and disable
* forced link in the Device Control register in an
* attempt to auto-negotiate with our link partner.
+ * If the partner code word is null, stop forcing
+ * and restart auto negotiation.
*/
- if (rxcw & E1000_RXCW_C) {
+ if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) {
/* Enable autoneg, and unforce link up */
E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
E1000_WRITE_REG(hw, E1000_CTRL,
@@ -1501,6 +1657,8 @@ static s32 e1000_check_for_serdes_link_8
e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = FALSE;
DEBUGOUT("FORCED_UP -> AN_PROG\n");
+ } else {
+ mac->serdes_has_link = TRUE;
}
break;
@@ -1559,6 +1717,7 @@ static s32 e1000_check_for_serdes_link_8
(ctrl & ~E1000_CTRL_SLU));
mac->serdes_link_state =
e1000_serdes_link_autoneg_progress;
+ mac->serdes_has_link = FALSE;
DEBUGOUT("DOWN -> AN_PROG\n");
break;
}
@@ -1569,16 +1728,32 @@ static s32 e1000_check_for_serdes_link_8
DEBUGOUT("ANYSTATE -> DOWN\n");
} else {
/*
- * We have sync, and can tolerate one invalid (IV)
- * codeword before declaring link down, so reread
- * to look again.
+ * Check several times, if Sync and Config
+ * both are consistently 1 then simply ignore
+ * the Invalid bit and restart Autoneg
*/
- usec_delay(10);
- rxcw = E1000_READ_REG(hw, E1000_RXCW);
- if (rxcw & E1000_RXCW_IV) {
- mac->serdes_link_state = e1000_serdes_link_down;
+ for (i = 0; i < AN_RETRY_COUNT; i++) {
+ usec_delay(10);
+ rxcw = E1000_READ_REG(hw, E1000_RXCW);
+ if ((rxcw & E1000_RXCW_IV) &&
+ !((rxcw & E1000_RXCW_SYNCH) &&
+ (rxcw & E1000_RXCW_C))) {
+ mac->serdes_has_link = FALSE;
+ mac->serdes_link_state =
+ e1000_serdes_link_down;
+ DEBUGOUT("ANYSTATE -> DOWN\n");
+ break;
+ }
+ }
+
+ if (i == AN_RETRY_COUNT) {
+ txcw = E1000_READ_REG(hw, E1000_TXCW);
+ txcw |= E1000_TXCW_ANE;
+ E1000_WRITE_REG(hw, E1000_TXCW, txcw);
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
mac->serdes_has_link = FALSE;
- DEBUGOUT("ANYSTATE -> DOWN\n");
+ DEBUGOUT("ANYSTATE -> AN_PROG\n");
}
}
}
@@ -1736,14 +1911,16 @@ static s32 e1000_read_mac_addr_82571(str
DEBUGFUNC("e1000_read_mac_addr_82571");
- /*
- * If there's an alternate MAC address place it in RAR0
- * so that it will override the Si installed default perm
- * address.
- */
- ret_val = e1000_check_alt_mac_addr_generic(hw);
- if (ret_val)
- goto out;
+ if (hw->mac.type == e1000_82571) {
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
+ }
ret_val = e1000_read_mac_addr_generic(hw);
Modified: stable/7/sys/dev/e1000/e1000_82571.h
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82571.h Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_82571.h Sat Nov 27 01:09:54 2010 (r215922)
@@ -1,6 +1,6 @@
/******************************************************************************
- Copyright (c) 2001-2008, Intel Corporation
+ Copyright (c) 2001-2010, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,7 @@
(ID_LED_DEF1_DEF2))
#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */
/* Intr Throttling - RW */
#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n)))
@@ -53,6 +54,11 @@
#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */
+#define E1000_BASE1000T_STATUS 10
+#define E1000_IDLE_ERROR_COUNT_MASK 0xFF
+#define E1000_RECEIVE_ERROR_COUNTER 21
+#define E1000_RECEIVE_ERROR_MAX 0xFFFF
+bool e1000_check_phy_82574(struct e1000_hw *hw);
bool e1000_get_laa_state_82571(struct e1000_hw *hw);
void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state);
Modified: stable/7/sys/dev/e1000/e1000_82575.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82575.c Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_82575.c Sat Nov 27 01:09:54 2010 (r215922)
@@ -85,6 +85,7 @@ static void e1000_power_down_phy_copper_
static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
static void e1000_power_up_serdes_link_82575(struct e1000_hw *hw);
static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
+static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw);
static const u16 e1000_82580_rxpbs_table[] =
{ 36, 72, 144, 1, 2, 4, 8, 16,
@@ -92,6 +93,37 @@ static const u16 e1000_82580_rxpbs_table
#define E1000_82580_RXPBS_TABLE_SIZE \
(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+
+/**
+ * e1000_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
+ * @hw: pointer to the HW structure
+ *
+ * Called to determine if the I2C pins are being used for I2C or as an
+ * external MDIO interface since the two options are mutually exclusive.
+ **/
+static bool e1000_sgmii_uses_mdio_82575(struct e1000_hw *hw)
+{
+ u32 reg = 0;
+ bool ext_mdio = FALSE;
+
+ DEBUGFUNC("e1000_sgmii_uses_mdio_82575");
+
+ switch (hw->mac.type) {
+ case e1000_82575:
+ case e1000_82576:
+ reg = E1000_READ_REG(hw, E1000_MDIC);
+ ext_mdio = !!(reg & E1000_MDIC_DEST);
+ break;
+ case e1000_82580:
+ reg = E1000_READ_REG(hw, E1000_MDICNFG);
+ ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO);
+ break;
+ default:
+ break;
+ }
+ return ext_mdio;
+}
+
/**
* e1000_init_phy_params_82575 - Init PHY func ptrs.
* @hw: pointer to the HW structure
@@ -100,6 +132,7 @@ static s32 e1000_init_phy_params_82575(s
{
struct e1000_phy_info *phy = &hw->phy;
s32 ret_val = E1000_SUCCESS;
+ u32 ctrl_ext;
DEBUGFUNC("e1000_init_phy_params_82575");
@@ -120,16 +153,26 @@ static s32 e1000_init_phy_params_82575(s
phy->ops.get_cfg_done = e1000_get_cfg_done_82575;
phy->ops.release = e1000_release_phy_82575;
+ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
+
if (e1000_sgmii_active_82575(hw)) {
phy->ops.reset = e1000_phy_hw_reset_sgmii_82575;
+ ctrl_ext |= E1000_CTRL_I2C_ENA;
+ } else {
+ phy->ops.reset = e1000_phy_hw_reset_generic;
+ ctrl_ext &= ~E1000_CTRL_I2C_ENA;
+ }
+
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
+ e1000_reset_mdicnfg_82580(hw);
+
+ if (e1000_sgmii_active_82575(hw) && !e1000_sgmii_uses_mdio_82575(hw)) {
phy->ops.read_reg = e1000_read_phy_reg_sgmii_82575;
phy->ops.write_reg = e1000_write_phy_reg_sgmii_82575;
} else if (hw->mac.type >= e1000_82580) {
- phy->ops.reset = e1000_phy_hw_reset_generic;
phy->ops.read_reg = e1000_read_phy_reg_82580;
phy->ops.write_reg = e1000_write_phy_reg_82580;
} else {
- phy->ops.reset = e1000_phy_hw_reset_generic;
phy->ops.read_reg = e1000_read_phy_reg_igp;
phy->ops.write_reg = e1000_write_phy_reg_igp;
}
@@ -256,27 +299,15 @@ static s32 e1000_init_mac_params_82575(s
switch (ctrl_ext & E1000_CTRL_EXT_LINK_MODE_MASK) {
case E1000_CTRL_EXT_LINK_MODE_SGMII:
dev_spec->sgmii_active = TRUE;
- ctrl_ext |= E1000_CTRL_I2C_ENA;
break;
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
hw->phy.media_type = e1000_media_type_internal_serdes;
- ctrl_ext |= E1000_CTRL_I2C_ENA;
break;
default:
- ctrl_ext &= ~E1000_CTRL_I2C_ENA;
break;
}
- E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
-
- /*
- * if using i2c make certain the MDICNFG register is cleared to prevent
- * communications from being misrouted to the mdic registers
- */
- if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580))
- E1000_WRITE_REG(hw, E1000_MDICNFG, 0);
-
/* Set mta register count */
mac->mta_reg_count = 128;
/* Set uta register count */
@@ -367,6 +398,7 @@ void e1000_init_function_pointers_82575(
hw->mac.ops.init_params = e1000_init_mac_params_82575;
hw->nvm.ops.init_params = e1000_init_nvm_params_82575;
hw->phy.ops.init_params = e1000_init_phy_params_82575;
+ hw->mbx.ops.init_params = e1000_init_mbx_params_pf;
}
/**
@@ -492,6 +524,7 @@ static s32 e1000_get_phy_id_82575(struct
s32 ret_val = E1000_SUCCESS;
u16 phy_id;
u32 ctrl_ext;
+ u32 mdic;
DEBUGFUNC("e1000_get_phy_id_82575");
@@ -508,6 +541,28 @@ static s32 e1000_get_phy_id_82575(struct
goto out;
}
+ if (e1000_sgmii_uses_mdio_82575(hw)) {
+ switch (hw->mac.type) {
+ case e1000_82575:
+ case e1000_82576:
+ mdic = E1000_READ_REG(hw, E1000_MDIC);
+ mdic &= E1000_MDIC_PHY_MASK;
+ phy->addr = mdic >> E1000_MDIC_PHY_SHIFT;
+ break;
+ case e1000_82580:
+ mdic = E1000_READ_REG(hw, E1000_MDICNFG);
+ mdic &= E1000_MDICNFG_PHY_MASK;
+ phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT;
+ break;
+ default:
+ ret_val = -E1000_ERR_PHY;
+ goto out;
+ break;
+ }
+ ret_val = e1000_get_phy_id(hw);
+ goto out;
+ }
+
/* Power on sgmii phy if it is disabled */
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
E1000_WRITE_REG(hw, E1000_CTRL_EXT,
@@ -1243,6 +1298,7 @@ static s32 e1000_setup_serdes_link_82575
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
/* disable PCS autoneg and support parallel detect only */
pcs_autoneg = FALSE;
+ /* fall through to default case */
default:
/*
* non-SGMII modes only supports a speed of 1000/Full for the
@@ -1638,6 +1694,39 @@ out:
return ret_val;
}
+
+/**
+ * e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing
+ * @hw: pointer to the hardware struct
+ * @enable: state to enter, either enabled or disabled
+ * @pf: Physical Function pool - do not set anti-spoofing for the PF
+ *
+ * enables/disables L2 switch anti-spoofing functionality.
+ **/
+void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
+{
+ u32 dtxswc;
+
+ switch (hw->mac.type) {
+ case e1000_82576:
+ dtxswc = E1000_READ_REG(hw, E1000_DTXSWC);
+ if (enable) {
+ dtxswc |= (E1000_DTXSWC_MAC_SPOOF_MASK |
+ E1000_DTXSWC_VLAN_SPOOF_MASK);
+ /* The PF can spoof - it has to in order to
+ * support emulation mode NICs */
+ dtxswc ^= (1 << pf | 1 << (pf + MAX_NUM_VFS));
+ } else {
+ dtxswc &= ~(E1000_DTXSWC_MAC_SPOOF_MASK |
+ E1000_DTXSWC_VLAN_SPOOF_MASK);
+ }
+ E1000_WRITE_REG(hw, E1000_DTXSWC, dtxswc);
+ break;
+ default:
+ break;
+ }
+}
+
/**
* e1000_vmdq_set_loopback_pf - enable or disable vmdq loopback
* @hw: pointer to the hardware struct
@@ -1739,6 +1828,45 @@ out:
}
/**
+ * e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits
+ * @hw: pointer to the HW structure
+ *
+ * This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on
+ * the values found in the EEPROM. This addresses an issue in which these
+ * bits are not restored from EEPROM after reset.
+ **/
+static s32 e1000_reset_mdicnfg_82580(struct e1000_hw *hw)
+{
+ s32 ret_val = E1000_SUCCESS;
+ u32 mdicnfg;
+ u16 nvm_data;
+
+ DEBUGFUNC("e1000_reset_mdicnfg_82580");
+
+ if (hw->mac.type != e1000_82580)
+ goto out;
+ if (!e1000_sgmii_active_82575(hw))
+ goto out;
+
+ ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
+ NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
+ &nvm_data);
+ if (ret_val) {
+ DEBUGOUT("NVM Read Error\n");
+ goto out;
+ }
+
+ mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
+ if (nvm_data & NVM_WORD24_EXT_MDIO)
+ mdicnfg |= E1000_MDICNFG_EXT_MDIO;
+ if (nvm_data & NVM_WORD24_COM_MDIO)
+ mdicnfg |= E1000_MDICNFG_COM_MDIO;
+ E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
+out:
+ return ret_val;
+}
+
+/**
* e1000_reset_hw_82580 - Reset hardware
* @hw: pointer to the HW structure
*
@@ -1814,6 +1942,10 @@ static s32 e1000_reset_hw_82580(struct e
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
+ ret_val = e1000_reset_mdicnfg_82580(hw);
+ if (ret_val)
+ DEBUGOUT("Could not reset MDICNFG based on EEPROM\n");
+
/* Install any alternate MAC address into RAR0 */
ret_val = e1000_check_alt_mac_addr_generic(hw);
Modified: stable/7/sys/dev/e1000/e1000_82575.h
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82575.h Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_82575.h Sat Nov 27 01:09:54 2010 (r215922)
@@ -458,6 +458,18 @@ struct e1000_adv_tx_context_desc {
/* RX packet buffer size defines */
#define E1000_RXPBS_SIZE_MASK_82576 0x0000007F
void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
+void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
+enum e1000_promisc_type {
+ e1000_promisc_disabled = 0, /* all promisc modes disabled */
+ e1000_promisc_unicast = 1, /* unicast promiscuous enabled */
+ e1000_promisc_multicast = 2, /* multicast promiscuous enabled */
+ e1000_promisc_enabled = 3, /* both uni and multicast promisc */
+ e1000_num_promisc_types
+};
+
+void e1000_vfta_set_vf(struct e1000_hw *, u16, bool);
+void e1000_rlpml_set_vf(struct e1000_hw *, u16);
+s32 e1000_promisc_set_vf(struct e1000_hw *, enum e1000_promisc_type type);
u16 e1000_rxpbs_adjust_82580(u32 data);
#endif /* _E1000_82575_H_ */
Modified: stable/7/sys/dev/e1000/e1000_api.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_api.c Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_api.c Sat Nov 27 01:09:54 2010 (r215922)
@@ -112,6 +112,31 @@ out:
return ret_val;
}
+/**
+ * e1000_init_mbx_params - Initialize mailbox function pointers
+ * @hw: pointer to the HW structure
+ *
+ * This function initializes the function pointers for the PHY
+ * set of functions. Called by drivers or by e1000_setup_init_funcs.
+ **/
+s32 e1000_init_mbx_params(struct e1000_hw *hw)
+{
+ s32 ret_val = E1000_SUCCESS;
+
+ if (hw->mbx.ops.init_params) {
+ ret_val = hw->mbx.ops.init_params(hw);
+ if (ret_val) {
+ DEBUGOUT("Mailbox Initialization Error\n");
+ goto out;
+ }
+ } else {
+ DEBUGOUT("mbx.init_mbx_params was NULL\n");
+ ret_val = -E1000_ERR_CONFIG;
+ }
+
+out:
+ return ret_val;
+}
/**
* e1000_set_mac_type - Sets MAC type
@@ -251,6 +276,8 @@ s32 e1000_set_mac_type(struct e1000_hw *
break;
case E1000_DEV_ID_ICH10_D_BM_LM:
case E1000_DEV_ID_ICH10_D_BM_LF:
+ case E1000_DEV_ID_ICH10_D_BM_V:
+ case E1000_DEV_ID_ICH10_HANKSVILLE:
mac->type = e1000_ich10lan;
break;
case E1000_DEV_ID_PCH_D_HV_DM:
@@ -259,6 +286,10 @@ s32 e1000_set_mac_type(struct e1000_hw *
case E1000_DEV_ID_PCH_M_HV_LC:
mac->type = e1000_pchlan;
break;
+ case E1000_DEV_ID_PCH2_LV_LM:
+ case E1000_DEV_ID_PCH2_LV_V:
+ mac->type = e1000_pch2lan;
+ break;
case E1000_DEV_ID_82575EB_COPPER:
case E1000_DEV_ID_82575EB_FIBER_SERDES:
case E1000_DEV_ID_82575GB_QUAD_COPPER:
@@ -269,6 +300,7 @@ s32 e1000_set_mac_type(struct e1000_hw *
case E1000_DEV_ID_82576_FIBER:
case E1000_DEV_ID_82576_SERDES:
case E1000_DEV_ID_82576_QUAD_COPPER:
+ case E1000_DEV_ID_82576_QUAD_COPPER_ET2:
case E1000_DEV_ID_82576_NS:
case E1000_DEV_ID_82576_NS_SERDES:
case E1000_DEV_ID_82576_SERDES_QUAD:
@@ -279,8 +311,14 @@ s32 e1000_set_mac_type(struct e1000_hw *
case E1000_DEV_ID_82580_SERDES:
case E1000_DEV_ID_82580_SGMII:
case E1000_DEV_ID_82580_COPPER_DUAL:
+ case E1000_DEV_ID_82580_QUAD_FIBER:
+ case E1000_DEV_ID_DH89XXCC_SGMII:
+ case E1000_DEV_ID_DH89XXCC_SERDES:
mac->type = e1000_82580;
break;
+ case E1000_DEV_ID_82576_VF:
+ mac->type = e1000_vfadapt;
+ break;
default:
/* Should never have loaded on this device */
ret_val = -E1000_ERR_MAC_INIT;
@@ -326,6 +364,7 @@ s32 e1000_setup_init_funcs(struct e1000_
e1000_init_mac_ops_generic(hw);
e1000_init_phy_ops_generic(hw);
e1000_init_nvm_ops_generic(hw);
+ e1000_init_mbx_ops_generic(hw);
/*
* Set up the init function pointers. These are functions within the
@@ -367,6 +406,7 @@ s32 e1000_setup_init_funcs(struct e1000_
case e1000_ich9lan:
case e1000_ich10lan:
case e1000_pchlan:
+ case e1000_pch2lan:
e1000_init_function_pointers_ich8lan(hw);
break;
case e1000_82575:
@@ -374,6 +414,9 @@ s32 e1000_setup_init_funcs(struct e1000_
case e1000_82580:
e1000_init_function_pointers_82575(hw);
break;
+ case e1000_vfadapt:
+ e1000_init_function_pointers_vf(hw);
+ break;
default:
DEBUGOUT("Hardware not supported\n");
ret_val = -E1000_ERR_CONFIG;
@@ -396,6 +439,10 @@ s32 e1000_setup_init_funcs(struct e1000_
ret_val = e1000_init_phy_params(hw);
if (ret_val)
goto out;
+
+ ret_val = e1000_init_mbx_params(hw);
+ if (ret_val)
+ goto out;
}
out:
@@ -1095,6 +1142,37 @@ s32 e1000_read_mac_addr(struct e1000_hw
}
/**
+ * e1000_read_pba_string - Read device part number string
+ * @hw: pointer to the HW structure
+ * @pba_num: pointer to device part number
+ * @pba_num_size: size of part number buffer
+ *
+ * Reads the product board assembly (PBA) number from the EEPROM and stores
+ * the value in pba_num.
+ * Currently no func pointer exists and all implementations are handled in the
+ * generic version of this function.
+ **/
+s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num, u32 pba_num_size)
+{
+ return e1000_read_pba_string_generic(hw, pba_num, pba_num_size);
+}
+
+/**
+ * e1000_read_pba_length - Read device part number string length
+ * @hw: pointer to the HW structure
+ * @pba_num_size: size of part number buffer
+ *
+ * Reads the product board assembly (PBA) number length from the EEPROM and
+ * stores the value in pba_num.
+ * Currently no func pointer exists and all implementations are handled in the
+ * generic version of this function.
+ **/
+s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size)
+{
+ return e1000_read_pba_length_generic(hw, pba_num_size);
+}
+
+/**
* e1000_read_pba_num - Read device part number
* @hw: pointer to the HW structure
* @pba_num: pointer to device part number
Modified: stable/7/sys/dev/e1000/e1000_api.h
==============================================================================
--- stable/7/sys/dev/e1000/e1000_api.h Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_api.h Sat Nov 27 01:09:54 2010 (r215922)
@@ -55,6 +55,7 @@ s32 e1000_setup_init_funcs(struct e1000
s32 e1000_init_mac_params(struct e1000_hw *hw);
s32 e1000_init_nvm_params(struct e1000_hw *hw);
s32 e1000_init_phy_params(struct e1000_hw *hw);
+s32 e1000_init_mbx_params(struct e1000_hw *hw);
s32 e1000_get_bus_info(struct e1000_hw *hw);
void e1000_clear_vfta(struct e1000_hw *hw);
void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value);
@@ -96,6 +97,9 @@ void e1000_power_up_phy(struct e1000_hw
void e1000_power_down_phy(struct e1000_hw *hw);
s32 e1000_read_mac_addr(struct e1000_hw *hw);
s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *part_num);
+s32 e1000_read_pba_string(struct e1000_hw *hw, u8 *pba_num,
+ u32 pba_num_size);
+s32 e1000_read_pba_length(struct e1000_hw *hw, u32 *pba_num_size);
void e1000_reload_nvm(struct e1000_hw *hw);
s32 e1000_update_nvm_checksum(struct e1000_hw *hw);
s32 e1000_validate_nvm_checksum(struct e1000_hw *hw);
Modified: stable/7/sys/dev/e1000/e1000_defines.h
==============================================================================
--- stable/7/sys/dev/e1000/e1000_defines.h Sat Nov 27 00:46:57 2010 (r215921)
+++ stable/7/sys/dev/e1000/e1000_defines.h Sat Nov 27 01:09:54 2010 (r215922)
@@ -49,6 +49,8 @@
#define E1000_WUC_LSCWO 0x00000020 /* Link Status wake up override */
#define E1000_WUC_SPM 0x80000000 /* Enable SPM */
#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */
+#define E1000_WUC_FLX6_PHY 0x4000 /* Flexible Filter 6 Enable */
+#define E1000_WUC_FLX7_PHY 0x8000 /* Flexible Filter 7 Enable */
/* Wake Up Filter Control */
#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
@@ -73,6 +75,8 @@
#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
#define E1000_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */
#define E1000_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
+#define E1000_WUFC_FLX6 0x00400000 /* Flexible Filter 6 Enable */
+#define E1000_WUFC_FLX7 0x00800000 /* Flexible Filter 7 Enable */
#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*/
@@ -80,9 +84,11 @@
#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_ALL_FILTERS_8 0x00FF00FF /* Mask for all 8 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 */
+#define E1000_WUFC_FLX_FILTERS_8 0x00FF0000 /* Mask for 8 flexible filters */
/*
* For 82576 to utilize Extended filter masks in addition to
* existing (filter) masks
@@ -109,10 +115,15 @@
#define E1000_WUS_FLX3 E1000_WUFC_FLX3
#define E1000_WUS_FLX4 E1000_WUFC_FLX4
#define E1000_WUS_FLX5 E1000_WUFC_FLX5
+#define E1000_WUS_FLX6 E1000_WUFC_FLX6
+#define E1000_WUS_FLX7 E1000_WUFC_FLX7
#define E1000_WUS_FLX4_PHY E1000_WUFC_FLX4_PHY
#define E1000_WUS_FLX5_PHY E1000_WUFC_FLX5_PHY
+#define E1000_WUS_FLX6_PHY 0x0400
+#define E1000_WUS_FLX7_PHY 0x0800
#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_8 E1000_WUFC_FLX_FILTERS_8
#define E1000_WUS_FLX_FILTERS_PHY_6 E1000_WUFC_FLX_FILTERS_PHY_6
/* Wake Up Packet Length */
@@ -122,6 +133,8 @@
#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
/* Six Flexible Filters are supported */
#define E1000_FLEXIBLE_FILTER_COUNT_MAX_6 6
+/* Eight Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX_8 8
/* 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 */
@@ -132,6 +145,7 @@
#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
#define E1000_FFLT_SIZE_6 E1000_FLEXIBLE_FILTER_COUNT_MAX_6
+#define E1000_FFLT_SIZE_8 E1000_FLEXIBLE_FILTER_COUNT_MAX_8
#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-7
mailing list