svn commit: r185510 - stable/7/sys/dev/e1000

Jack F Vogel jfv at FreeBSD.org
Sun Nov 30 23:13:53 PST 2008


Author: jfv
Date: Mon Dec  1 07:13:52 2008
New Revision: 185510
URL: http://svn.freebsd.org/changeset/base/185510

Log:
  MFC of a critical fix for the ESB2 adapters in the em
  driver, however the fix required a shared code change that
  involves both em and igb, requiring some compatibility
  changes throughout.
  
  Also, the igb driver now has header split. This is a hardware
  assist that is able to seperate the payload and header into
  seperate buffers. Using jumbo frames and 4K mbuf clusters, this
  should allow the use of ZERO COPY, but that has yet to be
  implemented.
  
  Approved by:re

Modified:
  stable/7/sys/dev/e1000/e1000_80003es2lan.c
  stable/7/sys/dev/e1000/e1000_82540.c
  stable/7/sys/dev/e1000/e1000_82541.c
  stable/7/sys/dev/e1000/e1000_82542.c
  stable/7/sys/dev/e1000/e1000_82543.c
  stable/7/sys/dev/e1000/e1000_82571.c
  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_mac.h
  stable/7/sys/dev/e1000/e1000_manage.c
  stable/7/sys/dev/e1000/e1000_nvm.c
  stable/7/sys/dev/e1000/e1000_osdep.c
  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

Modified: stable/7/sys/dev/e1000/e1000_80003es2lan.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_80003es2lan.c	Mon Dec  1 05:44:08 2008	(r185509)
+++ stable/7/sys/dev/e1000/e1000_80003es2lan.c	Mon Dec  1 07:13:52 2008	(r185510)
@@ -32,7 +32,9 @@
 ******************************************************************************/
 /*$FreeBSD$*/
 
-/* e1000_80003es2lan
+/*
+ * 80003ES2LAN Gigabit Ethernet Controller (Copper)
+ * 80003ES2LAN Gigabit Ethernet Controller (Serdes)
  */
 
 #include "e1000_api.h"
@@ -41,7 +43,9 @@ static s32  e1000_init_phy_params_80003e
 static s32  e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_init_mac_params_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_acquire_phy_80003es2lan(struct e1000_hw *hw);
+static s32  e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw);
 static void e1000_release_phy_80003es2lan(struct e1000_hw *hw);
+static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw);
 static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw);
 static s32  e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
@@ -64,6 +68,11 @@ static void e1000_clear_hw_cntrs_80003es
 static s32  e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
 static s32  e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex);
 static s32  e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);
+static s32  e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw);
+static s32  e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+                                            u16 *data);
+static s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+                                             u16 data);
 static s32  e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw);
 static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
 static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask);
@@ -84,8 +93,6 @@ static const u16 e1000_gg82563_cable_len
 /**
  *  e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
 {
@@ -122,6 +129,8 @@ static s32 e1000_init_phy_params_80003es
 	phy->ops.read_reg           = e1000_read_phy_reg_gg82563_80003es2lan;
 	phy->ops.write_reg          = e1000_write_phy_reg_gg82563_80003es2lan;
 
+	phy->ops.cfg_on_link_up    = e1000_cfg_on_link_up_80003es2lan;
+
 	/* This can only be done after all function pointers are setup. */
 	ret_val = e1000_get_phy_id(hw);
 
@@ -138,8 +147,6 @@ out:
 /**
  *  e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw)
 {
@@ -197,8 +204,6 @@ static s32 e1000_init_nvm_params_80003es
 /**
  *  e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
 {
@@ -280,8 +285,6 @@ static s32 e1000_init_mac_params_80003es
 	/* turn on/off LED */
 	mac->ops.led_on = e1000_led_on_generic;
 	mac->ops.led_off = e1000_led_off_generic;
-	/* remove device */
-	mac->ops.remove_device = e1000_remove_device_generic;
 	/* clear hardware counters */
 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan;
 	/* link info */
@@ -295,8 +298,7 @@ out:
  *  e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs.
  *  @hw: pointer to the HW structure
  *
