svn commit: r200243 - head/sys/dev/e1000

Jack F Vogel jfv at FreeBSD.org
Mon Dec 7 17:07:45 PST 2009


Author: jfv
Date: Tue Dec  8 01:07:44 2009
New Revision: 200243
URL: http://svn.freebsd.org/changeset/base/200243

Log:
  Resync with Intel versions of both the em and igb
  drivers. These add new hardware support, most importantly
  the pch (i5 chipset) in the em driver. Also, both drivers
  now have the simplified (and I hope improved) watchdog
  code. The igb driver uses the new RX cleanup that I
  first implemented in ixgbe.
  
  em  - version 6.9.24
  igb - version 1.8.4

Modified:
  head/sys/dev/e1000/LICENSE
  head/sys/dev/e1000/e1000_80003es2lan.c
  head/sys/dev/e1000/e1000_80003es2lan.h
  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_manage.c
  head/sys/dev/e1000/e1000_osdep.h
  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

Modified: head/sys/dev/e1000/LICENSE
==============================================================================
--- head/sys/dev/e1000/LICENSE	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/LICENSE	Tue Dec  8 01:07:44 2009	(r200243)
@@ -1,6 +1,6 @@
 $FreeBSD$
 
-  Copyright (c) 2001-2008, Intel Corporation 
+  Copyright (c) 2001-2009, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 

Modified: head/sys/dev/e1000/e1000_80003es2lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_80003es2lan.c	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/e1000_80003es2lan.c	Tue Dec  8 01:07:44 2009	(r200243)
@@ -171,7 +171,7 @@ static s32 e1000_init_nvm_params_80003es
 		break;
 	}
 
-	nvm->type               = e1000_nvm_eeprom_spi;
+	nvm->type = e1000_nvm_eeprom_spi;
 
 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
 	                  E1000_EECD_SIZE_EX_SHIFT);
@@ -206,17 +206,22 @@ static s32 e1000_init_nvm_params_80003es
 static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val = E1000_SUCCESS;
 
 	DEBUGFUNC("e1000_init_mac_params_80003es2lan");
 
-	/* Set media type */
+	/* Set media type and media-dependent function pointers */
 	switch (hw->device_id) {
 	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
 		hw->phy.media_type = e1000_media_type_internal_serdes;
+		mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
+		mac->ops.setup_physical_interface =
+			e1000_setup_fiber_serdes_link_generic;
 		break;
 	default:
 		hw->phy.media_type = e1000_media_type_copper;
+		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
+		mac->ops.setup_physical_interface =
+			e1000_setup_copper_link_80003es2lan;
 		break;
 	}
 
@@ -230,6 +235,8 @@ static s32 e1000_init_mac_params_80003es
 	mac->arc_subsystem_valid =
 	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
 	                ? TRUE : FALSE;
+	/* Adaptive IFS not supported */
+	mac->adaptive_ifs = FALSE;
 
 	/* Function pointers */
 
@@ -241,27 +248,6 @@ static s32 e1000_init_mac_params_80003es
 	mac->ops.init_hw = e1000_init_hw_80003es2lan;
 	/* link setup */
 	mac->ops.setup_link = e1000_setup_link_generic;
-	/* physical interface link setup */
-	mac->ops.setup_physical_interface =
-	        (hw->phy.media_type == e1000_media_type_copper)
-	                ? e1000_setup_copper_link_80003es2lan
-	                : e1000_setup_fiber_serdes_link_generic;
-	/* check for link */
-	switch (hw->phy.media_type) {
-	case e1000_media_type_copper:
-		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
-		break;
-	case e1000_media_type_fiber:
-		mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
-		break;
-	case e1000_media_type_internal_serdes:
-		mac->ops.check_for_link = e1000_check_for_serdes_link_generic;
-		break;
-	default:
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
-		break;
-	}
 	/* check management mode */
 	mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
 	/* multicast address update */
@@ -290,8 +276,10 @@ static s32 e1000_init_mac_params_80003es
 	/* link info */
 	mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan;
 
