svn commit: r194865 - in head/sys: dev/e1000 modules/igb
Jack F Vogel
jfv at FreeBSD.org
Wed Jun 24 17:41:30 UTC 2009
Author: jfv
Date: Wed Jun 24 17:41:29 2009
New Revision: 194865
URL: http://svn.freebsd.org/changeset/base/194865
Log:
Updates for both the em and igb drivers, add support
for multiqueue tx, shared code updates, new device
support, and some bug fixes.
Modified:
head/sys/dev/e1000/e1000_82540.c
head/sys/dev/e1000/e1000_82541.c
head/sys/dev/e1000/e1000_82571.c
head/sys/dev/e1000/e1000_82575.c
head/sys/dev/e1000/e1000_82575.h
head/sys/dev/e1000/e1000_api.c
head/sys/dev/e1000/e1000_defines.h
head/sys/dev/e1000/e1000_hw.h
head/sys/dev/e1000/e1000_ich8lan.c
head/sys/dev/e1000/e1000_ich8lan.h
head/sys/dev/e1000/e1000_mac.c
head/sys/dev/e1000/e1000_osdep.c
head/sys/dev/e1000/e1000_phy.c
head/sys/dev/e1000/e1000_phy.h
head/sys/dev/e1000/e1000_regs.h
head/sys/dev/e1000/if_em.c
head/sys/dev/e1000/if_em.h
head/sys/dev/e1000/if_igb.c
head/sys/dev/e1000/if_igb.h
head/sys/modules/igb/Makefile
Modified: head/sys/dev/e1000/e1000_82540.c
==============================================================================
--- head/sys/dev/e1000/e1000_82540.c Wed Jun 24 17:31:37 2009 (r194864)
+++ head/sys/dev/e1000/e1000_82540.c Wed Jun 24 17:41:29 2009 (r194865)
@@ -57,6 +57,7 @@ static s32 e1000_set_vco_speed_82540(st
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(s
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(s
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;
+}
Modified: head/sys/dev/e1000/e1000_82541.c
==============================================================================
--- head/sys/dev/e1000/e1000_82541.c Wed Jun 24 17:31:37 2009 (r194864)
+++ head/sys/dev/e1000/e1000_82541.c Wed Jun 24 17:41:29 2009 (r194865)
@@ -377,6 +377,7 @@ static s32 e1000_reset_hw_82541(struct e
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 e1
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 e1
*/
e1000_clear_hw_cntrs_82541(hw);
+out:
return ret_val;
}
Modified: head/sys/dev/e1000/e1000_82571.c
==============================================================================
--- head/sys/dev/e1000/e1000_82571.c Wed Jun 24 17:31:37 2009 (r194864)
+++ head/sys/dev/e1000/e1000_82571.c Wed Jun 24 17:41:29 2009 (r194865)
@@ -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(s
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(s
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(s
{
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(s
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(s
/* 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(s
/* 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(s
? 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
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 @@ out:
*
* 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(
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 @@ out:
*
* 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(struc
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
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 e
*/
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 e
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 e1
/* ...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_825
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_825
/* 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_825
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(struc
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
*/
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
**/
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
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
* 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(st
*/
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(st
(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(st
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
switch (hw->mac.type) {
case e1000_82574:
+ case e1000_82583:
case e1000_82573:
if(*data == ID_LED_RESERVED_F746)
*data = ID_LED_DEFAULT_82573;
Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c Wed Jun 24 17:31:37 2009 (r194864)
+++ head/sys/dev/e1000/e1000_82575.c Wed Jun 24 17:41:29 2009 (r194865)
@@ -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_8257
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(
**/
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(struc
**/
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(stru
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_82
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_82
}
/**
- * e1000_vmdq_loopback_enable_pf- Enables VM to VM queue loopback replication
- * @hw: pointer to the HW structure
- **/
-void e1000_vmdq_loopback_enable_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_loopback_disable_pf - Disable VM to VM queue loopbk 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_disable_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_replication_enable_pf - Enable replication of brdcst & multicst
- * @hw: pointer to the HW structure
- *
- * 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.
- **/
-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
+ * e1000_vmdq_set_replication_pf - enable or disable vmdq replication
* @hw: pointer to the HW structure
+ * @enable: state to enter, either enabled or disabled
*
- * Disables replication of broadcast and multicast packets to the VM's.
+ * enables/disables replication of packets across multiple pools
**/
-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 e
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 e1
**/
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
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
*/
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
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 @@ out:
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(s
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 e1
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;
+}
+
Modified: head/sys/dev/e1000/e1000_82575.h
==============================================================================
--- head/sys/dev/e1000/e1000_82575.h Wed Jun 24 17:31:37 2009 (r194864)
+++ head/sys/dev/e1000/e1000_82575.h Wed Jun 24 17:41:29 2009 (r194865)
@@ -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
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-head
mailing list