- *  The only function explicitly called by the api module to initialize
- *  all function pointers and parameters.
+ *  Called to initialize all function pointers and parameters.
  **/
 void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw)
 {
@@ -305,14 +307,14 @@ void e1000_init_function_pointers_80003e
 	hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan;
 	hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan;
 	hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan;
+	e1000_get_bus_info_pcie_generic(hw);
 }
 
 /**
  *  e1000_acquire_phy_80003es2lan - Acquire rights to access PHY
  *  @hw: pointer to the HW structure
  *
- *  A wrapper to acquire access rights to the correct PHY.  This is a
- *  function pointer entry point called by the api module.
+ *  A wrapper to acquire access rights to the correct PHY.
  **/
 static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
 {
@@ -321,8 +323,6 @@ static s32 e1000_acquire_phy_80003es2lan
 	DEBUGFUNC("e1000_acquire_phy_80003es2lan");
 
 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
-	mask |= E1000_SWFW_CSR_SM;
-
 	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
 }
 
@@ -330,8 +330,7 @@ static s32 e1000_acquire_phy_80003es2lan
  *  e1000_release_phy_80003es2lan - Release rights to access PHY
  *  @hw: pointer to the HW structure
  *
- *  A wrapper to release access rights to the correct PHY.  This is a
- *  function pointer entry point called by the api module.
+ *  A wrapper to release access rights to the correct PHY.
  **/
 static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
 {
@@ -340,7 +339,41 @@ static void e1000_release_phy_80003es2la
 	DEBUGFUNC("e1000_release_phy_80003es2lan");
 
 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
-	mask |= E1000_SWFW_CSR_SM;
+	e1000_release_swfw_sync_80003es2lan(hw, mask);
+}
+
+
+/**
+ *  e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire the semaphore to access the Kumeran interface.
+ *
+ **/
+static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
+{
+	u16 mask;
+
+	DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan");
+
+	mask = E1000_SWFW_CSR_SM;
+
+	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
+}
+
+/**
+ *  e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register
+ *  @hw: pointer to the HW structure
+ *
+ *  Release the semaphore used to access the Kumeran interface
+ **/
+static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw)
+{
+	u16 mask;
+
+	DEBUGFUNC("e1000_release_mac_csr_80003es2lan");
+
+	mask = E1000_SWFW_CSR_SM;
 
 	e1000_release_swfw_sync_80003es2lan(hw, mask);
 }
@@ -349,8 +382,7 @@ static void e1000_release_phy_80003es2la
  *  e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM
  *  @hw: pointer to the HW structure
  *
- *  Acquire the semaphore to access the EEPROM.  This is a function
- *  pointer entry point called by the api module.
+ *  Acquire the semaphore to access the EEPROM.
  **/
 static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw)
 {
@@ -375,8 +407,7 @@ out:
  *  e1000_release_nvm_80003es2lan - Relinquish rights to access NVM
  *  @hw: pointer to the HW structure
  *
- *  Release the semaphore used to access the EEPROM.  This is a
- *  function pointer entry point called by the api module.
+ *  Release the semaphore used to access the EEPROM.
  **/
 static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw)
 {
@@ -400,7 +431,7 @@ static s32 e1000_acquire_swfw_sync_80003
 	u32 swmask = mask;
 	u32 fwmask = mask << 16;
 	s32 ret_val = E1000_SUCCESS;
-	s32 i = 0, timeout = 200;
+	s32 i = 0, timeout = 50;
 
 	DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan");
 
@@ -452,8 +483,8 @@ static void e1000_release_swfw_sync_8000
 
 	DEBUGFUNC("e1000_release_swfw_sync_80003es2lan");
 
-	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS);
-	/* Empty */
+	while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS)
+		; /* Empty */
 
 	swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC);
 	swfw_sync &= ~mask;
@@ -468,8 +499,7 @@ static void e1000_release_swfw_sync_8000
  *  @offset: offset of the register to read
  *  @data: pointer to the data returned from the operation
  *
- *  Read the GG82563 PHY register.  This is a function pointer entry
- *  point called by the api module.
+ *  Read the GG82563 PHY register.
  **/
 static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
                                                   u32 offset, u16 *data)
@@ -520,9 +550,8 @@ static s32 e1000_read_phy_reg_gg82563_80
 
 	usec_delay(200);
 
-	ret_val = e1000_read_phy_reg_mdic(hw,
-	                                 MAX_PHY_REG_ADDRESS & offset,
-	                                 data);
+	ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+	                                   data);
 
 	usec_delay(200);
 	e1000_release_phy_80003es2lan(hw);
@@ -537,8 +566,7 @@ out:
  *  @offset: offset of the register to read
  *  @data: value to write to the register
  *
- *  Write to the GG82563 PHY register.  This is a function pointer entry
- *  point called by the api module.
+ *  Write to the GG82563 PHY register.
  **/
 static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
                                                    u32 offset, u16 data)
