svn commit: r190872 - head/sys/dev/e1000
Jack F Vogel
jfv at FreeBSD.org
Fri Apr 10 00:05:47 UTC 2009
Author: jfv
Date: Fri Apr 10 00:05:46 2009
New Revision: 190872
URL: http://svn.freebsd.org/changeset/base/190872
Log:
This delta syncs the em and igb drivers with Intel,
adds header split and SCTP support into the igb driver.
Various small improvements and fixes.
MFC after: 2 weeks
Modified:
head/sys/dev/e1000/e1000_80003es2lan.c
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_api.h
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_mac.h
head/sys/dev/e1000/e1000_nvm.c
head/sys/dev/e1000/e1000_nvm.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_igb.c
head/sys/dev/e1000/if_igb.h
Modified: head/sys/dev/e1000/e1000_80003es2lan.c
==============================================================================
--- head/sys/dev/e1000/e1000_80003es2lan.c Thu Apr 9 20:57:35 2009 (r190871)
+++ head/sys/dev/e1000/e1000_80003es2lan.c Fri Apr 10 00:05:46 2009 (r190872)
@@ -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
@@ -43,9 +43,7 @@ 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,
@@ -276,6 +274,8 @@ static s32 e1000_init_mac_params_80003es
mac->ops.mta_set = e1000_mta_set_generic;
/* read mac address */
mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan;
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */
mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
@@ -802,17 +802,16 @@ static s32 e1000_get_cable_length_80003e
index = phy_data & GG82563_DSPD_CABLE_LENGTH;
- 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 {
+ 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->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2;
+
out:
return ret_val;
}
@@ -892,7 +891,7 @@ static s32 e1000_reset_hw_80003es2lan(st
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
- e1000_check_alt_mac_addr_generic(hw);
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
out:
return ret_val;
@@ -916,7 +915,7 @@ static s32 e1000_init_hw_80003es2lan(str
e1000_initialize_hw_bits_80003es2lan(hw);
/* Initialize identification LED */
- ret_val = e1000_id_led_init_generic(hw);
+ ret_val = mac->ops.id_led_init(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
@@ -1104,9 +1103,9 @@ static s32 e1000_copper_link_setup_gg825
/* Bypass Rx and Tx FIFO's */
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);
+ E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
+ E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
+ E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
if (ret_val)
goto out;
@@ -1147,22 +1146,19 @@ static s32 e1000_copper_link_setup_gg825
if (!(hw->mac.ops.check_mng_mode(hw))) {
/* 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,
+ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
data);
if (ret_val)
goto out;
- 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,
+ &data);
+ if (ret_val)
+ goto out;
data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
- ret_val = hw->phy.ops.write_reg(hw,
- GG82563_PHY_KMRN_MODE_CTRL,
+ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
data);
-
if (ret_val)
goto out;
}
@@ -1261,7 +1257,6 @@ static s32 e1000_cfg_on_link_up_80003es2
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);
@@ -1393,7 +1388,8 @@ out:
* 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)
+static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+ u16 *data)
{
u32 kmrnctrlsta;
s32 ret_val = E1000_SUCCESS;
@@ -1429,7 +1425,8 @@ out:
* 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)
+static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+ u16 data)
{
u32 kmrnctrlsta;
s32 ret_val = E1000_SUCCESS;
@@ -1461,9 +1458,19 @@ static s32 e1000_read_mac_addr_80003es2l
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_mac_addr_80003es2lan");
- if (e1000_check_alt_mac_addr_generic(hw))
- ret_val = e1000_read_mac_addr_generic(hw);
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = e1000_read_mac_addr_generic(hw);
+
+out:
return ret_val;
}
Modified: head/sys/dev/e1000/e1000_82540.c
==============================================================================
--- head/sys/dev/e1000/e1000_82540.c Thu Apr 9 20:57:35 2009 (r190871)
+++ head/sys/dev/e1000/e1000_82540.c Fri Apr 10 00:05:46 2009 (r190872)
@@ -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
@@ -229,6 +229,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;
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_generic;
/* setup LED */
mac->ops.setup_led = e1000_setup_led_generic;
/* cleanup LED */
@@ -332,7 +334,7 @@ static s32 e1000_init_hw_82540(struct e1
DEBUGFUNC("e1000_init_hw_82540");
/* Initialize identification LED */
- ret_val = e1000_id_led_init_generic(hw);
+ ret_val = mac->ops.id_led_init(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
Modified: head/sys/dev/e1000/e1000_82541.c
==============================================================================
--- head/sys/dev/e1000/e1000_82541.c Thu Apr 9 20:57:35 2009 (r190871)
+++ head/sys/dev/e1000/e1000_82541.c Fri Apr 10 00:05:46 2009 (r190872)
@@ -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
@@ -261,6 +261,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;
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_generic;
/* setup LED */
mac->ops.setup_led = e1000_setup_led_82541;
/* cleanup LED */
@@ -381,7 +383,7 @@ static s32 e1000_init_hw_82541(struct e1
DEBUGFUNC("e1000_init_hw_82541");
/* Initialize identification LED */
- ret_val = e1000_id_led_init_generic(hw);
+ ret_val = mac->ops.id_led_init(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
Modified: head/sys/dev/e1000/e1000_82571.c
==============================================================================
--- head/sys/dev/e1000/e1000_82571.c Thu Apr 9 20:57:35 2009 (r190871)
+++ head/sys/dev/e1000/e1000_82571.c Fri Apr 10 00:05:46 2009 (r190872)
@@ -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
@@ -46,6 +46,7 @@
* 82573E Gigabit Ethernet Controller (Copper)
* 82573L Gigabit Ethernet Controller
* 82574L Gigabit Network Connection
+ * 82574L Gigabit Network Connection
*/
#include "e1000_api.h"
@@ -67,11 +68,9 @@ static s32 e1000_init_hw_82571(struct e
static void e1000_clear_vfta_82571(struct e1000_hw *hw);
static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
static s32 e1000_led_on_82574(struct e1000_hw *hw);
-static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count,
- u32 rar_used_count, u32 rar_count);
static s32 e1000_setup_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
+static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data);
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
@@ -330,7 +329,7 @@ static s32 e1000_init_mac_params_82571(s
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;
+ mac->ops.check_for_link = e1000_check_for_serdes_link_82571;
break;
default:
ret_val = -E1000_ERR_CONFIG;
@@ -347,7 +346,7 @@ static s32 e1000_init_mac_params_82571(s
break;
}
/* multicast address update */
- mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82571;
+ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
/* writing VFTA */
mac->ops.write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
@@ -356,6 +355,8 @@ static s32 e1000_init_mac_params_82571(s
mac->ops.mta_set = e1000_mta_set_generic;
/* read mac address */
mac->ops.read_mac_addr = e1000_read_mac_addr_82571;
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */
mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
@@ -528,8 +529,14 @@ static s32 e1000_acquire_nvm_82571(struc
if (ret_val)
goto out;
- if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574)
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
+ break;
+ default:
ret_val = e1000_acquire_nvm_generic(hw);
+ break;
+ }
if (ret_val)
e1000_put_hw_semaphore_82571(hw);
@@ -876,7 +883,9 @@ static s32 e1000_reset_hw_82571(struct e
* Must acquire the MDIO ownership before MAC reset.
* Ownership defaults to firmware after a reset.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL);
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -892,6 +901,9 @@ static s32 e1000_reset_hw_82571(struct e
msec_delay(2);
i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT);
+ break;
+ default:
+ break;
}
ctrl = E1000_READ_REG(hw, E1000_CTRL);
@@ -917,15 +929,30 @@ static s32 e1000_reset_hw_82571(struct e
* Need to wait for Phy configuration completion before accessing
* NVM and Phy.
*/
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574)
+
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
msec_delay(25);
+ break;
+ default:
+ break;
+ }
/* Clear any pending interrupt events. */
E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff);
icr = E1000_READ_REG(hw, E1000_ICR);
- if (!(e1000_check_alt_mac_addr_generic(hw)))
- e1000_set_laa_state_82571(hw, TRUE);
+ /* Install any alternate MAC address into RAR0 */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
+
+ e1000_set_laa_state_82571(hw, TRUE);
+
+ /* Reinitialize the 82571 serdes link state machine */
+ if (hw->phy.media_type == e1000_media_type_internal_serdes)
+ hw->mac.serdes_link_state = e1000_serdes_link_down;
out:
return ret_val;
@@ -949,7 +976,7 @@ static s32 e1000_init_hw_82571(struct e1
e1000_initialize_hw_bits_82571(hw);
/* Initialize identification LED */
- ret_val = e1000_id_led_init_generic(hw);
+ ret_val = mac->ops.id_led_init(hw);
if (ret_val) {
DEBUGOUT("Error initializing identification LED\n");
/* This is not fatal and we should not stop init due to this */
@@ -985,17 +1012,21 @@ static s32 e1000_init_hw_82571(struct e1
E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data);
/* ...for both queues. */
- if (mac->type != e1000_82573 && mac->type != e1000_82574) {
- 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_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
- } else {
+ switch (mac->type) {
+ case e1000_82574:
+ 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;
E1000_WRITE_REG(hw, E1000_GCR, reg_data);
+ break;
+ 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_WRITE_REG(hw, E1000_TXDCTL(1), reg_data);
+ break;
}
/*
@@ -1062,25 +1093,70 @@ static void e1000_initialize_hw_bits_825
}
/* Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
reg = E1000_READ_REG(hw, E1000_CTRL);
reg &= ~(1 << 29);
E1000_WRITE_REG(hw, E1000_CTRL, reg);
+ break;
+ default:
+ break;
}
/* Extended Device Control */
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
reg = E1000_READ_REG(hw, E1000_CTRL_EXT);
reg &= ~(1 << 23);
reg |= (1 << 22);
E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
+ break;
+ default:
+ break;
}
- /* PCI-Ex Control Register */
- if (hw->mac.type == e1000_82574) {
+
+ if (hw->mac.type == e1000_82571) {
+ reg = E1000_READ_REG(hw, E1000_PBA_ECC);
+ reg |= E1000_PBA_ECC_CORR_EN;
+ E1000_WRITE_REG(hw, E1000_PBA_ECC, reg);
+ }
+
+ /*
+ * 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);
+ reg &= ~E1000_CTRL_EXT_DMA_DYN_CLK_EN;
+ E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg);
+ }
+
+ /* PCI-Ex Control Registers */
+
+ switch (hw->mac.type) {
+ case e1000_82574:
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
+ * docs Fixes issue where some error prone or unreliable PCIe
+ * completions are occurring, particularly with ASPM enabled.
+ * Without fix, issue can cause tx timeouts.
+ */
+ reg = E1000_READ_REG(hw, E1000_GCR2);
+ reg |= 1;
+ E1000_WRITE_REG(hw, E1000_GCR2, reg);
+ break;
+ default:
+ break;
}
return;
@@ -1102,31 +1178,38 @@ static void e1000_clear_vfta_82571(struc
DEBUGFUNC("e1000_clear_vfta_82571");
- if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) {
+ switch (hw->mac.type) {
+ case e1000_82574:
+ 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;
+ E1000_VFTA_ENTRY_SHIFT) & E1000_VFTA_ENTRY_MASK;
vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id &
- E1000_VFTA_ENTRY_BIT_SHIFT_MASK);
+ 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);
+
+ 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;
}
}
@@ -1176,31 +1259,6 @@ static s32 e1000_led_on_82574(struct e10
return E1000_SUCCESS;
}
-/**
- * e1000_update_mc_addr_list_82571 - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
- **/
-static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count,
- u32 rar_used_count, u32 rar_count)
-{
- DEBUGFUNC("e1000_update_mc_addr_list_82571");
-
- if (e1000_get_laa_state_82571(hw))
- rar_count--;
-
- e1000_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count,
- rar_used_count, rar_count);
-}
/**
* e1000_setup_link_82571 - Setup flow control and link settings
@@ -1221,10 +1279,15 @@ static s32 e1000_setup_link_82571(struct
* the default flow control setting, so we explicitly
* set it to full.
*/
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- hw->fc.requested_mode == e1000_fc_default)
- hw->fc.requested_mode = e1000_fc_full;
-
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
+ if (hw->fc.requested_mode == e1000_fc_default)
+ hw->fc.requested_mode = e1000_fc_full;
+ break;
+ default:
+ break;
+ }
return e1000_setup_link_generic(hw);
}
@@ -1306,6 +1369,133 @@ 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.
+ **/
+s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw)
+{
+ struct e1000_mac_info *mac = &hw->mac;
+ u32 rxcw;
+ u32 ctrl;
+ u32 status;
+ s32 ret_val = E1000_SUCCESS;
+
+ DEBUGFUNC("e1000_check_for_serdes_link_82571");
+
+ ctrl = E1000_READ_REG(hw, E1000_CTRL);
+ status = E1000_READ_REG(hw, E1000_STATUS);
+ rxcw = E1000_READ_REG(hw, E1000_RXCW);
+
+ if ((rxcw & E1000_RXCW_SYNCH) && !(rxcw & E1000_RXCW_IV)) {
+
+ /* Receiver is synchronized with no invalid bits. */
+ switch (mac->serdes_link_state) {
+ case e1000_serdes_link_autoneg_complete:
+ if (!(status & E1000_STATUS_LU)) {
+ /*
+ * We have lost link, retry autoneg before
+ * reporting link failure
+ */
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ DEBUGOUT("AN_UP -> AN_PROG\n");
+ }
+ break;
+
+ case e1000_serdes_link_forced_up:
+ /*
+ * If we are receiving /C/ ordered sets, re-enable
+ * auto-negotiation in the TXCW register and disable
+ * forced link in the Device Control register in an
+ * attempt to auto-negotiate with our link partner.
+ */
+ if (rxcw & E1000_RXCW_C) {
+ /* Enable autoneg, and unforce link up */
+ E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
+ E1000_WRITE_REG(hw, E1000_CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ 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");
+ } else {
+ /*
+ * Disable autoneg, force link up and
+ * full duplex, and change state to forced
+ */
+ E1000_WRITE_REG(hw, E1000_TXCW,
+ (mac->txcw & ~E1000_TXCW_ANE));
+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+ E1000_WRITE_REG(hw, E1000_CTRL, ctrl);
+
+ /* Configure Flow Control after link up. */
+ ret_val =
+ e1000_config_fc_after_link_up_generic(hw);
+ if (ret_val) {
+ DEBUGOUT("Error config flow control\n");
+ break;
+ }
+ mac->serdes_link_state =
+ e1000_serdes_link_forced_up;
+ DEBUGOUT("AN_PROG -> FORCED_UP\n");
+ }
+ mac->serdes_has_link = TRUE;
+ break;
+
+ case e1000_serdes_link_down:
+ default:
+ /* The link was down but the receiver has now gained
+ * valid sync, so lets see if we can bring the link
+ * up. */
+ E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw);
+ E1000_WRITE_REG(hw, E1000_CTRL,
+ (ctrl & ~E1000_CTRL_SLU));
+ mac->serdes_link_state =
+ e1000_serdes_link_autoneg_progress;
+ DEBUGOUT("DOWN -> AN_PROG\n");
+ break;
+ }
+ } else {
+ if (!(rxcw & E1000_RXCW_SYNCH)) {
+ mac->serdes_has_link = FALSE;
+ mac->serdes_link_state = e1000_serdes_link_down;
+ DEBUGOUT("ANYSTATE -> DOWN\n");
+ } else {
+ /*
+ * 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);
+ if (rxcw & E1000_RXCW_IV) {
+ mac->serdes_link_state = e1000_serdes_link_down;
+ mac->serdes_has_link = FALSE;
+ DEBUGOUT("ANYSTATE -> DOWN\n");
+ }
+ }
+ }
+
+ return ret_val;
+}
+
+/**
* e1000_valid_led_default_82571 - Verify a valid default LED config
* @hw: pointer to the HW structure
* @data: pointer to the NVM (EEPROM)
@@ -1325,11 +1515,19 @@ static s32 e1000_valid_led_default_82571
goto out;
}
- if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
- *data == ID_LED_RESERVED_F746)
- *data = ID_LED_DEFAULT_82573;
- else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF)
- *data = ID_LED_DEFAULT;
+ switch (hw->mac.type) {
+ case e1000_82574:
+ case e1000_82573:
+ 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_DEFAULT;
+ break;
+ }
+
out:
return ret_val;
}
@@ -1435,6 +1633,7 @@ out:
return ret_val;
}
+
/**
* e1000_read_mac_addr_82571 - Read device MAC address
* @hw: pointer to the HW structure
@@ -1444,9 +1643,19 @@ static s32 e1000_read_mac_addr_82571(str
s32 ret_val = E1000_SUCCESS;
DEBUGFUNC("e1000_read_mac_addr_82571");
- if (e1000_check_alt_mac_addr_generic(hw))
- ret_val = e1000_read_mac_addr_generic(hw);
+ /*
+ * If there's an alternate MAC address place it in RAR0
+ * so that it will override the Si installed default perm
+ * address.
+ */
+ ret_val = e1000_check_alt_mac_addr_generic(hw);
+ if (ret_val)
+ goto out;
+
+ ret_val = e1000_read_mac_addr_generic(hw);
+
+out:
return ret_val;
}
Modified: head/sys/dev/e1000/e1000_82575.c
==============================================================================
--- head/sys/dev/e1000/e1000_82575.c Thu Apr 9 20:57:35 2009 (r190871)
+++ head/sys/dev/e1000/e1000_82575.c Fri Apr 10 00:05:46 2009 (r190872)
@@ -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
@@ -36,6 +36,7 @@
* 82575EB Gigabit Network Connection
* 82575EB Gigabit Backplane Connection
* 82575GB Gigabit Network Connection
+ * 82575GB Gigabit Network Connection
* 82576 Gigabit Network Connection
*/
@@ -75,11 +76,6 @@ 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);
-
-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_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
/**
@@ -281,13 +277,15 @@ static s32 e1000_init_mac_params_82575(s
/* read mac address */
mac->ops.read_mac_addr = e1000_read_mac_addr_82575;
/* multicast address update */
- mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82575;
+ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic;
/* writing VFTA */
mac->ops.write_vfta = e1000_write_vfta_generic;
/* clearing VFTA */
mac->ops.clear_vfta = e1000_clear_vfta_generic;
/* setting MTA */
mac->ops.mta_set = e1000_mta_set_generic;
+ /* ID LED init */
+ mac->ops.id_led_init = e1000_id_led_init_generic;
/* blink LED */
mac->ops.blink_led = e1000_blink_led_generic;
/* setup LED */
@@ -854,11 +852,18 @@ static s32 e1000_check_for_link_82575(st
/* SGMII link check is done through the PCS register. */
if ((hw->phy.media_type != e1000_media_type_copper) ||
- (e1000_sgmii_active_82575(hw)))
+ (e1000_sgmii_active_82575(hw))) {
ret_val = e1000_get_pcs_speed_and_duplex_82575(hw, &speed,
&duplex);
- else
+ /*
+ * Use this flag to determine if link needs to be checked or
+ * not. If we have link clear the flag so that we do not
+ * continue to check for link.
+ */
+ hw->mac.get_link_status = !hw->mac.serdes_has_link;
+ } else {
ret_val = e1000_check_for_copper_link_generic(hw);
+ }
return ret_val;
}
@@ -921,101 +926,6 @@ static s32 e1000_get_pcs_speed_and_duple
}
/**
- * e1000_init_rx_addrs_82575 - Initialize receive address's
- * @hw: pointer to the HW structure
- * @rar_count: receive address registers
- *
- * Setups the receive address registers by setting the base receive address
- * register to the devices MAC address and clearing all the other receive
- * address registers to 0.
- **/
-static void e1000_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
-{
- u32 i;
- u8 addr[6] = {0,0,0,0,0,0};
- /*
- * This function is essentially the same as that of
- * e1000_init_rx_addrs_generic. However it also takes care
- * of the special case where the register offset of the
- * second set of RARs begins elsewhere. This is implicitly taken care by
- * function e1000_rar_set_generic.
- */
-
- DEBUGFUNC("e1000_init_rx_addrs_82575");
-
- /* Setup the receive address */
- DEBUGOUT("Programming MAC Address into RAR[0]\n");
- hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
- /* Zero out the other (rar_entry_count - 1) receive addresses */
- DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);
- for (i = 1; i < rar_count; i++) {
- hw->mac.ops.rar_set(hw, addr, i);
- }
-}
-
-/**
- * e1000_update_mc_addr_list_82575 - Update Multicast addresses
- * @hw: pointer to the HW structure
- * @mc_addr_list: array of multicast addresses to program
- * @mc_addr_count: number of multicast addresses to program
- * @rar_used_count: the first RAR register free to program
- * @rar_count: total number of supported Receive Address Registers
- *
- * Updates the Receive Address Registers and Multicast Table Array.
- * The caller must have a packed mc_addr_list of multicast addresses.
- * The parameter rar_count will usually be hw->mac.rar_entry_count
- * unless there are workarounds that change this.
- **/
-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)
-{
- u32 hash_value;
- u32 i;
- u8 addr[6] = {0,0,0,0,0,0};
- /*
- * This function is essentially the same as that of
- * e1000_update_mc_addr_list_generic. However it also takes care
- * of the special case where the register offset of the
- * second set of RARs begins elsewhere. This is implicitly taken care by
- * function e1000_rar_set_generic.
- */
-
- DEBUGFUNC("e1000_update_mc_addr_list_82575");
-
- /*
- * Load the first set of multicast addresses into the exact
- * filters (RAR). If there are not enough to fill the RAR
- * array, clear the filters.
- */
- for (i = rar_used_count; i < rar_count; i++) {
- if (mc_addr_count) {
- e1000_rar_set_generic(hw, mc_addr_list, i);
- mc_addr_count--;
- mc_addr_list += ETH_ADDR_LEN;
- } else {
- e1000_rar_set_generic(hw, addr, i);
- }
- }
-
- /* Clear the old settings from the MTA */
- DEBUGOUT("Clearing MTA\n");
- for (i = 0; i < hw->mac.mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0);
- E1000_WRITE_FLUSH(hw);
- }
-
- /* Load any remaining multicast addresses into the hash table. */
- for (; mc_addr_count > 0; mc_addr_count--) {
- 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;
- }
-}
-
-/**
* e1000_shutdown_fiber_serdes_link_82575 - Remove link during power down
* @hw: pointer to the HW structure
*
@@ -1060,6 +970,253 @@ 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
+ * @hw: pointer to the HW structure
+ **/
+void e1000_vmdq_loopback_disable_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_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
+ * @hw: pointer to the HW structure
+ *
+ * Disables replication of broadcast and multicast packets to the VM's.
+ **/
+void e1000_vmdq_replication_disable_pf(struct e1000_hw *hw)
+{
+ u32 reg;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list