summaryrefslogtreecommitdiffstats
path: root/sys/dev/e1000/e1000_82575.c
diff options
context:
space:
mode:
authorjfv <jfv@FreeBSD.org>2008-11-26 23:57:23 +0000
committerjfv <jfv@FreeBSD.org>2008-11-26 23:57:23 +0000
commitacf860ad541ce9529aff0bf17061183badd98903 (patch)
treeb0f0b3a2e29a0fc9f60b8bee9111f6827eb01416 /sys/dev/e1000/e1000_82575.c
parent62188214bdac09b8b3fe223bd994d8aef28db6db (diff)
downloadFreeBSD-src-acf860ad541ce9529aff0bf17061183badd98903.zip
FreeBSD-src-acf860ad541ce9529aff0bf17061183badd98903.tar.gz
This delta is primarily a fix for es2lan devices that
will sometimes fail to initialize problem due to a lock contention with management hardware. However, in order to deliver that fix it was necessary to take a shared code update as a whole, and this required scattered changes in the core code to be compatible. The em driver now has VLAN HW support added as the igb driver had previously. MFC after: ASAP - in time for 7.1 RELEASE
Diffstat (limited to 'sys/dev/e1000/e1000_82575.c')
-rw-r--r--sys/dev/e1000/e1000_82575.c262
1 files changed, 74 insertions, 188 deletions
diff --git a/sys/dev/e1000/e1000_82575.c b/sys/dev/e1000/e1000_82575.c
index 2fbc0c3..3d16447 100644
--- a/sys/dev/e1000/e1000_82575.c
+++ b/sys/dev/e1000/e1000_82575.c
@@ -32,8 +32,11 @@
******************************************************************************/
/*$FreeBSD$*/
-/* e1000_82575
- * e1000_82576
+/*
+ * 82575EB Gigabit Network Connection
+ * 82575EB Gigabit Backplane Connection
+ * 82575GB Gigabit Network Connection
+ * 82576 Gigabit Network Connection
*/
#include "e1000_api.h"
@@ -77,18 +80,11 @@ static void e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count);
static void e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
u8 *mc_addr_list, u32 mc_addr_count,
u32 rar_used_count, u32 rar_count);
-void e1000_remove_device_82575(struct e1000_hw *hw);
void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
-struct e1000_dev_spec_82575 {
- bool sgmii_active;
-};
-
/**
* e1000_init_phy_params_82575 - 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_82575(struct e1000_hw *hw)
{
@@ -158,8 +154,6 @@ out:
/**
* e1000_init_nvm_params_82575 - 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_82575(struct e1000_hw *hw)
{
@@ -217,27 +211,15 @@ static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw)
/**
* e1000_init_mac_params_82575 - 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_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
- struct e1000_dev_spec_82575 *dev_spec;
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
u32 ctrl_ext = 0;
- s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_init_mac_params_82575");
- hw->dev_spec_size = sizeof(struct e1000_dev_spec_82575);
-
- /* Device-specific structure allocation */
- ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size);
- if (ret_val)
- goto out;
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
-
/* Set media type */
/*
* The 82575 uses bits 22:23 for link mode. The mode can be changed
@@ -315,23 +297,19 @@ static s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
/* 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_82575;
/* clear hardware counters */
mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82575;
/* link info */
mac->ops.get_link_up_info = e1000_get_link_up_info_82575;
-out:
- return ret_val;
+ return E1000_SUCCESS;
}
/**
* e1000_init_function_pointers_82575 - 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_82575(struct e1000_hw *hw)
{
@@ -346,8 +324,7 @@ void e1000_init_function_pointers_82575(struct e1000_hw *hw)
* e1000_acquire_phy_82575 - Acquire rights to access PHY
* @hw: pointer to the HW structure
*
- * Acquire access rights to the correct PHY. This is a
- * function pointer entry point called by the api module.
+ * Acquire access rights to the correct PHY.
**/
static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
{
@@ -364,8 +341,7 @@ static s32 e1000_acquire_phy_82575(struct e1000_hw *hw)
* e1000_release_phy_82575 - 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_82575(struct e1000_hw *hw)
{
@@ -1032,7 +1008,7 @@ static void e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
/* Load any remaining multicast addresses into the hash table. */
for (; mc_addr_count > 0; mc_addr_count--) {
- hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list);
+ hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
DEBUGOUT1("Hash value = 0x%03X\n", hash_value);
hw->mac.ops.mta_set(hw, hash_value);
mc_addr_list += ETH_ADDR_LEN;
@@ -1049,14 +1025,22 @@ static void e1000_update_mc_addr_list_82575(struct e1000_hw *hw,
void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
{
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))
return;
- /* if the management interface is not enabled, then power down */
- if (!e1000_enable_mng_pass_thru(hw)) {
+ if (hw->bus.func == 0)
+ hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
+
+ /*
+ * If APM is not enabled in the EEPROM and management interface is
+ * not enabled, then power down.
+ */
+ if (!(eeprom_data & E1000_NVM_APME_82575) &&
+ !e1000_enable_mng_pass_thru(hw)) {
/* Disable PCS to turn off link */
reg = E1000_READ_REG(hw, E1000_PCS_CFG0);
reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -1079,8 +1063,7 @@ void e1000_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw)
* e1000_reset_hw_82575 - 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_82575(struct e1000_hw *hw)
{
@@ -1462,86 +1445,14 @@ out:
**/
static bool e1000_sgmii_active_82575(struct e1000_hw *hw)
{
- struct e1000_dev_spec_82575 *dev_spec;
- bool ret_val;
+ 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) {
- ret_val = FALSE;
- goto out;
- }
-
- dev_spec = (struct e1000_dev_spec_82575 *)hw->dev_spec;
+ if (hw->mac.type != e1000_82575 && hw->mac.type != e1000_82576)
+ return FALSE;
- ret_val = dev_spec->sgmii_active;
-
-out:
- return ret_val;
-}
-
-/**
- * e1000_translate_register_82576 - Translate the proper register offset
- * @reg: e1000 register to be read
- *
- * Registers in 82576 are located in different offsets than other adapters
- * even though they function in the same manner. This function takes in
- * the name of the register to read and returns the correct offset for
- * 82576 silicon.
- **/
-u32 e1000_translate_register_82576(u32 reg)
-{
- /*
- * Some of the 82576 registers are located at different
- * offsets than they are in older adapters.
- * Despite the difference in location, the registers
- * function in the same manner.
- */
- switch (reg) {
- case E1000_TDBAL(0):
- reg = 0x0E000;
- break;
- case E1000_TDBAH(0):
- reg = 0x0E004;
- break;
- case E1000_TDLEN(0):
- reg = 0x0E008;
- break;
- case E1000_TDH(0):
- reg = 0x0E010;
- break;
- case E1000_TDT(0):
- reg = 0x0E018;
- break;
- case E1000_TXDCTL(0):
- reg = 0x0E028;
- break;
- case E1000_RDBAL(0):
- reg = 0x0C000;
- break;
- case E1000_RDBAH(0):
- reg = 0x0C004;
- break;
- case E1000_RDLEN(0):
- reg = 0x0C008;
- break;
- case E1000_RDH(0):
- reg = 0x0C010;
- break;
- case E1000_RDT(0):
- reg = 0x0C018;
- break;
- case E1000_RXDCTL(0):
- reg = 0x0C028;
- break;
- case E1000_SRRCTL(0):
- reg = 0x0C00C;
- break;
- default:
- break;
- }
-
- return reg;
+ return dev_spec->sgmii_active;
}
/**
@@ -1620,30 +1531,6 @@ static void e1000_power_down_phy_copper_82575(struct e1000_hw *hw)
}
/**
- * e1000_remove_device_82575 - Free device specific structure
- * @hw: pointer to the HW structure
- *
- * If a device specific structure was allocated, this function will
- * free it after shutting down the serdes interface if available.
- **/
-void e1000_remove_device_82575(struct e1000_hw *hw)
-{
- u16 eeprom_data = 0;
-
- /*
- * If APM is enabled in the EEPROM then leave the port on for fiber
- * serdes adapters.
- */
- if (hw->bus.func == 0)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
-
- if (!(eeprom_data & E1000_NVM_APME_82575))
- e1000_shutdown_fiber_serdes_link_82575(hw);
-
- e1000_remove_device_generic(hw);
-}
-
-/**
* e1000_clear_hw_cntrs_82575 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
@@ -1651,62 +1538,60 @@ void e1000_remove_device_82575(struct e1000_hw *hw)
**/
static void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw)
{
- volatile u32 temp;
-
DEBUGFUNC("e1000_clear_hw_cntrs_82575");
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);
-
- temp = E1000_READ_REG(hw, E1000_CBTMPC);
- temp = E1000_READ_REG(hw, E1000_HTDPMC);
- temp = E1000_READ_REG(hw, E1000_CBRMPC);
- temp = E1000_READ_REG(hw, E1000_RPTHC);
- temp = E1000_READ_REG(hw, E1000_HGPTC);
- temp = E1000_READ_REG(hw, E1000_HTCBDPC);
- temp = E1000_READ_REG(hw, E1000_HGORCL);
- temp = E1000_READ_REG(hw, E1000_HGORCH);
- temp = E1000_READ_REG(hw, E1000_HGOTCL);
- temp = E1000_READ_REG(hw, E1000_HGOTCH);
- temp = E1000_READ_REG(hw, E1000_LENERRS);
+ 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);
+
+ E1000_READ_REG(hw, E1000_CBTMPC);
+ E1000_READ_REG(hw, E1000_HTDPMC);
+ E1000_READ_REG(hw, E1000_CBRMPC);
+ E1000_READ_REG(hw, E1000_RPTHC);
+ E1000_READ_REG(hw, E1000_HGPTC);
+ E1000_READ_REG(hw, E1000_HTCBDPC);
+ E1000_READ_REG(hw, E1000_HGORCL);
+ E1000_READ_REG(hw, E1000_HGORCH);
+ E1000_READ_REG(hw, E1000_HGOTCL);
+ E1000_READ_REG(hw, E1000_HGOTCH);
+ E1000_READ_REG(hw, E1000_LENERRS);
/* This register should not be read in copper configurations */
if (hw->phy.media_type == e1000_media_type_internal_serdes)
- temp = E1000_READ_REG(hw, E1000_SCVPC);
+ E1000_READ_REG(hw, E1000_SCVPC);
}
/**
* e1000_rx_fifo_flush_82575 - Clean rx fifo after RX enable
@@ -1781,3 +1666,4 @@ void e1000_rx_fifo_flush_82575(struct e1000_hw *hw)
E1000_READ_REG(hw, E1000_RNBC);
E1000_READ_REG(hw, E1000_MPC);
}
+
OpenPOWER on IntegriCloud