@@ -590,8 +618,7 @@ static s32 e1000_write_phy_reg_gg82563_8
 
 	usec_delay(200);
 
-	ret_val = e1000_write_phy_reg_mdic(hw,
-	                                  MAX_PHY_REG_ADDRESS & offset,
+	ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
 	                                  data);
 
 	usec_delay(200);
@@ -608,8 +635,7 @@ out:
  *  @words: number of words to write
  *  @data: buffer of data to write to the NVM
  *
- *  Write "words" of data to the ESB2 NVM.  This is a function
- *  pointer entry point called by the api module.
+ *  Write "words" of data to the ESB2 NVM.
  **/
 static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset,
                             u16 words, u16 *data)
@@ -775,10 +801,17 @@ static s32 e1000_get_cable_length_80003e
 		goto out;
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
-	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
-	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];
 
-	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
+	if (index < GG82563_CABLE_LENGTH_TABLE_SIZE + 5) {
+		phy->min_cable_length = e1000_gg82563_cable_length_table[index];
+		phy->max_cable_length =
+		                 e1000_gg82563_cable_length_table[index+5];
+
+		phy->cable_length = (phy->min_cable_length +
+		                     phy->max_cable_length) / 2;
+	} else {
+		ret_val = E1000_ERR_PHY;
+	}
 
 out:
 	return ret_val;
@@ -791,7 +824,6 @@ out:
  *  @duplex: pointer to duplex buffer
  *
  *  Retrieve the current speed and duplex configuration.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
                                               u16 *duplex)
@@ -804,20 +836,13 @@ static s32 e1000_get_link_up_info_80003e
 		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
 		                                                    speed,
 		                                                    duplex);
-		if (ret_val)
-			goto out;
-		if (*speed == SPEED_1000)
-			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
-		else
-			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw,
-			                                      *duplex);
+		hw->phy.ops.cfg_on_link_up(hw);
 	} else {
 		ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw,
 		                                                  speed,
 		                                                  duplex);
 	}
 
-out:
 	return ret_val;
 }
 
@@ -826,7 +851,6 @@ out:
  *  @hw: pointer to the HW structure
  *
  *  Perform a global reset to the ESB2 controller.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
 {
@@ -840,9 +864,8 @@ static s32 e1000_reset_hw_80003es2lan(st
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
 	ret_val = e1000_disable_pcie_master_generic(hw);
-	if (ret_val) {
+	if (ret_val)
 		DEBUGOUT("PCI-E Master disable polling has failed.\n");
-	}
 
 	DEBUGOUT("Masking off all interrupts\n");
 	E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
@@ -855,8 +878,10 @@ static s32 e1000_reset_hw_80003es2lan(st
 
 	ctrl = E1000_READ_REG(hw, E1000_CTRL);
 
+	ret_val = e1000_acquire_phy_80003es2lan(hw);
 	DEBUGOUT("Issuing a global reset to MAC\n");
 	E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST);
+	e1000_release_phy_80003es2lan(hw);
 
 	ret_val = e1000_get_auto_rd_done_generic(hw);
 	if (ret_val)
@@ -878,7 +903,6 @@ out:
  *  @hw: pointer to the HW structure
  *
  *  Initialize the hw bits, LED, VFTA, MTA, link and hw counters.
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
 {
@@ -969,9 +993,6 @@ static void e1000_initialize_hw_bits_800
 
 	DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan");
 
-	if (hw->mac.disable_hw_init_bits)
-		goto out;
-
 	/* Transmit Descriptor Control 0 */
 	reg = E1000_READ_REG(hw, E1000_TXDCTL(0));
 	reg |= (1 << 22);
@@ -997,7 +1018,6 @@ static void e1000_initialize_hw_bits_800
 		reg |= (1 << 28);
 	E1000_WRITE_REG(hw, E1000_TARC(1), reg);
 
-out:
 	return;
 }
 
@@ -1012,8 +1032,7 @@ static s32 e1000_copper_link_setup_gg825
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 	u32 ctrl_ext;
-	u32 i = 0;
-	u16 data, data2;
+	u16 data;
 
 	DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan");
 
@@ -1084,20 +1103,20 @@ static s32 e1000_copper_link_setup_gg825
 	}
 
 	/* Bypass Rx and Tx FIFO's */
-	ret_val = e1000_write_kmrn_reg_generic(hw,
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
 	                        E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
 	                        E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
 	                                E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
 	if (ret_val)
 		goto out;
 
-	ret_val = e1000_read_kmrn_reg_generic(hw,
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
 	                              E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
 	                              &data);
 	if (ret_val)
 		goto out;
 	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
-	ret_val = e1000_write_kmrn_reg_generic(hw,
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
 	                               E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
 	                               data);
 	if (ret_val)
@@ -1129,30 +1148,20 @@ static s32 e1000_copper_link_setup_gg825
 		/* Enable Electrical Idle on the PHY */
 		data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
 		ret_val = hw->phy.ops.write_reg(hw,
-		                             GG82563_PHY_PWR_MGMT_CTRL,
-		                             data);
+		                                GG82563_PHY_PWR_MGMT_CTRL,
+		                                data);
 		if (ret_val)
 			goto out;
-
-		do {
-			ret_val = hw->phy.ops.read_reg(hw,
-			                          GG82563_PHY_KMRN_MODE_CTRL,
-			                          &data);
-			if (ret_val)
-				goto out;
-
-			ret_val = hw->phy.ops.read_reg(hw,
-			                          GG82563_PHY_KMRN_MODE_CTRL,
-			                          &data2);
+		ret_val = hw->phy.ops.read_reg(hw,
+			                       GG82563_PHY_KMRN_MODE_CTRL,
+			                       &data);
 			if (ret_val)
 				goto out;
-			i++;
-		} while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 		ret_val = hw->phy.ops.write_reg(hw,
-		                             GG82563_PHY_KMRN_MODE_CTRL,
-		                             data);
+		                                GG82563_PHY_KMRN_MODE_CTRL,
+		                                data);
 
 		if (ret_val)
 			goto out;
