Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Jun 2009 17:41:29 +0000 (UTC)
From:      Jack F Vogel <jfv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r194865 - in head/sys: dev/e1000 modules/igb
Message-ID:  <200906241741.n5OHfTaw022417@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906241741.n5OHfTaw022417>