-out:
-	return ret_val;
+	/* set lan id for port to determine which phy lock to use */
+	hw->mac.ops.set_lan_id(hw);
+
+	return E1000_SUCCESS;
 }
 
 /**
@@ -307,7 +295,6 @@ 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);
 }
 
 /**
@@ -342,7 +329,6 @@ static void e1000_release_phy_80003es2la
 	e1000_release_swfw_sync_80003es2lan(hw, mask);
 }
 
-
 /**
  *  e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
  *  @hw: pointer to the HW structure
@@ -532,28 +518,36 @@ static s32 e1000_read_phy_reg_gg82563_80
 		goto out;
 	}
 
-	/*
-	 * The "ready" bit in the MDIC register may be incorrectly set
-	 * before the device has completed the "Page Select" MDI
-	 * transaction.  So we wait 200us after each MDI command...
-	 */
-	usec_delay(200);
+	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
+		/*
+		 * The "ready" bit in the MDIC register may be incorrectly set
+		 * before the device has completed the "Page Select" MDI
+		 * transaction.  So we wait 200us after each MDI command...
+		 */
+		usec_delay(200);
 
-	/* ...and verify the command was successful. */
-	ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
+		/* ...and verify the command was successful. */
+		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
 
-	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-		ret_val = -E1000_ERR_PHY;
-		e1000_release_phy_80003es2lan(hw);
-		goto out;
-	}
+		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
+			ret_val = -E1000_ERR_PHY;
+			e1000_release_phy_80003es2lan(hw);
+			goto out;
+		}
+
+		usec_delay(200);
 
-	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);
+	} else {
+		ret_val = e1000_read_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
+	}
 
-	usec_delay(200);
 	e1000_release_phy_80003es2lan(hw);
 
 out:
@@ -599,29 +593,36 @@ static s32 e1000_write_phy_reg_gg82563_8
 		goto out;
 	}
 
+	if (hw->dev_spec._80003es2lan.mdic_wa_enable == TRUE) {
+		/*
+		 * The "ready" bit in the MDIC register may be incorrectly set
+		 * before the device has completed the "Page Select" MDI
+		 * transaction.  So we wait 200us after each MDI command...
+		 */
+		usec_delay(200);
 
-	/*
-	 * The "ready" bit in the MDIC register may be incorrectly set
-	 * before the device has completed the "Page Select" MDI
-	 * transaction.  So we wait 200us after each MDI command...
-	 */
-	usec_delay(200);
+		/* ...and verify the command was successful. */
+		ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
 
-	/* ...and verify the command was successful. */
-	ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp);
+		if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
+			ret_val = -E1000_ERR_PHY;
+			e1000_release_phy_80003es2lan(hw);
+			goto out;
+		}
 
-	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
-		ret_val = -E1000_ERR_PHY;
-		e1000_release_phy_80003es2lan(hw);
-		goto out;
-	}
+		usec_delay(200);
 
-	usec_delay(200);
+		ret_val = e1000_write_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
 
-	ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
-	                                  data);
+		usec_delay(200);
+	} else {
+		ret_val = e1000_write_phy_reg_mdic(hw,
+		                                  MAX_PHY_REG_ADDRESS & offset,
+		                                  data);
+	}
 
-	usec_delay(200);
 	e1000_release_phy_80003es2lan(hw);
 
 out:
@@ -802,13 +803,13 @@ static s32 e1000_get_cable_length_80003e
 
 	index = phy_data & GG82563_DSPD_CABLE_LENGTH;
 