@@ -1185,7 +1194,7 @@ out:
 static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 {
 	u32 ctrl;
-	s32  ret_val;
+	s32 ret_val;
 	u16 reg_data;
 
 	DEBUGFUNC("e1000_setup_copper_link_80003es2lan");
@@ -1200,26 +1209,26 @@ static s32 e1000_setup_copper_link_80003
 	 * iteration and increase the max iterations when
 	 * polling the phy; this fixes erroneous timeouts at 10Mbps.
 	 */
-	ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 4),
-	                                       0xFFFF);
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),
+	                                           0xFFFF);
 	if (ret_val)
 		goto out;
-	ret_val = e1000_read_kmrn_reg_generic(hw, GG82563_REG(0x34, 9),
-	                                      &reg_data);
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
+	                                          &reg_data);
 	if (ret_val)
 		goto out;
 	reg_data |= 0x3F;
-	ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 9),
-	                                       reg_data);
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
+	                                           reg_data);
 	if (ret_val)
 		goto out;
-	ret_val = e1000_read_kmrn_reg_generic(hw,
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
 	                              E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
 	                              &reg_data);
 	if (ret_val)
 		goto out;
 	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
-	ret_val = e1000_write_kmrn_reg_generic(hw,
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
 	                               E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
 	                               reg_data);
 	if (ret_val)
@@ -1236,6 +1245,40 @@ out:
 }
 
 /**
+ *  e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up
+ *  @hw: pointer to the HW structure
+ *  @duplex: current duplex setting
+ *
+ *  Configure the KMRN interface by applying last minute quirks for
+ *  10/100 operation.
+ **/
+static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
+{
+	s32 ret_val = E1000_SUCCESS;
+	u16 speed;
+	u16 duplex;
+
+	DEBUGFUNC("e1000_configure_on_link_up");
+
+	if (hw->phy.media_type == e1000_media_type_copper) {
+
+		ret_val = e1000_get_speed_and_duplex_copper_generic(hw,
+		                                                    &speed,
+		                                                    &duplex);
+		if (ret_val)
+			goto out;
+
+		if (speed == SPEED_1000)
+			ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
+		else
+			ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);
+	}
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation
  *  @hw: pointer to the HW structure
  *  @duplex: current duplex setting
@@ -1253,7 +1296,7 @@ static s32 e1000_cfg_kmrn_10_100_80003es
 	DEBUGFUNC("e1000_configure_kmrn_for_10_100");
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
-	ret_val = e1000_write_kmrn_reg_generic(hw,
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
 	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
 	                               reg_data);
 	if (ret_val)
@@ -1268,12 +1311,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es
 
 	do {
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-		                             &reg_data);
+		                               &reg_data);
 		if (ret_val)
 			goto out;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-		                             &reg_data2);