-	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE + 5) {
-		ret_val = E1000_ERR_PHY;
+	if (index >= GG82563_CABLE_LENGTH_TABLE_SIZE - 5) {
+		ret_val = -E1000_ERR_PHY;
 		goto out;
 	}
 
 	phy->min_cable_length = e1000_gg82563_cable_length_table[index];
-	phy->max_cable_length = e1000_gg82563_cable_length_table[index+5];
+	phy->max_cable_length = e1000_gg82563_cable_length_table[index + 5];
 
 	phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
 
@@ -916,10 +917,9 @@ static s32 e1000_init_hw_80003es2lan(str
 
 	/* Initialize identification LED */
 	ret_val = mac->ops.id_led_init(hw);
-	if (ret_val) {
+	if (ret_val)
 		DEBUGOUT("Error initializing identification LED\n");
 		/* This is not fatal and we should not stop init due to this */
-	}
 
 	/* Disabling VLAN filtering */
 	DEBUGOUT("Initializing the IEEE VLAN\n");
@@ -969,6 +969,19 @@ static s32 e1000_init_hw_80003es2lan(str
 	reg_data &= ~0x00100000;
 	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);
 
+	/* default to TRUE to enable the MDIC W/A */
+	hw->dev_spec._80003es2lan.mdic_wa_enable = TRUE;
+
+	ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
+	                              E1000_KMRNCTRLSTA_OFFSET >>
+	                              E1000_KMRNCTRLSTA_OFFSET_SHIFT,
+	                              &i);
+	if (!ret_val) {
+		if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
+		     E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
+			hw->dev_spec._80003es2lan.mdic_wa_enable = FALSE;
+	}
+
 	/*
 	 * Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
@@ -1303,7 +1316,6 @@ static s32 e1000_cfg_kmrn_10_100_80003es
 	tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN;
 	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
 
-
 	do {
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 		                               &reg_data);
@@ -1357,7 +1369,6 @@ static s32 e1000_cfg_kmrn_1000_80003es2l
 	tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;
 	E1000_WRITE_REG(hw, E1000_TIPG, tipg);
 
-
 	do {
 		ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
 		                               &reg_data);

Modified: head/sys/dev/e1000/e1000_80003es2lan.h
==============================================================================
--- head/sys/dev/e1000/e1000_80003es2lan.h	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/e1000_80003es2lan.h	Tue Dec  8 01:07:44 2009	(r200243)
@@ -1,6 +1,6 @@
-/*******************************************************************************
+/******************************************************************************
 
-  Copyright (c) 2001-2008, Intel Corporation 
+  Copyright (c) 2001-2009, Intel Corporation 
   All rights reserved.
   
   Redistribution and use in source and binary forms, with or without 
@@ -29,9 +29,8 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE.
 
-*******************************************************************************/
-/* $FreeBSD$ */
-
+******************************************************************************/
+/*$FreeBSD$*/
 
 #ifndef _E1000_80003ES2LAN_H_
 #define _E1000_80003ES2LAN_H_
@@ -49,6 +48,9 @@
 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT   0x0000
 #define E1000_KMRNCTRLSTA_OPMODE_E_IDLE          0x2000
 
+#define E1000_KMRNCTRLSTA_OPMODE_MASK            0x000C
+#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO     0x0004
+
 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
 #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN        0x00010000
 

Modified: head/sys/dev/e1000/e1000_82541.c
==============================================================================
--- head/sys/dev/e1000/e1000_82541.c	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/e1000_82541.c	Tue Dec  8 01:07:44 2009	(r200243)
@@ -59,6 +59,7 @@ static s32  e1000_set_d3_lplu_state_8254
 static s32  e1000_setup_led_82541(struct e1000_hw *hw);
 static s32  e1000_cleanup_led_82541(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw);
+static s32  e1000_read_mac_addr_82541(struct e1000_hw *hw);
 static s32  e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw,
                                                      bool link_up);
 static s32  e1000_phy_init_script_82541(struct e1000_hw *hw);
@@ -261,6 +262,8 @@ static s32 e1000_init_mac_params_82541(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_82541;
 	/* ID LED init */
 	mac->ops.id_led_init = e1000_id_led_init_generic;
 	/* setup LED */
@@ -1292,3 +1295,35 @@ static void e1000_clear_hw_cntrs_82541(s
 	E1000_READ_REG(hw, E1000_MGTPDC);
 	E1000_READ_REG(hw, E1000_MGTPTC);
 }
+
+/**
+ *  e1000_read_mac_addr_82541 - Read device MAC address
+ *  @hw: pointer to the HW structure
+ *
+ *  Reads the device MAC address from the EEPROM and stores the value.
+ **/
+static s32 e1000_read_mac_addr_82541(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);
+	}
+
+	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_82571.c
==============================================================================
--- head/sys/dev/e1000/e1000_82571.c	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/e1000_82571.c	Tue Dec  8 01:07:44 2009	(r200243)
@@ -46,7 +46,6 @@
  * 82573E Gigabit Ethernet Controller (Copper)
  * 82573L Gigabit Ethernet Controller
  * 82574L Gigabit Network Connection
- * 82574L Gigabit Network Connection
  * 82583V Gigabit Network Connection
  */
 