+		                               &reg_data2);
 		if (ret_val)
 			goto out;
 		i++;
@@ -1307,7 +1350,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2l
 	DEBUGFUNC("e1000_configure_kmrn_for_1000");
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
-	ret_val = e1000_write_kmrn_reg_generic(hw,
+	ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
 	                               E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
 	                               reg_data);
 	if (ret_val)
@@ -1322,12 +1365,12 @@ static s32 e1000_cfg_kmrn_1000_80003es2l
 
 	do {
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-		                             &reg_data);
+		                               &reg_data);
 		if (ret_val)
 			goto out;
 
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-		                             &reg_data2);
+		                               &reg_data2);
 		if (ret_val)
 			goto out;
 		i++;
@@ -1341,6 +1384,75 @@ out:
 }
 
 /**
+ *  e1000_read_kmrn_reg_80003es2lan - Read kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquire semaphore, then read the PHY register at offset
+ *  using the kumeran interface.  The information retrieved is stored in data.
+ *  Release the semaphore before exiting.
+ **/
+s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+	u32 kmrnctrlsta;
+	s32 ret_val = E1000_SUCCESS;
+
+	DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan");
+
+	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
+	if (ret_val)
+		goto out;
+
+	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
+	               E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
+	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
+
+	usec_delay(2);
+
+	kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA);
+	*data = (u16)kmrnctrlsta;
+
+	e1000_release_mac_csr_80003es2lan(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_write_kmrn_reg_80003es2lan - Write kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquire semaphore, then write the data to PHY register
+ *  at the offset using the kumeran interface.  Release semaphore
+ *  before exiting.
+ **/
+s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data)
+{
+	u32 kmrnctrlsta;
+	s32 ret_val = E1000_SUCCESS;
+
+	DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan");
+
+	ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
+	if (ret_val)
+		goto out;
+
+	kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
+	               E1000_KMRNCTRLSTA_OFFSET) | data;
+	E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta);
+
+	usec_delay(2);
+
+	e1000_release_mac_csr_80003es2lan(hw);
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000_read_mac_addr_80003es2lan - Read device MAC address
  *  @hw: pointer to the HW structure
  **/
@@ -1380,44 +1492,42 @@ static void e1000_power_down_phy_copper_
  **/
 static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
 {
-	volatile u32 temp;
-
 	DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan");
 
 	e1000_clear_hw_cntrs_base_generic(hw);
 
-	temp = E1000_READ_REG(hw, E1000_PRC64);
-	temp = E1000_READ_REG(hw, E1000_PRC127);
-	temp = E1000_READ_REG(hw, E1000_PRC255);
-	temp = E1000_READ_REG(hw, E1000_PRC511);
-	temp = E1000_READ_REG(hw, E1000_PRC1023);
-	temp = E1000_READ_REG(hw, E1000_PRC1522);
-	temp = E1000_READ_REG(hw, E1000_PTC64);
-	temp = E1000_READ_REG(hw, E1000_PTC127);
-	temp = E1000_READ_REG(hw, E1000_PTC255);
-	temp = E1000_READ_REG(hw, E1000_PTC511);
-	temp = E1000_READ_REG(hw, E1000_PTC1023);
-	temp = E1000_READ_REG(hw, E1000_PTC1522);
-
-	temp = E1000_READ_REG(hw, E1000_ALGNERRC);
-	temp = E1000_READ_REG(hw, E1000_RXERRC);
-	temp = E1000_READ_REG(hw, E1000_TNCRS);
-	temp = E1000_READ_REG(hw, E1000_CEXTERR);
-	temp = E1000_READ_REG(hw, E1000_TSCTC);
-	temp = E1000_READ_REG(hw, E1000_TSCTFC);
-
-	temp = E1000_READ_REG(hw, E1000_MGTPRC);
-	temp = E1000_READ_REG(hw, E1000_MGTPDC);
-	temp = E1000_READ_REG(hw, E1000_MGTPTC);
-
-	temp = E1000_READ_REG(hw, E1000_IAC);
-	temp = E1000_READ_REG(hw, E1000_ICRXOC);
-
-	temp = E1000_READ_REG(hw, E1000_ICRXPTC);
-	temp = E1000_READ_REG(hw, E1000_ICRXATC);
-	temp = E1000_READ_REG(hw, E1000_ICTXPTC);
-	temp = E1000_READ_REG(hw, E1000_ICTXATC);
-	temp = E1000_READ_REG(hw, E1000_ICTXQEC);
-	temp = E1000_READ_REG(hw, E1000_ICTXQMTC);
-	temp = E1000_READ_REG(hw, E1000_ICRXDMTC);
+	E1000_READ_REG(hw, E1000_PRC64);
+	E1000_READ_REG(hw, E1000_PRC127);
+	E1000_READ_REG(hw, E1000_PRC255);
+	E1000_READ_REG(hw, E1000_PRC511);
+	E1000_READ_REG(hw, E1000_PRC1023);
+	E1000_READ_REG(hw, E1000_PRC1522);
+	E1000_READ_REG(hw, E1000_PTC64);
+	E1000_READ_REG(hw, E1000_PTC127);
+	E1000_READ_REG(hw, E1000_PTC255);
+	E1000_READ_REG(hw, E1000_PTC511);
+	E1000_READ_REG(hw, E1000_PTC1023);
+	E1000_READ_REG(hw, E1000_PTC1522);
+
+	E1000_READ_REG(hw, E1000_ALGNERRC);
+	E1000_READ_REG(hw, E1000_RXERRC);
+	E1000_READ_REG(hw, E1000_TNCRS);
+	E1000_READ_REG(hw, E1000_CEXTERR);
+	E1000_READ_REG(hw, E1000_TSCTC);
+	E1000_READ_REG(hw, E1000_TSCTFC);
+
+	E1000_READ_REG(hw, E1000_MGTPRC);
+	E1000_READ_REG(hw, E1000_MGTPDC);
+	E1000_READ_REG(hw, E1000_MGTPTC);
+
+	E1000_READ_REG(hw, E1000_IAC);
+	E1000_READ_REG(hw, E1000_ICRXOC);
+
+	E1000_READ_REG(hw, E1000_ICRXPTC);
+	E1000_READ_REG(hw, E1000_ICRXATC);
+	E1000_READ_REG(hw, E1000_ICTXPTC);
+	E1000_READ_REG(hw, E1000_ICTXATC);
+	E1000_READ_REG(hw, E1000_ICTXQEC);
+	E1000_READ_REG(hw, E1000_ICTXQMTC);
+	E1000_READ_REG(hw, E1000_ICRXDMTC);
 }

Modified: stable/7/sys/dev/e1000/e1000_82540.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82540.c	Mon Dec  1 05:44:08 2008	(r185509)
+++ stable/7/sys/dev/e1000/e1000_82540.c	Mon Dec  1 07:13:52 2008	(r185510)
@@ -32,11 +32,15 @@
 ******************************************************************************/
 /*$FreeBSD$*/
 
-/* e1000_82540
- * e1000_82545
- * e1000_82546
- * e1000_82545_rev_3
- * e1000_82546_rev_3
+/*
+ * 82540EM Gigabit Ethernet Controller
+ * 82540EP Gigabit Ethernet Controller
+ * 82545EM Gigabit Ethernet Controller (Copper)
+ * 82545EM Gigabit Ethernet Controller (Fiber)
+ * 82545GM Gigabit Ethernet Controller
+ * 82546EB Gigabit Ethernet Controller (Copper)
+ * 82546EB Gigabit Ethernet Controller (Fiber)
+ * 82546GB Gigabit Ethernet Controller
  */
 
 #include "e1000_api.h"
@@ -57,8 +61,6 @@ static void e1000_power_down_phy_copper_
 /**
  * e1000_init_phy_params_82540 - Init PHY func ptrs.
  * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_phy_params_82540(struct e1000_hw *hw)
 {
@@ -110,8 +112,6 @@ out:
 /**
  * e1000_init_nvm_params_82540 - Init NVM func ptrs.
  * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw)
 {
@@ -153,8 +153,6 @@ static s32 e1000_init_nvm_params_82540(s
 /**
  * e1000_init_mac_params_82540 - Init MAC func ptrs.
  * @hw: pointer to the HW structure
- *
- * This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_mac_params_82540(struct e1000_hw *hw)
 {
@@ -189,6 +187,8 @@ static s32 e1000_init_mac_params_82540(s
 
 	/* bus type/speed/width */
 	mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
+	/* function id */
+	mac->ops.set_lan_id = e1000_set_lan_id_multi_port_pci;
 	/* reset */
 	mac->ops.reset_hw = e1000_reset_hw_82540;
 	/* hw initialization */
@@ -247,8 +247,7 @@ out:
  * e1000_init_function_pointers_82540 - Init func ptrs.
  * @hw: pointer to the HW structure
  *