@@ -106,7 +105,6 @@ static s32 e1000_init_phy_params_82571(s
 	phy->reset_delay_us              = 100;
 
 	phy->ops.acquire                 = e1000_get_hw_semaphore_82571;
-	phy->ops.check_polarity          = e1000_check_polarity_igp;
 	phy->ops.check_reset_block       = e1000_check_reset_block_generic;
 	phy->ops.release                 = e1000_put_hw_semaphore_82571;
 	phy->ops.reset                   = e1000_phy_hw_reset_generic;
@@ -121,6 +119,7 @@ static s32 e1000_init_phy_params_82571(s
 		phy->type                   = e1000_phy_igp_2;
 		phy->ops.get_cfg_done       = e1000_get_cfg_done_82571;
 		phy->ops.get_info           = e1000_get_phy_info_igp;
+		phy->ops.check_polarity     = e1000_check_polarity_igp;
 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp;
 		phy->ops.get_cable_length   = e1000_get_cable_length_igp_2;
 		phy->ops.read_reg           = e1000_read_phy_reg_igp;
@@ -132,6 +131,7 @@ static s32 e1000_init_phy_params_82571(s
 		/* Verify PHY ID */
 		if (phy->id != IGP01E1000_I_PHY_ID) {
 			ret_val = -E1000_ERR_PHY;
+			DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id);
 			goto out;
 		}
 		break;
@@ -139,6 +139,7 @@ static s32 e1000_init_phy_params_82571(s
 		phy->type                   = e1000_phy_m88;
 		phy->ops.get_cfg_done       = e1000_get_cfg_done_generic;
 		phy->ops.get_info           = e1000_get_phy_info_m88;
+		phy->ops.check_polarity     = e1000_check_polarity_m88;
 		phy->ops.commit             = e1000_phy_sw_reset_generic;
 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
 		phy->ops.get_cable_length   = e1000_get_cable_length_m88;
@@ -155,11 +156,12 @@ static s32 e1000_init_phy_params_82571(s
 			goto out;
 		}
 		break;
-	case e1000_82583:
 	case e1000_82574:
+	case e1000_82583:
 		phy->type                   = e1000_phy_bm;
 		phy->ops.get_cfg_done       = e1000_get_cfg_done_generic;
 		phy->ops.get_info           = e1000_get_phy_info_m88;
+		phy->ops.check_polarity     = e1000_check_polarity_m88;
 		phy->ops.commit             = e1000_phy_sw_reset_generic;
 		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88;
 		phy->ops.get_cable_length   = e1000_get_cable_length_m88;
@@ -266,28 +268,42 @@ static s32 e1000_init_nvm_params_82571(s
 static s32 e1000_init_mac_params_82571(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
-	s32 ret_val = E1000_SUCCESS;
 	u32 swsm = 0;
 	u32 swsm2 = 0;
 	bool force_clear_smbi = FALSE;
 
 	DEBUGFUNC("e1000_init_mac_params_82571");
 
-	/* Set media type */
+	/* Set media type and media-dependent function pointers */
 	switch (hw->device_id) {
 	case E1000_DEV_ID_82571EB_FIBER:
 	case E1000_DEV_ID_82572EI_FIBER:
 	case E1000_DEV_ID_82571EB_QUAD_FIBER:
 		hw->phy.media_type = e1000_media_type_fiber;
+		mac->ops.setup_physical_interface =
+			e1000_setup_fiber_serdes_link_82571;
+		mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
+		mac->ops.get_link_up_info =
+			e1000_get_speed_and_duplex_fiber_serdes_generic;
 		break;
 	case E1000_DEV_ID_82571EB_SERDES:
 	case E1000_DEV_ID_82571EB_SERDES_DUAL:
 	case E1000_DEV_ID_82571EB_SERDES_QUAD:
 	case E1000_DEV_ID_82572EI_SERDES:
 		hw->phy.media_type = e1000_media_type_internal_serdes;
+		mac->ops.setup_physical_interface =
+			e1000_setup_fiber_serdes_link_82571;
+		mac->ops.check_for_link = e1000_check_for_serdes_link_82571;
+		mac->ops.get_link_up_info =
+			e1000_get_speed_and_duplex_fiber_serdes_generic;
 		break;
 	default:
 		hw->phy.media_type = e1000_media_type_copper;
+		mac->ops.setup_physical_interface =
+			e1000_setup_copper_link_82571;
+		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
+		mac->ops.get_link_up_info =
+			e1000_get_speed_and_duplex_copper_generic;
 		break;
 	}
 
@@ -301,58 +317,19 @@ static s32 e1000_init_mac_params_82571(s
 	mac->arc_subsystem_valid =
 	        (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK)
 	                ? TRUE : FALSE;
+	/* Adaptive IFS supported */
+	mac->adaptive_ifs = TRUE;
 
 	/* Function pointers */
 
 	/* bus type/speed/width */
 	mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic;
-	/* function id */
-	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:
-		break;
-	}
 	/* reset */
 	mac->ops.reset_hw = e1000_reset_hw_82571;
 	/* hw initialization */
 	mac->ops.init_hw = e1000_init_hw_82571;
 	/* link setup */
 	mac->ops.setup_link = e1000_setup_link_82571;
-	/* physical interface link setup */
-	mac->ops.setup_physical_interface =
-	        (hw->phy.media_type == e1000_media_type_copper)
-	                ? e1000_setup_copper_link_82571
-	                : e1000_setup_fiber_serdes_link_82571;
-	/* check for link */
-	switch (hw->phy.media_type) {
-	case e1000_media_type_copper:
-		mac->ops.check_for_link = e1000_check_for_copper_link_generic;
-		break;
-	case e1000_media_type_fiber:
-		mac->ops.check_for_link = e1000_check_for_fiber_link_generic;
-		break;
-	case e1000_media_type_internal_serdes:
-		mac->ops.check_for_link = e1000_check_for_serdes_link_82571;
-		break;
-	default:
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
-		break;
-	}
-	/* 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:
-		mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
-		break;
-	}
 	/* multicast address update */
 	mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
 	/* writing VFTA */
@@ -371,24 +348,29 @@ static s32 e1000_init_mac_params_82571(s
 	mac->ops.setup_led = e1000_setup_led_generic;
 	/* cleanup LED */
 	mac->ops.cleanup_led = e1000_cleanup_led_generic;
-	/* turn on/off LED */
+	/* turn off LED */
+	mac->ops.led_off = e1000_led_off_generic;
+	/* clear hardware counters */
+	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82571;
+
+	/* MAC-specific function pointers */
 	switch (hw->mac.type) {
+	case e1000_82573:
+		mac->ops.set_lan_id = e1000_set_lan_id_single_port;
+		mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
+		mac->ops.led_on = e1000_led_on_generic;
+		break;
 	case e1000_82574:
 	case e1000_82583:
+		mac->ops.set_lan_id = e1000_set_lan_id_single_port;
+		mac->ops.check_mng_mode = e1000_check_mng_mode_82574;
 		mac->ops.led_on = e1000_led_on_82574;
 		break;
 	default:
+		mac->ops.check_mng_mode = e1000_check_mng_mode_generic;
 		mac->ops.led_on = e1000_led_on_generic;
 		break;
 	}
-	mac->ops.led_off = e1000_led_off_generic;
-	/* clear hardware counters */
-	mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82571;
-	/* link info */
-	mac->ops.get_link_up_info =
-	        (hw->phy.media_type == e1000_media_type_copper)
-	                ? 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
@@ -434,8 +416,7 @@ static s32 e1000_init_mac_params_82571(s
 	 */
 	 hw->dev_spec._82571.smb_counter = 0;
 
-out:
-	return ret_val;
+	return E1000_SUCCESS;
 }
 
 /**
@@ -501,7 +482,6 @@ static s32 e1000_get_phy_id_82571(struct
 		ret_val = -E1000_ERR_PHY;
 		break;
 	}
-
 out:
 	return ret_val;
 }
@@ -512,7 +492,7 @@ out:
  *
  *  Acquire the HW semaphore to access the PHY or NVM
  **/
-s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
+static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
 {
 	u32 swsm;
 	s32 ret_val = E1000_SUCCESS;
@@ -577,7 +557,7 @@ out:
  *
  *  Release hardware semaphore used to access the PHY or NVM
  **/
-void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
+static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
 {
 	u32 swsm;
 
@@ -610,9 +590,9 @@ static s32 e1000_acquire_nvm_82571(struc
 		goto out;
 
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		break;
 	default:
 		ret_val = e1000_acquire_nvm_generic(hw);
@@ -831,7 +811,8 @@ static s32 e1000_get_cfg_done_82571(stru
 	DEBUGFUNC("e1000_get_cfg_done_82571");
 
 	while (timeout) {
-		if (E1000_READ_REG(hw, E1000_EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0)
+		if (E1000_READ_REG(hw, E1000_EEMNGCTL) &
+		    E1000_NVM_CFG_DONE_PORT_0)
 			break;
 		msec_delay(1);
 		timeout--;
@@ -966,9 +947,9 @@ static s32 e1000_reset_hw_82571(struct e
 	 * Ownership defaults to firmware after a reset.
 	 */
 	switch (hw->mac.type) {
+	case e1000_82573:
 	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;
 
@@ -1014,9 +995,9 @@ static s32 e1000_reset_hw_82571(struct e
 	 */
 
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		msec_delay(25);
 		break;
 	default:
@@ -1061,10 +1042,9 @@ static s32 e1000_init_hw_82571(struct e1
 
 	/* Initialize identification LED */
 	ret_val = mac->ops.id_led_init(hw);
-	if (ret_val) {
+	if (ret_val)
 		DEBUGOUT("Error initializing identification LED\n");
 		/* This is not fatal and we should not stop init due to this */
-	}
 
 	/* Disabling VLAN filtering */
 	DEBUGOUT("Initializing the IEEE VLAN\n");
@@ -1097,9 +1077,9 @@ static s32 e1000_init_hw_82571(struct e1
 
 	/* ...for both queues. */
 	switch (mac->type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		e1000_enable_tx_pkt_filtering_generic(hw);
 		reg_data = E1000_READ_REG(hw, E1000_GCR);
 		reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
@@ -1108,8 +1088,8 @@ static s32 e1000_init_hw_82571(struct e1
 	default:
 		reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1));
 		reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) |
-					E1000_TXDCTL_FULL_TX_DESC_WB |
-					E1000_TXDCTL_COUNT_DESC;
+		           E1000_TXDCTL_FULL_TX_DESC_WB |
+		           E1000_TXDCTL_COUNT_DESC;
 		E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
 		break;
 	}
@@ -1178,11 +1158,10 @@ static void e1000_initialize_hw_bits_825
 	}
 
 	/* Device Control */
-
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		reg = E1000_READ_REG(hw, E1000_CTRL);
 		reg &= ~(1 << 29);
 		E1000_WRITE_REG(hw, E1000_CTRL, reg);
@@ -1193,9 +1172,9 @@ static void e1000_initialize_hw_bits_825
 
 	/* Extended Device Control */
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
 		reg &= ~(1 << 23);
 		reg |= (1 << 22);
@@ -1205,7 +1184,6 @@ static void e1000_initialize_hw_bits_825
 		break;
 	}
 
-
 	if (hw->mac.type == e1000_82571) {
 		reg = E1000_READ_REG(hw, E1000_PBA_ECC);
 		reg |= E1000_PBA_ECC_CORR_EN;
@@ -1216,7 +1194,6 @@ static void e1000_initialize_hw_bits_825
 	 * Workaround for hardware errata.
 	 * Ensure that DMA Dynamic Clock gating is disabled on 82571 and 82572
 	 */
-
 	if ((hw->mac.type == e1000_82571) ||
 	   (hw->mac.type == e1000_82572)) {
 		reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
@@ -1225,13 +1202,13 @@ static void e1000_initialize_hw_bits_825
 	}
 
 	/* PCI-Ex Control Registers */
-
 	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);
+
 		/*
 		 * Workaround for hardware errata.
 		 * apply workaround for hardware errata documented in errata
@@ -1267,39 +1244,36 @@ static void e1000_clear_vfta_82571(struc
 	DEBUGFUNC("e1000_clear_vfta_82571");
 
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		if (hw->mng_cookie.vlan_id != 0) {
 			/*
-			*The VFTA is a 4096b bit-field, each identifying
-			*a single VLAN ID.  The following operations
-			*determine which 32b entry (i.e. offset) into the
-			*array we want to set the VLAN ID (i.e. bit) of
-			*the manageability unit.
-			*/
+			 * The VFTA is a 4096b bit-field, each identifying
+			 * a single VLAN ID.  The following operations
+			 * determine which 32b entry (i.e. offset) into the
+			 * array we want to set the VLAN ID (i.e. bit) of
+			 * the manageability unit.
+			 */
 			vfta_offset = (hw->mng_cookie.vlan_id >>
 				E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
 			vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
 				E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
 		}
-
-		for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
-			/*
-			*If the offset we want to clear is the same offset of
-			*the manageability VLAN ID, then clear all bits except
-			*that of the manageability unit
-			*/
-			vfta_value = (offset == vfta_offset) ?
-							vfta_bit_in_reg : 0;
-			E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset,
-				vfta_value);
-			E1000_WRITE_FLUSH(hw);
-		}
 		break;
 	default:
 		break;
 	}
+	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
+		/*
+		 * If the offset we want to clear is the same offset of the
+		 * manageability VLAN ID, then clear all bits except that of
+		 * the manageability unit.
+		 */
+		vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0;
+		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, vfta_value);
+		E1000_WRITE_FLUSH(hw);
+	}
 }
 
 /**
@@ -1369,9 +1343,9 @@ static s32 e1000_setup_link_82571(struct
 	 * set it to full.
 	 */
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
 		if (hw->fc.requested_mode == e1000_fc_default)
 			hw->fc.requested_mode = e1000_fc_full;
 		break;
@@ -1460,7 +1434,7 @@ static s32 e1000_setup_fiber_serdes_link
  *  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.
+ *  determined by the result of autonegotiation. 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.
  *
@@ -1472,7 +1446,7 @@ static s32 e1000_setup_fiber_serdes_link
  *  4) forced_up (the link has been forced up, it did not autonegotiate)
  *
  **/
-s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
 {
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 rxcw;
@@ -1524,9 +1498,10 @@ s32 e1000_check_for_serdes_link_82571(st
 
 		case e1000_serdes_link_autoneg_progress:
 			if (rxcw & E1000_RXCW_C) {
-				/* We received /C/ ordered sets, meaning the
+				/*
+				 * We received /C/ ordered sets, meaning the
 				 * link partner has autonegotiated, and we can
-				 * trust the Link Up (LU) status bit
+				 * trust the Link Up (LU) status bit.
 				 */
 				if (status & E1000_STATUS_LU) {
 					mac->serdes_link_state =
@@ -1534,13 +1509,14 @@ s32 e1000_check_for_serdes_link_82571(st
 					DEBUGOUT("AN_PROG   -> AN_UP\n");
 					mac->serdes_has_link = TRUE;
 				} else {
-					/* Autoneg completed, but failed */
+					/* Autoneg completed, but failed. */
 					mac->serdes_link_state =
 					    e1000_serdes_link_down;
 					DEBUGOUT("AN_PROG   -> DOWN\n");
 				}
 			} else {
-				/* The link partner did not autoneg.
+				/*
+				 * The link partner did not autoneg.
 				 * Force link up and full duplex, and change
 				 * state to forced.
 				 */
@@ -1565,9 +1541,11 @@ s32 e1000_check_for_serdes_link_82571(st
 
 		case e1000_serdes_link_down:
 		default:
-			/* The link was down but the receiver has now gained
+			/*
+			 * The link was down but the receiver has now gained
 			 * valid sync, so lets see if we can bring the link
-			 * up. */
+			 * up.
+			 */
 			E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
 			E1000_WRITE_REG(hw, E1000_CTRL,
 			    (ctrl & ~E1000_CTRL_SLU));
@@ -1583,9 +1561,9 @@ s32 e1000_check_for_serdes_link_82571(st
 			DEBUGOUT("ANYSTATE  -> DOWN\n");
 		} else {
 			/*
-			 * We have sync, and can tolerate one
-			 * invalid (IV) codeword before declaring
-			 * link down, so reread to look again
+			 * We have sync, and can tolerate one invalid (IV)
+			 * codeword before declaring link down, so reread
+			 * to look again.
 			 */
 			usec_delay(10);
 			rxcw = E1000_READ_REG(hw, E1000_RXCW);
@@ -1621,15 +1599,15 @@ static s32 e1000_valid_led_default_82571
 	}
 
 	switch (hw->mac.type) {
+	case e1000_82573:
 	case e1000_82574:
 	case e1000_82583:
-	case e1000_82573:
-		if(*data == ID_LED_RESERVED_F746)
+		if (*data == ID_LED_RESERVED_F746)
 			*data = ID_LED_DEFAULT_82573;
 		break;
 	default:
 		if (*data == ID_LED_RESERVED_0000 ||
-			*data == ID_LED_RESERVED_FFFF)
+		    *data == ID_LED_RESERVED_FFFF)
 			*data = ID_LED_DEFAULT;
 		break;
 	}

Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c	Tue Dec  8 00:54:08 2009	(r200242)
+++ head/sys/dev/e1000/e1000_82575.c	Tue Dec  8 01:07:44 2009	(r200243)
@@ -59,16 +59,20 @@ static s32  e1000_phy_hw_reset_sgmii_825
 static s32  e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
                                            u16 *data);
 static s32  e1000_reset_hw_82575(struct e1000_hw *hw);
+static s32  e1000_reset_hw_82580(struct e1000_hw *hw);
+static s32 e1000_read_phy_reg_82580(struct e1000_hw *hw,
+                                    u32 offset, u16 *data);
+static s32 e1000_write_phy_reg_82580(struct e1000_hw *hw,
+                                     u32 offset, u16 data);
 static s32  e1000_set_d0_lplu_state_82575(struct e1000_hw *hw,
                                           bool active);
 static s32  e1000_setup_copper_link_82575(struct e1000_hw *hw);
-static s32  e1000_setup_fiber_serdes_link_82575(struct e1000_hw *hw);
+static s32  e1000_setup_serdes_link_82575(struct e1000_hw *hw);
 static s32  e1000_valid_led_default_82575(struct e1000_hw *hw, u16 *data);
 static s32  e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw,
                                             u32 offset, u16 data);
 static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw);
 static s32  e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask);
-static s32  e1000_configure_pcs_link_82575(struct e1000_hw *hw);
 static s32  e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw,
                                                  u16 *speed, u16 *duplex);
 static s32  e1000_get_phy_id_82575(struct e1000_hw *hw);
@@ -77,9 +81,15 @@ static bool e1000_sgmii_active_82575(str
 static s32  e1000_reset_init_script_82575(struct e1000_hw *hw);
 static s32  e1000_read_mac_addr_82575(struct e1000_hw *hw);
 static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw);
-void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
+static void e1000_shutdown_serdes_link_82575(struct e1000_hw *hw);
 static s32 e1000_set_pcie_completion_timeout(struct e1000_hw *hw);
 
+static const u16 e1000_82580_rxpbs_table[] =
+	{ 36, 72, 144, 1, 2, 4, 8, 16,
+	  35, 70, 140 };
+#define E1000_82580_RXPBS_TABLE_SIZE \
+	(sizeof(e1000_82580_rxpbs_table)/sizeof(u16))
+
 /**
  *  e1000_init_phy_params_82575 - Init PHY func ptrs.
  *  @hw: pointer to the HW structure
@@ -94,11 +104,11 @@ static s32 e1000_init_phy_params_82575(s
 	if (hw->phy.media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
 		goto out;
-	} else {
-		phy->ops.power_up   = e1000_power_up_phy_copper;
-		phy->ops.power_down = e1000_power_down_phy_copper_82575;
 	}
 
+	phy->ops.power_up   = e1000_power_up_phy_copper;
+	phy->ops.power_down = e1000_power_down_phy_copper_82575;
+
 	phy->autoneg_mask           = AUTONEG_ADVERTISE_SPEED_DEFAULT;
 	phy->reset_delay_us         = 100;
 
@@ -112,6 +122,11 @@ static s32 e1000_init_phy_params_82575(s
 		phy->ops.reset      = e1000_phy_hw_reset_sgmii_82575;
 		phy->ops.read_reg   = e1000_read_phy_reg_sgmii_82575;
 		phy->ops.write_reg  = e1000_write_phy_reg_sgmii_82575;
+	} else if ((hw->mac.type == e1000_82580) ||
+	           (hw->mac.type == e1000_82580er)) {
+		phy->ops.reset      = e1000_phy_hw_reset_generic;
+		phy->ops.read_reg   = e1000_read_phy_reg_82580;
+		phy->ops.write_reg  = e1000_write_phy_reg_82580;
 	} else {
 		phy->ops.reset      = e1000_phy_hw_reset_generic;
 		phy->ops.read_reg   = e1000_read_phy_reg_igp;
@@ -140,6 +155,13 @@ static s32 e1000_init_phy_params_82575(s
 		phy->ops.set_d0_lplu_state  = e1000_set_d0_lplu_state_82575;
 		phy->ops.set_d3_lplu_state  = e1000_set_d3_lplu_state_generic;
 		break;
+	case I82580_I_PHY_ID:
+		phy->type                   = e1000_phy_82580;
+		phy->ops.check_polarity     = e1000_check_polarity_82577;
+		phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82577;
+		phy->ops.get_cable_length   = e1000_get_cable_length_82577;
+		phy->ops.get_info           = e1000_get_phy_info_82577;
+		break;
 	default:
 		ret_val = -E1000_ERR_PHY;
 		goto out;
@@ -192,7 +214,7 @@ static s32 e1000_init_nvm_params_82575(s
 	/* EEPROM access above 16k is unsupported */
 	if (size > 14)
 		size = 14;
-	nvm->word_size	= 1 << size;
+	nvm->word_size = 1 << size;
 
 	/* Function Pointers */
 	nvm->ops.acquire       = e1000_acquire_nvm_82575;
@@ -230,24 +252,41 @@ static s32 e1000_init_mac_params_82575(s
 	dev_spec->sgmii_active = FALSE;
 
 	ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);

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


More information about the svn-src-all mailing list