- * The only function explicitly called by the api module to initialize
- * all function pointers and parameters.
+ * Called to initialize all function pointers and parameters.
  **/
 void e1000_init_function_pointers_82540(struct e1000_hw *hw)
 {
@@ -263,8 +262,7 @@ void e1000_init_function_pointers_82540(
  *  e1000_reset_hw_82540 - Reset hardware
  *  @hw: pointer to the HW structure
  *
- *  This resets the hardware into a known state.  This is a
- *  function pointer entry point called by the api module.
+ *  This resets the hardware into a known state.
  **/
 static s32 e1000_reset_hw_82540(struct e1000_hw *hw)
 {
@@ -322,8 +320,7 @@ static s32 e1000_reset_hw_82540(struct e
  *  e1000_init_hw_82540 - Initialize hardware
  *  @hw: pointer to the HW structure
  *
- *  This inits the hardware readying it for operation.  This is a
- *  function pointer entry point called by the api module.
+ *  This inits the hardware readying it for operation.
  **/
 static s32 e1000_init_hw_82540(struct e1000_hw *hw)
 {
@@ -406,8 +403,7 @@ static s32 e1000_init_hw_82540(struct e1
  *  Calls the appropriate function to configure the link for auto-neg or forced
  *  speed and duplex.  Then we check for link, once link is established calls
  *  to configure collision distance and flow control are called.  If link is
- *  not established, we return -E1000_ERR_PHY (-2).  This is a function
- *  pointer entry point called by the api module.
+ *  not established, we return -E1000_ERR_PHY (-2).
  **/
 static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw)
 {
@@ -454,8 +450,7 @@ out:
  *  Set the output amplitude to the value in the EEPROM and adjust the VCO
  *  speed to improve Bit Error Rate (BER) performance.  Configures collision
  *  distance and flow control for fiber and serdes links.  Upon successful
- *  setup, poll for link.  This is a function pointer entry point called by
- *  the api module.
+ *  setup, poll for link.
  **/
 static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw)
 {
@@ -650,34 +645,32 @@ static void e1000_power_down_phy_copper_
  **/
 static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw)
 {
-	volatile u32 temp;
-
 	DEBUGFUNC("e1000_clear_hw_cntrs_82540");
 
 	e1000_clear_hw_cntrs_base_generic(hw);
 
-	temp = E1000_READ_REG(hw, E1000_PRC64);
-	temp = E1000_READ_REG(hw, E1000_PRC127);
-	temp = E1000_READ_REG(hw, E1000_PRC255);
-	temp = E1000_READ_REG(hw, E1000_PRC511);
-	temp = E1000_READ_REG(hw, E1000_PRC1023);
-	temp = E1000_READ_REG(hw, E1000_PRC1522);
-	temp = E1000_READ_REG(hw, E1000_PTC64);
-	temp = E1000_READ_REG(hw, E1000_PTC127);
-	temp = E1000_READ_REG(hw, E1000_PTC255);
-	temp = E1000_READ_REG(hw, E1000_PTC511);
-	temp = E1000_READ_REG(hw, E1000_PTC1023);
-	temp = E1000_READ_REG(hw, E1000_PTC1522);
-
-	temp = E1000_READ_REG(hw, E1000_ALGNERRC);
-	temp = E1000_READ_REG(hw, E1000_RXERRC);
-	temp = E1000_READ_REG(hw, E1000_TNCRS);
-	temp = E1000_READ_REG(hw, E1000_CEXTERR);
-	temp = E1000_READ_REG(hw, E1000_TSCTC);
-	temp = E1000_READ_REG(hw, E1000_TSCTFC);
-
-	temp = E1000_READ_REG(hw, E1000_MGTPRC);
-	temp = E1000_READ_REG(hw, E1000_MGTPDC);
-	temp = E1000_READ_REG(hw, E1000_MGTPTC);
+	E1000_READ_REG(hw, E1000_PRC64);
+	E1000_READ_REG(hw, E1000_PRC127);
+	E1000_READ_REG(hw, E1000_PRC255);
+	E1000_READ_REG(hw, E1000_PRC511);
+	E1000_READ_REG(hw, E1000_PRC1023);
+	E1000_READ_REG(hw, E1000_PRC1522);
+	E1000_READ_REG(hw, E1000_PTC64);
+	E1000_READ_REG(hw, E1000_PTC127);
+	E1000_READ_REG(hw, E1000_PTC255);
+	E1000_READ_REG(hw, E1000_PTC511);
+	E1000_READ_REG(hw, E1000_PTC1023);
+	E1000_READ_REG(hw, E1000_PTC1522);
+
+	E1000_READ_REG(hw, E1000_ALGNERRC);
+	E1000_READ_REG(hw, E1000_RXERRC);
+	E1000_READ_REG(hw, E1000_TNCRS);
+	E1000_READ_REG(hw, E1000_CEXTERR);
+	E1000_READ_REG(hw, E1000_TSCTC);
+	E1000_READ_REG(hw, E1000_TSCTFC);
+
+	E1000_READ_REG(hw, E1000_MGTPRC);
+	E1000_READ_REG(hw, E1000_MGTPDC);
+	E1000_READ_REG(hw, E1000_MGTPTC);
 }
 

Modified: stable/7/sys/dev/e1000/e1000_82541.c
==============================================================================
--- stable/7/sys/dev/e1000/e1000_82541.c	Mon Dec  1 05:44:08 2008	(r185509)
+++ stable/7/sys/dev/e1000/e1000_82541.c	Mon Dec  1 07:13:52 2008	(r185510)
@@ -32,10 +32,13 @@
 ******************************************************************************/
 /*$FreeBSD$*/
 
-/* e1000_82541
- * e1000_82547
- * e1000_82541_rev_2
- * e1000_82547_rev_2
+/*
+ * 82541EI Gigabit Ethernet Controller
+ * 82541ER Gigabit Ethernet Controller
+ * 82541GI Gigabit Ethernet Controller
+ * 82541PI Gigabit Ethernet Controller
+ * 82547EI Gigabit Ethernet Controller
+ * 82547GI Gigabit Ethernet Controller
  */
 
 #include "e1000_api.h"
@@ -74,18 +77,9 @@ static const u16 e1000_igp_cable_length_
                 (sizeof(e1000_igp_cable_length_table) / \
                  sizeof(e1000_igp_cable_length_table[0]))
 
-struct e1000_dev_spec_82541 {
-	enum e1000_dsp_config dsp_config;
-	enum e1000_ffe_config ffe_config;
-	u16 spd_default;
-	bool phy_init_script;
-};
-
 /**
  *  e1000_init_phy_params_82541 - Init PHY func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_phy_params_82541(struct e1000_hw *hw)
 {
@@ -129,8 +123,6 @@ out:
 /**
  *  e1000_init_nvm_params_82541 - Init NVM func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_nvm_params_82541(struct e1000_hw *hw)
 {
@@ -227,13 +219,10 @@ out:
 /**
  *  e1000_init_mac_params_82541 - Init MAC func ptrs.
  *  @hw: pointer to the HW structure
- *
- *  This is a function pointer entry point called by the api module.
  **/
 static s32 e1000_init_mac_params_82541(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val;
 
 	DEBUGFUNC("e1000_init_mac_params_82541");
 
@@ -250,6 +239,8 @@ static s32 e1000_init_mac_params_82541(s
 
 	/* bus type/speed/width */
 	mac->ops.get_bus_info = e1000_get_bus_info_pci_generic;
+	/* function id */
+	mac->ops.set_lan_id = e1000_set_lan_id_single_port;
 	/* reset */
 	mac->ops.reset_hw = e1000_reset_hw_82541;
 	/* hw initialization */
@@ -277,25 +268,17 @@ static s32 e1000_init_mac_params_82541(s
 	/* turn on/off LED */
 	mac->ops.led_on = e1000_led_on_generic;
 	mac->ops.led_off = e1000_led_off_generic;
-	/* remove device */
-	mac->ops.remove_device = e1000_remove_device_generic;
 	/* clear hardware counters */
 	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82541;
 
-	hw->dev_spec_size = sizeof(struct e1000_dev_spec_82541);
-
-	/* Device-specific structure allocation */
-	ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
-
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
  *  e1000_init_function_pointers_82541 - Init func ptrs.
  *  @hw: pointer to the HW structure
  *
- *  The only function explicitly called by the api module to initialize
- *  all function pointers and parameters.
+ *  Called to initialize all function pointers and parameters.
  **/
 void e1000_init_function_pointers_82541(struct e1000_hw *hw)
 {
@@ -310,8 +293,7 @@ void e1000_init_function_pointers_82541(
  *  e1000_reset_hw_82541 - Reset hardware
  *  @hw: pointer to the HW structure
  *
- *  This resets the hardware into a known state.  This is a
- *  function pointer entry point called by the api module.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable mailing list