summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'openvz-sources/022.078-r3/5104_linux-2.6.8.1-e1000-7.2.7.patch')
-rw-r--r--openvz-sources/022.078-r3/5104_linux-2.6.8.1-e1000-7.2.7.patch20547
1 files changed, 0 insertions, 20547 deletions
diff --git a/openvz-sources/022.078-r3/5104_linux-2.6.8.1-e1000-7.2.7.patch b/openvz-sources/022.078-r3/5104_linux-2.6.8.1-e1000-7.2.7.patch
deleted file mode 100644
index 4897c7e..0000000
--- a/openvz-sources/022.078-r3/5104_linux-2.6.8.1-e1000-7.2.7.patch
+++ /dev/null
@@ -1,20547 +0,0 @@
-diff -pruN ./drivers/net/e1000.orig/e1000_ethtool.c ./drivers/net/e1000/e1000_ethtool.c
---- ./drivers/net/e1000.orig/e1000_ethtool.c 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_ethtool.c 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -30,6 +31,7 @@
-
- #include "e1000.h"
-
-+#ifdef SIOCETHTOOL
- #include <asm/uaccess.h>
-
- extern char e1000_driver_name[];
-@@ -37,14 +39,20 @@ extern char e1000_driver_version[];
-
- extern int e1000_up(struct e1000_adapter *adapter);
- extern void e1000_down(struct e1000_adapter *adapter);
-+extern void e1000_reinit_locked(struct e1000_adapter *adapter);
- extern void e1000_reset(struct e1000_adapter *adapter);
- extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
--extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
--extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
--extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
--extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
-+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
- extern void e1000_update_stats(struct e1000_adapter *adapter);
-
-+#ifdef ETHTOOL_OPS_COMPAT
-+#include "kcompat_ethtool.c"
-+#endif
-+
-+#ifdef ETHTOOL_GSTATS
- struct e1000_stats {
- char stat_string[ETH_GSTRING_LEN];
- int sizeof_stat;
-@@ -60,7 +68,6 @@ static const struct e1000_stats e1000_gs
- { "tx_bytes", E1000_STAT(net_stats.tx_bytes) },
- { "rx_errors", E1000_STAT(net_stats.rx_errors) },
- { "tx_errors", E1000_STAT(net_stats.tx_errors) },
-- { "rx_dropped", E1000_STAT(net_stats.rx_dropped) },
- { "tx_dropped", E1000_STAT(net_stats.tx_dropped) },
- { "multicast", E1000_STAT(net_stats.multicast) },
- { "collisions", E1000_STAT(net_stats.collisions) },
-@@ -68,7 +75,7 @@ static const struct e1000_stats e1000_gs
- { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) },
- { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) },
- { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) },
-- { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) },
-+ { "rx_no_buffer_count", E1000_STAT(stats.rnbc) },
- { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) },
- { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) },
- { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) },
-@@ -79,6 +86,7 @@ static const struct e1000_stats e1000_gs
- { "tx_deferred_ok", E1000_STAT(stats.dc) },
- { "tx_single_coll_ok", E1000_STAT(stats.scc) },
- { "tx_multi_coll_ok", E1000_STAT(stats.mcc) },
-+ { "tx_timeout_count", E1000_STAT(tx_timeout_count) },
- { "rx_long_length_errors", E1000_STAT(stats.roc) },
- { "rx_short_length_errors", E1000_STAT(stats.ruc) },
- { "rx_align_errors", E1000_STAT(stats.algnerrc) },
-@@ -88,26 +96,46 @@ static const struct e1000_stats e1000_gs
- { "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) },
- { "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
- { "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
-+ { "rx_long_byte_count", E1000_STAT(stats.gorcl) },
- { "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
-- { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
-- { "rx_long_byte_count", E1000_STAT(stats.gorcl) }
-+ { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
-+ { "rx_header_split", E1000_STAT(rx_hdr_split) },
-+ { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) },
-+#ifdef E1000_COUNT_ICR
-+ { "txdw", E1000_STAT(icr_txdw) },
-+ { "txqe", E1000_STAT(icr_txqe) },
-+ { "lsc", E1000_STAT(icr_lsc) },
-+ { "rxseq", E1000_STAT(icr_rxseq) },
-+ { "rxdmt", E1000_STAT(icr_rxdmt) },
-+ { "rxo", E1000_STAT(icr_rxo) },
-+ { "rxt", E1000_STAT(icr_rxt) },
-+ { "mdac", E1000_STAT(icr_mdac) },
-+ { "rxcfg", E1000_STAT(icr_rxcfg) },
-+ { "gpi", E1000_STAT(icr_gpi) },
-+#endif
- };
--#define E1000_STATS_LEN \
-+
-+#define E1000_QUEUE_STATS_LEN 0
-+#define E1000_GLOBAL_STATS_LEN \
- sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
-+#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN)
-+#endif /* ETHTOOL_GSTATS */
-+#ifdef ETHTOOL_TEST
- static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
- "Register test (offline)", "Eeprom test (offline)",
- "Interrupt test (offline)", "Loopback test (offline)",
- "Link test (on/offline)"
- };
- #define E1000_TEST_LEN sizeof(e1000_gstrings_test) / ETH_GSTRING_LEN
-+#endif /* ETHTOOL_TEST */
-
- static int
- e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
-- if(hw->media_type == e1000_media_type_copper) {
-+ if (hw->media_type == e1000_media_type_copper) {
-
- ecmd->supported = (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
-@@ -116,10 +144,11 @@ e1000_get_settings(struct net_device *ne
- SUPPORTED_1000baseT_Full|
- SUPPORTED_Autoneg |
- SUPPORTED_TP);
--
-+ if (hw->phy_type == e1000_phy_ife)
-+ ecmd->supported &= ~SUPPORTED_1000baseT_Full;
- ecmd->advertising = ADVERTISED_TP;
-
-- if(hw->autoneg == 1) {
-+ if (hw->autoneg == 1) {
- ecmd->advertising |= ADVERTISED_Autoneg;
-
- /* the e1000 autoneg seems to match ethtool nicely */
-@@ -130,7 +159,7 @@ e1000_get_settings(struct net_device *ne
- ecmd->port = PORT_TP;
- ecmd->phy_address = hw->phy_addr;
-
-- if(hw->mac_type == e1000_82543)
-+ if (hw->mac_type == e1000_82543)
- ecmd->transceiver = XCVR_EXTERNAL;
- else
- ecmd->transceiver = XCVR_INTERNAL;
-@@ -140,19 +169,19 @@ e1000_get_settings(struct net_device *ne
- SUPPORTED_FIBRE |
- SUPPORTED_Autoneg);
-
-- ecmd->advertising = (SUPPORTED_1000baseT_Full |
-- SUPPORTED_FIBRE |
-- SUPPORTED_Autoneg);
-+ ecmd->advertising = (ADVERTISED_1000baseT_Full |
-+ ADVERTISED_FIBRE |
-+ ADVERTISED_Autoneg);
-
- ecmd->port = PORT_FIBRE;
-
-- if(hw->mac_type >= e1000_82545)
-+ if (hw->mac_type >= e1000_82545)
- ecmd->transceiver = XCVR_INTERNAL;
- else
- ecmd->transceiver = XCVR_EXTERNAL;
- }
-
-- if(netif_carrier_ok(adapter->netdev)) {
-+ if (netif_carrier_ok(adapter->netdev)) {
-
- e1000_get_speed_and_duplex(hw, &adapter->link_speed,
- &adapter->link_duplex);
-@@ -161,7 +190,7 @@ e1000_get_settings(struct net_device *ne
- /* unfortunatly FULL_DUPLEX != DUPLEX_FULL
- * and HALF_DUPLEX != DUPLEX_HALF */
-
-- if(adapter->link_duplex == FULL_DUPLEX)
-+ if (adapter->link_duplex == FULL_DUPLEX)
- ecmd->duplex = DUPLEX_FULL;
- else
- ecmd->duplex = DUPLEX_HALF;
-@@ -170,104 +199,135 @@ e1000_get_settings(struct net_device *ne
- ecmd->duplex = -1;
- }
-
-- ecmd->autoneg = (hw->autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
-+ ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
-+ hw->autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
- return 0;
- }
-
- static int
- e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
-- if(ecmd->autoneg == AUTONEG_ENABLE) {
-+ /* When SoL/IDER sessions are active, autoneg/speed/duplex
-+ * cannot be changed */
-+ if (e1000_check_phy_reset_block(hw)) {
-+ DPRINTK(DRV, ERR, "Cannot change link characteristics "
-+ "when SoL/IDER is active.\n");
-+ return -EINVAL;
-+ }
-+
-+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
-+ msleep(1);
-+
-+ if (ecmd->autoneg == AUTONEG_ENABLE) {
- hw->autoneg = 1;
-- hw->autoneg_advertised = 0x002F;
-- ecmd->advertising = 0x002F;
-+ if (hw->media_type == e1000_media_type_fiber)
-+ hw->autoneg_advertised = ADVERTISED_1000baseT_Full |
-+ ADVERTISED_FIBRE |
-+ ADVERTISED_Autoneg;
-+ else
-+ hw->autoneg_advertised = ADVERTISED_10baseT_Half |
-+ ADVERTISED_10baseT_Full |
-+ ADVERTISED_100baseT_Half |
-+ ADVERTISED_100baseT_Full |
-+ ADVERTISED_1000baseT_Full|
-+ ADVERTISED_Autoneg |
-+ ADVERTISED_TP;
-+ ecmd->advertising = hw->autoneg_advertised;
- } else
-- if(e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex))
-+ if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
- return -EINVAL;
-+ }
-
- /* reset the link */
-
-- if(netif_running(adapter->netdev)) {
-+ if (netif_running(adapter->netdev)) {
- e1000_down(adapter);
- e1000_up(adapter);
- } else
- e1000_reset(adapter);
-
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
- return 0;
- }
-
--static void
-+static void
- e1000_get_pauseparam(struct net_device *netdev,
-- struct ethtool_pauseparam *pause)
-+ struct ethtool_pauseparam *pause)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-- pause->autoneg =
-+
-+ pause->autoneg =
- (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
--
-- if(hw->fc == e1000_fc_rx_pause)
-+
-+ if (hw->fc == e1000_fc_rx_pause)
- pause->rx_pause = 1;
-- else if(hw->fc == e1000_fc_tx_pause)
-+ else if (hw->fc == e1000_fc_tx_pause)
- pause->tx_pause = 1;
-- else if(hw->fc == e1000_fc_full) {
-+ else if (hw->fc == e1000_fc_full) {
- pause->rx_pause = 1;
- pause->tx_pause = 1;
- }
- }
-
--static int
-+static int
- e1000_set_pauseparam(struct net_device *netdev,
-- struct ethtool_pauseparam *pause)
-+ struct ethtool_pauseparam *pause)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
--
-+ int retval = 0;
-+
- adapter->fc_autoneg = pause->autoneg;
-
-- if(pause->rx_pause && pause->tx_pause)
-+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
-+ msleep(1);
-+
-+ if (pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_full;
-- else if(pause->rx_pause && !pause->tx_pause)
-+ else if (pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_rx_pause;
-- else if(!pause->rx_pause && pause->tx_pause)
-+ else if (!pause->rx_pause && pause->tx_pause)
- hw->fc = e1000_fc_tx_pause;
-- else if(!pause->rx_pause && !pause->tx_pause)
-+ else if (!pause->rx_pause && !pause->tx_pause)
- hw->fc = e1000_fc_none;
-
- hw->original_fc = hw->fc;
-
-- if(adapter->fc_autoneg == AUTONEG_ENABLE) {
-- if(netif_running(adapter->netdev)) {
-+ if (adapter->fc_autoneg == AUTONEG_ENABLE) {
-+ if (netif_running(adapter->netdev)) {
- e1000_down(adapter);
- e1000_up(adapter);
- } else
- e1000_reset(adapter);
-- }
-- else
-- return e1000_force_mac_fc(hw);
--
-- return 0;
-+ } else
-+ retval = ((hw->media_type == e1000_media_type_fiber) ?
-+ e1000_setup_link(hw) : e1000_force_mac_fc(hw));
-+
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
-+ return retval;
- }
-
- static uint32_t
- e1000_get_rx_csum(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- return adapter->rx_csum;
- }
-
- static int
- e1000_set_rx_csum(struct net_device *netdev, uint32_t data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- adapter->rx_csum = data;
-
-- if(netif_running(netdev)) {
-- e1000_down(adapter);
-- e1000_up(adapter);
-- } else
-+ if (netif_running(netdev))
-+ e1000_reinit_locked(adapter);
-+ else
- e1000_reset(adapter);
- return 0;
- }
-@@ -281,9 +341,9 @@ e1000_get_tx_csum(struct net_device *net
- static int
- e1000_set_tx_csum(struct net_device *netdev, uint32_t data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
-- if(adapter->hw.mac_type < e1000_82543) {
-+ if (adapter->hw.mac_type < e1000_82543) {
- if (!data)
- return -EINVAL;
- return 0;
-@@ -301,34 +361,37 @@ e1000_set_tx_csum(struct net_device *net
- static int
- e1000_set_tso(struct net_device *netdev, uint32_t data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- if ((adapter->hw.mac_type < e1000_82544) ||
-- (adapter->hw.mac_type == e1000_82547))
-+ (adapter->hw.mac_type == e1000_82547))
- return data ? -EINVAL : 0;
-
- if (data)
- netdev->features |= NETIF_F_TSO;
- else
- netdev->features &= ~NETIF_F_TSO;
-+
-+ DPRINTK(PROBE, INFO, "TSO is %s\n", data ? "Enabled" : "Disabled");
-+ adapter->tso_force = TRUE;
- return 0;
--}
-+}
- #endif /* NETIF_F_TSO */
-
- static uint32_t
- e1000_get_msglevel(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- return adapter->msg_enable;
- }
-
- static void
- e1000_set_msglevel(struct net_device *netdev, uint32_t data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- adapter->msg_enable = data;
- }
-
--static int
-+static int
- e1000_get_regs_len(struct net_device *netdev)
- {
- #define E1000_REGS_LEN 32
-@@ -337,9 +400,9 @@ e1000_get_regs_len(struct net_device *ne
-
- static void
- e1000_get_regs(struct net_device *netdev,
-- struct ethtool_regs *regs, void *p)
-+ struct ethtool_regs *regs, void *p)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- uint32_t *regs_buff = p;
- uint16_t phy_data;
-@@ -364,7 +427,7 @@ e1000_get_regs(struct net_device *netdev
- regs_buff[11] = E1000_READ_REG(hw, TIDV);
-
- regs_buff[12] = adapter->hw.phy_type; /* PHY type (IGP=1, M88=0) */
-- if(hw->phy_type == e1000_phy_igp) {
-+ if (hw->phy_type == e1000_phy_igp) {
- e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT,
- IGP01E1000_PHY_AGC_A);
- e1000_read_phy_reg(hw, IGP01E1000_PHY_AGC_A &
-@@ -400,12 +463,12 @@ e1000_get_regs(struct net_device *netdev
- regs_buff[23] = regs_buff[18]; /* mdix mode */
- e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, 0x0);
- } else {
-- e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
-+ e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
- regs_buff[13] = (uint32_t)phy_data; /* cable length */
- regs_buff[14] = 0; /* Dummy (to align w/ IGP phy reg dump) */
- regs_buff[15] = 0; /* Dummy (to align w/ IGP phy reg dump) */
- regs_buff[16] = 0; /* Dummy (to align w/ IGP phy reg dump) */
-- e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
-+ e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- regs_buff[17] = (uint32_t)phy_data; /* extended 10bt distance */
- regs_buff[18] = regs_buff[13]; /* cable polarity */
- regs_buff[19] = 0; /* Dummy (to align w/ IGP phy reg dump) */
-@@ -418,12 +481,16 @@ e1000_get_regs(struct net_device *netdev
- e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
- regs_buff[24] = (uint32_t)phy_data; /* phy local receiver status */
- regs_buff[25] = regs_buff[24]; /* phy remote receiver status */
-+ if (hw->mac_type >= e1000_82540 &&
-+ hw->media_type == e1000_media_type_copper) {
-+ regs_buff[26] = E1000_READ_REG(hw, MANC);
-+ }
- }
-
- static int
- e1000_get_eeprom_len(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- return adapter->hw.eeprom.word_size * 2;
- }
-
-@@ -431,14 +498,14 @@ static int
- e1000_get_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, uint8_t *bytes)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- uint16_t *eeprom_buff;
- int first_word, last_word;
- int ret_val = 0;
- uint16_t i;
-
-- if(eeprom->len == 0)
-+ if (eeprom->len == 0)
- return -EINVAL;
-
- eeprom->magic = hw->vendor_id | (hw->device_id << 16);
-@@ -446,18 +513,18 @@ e1000_get_eeprom(struct net_device *netd
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
-
-- eeprom_buff = kmalloc(sizeof(uint16_t) *
-+ eeprom_buff = kmalloc(sizeof(uint16_t) *
- (last_word - first_word + 1), GFP_KERNEL);
- if (!eeprom_buff)
- return -ENOMEM;
-
-- if(hw->eeprom.type == e1000_eeprom_spi)
-+ if (hw->eeprom.type == e1000_eeprom_spi)
- ret_val = e1000_read_eeprom(hw, first_word,
- last_word - first_word + 1,
- eeprom_buff);
- else {
- for (i = 0; i < last_word - first_word + 1; i++)
-- if((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
-+ if ((ret_val = e1000_read_eeprom(hw, first_word + i, 1,
- &eeprom_buff[i])))
- break;
- }
-@@ -466,9 +533,8 @@ e1000_get_eeprom(struct net_device *netd
- for (i = 0; i < last_word - first_word + 1; i++)
- le16_to_cpus(&eeprom_buff[i]);
-
--
-- memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset%2),
-- eeprom->len);
-+ memcpy(bytes, (uint8_t *)eeprom_buff + (eeprom->offset & 1),
-+ eeprom->len);
- kfree(eeprom_buff);
-
- return ret_val;
-@@ -478,17 +544,17 @@ static int
- e1000_set_eeprom(struct net_device *netdev,
- struct ethtool_eeprom *eeprom, uint8_t *bytes)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- uint16_t *eeprom_buff;
- void *ptr;
- int max_len, first_word, last_word, ret_val = 0;
- uint16_t i;
-
-- if(eeprom->len == 0)
-+ if (eeprom->len == 0)
- return -EOPNOTSUPP;
-
-- if(eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
-+ if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
- return -EFAULT;
-
- max_len = hw->eeprom.word_size * 2;
-@@ -496,19 +562,19 @@ e1000_set_eeprom(struct net_device *netd
- first_word = eeprom->offset >> 1;
- last_word = (eeprom->offset + eeprom->len - 1) >> 1;
- eeprom_buff = kmalloc(max_len, GFP_KERNEL);
-- if(!eeprom_buff)
-+ if (!eeprom_buff)
- return -ENOMEM;
-
- ptr = (void *)eeprom_buff;
-
-- if(eeprom->offset & 1) {
-+ if (eeprom->offset & 1) {
- /* need read/modify/write of first changed EEPROM word */
- /* only the second byte of the word is being modified */
- ret_val = e1000_read_eeprom(hw, first_word, 1,
- &eeprom_buff[0]);
- ptr++;
- }
-- if(((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
-+ if (((eeprom->offset + eeprom->len) & 1) && (ret_val == 0)) {
- /* need read/modify/write of last changed EEPROM word */
- /* only the first byte of the word is being modified */
- ret_val = e1000_read_eeprom(hw, last_word, 1,
-@@ -520,14 +586,17 @@ e1000_set_eeprom(struct net_device *netd
- le16_to_cpus(&eeprom_buff[i]);
-
- memcpy(ptr, bytes, eeprom->len);
-+
- for (i = 0; i < last_word - first_word + 1; i++)
- eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]);
-
- ret_val = e1000_write_eeprom(hw, first_word,
- last_word - first_word + 1, eeprom_buff);
-
-- /* Update the checksum over the first part of the EEPROM if needed */
-- if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
-+ /* Update the checksum over the first part of the EEPROM if needed
-+ * and flush shadow RAM for 82573 conrollers */
-+ if ((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) ||
-+ (hw->mac_type == e1000_82573)))
- e1000_update_eeprom_checksum(hw);
-
- kfree(eeprom_buff);
-@@ -538,11 +607,32 @@ static void
- e1000_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *drvinfo)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+ char firmware_version[32];
-+ uint16_t eeprom_data;
-
- strncpy(drvinfo->driver, e1000_driver_name, 32);
- strncpy(drvinfo->version, e1000_driver_version, 32);
-- strncpy(drvinfo->fw_version, "N/A", 32);
-+
-+ /* EEPROM image version # is reported as firmware version # for
-+ * 8257{1|2|3} controllers */
-+ e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data);
-+ switch (adapter->hw.mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_80003es2lan:
-+ case e1000_ich8lan:
-+ sprintf(firmware_version, "%d.%d-%d",
-+ (eeprom_data & 0xF000) >> 12,
-+ (eeprom_data & 0x0FF0) >> 4,
-+ eeprom_data & 0x000F);
-+ break;
-+ default:
-+ sprintf(firmware_version, "N/A");
-+ }
-+
-+ strncpy(drvinfo->fw_version, firmware_version, 32);
- strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
- drvinfo->n_stats = E1000_STATS_LEN;
- drvinfo->testinfo_len = E1000_TEST_LEN;
-@@ -554,10 +644,10 @@ static void
- e1000_get_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- e1000_mac_type mac_type = adapter->hw.mac_type;
-- struct e1000_desc_ring *txdr = &adapter->tx_ring;
-- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
-+ struct e1000_tx_ring *txdr = adapter->tx_ring;
-+ struct e1000_rx_ring *rxdr = adapter->rx_ring;
-
- ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
- E1000_MAX_82544_RXD;
-@@ -571,75 +661,113 @@ e1000_get_ringparam(struct net_device *n
- ring->rx_jumbo_pending = 0;
- }
-
--static int
-+static int
- e1000_set_ringparam(struct net_device *netdev,
- struct ethtool_ringparam *ring)
- {
-- int err;
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- e1000_mac_type mac_type = adapter->hw.mac_type;
-- struct e1000_desc_ring *txdr = &adapter->tx_ring;
-- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
-- struct e1000_desc_ring tx_old, tx_new;
-- struct e1000_desc_ring rx_old, rx_new;
-+ struct e1000_tx_ring *txdr, *tx_old, *tx_new;
-+ struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
-+ int i, err, tx_ring_size, rx_ring_size;
-+
-+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
-+ return -EINVAL;
-+
-+ tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
-+ rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
-+
-+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
-+ msleep(1);
-+
-+ if (netif_running(adapter->netdev))
-+ e1000_down(adapter);
-
- tx_old = adapter->tx_ring;
- rx_old = adapter->rx_ring;
--
-- if(netif_running(adapter->netdev))
-- e1000_down(adapter);
-+
-+ adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
-+ if (!adapter->tx_ring) {
-+ err = -ENOMEM;
-+ goto err_setup_rx;
-+ }
-+ memset(adapter->tx_ring, 0, tx_ring_size);
-+
-+ adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
-+ if (!adapter->rx_ring) {
-+ kfree(adapter->tx_ring);
-+ err = -ENOMEM;
-+ goto err_setup_rx;
-+ }
-+ memset(adapter->rx_ring, 0, rx_ring_size);
-+
-+ txdr = adapter->tx_ring;
-+ rxdr = adapter->rx_ring;
-
- rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
- rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
- E1000_MAX_RXD : E1000_MAX_82544_RXD));
-- E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
-+ E1000_ROUNDUP(rxdr->count, REQ_RX_DESCRIPTOR_MULTIPLE);
-
- txdr->count = max(ring->tx_pending,(uint32_t)E1000_MIN_TXD);
- txdr->count = min(txdr->count,(uint32_t)(mac_type < e1000_82544 ?
- E1000_MAX_TXD : E1000_MAX_82544_TXD));
-- E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
-+ E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE);
-
-- if(netif_running(adapter->netdev)) {
-- /* try to get new resources before deleting old */
-- if((err = e1000_setup_rx_resources(adapter)))
-+ for (i = 0; i < adapter->num_tx_queues; i++)
-+ txdr[i].count = txdr->count;
-+ for (i = 0; i < adapter->num_rx_queues; i++)
-+ rxdr[i].count = rxdr->count;
-+
-+ if (netif_running(adapter->netdev)) {
-+ /* Try to get new resources before deleting old */
-+ if ((err = e1000_setup_all_rx_resources(adapter)))
- goto err_setup_rx;
-- if((err = e1000_setup_tx_resources(adapter)))
-+ if ((err = e1000_setup_all_tx_resources(adapter)))
- goto err_setup_tx;
-
- /* save the new, restore the old in order to free it,
-- * then restore the new back again */
--
-+ * then restore the new back again */
-+
- rx_new = adapter->rx_ring;
- tx_new = adapter->tx_ring;
- adapter->rx_ring = rx_old;
- adapter->tx_ring = tx_old;
-- e1000_free_rx_resources(adapter);
-- e1000_free_tx_resources(adapter);
-+ e1000_free_all_rx_resources(adapter);
-+ e1000_free_all_tx_resources(adapter);
-+ kfree(tx_old);
-+ kfree(rx_old);
- adapter->rx_ring = rx_new;
- adapter->tx_ring = tx_new;
-- if((err = e1000_up(adapter)))
-- return err;
-+ if ((err = e1000_up(adapter)))
-+ goto err_setup;
- }
-+
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
- return 0;
- err_setup_tx:
-- e1000_free_rx_resources(adapter);
-+ e1000_free_all_rx_resources(adapter);
- err_setup_rx:
- adapter->rx_ring = rx_old;
- adapter->tx_ring = tx_old;
- e1000_up(adapter);
-+err_setup:
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
- return err;
- }
-
--
- #define REG_PATTERN_TEST(R, M, W) \
- { \
- uint32_t pat, value; \
- uint32_t test[] = \
- {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
-- for(pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \
-+ for (pat = 0; pat < sizeof(test)/sizeof(test[0]); pat++) { \
- E1000_WRITE_REG(&adapter->hw, R, (test[pat] & W)); \
- value = E1000_READ_REG(&adapter->hw, R); \
-- if(value != (test[pat] & W & M)) { \
-+ if (value != (test[pat] & W & M)) { \
-+ DPRINTK(DRV, ERR, "pattern test reg %04X failed: got " \
-+ "0x%08X expected 0x%08X\n", \
-+ E1000_##R, value, (test[pat] & W & M)); \
- *data = (adapter->hw.mac_type < e1000_82543) ? \
- E1000_82542_##R : E1000_##R; \
- return 1; \
-@@ -653,6 +781,8 @@ err_setup_rx:
- E1000_WRITE_REG(&adapter->hw, R, W & M); \
- value = E1000_READ_REG(&adapter->hw, R); \
- if ((W & M) != (value & M)) { \
-+ DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
-+ "expected 0x%08X\n", E1000_##R, (value & M), (W & M)); \
- *data = (adapter->hw.mac_type < e1000_82543) ? \
- E1000_82542_##R : E1000_##R; \
- return 1; \
-@@ -662,23 +792,46 @@ err_setup_rx:
- static int
- e1000_reg_test(struct e1000_adapter *adapter, uint64_t *data)
- {
-- uint32_t value;
-- uint32_t i;
-+ uint32_t value, before, after;
-+ uint32_t i, toggle;
-
- /* The status register is Read Only, so a write should fail.
- * Some bits that get toggled are ignored.
- */
-- value = (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833));
-- E1000_WRITE_REG(&adapter->hw, STATUS, (0xFFFFFFFF));
-- if(value != (E1000_READ_REG(&adapter->hw, STATUS) & (0xFFFFF833))) {
-+ switch (adapter->hw.mac_type) {
-+ /* there are several bits on newer hardware that are r/w */
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+ toggle = 0x7FFFF3FF;
-+ break;
-+ case e1000_82573:
-+ case e1000_ich8lan:
-+ toggle = 0x7FFFF033;
-+ break;
-+ default:
-+ toggle = 0xFFFFF833;
-+ break;
-+ }
-+
-+ before = E1000_READ_REG(&adapter->hw, STATUS);
-+ value = (E1000_READ_REG(&adapter->hw, STATUS) & toggle);
-+ E1000_WRITE_REG(&adapter->hw, STATUS, toggle);
-+ after = E1000_READ_REG(&adapter->hw, STATUS) & toggle;
-+ if (value != after) {
-+ DPRINTK(DRV, ERR, "failed STATUS register test got: "
-+ "0x%08X expected: 0x%08X\n", after, value);
- *data = 1;
- return 1;
- }
--
-- REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
-- REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
-- REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
-- REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
-+ /* restore previous status */
-+ E1000_WRITE_REG(&adapter->hw, STATUS, before);
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
-+ REG_PATTERN_TEST(FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
-+ REG_PATTERN_TEST(FCAH, 0x0000FFFF, 0xFFFFFFFF);
-+ REG_PATTERN_TEST(FCT, 0x0000FFFF, 0xFFFFFFFF);
-+ REG_PATTERN_TEST(VET, 0x0000FFFF, 0xFFFFFFFF);
-+ }
- REG_PATTERN_TEST(RDTR, 0x0000FFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDBAH, 0xFFFFFFFF, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDLEN, 0x000FFF80, 0x000FFFFF);
-@@ -691,20 +844,22 @@ e1000_reg_test(struct e1000_adapter *ada
- REG_PATTERN_TEST(TDLEN, 0x000FFF80, 0x000FFFFF);
-
- REG_SET_AND_CHECK(RCTL, 0xFFFFFFFF, 0x00000000);
-- REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0x003FFFFB);
-+ before = (adapter->hw.mac_type == e1000_ich8lan ?
-+ 0x06C3B33E : 0x06DFB3FE);
-+ REG_SET_AND_CHECK(RCTL, before, 0x003FFFFB);
- REG_SET_AND_CHECK(TCTL, 0xFFFFFFFF, 0x00000000);
-
-- if(adapter->hw.mac_type >= e1000_82543) {
-+ if (adapter->hw.mac_type >= e1000_82543) {
-
-- REG_SET_AND_CHECK(RCTL, 0x06DFB3FE, 0xFFFFFFFF);
-+ REG_SET_AND_CHECK(RCTL, before, 0xFFFFFFFF);
- REG_PATTERN_TEST(RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
-- REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
-+ if (adapter->hw.mac_type != e1000_ich8lan)
-+ REG_PATTERN_TEST(TXCW, 0xC000FFFF, 0x0000FFFF);
- REG_PATTERN_TEST(TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
- REG_PATTERN_TEST(TIDV, 0x0000FFFF, 0x0000FFFF);
--
-- for(i = 0; i < E1000_RAR_ENTRIES; i++) {
-- REG_PATTERN_TEST(RA + ((i << 1) << 2), 0xFFFFFFFF,
-- 0xFFFFFFFF);
-+ value = (adapter->hw.mac_type == e1000_ich8lan ?
-+ E1000_RAR_ENTRIES_ICH8LAN : E1000_RAR_ENTRIES);
-+ for (i = 0; i < value; i++) {
- REG_PATTERN_TEST(RA + (((i << 1) + 1) << 2), 0x8003FFFF,
- 0xFFFFFFFF);
- }
-@@ -718,7 +873,9 @@ e1000_reg_test(struct e1000_adapter *ada
-
- }
-
-- for(i = 0; i < E1000_MC_TBL_SIZE; i++)
-+ value = (adapter->hw.mac_type == e1000_ich8lan ?
-+ E1000_MC_TBL_SIZE_ICH8LAN : E1000_MC_TBL_SIZE);
-+ for (i = 0; i < value; i++)
- REG_PATTERN_TEST(MTA + (i << 2), 0xFFFFFFFF, 0xFFFFFFFF);
-
- *data = 0;
-@@ -734,8 +891,8 @@ e1000_eeprom_test(struct e1000_adapter *
-
- *data = 0;
- /* Read and add up the contents of the EEPROM */
-- for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-- if((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
-+ for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-+ if ((e1000_read_eeprom(&adapter->hw, i, 1, &temp)) < 0) {
- *data = 1;
- break;
- }
-@@ -743,7 +900,7 @@ e1000_eeprom_test(struct e1000_adapter *
- }
-
- /* If Checksum is not Correct return error else test passed */
-- if((checksum != (uint16_t) EEPROM_SUM) && !(*data))
-+ if ((checksum != (uint16_t) EEPROM_SUM) && !(*data))
- *data = 2;
-
- return *data;
-@@ -755,7 +912,7 @@ e1000_test_intr(int irq,
- struct pt_regs *regs)
- {
- struct net_device *netdev = (struct net_device *) data;
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
- adapter->test_icr |= E1000_READ_REG(&adapter->hw, ICR);
-
-@@ -766,56 +923,52 @@ static int
- e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data)
- {
- struct net_device *netdev = adapter->netdev;
-- uint32_t icr, mask, i=0;
-+ uint32_t mask, i=0, shared_int = TRUE;
-+ uint32_t irq = adapter->pdev->irq;
-
- *data = 0;
-
-+ /* NOTE: we don't test MSI interrupts here, yet */
- /* Hook up test interrupt handler just for this test */
-- if(request_irq(adapter->pdev->irq, &e1000_test_intr, SA_SHIRQ,
-- netdev->name, netdev)) {
-+ if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name,
-+ netdev))
-+ shared_int = FALSE;
-+ else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ,
-+ netdev->name, netdev)){
- *data = 1;
- return -1;
- }
-+ DPRINTK(HW, INFO, "testing %s interrupt\n",
-+ (shared_int ? "shared" : "unshared"));
-
- /* Disable all the interrupts */
- E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF);
- msec_delay(10);
-
-- /* Interrupts are disabled, so read interrupt cause
-- * register (icr) twice to verify that there are no interrupts
-- * pending. icr is clear on read.
-- */
-- icr = E1000_READ_REG(&adapter->hw, ICR);
-- icr = E1000_READ_REG(&adapter->hw, ICR);
--
-- if(icr != 0) {
-- /* if icr is non-zero, there is no point
-- * running other interrupt tests.
-- */
-- *data = 2;
-- i = 10;
-- }
--
- /* Test each interrupt */
-- for(; i < 10; i++) {
-+ for (; i < 10; i++) {
-
-+ if (adapter->hw.mac_type == e1000_ich8lan && i == 8)
-+ continue;
- /* Interrupt to test */
- mask = 1 << i;
-
-- /* Disable the interrupt to be reported in
-- * the cause register and then force the same
-- * interrupt and see if one gets posted. If
-- * an interrupt was posted to the bus, the
-- * test failed.
-- */
-- adapter->test_icr = 0;
-- E1000_WRITE_REG(&adapter->hw, IMC, mask);
-- E1000_WRITE_REG(&adapter->hw, ICS, mask);
-- msec_delay(10);
-+ if (!shared_int) {
-+ /* Disable the interrupt to be reported in
-+ * the cause register and then force the same
-+ * interrupt and see if one gets posted. If
-+ * an interrupt was posted to the bus, the
-+ * test failed.
-+ */
-+ adapter->test_icr = 0;
-+ E1000_WRITE_REG(&adapter->hw, IMC, mask);
-+ E1000_WRITE_REG(&adapter->hw, ICS, mask);
-+ msec_delay(10);
-
-- if(adapter->test_icr & mask) {
-- *data = 3;
-- break;
-+ if (adapter->test_icr & mask) {
-+ *data = 3;
-+ break;
-+ }
- }
-
- /* Enable the interrupt to be reported in
-@@ -829,25 +982,27 @@ e1000_intr_test(struct e1000_adapter *ad
- E1000_WRITE_REG(&adapter->hw, ICS, mask);
- msec_delay(10);
-
-- if(!(adapter->test_icr & mask)) {
-+ if (!(adapter->test_icr & mask)) {
- *data = 4;
- break;
- }
-
-- /* Disable the other interrupts to be reported in
-- * the cause register and then force the other
-- * interrupts and see if any get posted. If
-- * an interrupt was posted to the bus, the
-- * test failed.
-- */
-- adapter->test_icr = 0;
-- E1000_WRITE_REG(&adapter->hw, IMC, ~mask);
-- E1000_WRITE_REG(&adapter->hw, ICS, ~mask);
-- msec_delay(10);
-+ if (!shared_int) {
-+ /* Disable the other interrupts to be reported in
-+ * the cause register and then force the other
-+ * interrupts and see if any get posted. If
-+ * an interrupt was posted to the bus, the
-+ * test failed.
-+ */
-+ adapter->test_icr = 0;
-+ E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF);
-+ E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF);
-+ msec_delay(10);
-
-- if(adapter->test_icr) {
-- *data = 5;
-- break;
-+ if (adapter->test_icr) {
-+ *data = 5;
-+ break;
-+ }
- }
- }
-
-@@ -856,7 +1011,7 @@ e1000_intr_test(struct e1000_adapter *ad
- msec_delay(10);
-
- /* Unhook test interrupt handler */
-- free_irq(adapter->pdev->irq, netdev);
-+ free_irq(irq, netdev);
-
- return *data;
- }
-@@ -864,42 +1019,46 @@ e1000_intr_test(struct e1000_adapter *ad
- static void
- e1000_free_desc_rings(struct e1000_adapter *adapter)
- {
-- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
-+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
-+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
- int i;
-
-- if(txdr->desc && txdr->buffer_info) {
-- for(i = 0; i < txdr->count; i++) {
-- if(txdr->buffer_info[i].dma)
-+ if (txdr->desc && txdr->buffer_info) {
-+ for (i = 0; i < txdr->count; i++) {
-+ if (txdr->buffer_info[i].dma)
- pci_unmap_single(pdev, txdr->buffer_info[i].dma,
- txdr->buffer_info[i].length,
- PCI_DMA_TODEVICE);
-- if(txdr->buffer_info[i].skb)
-+ if (txdr->buffer_info[i].skb)
- dev_kfree_skb(txdr->buffer_info[i].skb);
- }
- }
-
-- if(rxdr->desc && rxdr->buffer_info) {
-- for(i = 0; i < rxdr->count; i++) {
-- if(rxdr->buffer_info[i].dma)
-+ if (rxdr->desc && rxdr->buffer_info) {
-+ for (i = 0; i < rxdr->count; i++) {
-+ if (rxdr->buffer_info[i].dma)
- pci_unmap_single(pdev, rxdr->buffer_info[i].dma,
- rxdr->buffer_info[i].length,
- PCI_DMA_FROMDEVICE);
-- if(rxdr->buffer_info[i].skb)
-+ if (rxdr->buffer_info[i].skb)
- dev_kfree_skb(rxdr->buffer_info[i].skb);
- }
- }
-
-- if(txdr->desc)
-+ if (txdr->desc) {
- pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma);
-- if(rxdr->desc)
-+ txdr->desc = NULL;
-+ }
-+ if (rxdr->desc) {
- pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
-+ rxdr->desc = NULL;
-+ }
-
-- if(txdr->buffer_info)
-- kfree(txdr->buffer_info);
-- if(rxdr->buffer_info)
-- kfree(rxdr->buffer_info);
-+ kfree(txdr->buffer_info);
-+ txdr->buffer_info = NULL;
-+ kfree(rxdr->buffer_info);
-+ rxdr->buffer_info = NULL;
-
- return;
- }
-@@ -907,18 +1066,19 @@ e1000_free_desc_rings(struct e1000_adapt
- static int
- e1000_setup_desc_rings(struct e1000_adapter *adapter)
- {
-- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
-+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
-+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
- uint32_t rctl;
- int size, i, ret_val;
-
- /* Setup Tx descriptor ring and Tx buffers */
-
-- txdr->count = 80;
-+ if (!txdr->count)
-+ txdr->count = E1000_DEFAULT_TXD;
-
- size = txdr->count * sizeof(struct e1000_buffer);
-- if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
-+ if (!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
- ret_val = 1;
- goto err_nomem;
- }
-@@ -926,7 +1086,7 @@ e1000_setup_desc_rings(struct e1000_adap
-
- txdr->size = txdr->count * sizeof(struct e1000_tx_desc);
- E1000_ROUNDUP(txdr->size, 4096);
-- if(!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) {
-+ if (!(txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma))) {
- ret_val = 2;
- goto err_nomem;
- }
-@@ -945,12 +1105,12 @@ e1000_setup_desc_rings(struct e1000_adap
- E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
- E1000_FDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
-
-- for(i = 0; i < txdr->count; i++) {
-+ for (i = 0; i < txdr->count; i++) {
- struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*txdr, i);
- struct sk_buff *skb;
- unsigned int size = 1024;
-
-- if(!(skb = alloc_skb(size, GFP_KERNEL))) {
-+ if (!(skb = alloc_skb(size, GFP_KERNEL))) {
- ret_val = 3;
- goto err_nomem;
- }
-@@ -970,17 +1130,18 @@ e1000_setup_desc_rings(struct e1000_adap
-
- /* Setup Rx descriptor ring and Rx buffers */
-
-- rxdr->count = 80;
-+ if (!rxdr->count)
-+ rxdr->count = E1000_DEFAULT_RXD;
-
- size = rxdr->count * sizeof(struct e1000_buffer);
-- if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
-+ if (!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) {
- ret_val = 4;
- goto err_nomem;
- }
- memset(rxdr->buffer_info, 0, size);
-
- rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
-- if(!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
-+ if (!(rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma))) {
- ret_val = 5;
- goto err_nomem;
- }
-@@ -1000,12 +1161,12 @@ e1000_setup_desc_rings(struct e1000_adap
- (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-
-- for(i = 0; i < rxdr->count; i++) {
-+ for (i = 0; i < rxdr->count; i++) {
- struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i);
- struct sk_buff *skb;
-
-- if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
-- GFP_KERNEL))) {
-+ if (!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN,
-+ GFP_KERNEL))) {
- ret_val = 6;
- goto err_nomem;
- }
-@@ -1021,7 +1182,7 @@ e1000_setup_desc_rings(struct e1000_adap
-
- return 0;
-
-- err_nomem:
-+err_nomem:
- e1000_free_desc_rings(adapter);
- return ret_val;
- }
-@@ -1095,7 +1256,7 @@ e1000_nonintegrated_phy_loopback(struct
- e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8100);
-
- /* Wait for reset to complete. */
-- udelay(500);
-+ usec_delay(500);
-
- /* Have to setup TX_CLK and TX_CRS after software reset */
- e1000_phy_reset_clk_and_crs(adapter);
-@@ -1113,15 +1274,15 @@ e1000_nonintegrated_phy_loopback(struct
-
- /* Check Phy Configuration */
- e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-- if(phy_reg != 0x4100)
-+ if (phy_reg != 0x4100)
- return 9;
-
- e1000_read_phy_reg(&adapter->hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_reg);
-- if(phy_reg != 0x0070)
-+ if (phy_reg != 0x0070)
- return 10;
-
- e1000_read_phy_reg(&adapter->hw, 29, &phy_reg);
-- if(phy_reg != 0x001A)
-+ if (phy_reg != 0x001A)
- return 11;
-
- return 0;
-@@ -1135,7 +1296,7 @@ e1000_integrated_phy_loopback(struct e10
-
- adapter->hw.autoneg = FALSE;
-
-- if(adapter->hw.phy_type == e1000_phy_m88) {
-+ if (adapter->hw.phy_type == e1000_phy_m88) {
- /* Auto-MDI/MDIX Off */
- e1000_write_phy_reg(&adapter->hw,
- M88E1000_PHY_SPEC_CTRL, 0x0808);
-@@ -1143,26 +1304,44 @@ e1000_integrated_phy_loopback(struct e10
- e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x9140);
- /* autoneg off */
- e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x8140);
-- }
-- /* force 1000, set loopback */
-- e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);
-+ } else if (adapter->hw.phy_type == e1000_phy_gg82563)
-+ e1000_write_phy_reg(&adapter->hw,
-+ GG82563_PHY_KMRN_MODE_CTRL,
-+ 0x1CC);
-
-- /* Now set up the MAC to the same speed/duplex as the PHY. */
- ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
-- ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
-- ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
-- E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
-- E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
-- E1000_CTRL_FD); /* Force Duplex to FULL */
-
-- if(adapter->hw.media_type == e1000_media_type_copper &&
-+ if (adapter->hw.phy_type == e1000_phy_ife) {
-+ /* force 100, set loopback */
-+ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x6100);
-+
-+ /* Now set up the MAC to the same speed/duplex as the PHY. */
-+ ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
-+ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
-+ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
-+ E1000_CTRL_SPD_100 |/* Force Speed to 100 */
-+ E1000_CTRL_FD); /* Force Duplex to FULL */
-+ } else {
-+ /* force 1000, set loopback */
-+ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, 0x4140);
-+
-+ /* Now set up the MAC to the same speed/duplex as the PHY. */
-+ ctrl_reg = E1000_READ_REG(&adapter->hw, CTRL);
-+ ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
-+ ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
-+ E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
-+ E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
-+ E1000_CTRL_FD); /* Force Duplex to FULL */
-+ }
-+
-+ if (adapter->hw.media_type == e1000_media_type_copper &&
- adapter->hw.phy_type == e1000_phy_m88) {
- ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
- } else {
- /* Set the ILOS bit on the fiber Nic is half
- * duplex link is detected. */
- stat_reg = E1000_READ_REG(&adapter->hw, STATUS);
-- if((stat_reg & E1000_STATUS_FD) == 0)
-+ if ((stat_reg & E1000_STATUS_FD) == 0)
- ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
- }
-
-@@ -1171,10 +1350,10 @@ e1000_integrated_phy_loopback(struct e10
- /* Disable the receiver on the PHY so when a cable is plugged in, the
- * PHY does not begin to autoneg when a cable is reconnected to the NIC.
- */
-- if(adapter->hw.phy_type == e1000_phy_m88)
-+ if (adapter->hw.phy_type == e1000_phy_m88)
- e1000_phy_disable_receiver(adapter);
-
-- udelay(500);
-+ usec_delay(500);
-
- return 0;
- }
-@@ -1187,14 +1366,14 @@ e1000_set_phy_loopback(struct e1000_adap
-
- switch (adapter->hw.mac_type) {
- case e1000_82543:
-- if(adapter->hw.media_type == e1000_media_type_copper) {
-+ if (adapter->hw.media_type == e1000_media_type_copper) {
- /* Attempt to setup Loopback mode on Non-integrated PHY.
- * Some PHY registers get corrupted at random, so
- * attempt this 10 times.
- */
-- while(e1000_nonintegrated_phy_loopback(adapter) &&
-+ while (e1000_nonintegrated_phy_loopback(adapter) &&
- count++ < 10);
-- if(count < 11)
-+ if (count < 11)
- return 0;
- }
- break;
-@@ -1209,6 +1388,11 @@ e1000_set_phy_loopback(struct e1000_adap
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_80003es2lan:
-+ case e1000_ich8lan:
- return e1000_integrated_phy_loopback(adapter);
- break;
-
-@@ -1229,22 +1413,33 @@ e1000_set_phy_loopback(struct e1000_adap
- static int
- e1000_setup_loopback_test(struct e1000_adapter *adapter)
- {
-+ struct e1000_hw *hw = &adapter->hw;
- uint32_t rctl;
-
-- if(adapter->hw.media_type == e1000_media_type_fiber ||
-- adapter->hw.media_type == e1000_media_type_internal_serdes) {
-- if(adapter->hw.mac_type == e1000_82545 ||
-- adapter->hw.mac_type == e1000_82546 ||
-- adapter->hw.mac_type == e1000_82545_rev_3 ||
-- adapter->hw.mac_type == e1000_82546_rev_3)
-+ if (hw->media_type == e1000_media_type_fiber ||
-+ hw->media_type == e1000_media_type_internal_serdes) {
-+ switch (hw->mac_type) {
-+ case e1000_82545:
-+ case e1000_82546:
-+ case e1000_82545_rev_3:
-+ case e1000_82546_rev_3:
- return e1000_set_phy_loopback(adapter);
-- else {
-- rctl = E1000_READ_REG(&adapter->hw, RCTL);
-+ break;
-+ case e1000_82571:
-+ case e1000_82572:
-+#define E1000_SERDES_LB_ON 0x410
-+ e1000_set_phy_loopback(adapter);
-+ E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_ON);
-+ msec_delay(10);
-+ return 0;
-+ break;
-+ default:
-+ rctl = E1000_READ_REG(hw, RCTL);
- rctl |= E1000_RCTL_LBM_TCVR;
-- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-+ E1000_WRITE_REG(hw, RCTL, rctl);
- return 0;
- }
-- } else if(adapter->hw.media_type == e1000_media_type_copper)
-+ } else if (hw->media_type == e1000_media_type_copper)
- return e1000_set_phy_loopback(adapter);
-
- return 7;
-@@ -1253,27 +1448,42 @@ e1000_setup_loopback_test(struct e1000_a
- static void
- e1000_loopback_cleanup(struct e1000_adapter *adapter)
- {
-+ struct e1000_hw *hw = &adapter->hw;
- uint32_t rctl;
- uint16_t phy_reg;
-
-- rctl = E1000_READ_REG(&adapter->hw, RCTL);
-+ rctl = E1000_READ_REG(hw, RCTL);
- rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
-- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-+ E1000_WRITE_REG(hw, RCTL, rctl);
-
-- if(adapter->hw.media_type == e1000_media_type_copper ||
-- ((adapter->hw.media_type == e1000_media_type_fiber ||
-- adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-- (adapter->hw.mac_type == e1000_82545 ||
-- adapter->hw.mac_type == e1000_82546 ||
-- adapter->hw.mac_type == e1000_82545_rev_3 ||
-- adapter->hw.mac_type == e1000_82546_rev_3))) {
-- adapter->hw.autoneg = TRUE;
-- e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_reg);
-- if(phy_reg & MII_CR_LOOPBACK) {
-+ switch (hw->mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ if (hw->media_type == e1000_media_type_fiber ||
-+ hw->media_type == e1000_media_type_internal_serdes) {
-+#define E1000_SERDES_LB_OFF 0x400
-+ E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF);
-+ msec_delay(10);
-+ break;
-+ }
-+ /* Fall Through */
-+ case e1000_82545:
-+ case e1000_82546:
-+ case e1000_82545_rev_3:
-+ case e1000_82546_rev_3:
-+ default:
-+ hw->autoneg = TRUE;
-+ if (hw->phy_type == e1000_phy_gg82563)
-+ e1000_write_phy_reg(hw,
-+ GG82563_PHY_KMRN_MODE_CTRL,
-+ 0x180);
-+ e1000_read_phy_reg(hw, PHY_CTRL, &phy_reg);
-+ if (phy_reg & MII_CR_LOOPBACK) {
- phy_reg &= ~MII_CR_LOOPBACK;
-- e1000_write_phy_reg(&adapter->hw, PHY_CTRL, phy_reg);
-- e1000_phy_reset(&adapter->hw);
-+ e1000_write_phy_reg(hw, PHY_CTRL, phy_reg);
-+ e1000_phy_reset(hw);
- }
-+ break;
- }
- }
-
-@@ -1281,7 +1491,7 @@ static void
- e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
- {
- memset(skb->data, 0xFF, frame_size);
-- frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
-+ frame_size &= ~1;
- memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
- memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
- memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
-@@ -1290,9 +1500,9 @@ e1000_create_lbtest_frame(struct sk_buff
- static int
- e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size)
- {
-- frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size;
-- if(*(skb->data + 3) == 0xFF) {
-- if((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
-+ frame_size &= ~1;
-+ if (*(skb->data + 3) == 0xFF) {
-+ if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
- (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
- return 0;
- }
-@@ -1303,38 +1513,90 @@ e1000_check_lbtest_frame(struct sk_buff
- static int
- e1000_run_loopback_test(struct e1000_adapter *adapter)
- {
-- struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-- struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
-+ struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
-+ struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
- struct pci_dev *pdev = adapter->pdev;
-- int i;
-+ int i, j, k, l, lc, good_cnt, ret_val=0;
-+ unsigned long time;
-
- E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1);
-
-- for(i = 0; i < 64; i++) {
-- e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024);
-- pci_dma_sync_single(pdev, txdr->buffer_info[i].dma,
-- txdr->buffer_info[i].length,
-- PCI_DMA_TODEVICE);
-- }
-- E1000_WRITE_REG(&adapter->hw, TDT, i);
--
-- msec_delay(200);
-+ /* Calculate the loop count based on the largest descriptor ring
-+ * The idea is to wrap the largest ring a number of times using 64
-+ * send/receive pairs during each loop
-+ */
-
-- pci_dma_sync_single(pdev, rxdr->buffer_info[0].dma,
-- rxdr->buffer_info[0].length, PCI_DMA_FROMDEVICE);
-+ if (rxdr->count <= txdr->count)
-+ lc = ((txdr->count / 64) * 2) + 1;
-+ else
-+ lc = ((rxdr->count / 64) * 2) + 1;
-
-- return e1000_check_lbtest_frame(rxdr->buffer_info[0].skb, 1024);
-+ k = l = 0;
-+ for (j = 0; j <= lc; j++) { /* loop count loop */
-+ for (i = 0; i < 64; i++) { /* send the packets */
-+ e1000_create_lbtest_frame(txdr->buffer_info[i].skb,
-+ 1024);
-+ pci_dma_sync_single_for_device(pdev,
-+ txdr->buffer_info[k].dma,
-+ txdr->buffer_info[k].length,
-+ PCI_DMA_TODEVICE);
-+ if (unlikely(++k == txdr->count)) k = 0;
-+ }
-+ E1000_WRITE_REG(&adapter->hw, TDT, k);
-+ msec_delay(200);
-+ time = jiffies; /* set the start time for the receive */
-+ good_cnt = 0;
-+ do { /* receive the sent packets */
-+ pci_dma_sync_single_for_cpu(pdev,
-+ rxdr->buffer_info[l].dma,
-+ rxdr->buffer_info[l].length,
-+ PCI_DMA_FROMDEVICE);
-+
-+ ret_val = e1000_check_lbtest_frame(
-+ rxdr->buffer_info[l].skb,
-+ 1024);
-+ if (!ret_val)
-+ good_cnt++;
-+ if (unlikely(++l == rxdr->count)) l = 0;
-+ /* time + 20 msecs (200 msecs on 2.4) is more than
-+ * enough time to complete the receives, if it's
-+ * exceeded, break and error off
-+ */
-+ } while (good_cnt < 64 && jiffies < (time + 20));
-+ if (good_cnt != 64) {
-+ ret_val = 13; /* ret_val is the same as mis-compare */
-+ break;
-+ }
-+ if (jiffies >= (time + 2)) {
-+ ret_val = 14; /* error code for time out error */
-+ break;
-+ }
-+ } /* end loop count loop */
-+ return ret_val;
- }
-
- static int
- e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data)
- {
-- if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback;
-- if((*data = e1000_setup_loopback_test(adapter))) goto err_loopback;
-+ /* PHY loopback cannot be performed if SoL/IDER
-+ * sessions are active */
-+ if (e1000_check_phy_reset_block(&adapter->hw)) {
-+ DPRINTK(DRV, ERR, "Cannot do PHY loopback test "
-+ "when SoL/IDER is active.\n");
-+ *data = 0;
-+ goto out;
-+ }
-+
-+ if ((*data = e1000_setup_desc_rings(adapter)))
-+ goto out;
-+ if ((*data = e1000_setup_loopback_test(adapter)))
-+ goto err_loopback;
- *data = e1000_run_loopback_test(adapter);
- e1000_loopback_cleanup(adapter);
-- e1000_free_desc_rings(adapter);
-+
- err_loopback:
-+ e1000_free_desc_rings(adapter);
-+out:
- return *data;
- }
-
-@@ -1342,70 +1604,99 @@ static int
- e1000_link_test(struct e1000_adapter *adapter, uint64_t *data)
- {
- *data = 0;
-- e1000_check_for_link(&adapter->hw);
-+ if (adapter->hw.media_type == e1000_media_type_internal_serdes) {
-+ int i = 0;
-+ adapter->hw.serdes_link_down = TRUE;
-+
-+ /* On some blade server designs, link establishment
-+ * could take as long as 2-3 minutes */
-+ do {
-+ e1000_check_for_link(&adapter->hw);
-+ if (adapter->hw.serdes_link_down == FALSE)
-+ return *data;
-+ msec_delay(20);
-+ } while (i++ < 3750);
-
-- if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
- *data = 1;
-+ } else {
-+ e1000_check_for_link(&adapter->hw);
-+ if (adapter->hw.autoneg) /* if auto_neg is set wait for it */
-+ msec_delay(4000);
-+
-+ if (!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) {
-+ *data = 1;
-+ }
- }
- return *data;
- }
-
--static int
-+static int
- e1000_diag_test_count(struct net_device *netdev)
- {
- return E1000_TEST_LEN;
- }
-
-+extern void e1000_power_up_phy(struct e1000_adapter *);
-+
- static void
--e1000_diag_test(struct net_device *netdev,
-+e1000_diag_test(struct net_device *netdev,
- struct ethtool_test *eth_test, uint64_t *data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- boolean_t if_running = netif_running(netdev);
-
-- if(eth_test->flags == ETH_TEST_FL_OFFLINE) {
-+ set_bit(__E1000_DRIVER_TESTING, &adapter->flags);
-+ if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
- /* Offline tests */
-
- /* save speed, duplex, autoneg settings */
- uint16_t autoneg_advertised = adapter->hw.autoneg_advertised;
-- uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex;
-+ uint8_t forced_speed_duplex = adapter->hw.forced_speed_duplex;
- uint8_t autoneg = adapter->hw.autoneg;
-
-+ DPRINTK(HW, INFO, "offline testing starting\n");
-+
- /* Link test performed before hardware reset so autoneg doesn't
- * interfere with test result */
-- if(e1000_link_test(adapter, &data[4]))
-+ if (e1000_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
-- if(if_running)
-- e1000_down(adapter);
-+ if (if_running)
-+ /* indicate we're in test mode */
-+ dev_close(netdev);
- else
- e1000_reset(adapter);
-
-- if(e1000_reg_test(adapter, &data[0]))
-+ if (e1000_reg_test(adapter, &data[0]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- e1000_reset(adapter);
-- if(e1000_eeprom_test(adapter, &data[1]))
-+ if (e1000_eeprom_test(adapter, &data[1]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- e1000_reset(adapter);
-- if(e1000_intr_test(adapter, &data[2]))
-+ if (e1000_intr_test(adapter, &data[2]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- e1000_reset(adapter);
-- if(e1000_loopback_test(adapter, &data[3]))
-+ /* make sure the phy is powered up */
-+ e1000_power_up_phy(adapter);
-+ if (e1000_loopback_test(adapter, &data[3]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
-- /* restore Autoneg/speed/duplex settings */
-+ /* restore speed, duplex, autoneg settings */
- adapter->hw.autoneg_advertised = autoneg_advertised;
-- adapter->hw.forced_speed_duplex = forced_speed_duplex;
-- adapter->hw.autoneg = autoneg;
-+ adapter->hw.forced_speed_duplex = forced_speed_duplex;
-+ adapter->hw.autoneg = autoneg;
-+
- e1000_reset(adapter);
-- if(if_running)
-- e1000_up(adapter);
-+ clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
-+ if (if_running)
-+ dev_open(netdev);
- } else {
-+ DPRINTK(HW, INFO, "online testing starting\n");
- /* Online tests */
-- if(e1000_link_test(adapter, &data[4]))
-+ if (e1000_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
-
- /* Offline tests aren't run; pass by default */
-@@ -1413,86 +1704,143 @@ e1000_diag_test(struct net_device *netde
- data[1] = 0;
- data[2] = 0;
- data[3] = 0;
-+
-+ clear_bit(__E1000_DRIVER_TESTING, &adapter->flags);
- }
-+ msleep_interruptible(4 * 1000);
- }
-
--static void
--e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-+static int e1000_wol_exclusion(struct e1000_adapter *adapter, struct ethtool_wolinfo *wol)
- {
-- struct e1000_adapter *adapter = netdev->priv;
- struct e1000_hw *hw = &adapter->hw;
-+ int retval = 1; /* fail by default */
-
-- switch(adapter->hw.device_id) {
-- case E1000_DEV_ID_82542:
-+ switch (hw->device_id) {
- case E1000_DEV_ID_82543GC_FIBER:
- case E1000_DEV_ID_82543GC_COPPER:
- case E1000_DEV_ID_82544EI_FIBER:
-+ case E1000_DEV_ID_82546EB_QUAD_COPPER:
-+ case E1000_DEV_ID_82545EM_FIBER:
-+ case E1000_DEV_ID_82545EM_COPPER:
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER:
-+ case E1000_DEV_ID_82546GB_PCIE:
-+ /* these don't support WoL at all */
- wol->supported = 0;
-- wol->wolopts = 0;
-- return;
--
-+ break;
- case E1000_DEV_ID_82546EB_FIBER:
- case E1000_DEV_ID_82546GB_FIBER:
-- /* Wake events only supported on port A for dual fiber */
-- if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
-+ case E1000_DEV_ID_82571EB_FIBER:
-+ case E1000_DEV_ID_82571EB_SERDES:
-+ case E1000_DEV_ID_82571EB_COPPER:
-+ /* Wake events not supported on port B */
-+ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) {
- wol->supported = 0;
-- wol->wolopts = 0;
-- return;
-+ break;
- }
-- /* Fall Through */
--
-+ /* return success for non excluded adapter ports */
-+ retval = 0;
-+ break;
-+ case E1000_DEV_ID_82571EB_QUAD_COPPER:
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
-+ /* quad port adapters only support WoL on port A */
-+ if (!adapter->quad_port_a) {
-+ wol->supported = 0;
-+ break;
-+ }
-+ /* return success for non excluded adapter ports */
-+ retval = 0;
-+ break;
- default:
-- wol->supported = WAKE_UCAST | WAKE_MCAST |
-- WAKE_BCAST | WAKE_MAGIC;
-+ /* dual port cards only support WoL on port A from now on
-+ * unless it was enabled in the eeprom for port B
-+ * so exclude FUNC_1 ports from having WoL enabled */
-+ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1 &&
-+ !adapter->eeprom_wol) {
-+ wol->supported = 0;
-+ break;
-+ }
-
-- wol->wolopts = 0;
-- if(adapter->wol & E1000_WUFC_EX)
-- wol->wolopts |= WAKE_UCAST;
-- if(adapter->wol & E1000_WUFC_MC)
-- wol->wolopts |= WAKE_MCAST;
-- if(adapter->wol & E1000_WUFC_BC)
-- wol->wolopts |= WAKE_BCAST;
-- if(adapter->wol & E1000_WUFC_MAG)
-- wol->wolopts |= WAKE_MAGIC;
-+ retval = 0;
-+ }
-+
-+ return retval;
-+}
-+
-+static void
-+e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
-+{
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+
-+ wol->supported = WAKE_UCAST | WAKE_MCAST |
-+ WAKE_BCAST | WAKE_MAGIC;
-+ wol->wolopts = 0;
-+
-+ /* this function will set ->supported = 0 and return 1 if wol is not
-+ * supported by this hardware */
-+ if (e1000_wol_exclusion(adapter, wol))
- return;
-+
-+ /* apply any specific unsupported masks here */
-+ switch (adapter->hw.device_id) {
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
-+ /* KSP3 does not suppport UCAST wake-ups */
-+ wol->supported &= ~WAKE_UCAST;
-+
-+ if (adapter->wol & E1000_WUFC_EX)
-+ DPRINTK(DRV, ERR, "Interface does not support "
-+ "directed (unicast) frame wake-up packets\n");
-+ break;
-+ default:
-+ break;
- }
-+
-+ if (adapter->wol & E1000_WUFC_EX)
-+ wol->wolopts |= WAKE_UCAST;
-+ if (adapter->wol & E1000_WUFC_MC)
-+ wol->wolopts |= WAKE_MCAST;
-+ if (adapter->wol & E1000_WUFC_BC)
-+ wol->wolopts |= WAKE_BCAST;
-+ if (adapter->wol & E1000_WUFC_MAG)
-+ wol->wolopts |= WAKE_MAGIC;
-+
-+ return;
- }
-
- static int
- e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-
-- switch(adapter->hw.device_id) {
-- case E1000_DEV_ID_82542:
-- case E1000_DEV_ID_82543GC_FIBER:
-- case E1000_DEV_ID_82543GC_COPPER:
-- case E1000_DEV_ID_82544EI_FIBER:
-- return wol->wolopts ? -EOPNOTSUPP : 0;
-+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
-+ return -EOPNOTSUPP;
-
-- case E1000_DEV_ID_82546EB_FIBER:
-- case E1000_DEV_ID_82546GB_FIBER:
-- /* Wake events only supported on port A for dual fiber */
-- if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
-- return wol->wolopts ? -EOPNOTSUPP : 0;
-- /* Fall Through */
-+ if (e1000_wol_exclusion(adapter, wol))
-+ return wol->wolopts ? -EOPNOTSUPP : 0;
-
-- default:
-- if(wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
-+ switch (hw->device_id) {
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
-+ if (wol->wolopts & WAKE_UCAST) {
-+ DPRINTK(DRV, ERR, "Interface does not support "
-+ "directed (unicast) frame wake-up packets\n");
- return -EOPNOTSUPP;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-
-- adapter->wol = 0;
-+ /* these settings will always override what we currently have */
-+ adapter->wol = 0;
-
-- if(wol->wolopts & WAKE_UCAST)
-- adapter->wol |= E1000_WUFC_EX;
-- if(wol->wolopts & WAKE_MCAST)
-- adapter->wol |= E1000_WUFC_MC;
-- if(wol->wolopts & WAKE_BCAST)
-- adapter->wol |= E1000_WUFC_BC;
-- if(wol->wolopts & WAKE_MAGIC)
-- adapter->wol |= E1000_WUFC_MAG;
-- }
-+ if (wol->wolopts & WAKE_UCAST)
-+ adapter->wol |= E1000_WUFC_EX;
-+ if (wol->wolopts & WAKE_MCAST)
-+ adapter->wol |= E1000_WUFC_MC;
-+ if (wol->wolopts & WAKE_BCAST)
-+ adapter->wol |= E1000_WUFC_BC;
-+ if (wol->wolopts & WAKE_MAGIC)
-+ adapter->wol |= E1000_WUFC_MAG;
-
- return 0;
- }
-@@ -1508,7 +1856,7 @@ e1000_led_blink_callback(unsigned long d
- {
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-
-- if(test_and_change_bit(E1000_LED_ON, &adapter->led_status))
-+ if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
- e1000_led_off(&adapter->hw);
- else
- e1000_led_on(&adapter->hw);
-@@ -1519,24 +1867,36 @@ e1000_led_blink_callback(unsigned long d
- static int
- e1000_phys_id(struct net_device *netdev, uint32_t data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
-- if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
-+ if (!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
- data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
-
-- if(!adapter->blink_timer.function) {
-- init_timer(&adapter->blink_timer);
-- adapter->blink_timer.function = e1000_led_blink_callback;
-- adapter->blink_timer.data = (unsigned long) adapter;
-+ if (adapter->hw.mac_type < e1000_82571) {
-+ if (!adapter->blink_timer.function) {
-+ init_timer(&adapter->blink_timer);
-+ adapter->blink_timer.function = e1000_led_blink_callback;
-+ adapter->blink_timer.data = (unsigned long) adapter;
-+ }
-+ e1000_setup_led(&adapter->hw);
-+ mod_timer(&adapter->blink_timer, jiffies);
-+ msleep_interruptible(data * 1000);
-+ del_timer_sync(&adapter->blink_timer);
-+ } else if (adapter->hw.phy_type == e1000_phy_ife) {
-+ if (!adapter->blink_timer.function) {
-+ init_timer(&adapter->blink_timer);
-+ adapter->blink_timer.function = e1000_led_blink_callback;
-+ adapter->blink_timer.data = (unsigned long) adapter;
-+ }
-+ mod_timer(&adapter->blink_timer, jiffies);
-+ msleep_interruptible(data * 1000);
-+ del_timer_sync(&adapter->blink_timer);
-+ e1000_write_phy_reg(&(adapter->hw), IFE_PHY_SPECIAL_CONTROL_LED, 0);
-+ } else {
-+ e1000_blink_led_start(&adapter->hw);
-+ msleep_interruptible(data * 1000);
- }
-
-- e1000_setup_led(&adapter->hw);
-- mod_timer(&adapter->blink_timer, jiffies);
--
-- set_current_state(TASK_INTERRUPTIBLE);
--
-- schedule_timeout(data * HZ);
-- del_timer_sync(&adapter->blink_timer);
- e1000_led_off(&adapter->hw);
- clear_bit(E1000_LED_ON, &adapter->led_status);
- e1000_cleanup_led(&adapter->hw);
-@@ -1547,56 +1907,57 @@ e1000_phys_id(struct net_device *netdev,
- static int
- e1000_nway_reset(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-- if(netif_running(netdev)) {
-- e1000_down(adapter);
-- e1000_up(adapter);
-- }
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+ if (netif_running(netdev))
-+ e1000_reinit_locked(adapter);
- return 0;
- }
-
--static int
-+static int
- e1000_get_stats_count(struct net_device *netdev)
- {
- return E1000_STATS_LEN;
- }
-
--static void
--e1000_get_ethtool_stats(struct net_device *netdev,
-+static void
-+e1000_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, uint64_t *data)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- int i;
-
- e1000_update_stats(adapter);
-- for(i = 0; i < E1000_STATS_LEN; i++) {
-- char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
-- data[i] = (e1000_gstrings_stats[i].sizeof_stat == sizeof(uint64_t))
-- ? *(uint64_t *)p : *(uint32_t *)p;
-+ for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
-+ char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset;
-+ data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
-+ sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p;
- }
-+/* BUG_ON(i != E1000_STATS_LEN); */
- }
-
--static void
-+static void
- e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
- {
-+ uint8_t *p = data;
- int i;
-
-- switch(stringset) {
-+ switch (stringset) {
- case ETH_SS_TEST:
-- memcpy(data, *e1000_gstrings_test,
-+ memcpy(data, *e1000_gstrings_test,
- E1000_TEST_LEN*ETH_GSTRING_LEN);
- break;
- case ETH_SS_STATS:
-- for (i=0; i < E1000_STATS_LEN; i++) {
-- memcpy(data + i * ETH_GSTRING_LEN,
-- e1000_gstrings_stats[i].stat_string,
-- ETH_GSTRING_LEN);
-+ for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
-+ memcpy(p, e1000_gstrings_stats[i].stat_string,
-+ ETH_GSTRING_LEN);
-+ p += ETH_GSTRING_LEN;
- }
-+/* BUG_ON(p - data != E1000_STATS_LEN * ETH_GSTRING_LEN); */
- break;
- }
- }
-
--struct ethtool_ops e1000_ethtool_ops = {
-+static struct ethtool_ops e1000_ethtool_ops = {
- .get_settings = e1000_get_settings,
- .set_settings = e1000_set_settings,
- .get_drvinfo = e1000_get_drvinfo,
-@@ -1617,7 +1978,7 @@ struct ethtool_ops e1000_ethtool_ops = {
- .set_pauseparam = e1000_set_pauseparam,
- .get_rx_csum = e1000_get_rx_csum,
- .set_rx_csum = e1000_set_rx_csum,
-- .get_tx_csum = e1000_get_tx_csum,
-+ .get_tx_csum = e1000_get_tx_csum,
- .set_tx_csum = e1000_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
-@@ -1631,9 +1992,13 @@ struct ethtool_ops e1000_ethtool_ops = {
- .phys_id = e1000_phys_id,
- .get_stats_count = e1000_get_stats_count,
- .get_ethtool_stats = e1000_get_ethtool_stats,
-+#ifdef ETHTOOL_GPERMADDR
-+ .get_perm_addr = ethtool_op_get_perm_addr,
-+#endif
- };
-
--void set_ethtool_ops(struct net_device *netdev)
-+void e1000_set_ethtool_ops(struct net_device *netdev)
- {
- SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
- }
-+#endif /* SIOCETHTOOL */
-diff -pruN ./drivers/net/e1000.orig/e1000.h ./drivers/net/e1000/e1000.h
---- ./drivers/net/e1000.orig/e1000.h 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000.h 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -49,11 +50,11 @@
- #include <linux/delay.h>
- #include <linux/timer.h>
- #include <linux/slab.h>
-+#include <linux/vmalloc.h>
- #include <linux/interrupt.h>
- #include <linux/string.h>
- #include <linux/pagemap.h>
--#include <linux/dma-mapping.h>
--#include <asm/bitops.h>
-+#include <linux/bitops.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <linux/capability.h>
-@@ -67,16 +68,23 @@
- #ifdef NETIF_F_TSO
- #include <net/checksum.h>
- #endif
--#include <linux/workqueue.h>
-+#ifdef SIOCGMIIPHY
- #include <linux/mii.h>
-+#endif
-+#ifdef SIOCETHTOOL
- #include <linux/ethtool.h>
-+#endif
-+#ifdef NETIF_F_HW_VLAN_TX
- #include <linux/if_vlan.h>
--#include <linux/moduleparam.h>
-+#endif
-
- #define BAR_0 0
- #define BAR_1 1
- #define BAR_5 5
-
-+#include "kcompat.h"
-+#define INTEL_E1000_ETHERNET_DEVICE(device_id) {\
-+ PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
-
- struct e1000_adapter;
-
-@@ -98,17 +106,25 @@ struct e1000_adapter;
-
- #define E1000_MAX_INTR 10
-
--/* How many descriptors for TX and RX ? */
-+/* TX/RX descriptor defines */
- #define E1000_DEFAULT_TXD 256
- #define E1000_MAX_TXD 256
- #define E1000_MIN_TXD 80
- #define E1000_MAX_82544_TXD 4096
-+
- #define E1000_DEFAULT_RXD 256
- #define E1000_MAX_RXD 256
- #define E1000_MIN_RXD 80
- #define E1000_MAX_82544_RXD 4096
-
-+/* this is the size past which hardware will drop packets when setting LPE=0 */
-+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
-+
- /* Supported Rx Buffer Sizes */
-+#define E1000_RXBUFFER_128 128 /* Used for packet split */
-+#define E1000_RXBUFFER_256 256 /* Used for packet split */
-+#define E1000_RXBUFFER_512 512
-+#define E1000_RXBUFFER_1024 1024
- #define E1000_RXBUFFER_2048 2048
- #define E1000_RXBUFFER_4096 4096
- #define E1000_RXBUFFER_8192 8192
-@@ -123,28 +139,33 @@ struct e1000_adapter;
- #define E1000_TX_HEAD_ADDR_SHIFT 7
- #define E1000_PBA_TX_MASK 0xFFFF0000
-
--/* Flow Control High-Watermark: 5688 bytes below Rx FIFO size */
--#define E1000_FC_HIGH_DIFF 0x1638
--
--/* Flow Control Low-Watermark: 5696 bytes below Rx FIFO size */
--#define E1000_FC_LOW_DIFF 0x1640
-+/* Flow Control Watermarks */
-+#define E1000_FC_HIGH_DIFF 0x1638 /* High: 5688 bytes below Rx FIFO size */
-+#define E1000_FC_LOW_DIFF 0x1640 /* Low: 5696 bytes below Rx FIFO size */
-
--/* Flow Control Pause Time: 858 usec */
--#define E1000_FC_PAUSE_TIME 0x0680
-+#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */
-
- /* How many Tx Descriptors do we need to call netif_wake_queue ? */
- #define E1000_TX_QUEUE_WAKE 16
- /* How many Rx Buffers do we bundle into one write to the hardware ? */
- #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */
-
--#define AUTO_ALL_MODES 0
--#define E1000_EEPROM_APME 0x0400
-+#define AUTO_ALL_MODES 0
-+#define E1000_EEPROM_82544_APM 0x0004
-+#define E1000_EEPROM_ICH8_APME 0x0004
-+#define E1000_EEPROM_APME 0x0400
-
- #ifndef E1000_MASTER_SLAVE
- /* Switch to override PHY master/slave setting */
- #define E1000_MASTER_SLAVE e1000_ms_hw_default
- #endif
-
-+#ifdef NETIF_F_HW_VLAN_TX
-+#define E1000_MNG_VLAN_NONE -1
-+#endif
-+/* Number of packet split data buffers (not including the header buffer) */
-+#define PS_PAGE_BUFFERS MAX_PS_BUFFERS-1
-+
- /* only works for sizes that are powers of 2 */
- #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1)))
-
-@@ -152,13 +173,39 @@ struct e1000_adapter;
- * so a DMA handle can be stored along with the buffer */
- struct e1000_buffer {
- struct sk_buff *skb;
-- uint64_t dma;
-- unsigned long length;
-+ dma_addr_t dma;
- unsigned long time_stamp;
-- unsigned int next_to_watch;
-+ uint16_t length;
-+ uint16_t next_to_watch;
-+};
-+
-+
-+struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
-+struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
-+
-+struct e1000_tx_ring {
-+ /* pointer to the descriptor ring memory */
-+ void *desc;
-+ /* physical address of the descriptor ring */
-+ dma_addr_t dma;
-+ /* length of descriptor ring in bytes */
-+ unsigned int size;
-+ /* number of descriptors in the ring */
-+ unsigned int count;
-+ /* next descriptor to associate a buffer with */
-+ unsigned int next_to_use;
-+ /* next descriptor to check for DD status bit */
-+ unsigned int next_to_clean;
-+ /* array of buffer information structs */
-+ struct e1000_buffer *buffer_info;
-+
-+ spinlock_t tx_lock;
-+ uint16_t tdh;
-+ uint16_t tdt;
-+ boolean_t last_tx_tso;
- };
-
--struct e1000_desc_ring {
-+struct e1000_rx_ring {
- /* pointer to the descriptor ring memory */
- void *desc;
- /* physical address of the descriptor ring */
-@@ -173,12 +220,25 @@ struct e1000_desc_ring {
- unsigned int next_to_clean;
- /* array of buffer information structs */
- struct e1000_buffer *buffer_info;
-+ /* arrays of page information for packet split */
-+ struct e1000_ps_page *ps_page;
-+ struct e1000_ps_page_dma *ps_page_dma;
-+
-+ /* cpu for rx queue */
-+ int cpu;
-+
-+ uint16_t rdh;
-+ uint16_t rdt;
- };
-
- #define E1000_DESC_UNUSED(R) \
- ((((R)->next_to_clean > (R)->next_to_use) ? 0 : (R)->count) + \
- (R)->next_to_clean - (R)->next_to_use - 1)
-
-+#define E1000_RX_DESC_PS(R, i) \
-+ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
-+#define E1000_RX_DESC_EXT(R, i) \
-+ (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
- #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i]))
- #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc)
- #define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc)
-@@ -190,26 +250,33 @@ struct e1000_adapter {
- struct timer_list tx_fifo_stall_timer;
- struct timer_list watchdog_timer;
- struct timer_list phy_info_timer;
-+#ifdef NETIF_F_HW_VLAN_TX
- struct vlan_group *vlgrp;
-+ uint16_t mng_vlan_id;
-+#endif
- uint32_t bd_number;
- uint32_t rx_buffer_len;
-- uint32_t part_num;
- uint32_t wol;
- uint32_t smartspeed;
- uint32_t en_mng_pt;
- uint16_t link_speed;
- uint16_t link_duplex;
- spinlock_t stats_lock;
-+#ifdef CONFIG_E1000_NAPI
-+ spinlock_t tx_queue_lock;
-+#endif
- atomic_t irq_sem;
-- struct work_struct tx_timeout_task;
-- uint8_t fc_autoneg;
-+ struct work_struct reset_task;
-+ uint8_t fc_autoneg;
-
-+#ifdef ETHTOOL_PHYS_ID
- struct timer_list blink_timer;
- unsigned long led_status;
-+#endif
-
- /* TX */
-- struct e1000_desc_ring tx_ring;
-- spinlock_t tx_lock;
-+ struct e1000_tx_ring *tx_ring; /* One per active queue */
-+ unsigned long tx_queue_len;
- uint32_t txd_cmd;
- uint32_t tx_int_delay;
- uint32_t tx_abs_int_delay;
-@@ -217,21 +284,45 @@ struct e1000_adapter {
- uint64_t gotcl_old;
- uint64_t tpt_old;
- uint64_t colc_old;
-+ uint32_t tx_timeout_count;
- uint32_t tx_fifo_head;
- uint32_t tx_head_addr;
- uint32_t tx_fifo_size;
-+ uint8_t tx_timeout_factor;
- atomic_t tx_fifo_stall;
- boolean_t pcix_82544;
-+ boolean_t detect_tx_hung;
-
- /* RX */
-- struct e1000_desc_ring rx_ring;
-+#ifdef CONFIG_E1000_NAPI
-+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int *work_done, int work_to_do);
-+#else
-+ boolean_t (*clean_rx) (struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring);
-+#endif
-+ void (*alloc_rx_buf) (struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int cleaned_count);
-+ struct e1000_rx_ring *rx_ring; /* One per active queue */
-+#ifdef CONFIG_E1000_NAPI
-+ struct net_device *polling_netdev; /* One per active queue */
-+#endif
-+ int num_tx_queues;
-+ int num_rx_queues;
-+
- uint64_t hw_csum_err;
- uint64_t hw_csum_good;
-+ uint64_t rx_hdr_split;
-+ uint32_t alloc_rx_buff_failed;
- uint32_t rx_int_delay;
- uint32_t rx_abs_int_delay;
- boolean_t rx_csum;
-+ unsigned int rx_ps_pages;
- uint32_t gorcl;
- uint64_t gorcl_old;
-+ uint16_t rx_ps_bsize0;
-
- /* Interrupt Throttle Rate */
- uint32_t itr;
-@@ -247,12 +338,42 @@ struct e1000_adapter {
- struct e1000_phy_info phy_info;
- struct e1000_phy_stats phy_stats;
-
-+#ifdef ETHTOOL_TEST
- uint32_t test_icr;
-- struct e1000_desc_ring test_tx_ring;
-- struct e1000_desc_ring test_rx_ring;
-+ struct e1000_tx_ring test_tx_ring;
-+ struct e1000_rx_ring test_rx_ring;
-+#endif
-
-+#ifdef E1000_COUNT_ICR
-+ uint64_t icr_txdw;
-+ uint64_t icr_txqe;
-+ uint64_t icr_lsc;
-+ uint64_t icr_rxseq;
-+ uint64_t icr_rxdmt;
-+ uint64_t icr_rxo;
-+ uint64_t icr_rxt;
-+ uint64_t icr_mdac;
-+ uint64_t icr_rxcfg;
-+ uint64_t icr_gpi;
-+#endif
-
-- uint32_t pci_state[16];
-+ uint32_t *config_space;
- int msg_enable;
-+#ifdef CONFIG_PCI_MSI
-+ boolean_t have_msi;
-+#endif
-+ /* to not mess up cache alignment, always add to the bottom */
-+#ifdef NETIF_F_TSO
-+ boolean_t tso_force;
-+#endif
-+ boolean_t smart_power_down; /* phy smart power down */
-+ boolean_t quad_port_a;
-+ unsigned long flags;
-+ uint32_t eeprom_wol;
-+};
-+
-+enum e1000_state_t {
-+ __E1000_DRIVER_TESTING,
-+ __E1000_RESETTING,
- };
- #endif /* _E1000_H_ */
-diff -pruN ./drivers/net/e1000.orig/e1000_hw.c ./drivers/net/e1000/e1000_hw.c
---- ./drivers/net/e1000.orig/e1000_hw.c 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_hw.c 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -30,6 +31,7 @@
- * Shared functions for accessing and configuring the MAC
- */
-
-+
- #include "e1000_hw.h"
-
- static int32_t e1000_set_phy_type(struct e1000_hw *hw);
-@@ -63,9 +65,14 @@ static uint16_t e1000_shift_in_ee_bits(s
- static int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
- static void e1000_release_eeprom(struct e1000_hw *hw);
- static void e1000_standby_eeprom(struct e1000_hw *hw);
--static int32_t e1000_id_led_init(struct e1000_hw * hw);
- static int32_t e1000_set_vco_speed(struct e1000_hw *hw);
-+static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw);
- static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
-+static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
-+static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
-+static int32_t e1000_configure_kmrn_for_10_100(struct e1000_hw *hw,
-+ uint16_t duplex);
-+static int32_t e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
-
- /* IGP cable length table */
- static const
-@@ -79,6 +86,17 @@ uint16_t e1000_igp_cable_length_table[IG
- 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
- 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120};
-
-+static const
-+uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
-+ { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
-+ 0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
-+ 6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
-+ 21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
-+ 40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
-+ 60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
-+ 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
-+ 104, 109, 114, 118, 121, 124};
-+
-
- /******************************************************************************
- * Set the phy type member in the hw struct.
-@@ -90,20 +108,37 @@ e1000_set_phy_type(struct e1000_hw *hw)
- {
- DEBUGFUNC("e1000_set_phy_type");
-
-- switch(hw->phy_id) {
-+ if (hw->mac_type == e1000_undefined)
-+ return -E1000_ERR_PHY_TYPE;
-+
-+ switch (hw->phy_id) {
- case M88E1000_E_PHY_ID:
- case M88E1000_I_PHY_ID:
- case M88E1011_I_PHY_ID:
-+ case M88E1111_I_PHY_ID:
- hw->phy_type = e1000_phy_m88;
- break;
- case IGP01E1000_I_PHY_ID:
-- if(hw->mac_type == e1000_82541 ||
-- hw->mac_type == e1000_82541_rev_2 ||
-- hw->mac_type == e1000_82547 ||
-- hw->mac_type == e1000_82547_rev_2) {
-+ if (hw->mac_type == e1000_82541 ||
-+ hw->mac_type == e1000_82541_rev_2 ||
-+ hw->mac_type == e1000_82547 ||
-+ hw->mac_type == e1000_82547_rev_2) {
- hw->phy_type = e1000_phy_igp;
- break;
- }
-+ case IGP03E1000_E_PHY_ID:
-+ hw->phy_type = e1000_phy_igp_3;
-+ break;
-+ case IFE_E_PHY_ID:
-+ case IFE_PLUS_E_PHY_ID:
-+ case IFE_C_E_PHY_ID:
-+ hw->phy_type = e1000_phy_ife;
-+ break;
-+ case GG82563_E_PHY_ID:
-+ if (hw->mac_type == e1000_80003es2lan) {
-+ hw->phy_type = e1000_phy_gg82563;
-+ break;
-+ }
- /* Fall Through */
- default:
- /* Should never have loaded on this device */
-@@ -114,6 +149,7 @@ e1000_set_phy_type(struct e1000_hw *hw)
- return E1000_SUCCESS;
- }
-
-+
- /******************************************************************************
- * IGP phy init script - initializes the GbE PHY
- *
-@@ -122,16 +158,30 @@ e1000_set_phy_type(struct e1000_hw *hw)
- static void
- e1000_phy_init_script(struct e1000_hw *hw)
- {
-+ uint32_t ret_val;
-+ uint16_t phy_saved_data;
-+
- DEBUGFUNC("e1000_phy_init_script");
-
-- if(hw->phy_init_script) {
-+ if (hw->phy_init_script) {
-+ msec_delay(20);
-+
-+ /* Save off the current value of register 0x2F5B to be restored at
-+ * the end of this routine. */
-+ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-+
-+ /* Disabled the PHY transmitter */
-+ e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-+
- msec_delay(20);
-
- e1000_write_phy_reg(hw,0x0000,0x0140);
-
- msec_delay(5);
-
-- if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
-+ switch (hw->mac_type) {
-+ case e1000_82541:
-+ case e1000_82547:
- e1000_write_phy_reg(hw, 0x1F95, 0x0001);
-
- e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
-@@ -149,28 +199,39 @@ e1000_phy_init_script(struct e1000_hw *h
- e1000_write_phy_reg(hw, 0x1F96, 0x003F);
-
- e1000_write_phy_reg(hw, 0x2010, 0x0008);
-- } else {
-+ break;
-+
-+ case e1000_82541_rev_2:
-+ case e1000_82547_rev_2:
- e1000_write_phy_reg(hw, 0x1F73, 0x0099);
-+ break;
-+ default:
-+ break;
- }
-
- e1000_write_phy_reg(hw, 0x0000, 0x3300);
-
-- if(hw->mac_type == e1000_82547) {
-+ msec_delay(20);
-+
-+ /* Now enable the transmitter */
-+ e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-+
-+ if (hw->mac_type == e1000_82547) {
- uint16_t fused, fine, coarse;
-
- /* Move to analog registers page */
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
-
-- if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
-+ if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
- e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused);
-
- fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
- coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK;
-
-- if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
-+ if (coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
- coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10;
- fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
-- } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
-+ } else if (coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
- fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
-
- fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) |
-@@ -243,29 +304,77 @@ e1000_set_mac_type(struct e1000_hw *hw)
- case E1000_DEV_ID_82546GB_COPPER:
- case E1000_DEV_ID_82546GB_FIBER:
- case E1000_DEV_ID_82546GB_SERDES:
-+ case E1000_DEV_ID_82546GB_PCIE:
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER:
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
- hw->mac_type = e1000_82546_rev_3;
- break;
- case E1000_DEV_ID_82541EI:
- case E1000_DEV_ID_82541EI_MOBILE:
-+ case E1000_DEV_ID_82541ER_LOM:
- hw->mac_type = e1000_82541;
- break;
- case E1000_DEV_ID_82541ER:
- case E1000_DEV_ID_82541GI:
-+ case E1000_DEV_ID_82541GI_LF:
- case E1000_DEV_ID_82541GI_MOBILE:
- hw->mac_type = e1000_82541_rev_2;
- break;
- case E1000_DEV_ID_82547EI:
-+ case E1000_DEV_ID_82547EI_MOBILE:
- hw->mac_type = e1000_82547;
- break;
- case E1000_DEV_ID_82547GI:
- hw->mac_type = e1000_82547_rev_2;
- break;
-+ case E1000_DEV_ID_82571EB_COPPER:
-+ case E1000_DEV_ID_82571EB_FIBER:
-+ case E1000_DEV_ID_82571EB_SERDES:
-+ case E1000_DEV_ID_82571EB_QUAD_COPPER:
-+ hw->mac_type = e1000_82571;
-+ break;
-+ case E1000_DEV_ID_82572EI_COPPER:
-+ case E1000_DEV_ID_82572EI_FIBER:
-+ case E1000_DEV_ID_82572EI_SERDES:
-+ case E1000_DEV_ID_82572EI:
-+ hw->mac_type = e1000_82572;
-+ break;
-+ case E1000_DEV_ID_82573E:
-+ case E1000_DEV_ID_82573E_IAMT:
-+ case E1000_DEV_ID_82573L:
-+ hw->mac_type = e1000_82573;
-+ break;
-+ case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
-+ case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
-+ case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
-+ case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
-+ hw->mac_type = e1000_80003es2lan;
-+ break;
-+ case E1000_DEV_ID_ICH8_IGP_M_AMT:
-+ case E1000_DEV_ID_ICH8_IGP_AMT:
-+ case E1000_DEV_ID_ICH8_IGP_C:
-+ case E1000_DEV_ID_ICH8_IFE:
-+ case E1000_DEV_ID_ICH8_IGP_M:
-+ hw->mac_type = e1000_ich8lan;
-+ break;
- default:
- /* Should never have loaded on this device */
- return -E1000_ERR_MAC_TYPE;
- }
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
-+ case e1000_ich8lan:
-+ hw->swfwhw_semaphore_present = TRUE;
-+ hw->asf_firmware_present = TRUE;
-+ break;
-+ case e1000_80003es2lan:
-+ hw->swfw_sync_present = TRUE;
-+ /* fall through */
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ hw->eeprom_semaphore_present = TRUE;
-+ /* fall through */
- case e1000_82541:
- case e1000_82547:
- case e1000_82541_rev_2:
-@@ -291,7 +400,7 @@ e1000_set_media_type(struct e1000_hw *hw
-
- DEBUGFUNC("e1000_set_media_type");
-
-- if(hw->mac_type != e1000_82543) {
-+ if (hw->mac_type != e1000_82543) {
- /* tbi_compatibility is only valid on 82543 */
- hw->tbi_compatibility_en = FALSE;
- }
-@@ -299,21 +408,34 @@ e1000_set_media_type(struct e1000_hw *hw
- switch (hw->device_id) {
- case E1000_DEV_ID_82545GM_SERDES:
- case E1000_DEV_ID_82546GB_SERDES:
-+ case E1000_DEV_ID_82571EB_SERDES:
-+ case E1000_DEV_ID_82572EI_SERDES:
-+ case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
- hw->media_type = e1000_media_type_internal_serdes;
- break;
- default:
-- if(hw->mac_type >= e1000_82543) {
-+ switch (hw->mac_type) {
-+ case e1000_82542_rev2_0:
-+ case e1000_82542_rev2_1:
-+ hw->media_type = e1000_media_type_fiber;
-+ break;
-+ case e1000_ich8lan:
-+ case e1000_82573:
-+ /* The STATUS_TBIMODE bit is reserved or reused for the this
-+ * device.
-+ */
-+ hw->media_type = e1000_media_type_copper;
-+ break;
-+ default:
- status = E1000_READ_REG(hw, STATUS);
-- if(status & E1000_STATUS_TBIMODE) {
-+ if (status & E1000_STATUS_TBIMODE) {
- hw->media_type = e1000_media_type_fiber;
- /* tbi_compatibility not valid on fiber */
- hw->tbi_compatibility_en = FALSE;
- } else {
- hw->media_type = e1000_media_type_copper;
- }
-- } else {
-- /* This is an 82542 (fiber only) */
-- hw->media_type = e1000_media_type_fiber;
-+ break;
- }
- }
- }
-@@ -331,15 +453,27 @@ e1000_reset_hw(struct e1000_hw *hw)
- uint32_t icr;
- uint32_t manc;
- uint32_t led_ctrl;
-+ uint32_t timeout;
-+ uint32_t extcnf_ctrl;
-+ int32_t ret_val;
-
- DEBUGFUNC("e1000_reset_hw");
-
- /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
-- if(hw->mac_type == e1000_82542_rev2_0) {
-+ if (hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- }
-
-+ if (hw->bus_type == e1000_bus_type_pci_express) {
-+ /* Prevent the PCI-E bus from sticking if there is no TLP connection
-+ * on the last TLP read/write transaction when MAC is reset.
-+ */
-+ if (e1000_disable_pciex_master(hw) != E1000_SUCCESS) {
-+ DEBUGOUT("PCI-E Master disable polling has failed.\n");
-+ }
-+ }
-+
- /* Clear interrupt mask to stop board from generating interrupts */
- DEBUGOUT("Masking off all interrupts\n");
- E1000_WRITE_REG(hw, IMC, 0xffffffff);
-@@ -363,11 +497,41 @@ e1000_reset_hw(struct e1000_hw *hw)
- ctrl = E1000_READ_REG(hw, CTRL);
-
- /* Must reset the PHY before resetting the MAC */
-- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-- E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
-+ if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-+ E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
- msec_delay(5);
- }
-
-+ /* Must acquire the MDIO ownership before MAC reset.
-+ * Ownership defaults to firmware after a reset. */
-+ if (hw->mac_type == e1000_82573) {
-+ timeout = 10;
-+
-+ extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
-+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-+
-+ do {
-+ E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
-+ extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
-+
-+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
-+ break;
-+ else
-+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
-+
-+ msec_delay(2);
-+ timeout--;
-+ } while (timeout);
-+ }
-+
-+ /* Workaround for ICH8 bit corruption issue in FIFO memory */
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /* Set Tx and Rx buffer allocation to 8k apiece. */
-+ E1000_WRITE_REG(hw, PBA, E1000_PBA_8K);
-+ /* Set Packet Buffer Size to 16k. */
-+ E1000_WRITE_REG(hw, PBS, E1000_PBS_16K);
-+ }
-+
- /* Issue a global reset to the MAC. This will reset the chip's
- * transmit, receive, DMA, and link units. It will not effect
- * the current PCI configuration. The global reset bit is self-
-@@ -375,7 +539,7 @@ e1000_reset_hw(struct e1000_hw *hw)
- */
- DEBUGOUT("Issuing a global reset to MAC\n");
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82544:
- case e1000_82540:
- case e1000_82545:
-@@ -391,6 +555,20 @@ e1000_reset_hw(struct e1000_hw *hw)
- /* Reset is performed on a shadow of the control register */
- E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
- break;
-+ case e1000_ich8lan:
-+ if (!hw->phy_reset_disable &&
-+ e1000_check_phy_reset_block(hw) == E1000_SUCCESS) {
-+ /* e1000_ich8lan PHY HW reset requires MAC CORE reset
-+ * at the same time to make sure the interface between
-+ * MAC and the external PHY is reset.
-+ */
-+ ctrl |= E1000_CTRL_PHY_RST;
-+ }
-+
-+ e1000_get_software_flag(hw);
-+ E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
-+ msec_delay(5);
-+ break;
- default:
- E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
- break;
-@@ -400,13 +578,13 @@ e1000_reset_hw(struct e1000_hw *hw)
- * device. Later controllers reload the EEPROM automatically, so just wait
- * for reload to complete.
- */
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- case e1000_82544:
- /* Wait for reset to complete */
-- udelay(10);
-+ usec_delay(10);
- ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_EE_RST;
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-@@ -421,6 +599,24 @@ e1000_reset_hw(struct e1000_hw *hw)
- /* Wait for EEPROM reload */
- msec_delay(20);
- break;
-+ case e1000_82573:
-+ if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
-+ usec_delay(10);
-+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-+ ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-+ E1000_WRITE_FLUSH(hw);
-+ }
-+ /* fall through */
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_ich8lan:
-+ case e1000_80003es2lan:
-+ ret_val = e1000_get_auto_rd_done(hw);
-+ if (ret_val)
-+ /* We don't want to continue accessing MAC registers. */
-+ return ret_val;
-+ break;
- default:
- /* Wait for EEPROM reload (it happens automatically) */
- msec_delay(5);
-@@ -428,13 +624,13 @@ e1000_reset_hw(struct e1000_hw *hw)
- }
-
- /* Disable HW ARPs on ASF enabled adapters */
-- if(hw->mac_type >= e1000_82540) {
-+ if (hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) {
- manc = E1000_READ_REG(hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(hw, MANC, manc);
- }
-
-- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-+ if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- e1000_phy_init_script(hw);
-
- /* Configure activity LED after PHY reset */
-@@ -452,11 +648,17 @@ e1000_reset_hw(struct e1000_hw *hw)
- icr = E1000_READ_REG(hw, ICR);
-
- /* If MWI was previously enabled, reenable it. */
-- if(hw->mac_type == e1000_82542_rev2_0) {
-- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-+ if (hw->mac_type == e1000_82542_rev2_0) {
-+ if (hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
- e1000_pci_set_mwi(hw);
- }
-
-+ if (hw->mac_type == e1000_ich8lan) {
-+ uint32_t kab = E1000_READ_REG(hw, KABGTXD);
-+ kab |= E1000_KABGTXD_BGSQLBIAS;
-+ E1000_WRITE_REG(hw, KABGTXD, kab);
-+ }
-+
- return E1000_SUCCESS;
- }
-
-@@ -481,11 +683,25 @@ e1000_init_hw(struct e1000_hw *hw)
- uint16_t pcix_stat_hi_word;
- uint16_t cmd_mmrbc;
- uint16_t stat_mmrbc;
-+ uint32_t mta_size;
-+ uint32_t reg_data;
-+ uint32_t ctrl_ext;
-+
- DEBUGFUNC("e1000_init_hw");
-
-+ if (hw->mac_type == e1000_ich8lan) {
-+ reg_data = E1000_READ_REG(hw, TARC0);
-+ reg_data |= 0x30000000;
-+ E1000_WRITE_REG(hw, TARC0, reg_data);
-+
-+ reg_data = E1000_READ_REG(hw, STATUS);
-+ reg_data &= ~0x80000000;
-+ E1000_WRITE_REG(hw, STATUS, reg_data);
-+ }
-+
- /* Initialize Identification LED */
- ret_val = e1000_id_led_init(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error Initializing Identification LED\n");
- return ret_val;
- }
-@@ -495,12 +711,15 @@ e1000_init_hw(struct e1000_hw *hw)
-
- /* Disabling VLAN filtering. */
- DEBUGOUT("Initializing the IEEE VLAN\n");
-- E1000_WRITE_REG(hw, VET, 0);
--
-- e1000_clear_vfta(hw);
-+ /* VET hardcoded to standard value and VFTA removed in ICH8 LAN */
-+ if (hw->mac_type != e1000_ich8lan) {
-+ if (hw->mac_type < e1000_82545_rev_3)
-+ E1000_WRITE_REG(hw, VET, 0);
-+ e1000_clear_vfta(hw);
-+ }
-
- /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
-- if(hw->mac_type == e1000_82542_rev2_0) {
-+ if (hw->mac_type == e1000_82542_rev2_0) {
- DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
- e1000_pci_clear_mwi(hw);
- E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
-@@ -514,35 +733,43 @@ e1000_init_hw(struct e1000_hw *hw)
- e1000_init_rx_addrs(hw);
-
- /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
-- if(hw->mac_type == e1000_82542_rev2_0) {
-+ if (hw->mac_type == e1000_82542_rev2_0) {
- E1000_WRITE_REG(hw, RCTL, 0);
- E1000_WRITE_FLUSH(hw);
- msec_delay(1);
-- if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
-+ if (hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
- e1000_pci_set_mwi(hw);
- }
-
- /* Zero out the Multicast HASH table */
- DEBUGOUT("Zeroing the MTA\n");
-- for(i = 0; i < E1000_MC_TBL_SIZE; i++)
-+ mta_size = E1000_MC_TBL_SIZE;
-+ if (hw->mac_type == e1000_ich8lan)
-+ mta_size = E1000_MC_TBL_SIZE_ICH8LAN;
-+ for (i = 0; i < mta_size; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-+ /* use write flush to prevent Memory Write Block (MWB) from
-+ * occuring when accessing our register space */
-+ E1000_WRITE_FLUSH(hw);
-+ }
-
- /* Set the PCI priority bit correctly in the CTRL register. This
- * determines if the adapter gives priority to receives, or if it
-- * gives equal priority to transmits and receives.
-+ * gives equal priority to transmits and receives. Valid only on
-+ * 82542 and 82543 silicon.
- */
-- if(hw->dma_fairness) {
-+ if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
- }
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
- default:
- /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
-- if(hw->bus_type == e1000_bus_type_pcix) {
-+ if (hw->bus_type == e1000_bus_type_pcix) {
- e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
- e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
- &pcix_stat_hi_word);
-@@ -550,9 +777,9 @@ e1000_init_hw(struct e1000_hw *hw)
- PCIX_COMMAND_MMRBC_SHIFT;
- stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
- PCIX_STATUS_HI_MMRBC_SHIFT;
-- if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
-+ if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
- stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
-- if(cmd_mmrbc > stat_mmrbc) {
-+ if (cmd_mmrbc > stat_mmrbc) {
- pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
- pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
- e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
-@@ -562,16 +789,78 @@ e1000_init_hw(struct e1000_hw *hw)
- break;
- }
-
-+ /* More time needed for PHY to initialize */
-+ if (hw->mac_type == e1000_ich8lan)
-+ msec_delay(15);
-+
- /* Call a subroutine to configure the link and setup flow control. */
- ret_val = e1000_setup_link(hw);
-
- /* Set the transmit descriptor write-back policy */
-- if(hw->mac_type > e1000_82544) {
-+ if (hw->mac_type > e1000_82544) {
- ctrl = E1000_READ_REG(hw, TXDCTL);
- ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-+ switch (hw->mac_type) {
-+ default:
-+ break;
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_ich8lan:
-+ case e1000_80003es2lan:
-+ ctrl |= E1000_TXDCTL_COUNT_DESC;
-+ break;
-+ }
- E1000_WRITE_REG(hw, TXDCTL, ctrl);
- }
-
-+ if (hw->mac_type == e1000_82573) {
-+ e1000_enable_tx_pkt_filtering(hw);
-+ }
-+
-+ switch (hw->mac_type) {
-+ default:
-+ break;
-+ case e1000_80003es2lan:
-+ /* Enable retransmit on late collisions */
-+ reg_data = E1000_READ_REG(hw, TCTL);
-+ reg_data |= E1000_TCTL_RTLC;
-+ E1000_WRITE_REG(hw, TCTL, reg_data);
-+
-+ /* Configure Gigabit Carry Extend Padding */
-+ reg_data = E1000_READ_REG(hw, TCTL_EXT);
-+ reg_data &= ~E1000_TCTL_EXT_GCEX_MASK;
-+ reg_data |= DEFAULT_80003ES2LAN_TCTL_EXT_GCEX;
-+ E1000_WRITE_REG(hw, TCTL_EXT, reg_data);
-+
-+ /* Configure Transmit Inter-Packet Gap */
-+ reg_data = E1000_READ_REG(hw, TIPG);
-+ reg_data &= ~E1000_TIPG_IPGT_MASK;
-+ reg_data |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
-+ E1000_WRITE_REG(hw, TIPG, reg_data);
-+
-+ reg_data = E1000_READ_REG_ARRAY(hw, FFLT, 0x0001);
-+ reg_data &= ~0x00100000;
-+ E1000_WRITE_REG_ARRAY(hw, FFLT, 0x0001, reg_data);
-+ /* Fall through */
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_ich8lan:
-+ ctrl = E1000_READ_REG(hw, TXDCTL1);
-+ ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB;
-+ if (hw->mac_type >= e1000_82571)
-+ ctrl |= E1000_TXDCTL_COUNT_DESC;
-+ E1000_WRITE_REG(hw, TXDCTL1, ctrl);
-+ break;
-+ }
-+
-+
-+ if (hw->mac_type == e1000_82573) {
-+ uint32_t gcr = E1000_READ_REG(hw, GCR);
-+ gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
-+ E1000_WRITE_REG(hw, GCR, gcr);
-+ }
-+
- /* Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
-@@ -579,6 +868,20 @@ e1000_init_hw(struct e1000_hw *hw)
- */
- e1000_clear_hw_cntrs(hw);
-
-+ /* ICH8 No-snoop bits are opposite polarity.
-+ * Set to snoop by default after reset. */
-+ if (hw->mac_type == e1000_ich8lan)
-+ e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);
-+
-+ if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
-+ hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
-+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-+ /* Relaxed ordering must be disabled to avoid a parity
-+ * error crash in a PCI slot. */
-+ ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
-+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-+ }
-+
- return ret_val;
- }
-
-@@ -595,10 +898,10 @@ e1000_adjust_serdes_amplitude(struct e10
-
- DEBUGFUNC("e1000_adjust_serdes_amplitude");
-
-- if(hw->media_type != e1000_media_type_internal_serdes)
-+ if (hw->media_type != e1000_media_type_internal_serdes)
- return E1000_SUCCESS;
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
-@@ -611,11 +914,11 @@ e1000_adjust_serdes_amplitude(struct e10
- return ret_val;
- }
-
-- if(eeprom_data != EEPROM_RESERVED_WORD) {
-+ if (eeprom_data != EEPROM_RESERVED_WORD) {
- /* Adjust SERDES output amplitude only. */
-- eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
-+ eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL, eeprom_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- }
-
-@@ -642,6 +945,11 @@ e1000_setup_link(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_setup_link");
-
-+ /* In the case of the phy reset being blocked, we already have a link.
-+ * We do not have to set it up again. */
-+ if (e1000_check_phy_reset_block(hw))
-+ return E1000_SUCCESS;
-+
- /* Read and store word 0x0F of the EEPROM. This word contains bits
- * that determine the hardware's default PAUSE (flow control) mode,
- * a bit that determines whether the HW defaults to enabling or
-@@ -650,29 +958,38 @@ e1000_setup_link(struct e1000_hw *hw)
- * control setting, then the variable hw->fc will
- * be initialized based on a value in the EEPROM.
- */
-- if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) {
-- DEBUGOUT("EEPROM Read Error\n");
-- return -E1000_ERR_EEPROM;
-- }
--
-- if(hw->fc == e1000_fc_default) {
-- if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-- hw->fc = e1000_fc_none;
-- else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-- EEPROM_WORD0F_ASM_DIR)
-- hw->fc = e1000_fc_tx_pause;
-- else
-+ if (hw->fc == e1000_fc_default) {
-+ switch (hw->mac_type) {
-+ case e1000_ich8lan:
-+ case e1000_82573:
- hw->fc = e1000_fc_full;
-+ break;
-+ default:
-+ ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
-+ 1, &eeprom_data);
-+ if (ret_val) {
-+ DEBUGOUT("EEPROM Read Error\n");
-+ return -E1000_ERR_EEPROM;
-+ }
-+ if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
-+ hw->fc = e1000_fc_none;
-+ else if ((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) ==
-+ EEPROM_WORD0F_ASM_DIR)
-+ hw->fc = e1000_fc_tx_pause;
-+ else
-+ hw->fc = e1000_fc_full;
-+ break;
-+ }
- }
-
- /* We want to save off the original Flow Control configuration just
- * in case we get disconnected and then reconnected into a different
- * hub or switch with different Flow Control capabilities.
- */
-- if(hw->mac_type == e1000_82542_rev2_0)
-+ if (hw->mac_type == e1000_82542_rev2_0)
- hw->fc &= (~e1000_fc_tx_pause);
-
-- if((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
-+ if ((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
- hw->fc &= (~e1000_fc_rx_pause);
-
- hw->original_fc = hw->fc;
-@@ -686,7 +1003,13 @@ e1000_setup_link(struct e1000_hw *hw)
- * signal detection. So this should be done before e1000_setup_pcs_link()
- * or e1000_phy_setup() is called.
- */
-- if(hw->mac_type == e1000_82543) {
-+ if (hw->mac_type == e1000_82543) {
-+ ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG,
-+ 1, &eeprom_data);
-+ if (ret_val) {
-+ DEBUGOUT("EEPROM Read Error\n");
-+ return -E1000_ERR_EEPROM;
-+ }
- ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) <<
- SWDPIO__EXT_SHIFT);
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-@@ -704,9 +1027,13 @@ e1000_setup_link(struct e1000_hw *hw)
- */
- DEBUGOUT("Initializing the Flow Control address, type and timer regs\n");
-
-- E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
-- E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
-- E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
-+ /* FCAL/H and FCT are hardcoded to standard values in e1000_ich8lan. */
-+ if (hw->mac_type != e1000_ich8lan) {
-+ E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
-+ E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
-+ E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
-+ }
-+
- E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
-
- /* Set the flow control receive threshold registers. Normally,
-@@ -715,14 +1042,14 @@ e1000_setup_link(struct e1000_hw *hw)
- * ability to transmit pause frames in not enabled, then these
- * registers will be set to 0.
- */
-- if(!(hw->fc & e1000_fc_tx_pause)) {
-+ if (!(hw->fc & e1000_fc_tx_pause)) {
- E1000_WRITE_REG(hw, FCRTL, 0);
- E1000_WRITE_REG(hw, FCRTH, 0);
- } else {
- /* We need to set up the Receive Threshold high and low water marks
- * as well as (optionally) enabling the transmission of XON frames.
- */
-- if(hw->fc_send_xon) {
-+ if (hw->fc_send_xon) {
- E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | E1000_FCRTL_XONE));
- E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
- } else {
-@@ -754,6 +1081,14 @@ e1000_setup_fiber_serdes_link(struct e10
-
- DEBUGFUNC("e1000_setup_fiber_serdes_link");
-
-+ /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
-+ * until explicitly turned off or a power cycle is performed. A read to
-+ * the register does not indicate its status. Therefore, we ensure
-+ * loopback mode is disabled during initialization.
-+ */
-+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
-+ E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
-+
- /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
-@@ -761,11 +1096,11 @@ e1000_setup_fiber_serdes_link(struct e10
- * the EEPROM.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
-- if(hw->media_type == e1000_media_type_fiber)
-+ if (hw->media_type == e1000_media_type_fiber)
- signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
-
- ret_val = e1000_adjust_serdes_amplitude(hw);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* Take the link out of reset */
-@@ -773,7 +1108,7 @@ e1000_setup_fiber_serdes_link(struct e10
-
- /* Adjust VCO speed to improve BER performance */
- ret_val = e1000_set_vco_speed(hw);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- e1000_config_collision_dist(hw);
-@@ -844,15 +1179,15 @@ e1000_setup_fiber_serdes_link(struct e10
- * less than 500 milliseconds even if the other end is doing it in SW).
- * For internal serdes, we just assume a signal is present, then poll.
- */
-- if(hw->media_type == e1000_media_type_internal_serdes ||
-+ if (hw->media_type == e1000_media_type_internal_serdes ||
- (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
- DEBUGOUT("Looking for Link\n");
-- for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
-+ for (i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
- msec_delay(10);
- status = E1000_READ_REG(hw, STATUS);
-- if(status & E1000_STATUS_LU) break;
-+ if (status & E1000_STATUS_LU) break;
- }
-- if(i == (LINK_UP_TIMEOUT / 10)) {
-+ if (i == (LINK_UP_TIMEOUT / 10)) {
- DEBUGOUT("Never got a valid link from auto-neg!!!\n");
- hw->autoneg_failed = 1;
- /* AutoNeg failed to achieve a link, so we'll call
-@@ -861,7 +1196,7 @@ e1000_setup_fiber_serdes_link(struct e10
- * non-autonegotiating link partners.
- */
- ret_val = e1000_check_for_link(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error while checking for link\n");
- return ret_val;
- }
-@@ -877,39 +1212,39 @@ e1000_setup_fiber_serdes_link(struct e10
- }
-
- /******************************************************************************
--* Detects which PHY is present and the speed and duplex
-+* Make sure we have a valid PHY and change PHY mode before link setup.
- *
- * hw - Struct containing variables accessed by shared code
- ******************************************************************************/
- static int32_t
--e1000_setup_copper_link(struct e1000_hw *hw)
-+e1000_copper_link_preconfig(struct e1000_hw *hw)
- {
- uint32_t ctrl;
-- uint32_t led_ctrl;
- int32_t ret_val;
-- uint16_t i;
- uint16_t phy_data;
-
-- DEBUGFUNC("e1000_setup_copper_link");
-+ DEBUGFUNC("e1000_copper_link_preconfig");
-
- ctrl = E1000_READ_REG(hw, CTRL);
- /* With 82543, we need to force speed and duplex on the MAC equal to what
- * the PHY speed and duplex configuration is. In addition, we need to
- * perform a hardware reset on the PHY to take it out of reset.
- */
-- if(hw->mac_type > e1000_82543) {
-+ if (hw->mac_type > e1000_82543) {
- ctrl |= E1000_CTRL_SLU;
- ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
- E1000_WRITE_REG(hw, CTRL, ctrl);
- } else {
- ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU);
- E1000_WRITE_REG(hw, CTRL, ctrl);
-- e1000_phy_hw_reset(hw);
-+ ret_val = e1000_phy_hw_reset(hw);
-+ if (ret_val)
-+ return ret_val;
- }
-
- /* Make sure we have a valid PHY */
- ret_val = e1000_detect_gig_phy(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error, did not detect valid phy.\n");
- return ret_val;
- }
-@@ -917,336 +1252,641 @@ e1000_setup_copper_link(struct e1000_hw
-
- /* Set PHY to class A mode (if necessary) */
- ret_val = e1000_set_phy_mode(hw);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if(hw->mac_type == e1000_82545_rev_3) {
-+ if ((hw->mac_type == e1000_82545_rev_3) ||
-+ (hw->mac_type == e1000_82546_rev_3)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
- phy_data |= 0x00000008;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
- }
-
-- if(hw->mac_type <= e1000_82543 ||
-- hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
-- hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
-+ if (hw->mac_type <= e1000_82543 ||
-+ hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
-+ hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2)
- hw->phy_reset_disable = FALSE;
-
-- if(!hw->phy_reset_disable) {
-- if (hw->phy_type == e1000_phy_igp) {
-+ return E1000_SUCCESS;
-+}
-
-- ret_val = e1000_phy_reset(hw);
-- if(ret_val) {
-- DEBUGOUT("Error Resetting the PHY\n");
-- return ret_val;
-- }
-
-- /* Wait 10ms for MAC to configure PHY from eeprom settings */
-- msec_delay(15);
-+/********************************************************************
-+* Copper link setup for e1000_phy_igp series.
-+*
-+* hw - Struct containing variables accessed by shared code
-+*********************************************************************/
-+static int32_t
-+e1000_copper_link_igp_setup(struct e1000_hw *hw)
-+{
-+ uint32_t led_ctrl;
-+ int32_t ret_val;
-+ uint16_t phy_data;
-
-- /* Configure activity LED after PHY reset */
-- led_ctrl = E1000_READ_REG(hw, LEDCTL);
-- led_ctrl &= IGP_ACTIVITY_LED_MASK;
-- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
-+ DEBUGFUNC("e1000_copper_link_igp_setup");
-
-- /* disable lplu d3 during driver init */
-- ret_val = e1000_set_d3_lplu_state(hw, FALSE);
-- if(ret_val) {
-- DEBUGOUT("Error Disabling LPLU D3\n");
-- return ret_val;
-- }
-+ if (hw->phy_reset_disable)
-+ return E1000_SUCCESS;
-
-- /* Configure mdi-mdix settings */
-- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-- &phy_data);
-- if(ret_val)
-- return ret_val;
-+ ret_val = e1000_phy_reset(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Resetting the PHY\n");
-+ return ret_val;
-+ }
-
-- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-- hw->dsp_config_state = e1000_dsp_config_disabled;
-- /* Force MDI for IGP B-0 PHY */
-- phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
-- IGP01E1000_PSCR_FORCE_MDI_MDIX);
-- hw->mdix = 1;
-+ /* Wait 15ms for MAC to configure PHY from eeprom settings */
-+ msec_delay(15);
-+ if (hw->mac_type != e1000_ich8lan) {
-+ /* Configure activity LED after PHY reset */
-+ led_ctrl = E1000_READ_REG(hw, LEDCTL);
-+ led_ctrl &= IGP_ACTIVITY_LED_MASK;
-+ led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
-+ E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
-+ }
-
-- } else {
-- hw->dsp_config_state = e1000_dsp_config_enabled;
-- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-+ /* The NVM settings will configure LPLU in D3 for IGP2 and IGP3 PHYs */
-+ if (hw->phy_type == e1000_phy_igp) {
-+ /* disable lplu d3 during driver init */
-+ ret_val = e1000_set_d3_lplu_state(hw, FALSE);
-+ if (ret_val) {
-+ DEBUGOUT("Error Disabling LPLU D3\n");
-+ return ret_val;
-+ }
-+ }
-
-- switch (hw->mdix) {
-- case 1:
-- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-- break;
-- case 2:
-- phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
-- break;
-- case 0:
-- default:
-- phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
-- break;
-- }
-- }
-- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
-- phy_data);
-- if(ret_val)
-- return ret_val;
-+ /* disable lplu d0 during driver init */
-+ ret_val = e1000_set_d0_lplu_state(hw, FALSE);
-+ if (ret_val) {
-+ DEBUGOUT("Error Disabling LPLU D0\n");
-+ return ret_val;
-+ }
-+ /* Configure mdi-mdix settings */
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-
-- /* set auto-master slave resolution settings */
-- if(hw->autoneg) {
-- e1000_ms_type phy_ms_setting = hw->master_slave;
-+ if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-+ hw->dsp_config_state = e1000_dsp_config_disabled;
-+ /* Force MDI for earlier revs of the IGP PHY */
-+ phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX);
-+ hw->mdix = 1;
-
-- if(hw->ffe_config_state == e1000_ffe_config_active)
-- hw->ffe_config_state = e1000_ffe_config_enabled;
-+ } else {
-+ hw->dsp_config_state = e1000_dsp_config_enabled;
-+ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
-
-- if(hw->dsp_config_state == e1000_dsp_config_activated)
-- hw->dsp_config_state = e1000_dsp_config_enabled;
-+ switch (hw->mdix) {
-+ case 1:
-+ phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-+ break;
-+ case 2:
-+ phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
-+ break;
-+ case 0:
-+ default:
-+ phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
-+ break;
-+ }
-+ }
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-
-- /* when autonegotiation advertisment is only 1000Mbps then we
-- * should disable SmartSpeed and enable Auto MasterSlave
-- * resolution as hardware default. */
-- if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
-- /* Disable SmartSpeed */
-- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-- &phy_data);
-- if(ret_val)
-- return ret_val;
-- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-- ret_val = e1000_write_phy_reg(hw,
-- IGP01E1000_PHY_PORT_CONFIG,
-- phy_data);
-- if(ret_val)
-- return ret_val;
-- /* Set auto Master/Slave resolution process */
-- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-- if(ret_val)
-- return ret_val;
-- phy_data &= ~CR_1000T_MS_ENABLE;
-- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-- if(ret_val)
-- return ret_val;
-- }
-+ /* set auto-master slave resolution settings */
-+ if (hw->autoneg) {
-+ e1000_ms_type phy_ms_setting = hw->master_slave;
-
-- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-- if(ret_val)
-- return ret_val;
-+ if (hw->ffe_config_state == e1000_ffe_config_active)
-+ hw->ffe_config_state = e1000_ffe_config_enabled;
-
-- /* load defaults for future use */
-- hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
-- ((phy_data & CR_1000T_MS_VALUE) ?
-- e1000_ms_force_master :
-- e1000_ms_force_slave) :
-- e1000_ms_auto;
--
-- switch (phy_ms_setting) {
-- case e1000_ms_force_master:
-- phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
-- break;
-- case e1000_ms_force_slave:
-- phy_data |= CR_1000T_MS_ENABLE;
-- phy_data &= ~(CR_1000T_MS_VALUE);
-- break;
-- case e1000_ms_auto:
-- phy_data &= ~CR_1000T_MS_ENABLE;
-- default:
-- break;
-- }
-- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-- if(ret_val)
-- return ret_val;
-- }
-- } else {
-- /* Enable CRS on TX. This must be set for half-duplex operation. */
-- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-+ if (hw->dsp_config_state == e1000_dsp_config_activated)
-+ hw->dsp_config_state = e1000_dsp_config_enabled;
-+
-+ /* when autonegotiation advertisment is only 1000Mbps then we
-+ * should disable SmartSpeed and enable Auto MasterSlave
-+ * resolution as hardware default. */
-+ if (hw->autoneg_advertised == ADVERTISE_1000_FULL) {
-+ /* Disable SmartSpeed */
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
--
-- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
--
-- /* Options:
-- * MDI/MDI-X = 0 (default)
-- * 0 - Auto for all speeds
-- * 1 - MDI mode
-- * 2 - MDI-X mode
-- * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-- */
-- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
--
-- switch (hw->mdix) {
-- case 1:
-- phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-- break;
-- case 2:
-- phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-- break;
-- case 3:
-- phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-- break;
-- case 0:
-- default:
-- phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-- break;
-- }
--
-- /* Options:
-- * disable_polarity_correction = 0 (default)
-- * Automatic Correction for Reversed Cable Polarity
-- * 0 - Disabled
-- * 1 - Enabled
-- */
-- phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-- if(hw->disable_polarity_correction == 1)
-- phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
-+ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
- phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
--
-- /* Force TX_CLK in the Extended PHY Specific Control Register
-- * to 25MHz clock.
-- */
-- ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-- &phy_data);
-- if(ret_val)
-+ /* Set auto Master/Slave resolution process */
-+ ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-+ if (ret_val)
- return ret_val;
--
-- phy_data |= M88E1000_EPSCR_TX_CLK_25;
--
-- if (hw->phy_revision < M88E1011_I_REV_4) {
-- /* Configure Master and Slave downshift values */
-- phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-- M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-- phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-- M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-- ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
-- phy_data);
-- if(ret_val)
-- return ret_val;
-- }
--
-- /* SW Reset the PHY so all changes take effect */
-- ret_val = e1000_phy_reset(hw);
-- if(ret_val) {
-- DEBUGOUT("Error Resetting the PHY\n");
-+ phy_data &= ~CR_1000T_MS_ENABLE;
-+ ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-+ if (ret_val)
- return ret_val;
-- }
- }
-
-- /* Options:
-- * autoneg = 1 (default)
-- * PHY will advertise value(s) parsed from
-- * autoneg_advertised and fc
-- * autoneg = 0
-- * PHY will be set to 10H, 10F, 100H, or 100F
-- * depending on value parsed from forced_speed_duplex.
-- */
--
-- /* Is autoneg enabled? This is enabled by default or by software
-- * override. If so, call e1000_phy_setup_autoneg routine to parse the
-- * autoneg_advertised and fc options. If autoneg is NOT enabled, then
-- * the user should have provided a speed/duplex override. If so, then
-- * call e1000_phy_force_speed_duplex to parse and set this up.
-- */
-- if(hw->autoneg) {
-- /* Perform some bounds checking on the hw->autoneg_advertised
-- * parameter. If this variable is zero, then set it to the default.
-- */
-- hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-+ ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-
-- /* If autoneg_advertised is zero, we assume it was not defaulted
-- * by the calling code so we set to advertise full capability.
-- */
-- if(hw->autoneg_advertised == 0)
-- hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-+ /* load defaults for future use */
-+ hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
-+ ((phy_data & CR_1000T_MS_VALUE) ?
-+ e1000_ms_force_master :
-+ e1000_ms_force_slave) :
-+ e1000_ms_auto;
-+
-+ switch (phy_ms_setting) {
-+ case e1000_ms_force_master:
-+ phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
-+ break;
-+ case e1000_ms_force_slave:
-+ phy_data |= CR_1000T_MS_ENABLE;
-+ phy_data &= ~(CR_1000T_MS_VALUE);
-+ break;
-+ case e1000_ms_auto:
-+ phy_data &= ~CR_1000T_MS_ENABLE;
-+ default:
-+ break;
-+ }
-+ ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-
-- DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-- ret_val = e1000_phy_setup_autoneg(hw);
-- if(ret_val) {
-- DEBUGOUT("Error Setting up Auto-Negotiation\n");
-- return ret_val;
-- }
-- DEBUGOUT("Restarting Auto-Neg\n");
-+ return E1000_SUCCESS;
-+}
-
-- /* Restart auto-negotiation by setting the Auto Neg Enable bit and
-- * the Auto Neg Restart bit in the PHY control register.
-- */
-- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-- if(ret_val)
-- return ret_val;
-+/********************************************************************
-+* Copper link setup for e1000_phy_gg82563 series.
-+*
-+* hw - Struct containing variables accessed by shared code
-+*********************************************************************/
-+static int32_t
-+e1000_copper_link_ggp_setup(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t phy_data;
-+ uint32_t reg_data;
-
-- phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-- if(ret_val)
-- return ret_val;
-+ DEBUGFUNC("e1000_copper_link_ggp_setup");
-
-- /* Does the user want to wait for Auto-Neg to complete here, or
-- * check at a later time (for example, callback routine).
-- */
-- if(hw->wait_autoneg_complete) {
-- ret_val = e1000_wait_autoneg(hw);
-- if(ret_val) {
-- DEBUGOUT("Error while waiting for autoneg to complete\n");
-- return ret_val;
-- }
-- }
-- hw->get_link_status = TRUE;
-- } else {
-- DEBUGOUT("Forcing speed and duplex\n");
-- ret_val = e1000_phy_force_speed_duplex(hw);
-- if(ret_val) {
-- DEBUGOUT("Error Forcing Speed and Duplex\n");
-- return ret_val;
-- }
-- }
-- } /* !hw->phy_reset_disable */
-+ if (!hw->phy_reset_disable) {
-
-- /* Check link status. Wait up to 100 microseconds for link to become
-- * valid.
-- */
-- for(i = 0; i < 10; i++) {
-- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ /* Enable CRS on TX for half-duplex operation. */
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
-+ &phy_data);
-+ if (ret_val)
- return ret_val;
-- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+
-+ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
-+ /* Use 25MHz for both link down and 1000BASE-T for Tx clock */
-+ phy_data |= GG82563_MSCR_TX_CLK_1000MBPS_25MHZ;
-+
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL,
-+ phy_data);
-+ if (ret_val)
- return ret_val;
-
-- if(phy_data & MII_SR_LINK_STATUS) {
-- /* We have link, so we need to finish the config process:
-- * 1) Set up the MAC to the current PHY speed/duplex
-- * if we are on 82543. If we
-- * are on newer silicon, we only need to configure
-- * collision distance in the Transmit Control Register.
-- * 2) Set up flow control on the MAC to that established with
-- * the link partner.
-- */
-- if(hw->mac_type >= e1000_82544) {
-- e1000_config_collision_dist(hw);
-- } else {
-- ret_val = e1000_config_mac_to_phy(hw);
-- if(ret_val) {
-- DEBUGOUT("Error configuring MAC to PHY settings\n");
-- return ret_val;
-- }
-- }
-- ret_val = e1000_config_fc_after_link_up(hw);
-- if(ret_val) {
-- DEBUGOUT("Error Configuring Flow Control\n");
-+ /* Options:
-+ * MDI/MDI-X = 0 (default)
-+ * 0 - Auto for all speeds
-+ * 1 - MDI mode
-+ * 2 - MDI-X mode
-+ * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-+ */
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK;
-+
-+ switch (hw->mdix) {
-+ case 1:
-+ phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDI;
-+ break;
-+ case 2:
-+ phy_data |= GG82563_PSCR_CROSSOVER_MODE_MDIX;
-+ break;
-+ case 0:
-+ default:
-+ phy_data |= GG82563_PSCR_CROSSOVER_MODE_AUTO;
-+ break;
-+ }
-+
-+ /* Options:
-+ * disable_polarity_correction = 0 (default)
-+ * Automatic Correction for Reversed Cable Polarity
-+ * 0 - Disabled
-+ * 1 - Enabled
-+ */
-+ phy_data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
-+ if (hw->disable_polarity_correction == 1)
-+ phy_data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* SW Reset the PHY so all changes take effect */
-+ ret_val = e1000_phy_reset(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Resetting the PHY\n");
-+ return ret_val;
-+ }
-+ } /* phy_reset_disable */
-+
-+ if (hw->mac_type == e1000_80003es2lan) {
-+ /* Bypass RX and TX FIFO's */
-+ ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL,
-+ E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS |
-+ E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, phy_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ reg_data = E1000_READ_REG(hw, CTRL_EXT);
-+ reg_data &= ~(E1000_CTRL_EXT_LINK_MODE_MASK);
-+ E1000_WRITE_REG(hw, CTRL_EXT, reg_data);
-+
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Do not init these registers when the HW is in IAMT mode, since the
-+ * firmware will have already initialized them. We only initialize
-+ * them if the HW is not in IAMT mode.
-+ */
-+ if (e1000_check_mng_mode(hw) == FALSE) {
-+ /* Enable Electrical Idle on the PHY */
-+ phy_data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL,
-+ phy_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ /* Workaround: Disable padding in Kumeran interface in the MAC
-+ * and in the PHY to avoid CRC errors.
-+ */
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ phy_data |= GG82563_ICR_DIS_PADDING;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_INBAND_CTRL,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/********************************************************************
-+* Copper link setup for e1000_phy_m88 series.
-+*
-+* hw - Struct containing variables accessed by shared code
-+*********************************************************************/
-+static int32_t
-+e1000_copper_link_mgp_setup(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t phy_data;
-+
-+ DEBUGFUNC("e1000_copper_link_mgp_setup");
-+
-+ if (hw->phy_reset_disable)
-+ return E1000_SUCCESS;
-+
-+ /* Enable CRS on TX. This must be set for half-duplex operation. */
-+ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
-+
-+ /* Options:
-+ * MDI/MDI-X = 0 (default)
-+ * 0 - Auto for all speeds
-+ * 1 - MDI mode
-+ * 2 - MDI-X mode
-+ * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
-+ */
-+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
-+
-+ switch (hw->mdix) {
-+ case 1:
-+ phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
-+ break;
-+ case 2:
-+ phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
-+ break;
-+ case 3:
-+ phy_data |= M88E1000_PSCR_AUTO_X_1000T;
-+ break;
-+ case 0:
-+ default:
-+ phy_data |= M88E1000_PSCR_AUTO_X_MODE;
-+ break;
-+ }
-+
-+ /* Options:
-+ * disable_polarity_correction = 0 (default)
-+ * Automatic Correction for Reversed Cable Polarity
-+ * 0 - Disabled
-+ * 1 - Enabled
-+ */
-+ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
-+ if (hw->disable_polarity_correction == 1)
-+ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ if (hw->phy_revision < M88E1011_I_REV_4) {
-+ /* Force TX_CLK in the Extended PHY Specific Control Register
-+ * to 25MHz clock.
-+ */
-+ ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= M88E1000_EPSCR_TX_CLK_25;
-+
-+ if ((hw->phy_revision == E1000_REVISION_2) &&
-+ (hw->phy_id == M88E1111_I_PHY_ID)) {
-+ /* Vidalia Phy, set the downshift counter to 5x */
-+ phy_data &= ~(M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK);
-+ phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X;
-+ ret_val = e1000_write_phy_reg(hw,
-+ M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else {
-+ /* Configure Master and Slave downshift values */
-+ phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
-+ M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
-+ phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
-+ M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
-+ ret_val = e1000_write_phy_reg(hw,
-+ M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+ }
-+
-+ /* SW Reset the PHY so all changes take effect */
-+ ret_val = e1000_phy_reset(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Resetting the PHY\n");
-+ return ret_val;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/********************************************************************
-+* Setup auto-negotiation and flow control advertisements,
-+* and then perform auto-negotiation.
-+*
-+* hw - Struct containing variables accessed by shared code
-+*********************************************************************/
-+static int32_t
-+e1000_copper_link_autoneg(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t phy_data;
-+
-+ DEBUGFUNC("e1000_copper_link_autoneg");
-+
-+ /* Perform some bounds checking on the hw->autoneg_advertised
-+ * parameter. If this variable is zero, then set it to the default.
-+ */
-+ hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
-+
-+ /* If autoneg_advertised is zero, we assume it was not defaulted
-+ * by the calling code so we set to advertise full capability.
-+ */
-+ if (hw->autoneg_advertised == 0)
-+ hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
-+
-+ /* IFE phy only supports 10/100 */
-+ if (hw->phy_type == e1000_phy_ife)
-+ hw->autoneg_advertised &= AUTONEG_ADVERTISE_10_100_ALL;
-+
-+ DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
-+ ret_val = e1000_phy_setup_autoneg(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Setting up Auto-Negotiation\n");
-+ return ret_val;
-+ }
-+ DEBUGOUT("Restarting Auto-Neg\n");
-+
-+ /* Restart auto-negotiation by setting the Auto Neg Enable bit and
-+ * the Auto Neg Restart bit in the PHY control register.
-+ */
-+ ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
-+ ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Does the user want to wait for Auto-Neg to complete here, or
-+ * check at a later time (for example, callback routine).
-+ */
-+ if (hw->wait_autoneg_complete) {
-+ ret_val = e1000_wait_autoneg(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error while waiting for autoneg to complete\n");
-+ return ret_val;
-+ }
-+ }
-+
-+ hw->get_link_status = TRUE;
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/******************************************************************************
-+* Config the MAC and the PHY after link is up.
-+* 1) Set up the MAC to the current PHY speed/duplex
-+* if we are on 82543. If we
-+* are on newer silicon, we only need to configure
-+* collision distance in the Transmit Control Register.
-+* 2) Set up flow control on the MAC to that established with
-+* the link partner.
-+* 3) Config DSP to improve Gigabit link quality for some PHY revisions.
-+*
-+* hw - Struct containing variables accessed by shared code
-+******************************************************************************/
-+static int32_t
-+e1000_copper_link_postconfig(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ DEBUGFUNC("e1000_copper_link_postconfig");
-+
-+ if (hw->mac_type >= e1000_82544) {
-+ e1000_config_collision_dist(hw);
-+ } else {
-+ ret_val = e1000_config_mac_to_phy(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error configuring MAC to PHY settings\n");
-+ return ret_val;
-+ }
-+ }
-+ ret_val = e1000_config_fc_after_link_up(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Configuring Flow Control\n");
-+ return ret_val;
-+ }
-+
-+ /* Config DSP to improve Giga link quality */
-+ if (hw->phy_type == e1000_phy_igp) {
-+ ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
-+ if (ret_val) {
-+ DEBUGOUT("Error Configuring DSP after link up\n");
-+ return ret_val;
-+ }
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/******************************************************************************
-+* Detects which PHY is present and setup the speed and duplex
-+*
-+* hw - Struct containing variables accessed by shared code
-+******************************************************************************/
-+static int32_t
-+e1000_setup_copper_link(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t i;
-+ uint16_t phy_data;
-+ uint16_t reg_data;
-+
-+ DEBUGFUNC("e1000_setup_copper_link");
-+
-+ switch (hw->mac_type) {
-+ case e1000_80003es2lan:
-+ case e1000_ich8lan:
-+ /* Set the mac to wait the maximum time between each
-+ * iteration and increase the max iterations when
-+ * polling the phy; this fixes erroneous timeouts at 10Mbps. */
-+ ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
-+ if (ret_val)
-+ return ret_val;
-+ ret_val = e1000_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
-+ if (ret_val)
-+ return ret_val;
-+ reg_data |= 0x3F;
-+ ret_val = e1000_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
-+ if (ret_val)
-+ return ret_val;
-+ default:
-+ break;
-+ }
-+
-+ /* Check if it is a valid PHY and set PHY mode if necessary. */
-+ ret_val = e1000_copper_link_preconfig(hw);
-+ if (ret_val)
-+ return ret_val;
-+
-+ switch (hw->mac_type) {
-+ case e1000_80003es2lan:
-+ /* Kumeran registers are written-only */
-+ reg_data = E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT;
-+ reg_data |= E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING;
-+ ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_INB_CTRL,
-+ reg_data);
-+ if (ret_val)
-+ return ret_val;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ if (hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2) {
-+ ret_val = e1000_copper_link_igp_setup(hw);
-+ if (ret_val)
-+ return ret_val;
-+ } else if (hw->phy_type == e1000_phy_m88) {
-+ ret_val = e1000_copper_link_mgp_setup(hw);
-+ if (ret_val)
-+ return ret_val;
-+ } else if (hw->phy_type == e1000_phy_gg82563) {
-+ ret_val = e1000_copper_link_ggp_setup(hw);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ if (hw->autoneg) {
-+ /* Setup autoneg and flow control advertisement
-+ * and perform autonegotiation */
-+ ret_val = e1000_copper_link_autoneg(hw);
-+ if (ret_val)
-+ return ret_val;
-+ } else {
-+ /* PHY will be set to 10H, 10F, 100H,or 100F
-+ * depending on value from forced_speed_duplex. */
-+ DEBUGOUT("Forcing speed and duplex\n");
-+ ret_val = e1000_phy_force_speed_duplex(hw);
-+ if (ret_val) {
-+ DEBUGOUT("Error Forcing Speed and Duplex\n");
-+ return ret_val;
-+ }
-+ }
-+
-+ /* Check link status. Wait up to 100 microseconds for link to become
-+ * valid.
-+ */
-+ for (i = 0; i < 10; i++) {
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ if (phy_data & MII_SR_LINK_STATUS) {
-+ /* Config the MAC and PHY after link is up */
-+ ret_val = e1000_copper_link_postconfig(hw);
-+ if (ret_val)
- return ret_val;
-- }
-- DEBUGOUT("Valid link established!!!\n");
-
-- if(hw->phy_type == e1000_phy_igp) {
-- ret_val = e1000_config_dsp_after_link_change(hw, TRUE);
-- if(ret_val) {
-- DEBUGOUT("Error Configuring DSP after link up\n");
-- return ret_val;
-- }
-- }
- DEBUGOUT("Valid link established!!!\n");
- return E1000_SUCCESS;
- }
-- udelay(10);
-+ usec_delay(10);
- }
-
- DEBUGOUT("Unable to establish link!!!\n");
-@@ -1254,6 +1894,79 @@ e1000_setup_copper_link(struct e1000_hw
- }
-
- /******************************************************************************
-+* Configure the MAC-to-PHY interface for 10/100Mbps
-+*
-+* hw - Struct containing variables accessed by shared code
-+******************************************************************************/
-+static int32_t
-+e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, uint16_t duplex)
-+{
-+ int32_t ret_val = E1000_SUCCESS;
-+ uint32_t tipg;
-+ uint16_t reg_data;
-+
-+ DEBUGFUNC("e1000_configure_kmrn_for_10_100");
-+
-+ reg_data = E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT;
-+ ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
-+ reg_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Configure Transmit Inter-Packet Gap */
-+ tipg = E1000_READ_REG(hw, TIPG);
-+ tipg &= ~E1000_TIPG_IPGT_MASK;
-+ tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_10_100;
-+ E1000_WRITE_REG(hw, TIPG, tipg);
-+
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ if (duplex == HALF_DUPLEX)
-+ reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
-+ else
-+ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-+
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
-+
-+ return ret_val;
-+}
-+
-+static int32_t
-+e1000_configure_kmrn_for_1000(struct e1000_hw *hw)
-+{
-+ int32_t ret_val = E1000_SUCCESS;
-+ uint16_t reg_data;
-+ uint32_t tipg;
-+
-+ DEBUGFUNC("e1000_configure_kmrn_for_1000");
-+
-+ reg_data = E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT;
-+ ret_val = e1000_write_kmrn_reg(hw, E1000_KUMCTRLSTA_OFFSET_HD_CTRL,
-+ reg_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Configure Transmit Inter-Packet Gap */
-+ tipg = E1000_READ_REG(hw, TIPG);
-+ tipg &= ~E1000_TIPG_IPGT_MASK;
-+ tipg |= DEFAULT_80003ES2LAN_TIPG_IPGT_1000;
-+ E1000_WRITE_REG(hw, TIPG, tipg);
-+
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
-+
-+ return ret_val;
-+}
-+
-+/******************************************************************************
- * Configures PHY autoneg and flow control advertisement settings
- *
- * hw - Struct containing variables accessed by shared code
-@@ -1269,13 +1982,16 @@ e1000_phy_setup_autoneg(struct e1000_hw
-
- /* Read the MII Auto-Neg Advertisement Register (Address 4). */
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- /* Read the MII 1000Base-T Control Register (Address 9). */
-- ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
-- if(ret_val)
-- return ret_val;
-+ if (hw->phy_type != e1000_phy_ife) {
-+ /* Read the MII 1000Base-T Control Register (Address 9). */
-+ ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg);
-+ if (ret_val)
-+ return ret_val;
-+ } else
-+ mii_1000t_ctrl_reg=0;
-
- /* Need to parse both autoneg_advertised and fc and set up
- * the appropriate PHY registers. First we will parse for
-@@ -1294,38 +2010,41 @@ e1000_phy_setup_autoneg(struct e1000_hw
- DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
-
- /* Do we want to advertise 10 Mb Half Duplex? */
-- if(hw->autoneg_advertised & ADVERTISE_10_HALF) {
-+ if (hw->autoneg_advertised & ADVERTISE_10_HALF) {
- DEBUGOUT("Advertise 10mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
- }
-
- /* Do we want to advertise 10 Mb Full Duplex? */
-- if(hw->autoneg_advertised & ADVERTISE_10_FULL) {
-+ if (hw->autoneg_advertised & ADVERTISE_10_FULL) {
- DEBUGOUT("Advertise 10mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Half Duplex? */
-- if(hw->autoneg_advertised & ADVERTISE_100_HALF) {
-+ if (hw->autoneg_advertised & ADVERTISE_100_HALF) {
- DEBUGOUT("Advertise 100mb Half duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
- }
-
- /* Do we want to advertise 100 Mb Full Duplex? */
-- if(hw->autoneg_advertised & ADVERTISE_100_FULL) {
-+ if (hw->autoneg_advertised & ADVERTISE_100_FULL) {
- DEBUGOUT("Advertise 100mb Full duplex\n");
- mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
- }
-
- /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
-- if(hw->autoneg_advertised & ADVERTISE_1000_HALF) {
-+ if (hw->autoneg_advertised & ADVERTISE_1000_HALF) {
- DEBUGOUT("Advertise 1000mb Half duplex requested, request denied!\n");
- }
-
- /* Do we want to advertise 1000 Mb Full Duplex? */
-- if(hw->autoneg_advertised & ADVERTISE_1000_FULL) {
-+ if (hw->autoneg_advertised & ADVERTISE_1000_FULL) {
- DEBUGOUT("Advertise 1000mb Full duplex\n");
- mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
-+ if (hw->phy_type == e1000_phy_ife) {
-+ DEBUGOUT("e1000_phy_ife is a 10/100 PHY. Gigabit speed is not supported.\n");
-+ }
- }
-
- /* Check for a software override of the flow control settings, and
-@@ -1382,14 +2101,16 @@ e1000_phy_setup_autoneg(struct e1000_hw
- }
-
- ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
-
-- ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
-- if(ret_val)
-- return ret_val;
-+ if (hw->phy_type != e1000_phy_ife) {
-+ ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg);
-+ if (ret_val)
-+ return ret_val;
-+ }
-
- return E1000_SUCCESS;
- }
-@@ -1428,7 +2149,7 @@ e1000_phy_force_speed_duplex(struct e100
-
- /* Read the MII Control Register. */
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &mii_ctrl_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* We need to disable autoneg in order to force link and duplex. */
-@@ -1436,8 +2157,8 @@ e1000_phy_force_speed_duplex(struct e100
- mii_ctrl_reg &= ~MII_CR_AUTO_NEG_EN;
-
- /* Are we forcing Full or Half Duplex? */
-- if(hw->forced_speed_duplex == e1000_100_full ||
-- hw->forced_speed_duplex == e1000_10_full) {
-+ if (hw->forced_speed_duplex == e1000_100_full ||
-+ hw->forced_speed_duplex == e1000_10_full) {
- /* We want to force full duplex so we SET the full duplex bits in the
- * Device and MII Control Registers.
- */
-@@ -1454,7 +2175,7 @@ e1000_phy_force_speed_duplex(struct e100
- }
-
- /* Are we forcing 100Mbps??? */
-- if(hw->forced_speed_duplex == e1000_100_full ||
-+ if (hw->forced_speed_duplex == e1000_100_full ||
- hw->forced_speed_duplex == e1000_100_half) {
- /* Set the 100Mb bit and turn off the 1000Mb and 10Mb bits. */
- ctrl |= E1000_CTRL_SPD_100;
-@@ -1474,9 +2195,10 @@ e1000_phy_force_speed_duplex(struct e100
- /* Write the configured values back to the Device Control Reg. */
- E1000_WRITE_REG(hw, CTRL, ctrl);
-
-- if (hw->phy_type == e1000_phy_m88) {
-+ if ((hw->phy_type == e1000_phy_m88) ||
-+ (hw->phy_type == e1000_phy_gg82563)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
-@@ -1484,35 +2206,47 @@ e1000_phy_force_speed_duplex(struct e100
- */
- phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- DEBUGOUT1("M88E1000 PSCR: %x \n", phy_data);
-
- /* Need to reset the PHY or these changes will be ignored */
- mii_ctrl_reg |= MII_CR_RESET;
-+ /* Disable MDI-X support for 10/100 */
-+ } else if (hw->phy_type == e1000_phy_ife) {
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~IFE_PMC_AUTO_MDIX;
-+ phy_data &= ~IFE_PMC_FORCE_MDIX;
-+
-+ ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, phy_data);
-+ if (ret_val)
-+ return ret_val;
- } else {
- /* Clear Auto-Crossover to force MDI manually. IGP requires MDI
- * forced whenever speed or duplex are forced.
- */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
- phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
-
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- }
-
- /* Write back the modified PHY MII control register. */
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, mii_ctrl_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- udelay(1);
-+ usec_delay(1);
-
- /* The wait_autoneg_complete flag may be a little misleading here.
- * Since we are forcing speed and duplex, Auto-Neg is not enabled.
-@@ -1521,48 +2255,50 @@ e1000_phy_force_speed_duplex(struct e100
- * only if the user has set wait_autoneg_complete to 1, which is
- * the default.
- */
-- if(hw->wait_autoneg_complete) {
-+ if (hw->wait_autoneg_complete) {
- /* We will wait for autoneg to complete. */
- DEBUGOUT("Waiting for forced speed/duplex link.\n");
- mii_status_reg = 0;
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
-- for(i = PHY_FORCE_TIME; i > 0; i--) {
-+ for (i = PHY_FORCE_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if(mii_status_reg & MII_SR_LINK_STATUS) break;
-+ if (mii_status_reg & MII_SR_LINK_STATUS) break;
- msec_delay(100);
- }
-- if((i == 0) && (hw->phy_type == e1000_phy_m88)) {
-+ if ((i == 0) &&
-+ ((hw->phy_type == e1000_phy_m88) ||
-+ (hw->phy_type == e1000_phy_gg82563))) {
- /* We didn't get link. Reset the DSP and wait again for link. */
- ret_val = e1000_phy_reset_dsp(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error Resetting PHY DSP\n");
- return ret_val;
- }
- }
- /* This loop will early-out if the link condition has been met. */
-- for(i = PHY_FORCE_TIME; i > 0; i--) {
-- if(mii_status_reg & MII_SR_LINK_STATUS) break;
-+ for (i = PHY_FORCE_TIME; i > 0; i--) {
-+ if (mii_status_reg & MII_SR_LINK_STATUS) break;
- msec_delay(100);
- /* Read the MII Status Register and wait for Auto-Neg Complete bit
- * to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- }
- }
-@@ -1573,24 +2309,53 @@ e1000_phy_force_speed_duplex(struct e100
- * defaults back to a 2.5MHz clock when the PHY is reset.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_EPSCR_TX_CLK_25;
- ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* In addition, because of the s/w reset above, we need to enable CRS on
- * TX. This must be set for both full and half duplex operation.
- */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
-- if(ret_val)
-+ if (ret_val)
-+ return ret_val;
-+
-+ if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
-+ (!hw->autoneg) && (hw->forced_speed_duplex == e1000_10_full ||
-+ hw->forced_speed_duplex == e1000_10_half)) {
-+ ret_val = e1000_polarity_reversal_workaround(hw);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+ } else if (hw->phy_type == e1000_phy_gg82563) {
-+ /* The TX_CLK of the Extended PHY Specific Control Register defaults
-+ * to 2.5MHz on a reset. We need to re-force it back to 25MHz, if
-+ * we're not in a forced 10/duplex configuration. */
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
-+ if ((hw->forced_speed_duplex == e1000_10_full) ||
-+ (hw->forced_speed_duplex == e1000_10_half))
-+ phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ;
-+ else
-+ phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25MHZ;
-+
-+ /* Also due to the reset, we need to enable CRS on Tx. */
-+ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
-+
-+ ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data);
-+ if (ret_val)
- return ret_val;
- }
- return E1000_SUCCESS;
-@@ -1607,14 +2372,19 @@ e1000_phy_force_speed_duplex(struct e100
- void
- e1000_config_collision_dist(struct e1000_hw *hw)
- {
-- uint32_t tctl;
-+ uint32_t tctl, coll_dist;
-
- DEBUGFUNC("e1000_config_collision_dist");
-
-+ if (hw->mac_type < e1000_82543)
-+ coll_dist = E1000_COLLISION_DISTANCE_82542;
-+ else
-+ coll_dist = E1000_COLLISION_DISTANCE;
-+
- tctl = E1000_READ_REG(hw, TCTL);
-
- tctl &= ~E1000_TCTL_COLD;
-- tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
-+ tctl |= coll_dist << E1000_COLD_SHIFT;
-
- E1000_WRITE_REG(hw, TCTL, tctl);
- E1000_WRITE_FLUSH(hw);
-@@ -1638,6 +2408,11 @@ e1000_config_mac_to_phy(struct e1000_hw
-
- DEBUGFUNC("e1000_config_mac_to_phy");
-
-+ /* 82544 or newer MAC, Auto Speed Detection takes care of
-+ * MAC speed/duplex configuration.*/
-+ if (hw->mac_type >= e1000_82544)
-+ return E1000_SUCCESS;
-+
- /* Read the Device Control Register and set the bits to Force Speed
- * and Duplex.
- */
-@@ -1648,45 +2423,25 @@ e1000_config_mac_to_phy(struct e1000_hw
- /* Set up duplex in the Device Control and Transmit Control
- * registers depending on negotiated values.
- */
-- if (hw->phy_type == e1000_phy_igp) {
-- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
-- &phy_data);
-- if(ret_val)
-- return ret_val;
--
-- if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD;
-- else ctrl &= ~E1000_CTRL_FD;
--
-- e1000_config_collision_dist(hw);
-+ ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-
-- /* Set up speed in the Device Control register depending on
-- * negotiated values.
-- */
-- if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-- IGP01E1000_PSSR_SPEED_1000MBPS)
-- ctrl |= E1000_CTRL_SPD_1000;
-- else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-- IGP01E1000_PSSR_SPEED_100MBPS)
-- ctrl |= E1000_CTRL_SPD_100;
-- } else {
-- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
-- &phy_data);
-- if(ret_val)
-- return ret_val;
-+ if (phy_data & M88E1000_PSSR_DPLX)
-+ ctrl |= E1000_CTRL_FD;
-+ else
-+ ctrl &= ~E1000_CTRL_FD;
-
-- if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
-- else ctrl &= ~E1000_CTRL_FD;
-+ e1000_config_collision_dist(hw);
-
-- e1000_config_collision_dist(hw);
-+ /* Set up speed in the Device Control register depending on
-+ * negotiated values.
-+ */
-+ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
-+ ctrl |= E1000_CTRL_SPD_1000;
-+ else if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
-+ ctrl |= E1000_CTRL_SPD_100;
-
-- /* Set up speed in the Device Control register depending on
-- * negotiated values.
-- */
-- if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
-- ctrl |= E1000_CTRL_SPD_1000;
-- else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS)
-- ctrl |= E1000_CTRL_SPD_100;
-- }
- /* Write the configured values back to the Device Control Reg. */
- E1000_WRITE_REG(hw, CTRL, ctrl);
- return E1000_SUCCESS;
-@@ -1752,7 +2507,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
- }
-
- /* Disable TX Flow Control for 82542 (rev 2.0) */
-- if(hw->mac_type == e1000_82542_rev2_0)
-+ if (hw->mac_type == e1000_82542_rev2_0)
- ctrl &= (~E1000_CTRL_TFCE);
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
-@@ -1786,11 +2541,12 @@ e1000_config_fc_after_link_up(struct e10
- * so we had to force link. In this case, we need to force the
- * configuration of the MAC to match the "fc" parameter.
- */
-- if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
-- ((hw->media_type == e1000_media_type_internal_serdes) && (hw->autoneg_failed)) ||
-- ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
-+ if (((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) ||
-+ ((hw->media_type == e1000_media_type_internal_serdes) &&
-+ (hw->autoneg_failed)) ||
-+ ((hw->media_type == e1000_media_type_copper) && (!hw->autoneg))) {
- ret_val = e1000_force_mac_fc(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
-@@ -1801,19 +2557,19 @@ e1000_config_fc_after_link_up(struct e10
- * has completed, and if so, how the PHY and link partner has
- * flow control configured.
- */
-- if((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
-+ if ((hw->media_type == e1000_media_type_copper) && hw->autoneg) {
- /* Read the MII Status Register and check to see if AutoNeg
- * has completed. We read this twice because this reg has
- * some "sticky" (latched) bits.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
-+ if (mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
- /* The AutoNeg process has completed, so we now need to
- * read both the Auto Negotiation Advertisement Register
- * (Address 4) and the Auto_Negotiation Base Page Ability
-@@ -1822,11 +2578,11 @@ e1000_config_fc_after_link_up(struct e10
- */
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
- &mii_nway_adv_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
- &mii_nway_lp_ability_reg);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* Two bits in the Auto Negotiation Advertisement Register
-@@ -1863,20 +2619,20 @@ e1000_config_fc_after_link_up(struct e10
- * 1 | DC | 1 | DC | e1000_fc_full
- *
- */
-- if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
-+ if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-+ (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
- /* Now we need to check if the user selected RX ONLY
- * of pause frames. In this case, we had to advertise
- * FULL flow control because we could not advertise RX
- * ONLY. Hence, we must now check to see if we need to
- * turn OFF the TRANSMISSION of PAUSE frames.
- */
-- if(hw->original_fc == e1000_fc_full) {
-+ if (hw->original_fc == e1000_fc_full) {
- hw->fc = e1000_fc_full;
-- DEBUGOUT("Flow Control = FULL.\r\n");
-+ DEBUGOUT("Flow Control = FULL.\n");
- } else {
- hw->fc = e1000_fc_rx_pause;
-- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
-+ DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
- }
- /* For receiving PAUSE frames ONLY.
-@@ -1887,12 +2643,12 @@ e1000_config_fc_after_link_up(struct e10
- * 0 | 1 | 1 | 1 | e1000_fc_tx_pause
- *
- */
-- else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-- (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-+ else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-+ (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-+ (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-+ (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_tx_pause;
-- DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n");
-+ DEBUGOUT("Flow Control = TX PAUSE frames only.\n");
- }
- /* For transmitting PAUSE frames ONLY.
- *
-@@ -1902,12 +2658,12 @@ e1000_config_fc_after_link_up(struct e10
- * 1 | 1 | 0 | 1 | e1000_fc_rx_pause
- *
- */
-- else if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-- (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-- !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-- (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-+ else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
-+ (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
-+ !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
-+ (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
- hw->fc = e1000_fc_rx_pause;
-- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
-+ DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
- /* Per the IEEE spec, at this point flow control should be
- * disabled. However, we want to consider that we could
-@@ -1929,14 +2685,14 @@ e1000_config_fc_after_link_up(struct e10
- * be asked to delay transmission of packets than asking
- * our link partner to pause transmission of frames.
- */
-- else if((hw->original_fc == e1000_fc_none ||
-- hw->original_fc == e1000_fc_tx_pause) ||
-- hw->fc_strict_ieee) {
-+ else if ((hw->original_fc == e1000_fc_none ||
-+ hw->original_fc == e1000_fc_tx_pause) ||
-+ hw->fc_strict_ieee) {
- hw->fc = e1000_fc_none;
-- DEBUGOUT("Flow Control = NONE.\r\n");
-+ DEBUGOUT("Flow Control = NONE.\n");
- } else {
- hw->fc = e1000_fc_rx_pause;
-- DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n");
-+ DEBUGOUT("Flow Control = RX PAUSE frames only.\n");
- }
-
- /* Now we need to do one last check... If we auto-
-@@ -1944,24 +2700,24 @@ e1000_config_fc_after_link_up(struct e10
- * enabled per IEEE 802.3 spec.
- */
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
-- if(duplex == HALF_DUPLEX)
-+ if (duplex == HALF_DUPLEX)
- hw->fc = e1000_fc_none;
-
- /* Now we call a subroutine to actually force the MAC
- * controller to use the correct flow control settings.
- */
- ret_val = e1000_force_mac_fc(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error forcing flow control settings\n");
- return ret_val;
- }
- } else {
-- DEBUGOUT("Copper PHY and Auto Neg has not completed.\r\n");
-+ DEBUGOUT("Copper PHY and Auto Neg has not completed.\n");
- }
- }
- return E1000_SUCCESS;
-@@ -1981,6 +2737,7 @@ e1000_check_for_link(struct e1000_hw *hw
- uint32_t ctrl;
- uint32_t status;
- uint32_t rctl;
-+ uint32_t icr;
- uint32_t signal = 0;
- int32_t ret_val;
- uint16_t phy_data;
-@@ -1994,13 +2751,13 @@ e1000_check_for_link(struct e1000_hw *hw
- * set when the optics detect a signal. On older adapters, it will be
- * cleared when there is a signal. This applies to fiber media only.
- */
-- if((hw->media_type == e1000_media_type_fiber) ||
-- (hw->media_type == e1000_media_type_internal_serdes)) {
-+ if ((hw->media_type == e1000_media_type_fiber) ||
-+ (hw->media_type == e1000_media_type_internal_serdes)) {
- rxcw = E1000_READ_REG(hw, RXCW);
-
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
-- if(status & E1000_STATUS_LU)
-+ if (status & E1000_STATUS_LU)
- hw->get_link_status = FALSE;
- }
- }
-@@ -2011,25 +2768,44 @@ e1000_check_for_link(struct e1000_hw *hw
- * receive a Link Status Change interrupt or we have Rx Sequence
- * Errors.
- */
-- if((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
-+ if ((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
- /* First we want to see if the MII Status Register reports
- * link. If so, then we want to get the current speed/duplex
- * of the PHY.
- * Read the register twice since the link bit is sticky.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if(phy_data & MII_SR_LINK_STATUS) {
-+ if (phy_data & MII_SR_LINK_STATUS) {
- hw->get_link_status = FALSE;
- /* Check if there was DownShift, must be checked immediately after
- * link-up */
- e1000_check_downshift(hw);
-
-+ /* If we are on 82544 or 82543 silicon and speed/duplex
-+ * are forced to 10H or 10F, then we will implement the polarity
-+ * reversal workaround. We disable interrupts first, and upon
-+ * returning, place the devices interrupt state to its previous
-+ * value except for the link status change interrupt which will
-+ * happen due to the execution of this workaround.
-+ */
-+
-+ if ((hw->mac_type == e1000_82544 || hw->mac_type == e1000_82543) &&
-+ (!hw->autoneg) &&
-+ (hw->forced_speed_duplex == e1000_10_full ||
-+ hw->forced_speed_duplex == e1000_10_half)) {
-+ E1000_WRITE_REG(hw, IMC, 0xffffffff);
-+ ret_val = e1000_polarity_reversal_workaround(hw);
-+ icr = E1000_READ_REG(hw, ICR);
-+ E1000_WRITE_REG(hw, ICS, (icr & ~E1000_ICS_LSC));
-+ E1000_WRITE_REG(hw, IMS, IMS_ENABLE_MASK);
-+ }
-+
- } else {
- /* No link detected */
- e1000_config_dsp_after_link_change(hw, FALSE);
-@@ -2039,7 +2815,7 @@ e1000_check_for_link(struct e1000_hw *hw
- /* If we are forcing speed/duplex, then we simply return since
- * we have already determined whether we have link or not.
- */
-- if(!hw->autoneg) return -E1000_ERR_CONFIG;
-+ if (!hw->autoneg) return -E1000_ERR_CONFIG;
-
- /* optimize the dsp settings for the igp phy */
- e1000_config_dsp_after_link_change(hw, TRUE);
-@@ -2052,11 +2828,11 @@ e1000_check_for_link(struct e1000_hw *hw
- * speed/duplex on the MAC to the current PHY speed/duplex
- * settings.
- */
-- if(hw->mac_type >= e1000_82544)
-+ if (hw->mac_type >= e1000_82544)
- e1000_config_collision_dist(hw);
- else {
- ret_val = e1000_config_mac_to_phy(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error configuring MAC to PHY settings\n");
- return ret_val;
- }
-@@ -2067,7 +2843,7 @@ e1000_check_for_link(struct e1000_hw *hw
- * have had to re-autoneg with a different link partner.
- */
- ret_val = e1000_config_fc_after_link_up(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
-@@ -2079,14 +2855,18 @@ e1000_check_for_link(struct e1000_hw *hw
- * at gigabit speed, then TBI compatibility is not needed. If we are
- * at gigabit speed, we turn on TBI compatibility.
- */
-- if(hw->tbi_compatibility_en) {
-+ if (hw->tbi_compatibility_en) {
- uint16_t speed, duplex;
-- e1000_get_speed_and_duplex(hw, &speed, &duplex);
-- if(speed != SPEED_1000) {
-+ ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
-+ if (ret_val) {
-+ DEBUGOUT("Error getting link speed and duplex\n");
-+ return ret_val;
-+ }
-+ if (speed != SPEED_1000) {
- /* If link speed is not set to gigabit speed, we do not need
- * to enable TBI compatibility.
- */
-- if(hw->tbi_compatibility_on) {
-+ if (hw->tbi_compatibility_on) {
- /* If we previously were in the mode, turn it off. */
- rctl = E1000_READ_REG(hw, RCTL);
- rctl &= ~E1000_RCTL_SBP;
-@@ -2099,7 +2879,7 @@ e1000_check_for_link(struct e1000_hw *hw
- * packets. Some frames have an additional byte on the end and
- * will look like CRC errors to to the hardware.
- */
-- if(!hw->tbi_compatibility_on) {
-+ if (!hw->tbi_compatibility_on) {
- hw->tbi_compatibility_on = TRUE;
- rctl = E1000_READ_REG(hw, RCTL);
- rctl |= E1000_RCTL_SBP;
-@@ -2115,16 +2895,16 @@ e1000_check_for_link(struct e1000_hw *hw
- * auto-negotiation time to complete, in case the cable was just plugged
- * in. The autoneg_failed flag does this.
- */
-- else if((((hw->media_type == e1000_media_type_fiber) &&
-+ else if ((((hw->media_type == e1000_media_type_fiber) &&
- ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
-- (hw->media_type == e1000_media_type_internal_serdes)) &&
-- (!(status & E1000_STATUS_LU)) &&
-- (!(rxcw & E1000_RXCW_C))) {
-- if(hw->autoneg_failed == 0) {
-+ (hw->media_type == e1000_media_type_internal_serdes)) &&
-+ (!(status & E1000_STATUS_LU)) &&
-+ (!(rxcw & E1000_RXCW_C))) {
-+ if (hw->autoneg_failed == 0) {
- hw->autoneg_failed = 1;
- return 0;
- }
-- DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
-+ DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
-
- /* Disable auto-negotiation in the TXCW register */
- E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
-@@ -2136,7 +2916,7 @@ e1000_check_for_link(struct e1000_hw *hw
-
- /* Configure Flow Control after forcing link up. */
- ret_val = e1000_config_fc_after_link_up(hw);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error configuring flow control\n");
- return ret_val;
- }
-@@ -2146,10 +2926,10 @@ e1000_check_for_link(struct e1000_hw *hw
- * Device Control register in an attempt to auto-negotiate with our link
- * partner.
- */
-- else if(((hw->media_type == e1000_media_type_fiber) ||
-- (hw->media_type == e1000_media_type_internal_serdes)) &&
-- (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-- DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\r\n");
-+ else if (((hw->media_type == e1000_media_type_fiber) ||
-+ (hw->media_type == e1000_media_type_internal_serdes)) &&
-+ (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-+ DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
- E1000_WRITE_REG(hw, TXCW, hw->txcw);
- E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
-
-@@ -2158,12 +2938,12 @@ e1000_check_for_link(struct e1000_hw *hw
- /* If we force link for non-auto-negotiation switch, check link status
- * based on MAC synchronization for internal serdes media type.
- */
-- else if((hw->media_type == e1000_media_type_internal_serdes) &&
-- !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
-+ else if ((hw->media_type == e1000_media_type_internal_serdes) &&
-+ !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
- /* SYNCH bit and IV bit are sticky. */
-- udelay(10);
-- if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
-- if(!(rxcw & E1000_RXCW_IV)) {
-+ usec_delay(10);
-+ if (E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
-+ if (!(rxcw & E1000_RXCW_IV)) {
- hw->serdes_link_down = FALSE;
- DEBUGOUT("SERDES: Link is up.\n");
- }
-@@ -2172,8 +2952,8 @@ e1000_check_for_link(struct e1000_hw *hw
- DEBUGOUT("SERDES: Link is down.\n");
- }
- }
-- if((hw->media_type == e1000_media_type_internal_serdes) &&
-- (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
-+ if ((hw->media_type == e1000_media_type_internal_serdes) &&
-+ (E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
- hw->serdes_link_down = !(E1000_STATUS_LU & E1000_READ_REG(hw, STATUS));
- }
- return E1000_SUCCESS;
-@@ -2197,12 +2977,12 @@ e1000_get_speed_and_duplex(struct e1000_
-
- DEBUGFUNC("e1000_get_speed_and_duplex");
-
-- if(hw->mac_type >= e1000_82543) {
-+ if (hw->mac_type >= e1000_82543) {
- status = E1000_READ_REG(hw, STATUS);
-- if(status & E1000_STATUS_SPEED_1000) {
-+ if (status & E1000_STATUS_SPEED_1000) {
- *speed = SPEED_1000;
- DEBUGOUT("1000 Mbs, ");
-- } else if(status & E1000_STATUS_SPEED_100) {
-+ } else if (status & E1000_STATUS_SPEED_100) {
- *speed = SPEED_100;
- DEBUGOUT("100 Mbs, ");
- } else {
-@@ -2210,15 +2990,15 @@ e1000_get_speed_and_duplex(struct e1000_
- DEBUGOUT("10 Mbs, ");
- }
-
-- if(status & E1000_STATUS_FD) {
-+ if (status & E1000_STATUS_FD) {
- *duplex = FULL_DUPLEX;
-- DEBUGOUT("Full Duplex\r\n");
-+ DEBUGOUT("Full Duplex\n");
- } else {
- *duplex = HALF_DUPLEX;
-- DEBUGOUT(" Half Duplex\r\n");
-+ DEBUGOUT(" Half Duplex\n");
- }
- } else {
-- DEBUGOUT("1000 Mbs, Full Duplex\r\n");
-+ DEBUGOUT("1000 Mbs, Full Duplex\n");
- *speed = SPEED_1000;
- *duplex = FULL_DUPLEX;
- }
-@@ -2227,23 +3007,39 @@ e1000_get_speed_and_duplex(struct e1000_
- * if it is operating at half duplex. Here we set the duplex settings to
- * match the duplex in the link partner's capabilities.
- */
-- if(hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
-+ if (hw->phy_type == e1000_phy_igp && hw->speed_downgraded) {
- ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if(!(phy_data & NWAY_ER_LP_NWAY_CAPS))
-+ if (!(phy_data & NWAY_ER_LP_NWAY_CAPS))
- *duplex = HALF_DUPLEX;
- else {
- ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-- if((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
-+ if ((*speed == SPEED_100 && !(phy_data & NWAY_LPAR_100TX_FD_CAPS)) ||
- (*speed == SPEED_10 && !(phy_data & NWAY_LPAR_10T_FD_CAPS)))
- *duplex = HALF_DUPLEX;
- }
- }
-
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (hw->media_type == e1000_media_type_copper)) {
-+ if (*speed == SPEED_1000)
-+ ret_val = e1000_configure_kmrn_for_1000(hw);
-+ else
-+ ret_val = e1000_configure_kmrn_for_10_100(hw, *duplex);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ if ((hw->phy_type == e1000_phy_igp_3) && (*speed == SPEED_1000)) {
-+ ret_val = e1000_kumeran_lock_loss_workaround(hw);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
- return E1000_SUCCESS;
- }
-
-@@ -2263,17 +3059,17 @@ e1000_wait_autoneg(struct e1000_hw *hw)
- DEBUGOUT("Waiting for Auto-Neg to complete.\n");
-
- /* We will wait for autoneg to complete or 4.5 seconds to expire. */
-- for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
-+ for (i = PHY_AUTO_NEG_TIME; i > 0; i--) {
- /* Read the MII Status Register and wait for Auto-Neg
- * Complete bit to be set.
- */
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-- if(phy_data & MII_SR_AUTONEG_COMPLETE) {
-+ if (phy_data & MII_SR_AUTONEG_COMPLETE) {
- return E1000_SUCCESS;
- }
- msec_delay(100);
-@@ -2296,7 +3092,7 @@ e1000_raise_mdi_clk(struct e1000_hw *hw,
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
-- udelay(10);
-+ usec_delay(10);
- }
-
- /******************************************************************************
-@@ -2314,7 +3110,7 @@ e1000_lower_mdi_clk(struct e1000_hw *hw,
- */
- E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
- E1000_WRITE_FLUSH(hw);
-- udelay(10);
-+ usec_delay(10);
- }
-
- /******************************************************************************
-@@ -2346,19 +3142,21 @@ e1000_shift_out_mdi_bits(struct e1000_hw
- /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
- ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
-
-- while(mask) {
-+ while (mask) {
- /* A "1" is shifted out to the PHY by setting the MDIO bit to "1" and
- * then raising and lowering the Management Data Clock. A "0" is
- * shifted out to the PHY by setting the MDIO bit to "0" and then
- * raising and lowering the clock.
- */
-- if(data & mask) ctrl |= E1000_CTRL_MDIO;
-- else ctrl &= ~E1000_CTRL_MDIO;
-+ if (data & mask)
-+ ctrl |= E1000_CTRL_MDIO;
-+ else
-+ ctrl &= ~E1000_CTRL_MDIO;
-
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-
-- udelay(10);
-+ usec_delay(10);
-
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-@@ -2404,12 +3202,13 @@ e1000_shift_in_mdi_bits(struct e1000_hw
- e1000_raise_mdi_clk(hw, &ctrl);
- e1000_lower_mdi_clk(hw, &ctrl);
-
-- for(data = 0, i = 0; i < 16; i++) {
-+ for (data = 0, i = 0; i < 16; i++) {
- data = data << 1;
- e1000_raise_mdi_clk(hw, &ctrl);
- ctrl = E1000_READ_REG(hw, CTRL);
- /* Check to see if we shifted in a "1". */
-- if(ctrl & E1000_CTRL_MDIO) data |= 1;
-+ if (ctrl & E1000_CTRL_MDIO)
-+ data |= 1;
- e1000_lower_mdi_clk(hw, &ctrl);
- }
-
-@@ -2419,6 +3218,80 @@ e1000_shift_in_mdi_bits(struct e1000_hw
- return data;
- }
-
-+int32_t
-+e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask)
-+{
-+ uint32_t swfw_sync = 0;
-+ uint32_t swmask = mask;
-+ uint32_t fwmask = mask << 16;
-+ int32_t timeout = 200;
-+
-+ DEBUGFUNC("e1000_swfw_sync_acquire");
-+
-+ if (hw->swfwhw_semaphore_present)
-+ return e1000_get_software_flag(hw);
-+
-+ if (!hw->swfw_sync_present)
-+ return e1000_get_hw_eeprom_semaphore(hw);
-+
-+ while (timeout) {
-+ if (e1000_get_hw_eeprom_semaphore(hw))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
-+ if (!(swfw_sync & (fwmask | swmask))) {
-+ break;
-+ }
-+
-+ /* firmware currently using resource (fwmask) */
-+ /* or other software thread currently using resource (swmask) */
-+ e1000_put_hw_eeprom_semaphore(hw);
-+ msec_delay_irq(5);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n");
-+ return -E1000_ERR_SWFW_SYNC;
-+ }
-+
-+ swfw_sync |= swmask;
-+ E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
-+
-+ e1000_put_hw_eeprom_semaphore(hw);
-+ return E1000_SUCCESS;
-+}
-+
-+void
-+e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask)
-+{
-+ uint32_t swfw_sync;
-+ uint32_t swmask = mask;
-+
-+ DEBUGFUNC("e1000_swfw_sync_release");
-+
-+ if (hw->swfwhw_semaphore_present) {
-+ e1000_release_software_flag(hw);
-+ return;
-+ }
-+
-+ if (!hw->swfw_sync_present) {
-+ e1000_put_hw_eeprom_semaphore(hw);
-+ return;
-+ }
-+
-+ /* if (e1000_get_hw_eeprom_semaphore(hw))
-+ * return -E1000_ERR_SWFW_SYNC; */
-+ while (e1000_get_hw_eeprom_semaphore(hw) != E1000_SUCCESS);
-+ /* empty */
-+
-+ swfw_sync = E1000_READ_REG(hw, SW_FW_SYNC);
-+ swfw_sync &= ~swmask;
-+ E1000_WRITE_REG(hw, SW_FW_SYNC, swfw_sync);
-+
-+ e1000_put_hw_eeprom_semaphore(hw);
-+}
-+
- /*****************************************************************************
- * Reads the value from a PHY register, if the value is on a specific non zero
- * page, sets the page first.
-@@ -2431,20 +3304,56 @@ e1000_read_phy_reg(struct e1000_hw *hw,
- uint16_t *phy_data)
- {
- uint32_t ret_val;
-+ uint16_t swfw;
-
- DEBUGFUNC("e1000_read_phy_reg");
-
-- if(hw->phy_type == e1000_phy_igp &&
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-+ swfw = E1000_SWFW_PHY1_SM;
-+ } else {
-+ swfw = E1000_SWFW_PHY0_SM;
-+ }
-+ if (e1000_swfw_sync_acquire(hw, swfw))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ if ((hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr);
-- if(ret_val)
-+ if (ret_val) {
-+ e1000_swfw_sync_release(hw, swfw);
- return ret_val;
-+ }
-+ } else if (hw->phy_type == e1000_phy_gg82563) {
-+ if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
-+ (hw->mac_type == e1000_80003es2lan)) {
-+ /* Select Configuration Page */
-+ if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
-+ ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
-+ (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT));
-+ } else {
-+ /* Use Alternative Page Select register to access
-+ * registers 30 and 31
-+ */
-+ ret_val = e1000_write_phy_reg_ex(hw,
-+ GG82563_PHY_PAGE_SELECT_ALT,
-+ (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT));
-+ }
-+
-+ if (ret_val) {
-+ e1000_swfw_sync_release(hw, swfw);
-+ return ret_val;
-+ }
-+ }
- }
-
-- ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
-+ ret_val = e1000_read_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
-+ e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
-
-@@ -2459,12 +3368,12 @@ e1000_read_phy_reg_ex(struct e1000_hw *h
-
- DEBUGFUNC("e1000_read_phy_reg_ex");
-
-- if(reg_addr > MAX_PHY_REG_ADDRESS) {
-+ if (reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
-- if(hw->mac_type > e1000_82543) {
-+ if (hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, and register address in the MDI
- * Control register. The MAC will take care of interfacing with the
- * PHY to retrieve the desired data.
-@@ -2476,16 +3385,16 @@ e1000_read_phy_reg_ex(struct e1000_hw *h
- E1000_WRITE_REG(hw, MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
-- for(i = 0; i < 64; i++) {
-- udelay(50);
-+ for (i = 0; i < 64; i++) {
-+ usec_delay(50);
- mdic = E1000_READ_REG(hw, MDIC);
-- if(mdic & E1000_MDIC_READY) break;
-+ if (mdic & E1000_MDIC_READY) break;
- }
-- if(!(mdic & E1000_MDIC_READY)) {
-+ if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Read did not complete\n");
- return -E1000_ERR_PHY;
- }
-- if(mdic & E1000_MDIC_ERROR) {
-+ if (mdic & E1000_MDIC_ERROR) {
- DEBUGOUT("MDI Error\n");
- return -E1000_ERR_PHY;
- }
-@@ -2535,20 +3444,56 @@ e1000_write_phy_reg(struct e1000_hw *hw,
- uint16_t phy_data)
- {
- uint32_t ret_val;
-+ uint16_t swfw;
-
- DEBUGFUNC("e1000_write_phy_reg");
-
-- if(hw->phy_type == e1000_phy_igp &&
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-+ swfw = E1000_SWFW_PHY1_SM;
-+ } else {
-+ swfw = E1000_SWFW_PHY0_SM;
-+ }
-+ if (e1000_swfw_sync_acquire(hw, swfw))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ if ((hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2) &&
- (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT,
- (uint16_t)reg_addr);
-- if(ret_val)
-+ if (ret_val) {
-+ e1000_swfw_sync_release(hw, swfw);
- return ret_val;
-+ }
-+ } else if (hw->phy_type == e1000_phy_gg82563) {
-+ if (((reg_addr & MAX_PHY_REG_ADDRESS) > MAX_PHY_MULTI_PAGE_REG) ||
-+ (hw->mac_type == e1000_80003es2lan)) {
-+ /* Select Configuration Page */
-+ if ((reg_addr & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
-+ ret_val = e1000_write_phy_reg_ex(hw, GG82563_PHY_PAGE_SELECT,
-+ (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT));
-+ } else {
-+ /* Use Alternative Page Select register to access
-+ * registers 30 and 31
-+ */
-+ ret_val = e1000_write_phy_reg_ex(hw,
-+ GG82563_PHY_PAGE_SELECT_ALT,
-+ (uint16_t)((uint16_t)reg_addr >> GG82563_PAGE_SHIFT));
-+ }
-+
-+ if (ret_val) {
-+ e1000_swfw_sync_release(hw, swfw);
-+ return ret_val;
-+ }
-+ }
- }
-
-- ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & reg_addr,
-+ ret_val = e1000_write_phy_reg_ex(hw, MAX_PHY_REG_ADDRESS & reg_addr,
- phy_data);
-
-+ e1000_swfw_sync_release(hw, swfw);
- return ret_val;
- }
-
-@@ -2563,12 +3508,12 @@ e1000_write_phy_reg_ex(struct e1000_hw *
-
- DEBUGFUNC("e1000_write_phy_reg_ex");
-
-- if(reg_addr > MAX_PHY_REG_ADDRESS) {
-+ if (reg_addr > MAX_PHY_REG_ADDRESS) {
- DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
- return -E1000_ERR_PARAM;
- }
-
-- if(hw->mac_type > e1000_82543) {
-+ if (hw->mac_type > e1000_82543) {
- /* Set up Op-code, Phy Address, register address, and data intended
- * for the PHY register in the MDI Control register. The MAC will take
- * care of interfacing with the PHY to send the desired data.
-@@ -2581,12 +3526,12 @@ e1000_write_phy_reg_ex(struct e1000_hw *
- E1000_WRITE_REG(hw, MDIC, mdic);
-
- /* Poll the ready bit to see if the MDI read completed */
-- for(i = 0; i < 640; i++) {
-- udelay(5);
-+ for (i = 0; i < 641; i++) {
-+ usec_delay(5);
- mdic = E1000_READ_REG(hw, MDIC);
-- if(mdic & E1000_MDIC_READY) break;
-+ if (mdic & E1000_MDIC_READY) break;
- }
-- if(!(mdic & E1000_MDIC_READY)) {
-+ if (!(mdic & E1000_MDIC_READY)) {
- DEBUGOUT("MDI Write did not complete\n");
- return -E1000_ERR_PHY;
- }
-@@ -2615,31 +3560,121 @@ e1000_write_phy_reg_ex(struct e1000_hw *
- return E1000_SUCCESS;
- }
-
-+int32_t
-+e1000_read_kmrn_reg(struct e1000_hw *hw,
-+ uint32_t reg_addr,
-+ uint16_t *data)
-+{
-+ uint32_t reg_val;
-+ uint16_t swfw;
-+ DEBUGFUNC("e1000_read_kmrn_reg");
-+
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-+ swfw = E1000_SWFW_PHY1_SM;
-+ } else {
-+ swfw = E1000_SWFW_PHY0_SM;
-+ }
-+ if (e1000_swfw_sync_acquire(hw, swfw))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ /* Write register address */
-+ reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
-+ E1000_KUMCTRLSTA_OFFSET) |
-+ E1000_KUMCTRLSTA_REN;
-+ E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
-+ usec_delay(2);
-+
-+ /* Read the data returned */
-+ reg_val = E1000_READ_REG(hw, KUMCTRLSTA);
-+ *data = (uint16_t)reg_val;
-+
-+ e1000_swfw_sync_release(hw, swfw);
-+ return E1000_SUCCESS;
-+}
-+
-+int32_t
-+e1000_write_kmrn_reg(struct e1000_hw *hw,
-+ uint32_t reg_addr,
-+ uint16_t data)
-+{
-+ uint32_t reg_val;
-+ uint16_t swfw;
-+ DEBUGFUNC("e1000_write_kmrn_reg");
-+
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-+ swfw = E1000_SWFW_PHY1_SM;
-+ } else {
-+ swfw = E1000_SWFW_PHY0_SM;
-+ }
-+ if (e1000_swfw_sync_acquire(hw, swfw))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ reg_val = ((reg_addr << E1000_KUMCTRLSTA_OFFSET_SHIFT) &
-+ E1000_KUMCTRLSTA_OFFSET) | data;
-+ E1000_WRITE_REG(hw, KUMCTRLSTA, reg_val);
-+ usec_delay(2);
-+
-+ e1000_swfw_sync_release(hw, swfw);
-+ return E1000_SUCCESS;
-+}
-+
- /******************************************************************************
- * Returns the PHY to the power-on reset state
- *
- * hw - Struct containing variables accessed by shared code
- ******************************************************************************/
--void
-+int32_t
- e1000_phy_hw_reset(struct e1000_hw *hw)
- {
- uint32_t ctrl, ctrl_ext;
- uint32_t led_ctrl;
-+ int32_t ret_val;
-+ uint16_t swfw;
-
- DEBUGFUNC("e1000_phy_hw_reset");
-
-+ /* In the case of the phy reset being blocked, it's not an error, we
-+ * simply return success without performing the reset. */
-+ ret_val = e1000_check_phy_reset_block(hw);
-+ if (ret_val)
-+ return E1000_SUCCESS;
-+
- DEBUGOUT("Resetting Phy...\n");
-
-- if(hw->mac_type > e1000_82543) {
-+ if (hw->mac_type > e1000_82543) {
-+ if ((hw->mac_type == e1000_80003es2lan) &&
-+ (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)) {
-+ swfw = E1000_SWFW_PHY1_SM;
-+ } else {
-+ swfw = E1000_SWFW_PHY0_SM;
-+ }
-+ if (e1000_swfw_sync_acquire(hw, swfw)) {
-+ e1000_release_software_semaphore(hw);
-+ return -E1000_ERR_SWFW_SYNC;
-+ }
- /* Read the device control register and assert the E1000_CTRL_PHY_RST
- * bit. Then, take it out of reset.
-+ * For pre-e1000_82571 hardware, we delay for 10ms between the assert
-+ * and deassert. For e1000_82571 hardware and later, we instead delay
-+ * for 50us between and 10ms after the deassertion.
- */
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
- E1000_WRITE_FLUSH(hw);
-- msec_delay(10);
-+
-+ if (hw->mac_type < e1000_82571)
-+ msec_delay(10);
-+ else
-+ usec_delay(100);
-+
- E1000_WRITE_REG(hw, CTRL, ctrl);
- E1000_WRITE_FLUSH(hw);
-+
-+ if (hw->mac_type >= e1000_82571)
-+ msec_delay_irq(10);
-+ e1000_swfw_sync_release(hw, swfw);
- } else {
- /* Read the Extended Device Control Register, assert the PHY_RESET_DIR
- * bit to put the PHY into reset. Then, take it out of reset.
-@@ -2654,15 +3689,26 @@ e1000_phy_hw_reset(struct e1000_hw *hw)
- E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
- E1000_WRITE_FLUSH(hw);
- }
-- udelay(150);
-+ usec_delay(150);
-
-- if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
-+ if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
- /* Configure activity LED after PHY reset */
- led_ctrl = E1000_READ_REG(hw, LEDCTL);
- led_ctrl &= IGP_ACTIVITY_LED_MASK;
- led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE);
- E1000_WRITE_REG(hw, LEDCTL, led_ctrl);
- }
-+
-+ /* Wait for FW to finish PHY configuration. */
-+ ret_val = e1000_get_phy_cfg_done(hw);
-+ if (ret_val != E1000_SUCCESS)
-+ return ret_val;
-+ e1000_release_software_semaphore(hw);
-+
-+ if ((hw->mac_type == e1000_ich8lan) && (hw->phy_type == e1000_phy_igp_3))
-+ ret_val = e1000_init_lcd_from_nvm(hw);
-+
-+ return ret_val;
- }
-
- /******************************************************************************
-@@ -2680,26 +3726,152 @@ e1000_phy_reset(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_phy_reset");
-
-- if(hw->mac_type != e1000_82541_rev_2) {
-+ /* In the case of the phy reset being blocked, it's not an error, we
-+ * simply return success without performing the reset. */
-+ ret_val = e1000_check_phy_reset_block(hw);
-+ if (ret_val)
-+ return E1000_SUCCESS;
-+
-+ switch (hw->mac_type) {
-+ case e1000_82541_rev_2:
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_ich8lan:
-+ ret_val = e1000_phy_hw_reset(hw);
-+ if (ret_val)
-+ return ret_val;
-+
-+ break;
-+ default:
- ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data |= MII_CR_RESET;
- ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- udelay(1);
-- } else e1000_phy_hw_reset(hw);
-+ usec_delay(1);
-+ break;
-+ }
-
-- if(hw->phy_type == e1000_phy_igp)
-+ if (hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2)
- e1000_phy_init_script(hw);
-
- return E1000_SUCCESS;
- }
-
- /******************************************************************************
-+* Work-around for 82566 power-down: on D3 entry-
-+* 1) disable gigabit link
-+* 2) write VR power-down enable
-+* 3) read it back
-+* if successful continue, else issue LCD reset and repeat
-+*
-+* hw - struct containing variables accessed by shared code
-+******************************************************************************/
-+void
-+e1000_phy_powerdown_workaround(struct e1000_hw *hw)
-+{
-+ int32_t reg;
-+ uint16_t phy_data;
-+ int32_t retry = 0;
-+
-+ DEBUGFUNC("e1000_phy_powerdown_workaround");
-+
-+ if (hw->phy_type != e1000_phy_igp_3)
-+ return;
-+
-+ do {
-+ /* Disable link */
-+ reg = E1000_READ_REG(hw, PHY_CTRL);
-+ E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
-+ E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
-+
-+ /* Write VR power-down enable */
-+ e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
-+ e1000_write_phy_reg(hw, IGP3_VR_CTRL, phy_data |
-+ IGP3_VR_CTRL_MODE_SHUT);
-+
-+ /* Read it back and test */
-+ e1000_read_phy_reg(hw, IGP3_VR_CTRL, &phy_data);
-+ if ((phy_data & IGP3_VR_CTRL_MODE_SHUT) || retry)
-+ break;
-+
-+ /* Issue PHY reset and repeat at most one more time */
-+ reg = E1000_READ_REG(hw, CTRL);
-+ E1000_WRITE_REG(hw, CTRL, reg | E1000_CTRL_PHY_RST);
-+ retry++;
-+ } while (retry);
-+
-+ return;
-+
-+}
-+
-+/******************************************************************************
-+* Work-around for 82566 Kumeran PCS lock loss:
-+* On link status change (i.e. PCI reset, speed change) and link is up and
-+* speed is gigabit-
-+* 0) if workaround is optionally disabled do nothing
-+* 1) wait 1ms for Kumeran link to come up
-+* 2) check Kumeran Diagnostic register PCS lock loss bit
-+* 3) if not set the link is locked (all is good), otherwise...
-+* 4) reset the PHY
-+* 5) repeat up to 10 times
-+* Note: this is only called for IGP3 copper when speed is 1gb.
-+*
-+* hw - struct containing variables accessed by shared code
-+******************************************************************************/
-+int32_t
-+e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ int32_t reg;
-+ int32_t cnt;
-+ uint16_t phy_data;
-+
-+ if (hw->kmrn_lock_loss_workaround_disabled)
-+ return E1000_SUCCESS;
-+
-+ /* Make sure link is up before proceeding. If not just return.
-+ * Attempting this while link is negotiating fouled up link
-+ * stability */
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-+
-+ if (phy_data & MII_SR_LINK_STATUS) {
-+ for (cnt = 0; cnt < 10; cnt++) {
-+ /* read once to clear */
-+ ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ /* and again to get new status */
-+ ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* check for PCS lock */
-+ if (!(phy_data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS))
-+ return E1000_SUCCESS;
-+
-+ /* Issue PHY reset */
-+ e1000_phy_hw_reset(hw);
-+ msec_delay_irq(5);
-+ }
-+ /* Disable GigE link negotiation */
-+ reg = E1000_READ_REG(hw, PHY_CTRL);
-+ E1000_WRITE_REG(hw, PHY_CTRL, reg | E1000_PHY_CTRL_GBE_DISABLE |
-+ E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
-+
-+ /* unable to acquire PCS lock */
-+ return E1000_ERR_PHY;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/******************************************************************************
- * Probes the expected PHY address for known PHY IDs
- *
- * hw - Struct containing variables accessed by shared code
-@@ -2713,39 +3885,70 @@ e1000_detect_gig_phy(struct e1000_hw *hw
-
- DEBUGFUNC("e1000_detect_gig_phy");
-
-+ /* The 82571 firmware may still be configuring the PHY. In this
-+ * case, we cannot access the PHY until the configuration is done. So
-+ * we explicitly set the PHY values. */
-+ if (hw->mac_type == e1000_82571 ||
-+ hw->mac_type == e1000_82572) {
-+ hw->phy_id = IGP01E1000_I_PHY_ID;
-+ hw->phy_type = e1000_phy_igp_2;
-+ return E1000_SUCCESS;
-+ }
-+
-+ /* ESB-2 PHY reads require e1000_phy_gg82563 to be set because of a work-
-+ * around that forces PHY page 0 to be set or the reads fail. The rest of
-+ * the code in this routine uses e1000_read_phy_reg to read the PHY ID.
-+ * So for ESB-2 we need to have this set so our reads won't fail. If the
-+ * attached PHY is not a e1000_phy_gg82563, the routines below will figure
-+ * this out as well. */
-+ if (hw->mac_type == e1000_80003es2lan)
-+ hw->phy_type = e1000_phy_gg82563;
-+
- /* Read the PHY ID Registers to identify which PHY is onboard. */
- ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- hw->phy_id = (uint32_t) (phy_id_high << 16);
-- udelay(20);
-+ usec_delay(20);
- ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
- hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82543:
-- if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
-+ if (hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
- break;
- case e1000_82544:
-- if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
-+ if (hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
- break;
- case e1000_82540:
- case e1000_82545:
- case e1000_82545_rev_3:
- case e1000_82546:
- case e1000_82546_rev_3:
-- if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
-+ if (hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
- case e1000_82547:
- case e1000_82547_rev_2:
-- if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
-+ if (hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
-+ break;
-+ case e1000_82573:
-+ if (hw->phy_id == M88E1111_I_PHY_ID) match = TRUE;
-+ break;
-+ case e1000_80003es2lan:
-+ if (hw->phy_id == GG82563_E_PHY_ID) match = TRUE;
-+ break;
-+ case e1000_ich8lan:
-+ if (hw->phy_id == IGP03E1000_E_PHY_ID) match = TRUE;
-+ if (hw->phy_id == IFE_E_PHY_ID) match = TRUE;
-+ if (hw->phy_id == IFE_PLUS_E_PHY_ID) match = TRUE;
-+ if (hw->phy_id == IFE_C_E_PHY_ID) match = TRUE;
- break;
- default:
- DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
-@@ -2773,14 +3976,16 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
- DEBUGFUNC("e1000_phy_reset_dsp");
-
- do {
-- ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
-- if(ret_val) break;
-+ if (hw->phy_type != e1000_phy_gg82563) {
-+ ret_val = e1000_write_phy_reg(hw, 29, 0x001d);
-+ if (ret_val) break;
-+ }
- ret_val = e1000_write_phy_reg(hw, 30, 0x00c1);
-- if(ret_val) break;
-+ if (ret_val) break;
- ret_val = e1000_write_phy_reg(hw, 30, 0x0000);
-- if(ret_val) break;
-+ if (ret_val) break;
- ret_val = E1000_SUCCESS;
-- } while(0);
-+ } while (0);
-
- return ret_val;
- }
-@@ -2802,7 +4007,7 @@ e1000_phy_igp_get_info(struct e1000_hw *
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
-- phy_info->downshift = hw->speed_downgraded;
-+ phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
-
- /* IGP01E1000 does not need to support it. */
- phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
-@@ -2812,23 +4017,23 @@ e1000_phy_igp_get_info(struct e1000_hw *
-
- /* Check polarity status */
- ret_val = e1000_check_polarity(hw, &polarity);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->cable_polarity = polarity;
-
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (phy_data & IGP01E1000_PSSR_MDIX) >>
- IGP01E1000_PSSR_MDIX_SHIFT;
-
-- if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-+ if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
- /* Local/Remote Receiver Information are only valid at 1000 Mbps */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-@@ -2838,19 +4043,19 @@ e1000_phy_igp_get_info(struct e1000_hw *
-
- /* Get cable length */
- ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- /* transalte to old method */
-+ /* Translate to old method */
- average = (max_length + min_length) / 2;
-
-- if(average <= e1000_igp_cable_length_50)
-+ if (average <= e1000_igp_cable_length_50)
- phy_info->cable_length = e1000_cable_length_50;
-- else if(average <= e1000_igp_cable_length_80)
-+ else if (average <= e1000_igp_cable_length_80)
- phy_info->cable_length = e1000_cable_length_50_80;
-- else if(average <= e1000_igp_cable_length_110)
-+ else if (average <= e1000_igp_cable_length_110)
- phy_info->cable_length = e1000_cable_length_80_110;
-- else if(average <= e1000_igp_cable_length_140)
-+ else if (average <= e1000_igp_cable_length_140)
- phy_info->cable_length = e1000_cable_length_110_140;
- else
- phy_info->cable_length = e1000_cable_length_140;
-@@ -2860,6 +4065,53 @@ e1000_phy_igp_get_info(struct e1000_hw *
- }
-
- /******************************************************************************
-+* Get PHY information from various PHY registers for ife PHY only.
-+*
-+* hw - Struct containing variables accessed by shared code
-+* phy_info - PHY information structure
-+******************************************************************************/
-+int32_t
-+e1000_phy_ife_get_info(struct e1000_hw *hw,
-+ struct e1000_phy_info *phy_info)
-+{
-+ int32_t ret_val;
-+ uint16_t phy_data, polarity;
-+
-+ DEBUGFUNC("e1000_phy_ife_get_info");
-+
-+ phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
-+ phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal;
-+
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ phy_info->polarity_correction =
-+ (phy_data & IFE_PSC_AUTO_POLARITY_DISABLE) >>
-+ IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT;
-+
-+ if (phy_info->polarity_correction == e1000_polarity_reversal_enabled) {
-+ ret_val = e1000_check_polarity(hw, &polarity);
-+ if (ret_val)
-+ return ret_val;
-+ } else {
-+ /* Polarity is forced. */
-+ polarity = (phy_data & IFE_PSC_FORCE_POLARITY) >>
-+ IFE_PSC_FORCE_POLARITY_SHIFT;
-+ }
-+ phy_info->cable_polarity = polarity;
-+
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_info->mdix_mode =
-+ (phy_data & (IFE_PMC_AUTO_MDIX | IFE_PMC_FORCE_MDIX)) >>
-+ IFE_PMC_MDIX_MODE_SHIFT;
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/******************************************************************************
- * Get PHY information from various PHY registers fot m88 PHY only.
- *
- * hw - Struct containing variables accessed by shared code
-@@ -2876,10 +4128,10 @@ e1000_phy_m88_get_info(struct e1000_hw *
-
- /* The downshift status is checked only once, after link is established,
- * and it stored in the hw->speed_downgraded parameter. */
-- phy_info->downshift = hw->speed_downgraded;
-+ phy_info->downshift = (e1000_downshift)hw->speed_downgraded;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->extended_10bt_distance =
-@@ -2891,27 +4143,35 @@ e1000_phy_m88_get_info(struct e1000_hw *
-
- /* Check polarity status */
- ret_val = e1000_check_polarity(hw, &polarity);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
--
- phy_info->cable_polarity = polarity;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->mdix_mode = (phy_data & M88E1000_PSSR_MDIX) >>
- M88E1000_PSSR_MDIX_SHIFT;
-
-- if(phy_data & M88E1000_PSSR_1000MBS) {
-- /* Cable Length Estimation and Local/Remote Receiver Informatoion
-- * are only valid at 1000 Mbps
-- */
-- phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-- M88E1000_PSSR_CABLE_LENGTH_SHIFT);
-+ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
-+ /* Cable Length Estimation and Local/Remote Receiver Information
-+ * are only valid at 1000 Mbps.
-+ */
-+ if (hw->phy_type != e1000_phy_gg82563) {
-+ phy_info->cable_length = ((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-+ M88E1000_PSSR_CABLE_LENGTH_SHIFT);
-+ } else {
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_info->cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
-+ }
-
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_info->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) >>
-@@ -2948,26 +4208,30 @@ e1000_phy_get_info(struct e1000_hw *hw,
- phy_info->local_rx = e1000_1000t_rx_status_undefined;
- phy_info->remote_rx = e1000_1000t_rx_status_undefined;
-
-- if(hw->media_type != e1000_media_type_copper) {
-+ if (hw->media_type != e1000_media_type_copper) {
- DEBUGOUT("PHY info is only valid for copper media\n");
- return -E1000_ERR_CONFIG;
- }
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- if((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
-+ if ((phy_data & MII_SR_LINK_STATUS) != MII_SR_LINK_STATUS) {
- DEBUGOUT("PHY info is only valid if link is up\n");
- return -E1000_ERR_CONFIG;
- }
-
-- if(hw->phy_type == e1000_phy_igp)
-+ if (hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2)
- return e1000_phy_igp_get_info(hw, phy_info);
-+ else if (hw->phy_type == e1000_phy_ife)
-+ return e1000_phy_ife_get_info(hw, phy_info);
- else
- return e1000_phy_m88_get_info(hw, phy_info);
- }
-@@ -2977,7 +4241,7 @@ e1000_validate_mdi_setting(struct e1000_
- {
- DEBUGFUNC("e1000_validate_mdi_settings");
-
-- if(!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
-+ if (!hw->autoneg && (hw->mdix == 0 || hw->mdix == 3)) {
- DEBUGOUT("Invalid MDI setting detected\n");
- hw->mdix = 1;
- return -E1000_ERR_CONFIG;
-@@ -2988,15 +4252,17 @@ e1000_validate_mdi_setting(struct e1000_
-
- /******************************************************************************
- * Sets up eeprom variables in the hw struct. Must be called after mac_type
-- * is configured.
-+ * is configured. Additionally, if this is ICH8, the flash controller GbE
-+ * registers must be mapped, or this will crash.
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
--void
-+int32_t
- e1000_init_eeprom_params(struct e1000_hw *hw)
- {
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t eecd = E1000_READ_REG(hw, EECD);
-+ int32_t ret_val = E1000_SUCCESS;
- uint16_t eeprom_size;
-
- DEBUGFUNC("e1000_init_eeprom_params");
-@@ -3011,6 +4277,8 @@ e1000_init_eeprom_params(struct e1000_hw
- eeprom->opcode_bits = 3;
- eeprom->address_bits = 6;
- eeprom->delay_usec = 50;
-+ eeprom->use_eerd = FALSE;
-+ eeprom->use_eewr = FALSE;
- break;
- case e1000_82540:
- case e1000_82545:
-@@ -3020,13 +4288,15 @@ e1000_init_eeprom_params(struct e1000_hw
- eeprom->type = e1000_eeprom_microwire;
- eeprom->opcode_bits = 3;
- eeprom->delay_usec = 50;
-- if(eecd & E1000_EECD_SIZE) {
-+ if (eecd & E1000_EECD_SIZE) {
- eeprom->word_size = 256;
- eeprom->address_bits = 8;
- } else {
- eeprom->word_size = 64;
- eeprom->address_bits = 6;
- }
-+ eeprom->use_eerd = FALSE;
-+ eeprom->use_eewr = FALSE;
- break;
- case e1000_82541:
- case e1000_82541_rev_2:
-@@ -3055,8 +4325,11 @@ e1000_init_eeprom_params(struct e1000_hw
- eeprom->address_bits = 6;
- }
- }
-+ eeprom->use_eerd = FALSE;
-+ eeprom->use_eewr = FALSE;
- break;
-- default:
-+ case e1000_82571:
-+ case e1000_82572:
- eeprom->type = e1000_eeprom_spi;
- eeprom->opcode_bits = 8;
- eeprom->delay_usec = 1;
-@@ -3067,40 +4340,103 @@ e1000_init_eeprom_params(struct e1000_hw
- eeprom->page_size = 8;
- eeprom->address_bits = 8;
- }
-+ eeprom->use_eerd = FALSE;
-+ eeprom->use_eewr = FALSE;
- break;
-- }
--
-- if (eeprom->type == e1000_eeprom_spi) {
-- eeprom->word_size = 64;
-- if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
-- eeprom_size &= EEPROM_SIZE_MASK;
--
-- switch (eeprom_size) {
-- case EEPROM_SIZE_16KB:
-- eeprom->word_size = 8192;
-- break;
-- case EEPROM_SIZE_8KB:
-- eeprom->word_size = 4096;
-- break;
-- case EEPROM_SIZE_4KB:
-- eeprom->word_size = 2048;
-- break;
-- case EEPROM_SIZE_2KB:
-- eeprom->word_size = 1024;
-- break;
-- case EEPROM_SIZE_1KB:
-- eeprom->word_size = 512;
-- break;
-- case EEPROM_SIZE_512B:
-- eeprom->word_size = 256;
-- break;
-- case EEPROM_SIZE_128B:
-- default:
-- eeprom->word_size = 64;
-- break;
-- }
-+ case e1000_82573:
-+ eeprom->type = e1000_eeprom_spi;
-+ eeprom->opcode_bits = 8;
-+ eeprom->delay_usec = 1;
-+ if (eecd & E1000_EECD_ADDR_BITS) {
-+ eeprom->page_size = 32;
-+ eeprom->address_bits = 16;
-+ } else {
-+ eeprom->page_size = 8;
-+ eeprom->address_bits = 8;
-+ }
-+ eeprom->use_eerd = TRUE;
-+ eeprom->use_eewr = TRUE;
-+ if (e1000_is_onboard_nvm_eeprom(hw) == FALSE) {
-+ eeprom->type = e1000_eeprom_flash;
-+ eeprom->word_size = 2048;
-+
-+ /* Ensure that the Autonomous FLASH update bit is cleared due to
-+ * Flash update issue on parts which use a FLASH for NVM. */
-+ eecd &= ~E1000_EECD_AUPDEN;
-+ E1000_WRITE_REG(hw, EECD, eecd);
-+ }
-+ break;
-+ case e1000_80003es2lan:
-+ eeprom->type = e1000_eeprom_spi;
-+ eeprom->opcode_bits = 8;
-+ eeprom->delay_usec = 1;
-+ if (eecd & E1000_EECD_ADDR_BITS) {
-+ eeprom->page_size = 32;
-+ eeprom->address_bits = 16;
-+ } else {
-+ eeprom->page_size = 8;
-+ eeprom->address_bits = 8;
-+ }
-+ eeprom->use_eerd = TRUE;
-+ eeprom->use_eewr = FALSE;
-+ break;
-+ case e1000_ich8lan:
-+ {
-+ int32_t i = 0;
-+ uint32_t flash_size = E1000_READ_ICH8_REG(hw, ICH8_FLASH_GFPREG);
-+
-+ eeprom->type = e1000_eeprom_ich8;
-+ eeprom->use_eerd = FALSE;
-+ eeprom->use_eewr = FALSE;
-+ eeprom->word_size = E1000_SHADOW_RAM_WORDS;
-+
-+ /* Zero the shadow RAM structure. But don't load it from NVM
-+ * so as to save time for driver init */
-+ if (hw->eeprom_shadow_ram != NULL) {
-+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
-+ hw->eeprom_shadow_ram[i].modified = FALSE;
-+ hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
-+ }
-+ }
-+
-+ hw->flash_base_addr = (flash_size & ICH8_GFPREG_BASE_MASK) *
-+ ICH8_FLASH_SECTOR_SIZE;
-+
-+ hw->flash_bank_size = ((flash_size >> 16) & ICH8_GFPREG_BASE_MASK) + 1;
-+ hw->flash_bank_size -= (flash_size & ICH8_GFPREG_BASE_MASK);
-+ hw->flash_bank_size *= ICH8_FLASH_SECTOR_SIZE;
-+ hw->flash_bank_size /= 2 * sizeof(uint16_t);
-+
-+ break;
-+ }
-+ default:
-+ break;
-+ }
-+
-+ if (eeprom->type == e1000_eeprom_spi) {
-+ /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to
-+ * 32KB (incremented by powers of 2).
-+ */
-+ if (hw->mac_type <= e1000_82547_rev_2) {
-+ /* Set to default value for initial eeprom read. */
-+ eeprom->word_size = 64;
-+ ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size);
-+ if (ret_val)
-+ return ret_val;
-+ eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT;
-+ /* 256B eeprom size was not supported in earlier hardware, so we
-+ * bump eeprom_size up one to ensure that "1" (which maps to 256B)
-+ * is never the result used in the shifting logic below. */
-+ if (eeprom_size)
-+ eeprom_size++;
-+ } else {
-+ eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >>
-+ E1000_EECD_SIZE_EX_SHIFT);
- }
-+
-+ eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT);
- }
-+ return ret_val;
- }
-
- /******************************************************************************
-@@ -3119,7 +4455,7 @@ e1000_raise_ee_clk(struct e1000_hw *hw,
- *eecd = *eecd | E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(hw->eeprom.delay_usec);
-+ usec_delay(hw->eeprom.delay_usec);
- }
-
- /******************************************************************************
-@@ -3138,7 +4474,7 @@ e1000_lower_ee_clk(struct e1000_hw *hw,
- *eecd = *eecd & ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, *eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(hw->eeprom.delay_usec);
-+ usec_delay(hw->eeprom.delay_usec);
- }
-
- /******************************************************************************
-@@ -3176,20 +4512,20 @@ e1000_shift_out_ee_bits(struct e1000_hw
- */
- eecd &= ~E1000_EECD_DI;
-
-- if(data & mask)
-+ if (data & mask)
- eecd |= E1000_EECD_DI;
-
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
-
- e1000_raise_ee_clk(hw, &eecd);
- e1000_lower_ee_clk(hw, &eecd);
-
- mask = mask >> 1;
-
-- } while(mask);
-+ } while (mask);
-
- /* We leave the "DI" bit set to "0" when we leave this routine. */
- eecd &= ~E1000_EECD_DI;
-@@ -3221,14 +4557,14 @@ e1000_shift_in_ee_bits(struct e1000_hw *
- eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
- data = 0;
-
-- for(i = 0; i < count; i++) {
-+ for (i = 0; i < count; i++) {
- data = data << 1;
- e1000_raise_ee_clk(hw, &eecd);
-
- eecd = E1000_READ_REG(hw, EECD);
-
- eecd &= ~(E1000_EECD_DI);
-- if(eecd & E1000_EECD_DO)
-+ if (eecd & E1000_EECD_DO)
- data |= 1;
-
- e1000_lower_ee_clk(hw, &eecd);
-@@ -3253,24 +4589,29 @@ e1000_acquire_eeprom(struct e1000_hw *hw
-
- DEBUGFUNC("e1000_acquire_eeprom");
-
-+ if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
-+ return -E1000_ERR_SWFW_SYNC;
- eecd = E1000_READ_REG(hw, EECD);
-
-- /* Request EEPROM Access */
-- if(hw->mac_type > e1000_82544) {
-- eecd |= E1000_EECD_REQ;
-- E1000_WRITE_REG(hw, EECD, eecd);
-- eecd = E1000_READ_REG(hw, EECD);
-- while((!(eecd & E1000_EECD_GNT)) &&
-- (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
-- i++;
-- udelay(5);
-- eecd = E1000_READ_REG(hw, EECD);
-- }
-- if(!(eecd & E1000_EECD_GNT)) {
-- eecd &= ~E1000_EECD_REQ;
-+ if (hw->mac_type != e1000_82573) {
-+ /* Request EEPROM Access */
-+ if (hw->mac_type > e1000_82544) {
-+ eecd |= E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
-- DEBUGOUT("Could not acquire EEPROM grant\n");
-- return -E1000_ERR_EEPROM;
-+ eecd = E1000_READ_REG(hw, EECD);
-+ while ((!(eecd & E1000_EECD_GNT)) &&
-+ (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
-+ i++;
-+ usec_delay(5);
-+ eecd = E1000_READ_REG(hw, EECD);
-+ }
-+ if (!(eecd & E1000_EECD_GNT)) {
-+ eecd &= ~E1000_EECD_REQ;
-+ E1000_WRITE_REG(hw, EECD, eecd);
-+ DEBUGOUT("Could not acquire EEPROM grant\n");
-+ e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
-+ return -E1000_ERR_EEPROM;
-+ }
- }
- }
-
-@@ -3288,7 +4629,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw
- /* Clear SK and CS */
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
-- udelay(1);
-+ usec_delay(1);
- }
-
- return E1000_SUCCESS;
-@@ -3307,39 +4648,39 @@ e1000_standby_eeprom(struct e1000_hw *hw
-
- eecd = E1000_READ_REG(hw, EECD);
-
-- if(eeprom->type == e1000_eeprom_microwire) {
-+ if (eeprom->type == e1000_eeprom_microwire) {
- eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
-
- /* Clock high */
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
-
- /* Select EEPROM */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
-
- /* Clock low */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-- } else if(eeprom->type == e1000_eeprom_spi) {
-+ usec_delay(eeprom->delay_usec);
-+ } else if (eeprom->type == e1000_eeprom_spi) {
- /* Toggle CS to flush commands */
- eecd |= E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
- eecd &= ~E1000_EECD_CS;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(eeprom->delay_usec);
-+ usec_delay(eeprom->delay_usec);
- }
- }
-
-@@ -3363,8 +4704,8 @@ e1000_release_eeprom(struct e1000_hw *hw
-
- E1000_WRITE_REG(hw, EECD, eecd);
-
-- udelay(hw->eeprom.delay_usec);
-- } else if(hw->eeprom.type == e1000_eeprom_microwire) {
-+ usec_delay(hw->eeprom.delay_usec);
-+ } else if (hw->eeprom.type == e1000_eeprom_microwire) {
- /* cleanup eeprom */
-
- /* CS on Microwire is active-high */
-@@ -3376,20 +4717,22 @@ e1000_release_eeprom(struct e1000_hw *hw
- eecd |= E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(hw->eeprom.delay_usec);
-+ usec_delay(hw->eeprom.delay_usec);
-
- /* Falling edge of clock */
- eecd &= ~E1000_EECD_SK;
- E1000_WRITE_REG(hw, EECD, eecd);
- E1000_WRITE_FLUSH(hw);
-- udelay(hw->eeprom.delay_usec);
-+ usec_delay(hw->eeprom.delay_usec);
- }
-
- /* Stop requesting EEPROM access */
-- if(hw->mac_type > e1000_82544) {
-+ if (hw->mac_type > e1000_82544) {
- eecd &= ~E1000_EECD_REQ;
- E1000_WRITE_REG(hw, EECD, eecd);
- }
-+
-+ e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
- }
-
- /******************************************************************************
-@@ -3418,16 +4761,16 @@ e1000_spi_eeprom_ready(struct e1000_hw *
- if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
- break;
-
-- udelay(5);
-+ usec_delay(5);
- retry_count += 5;
-
- e1000_standby_eeprom(hw);
-- } while(retry_count < EEPROM_MAX_RETRY_SPI);
-+ } while (retry_count < EEPROM_MAX_RETRY_SPI);
-
- /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
- * only 0-5mSec on 5V devices)
- */
-- if(retry_count >= EEPROM_MAX_RETRY_SPI) {
-+ if (retry_count >= EEPROM_MAX_RETRY_SPI) {
- DEBUGOUT("SPI EEPROM Status error\n");
- return -E1000_ERR_EEPROM;
- }
-@@ -3451,27 +4794,49 @@ e1000_read_eeprom(struct e1000_hw *hw,
- {
- struct e1000_eeprom_info *eeprom = &hw->eeprom;
- uint32_t i = 0;
-+ int32_t ret_val;
-
- DEBUGFUNC("e1000_read_eeprom");
-
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
-- if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
-+ if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
-
-- /* Prepare the EEPROM for reading */
-- if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-- return -E1000_ERR_EEPROM;
-+ /* FLASH reads without acquiring the semaphore are safe */
-+ if (e1000_is_onboard_nvm_eeprom(hw) == TRUE &&
-+ hw->eeprom.use_eerd == FALSE) {
-+ switch (hw->mac_type) {
-+ case e1000_80003es2lan:
-+ break;
-+ default:
-+ /* Prepare the EEPROM for reading */
-+ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
-+ return -E1000_ERR_EEPROM;
-+ break;
-+ }
-+ }
-+
-+ if (eeprom->use_eerd == TRUE) {
-+ ret_val = e1000_read_eeprom_eerd(hw, offset, words, data);
-+ if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) ||
-+ (hw->mac_type != e1000_82573))
-+ e1000_release_eeprom(hw);
-+ return ret_val;
-+ }
-
-- if(eeprom->type == e1000_eeprom_spi) {
-+ if (eeprom->type == e1000_eeprom_ich8)
-+ return e1000_read_eeprom_ich8(hw, offset, words, data);
-+
-+ if (eeprom->type == e1000_eeprom_spi) {
- uint16_t word_in;
- uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
-
-- if(e1000_spi_eeprom_ready(hw)) {
-+ if (e1000_spi_eeprom_ready(hw)) {
- e1000_release_eeprom(hw);
- return -E1000_ERR_EEPROM;
- }
-@@ -3479,7 +4844,7 @@ e1000_read_eeprom(struct e1000_hw *hw,
- e1000_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
-- if((eeprom->address_bits == 8) && (offset >= 128))
-+ if ((eeprom->address_bits == 8) && (offset >= 128))
- read_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the READ command (opcode + addr) */
-@@ -3495,7 +4860,7 @@ e1000_read_eeprom(struct e1000_hw *hw,
- word_in = e1000_shift_in_ee_bits(hw, 16);
- data[i] = (word_in >> 8) | (word_in << 8);
- }
-- } else if(eeprom->type == e1000_eeprom_microwire) {
-+ } else if (eeprom->type == e1000_eeprom_microwire) {
- for (i = 0; i < words; i++) {
- /* Send the READ command (opcode + addr) */
- e1000_shift_out_ee_bits(hw, EEPROM_READ_OPCODE_MICROWIRE,
-@@ -3517,6 +4882,141 @@ e1000_read_eeprom(struct e1000_hw *hw,
- }
-
- /******************************************************************************
-+ * Reads a 16 bit word from the EEPROM using the EERD register.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ * offset - offset of word in the EEPROM to read
-+ * data - word read from the EEPROM
-+ * words - number of words to read
-+ *****************************************************************************/
-+int32_t
-+e1000_read_eeprom_eerd(struct e1000_hw *hw,
-+ uint16_t offset,
-+ uint16_t words,
-+ uint16_t *data)
-+{
-+ uint32_t i, eerd = 0;
-+ int32_t error = 0;
-+
-+ for (i = 0; i < words; i++) {
-+ eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) +
-+ E1000_EEPROM_RW_REG_START;
-+
-+ E1000_WRITE_REG(hw, EERD, eerd);
-+ error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ);
-+
-+ if (error) {
-+ break;
-+ }
-+ data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA);
-+
-+ }
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Writes a 16 bit word from the EEPROM using the EEWR register.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ * offset - offset of word in the EEPROM to read
-+ * data - word read from the EEPROM
-+ * words - number of words to read
-+ *****************************************************************************/
-+int32_t
-+e1000_write_eeprom_eewr(struct e1000_hw *hw,
-+ uint16_t offset,
-+ uint16_t words,
-+ uint16_t *data)
-+{
-+ uint32_t register_value = 0;
-+ uint32_t i = 0;
-+ int32_t error = 0;
-+
-+ if (e1000_swfw_sync_acquire(hw, E1000_SWFW_EEP_SM))
-+ return -E1000_ERR_SWFW_SYNC;
-+
-+ for (i = 0; i < words; i++) {
-+ register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) |
-+ ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) |
-+ E1000_EEPROM_RW_REG_START;
-+
-+ error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-+ if (error) {
-+ break;
-+ }
-+
-+ E1000_WRITE_REG(hw, EEWR, register_value);
-+
-+ error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE);
-+
-+ if (error) {
-+ break;
-+ }
-+ }
-+
-+ e1000_swfw_sync_release(hw, E1000_SWFW_EEP_SM);
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Polls the status bit (bit 1) of the EERD to determine when the read is done.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ *****************************************************************************/
-+int32_t
-+e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
-+{
-+ uint32_t attempts = 100000;
-+ uint32_t i, reg = 0;
-+ int32_t done = E1000_ERR_EEPROM;
-+
-+ for (i = 0; i < attempts; i++) {
-+ if (eerd == E1000_EEPROM_POLL_READ)
-+ reg = E1000_READ_REG(hw, EERD);
-+ else
-+ reg = E1000_READ_REG(hw, EEWR);
-+
-+ if (reg & E1000_EEPROM_RW_REG_DONE) {
-+ done = E1000_SUCCESS;
-+ break;
-+ }
-+ usec_delay(5);
-+ }
-+
-+ return done;
-+}
-+
-+/***************************************************************************
-+* Description: Determines if the onboard NVM is FLASH or EEPROM.
-+*
-+* hw - Struct containing variables accessed by shared code
-+****************************************************************************/
-+boolean_t
-+e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
-+{
-+ uint32_t eecd = 0;
-+
-+ DEBUGFUNC("e1000_is_onboard_nvm_eeprom");
-+
-+ if (hw->mac_type == e1000_ich8lan)
-+ return FALSE;
-+
-+ if (hw->mac_type == e1000_82573) {
-+ eecd = E1000_READ_REG(hw, EECD);
-+
-+ /* Isolate bits 15 & 16 */
-+ eecd = ((eecd >> 15) & 0x03);
-+
-+ /* If both bits are set, device is Flash type */
-+ if (eecd == 0x03) {
-+ return FALSE;
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+/******************************************************************************
- * Verifies that the EEPROM has a valid checksum
- *
- * hw - Struct containing variables accessed by shared code
-@@ -3533,15 +5033,48 @@ e1000_validate_eeprom_checksum(struct e1
-
- DEBUGFUNC("e1000_validate_eeprom_checksum");
-
-- for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-- if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
-+ if ((hw->mac_type == e1000_82573) &&
-+ (e1000_is_onboard_nvm_eeprom(hw) == FALSE)) {
-+ /* Check bit 4 of word 10h. If it is 0, firmware is done updating
-+ * 10h-12h. Checksum may need to be fixed. */
-+ e1000_read_eeprom(hw, 0x10, 1, &eeprom_data);
-+ if ((eeprom_data & 0x10) == 0) {
-+ /* Read 0x23 and check bit 15. This bit is a 1 when the checksum
-+ * has already been fixed. If the checksum is still wrong and this
-+ * bit is a 1, we need to return bad checksum. Otherwise, we need
-+ * to set this bit to a 1 and update the checksum. */
-+ e1000_read_eeprom(hw, 0x23, 1, &eeprom_data);
-+ if ((eeprom_data & 0x8000) == 0) {
-+ eeprom_data |= 0x8000;
-+ e1000_write_eeprom(hw, 0x23, 1, &eeprom_data);
-+ e1000_update_eeprom_checksum(hw);
-+ }
-+ }
-+ }
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /* Drivers must allocate the shadow ram structure for the
-+ * EEPROM checksum to be updated. Otherwise, this bit as well
-+ * as the checksum must both be set correctly for this
-+ * validation to pass.
-+ */
-+ e1000_read_eeprom(hw, 0x19, 1, &eeprom_data);
-+ if ((eeprom_data & 0x40) == 0) {
-+ eeprom_data |= 0x40;
-+ e1000_write_eeprom(hw, 0x19, 1, &eeprom_data);
-+ e1000_update_eeprom_checksum(hw);
-+ }
-+ }
-+
-+ for (i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
-+ if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
-
-- if(checksum == (uint16_t) EEPROM_SUM)
-+ if (checksum == (uint16_t) EEPROM_SUM)
- return E1000_SUCCESS;
- else {
- DEBUGOUT("EEPROM Checksum Invalid\n");
-@@ -3560,22 +5093,33 @@ e1000_validate_eeprom_checksum(struct e1
- int32_t
- e1000_update_eeprom_checksum(struct e1000_hw *hw)
- {
-+ uint32_t ctrl_ext;
- uint16_t checksum = 0;
- uint16_t i, eeprom_data;
-
- DEBUGFUNC("e1000_update_eeprom_checksum");
-
-- for(i = 0; i < EEPROM_CHECKSUM_REG; i++) {
-- if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
-+ for (i = 0; i < EEPROM_CHECKSUM_REG; i++) {
-+ if (e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- checksum += eeprom_data;
- }
- checksum = (uint16_t) EEPROM_SUM - checksum;
-- if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
-+ if (e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) {
- DEBUGOUT("EEPROM Write Error\n");
- return -E1000_ERR_EEPROM;
-+ } else if (hw->eeprom.type == e1000_eeprom_flash) {
-+ e1000_commit_shadow_ram(hw);
-+ } else if (hw->eeprom.type == e1000_eeprom_ich8) {
-+ e1000_commit_shadow_ram(hw);
-+ /* Reload the EEPROM, or else modifications will not appear
-+ * until after next adapter reset. */
-+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-+ ctrl_ext |= E1000_CTRL_EXT_EE_RST;
-+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-+ msec_delay(10);
- }
- return E1000_SUCCESS;
- }
-@@ -3605,17 +5149,24 @@ e1000_write_eeprom(struct e1000_hw *hw,
- /* A check for invalid values: offset too large, too many words, and not
- * enough words.
- */
-- if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) ||
-+ if ((offset >= eeprom->word_size) || (words > eeprom->word_size - offset) ||
- (words == 0)) {
- DEBUGOUT("\"words\" parameter out of bounds\n");
- return -E1000_ERR_EEPROM;
- }
-
-+ /* 82573 writes only through eewr */
-+ if (eeprom->use_eewr == TRUE)
-+ return e1000_write_eeprom_eewr(hw, offset, words, data);
-+
-+ if (eeprom->type == e1000_eeprom_ich8)
-+ return e1000_write_eeprom_ich8(hw, offset, words, data);
-+
- /* Prepare the EEPROM for writing */
- if (e1000_acquire_eeprom(hw) != E1000_SUCCESS)
- return -E1000_ERR_EEPROM;
-
-- if(eeprom->type == e1000_eeprom_microwire) {
-+ if (eeprom->type == e1000_eeprom_microwire) {
- status = e1000_write_eeprom_microwire(hw, offset, words, data);
- } else {
- status = e1000_write_eeprom_spi(hw, offset, words, data);
-@@ -3651,7 +5202,7 @@ e1000_write_eeprom_spi(struct e1000_hw *
- while (widx < words) {
- uint8_t write_opcode = EEPROM_WRITE_OPCODE_SPI;
-
-- if(e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
-+ if (e1000_spi_eeprom_ready(hw)) return -E1000_ERR_EEPROM;
-
- e1000_standby_eeprom(hw);
-
-@@ -3662,7 +5213,7 @@ e1000_write_eeprom_spi(struct e1000_hw *
- e1000_standby_eeprom(hw);
-
- /* Some SPI eeproms use the 8th address bit embedded in the opcode */
-- if((eeprom->address_bits == 8) && (offset >= 128))
-+ if ((eeprom->address_bits == 8) && (offset >= 128))
- write_opcode |= EEPROM_A8_OPCODE_SPI;
-
- /* Send the Write command (8-bit opcode + addr) */
-@@ -3684,7 +5235,7 @@ e1000_write_eeprom_spi(struct e1000_hw *
- * operation, while the smaller eeproms are capable of an 8-byte
- * PAGE WRITE operation. Break the inner loop to pass new address
- */
-- if((((offset + widx)*2) % eeprom->page_size) == 0) {
-+ if ((((offset + widx)*2) % eeprom->page_size) == 0) {
- e1000_standby_eeprom(hw);
- break;
- }
-@@ -3750,12 +5301,12 @@ e1000_write_eeprom_microwire(struct e100
- * signal that the command has been completed by raising the DO signal.
- * If DO does not go high in 10 milliseconds, then error out.
- */
-- for(i = 0; i < 200; i++) {
-+ for (i = 0; i < 200; i++) {
- eecd = E1000_READ_REG(hw, EECD);
-- if(eecd & E1000_EECD_DO) break;
-- udelay(50);
-+ if (eecd & E1000_EECD_DO) break;
-+ usec_delay(50);
- }
-- if(i == 200) {
-+ if (i == 200) {
- DEBUGOUT("EEPROM Write did not complete\n");
- return -E1000_ERR_EEPROM;
- }
-@@ -3781,6 +5332,171 @@ e1000_write_eeprom_microwire(struct e100
- }
-
- /******************************************************************************
-+ * Flushes the cached eeprom to NVM. This is done by saving the modified values
-+ * in the eeprom cache and the non modified values in the currently active bank
-+ * to the new bank.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ * offset - offset of word in the EEPROM to read
-+ * data - word read from the EEPROM
-+ * words - number of words to read
-+ *****************************************************************************/
-+int32_t
-+e1000_commit_shadow_ram(struct e1000_hw *hw)
-+{
-+ uint32_t attempts = 100000;
-+ uint32_t eecd = 0;
-+ uint32_t flop = 0;
-+ uint32_t i = 0;
-+ int32_t error = E1000_SUCCESS;
-+ uint32_t old_bank_offset = 0;
-+ uint32_t new_bank_offset = 0;
-+ uint32_t sector_retries = 0;
-+ uint8_t low_byte = 0;
-+ uint8_t high_byte = 0;
-+ uint8_t temp_byte = 0;
-+ boolean_t sector_write_failed = FALSE;
-+
-+ if (hw->mac_type == e1000_82573) {
-+ /* The flop register will be used to determine if flash type is STM */
-+ flop = E1000_READ_REG(hw, FLOP);
-+ for (i=0; i < attempts; i++) {
-+ eecd = E1000_READ_REG(hw, EECD);
-+ if ((eecd & E1000_EECD_FLUPD) == 0) {
-+ break;
-+ }
-+ usec_delay(5);
-+ }
-+
-+ if (i == attempts) {
-+ return -E1000_ERR_EEPROM;
-+ }
-+
-+ /* If STM opcode located in bits 15:8 of flop, reset firmware */
-+ if ((flop & 0xFF00) == E1000_STM_OPCODE) {
-+ E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET);
-+ }
-+
-+ /* Perform the flash update */
-+ E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD);
-+
-+ for (i=0; i < attempts; i++) {
-+ eecd = E1000_READ_REG(hw, EECD);
-+ if ((eecd & E1000_EECD_FLUPD) == 0) {
-+ break;
-+ }
-+ usec_delay(5);
-+ }
-+
-+ if (i == attempts) {
-+ return -E1000_ERR_EEPROM;
-+ }
-+ }
-+
-+ if (hw->mac_type == e1000_ich8lan && hw->eeprom_shadow_ram != NULL) {
-+ /* We're writing to the opposite bank so if we're on bank 1,
-+ * write to bank 0 etc. We also need to erase the segment that
-+ * is going to be written */
-+ if (!(E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL)) {
-+ new_bank_offset = hw->flash_bank_size * 2;
-+ old_bank_offset = 0;
-+ e1000_erase_ich8_4k_segment(hw, 1);
-+ } else {
-+ old_bank_offset = hw->flash_bank_size * 2;
-+ new_bank_offset = 0;
-+ e1000_erase_ich8_4k_segment(hw, 0);
-+ }
-+
-+ do {
-+ sector_write_failed = FALSE;
-+ /* Loop for every byte in the shadow RAM,
-+ * which is in units of words. */
-+ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
-+ /* Determine whether to write the value stored
-+ * in the other NVM bank or a modified value stored
-+ * in the shadow RAM */
-+ if (hw->eeprom_shadow_ram[i].modified == TRUE) {
-+ low_byte = (uint8_t)hw->eeprom_shadow_ram[i].eeprom_word;
-+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-+ &temp_byte);
-+ usec_delay(100);
-+ error = e1000_verify_write_ich8_byte(hw,
-+ (i << 1) + new_bank_offset,
-+ low_byte);
-+ if (error != E1000_SUCCESS)
-+ sector_write_failed = TRUE;
-+ high_byte =
-+ (uint8_t)(hw->eeprom_shadow_ram[i].eeprom_word >> 8);
-+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
-+ &temp_byte);
-+ usec_delay(100);
-+ } else {
-+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset,
-+ &low_byte);
-+ usec_delay(100);
-+ error = e1000_verify_write_ich8_byte(hw,
-+ (i << 1) + new_bank_offset, low_byte);
-+ if (error != E1000_SUCCESS)
-+ sector_write_failed = TRUE;
-+ e1000_read_ich8_byte(hw, (i << 1) + old_bank_offset + 1,
-+ &high_byte);
-+ }
-+
-+ /* If the word is 0x13, then make sure the signature bits
-+ * (15:14) are 11b until the commit has completed.
-+ * This will allow us to write 10b which indicates the
-+ * signature is valid. We want to do this after the write
-+ * has completed so that we don't mark the segment valid
-+ * while the write is still in progress */
-+ if (i == E1000_ICH8_NVM_SIG_WORD)
-+ high_byte = E1000_ICH8_NVM_SIG_MASK | high_byte;
-+
-+ error = e1000_verify_write_ich8_byte(hw,
-+ (i << 1) + new_bank_offset + 1, high_byte);
-+ if (error != E1000_SUCCESS)
-+ sector_write_failed = TRUE;
-+
-+ if (sector_write_failed == FALSE) {
-+ /* Clear the now not used entry in the cache */
-+ hw->eeprom_shadow_ram[i].modified = FALSE;
-+ hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
-+ }
-+ }
-+
-+ /* Don't bother writing the segment valid bits if sector
-+ * programming failed. */
-+ if (sector_write_failed == FALSE) {
-+ /* Finally validate the new segment by setting bit 15:14
-+ * to 10b in word 0x13 , this can be done without an
-+ * erase as well since these bits are 11 to start with
-+ * and we need to change bit 14 to 0b */
-+ e1000_read_ich8_byte(hw,
-+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-+ &high_byte);
-+ high_byte &= 0xBF;
-+ error = e1000_verify_write_ich8_byte(hw,
-+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + new_bank_offset,
-+ high_byte);
-+ if (error != E1000_SUCCESS)
-+ sector_write_failed = TRUE;
-+
-+ /* And invalidate the previously valid segment by setting
-+ * its signature word (0x13) high_byte to 0b. This can be
-+ * done without an erase because flash erase sets all bits
-+ * to 1's. We can write 1's to 0's without an erase */
-+ error = e1000_verify_write_ich8_byte(hw,
-+ E1000_ICH8_NVM_SIG_WORD * 2 + 1 + old_bank_offset,
-+ 0);
-+ if (error != E1000_SUCCESS)
-+ sector_write_failed = TRUE;
-+ }
-+ } while (++sector_retries < 10 && sector_write_failed == TRUE);
-+ }
-+
-+ return error;
-+}
-+
-+/******************************************************************************
- * Reads the adapter's part number from the EEPROM
- *
- * hw - Struct containing variables accessed by shared code
-@@ -3796,7 +5512,7 @@ e1000_read_part_num(struct e1000_hw *hw,
- DEBUGFUNC("e1000_read_part_num");
-
- /* Get word 0 from EEPROM */
-- if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
-+ if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
-@@ -3804,7 +5520,7 @@ e1000_read_part_num(struct e1000_hw *hw,
- *part_num = (uint32_t) (eeprom_data << 16);
-
- /* Get word 1 from EEPROM */
-- if(e1000_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) {
-+ if (e1000_read_eeprom(hw, ++offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
-@@ -3828,20 +5544,29 @@ e1000_read_mac_addr(struct e1000_hw * hw
-
- DEBUGFUNC("e1000_read_mac_addr");
-
-- for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
-+ for (i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
- offset = i >> 1;
-- if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
-+ if (e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
- hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
- hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
- }
-- if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
-- (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
-+
-+ switch (hw->mac_type) {
-+ default:
-+ break;
-+ case e1000_82546:
-+ case e1000_82546_rev_3:
-+ case e1000_82571:
-+ case e1000_80003es2lan:
-+ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
- hw->perm_mac_addr[5] ^= 0x01;
-+ break;
-+ }
-
-- for(i = 0; i < NODE_ADDRESS_SIZE; i++)
-+ for (i = 0; i < NODE_ADDRESS_SIZE; i++)
- hw->mac_addr[i] = hw->perm_mac_addr[i];
- return E1000_SUCCESS;
- }
-@@ -3859,6 +5584,7 @@ void
- e1000_init_rx_addrs(struct e1000_hw *hw)
- {
- uint32_t i;
-+ uint32_t rar_num;
-
- DEBUGFUNC("e1000_init_rx_addrs");
-
-@@ -3867,11 +5593,23 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
-
- e1000_rar_set(hw, hw->mac_addr, 0);
-
-+ rar_num = E1000_RAR_ENTRIES;
-+
-+ /* Reserve a spot for the Locally Administered Address to work around
-+ * an 82571 issue in which a reset on one port will reload the MAC on
-+ * the other port. */
-+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
-+ rar_num -= 1;
-+ if (hw->mac_type == e1000_ich8lan)
-+ rar_num = E1000_RAR_ENTRIES_ICH8LAN;
-+
- /* Zero out the other 15 receive addresses. */
- DEBUGOUT("Clearing RAR[1-15]\n");
-- for(i = 1; i < E1000_RAR_ENTRIES; i++) {
-+ for (i = 1; i < rar_num; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-+ E1000_WRITE_FLUSH(hw);
- }
- }
-
-@@ -3898,6 +5636,8 @@ e1000_mc_addr_list_update(struct e1000_h
- {
- uint32_t hash_value;
- uint32_t i;
-+ uint32_t num_rar_entry;
-+ uint32_t num_mta_entry;
-
- DEBUGFUNC("e1000_mc_addr_list_update");
-
-@@ -3906,19 +5646,34 @@ e1000_mc_addr_list_update(struct e1000_h
-
- /* Clear RAR[1-15] */
- DEBUGOUT(" Clearing RAR[1-15]\n");
-- for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) {
-+ num_rar_entry = E1000_RAR_ENTRIES;
-+ if (hw->mac_type == e1000_ich8lan)
-+ num_rar_entry = E1000_RAR_ENTRIES_ICH8LAN;
-+ /* Reserve a spot for the Locally Administered Address to work around
-+ * an 82571 issue in which a reset on one port will reload the MAC on
-+ * the other port. */
-+ if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
-+ num_rar_entry -= 1;
-+
-+ for (i = rar_used_count; i < num_rar_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
-+ E1000_WRITE_FLUSH(hw);
- }
-
- /* Clear the MTA */
- DEBUGOUT(" Clearing MTA\n");
-- for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) {
-+ num_mta_entry = E1000_NUM_MTA_REGISTERS;
-+ if (hw->mac_type == e1000_ich8lan)
-+ num_mta_entry = E1000_NUM_MTA_REGISTERS_ICH8LAN;
-+ for (i = 0; i < num_mta_entry; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-+ E1000_WRITE_FLUSH(hw);
- }
-
- /* Add the new addresses */
-- for(i = 0; i < mc_addr_count; i++) {
-+ for (i = 0; i < mc_addr_count; i++) {
- DEBUGOUT(" Adding the multicast addresses:\n");
- DEBUGOUT7(" MC Addr #%d =%.2X %.2X %.2X %.2X %.2X %.2X\n", i,
- mc_addr_list[i * (ETH_LENGTH_OF_ADDRESS + pad)],
-@@ -3937,7 +5692,7 @@ e1000_mc_addr_list_update(struct e1000_h
- /* Place this multicast address in the RAR if there is room, *
- * else put it in the MTA
- */
-- if(rar_used_count < E1000_RAR_ENTRIES) {
-+ if (rar_used_count < num_rar_entry) {
- e1000_rar_set(hw,
- mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)),
- rar_used_count);
-@@ -3970,24 +5725,47 @@ e1000_hash_mc_addr(struct e1000_hw *hw,
- * LSB MSB
- */
- case 0:
-- /* [47:36] i.e. 0x563 for above example address */
-- hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /* [47:38] i.e. 0x158 for above example address */
-+ hash_value = ((mc_addr[4] >> 6) | (((uint16_t) mc_addr[5]) << 2));
-+ } else {
-+ /* [47:36] i.e. 0x563 for above example address */
-+ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
-+ }
- break;
- case 1:
-- /* [46:35] i.e. 0xAC6 for above example address */
-- hash_value = ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /* [46:37] i.e. 0x2B1 for above example address */
-+ hash_value = ((mc_addr[4] >> 5) | (((uint16_t) mc_addr[5]) << 3));
-+ } else {
-+ /* [46:35] i.e. 0xAC6 for above example address */
-+ hash_value = ((mc_addr[4] >> 3) | (((uint16_t) mc_addr[5]) << 5));
-+ }
- break;
- case 2:
-- /* [45:34] i.e. 0x5D8 for above example address */
-- hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /*[45:36] i.e. 0x163 for above example address */
-+ hash_value = ((mc_addr[4] >> 4) | (((uint16_t) mc_addr[5]) << 4));
-+ } else {
-+ /* [45:34] i.e. 0x5D8 for above example address */
-+ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
-+ }
- break;
- case 3:
-- /* [43:32] i.e. 0x634 for above example address */
-- hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8));
-+ if (hw->mac_type == e1000_ich8lan) {
-+ /* [43:34] i.e. 0x18D for above example address */
-+ hash_value = ((mc_addr[4] >> 2) | (((uint16_t) mc_addr[5]) << 6));
-+ } else {
-+ /* [43:32] i.e. 0x634 for above example address */
-+ hash_value = ((mc_addr[4]) | (((uint16_t) mc_addr[5]) << 8));
-+ }
- break;
- }
-
- hash_value &= 0xFFF;
-+ if (hw->mac_type == e1000_ich8lan)
-+ hash_value &= 0x3FF;
-+
- return hash_value;
- }
-
-@@ -4014,6 +5792,8 @@ e1000_mta_set(struct e1000_hw *hw,
- * register are determined by the lower 5 bits of the value.
- */
- hash_reg = (hash_value >> 5) & 0x7F;
-+ if (hw->mac_type == e1000_ich8lan)
-+ hash_reg &= 0x1F;
- hash_bit = hash_value & 0x1F;
-
- mta = E1000_READ_REG_ARRAY(hw, MTA, hash_reg);
-@@ -4024,12 +5804,15 @@ e1000_mta_set(struct e1000_hw *hw,
- * in the MTA, save off the previous entry before writing and
- * restore the old value after writing.
- */
-- if((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
-+ if ((hw->mac_type == e1000_82544) && ((hash_reg & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, MTA, (hash_reg - 1));
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, MTA, (hash_reg - 1), temp);
-+ E1000_WRITE_FLUSH(hw);
- } else {
- E1000_WRITE_REG_ARRAY(hw, MTA, hash_reg, mta);
-+ E1000_WRITE_FLUSH(hw);
- }
- }
-
-@@ -4053,11 +5836,42 @@ e1000_rar_set(struct e1000_hw *hw,
- rar_low = ((uint32_t) addr[0] |
- ((uint32_t) addr[1] << 8) |
- ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
-+ rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8));
-
-- rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8) | E1000_RAH_AV);
-+ /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
-+ * unit hang.
-+ *
-+ * Description:
-+ * If there are any Rx frames queued up or otherwise present in the HW
-+ * before RSS is enabled, and then we enable RSS, the HW Rx unit will
-+ * hang. To work around this issue, we have to disable receives and
-+ * flush out all Rx frames before we enable RSS. To do so, we modify we
-+ * redirect all Rx traffic to manageability and then reset the HW.
-+ * This flushes away Rx frames, and (since the redirections to
-+ * manageability persists across resets) keeps new ones from coming in
-+ * while we work. Then, we clear the Address Valid AV bit for all MAC
-+ * addresses and undo the re-direction to manageability.
-+ * Now, frames are coming in again, but the MAC won't accept them, so
-+ * far so good. We now proceed to initialize RSS (if necessary) and
-+ * configure the Rx unit. Last, we re-enable the AV bits and continue
-+ * on our merry way.
-+ */
-+ switch (hw->mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+ if (hw->leave_av_bit_off == TRUE)
-+ break;
-+ default:
-+ /* Indicate to hardware the Address is Valid. */
-+ rar_high |= E1000_RAH_AV;
-+ break;
-+ }
-
- E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
-+ E1000_WRITE_FLUSH(hw);
- }
-
- /******************************************************************************
-@@ -4074,12 +5888,18 @@ e1000_write_vfta(struct e1000_hw *hw,
- {
- uint32_t temp;
-
-- if((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
-+ if (hw->mac_type == e1000_ich8lan)
-+ return;
-+
-+ if ((hw->mac_type == e1000_82544) && ((offset & 0x1) == 1)) {
- temp = E1000_READ_REG_ARRAY(hw, VFTA, (offset - 1));
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, VFTA, (offset - 1), temp);
-+ E1000_WRITE_FLUSH(hw);
- } else {
- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, value);
-+ E1000_WRITE_FLUSH(hw);
- }
- }
-
-@@ -4092,12 +5912,37 @@ void
- e1000_clear_vfta(struct e1000_hw *hw)
- {
- uint32_t offset;
-+ uint32_t vfta_value = 0;
-+ uint32_t vfta_offset = 0;
-+ uint32_t vfta_bit_in_reg = 0;
-+
-+ if (hw->mac_type == e1000_ich8lan)
-+ return;
-
-- for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
-- E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
-+ if (hw->mac_type == 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. */
-+ 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, VFTA, offset, vfta_value);
-+ E1000_WRITE_FLUSH(hw);
-+ }
- }
-
--static int32_t
-+int32_t
- e1000_id_led_init(struct e1000_hw * hw)
- {
- uint32_t ledctl;
-@@ -4109,7 +5954,7 @@ e1000_id_led_init(struct e1000_hw * hw)
-
- DEBUGFUNC("e1000_id_led_init");
-
-- if(hw->mac_type < e1000_82540) {
-+ if (hw->mac_type < e1000_82540) {
- /* Nothing to do */
- return E1000_SUCCESS;
- }
-@@ -4119,15 +5964,24 @@ e1000_id_led_init(struct e1000_hw * hw)
- hw->ledctl_mode1 = hw->ledctl_default;
- hw->ledctl_mode2 = hw->ledctl_default;
-
-- if(e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
-+ if (e1000_read_eeprom(hw, EEPROM_ID_LED_SETTINGS, 1, &eeprom_data) < 0) {
- DEBUGOUT("EEPROM Read Error\n");
- return -E1000_ERR_EEPROM;
- }
-- if((eeprom_data== ID_LED_RESERVED_0000) ||
-- (eeprom_data == ID_LED_RESERVED_FFFF)) eeprom_data = ID_LED_DEFAULT;
-- for(i = 0; i < 4; i++) {
-+
-+ if ((hw->mac_type == e1000_82573) &&
-+ (eeprom_data == ID_LED_RESERVED_82573))
-+ eeprom_data = ID_LED_DEFAULT_82573;
-+ else if ((eeprom_data == ID_LED_RESERVED_0000) ||
-+ (eeprom_data == ID_LED_RESERVED_FFFF)) {
-+ if (hw->mac_type == e1000_ich8lan)
-+ eeprom_data = ID_LED_DEFAULT_ICH8LAN;
-+ else
-+ eeprom_data = ID_LED_DEFAULT;
-+ }
-+ for (i = 0; i < 4; i++) {
- temp = (eeprom_data >> (i << 2)) & led_mask;
-- switch(temp) {
-+ switch (temp) {
- case ID_LED_ON1_DEF2:
- case ID_LED_ON1_ON2:
- case ID_LED_ON1_OFF2:
-@@ -4144,7 +5998,7 @@ e1000_id_led_init(struct e1000_hw * hw)
- /* Do nothing */
- break;
- }
-- switch(temp) {
-+ switch (temp) {
- case ID_LED_DEF1_ON2:
- case ID_LED_ON1_ON2:
- case ID_LED_OFF1_ON2:
-@@ -4178,7 +6032,7 @@ e1000_setup_led(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_setup_led");
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
-@@ -4192,16 +6046,16 @@ e1000_setup_led(struct e1000_hw *hw)
- /* Turn off PHY Smart Power Down (if enabled) */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO,
- &hw->phy_spd_default);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- (uint16_t)(hw->phy_spd_default &
- ~IGP01E1000_GMII_SPD));
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- /* Fall Through */
- default:
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- ledctl = E1000_READ_REG(hw, LEDCTL);
- /* Save current LEDCTL settings */
- hw->ledctl_default = ledctl;
-@@ -4212,7 +6066,7 @@ e1000_setup_led(struct e1000_hw *hw)
- ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
- E1000_LEDCTL_LED0_MODE_SHIFT);
- E1000_WRITE_REG(hw, LEDCTL, ledctl);
-- } else if(hw->media_type == e1000_media_type_copper)
-+ } else if (hw->media_type == e1000_media_type_copper)
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
- break;
- }
-@@ -4220,22 +6074,61 @@ e1000_setup_led(struct e1000_hw *hw)
- return E1000_SUCCESS;
- }
-
-+
- /******************************************************************************
-- * Restores the saved state of the SW controlable LED.
-+ * Used on 82571 and later Si that has LED blink bits.
-+ * Callers must use their own timer and should have already called
-+ * e1000_id_led_init()
-+ * Call e1000_cleanup led() to stop blinking
- *
- * hw - Struct containing variables accessed by shared code
- *****************************************************************************/
- int32_t
--e1000_cleanup_led(struct e1000_hw *hw)
-+e1000_blink_led_start(struct e1000_hw *hw)
- {
-- int32_t ret_val = E1000_SUCCESS;
-+ int16_t i;
-+ uint32_t ledctl_blink = 0;
-
-- DEBUGFUNC("e1000_cleanup_led");
-+ DEBUGFUNC("e1000_id_led_blink_on");
-
-- switch(hw->mac_type) {
-- case e1000_82542_rev2_0:
-- case e1000_82542_rev2_1:
-- case e1000_82543:
-+ if (hw->mac_type < e1000_82571) {
-+ /* Nothing to do */
-+ return E1000_SUCCESS;
-+ }
-+ if (hw->media_type == e1000_media_type_fiber) {
-+ /* always blink LED0 for PCI-E fiber */
-+ ledctl_blink = E1000_LEDCTL_LED0_BLINK |
-+ (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
-+ } else {
-+ /* set the blink bit for each LED that's "on" (0x0E) in ledctl_mode2 */
-+ ledctl_blink = hw->ledctl_mode2;
-+ for (i=0; i < 4; i++)
-+ if (((hw->ledctl_mode2 >> (i * 8)) & 0xFF) ==
-+ E1000_LEDCTL_MODE_LED_ON)
-+ ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << (i * 8));
-+ }
-+
-+ E1000_WRITE_REG(hw, LEDCTL, ledctl_blink);
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/******************************************************************************
-+ * Restores the saved state of the SW controlable LED.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ *****************************************************************************/
-+int32_t
-+e1000_cleanup_led(struct e1000_hw *hw)
-+{
-+ int32_t ret_val = E1000_SUCCESS;
-+
-+ DEBUGFUNC("e1000_cleanup_led");
-+
-+ switch (hw->mac_type) {
-+ case e1000_82542_rev2_0:
-+ case e1000_82542_rev2_1:
-+ case e1000_82543:
- case e1000_82544:
- /* No cleanup necessary */
- break;
-@@ -4246,10 +6139,14 @@ e1000_cleanup_led(struct e1000_hw *hw)
- /* Turn on PHY Smart Power Down (if previously enabled) */
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO,
- hw->phy_spd_default);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- /* Fall Through */
- default:
-+ if (hw->phy_type == e1000_phy_ife) {
-+ e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
-+ break;
-+ }
- /* Restore LEDCTL settings */
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_default);
- break;
-@@ -4270,7 +6167,7 @@ e1000_led_on(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_led_on");
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
-@@ -4279,7 +6176,7 @@ e1000_led_on(struct e1000_hw *hw)
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case e1000_82544:
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn on the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
-@@ -4290,11 +6187,14 @@ e1000_led_on(struct e1000_hw *hw)
- }
- break;
- default:
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn on the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
-- } else if(hw->media_type == e1000_media_type_copper) {
-+ } else if (hw->phy_type == e1000_phy_ife) {
-+ e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
-+ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON));
-+ } else if (hw->media_type == e1000_media_type_copper) {
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode2);
- return E1000_SUCCESS;
- }
-@@ -4318,7 +6218,7 @@ e1000_led_off(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_led_off");
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
-@@ -4327,7 +6227,7 @@ e1000_led_off(struct e1000_hw *hw)
- ctrl |= E1000_CTRL_SWDPIO0;
- break;
- case e1000_82544:
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- /* Clear SW Defineable Pin 0 to turn off the LED */
- ctrl &= ~E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
-@@ -4338,11 +6238,14 @@ e1000_led_off(struct e1000_hw *hw)
- }
- break;
- default:
-- if(hw->media_type == e1000_media_type_fiber) {
-+ if (hw->media_type == e1000_media_type_fiber) {
- /* Set SW Defineable Pin 0 to turn off the LED */
- ctrl |= E1000_CTRL_SWDPIN0;
- ctrl |= E1000_CTRL_SWDPIO0;
-- } else if(hw->media_type == e1000_media_type_copper) {
-+ } else if (hw->phy_type == e1000_phy_ife) {
-+ e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED,
-+ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF));
-+ } else if (hw->media_type == e1000_media_type_copper) {
- E1000_WRITE_REG(hw, LEDCTL, hw->ledctl_mode1);
- return E1000_SUCCESS;
- }
-@@ -4380,12 +6283,16 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw
- temp = E1000_READ_REG(hw, XOFFRXC);
- temp = E1000_READ_REG(hw, XOFFTXC);
- temp = E1000_READ_REG(hw, FCRUC);
-+
-+ if (hw->mac_type != e1000_ich8lan) {
- temp = E1000_READ_REG(hw, PRC64);
- temp = E1000_READ_REG(hw, PRC127);
- temp = E1000_READ_REG(hw, PRC255);
- temp = E1000_READ_REG(hw, PRC511);
- temp = E1000_READ_REG(hw, PRC1023);
- temp = E1000_READ_REG(hw, PRC1522);
-+ }
-+
- temp = E1000_READ_REG(hw, GPRC);
- temp = E1000_READ_REG(hw, BPRC);
- temp = E1000_READ_REG(hw, MPRC);
-@@ -4405,16 +6312,20 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw
- temp = E1000_READ_REG(hw, TOTH);
- temp = E1000_READ_REG(hw, TPR);
- temp = E1000_READ_REG(hw, TPT);
-+
-+ if (hw->mac_type != e1000_ich8lan) {
- temp = E1000_READ_REG(hw, PTC64);
- temp = E1000_READ_REG(hw, PTC127);
- temp = E1000_READ_REG(hw, PTC255);
- temp = E1000_READ_REG(hw, PTC511);
- temp = E1000_READ_REG(hw, PTC1023);
- temp = E1000_READ_REG(hw, PTC1522);
-+ }
-+
- temp = E1000_READ_REG(hw, MPTC);
- temp = E1000_READ_REG(hw, BPTC);
-
-- if(hw->mac_type < e1000_82543) return;
-+ if (hw->mac_type < e1000_82543) return;
-
- temp = E1000_READ_REG(hw, ALGNERRC);
- temp = E1000_READ_REG(hw, RXERRC);
-@@ -4423,11 +6334,26 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw
- temp = E1000_READ_REG(hw, TSCTC);
- temp = E1000_READ_REG(hw, TSCTFC);
-
-- if(hw->mac_type <= e1000_82544) return;
-+ if (hw->mac_type <= e1000_82544) return;
-
- temp = E1000_READ_REG(hw, MGTPRC);
- temp = E1000_READ_REG(hw, MGTPDC);
- temp = E1000_READ_REG(hw, MGTPTC);
-+
-+ if (hw->mac_type <= e1000_82547_rev_2) return;
-+
-+ temp = E1000_READ_REG(hw, IAC);
-+ temp = E1000_READ_REG(hw, ICRXOC);
-+
-+ if (hw->mac_type == e1000_ich8lan) return;
-+
-+ temp = E1000_READ_REG(hw, ICRXPTC);
-+ temp = E1000_READ_REG(hw, ICRXATC);
-+ temp = E1000_READ_REG(hw, ICTXPTC);
-+ temp = E1000_READ_REG(hw, ICTXATC);
-+ temp = E1000_READ_REG(hw, ICTXQEC);
-+ temp = E1000_READ_REG(hw, ICTXQMTC);
-+ temp = E1000_READ_REG(hw, ICRXDMTC);
- }
-
- /******************************************************************************
-@@ -4445,8 +6371,8 @@ e1000_reset_adaptive(struct e1000_hw *hw
- {
- DEBUGFUNC("e1000_reset_adaptive");
-
-- if(hw->adaptive_ifs) {
-- if(!hw->ifs_params_forced) {
-+ if (hw->adaptive_ifs) {
-+ if (!hw->ifs_params_forced) {
- hw->current_ifs_val = 0;
- hw->ifs_min_val = IFS_MIN;
- hw->ifs_max_val = IFS_MAX;
-@@ -4473,12 +6399,12 @@ e1000_update_adaptive(struct e1000_hw *h
- {
- DEBUGFUNC("e1000_update_adaptive");
-
-- if(hw->adaptive_ifs) {
-- if((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
-- if(hw->tx_packet_delta > MIN_NUM_XMITS) {
-+ if (hw->adaptive_ifs) {
-+ if ((hw->collision_delta * hw->ifs_ratio) > hw->tx_packet_delta) {
-+ if (hw->tx_packet_delta > MIN_NUM_XMITS) {
- hw->in_ifs_mode = TRUE;
-- if(hw->current_ifs_val < hw->ifs_max_val) {
-- if(hw->current_ifs_val == 0)
-+ if (hw->current_ifs_val < hw->ifs_max_val) {
-+ if (hw->current_ifs_val == 0)
- hw->current_ifs_val = hw->ifs_min_val;
- else
- hw->current_ifs_val += hw->ifs_step_size;
-@@ -4486,7 +6412,7 @@ e1000_update_adaptive(struct e1000_hw *h
- }
- }
- } else {
-- if(hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
-+ if (hw->in_ifs_mode && (hw->tx_packet_delta <= MIN_NUM_XMITS)) {
- hw->current_ifs_val = 0;
- hw->in_ifs_mode = FALSE;
- E1000_WRITE_REG(hw, AIT, 0);
-@@ -4533,46 +6459,46 @@ e1000_tbi_adjust_stats(struct e1000_hw *
- * This could be simplified if all environments supported
- * 64-bit integers.
- */
-- if(carry_bit && ((stats->gorcl & 0x80000000) == 0))
-+ if (carry_bit && ((stats->gorcl & 0x80000000) == 0))
- stats->gorch++;
- /* Is this a broadcast or multicast? Check broadcast first,
- * since the test for a multicast frame will test positive on
- * a broadcast frame.
- */
-- if((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff))
-+ if ((mac_addr[0] == (uint8_t) 0xff) && (mac_addr[1] == (uint8_t) 0xff))
- /* Broadcast packet */
- stats->bprc++;
-- else if(*mac_addr & 0x01)
-+ else if (*mac_addr & 0x01)
- /* Multicast packet */
- stats->mprc++;
-
-- if(frame_len == hw->max_frame_size) {
-+ if (frame_len == hw->max_frame_size) {
- /* In this case, the hardware has overcounted the number of
- * oversize frames.
- */
-- if(stats->roc > 0)
-+ if (stats->roc > 0)
- stats->roc--;
- }
-
- /* Adjust the bin counters when the extra byte put the frame in the
- * wrong bin. Remember that the frame_len was adjusted above.
- */
-- if(frame_len == 64) {
-+ if (frame_len == 64) {
- stats->prc64++;
- stats->prc127--;
-- } else if(frame_len == 127) {
-+ } else if (frame_len == 127) {
- stats->prc127++;
- stats->prc255--;
-- } else if(frame_len == 255) {
-+ } else if (frame_len == 255) {
- stats->prc255++;
- stats->prc511--;
-- } else if(frame_len == 511) {
-+ } else if (frame_len == 511) {
- stats->prc511++;
- stats->prc1023--;
-- } else if(frame_len == 1023) {
-+ } else if (frame_len == 1023) {
- stats->prc1023++;
- stats->prc1522--;
-- } else if(frame_len == 1522) {
-+ } else if (frame_len == 1522) {
- stats->prc1522++;
- }
- }
-@@ -4587,41 +6513,57 @@ e1000_get_bus_info(struct e1000_hw *hw)
- {
- uint32_t status;
-
-- if(hw->mac_type < e1000_82543) {
-+ switch (hw->mac_type) {
-+ case e1000_82542_rev2_0:
-+ case e1000_82542_rev2_1:
- hw->bus_type = e1000_bus_type_unknown;
- hw->bus_speed = e1000_bus_speed_unknown;
- hw->bus_width = e1000_bus_width_unknown;
-- return;
-- }
--
-- status = E1000_READ_REG(hw, STATUS);
-- hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
-- e1000_bus_type_pcix : e1000_bus_type_pci;
-+ break;
-+ case e1000_82572:
-+ case e1000_82573:
-+ hw->bus_type = e1000_bus_type_pci_express;
-+ hw->bus_speed = e1000_bus_speed_2500;
-+ hw->bus_width = e1000_bus_width_pciex_1;
-+ break;
-+ case e1000_82571:
-+ case e1000_ich8lan:
-+ case e1000_80003es2lan:
-+ hw->bus_type = e1000_bus_type_pci_express;
-+ hw->bus_speed = e1000_bus_speed_2500;
-+ hw->bus_width = e1000_bus_width_pciex_4;
-+ break;
-+ default:
-+ status = E1000_READ_REG(hw, STATUS);
-+ hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ?
-+ e1000_bus_type_pcix : e1000_bus_type_pci;
-
-- if(hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
-- hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
-- e1000_bus_speed_66 : e1000_bus_speed_120;
-- } else if(hw->bus_type == e1000_bus_type_pci) {
-- hw->bus_speed = (status & E1000_STATUS_PCI66) ?
-- e1000_bus_speed_66 : e1000_bus_speed_33;
-- } else {
-- switch (status & E1000_STATUS_PCIX_SPEED) {
-- case E1000_STATUS_PCIX_SPEED_66:
-- hw->bus_speed = e1000_bus_speed_66;
-- break;
-- case E1000_STATUS_PCIX_SPEED_100:
-- hw->bus_speed = e1000_bus_speed_100;
-- break;
-- case E1000_STATUS_PCIX_SPEED_133:
-- hw->bus_speed = e1000_bus_speed_133;
-- break;
-- default:
-- hw->bus_speed = e1000_bus_speed_reserved;
-- break;
-+ if (hw->device_id == E1000_DEV_ID_82546EB_QUAD_COPPER) {
-+ hw->bus_speed = (hw->bus_type == e1000_bus_type_pci) ?
-+ e1000_bus_speed_66 : e1000_bus_speed_120;
-+ } else if (hw->bus_type == e1000_bus_type_pci) {
-+ hw->bus_speed = (status & E1000_STATUS_PCI66) ?
-+ e1000_bus_speed_66 : e1000_bus_speed_33;
-+ } else {
-+ switch (status & E1000_STATUS_PCIX_SPEED) {
-+ case E1000_STATUS_PCIX_SPEED_66:
-+ hw->bus_speed = e1000_bus_speed_66;
-+ break;
-+ case E1000_STATUS_PCIX_SPEED_100:
-+ hw->bus_speed = e1000_bus_speed_100;
-+ break;
-+ case E1000_STATUS_PCIX_SPEED_133:
-+ hw->bus_speed = e1000_bus_speed_133;
-+ break;
-+ default:
-+ hw->bus_speed = e1000_bus_speed_reserved;
-+ break;
-+ }
- }
-+ hw->bus_width = (status & E1000_STATUS_BUS64) ?
-+ e1000_bus_width_64 : e1000_bus_width_32;
-+ break;
- }
-- hw->bus_width = (status & E1000_STATUS_BUS64) ?
-- e1000_bus_width_64 : e1000_bus_width_32;
- }
- /******************************************************************************
- * Reads a value from one of the devices registers using port I/O (as opposed
-@@ -4684,23 +6626,25 @@ e1000_get_cable_length(struct e1000_hw *
- {
- int32_t ret_val;
- uint16_t agc_value = 0;
-- uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
- uint16_t i, phy_data;
-+ uint16_t cable_length;
-
- DEBUGFUNC("e1000_get_cable_length");
-
- *min_length = *max_length = 0;
-
- /* Use old method for Phy older than IGP */
-- if(hw->phy_type == e1000_phy_m88) {
-+ if (hw->phy_type == e1000_phy_m88) {
-+
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-+ cable_length = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-+ M88E1000_PSSR_CABLE_LENGTH_SHIFT;
-
- /* Convert the enum value to ranged values */
-- switch((phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
-- M88E1000_PSSR_CABLE_LENGTH_SHIFT) {
-+ switch (cable_length) {
- case e1000_cable_length_50:
- *min_length = 0;
- *max_length = e1000_igp_cable_length_50;
-@@ -4725,36 +6669,66 @@ e1000_get_cable_length(struct e1000_hw *
- return -E1000_ERR_PHY;
- break;
- }
-- } else if(hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
-+ } else if (hw->phy_type == e1000_phy_gg82563) {
-+ ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ cable_length = phy_data & GG82563_DSPD_CABLE_LENGTH;
-+
-+ switch (cable_length) {
-+ case e1000_gg_cable_length_60:
-+ *min_length = 0;
-+ *max_length = e1000_igp_cable_length_60;
-+ break;
-+ case e1000_gg_cable_length_60_115:
-+ *min_length = e1000_igp_cable_length_60;
-+ *max_length = e1000_igp_cable_length_115;
-+ break;
-+ case e1000_gg_cable_length_115_150:
-+ *min_length = e1000_igp_cable_length_115;
-+ *max_length = e1000_igp_cable_length_150;
-+ break;
-+ case e1000_gg_cable_length_150:
-+ *min_length = e1000_igp_cable_length_150;
-+ *max_length = e1000_igp_cable_length_180;
-+ break;
-+ default:
-+ return -E1000_ERR_PHY;
-+ break;
-+ }
-+ } else if (hw->phy_type == e1000_phy_igp) { /* For IGP PHY */
-+ uint16_t cur_agc_value;
-+ uint16_t min_agc_value = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
- uint16_t agc_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_A,
- IGP01E1000_PHY_AGC_B,
- IGP01E1000_PHY_AGC_C,
- IGP01E1000_PHY_AGC_D};
- /* Read the AGC registers for all channels */
-- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-+ for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-
- ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- cur_agc = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
-+ cur_agc_value = phy_data >> IGP01E1000_AGC_LENGTH_SHIFT;
-
-- /* Array bound check. */
-- if((cur_agc >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
-- (cur_agc == 0))
-+ /* Value bound check. */
-+ if ((cur_agc_value >= IGP01E1000_AGC_LENGTH_TABLE_SIZE - 1) ||
-+ (cur_agc_value == 0))
- return -E1000_ERR_PHY;
-
-- agc_value += cur_agc;
-+ agc_value += cur_agc_value;
-
- /* Update minimal AGC value. */
-- if(min_agc > cur_agc)
-- min_agc = cur_agc;
-+ if (min_agc_value > cur_agc_value)
-+ min_agc_value = cur_agc_value;
- }
-
- /* Remove the minimal AGC result for length < 50m */
-- if(agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
-- agc_value -= min_agc;
-+ if (agc_value < IGP01E1000_PHY_CHANNEL_NUM * e1000_igp_cable_length_50) {
-+ agc_value -= min_agc_value;
-
- /* Get the average length of the remaining 3 channels */
- agc_value /= (IGP01E1000_PHY_CHANNEL_NUM - 1);
-@@ -4770,6 +6744,51 @@ e1000_get_cable_length(struct e1000_hw *
- IGP01E1000_AGC_RANGE) : 0;
- *max_length = e1000_igp_cable_length_table[agc_value] +
- IGP01E1000_AGC_RANGE;
-+ } else if (hw->phy_type == e1000_phy_igp_2 ||
-+ hw->phy_type == e1000_phy_igp_3) {
-+ uint16_t cur_agc_index, max_agc_index = 0;
-+ uint16_t min_agc_index = IGP02E1000_AGC_LENGTH_TABLE_SIZE - 1;
-+ uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
-+ {IGP02E1000_PHY_AGC_A,
-+ IGP02E1000_PHY_AGC_B,
-+ IGP02E1000_PHY_AGC_C,
-+ IGP02E1000_PHY_AGC_D};
-+ /* Read the AGC registers for all channels */
-+ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
-+ ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Getting bits 15:9, which represent the combination of course and
-+ * fine gain values. The result is a number that can be put into
-+ * the lookup table to obtain the approximate cable length. */
-+ cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
-+ IGP02E1000_AGC_LENGTH_MASK;
-+
-+ /* Array index bound check. */
-+ if ((cur_agc_index >= IGP02E1000_AGC_LENGTH_TABLE_SIZE) ||
-+ (cur_agc_index == 0))
-+ return -E1000_ERR_PHY;
-+
-+ /* Remove min & max AGC values from calculation. */
-+ if (e1000_igp_2_cable_length_table[min_agc_index] >
-+ e1000_igp_2_cable_length_table[cur_agc_index])
-+ min_agc_index = cur_agc_index;
-+ if (e1000_igp_2_cable_length_table[max_agc_index] <
-+ e1000_igp_2_cable_length_table[cur_agc_index])
-+ max_agc_index = cur_agc_index;
-+
-+ agc_value += e1000_igp_2_cable_length_table[cur_agc_index];
-+ }
-+
-+ agc_value -= (e1000_igp_2_cable_length_table[min_agc_index] +
-+ e1000_igp_2_cable_length_table[max_agc_index]);
-+ agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
-+
-+ /* Calculate cable length with the error range of +/- 10 meters. */
-+ *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
-+ (agc_value - IGP02E1000_AGC_RANGE) : 0;
-+ *max_length = agc_value + IGP02E1000_AGC_RANGE;
- }
-
- return E1000_SUCCESS;
-@@ -4800,30 +6819,33 @@ e1000_check_polarity(struct e1000_hw *hw
-
- DEBUGFUNC("e1000_check_polarity");
-
-- if(hw->phy_type == e1000_phy_m88) {
-+ if ((hw->phy_type == e1000_phy_m88) ||
-+ (hw->phy_type == e1000_phy_gg82563)) {
- /* return the Polarity bit in the Status register. */
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >>
- M88E1000_PSSR_REV_POLARITY_SHIFT;
-- } else if(hw->phy_type == e1000_phy_igp) {
-+ } else if (hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2) {
- /* Read the Status register to check the speed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* If speed is 1000 Mbps, must read the IGP01E1000_PHY_PCS_INIT_REG to
- * find the polarity status */
-- if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
-+ if ((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
- IGP01E1000_PSSR_SPEED_1000MBPS) {
-
- /* Read the GIG initialization PCS register (0x00B4) */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PCS_INIT_REG,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* Check the polarity bits */
-@@ -4833,6 +6855,13 @@ e1000_check_polarity(struct e1000_hw *hw
- * 100 Mbps this bit is always 0) */
- *polarity = phy_data & IGP01E1000_PSSR_POLARITY_REVERSED;
- }
-+ } else if (hw->phy_type == e1000_phy_ife) {
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_EXTENDED_STATUS_CONTROL,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ *polarity = (phy_data & IFE_PESC_POLARITY_REVERSED) >>
-+ IFE_PESC_POLARITY_REVERSED_SHIFT;
- }
- return E1000_SUCCESS;
- }
-@@ -4845,7 +6874,7 @@ e1000_check_polarity(struct e1000_hw *hw
- * 1 - Downshift ocured.
- *
- * returns: - E1000_ERR_XXX
-- * E1000_SUCCESS
-+ * E1000_SUCCESS
- *
- * For phy's older then IGP, this function reads the Downshift bit in the Phy
- * Specific Status register. For IGP phy's, it reads the Downgrade bit in the
-@@ -4860,23 +6889,29 @@ e1000_check_downshift(struct e1000_hw *h
-
- DEBUGFUNC("e1000_check_downshift");
-
-- if(hw->phy_type == e1000_phy_igp) {
-+ if (hw->phy_type == e1000_phy_igp ||
-+ hw->phy_type == e1000_phy_igp_3 ||
-+ hw->phy_type == e1000_phy_igp_2) {
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & IGP01E1000_PLHR_SS_DOWNGRADE) ? 1 : 0;
-- }
-- else if(hw->phy_type == e1000_phy_m88) {
-+ } else if ((hw->phy_type == e1000_phy_m88) ||
-+ (hw->phy_type == e1000_phy_gg82563)) {
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >>
- M88E1000_PSSR_DOWNSHIFT_SHIFT;
-+ } else if (hw->phy_type == e1000_phy_ife) {
-+ /* e1000_phy_ife supports 10/100 speed only */
-+ hw->speed_downgraded = FALSE;
- }
-+
- return E1000_SUCCESS;
- }
-
-@@ -4897,7 +6932,7 @@ e1000_config_dsp_after_link_change(struc
- boolean_t link_up)
- {
- int32_t ret_val;
-- uint16_t phy_data, speed, duplex, i;
-+ uint16_t phy_data, phy_saved_data, speed, duplex, i;
- uint16_t dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =
- {IGP01E1000_PHY_AGC_PARAM_A,
- IGP01E1000_PHY_AGC_PARAM_B,
-@@ -4907,40 +6942,42 @@ e1000_config_dsp_after_link_change(struc
-
- DEBUGFUNC("e1000_config_dsp_after_link_change");
-
-- if(hw->phy_type != e1000_phy_igp)
-+ if (hw->phy_type != e1000_phy_igp)
- return E1000_SUCCESS;
-
-- if(link_up) {
-+ if (link_up) {
- ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex);
-- if(ret_val) {
-+ if (ret_val) {
- DEBUGOUT("Error getting link speed and duplex\n");
- return ret_val;
- }
-
-- if(speed == SPEED_1000) {
-+ if (speed == SPEED_1000) {
-
-- e1000_get_cable_length(hw, &min_length, &max_length);
-+ ret_val = e1000_get_cable_length(hw, &min_length, &max_length);
-+ if (ret_val)
-+ return ret_val;
-
-- if((hw->dsp_config_state == e1000_dsp_config_enabled) &&
-+ if ((hw->dsp_config_state == e1000_dsp_config_enabled) &&
- min_length >= e1000_igp_cable_length_50) {
-
-- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-+ for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i],
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
-
- ret_val = e1000_write_phy_reg(hw, dsp_reg_array[i],
- phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- }
- hw->dsp_config_state = e1000_dsp_config_activated;
- }
-
-- if((hw->ffe_config_state == e1000_ffe_config_enabled) &&
-+ if ((hw->ffe_config_state == e1000_ffe_config_enabled) &&
- (min_length < e1000_igp_cable_length_50)) {
-
- uint16_t ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20;
-@@ -4949,74 +6986,121 @@ e1000_config_dsp_after_link_change(struc
- /* clear previous idle error counts */
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- for(i = 0; i < ffe_idle_err_timeout; i++) {
-- udelay(1000);
-+ for (i = 0; i < ffe_idle_err_timeout; i++) {
-+ usec_delay(1000);
- ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS,
- &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- idle_errs += (phy_data & SR_1000T_IDLE_ERROR_CNT);
-- if(idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
-+ if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) {
- hw->ffe_config_state = e1000_ffe_config_active;
-
- ret_val = e1000_write_phy_reg(hw,
- IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_CM_CP);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- break;
- }
-
-- if(idle_errs)
-+ if (idle_errs)
- ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_100;
- }
- }
- }
- } else {
-- if(hw->dsp_config_state == e1000_dsp_config_activated) {
-+ if (hw->dsp_config_state == e1000_dsp_config_activated) {
-+ /* Save off the current value of register 0x2F5B to be restored at
-+ * the end of the routines. */
-+ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Disable the PHY transmitter */
-+ ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ msec_delay_irq(20);
-+
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-- for(i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
-+ for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) {
- ret_val = e1000_read_phy_reg(hw, dsp_reg_array[i], &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX;
- phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS;
-
- ret_val = e1000_write_phy_reg(hw,dsp_reg_array[i], phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- }
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
-- if(ret_val)
-+ if (ret_val)
-+ return ret_val;
-+
-+ msec_delay_irq(20);
-+
-+ /* Now enable the transmitter */
-+ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-+
-+ if (ret_val)
- return ret_val;
-
- hw->dsp_config_state = e1000_dsp_config_enabled;
- }
-
-- if(hw->ffe_config_state == e1000_ffe_config_active) {
-+ if (hw->ffe_config_state == e1000_ffe_config_active) {
-+ /* Save off the current value of register 0x2F5B to be restored at
-+ * the end of the routines. */
-+ ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* Disable the PHY transmitter */
-+ ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003);
-+
-+ if (ret_val)
-+ return ret_val;
-+
-+ msec_delay_irq(20);
-+
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_FORCE_GIGA);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_DSP_FFE,
- IGP01E1000_PHY_DSP_FFE_DEFAULT);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, 0x0000,
- IGP01E1000_IEEE_RESTART_AUTONEG);
-- if(ret_val)
-+ if (ret_val)
-+ return ret_val;
-+
-+ msec_delay_irq(20);
-+
-+ /* Now enable the transmitter */
-+ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data);
-+
-+ if (ret_val)
- return ret_val;
-+
- hw->ffe_config_state = e1000_ffe_config_enabled;
- }
- }
-@@ -5039,20 +7123,20 @@ e1000_set_phy_mode(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_set_phy_mode");
-
-- if((hw->mac_type == e1000_82545_rev_3) &&
-- (hw->media_type == e1000_media_type_copper)) {
-+ if ((hw->mac_type == e1000_82545_rev_3) &&
-+ (hw->media_type == e1000_media_type_copper)) {
- ret_val = e1000_read_eeprom(hw, EEPROM_PHY_CLASS_WORD, 1, &eeprom_data);
-- if(ret_val) {
-+ if (ret_val) {
- return ret_val;
- }
-
-- if((eeprom_data != EEPROM_RESERVED_WORD) &&
-- (eeprom_data & EEPROM_PHY_CLASS_A)) {
-+ if ((eeprom_data != EEPROM_RESERVED_WORD) &&
-+ (eeprom_data & EEPROM_PHY_CLASS_A)) {
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- hw->phy_reset_disable = FALSE;
-@@ -5080,57 +7164,212 @@ int32_t
- e1000_set_d3_lplu_state(struct e1000_hw *hw,
- boolean_t active)
- {
-+ uint32_t phy_ctrl = 0;
- int32_t ret_val;
- uint16_t phy_data;
- DEBUGFUNC("e1000_set_d3_lplu_state");
-
-- if(!((hw->mac_type == e1000_82541_rev_2) ||
-- (hw->mac_type == e1000_82547_rev_2)))
-+ if (hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2
-+ && hw->phy_type != e1000_phy_igp_3)
- return E1000_SUCCESS;
-
- /* During driver activity LPLU should not be used or it will attain link
- * from the lowest speeds starting from 10Mbps. The capability is used for
- * Dx transitions and states */
-- ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
-- if(ret_val)
-- return ret_val;
--
-- if(!active) {
-- phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
-- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
-- if(ret_val)
-+ if (hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) {
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else if (hw->mac_type == e1000_ich8lan) {
-+ /* MAC writes into PHY register based on the state transition
-+ * and start auto-negotiation. SW driver can overwrite the settings
-+ * in CSR PHY power control E1000_PHY_CTRL register. */
-+ phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
-+ } else {
-+ ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
-+ if (ret_val)
- return ret_val;
-+ }
-+
-+ if (!active) {
-+ if (hw->mac_type == e1000_82541_rev_2 ||
-+ hw->mac_type == e1000_82547_rev_2) {
-+ phy_data &= ~IGP01E1000_GMII_FLEX_SPD;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else {
-+ if (hw->mac_type == e1000_ich8lan) {
-+ phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
-+ E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
-+ } else {
-+ phy_data &= ~IGP02E1000_PM_D3_LPLU;
-+ ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+ }
-
- /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
- * Dx states where the power conservation is most important. During
- * driver activity we should enable SmartSpeed, so performance is
- * maintained. */
-+ if (hw->smart_speed == e1000_smart_speed_on) {
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else if (hw->smart_speed == e1000_smart_speed_off) {
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ } else if ((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
-+ (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
-+ (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
-+
-+ if (hw->mac_type == e1000_82541_rev_2 ||
-+ hw->mac_type == e1000_82547_rev_2) {
-+ phy_data |= IGP01E1000_GMII_FLEX_SPD;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else {
-+ if (hw->mac_type == e1000_ich8lan) {
-+ phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
-+ E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
-+ } else {
-+ phy_data |= IGP02E1000_PM_D3_LPLU;
-+ ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+ }
-+
-+ /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
-+ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
-- } else if((hw->autoneg_advertised == AUTONEG_ADVERTISE_SPEED_DEFAULT) ||
-- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) ||
-- (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) {
-+ }
-+ return E1000_SUCCESS;
-+}
-+
-+/*****************************************************************************
-+ *
-+ * This function sets the lplu d0 state according to the active flag. When
-+ * activating lplu this function also disables smart speed and vise versa.
-+ * lplu will not be activated unless the device autonegotiation advertisment
-+ * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes.
-+ * hw: Struct containing variables accessed by shared code
-+ * active - true to enable lplu false to disable lplu.
-+ *
-+ * returns: - E1000_ERR_PHY if fail to read/write the PHY
-+ * E1000_SUCCESS at any other case.
-+ *
-+ ****************************************************************************/
-+
-+int32_t
-+e1000_set_d0_lplu_state(struct e1000_hw *hw,
-+ boolean_t active)
-+{
-+ uint32_t phy_ctrl = 0;
-+ int32_t ret_val;
-+ uint16_t phy_data;
-+ DEBUGFUNC("e1000_set_d0_lplu_state");
-+
-+ if (hw->mac_type <= e1000_82547_rev_2)
-+ return E1000_SUCCESS;
-
-- phy_data |= IGP01E1000_GMII_FLEX_SPD;
-- ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data);
-- if(ret_val)
-+ if (hw->mac_type == e1000_ich8lan) {
-+ phy_ctrl = E1000_READ_REG(hw, PHY_CTRL);
-+ } else {
-+ ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
-+ if (ret_val)
- return ret_val;
-+ }
-+
-+ if (!active) {
-+ if (hw->mac_type == e1000_ich8lan) {
-+ phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
-+ E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
-+ } else {
-+ phy_data &= ~IGP02E1000_PM_D0_LPLU;
-+ ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+ /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during
-+ * Dx states where the power conservation is most important. During
-+ * driver activity we should enable SmartSpeed, so performance is
-+ * maintained. */
-+ if (hw->smart_speed == e1000_smart_speed_on) {
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= IGP01E1000_PSCFR_SMART_SPEED;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ } else if (hw->smart_speed == e1000_smart_speed_off) {
-+ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-+ ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG,
-+ phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+
-+
-+ } else {
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
-+ E1000_WRITE_REG(hw, PHY_CTRL, phy_ctrl);
-+ } else {
-+ phy_data |= IGP02E1000_PM_D0_LPLU;
-+ ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+ }
-
- /* When LPLU is enabled we should disable SmartSpeed */
- ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
- ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- }
-@@ -5151,7 +7390,7 @@ e1000_set_vco_speed(struct e1000_hw *hw)
-
- DEBUGFUNC("e1000_set_vco_speed");
-
-- switch(hw->mac_type) {
-+ switch (hw->mac_type) {
- case e1000_82545_rev_3:
- case e1000_82546_rev_3:
- break;
-@@ -5162,65 +7401,1693 @@ e1000_set_vco_speed(struct e1000_hw *hw)
- /* Set PHY register 30, page 5, bit 8 to 0 */
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data &= ~M88E1000_PHY_VCO_REG_BIT8;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- /* Set PHY register 30, page 4, bit 11 to 1 */
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- phy_data |= M88E1000_PHY_VCO_REG_BIT11;
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page);
-- if(ret_val)
-+ if (ret_val)
- return ret_val;
-
- return E1000_SUCCESS;
- }
-
--/******************************************************************************
-- * Verifies the hardware needs to allow ARPs to be processed by the host
-- *
-- * hw - Struct containing variables accessed by shared code
-- *
-- * returns: - TRUE/FALSE
-+
-+/*****************************************************************************
-+ * This function reads the cookie from ARC ram.
- *
-- *****************************************************************************/
--uint32_t
--e1000_enable_mng_pass_thru(struct e1000_hw *hw)
-+ * returns: - E1000_SUCCESS .
-+ ****************************************************************************/
-+int32_t
-+e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer)
- {
-- uint32_t manc;
-+ uint8_t i;
-+ uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET;
-+ uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH;
-
-- if (hw->asf_firmware_present) {
-- manc = E1000_READ_REG(hw, MANC);
-+ length = (length >> 2);
-+ offset = (offset >> 2);
-
-- if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-- !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
-- return FALSE;
-- if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
-- return TRUE;
-+ for (i = 0; i < length; i++) {
-+ *((uint32_t *) buffer + i) =
-+ E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i);
- }
-- return FALSE;
-+ return E1000_SUCCESS;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function checks whether the HOST IF is enabled for command operaton
-+ * and also checks whether the previous command is completed.
-+ * It busy waits in case of previous command is not completed.
-+ *
-+ * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or
-+ * timeout
-+ * - E1000_SUCCESS for success.
-+ ****************************************************************************/
-+int32_t
-+e1000_mng_enable_host_if(struct e1000_hw * hw)
-+{
-+ uint32_t hicr;
-+ uint8_t i;
-+
-+ /* Check that the host interface is enabled. */
-+ hicr = E1000_READ_REG(hw, HICR);
-+ if ((hicr & E1000_HICR_EN) == 0) {
-+ DEBUGOUT("E1000_HOST_EN bit disabled.\n");
-+ return -E1000_ERR_HOST_INTERFACE_COMMAND;
-+ }
-+ /* check the previous command is completed */
-+ for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) {
-+ hicr = E1000_READ_REG(hw, HICR);
-+ if (!(hicr & E1000_HICR_C))
-+ break;
-+ msec_delay_irq(1);
-+ }
-+
-+ if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) {
-+ DEBUGOUT("Previous command timeout failed .\n");
-+ return -E1000_ERR_HOST_INTERFACE_COMMAND;
-+ }
-+ return E1000_SUCCESS;
- }
-+
-+/*****************************************************************************
-+ * This function writes the buffer content at the offset given on the host if.
-+ * It also does alignment considerations to do the writes in most efficient way.
-+ * Also fills up the sum of the buffer in *buffer parameter.
-+ *
-+ * returns - E1000_SUCCESS for success.
-+ ****************************************************************************/
-+int32_t
-+e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
-+ uint16_t length, uint16_t offset, uint8_t *sum)
-+{
-+ uint8_t *tmp;
-+ uint8_t *bufptr = buffer;
-+ uint32_t data = 0;
-+ uint16_t remaining, i, j, prev_bytes;
-+
-+ /* sum = only sum of the data and it is not checksum */
-+
-+ if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) {
-+ return -E1000_ERR_PARAM;
-+ }
-+
-+ tmp = (uint8_t *)&data;
-+ prev_bytes = offset & 0x3;
-+ offset &= 0xFFFC;
-+ offset >>= 2;
-+
-+ if (prev_bytes) {
-+ data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset);
-+ for (j = prev_bytes; j < sizeof(uint32_t); j++) {
-+ *(tmp + j) = *bufptr++;
-+ *sum += *(tmp + j);
-+ }
-+ E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data);
-+ length -= j - prev_bytes;
-+ offset++;
-+ }
-+
-+ remaining = length & 0x3;
-+ length -= remaining;
-+
-+ /* Calculate length in DWORDs */
-+ length >>= 2;
-+
-+ /* The device driver writes the relevant command block into the
-+ * ram area. */
-+ for (i = 0; i < length; i++) {
-+ for (j = 0; j < sizeof(uint32_t); j++) {
-+ *(tmp + j) = *bufptr++;
-+ *sum += *(tmp + j);
-+ }
-+
-+ E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
-+ }
-+ if (remaining) {
-+ for (j = 0; j < sizeof(uint32_t); j++) {
-+ if (j < remaining)
-+ *(tmp + j) = *bufptr++;
-+ else
-+ *(tmp + j) = 0;
-+
-+ *sum += *(tmp + j);
-+ }
-+ E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data);
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function writes the command header after does the checksum calculation.
-+ *
-+ * returns - E1000_SUCCESS for success.
-+ ****************************************************************************/
-+int32_t
-+e1000_mng_write_cmd_header(struct e1000_hw * hw,
-+ struct e1000_host_mng_command_header * hdr)
-+{
-+ uint16_t i;
-+ uint8_t sum;
-+ uint8_t *buffer;
-+
-+ /* Write the whole command header structure which includes sum of
-+ * the buffer */
-+
-+ uint16_t length = sizeof(struct e1000_host_mng_command_header);
-+
-+ sum = hdr->checksum;
-+ hdr->checksum = 0;
-+
-+ buffer = (uint8_t *) hdr;
-+ i = length;
-+ while (i--)
-+ sum += buffer[i];
-+
-+ hdr->checksum = 0 - sum;
-+
-+ length >>= 2;
-+ /* The device driver writes the relevant command block into the ram area. */
-+ for (i = 0; i < length; i++) {
-+ E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i));
-+ E1000_WRITE_FLUSH(hw);
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function indicates to ARC that a new command is pending which completes
-+ * one write operation by the driver.
-+ *
-+ * returns - E1000_SUCCESS for success.
-+ ****************************************************************************/
-+int32_t
-+e1000_mng_write_commit(struct e1000_hw * hw)
-+{
-+ uint32_t hicr;
-+
-+ hicr = E1000_READ_REG(hw, HICR);
-+ /* Setting this bit tells the ARC that a new command is pending. */
-+ E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C);
-+
-+ return E1000_SUCCESS;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function checks the mode of the firmware.
-+ *
-+ * returns - TRUE when the mode is IAMT or FALSE.
-+ ****************************************************************************/
-+boolean_t
-+e1000_check_mng_mode(struct e1000_hw *hw)
-+{
-+ uint32_t fwsm;
-+
-+ fwsm = E1000_READ_REG(hw, FWSM);
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ if ((fwsm & E1000_FWSM_MODE_MASK) ==
-+ (E1000_MNG_ICH_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
-+ return TRUE;
-+ } else if ((fwsm & E1000_FWSM_MODE_MASK) ==
-+ (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT))
-+ return TRUE;
-+
-+ return FALSE;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function writes the dhcp info .
-+ ****************************************************************************/
-+int32_t
-+e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer,
-+ uint16_t length)
-+{
-+ int32_t ret_val;
-+ struct e1000_host_mng_command_header hdr;
-+
-+ hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD;
-+ hdr.command_length = length;
-+ hdr.reserved1 = 0;
-+ hdr.reserved2 = 0;
-+ hdr.checksum = 0;
-+
-+ ret_val = e1000_mng_enable_host_if(hw);
-+ if (ret_val == E1000_SUCCESS) {
-+ ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr),
-+ &(hdr.checksum));
-+ if (ret_val == E1000_SUCCESS) {
-+ ret_val = e1000_mng_write_cmd_header(hw, &hdr);
-+ if (ret_val == E1000_SUCCESS)
-+ ret_val = e1000_mng_write_commit(hw);
-+ }
-+ }
-+ return ret_val;
-+}
-+
-+
-+/*****************************************************************************
-+ * This function calculates the checksum.
-+ *
-+ * returns - checksum of buffer contents.
-+ ****************************************************************************/
-+uint8_t
-+e1000_calculate_mng_checksum(char *buffer, uint32_t length)
-+{
-+ uint8_t sum = 0;
-+ uint32_t i;
-+
-+ if (!buffer)
-+ return 0;
-+
-+ for (i=0; i < length; i++)
-+ sum += buffer[i];
-+
-+ return (uint8_t) (0 - sum);
-+}
-+
-+/*****************************************************************************
-+ * This function checks whether tx pkt filtering needs to be enabled or not.
-+ *
-+ * returns - TRUE for packet filtering or FALSE.
-+ ****************************************************************************/
-+boolean_t
-+e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
-+{
-+ /* called in init as well as watchdog timer functions */
-+
-+ int32_t ret_val, checksum;
-+ boolean_t tx_filter = FALSE;
-+ struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie);
-+ uint8_t *buffer = (uint8_t *) &(hw->mng_cookie);
-+
-+ if (e1000_check_mng_mode(hw)) {
-+ ret_val = e1000_mng_enable_host_if(hw);
-+ if (ret_val == E1000_SUCCESS) {
-+ ret_val = e1000_host_if_read_cookie(hw, buffer);
-+ if (ret_val == E1000_SUCCESS) {
-+ checksum = hdr->checksum;
-+ hdr->checksum = 0;
-+ if ((hdr->signature == E1000_IAMT_SIGNATURE) &&
-+ checksum == e1000_calculate_mng_checksum((char *)buffer,
-+ E1000_MNG_DHCP_COOKIE_LENGTH)) {
-+ if (hdr->status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT)
-+ tx_filter = TRUE;
-+ } else
-+ tx_filter = TRUE;
-+ } else
-+ tx_filter = TRUE;
-+ }
-+ }
-+
-+ hw->tx_pkt_filtering = tx_filter;
-+ return tx_filter;
-+}
-+
-+/******************************************************************************
-+ * Verifies the hardware needs to allow ARPs to be processed by the host
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ *
-+ * returns: - TRUE/FALSE
-+ *
-+ *****************************************************************************/
-+uint32_t
-+e1000_enable_mng_pass_thru(struct e1000_hw *hw)
-+{
-+ uint32_t manc;
-+ uint32_t fwsm, factps;
-+
-+ if (hw->asf_firmware_present) {
-+ manc = E1000_READ_REG(hw, MANC);
-+
-+ if (!(manc & E1000_MANC_RCV_TCO_EN) ||
-+ !(manc & E1000_MANC_EN_MAC_ADDR_FILTER))
-+ return FALSE;
-+ if (e1000_arc_subsystem_valid(hw) == TRUE) {
-+ fwsm = E1000_READ_REG(hw, FWSM);
-+ factps = E1000_READ_REG(hw, FACTPS);
-+
-+ if (((fwsm & E1000_FWSM_MODE_MASK) ==
-+ (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) &&
-+ (factps & E1000_FACTPS_MNGCG))
-+ return TRUE;
-+ } else
-+ if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN))
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+static int32_t
-+e1000_polarity_reversal_workaround(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t mii_status_reg;
-+ uint16_t i;
-+
-+ /* Polarity reversal workaround for forced 10F/10H links. */
-+
-+ /* Disable the transmitter on the PHY */
-+
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
-+ if (ret_val)
-+ return ret_val;
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* This loop will early-out if the NO link condition has been met. */
-+ for (i = PHY_FORCE_TIME; i > 0; i--) {
-+ /* Read the MII Status Register and wait for Link Status bit
-+ * to be clear.
-+ */
-+
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-+ if (ret_val)
-+ return ret_val;
-+
-+ if ((mii_status_reg & ~MII_SR_LINK_STATUS) == 0) break;
-+ msec_delay_irq(100);
-+ }
-+
-+ /* Recommended delay time after link has been lost */
-+ msec_delay_irq(1000);
-+
-+ /* Now we will re-enable th transmitter on the PHY */
-+
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019);
-+ if (ret_val)
-+ return ret_val;
-+ msec_delay_irq(50);
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0);
-+ if (ret_val)
-+ return ret_val;
-+ msec_delay_irq(50);
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00);
-+ if (ret_val)
-+ return ret_val;
-+ msec_delay_irq(50);
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000);
-+ if (ret_val)
-+ return ret_val;
-+
-+ /* This loop will early-out if the link condition has been met. */
-+ for (i = PHY_FORCE_TIME; i > 0; i--) {
-+ /* Read the MII Status Register and wait for Link Status bit
-+ * to be set.
-+ */
-+
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg);
-+ if (ret_val)
-+ return ret_val;
-+
-+ if (mii_status_reg & MII_SR_LINK_STATUS) break;
-+ msec_delay_irq(100);
-+ }
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Disables PCI-Express master access.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - none.
-+ *
-+ ***************************************************************************/
-+void
-+e1000_set_pci_express_master_disable(struct e1000_hw *hw)
-+{
-+ uint32_t ctrl;
-+
-+ DEBUGFUNC("e1000_set_pci_express_master_disable");
-+
-+ if (hw->bus_type != e1000_bus_type_pci_express)
-+ return;
-+
-+ ctrl = E1000_READ_REG(hw, CTRL);
-+ ctrl |= E1000_CTRL_GIO_MASTER_DISABLE;
-+ E1000_WRITE_REG(hw, CTRL, ctrl);
-+}
-+
-+/***************************************************************************
-+ *
-+ * Enables PCI-Express master access.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - none.
-+ *
-+ ***************************************************************************/
-+void
-+e1000_enable_pciex_master(struct e1000_hw *hw)
-+{
-+ uint32_t ctrl;
-+
-+ DEBUGFUNC("e1000_enable_pciex_master");
-+
-+ if (hw->bus_type != e1000_bus_type_pci_express)
-+ return;
-+
-+ ctrl = E1000_READ_REG(hw, CTRL);
-+ ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
-+ E1000_WRITE_REG(hw, CTRL, ctrl);
-+}
-+
-+/*******************************************************************************
-+ *
-+ * Disables PCI-Express master access and verifies there are no pending requests
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't
-+ * caused the master requests to be disabled.
-+ * E1000_SUCCESS master requests disabled.
-+ *
-+ ******************************************************************************/
-+int32_t
-+e1000_disable_pciex_master(struct e1000_hw *hw)
-+{
-+ int32_t timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */
-+
-+ DEBUGFUNC("e1000_disable_pciex_master");
-+
-+ if (hw->bus_type != e1000_bus_type_pci_express)
-+ return E1000_SUCCESS;
-+
-+ e1000_set_pci_express_master_disable(hw);
-+
-+ while (timeout) {
-+ if (!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE))
-+ break;
-+ else
-+ usec_delay(100);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("Master requests are pending.\n");
-+ return -E1000_ERR_MASTER_REQUESTS_PENDING;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/*******************************************************************************
-+ *
-+ * Check for EEPROM Auto Read bit done.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_ERR_RESET if fail to reset MAC
-+ * E1000_SUCCESS at any other case.
-+ *
-+ ******************************************************************************/
-+int32_t
-+e1000_get_auto_rd_done(struct e1000_hw *hw)
-+{
-+ int32_t timeout = AUTO_READ_DONE_TIMEOUT;
-+
-+ DEBUGFUNC("e1000_get_auto_rd_done");
-+
-+ switch (hw->mac_type) {
-+ default:
-+ msec_delay(5);
-+ break;
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_80003es2lan:
-+ case e1000_ich8lan:
-+ while (timeout) {
-+ if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD)
-+ break;
-+ else msec_delay(1);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("Auto read by HW from EEPROM has not completed.\n");
-+ return -E1000_ERR_RESET;
-+ }
-+ break;
-+ }
-+
-+ /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high.
-+ * Need to wait for PHY configuration completion before accessing NVM
-+ * and PHY. */
-+ if (hw->mac_type == e1000_82573)
-+ msec_delay(25);
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ * Checks if the PHY configuration is done
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_ERR_RESET if fail to reset MAC
-+ * E1000_SUCCESS at any other case.
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_get_phy_cfg_done(struct e1000_hw *hw)
-+{
-+ int32_t timeout = PHY_CFG_TIMEOUT;
-+ uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
-+
-+ DEBUGFUNC("e1000_get_phy_cfg_done");
-+
-+ switch (hw->mac_type) {
-+ default:
-+ msec_delay_irq(10);
-+ break;
-+ case e1000_80003es2lan:
-+ /* Separate *_CFG_DONE_* bit for each port */
-+ if (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
-+ cfg_mask = E1000_EEPROM_CFG_DONE_PORT_1;
-+ /* Fall Through */
-+ case e1000_82571:
-+ case e1000_82572:
-+ while (timeout) {
-+ if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
-+ break;
-+ else
-+ msec_delay(1);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("MNG configuration cycle has not completed.\n");
-+ return -E1000_ERR_RESET;
-+ }
-+ break;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Using the combination of SMBI and SWESMBI semaphore bits when resetting
-+ * adapter or Eeprom access.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_ERR_EEPROM if fail to access EEPROM.
-+ * E1000_SUCCESS at any other case.
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
-+{
-+ int32_t timeout;
-+ uint32_t swsm;
-+
-+ DEBUGFUNC("e1000_get_hw_eeprom_semaphore");
-+
-+ if (!hw->eeprom_semaphore_present)
-+ return E1000_SUCCESS;
-+
-+ if (hw->mac_type == e1000_80003es2lan) {
-+ /* Get the SW semaphore. */
-+ if (e1000_get_software_semaphore(hw) != E1000_SUCCESS)
-+ return -E1000_ERR_EEPROM;
-+ }
-+
-+ /* Get the FW semaphore. */
-+ timeout = hw->eeprom.word_size + 1;
-+ while (timeout) {
-+ swsm = E1000_READ_REG(hw, SWSM);
-+ swsm |= E1000_SWSM_SWESMBI;
-+ E1000_WRITE_REG(hw, SWSM, swsm);
-+ /* if we managed to set the bit we got the semaphore. */
-+ swsm = E1000_READ_REG(hw, SWSM);
-+ if (swsm & E1000_SWSM_SWESMBI)
-+ break;
-+
-+ usec_delay(50);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ /* Release semaphores */
-+ e1000_put_hw_eeprom_semaphore(hw);
-+ DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n");
-+ return -E1000_ERR_EEPROM;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ * This function clears HW semaphore bits.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - None.
-+ *
-+ ***************************************************************************/
-+void
-+e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
-+{
-+ uint32_t swsm;
-+
-+ DEBUGFUNC("e1000_put_hw_eeprom_semaphore");
-+
-+ if (!hw->eeprom_semaphore_present)
-+ return;
-+
-+ swsm = E1000_READ_REG(hw, SWSM);
-+ if (hw->mac_type == e1000_80003es2lan) {
-+ /* Release both semaphores. */
-+ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
-+ } else
-+ swsm &= ~(E1000_SWSM_SWESMBI);
-+ E1000_WRITE_REG(hw, SWSM, swsm);
-+}
-+
-+/***************************************************************************
-+ *
-+ * Obtaining software semaphore bit (SMBI) before resetting PHY.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_ERR_RESET if fail to obtain semaphore.
-+ * E1000_SUCCESS at any other case.
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_get_software_semaphore(struct e1000_hw *hw)
-+{
-+ int32_t timeout = hw->eeprom.word_size + 1;
-+ uint32_t swsm;
-+
-+ DEBUGFUNC("e1000_get_software_semaphore");
-+
-+ if (hw->mac_type != e1000_80003es2lan)
-+ return E1000_SUCCESS;
-+
-+ while (timeout) {
-+ swsm = E1000_READ_REG(hw, SWSM);
-+ /* If SMBI bit cleared, it is now set and we hold the semaphore */
-+ if (!(swsm & E1000_SWSM_SMBI))
-+ break;
-+ msec_delay_irq(1);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("Driver can't access device - SMBI bit is set.\n");
-+ return -E1000_ERR_RESET;
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Release semaphore bit (SMBI).
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ ***************************************************************************/
-+void
-+e1000_release_software_semaphore(struct e1000_hw *hw)
-+{
-+ uint32_t swsm;
-+
-+ DEBUGFUNC("e1000_release_software_semaphore");
-+
-+ if (hw->mac_type != e1000_80003es2lan)
-+ return;
-+
-+ swsm = E1000_READ_REG(hw, SWSM);
-+ /* Release the SW semaphores.*/
-+ swsm &= ~E1000_SWSM_SMBI;
-+ E1000_WRITE_REG(hw, SWSM, swsm);
-+}
-+
-+/******************************************************************************
-+ * Checks if PHY reset is blocked due to SOL/IDER session, for example.
-+ * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to
-+ * the caller to figure out how to deal with it.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ *
-+ * returns: - E1000_BLK_PHY_RESET
-+ * E1000_SUCCESS
-+ *
-+ *****************************************************************************/
-+int32_t
-+e1000_check_phy_reset_block(struct e1000_hw *hw)
-+{
-+ uint32_t manc = 0;
-+ uint32_t fwsm = 0;
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ fwsm = E1000_READ_REG(hw, FWSM);
-+ return (fwsm & E1000_FWSM_RSPCIPHY) ? E1000_SUCCESS
-+ : E1000_BLK_PHY_RESET;
-+ }
-+
-+ if (hw->mac_type > e1000_82547_rev_2)
-+ manc = E1000_READ_REG(hw, MANC);
-+ return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ?
-+ E1000_BLK_PHY_RESET : E1000_SUCCESS;
-+}
-+
-+uint8_t
-+e1000_arc_subsystem_valid(struct e1000_hw *hw)
-+{
-+ uint32_t fwsm;
-+
-+ /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC
-+ * may not be provided a DMA clock when no manageability features are
-+ * enabled. We do not want to perform any reads/writes to these registers
-+ * if this is the case. We read FWSM to determine the manageability mode.
-+ */
-+ switch (hw->mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_80003es2lan:
-+ fwsm = E1000_READ_REG(hw, FWSM);
-+ if ((fwsm & E1000_FWSM_MODE_MASK) != 0)
-+ return TRUE;
-+ break;
-+ case e1000_ich8lan:
-+ return TRUE;
-+ default:
-+ break;
-+ }
-+ return FALSE;
-+}
-+
-+
-+/******************************************************************************
-+ * Configure PCI-Ex no-snoop
-+ *
-+ * hw - Struct containing variables accessed by shared code.
-+ * no_snoop - Bitmap of no-snoop events.
-+ *
-+ * returns: E1000_SUCCESS
-+ *
-+ *****************************************************************************/
-+int32_t
-+e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop)
-+{
-+ uint32_t gcr_reg = 0;
-+
-+ DEBUGFUNC("e1000_set_pci_ex_no_snoop");
-+
-+ if (hw->bus_type == e1000_bus_type_unknown)
-+ e1000_get_bus_info(hw);
-+
-+ if (hw->bus_type != e1000_bus_type_pci_express)
-+ return E1000_SUCCESS;
-+
-+ if (no_snoop) {
-+ gcr_reg = E1000_READ_REG(hw, GCR);
-+ gcr_reg &= ~(PCI_EX_NO_SNOOP_ALL);
-+ gcr_reg |= no_snoop;
-+ E1000_WRITE_REG(hw, GCR, gcr_reg);
-+ }
-+ if (hw->mac_type == e1000_ich8lan) {
-+ uint32_t ctrl_ext;
-+
-+ E1000_WRITE_REG(hw, GCR, PCI_EX_82566_SNOOP_ALL);
-+
-+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-+ ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
-+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Get software semaphore FLAG bit (SWFLAG).
-+ * SWFLAG is used to synchronize the access to all shared resource between
-+ * SW, FW and HW.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_get_software_flag(struct e1000_hw *hw)
-+{
-+ int32_t timeout = PHY_CFG_TIMEOUT;
-+ uint32_t extcnf_ctrl;
-+
-+ DEBUGFUNC("e1000_get_software_flag");
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ while (timeout) {
-+ extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
-+ extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
-+ E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
-+
-+ extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL);
-+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
-+ break;
-+ msec_delay_irq(1);
-+ timeout--;
-+ }
-+
-+ if (!timeout) {
-+ DEBUGOUT("FW or HW locks the resource too long.\n");
-+ return -E1000_ERR_CONFIG;
-+ }
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Release software semaphore FLAG bit (SWFLAG).
-+ * SWFLAG is used to synchronize the access to all shared resource between
-+ * SW, FW and HW.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ ***************************************************************************/
-+void
-+e1000_release_software_flag(struct e1000_hw *hw)
-+{
-+ uint32_t extcnf_ctrl;
-+
-+ DEBUGFUNC("e1000_release_software_flag");
-+
-+ if (hw->mac_type == e1000_ich8lan) {
-+ extcnf_ctrl= E1000_READ_REG(hw, EXTCNF_CTRL);
-+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
-+ E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl);
-+ }
-+
-+ return;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Disable dynamic power down mode in ife PHY.
-+ * It can be used to workaround band-gap problem.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw)
-+{
-+ uint16_t phy_data;
-+ int32_t ret_val = E1000_SUCCESS;
-+
-+ DEBUGFUNC("e1000_ife_disable_dynamic_power_down");
-+
-+ if (hw->phy_type == e1000_phy_ife) {
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-+ ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-+ }
-+
-+ return ret_val;
-+}
-+
-+/***************************************************************************
-+ *
-+ * Enable dynamic power down mode in ife PHY.
-+ * It can be used to workaround band-gap problem.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ ***************************************************************************/
-+int32_t
-+e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw)
-+{
-+ uint16_t phy_data;
-+ int32_t ret_val = E1000_SUCCESS;
-+
-+ DEBUGFUNC("e1000_ife_enable_dynamic_power_down");
-+
-+ if (hw->phy_type == e1000_phy_ife) {
-+ ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data &= ~IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN;
-+ ret_val = e1000_write_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, phy_data);
-+ }
-+
-+ return ret_val;
-+}
-+
-+/******************************************************************************
-+ * Reads a 16 bit word or words from the EEPROM using the ICH8's flash access
-+ * register.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ * offset - offset of word in the EEPROM to read
-+ * data - word read from the EEPROM
-+ * words - number of words to read
-+ *****************************************************************************/
-+int32_t
-+e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words,
-+ uint16_t *data)
-+{
-+ int32_t error = E1000_SUCCESS;
-+ uint32_t flash_bank = 0;
-+ uint32_t act_offset = 0;
-+ uint32_t bank_offset = 0;
-+ uint16_t word = 0;
-+ uint16_t i = 0;
-+
-+ /* We need to know which is the valid flash bank. In the event
-+ * that we didn't allocate eeprom_shadow_ram, we may not be
-+ * managing flash_bank. So it cannot be trusted and needs
-+ * to be updated with each read.
-+ */
-+ /* Value of bit 22 corresponds to the flash bank we're on. */
-+ flash_bank = (E1000_READ_REG(hw, EECD) & E1000_EECD_SEC1VAL) ? 1 : 0;
-+
-+ /* Adjust offset appropriately if we're on bank 1 - adjust for word size */
-+ bank_offset = flash_bank * (hw->flash_bank_size * 2);
-+
-+ error = e1000_get_software_flag(hw);
-+ if (error != E1000_SUCCESS)
-+ return error;
-+
-+ for (i = 0; i < words; i++) {
-+ if (hw->eeprom_shadow_ram != NULL &&
-+ hw->eeprom_shadow_ram[offset+i].modified == TRUE) {
-+ data[i] = hw->eeprom_shadow_ram[offset+i].eeprom_word;
-+ } else {
-+ /* The NVM part needs a byte offset, hence * 2 */
-+ act_offset = bank_offset + ((offset + i) * 2);
-+ error = e1000_read_ich8_word(hw, act_offset, &word);
-+ if (error != E1000_SUCCESS)
-+ break;
-+ data[i] = word;
-+ }
-+ }
-+
-+ e1000_release_software_flag(hw);
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Writes a 16 bit word or words to the EEPROM using the ICH8's flash access
-+ * register. Actually, writes are written to the shadow ram cache in the hw
-+ * structure hw->e1000_shadow_ram. e1000_commit_shadow_ram flushes this to
-+ * the NVM, which occurs when the NVM checksum is updated.
-+ *
-+ * hw - Struct containing variables accessed by shared code
-+ * offset - offset of word in the EEPROM to write
-+ * words - number of words to write
-+ * data - words to write to the EEPROM
-+ *****************************************************************************/
-+int32_t
-+e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset, uint16_t words,
-+ uint16_t *data)
-+{
-+ uint32_t i = 0;
-+ int32_t error = E1000_SUCCESS;
-+
-+ error = e1000_get_software_flag(hw);
-+ if (error != E1000_SUCCESS)
-+ return error;
-+
-+ /* A driver can write to the NVM only if it has eeprom_shadow_ram
-+ * allocated. Subsequent reads to the modified words are read from
-+ * this cached structure as well. Writes will only go into this
-+ * cached structure unless it's followed by a call to
-+ * e1000_update_eeprom_checksum() where it will commit the changes
-+ * and clear the "modified" field.
-+ */
-+ if (hw->eeprom_shadow_ram != NULL) {
-+ for (i = 0; i < words; i++) {
-+ if ((offset + i) < E1000_SHADOW_RAM_WORDS) {
-+ hw->eeprom_shadow_ram[offset+i].modified = TRUE;
-+ hw->eeprom_shadow_ram[offset+i].eeprom_word = data[i];
-+ } else {
-+ error = -E1000_ERR_EEPROM;
-+ break;
-+ }
-+ }
-+ } else {
-+ /* Drivers have the option to not allocate eeprom_shadow_ram as long
-+ * as they don't perform any NVM writes. An attempt in doing so
-+ * will result in this error.
-+ */
-+ error = -E1000_ERR_EEPROM;
-+ }
-+
-+ e1000_release_software_flag(hw);
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * This function does initial flash setup so that a new read/write/erase cycle
-+ * can be started.
-+ *
-+ * hw - The pointer to the hw structure
-+ ****************************************************************************/
-+int32_t
-+e1000_ich8_cycle_init(struct e1000_hw *hw)
-+{
-+ union ich8_hws_flash_status hsfsts;
-+ int32_t error = E1000_ERR_EEPROM;
-+ int32_t i = 0;
-+
-+ DEBUGFUNC("e1000_ich8_cycle_init");
-+
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+
-+ /* May be check the Flash Des Valid bit in Hw status */
-+ if (hsfsts.hsf_status.fldesvalid == 0) {
-+ DEBUGOUT("Flash descriptor invalid. SW Sequencing must be used.");
-+ return error;
-+ }
-+
-+ /* Clear FCERR in Hw status by writing 1 */
-+ /* Clear DAEL in Hw status by writing a 1 */
-+ hsfsts.hsf_status.flcerr = 1;
-+ hsfsts.hsf_status.dael = 1;
-+
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFSTS, hsfsts.regval);
-+
-+ /* Either we should have a hardware SPI cycle in progress bit to check
-+ * against, in order to start a new cycle or FDONE bit should be changed
-+ * in the hardware so that it is 1 after harware reset, which can then be
-+ * used as an indication whether a cycle is in progress or has been
-+ * completed .. we should also have some software semaphore mechanism to
-+ * guard FDONE or the cycle in progress bit so that two threads access to
-+ * those bits can be sequentiallized or a way so that 2 threads dont
-+ * start the cycle at the same time */
-+
-+ if (hsfsts.hsf_status.flcinprog == 0) {
-+ /* There is no cycle running at present, so we can start a cycle */
-+ /* Begin by setting Flash Cycle Done. */
-+ hsfsts.hsf_status.flcdone = 1;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFSTS, hsfsts.regval);
-+ error = E1000_SUCCESS;
-+ } else {
-+ /* otherwise poll for sometime so the current cycle has a chance
-+ * to end before giving up. */
-+ for (i = 0; i < ICH8_FLASH_COMMAND_TIMEOUT; i++) {
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+ if (hsfsts.hsf_status.flcinprog == 0) {
-+ error = E1000_SUCCESS;
-+ break;
-+ }
-+ usec_delay(1);
-+ }
-+ if (error == E1000_SUCCESS) {
-+ /* Successful in waiting for previous cycle to timeout,
-+ * now set the Flash Cycle Done. */
-+ hsfsts.hsf_status.flcdone = 1;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFSTS, hsfsts.regval);
-+ } else {
-+ DEBUGOUT("Flash controller busy, cannot get access");
-+ }
-+ }
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * This function starts a flash cycle and waits for its completion
-+ *
-+ * hw - The pointer to the hw structure
-+ ****************************************************************************/
-+int32_t
-+e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout)
-+{
-+ union ich8_hws_flash_ctrl hsflctl;
-+ union ich8_hws_flash_status hsfsts;
-+ int32_t error = E1000_ERR_EEPROM;
-+ uint32_t i = 0;
-+
-+ /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */
-+ hsflctl.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFCTL);
-+ hsflctl.hsf_ctrl.flcgo = 1;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFCTL, hsflctl.regval);
-+
-+ /* wait till FDONE bit is set to 1 */
-+ do {
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+ if (hsfsts.hsf_status.flcdone == 1)
-+ break;
-+ usec_delay(1);
-+ i++;
-+ } while (i < timeout);
-+ if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) {
-+ error = E1000_SUCCESS;
-+ }
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Reads a byte or word from the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - The pointer to the hw structure
-+ * index - The index of the byte or word to read.
-+ * size - Size of data to read, 1=byte 2=word
-+ * data - Pointer to the word to store the value read.
-+ *****************************************************************************/
-+int32_t
-+e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index,
-+ uint32_t size, uint16_t* data)
-+{
-+ union ich8_hws_flash_status hsfsts;
-+ union ich8_hws_flash_ctrl hsflctl;
-+ uint32_t flash_linear_address;
-+ uint32_t flash_data = 0;
-+ int32_t error = -E1000_ERR_EEPROM;
-+ int32_t count = 0;
-+
-+ DEBUGFUNC("e1000_read_ich8_data");
-+
-+ if (size < 1 || size > 2 || data == 0x0 ||
-+ index > ICH8_FLASH_LINEAR_ADDR_MASK)
-+ return error;
-+
-+ flash_linear_address = (ICH8_FLASH_LINEAR_ADDR_MASK & index) +
-+ hw->flash_base_addr;
-+
-+ do {
-+ usec_delay(1);
-+ /* Steps */
-+ error = e1000_ich8_cycle_init(hw);
-+ if (error != E1000_SUCCESS)
-+ break;
-+
-+ hsflctl.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFCTL);
-+ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
-+ hsflctl.hsf_ctrl.fldbcount = size - 1;
-+ hsflctl.hsf_ctrl.flcycle = ICH8_CYCLE_READ;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFCTL, hsflctl.regval);
-+
-+ /* Write the last 24 bits of index into Flash Linear address field in
-+ * Flash Address */
-+ /* TODO: TBD maybe check the index against the size of flash */
-+
-+ E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
-+
-+ error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_COMMAND_TIMEOUT);
-+
-+ /* Check if FCERR is set to 1, if set to 1, clear it and try the whole
-+ * sequence a few more times, else read in (shift in) the Flash Data0,
-+ * the order is least significant byte first msb to lsb */
-+ if (error == E1000_SUCCESS) {
-+ flash_data = E1000_READ_ICH8_REG(hw, ICH8_FLASH_FDATA0);
-+ if (size == 1) {
-+ *data = (uint8_t)(flash_data & 0x000000FF);
-+ } else if (size == 2) {
-+ *data = (uint16_t)(flash_data & 0x0000FFFF);
-+ }
-+ break;
-+ } else {
-+ /* If we've gotten here, then things are probably completely hosed,
-+ * but if the error condition is detected, it won't hurt to give
-+ * it another try...ICH8_FLASH_CYCLE_REPEAT_COUNT times.
-+ */
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+ if (hsfsts.hsf_status.flcerr == 1) {
-+ /* Repeat for some time before giving up. */
-+ continue;
-+ } else if (hsfsts.hsf_status.flcdone == 0) {
-+ DEBUGOUT("Timeout error - flash cycle did not complete.");
-+ break;
-+ }
-+ }
-+ } while (count++ < ICH8_FLASH_CYCLE_REPEAT_COUNT);
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Writes One /two bytes to the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - The pointer to the hw structure
-+ * index - The index of the byte/word to read.
-+ * size - Size of data to read, 1=byte 2=word
-+ * data - The byte(s) to write to the NVM.
-+ *****************************************************************************/
-+int32_t
-+e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index, uint32_t size,
-+ uint16_t data)
-+{
-+ union ich8_hws_flash_status hsfsts;
-+ union ich8_hws_flash_ctrl hsflctl;
-+ uint32_t flash_linear_address;
-+ uint32_t flash_data = 0;
-+ int32_t error = -E1000_ERR_EEPROM;
-+ int32_t count = 0;
-+
-+ DEBUGFUNC("e1000_write_ich8_data");
-+
-+ if (size < 1 || size > 2 || data > size * 0xff ||
-+ index > ICH8_FLASH_LINEAR_ADDR_MASK)
-+ return error;
-+
-+ flash_linear_address = (ICH8_FLASH_LINEAR_ADDR_MASK & index) +
-+ hw->flash_base_addr;
-+
-+ do {
-+ usec_delay(1);
-+ /* Steps */
-+ error = e1000_ich8_cycle_init(hw);
-+ if (error != E1000_SUCCESS)
-+ break;
-+
-+ hsflctl.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFCTL);
-+ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */
-+ hsflctl.hsf_ctrl.fldbcount = size -1;
-+ hsflctl.hsf_ctrl.flcycle = ICH8_CYCLE_WRITE;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFCTL, hsflctl.regval);
-+
-+ /* Write the last 24 bits of index into Flash Linear address field in
-+ * Flash Address */
-+ E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
-+
-+ if (size == 1)
-+ flash_data = (uint32_t)data & 0x00FF;
-+ else
-+ flash_data = (uint32_t)data;
-+
-+ E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FDATA0, flash_data);
-+
-+ /* check if FCERR is set to 1 , if set to 1, clear it and try the whole
-+ * sequence a few more times else done */
-+ error = e1000_ich8_flash_cycle(hw, ICH8_FLASH_COMMAND_TIMEOUT);
-+ if (error == E1000_SUCCESS) {
-+ break;
-+ } else {
-+ /* If we're here, then things are most likely completely hosed,
-+ * but if the error condition is detected, it won't hurt to give
-+ * it another try...ICH8_FLASH_CYCLE_REPEAT_COUNT times.
-+ */
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+ if (hsfsts.hsf_status.flcerr == 1) {
-+ /* Repeat for some time before giving up. */
-+ continue;
-+ } else if (hsfsts.hsf_status.flcdone == 0) {
-+ DEBUGOUT("Timeout error - flash cycle did not complete.");
-+ break;
-+ }
-+ }
-+ } while (count++ < ICH8_FLASH_CYCLE_REPEAT_COUNT);
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Reads a single byte from the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * index - The index of the byte to read.
-+ * data - Pointer to a byte to store the value read.
-+ *****************************************************************************/
-+int32_t
-+e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t* data)
-+{
-+ int32_t status = E1000_SUCCESS;
-+ uint16_t word = 0;
-+
-+ status = e1000_read_ich8_data(hw, index, 1, &word);
-+ if (status == E1000_SUCCESS) {
-+ *data = (uint8_t)word;
-+ }
-+
-+ return status;
-+}
-+
-+/******************************************************************************
-+ * Writes a single byte to the NVM using the ICH8 flash access registers.
-+ * Performs verification by reading back the value and then going through
-+ * a retry algorithm before giving up.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * index - The index of the byte to write.
-+ * byte - The byte to write to the NVM.
-+ *****************************************************************************/
-+int32_t
-+e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t byte)
-+{
-+ int32_t error = E1000_SUCCESS;
-+ int32_t program_retries;
-+ uint8_t temp_byte;
-+
-+ e1000_write_ich8_byte(hw, index, byte);
-+ usec_delay(100);
-+
-+ for (program_retries = 0; program_retries < 100; program_retries++) {
-+ e1000_read_ich8_byte(hw, index, &temp_byte);
-+ if (temp_byte == byte)
-+ break;
-+ usec_delay(10);
-+ e1000_write_ich8_byte(hw, index, byte);
-+ usec_delay(100);
-+ }
-+ if (program_retries == 100)
-+ error = E1000_ERR_EEPROM;
-+
-+ return error;
-+}
-+
-+/******************************************************************************
-+ * Writes a single byte to the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * index - The index of the byte to read.
-+ * data - The byte to write to the NVM.
-+ *****************************************************************************/
-+int32_t
-+e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index, uint8_t data)
-+{
-+ int32_t status = E1000_SUCCESS;
-+ uint16_t word = (uint16_t)data;
-+
-+ status = e1000_write_ich8_data(hw, index, 1, word);
-+
-+ return status;
-+}
-+
-+/******************************************************************************
-+ * Reads a word from the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * index - The starting byte index of the word to read.
-+ * data - Pointer to a word to store the value read.
-+ *****************************************************************************/
-+int32_t
-+e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t *data)
-+{
-+ int32_t status = E1000_SUCCESS;
-+ status = e1000_read_ich8_data(hw, index, 2, data);
-+ return status;
-+}
-+
-+/******************************************************************************
-+ * Writes a word to the NVM using the ICH8 flash access registers.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * index - The starting byte index of the word to read.
-+ * data - The word to write to the NVM.
-+ *****************************************************************************/
-+int32_t
-+e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index, uint16_t data)
-+{
-+ int32_t status = E1000_SUCCESS;
-+ status = e1000_write_ich8_data(hw, index, 2, data);
-+ return status;
-+}
-+
-+/******************************************************************************
-+ * Erases the bank specified. Each bank is a 4k block. Segments are 0 based.
-+ * segment N is 4096 * N + flash_reg_addr.
-+ *
-+ * hw - pointer to e1000_hw structure
-+ * segment - 0 for first segment, 1 for second segment, etc.
-+ *****************************************************************************/
-+int32_t
-+e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment)
-+{
-+ union ich8_hws_flash_status hsfsts;
-+ union ich8_hws_flash_ctrl hsflctl;
-+ uint32_t flash_linear_address;
-+ int32_t count = 0;
-+ int32_t error = E1000_ERR_EEPROM;
-+ int32_t iteration, seg_size;
-+ int32_t sector_size;
-+ int32_t j = 0;
-+ int32_t error_flag = 0;
-+
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+
-+ /* Determine HW Sector size: Read BERASE bits of Hw flash Status register */
-+ /* 00: The Hw sector is 256 bytes, hence we need to erase 16
-+ * consecutive sectors. The start index for the nth Hw sector can be
-+ * calculated as = segment * 4096 + n * 256
-+ * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
-+ * The start index for the nth Hw sector can be calculated
-+ * as = segment * 4096
-+ * 10: Error condition
-+ * 11: The Hw sector size is much bigger than the size asked to
-+ * erase...error condition */
-+ if (hsfsts.hsf_status.berasesz == 0x0) {
-+ /* Hw sector size 256 */
-+ sector_size = seg_size = ICH8_FLASH_SEG_SIZE_256;
-+ iteration = ICH8_FLASH_SECTOR_SIZE / ICH8_FLASH_SEG_SIZE_256;
-+ } else if (hsfsts.hsf_status.berasesz == 0x1) {
-+ sector_size = seg_size = ICH8_FLASH_SEG_SIZE_4K;
-+ iteration = 1;
-+ } else if (hsfsts.hsf_status.berasesz == 0x3) {
-+ sector_size = seg_size = ICH8_FLASH_SEG_SIZE_64K;
-+ iteration = 1;
-+ } else {
-+ return error;
-+ }
-+
-+ for (j = 0; j < iteration ; j++) {
-+ do {
-+ count++;
-+ /* Steps */
-+ error = e1000_ich8_cycle_init(hw);
-+ if (error != E1000_SUCCESS) {
-+ error_flag = 1;
-+ break;
-+ }
-+
-+ /* Write a value 11 (block Erase) in Flash Cycle field in Hw flash
-+ * Control */
-+ hsflctl.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFCTL);
-+ hsflctl.hsf_ctrl.flcycle = ICH8_CYCLE_ERASE;
-+ E1000_WRITE_ICH8_REG16(hw, ICH8_FLASH_HSFCTL, hsflctl.regval);
-+
-+ /* Write the last 24 bits of an index within the block into Flash
-+ * Linear address field in Flash Address. This probably needs to
-+ * be calculated here based off the on-chip segment size and the
-+ * software segment size assumed (4K) */
-+ /* TBD */
-+ flash_linear_address = segment * sector_size + j * seg_size;
-+ flash_linear_address &= ICH8_FLASH_LINEAR_ADDR_MASK;
-+ flash_linear_address += hw->flash_base_addr;
-+
-+ E1000_WRITE_ICH8_REG(hw, ICH8_FLASH_FADDR, flash_linear_address);
-+
-+ error = e1000_ich8_flash_cycle(hw, 1000000);
-+ /* Check if FCERR is set to 1. If 1, clear it and try the whole
-+ * sequence a few more times else Done */
-+ if (error == E1000_SUCCESS) {
-+ break;
-+ } else {
-+ hsfsts.regval = E1000_READ_ICH8_REG16(hw, ICH8_FLASH_HSFSTS);
-+ if (hsfsts.hsf_status.flcerr == 1) {
-+ /* repeat for some time before giving up */
-+ continue;
-+ } else if (hsfsts.hsf_status.flcdone == 0) {
-+ error_flag = 1;
-+ break;
-+ }
-+ }
-+ } while ((count < ICH8_FLASH_CYCLE_REPEAT_COUNT) && !error_flag);
-+ if (error_flag == 1)
-+ break;
-+ }
-+ if (error_flag != 1)
-+ error = E1000_SUCCESS;
-+ return error;
-+}
-+
-+/******************************************************************************
-+ *
-+ * Reverse duplex setting without breaking the link.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *
-+ *****************************************************************************/
-+int32_t
-+e1000_duplex_reversal(struct e1000_hw *hw)
-+{
-+ int32_t ret_val;
-+ uint16_t phy_data;
-+
-+ if (hw->phy_type != e1000_phy_igp_3)
-+ return E1000_SUCCESS;
-+
-+ ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data ^= MII_CR_FULL_DUPLEX;
-+
-+ ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, &phy_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ phy_data |= IGP3_PHY_MISC_DUPLEX_MANUAL_SET;
-+ ret_val = e1000_write_phy_reg(hw, IGP3E1000_PHY_MISC_CTRL, phy_data);
-+
-+ return ret_val;
-+}
-+
-+int32_t
-+e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw,
-+ uint32_t cnf_base_addr, uint32_t cnf_size)
-+{
-+ uint32_t ret_val = E1000_SUCCESS;
-+ uint16_t word_addr, reg_data, reg_addr;
-+ uint16_t i;
-+
-+ /* cnf_base_addr is in DWORD */
-+ word_addr = (uint16_t)(cnf_base_addr << 1);
-+
-+ /* cnf_size is returned in size of dwords */
-+ for (i = 0; i < cnf_size; i++) {
-+ ret_val = e1000_read_eeprom(hw, (word_addr + i*2), 1, &reg_data);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_read_eeprom(hw, (word_addr + i*2 + 1), 1, &reg_addr);
-+ if (ret_val)
-+ return ret_val;
-+
-+ ret_val = e1000_get_software_flag(hw);
-+ if (ret_val != E1000_SUCCESS)
-+ return ret_val;
-+
-+ ret_val = e1000_write_phy_reg_ex(hw, (uint32_t)reg_addr, reg_data);
-+
-+ e1000_release_software_flag(hw);
-+ }
-+
-+ return ret_val;
-+}
-+
-+
-+/******************************************************************************
-+ * This function initializes the PHY from the NVM on ICH8 platforms. This
-+ * is needed due to an issue where the NVM configuration is not properly
-+ * autoloaded after power transitions. Therefore, after each PHY reset, we
-+ * will load the configuration data out of the NVM manually.
-+ *
-+ * hw: Struct containing variables accessed by shared code
-+ *****************************************************************************/
-+int32_t
-+e1000_init_lcd_from_nvm(struct e1000_hw *hw)
-+{
-+ uint32_t reg_data, cnf_base_addr, cnf_size, ret_val, loop;
-+
-+ if (hw->phy_type != e1000_phy_igp_3)
-+ return E1000_SUCCESS;
-+
-+ /* Check if SW needs configure the PHY */
-+ reg_data = E1000_READ_REG(hw, FEXTNVM);
-+ if (!(reg_data & FEXTNVM_SW_CONFIG))
-+ return E1000_SUCCESS;
-+
-+ /* Wait for basic configuration completes before proceeding*/
-+ loop = 0;
-+ do {
-+ reg_data = E1000_READ_REG(hw, STATUS) & E1000_STATUS_LAN_INIT_DONE;
-+ usec_delay(100);
-+ loop++;
-+ } while ((!reg_data) && (loop < 50));
-+
-+ /* Clear the Init Done bit for the next init event */
-+ reg_data = E1000_READ_REG(hw, STATUS);
-+ reg_data &= ~E1000_STATUS_LAN_INIT_DONE;
-+ E1000_WRITE_REG(hw, STATUS, reg_data);
-+
-+ /* Make sure HW does not configure LCD from PHY extended configuration
-+ before SW configuration */
-+ reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
-+ if ((reg_data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) == 0x0000) {
-+ reg_data = E1000_READ_REG(hw, EXTCNF_SIZE);
-+ cnf_size = reg_data & E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH;
-+ cnf_size >>= 16;
-+ if (cnf_size) {
-+ reg_data = E1000_READ_REG(hw, EXTCNF_CTRL);
-+ cnf_base_addr = reg_data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER;
-+ /* cnf_base_addr is in DWORD */
-+ cnf_base_addr >>= 16;
-+
-+ /* Configure LCD from extended configuration region. */
-+ ret_val = e1000_init_lcd_from_nvm_config_region(hw, cnf_base_addr,
-+ cnf_size);
-+ if (ret_val)
-+ return ret_val;
-+ }
-+ }
-+
-+ return E1000_SUCCESS;
-+}
-+
-+
-+
-diff -pruN ./drivers/net/e1000.orig/e1000_hw.h ./drivers/net/e1000/e1000_hw.h
---- ./drivers/net/e1000.orig/e1000_hw.h 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_hw.h 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -57,6 +58,11 @@ typedef enum {
- e1000_82541_rev_2,
- e1000_82547,
- e1000_82547_rev_2,
-+ e1000_82571,
-+ e1000_82572,
-+ e1000_82573,
-+ e1000_80003es2lan,
-+ e1000_ich8lan,
- e1000_num_macs
- } e1000_mac_type;
-
-@@ -64,6 +70,9 @@ typedef enum {
- e1000_eeprom_uninitialized = 0,
- e1000_eeprom_spi,
- e1000_eeprom_microwire,
-+ e1000_eeprom_flash,
-+ e1000_eeprom_ich8,
-+ e1000_eeprom_none, /* No NVM support */
- e1000_num_eeprom_types
- } e1000_eeprom_type;
-
-@@ -91,11 +100,17 @@ typedef enum {
- e1000_fc_default = 0xFF
- } e1000_fc_type;
-
-+struct e1000_shadow_ram {
-+ uint16_t eeprom_word;
-+ boolean_t modified;
-+};
-+
- /* PCI bus types */
- typedef enum {
- e1000_bus_type_unknown = 0,
- e1000_bus_type_pci,
- e1000_bus_type_pcix,
-+ e1000_bus_type_pci_express,
- e1000_bus_type_reserved
- } e1000_bus_type;
-
-@@ -107,6 +122,7 @@ typedef enum {
- e1000_bus_speed_100,
- e1000_bus_speed_120,
- e1000_bus_speed_133,
-+ e1000_bus_speed_2500,
- e1000_bus_speed_reserved
- } e1000_bus_speed;
-
-@@ -115,6 +131,9 @@ typedef enum {
- e1000_bus_width_unknown = 0,
- e1000_bus_width_32,
- e1000_bus_width_64,
-+ e1000_bus_width_pciex_1,
-+ e1000_bus_width_pciex_2,
-+ e1000_bus_width_pciex_4,
- e1000_bus_width_reserved
- } e1000_bus_width;
-
-@@ -129,6 +148,13 @@ typedef enum {
- } e1000_cable_length;
-
- typedef enum {
-+ e1000_gg_cable_length_60 = 0,
-+ e1000_gg_cable_length_60_115 = 1,
-+ e1000_gg_cable_length_115_150 = 2,
-+ e1000_gg_cable_length_150 = 4
-+} e1000_gg_cable_length;
-+
-+typedef enum {
- e1000_igp_cable_length_10 = 10,
- e1000_igp_cable_length_20 = 20,
- e1000_igp_cable_length_30 = 30,
-@@ -140,6 +166,7 @@ typedef enum {
- e1000_igp_cable_length_90 = 90,
- e1000_igp_cable_length_100 = 100,
- e1000_igp_cable_length_110 = 110,
-+ e1000_igp_cable_length_115 = 115,
- e1000_igp_cable_length_120 = 120,
- e1000_igp_cable_length_130 = 130,
- e1000_igp_cable_length_140 = 140,
-@@ -168,6 +195,12 @@ typedef enum {
- } e1000_downshift;
-
- typedef enum {
-+ e1000_smart_speed_default = 0,
-+ e1000_smart_speed_on,
-+ e1000_smart_speed_off
-+} e1000_smart_speed;
-+
-+typedef enum {
- e1000_polarity_reversal_enabled = 0,
- e1000_polarity_reversal_disabled,
- e1000_polarity_reversal_undefined = 0xFF
-@@ -190,6 +223,10 @@ typedef enum {
- typedef enum {
- e1000_phy_m88 = 0,
- e1000_phy_igp,
-+ e1000_phy_igp_2,
-+ e1000_phy_gg82563,
-+ e1000_phy_igp_3,
-+ e1000_phy_ife,
- e1000_phy_undefined = 0xFF
- } e1000_phy_type;
-
-@@ -236,8 +273,19 @@ struct e1000_eeprom_info {
- uint16_t address_bits;
- uint16_t delay_usec;
- uint16_t page_size;
-+ boolean_t use_eerd;
-+ boolean_t use_eewr;
- };
-
-+/* Flex ASF Information */
-+#define E1000_HOST_IF_MAX_SIZE 2048
-+
-+typedef enum {
-+ e1000_byte_align = 0,
-+ e1000_word_align = 1,
-+ e1000_dword_align = 2
-+} e1000_align_type;
-+
-
-
- /* Error Codes */
-@@ -248,11 +296,17 @@ struct e1000_eeprom_info {
- #define E1000_ERR_PARAM 4
- #define E1000_ERR_MAC_TYPE 5
- #define E1000_ERR_PHY_TYPE 6
-+#define E1000_ERR_RESET 9
-+#define E1000_ERR_MASTER_REQUESTS_PENDING 10
-+#define E1000_ERR_HOST_INTERFACE_COMMAND 11
-+#define E1000_BLK_PHY_RESET 12
-+#define E1000_ERR_SWFW_SYNC 13
-
- /* Function prototypes */
- /* Initialization */
- int32_t e1000_reset_hw(struct e1000_hw *hw);
- int32_t e1000_init_hw(struct e1000_hw *hw);
-+int32_t e1000_id_led_init(struct e1000_hw * hw);
- int32_t e1000_set_mac_type(struct e1000_hw *hw);
- void e1000_set_media_type(struct e1000_hw *hw);
-
-@@ -269,8 +323,13 @@ int32_t e1000_force_mac_fc(struct e1000_
- /* PHY */
- int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data);
- int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
--void e1000_phy_hw_reset(struct e1000_hw *hw);
-+int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
- int32_t e1000_phy_reset(struct e1000_hw *hw);
-+void e1000_phy_powerdown_workaround(struct e1000_hw *hw);
-+int32_t e1000_kumeran_lock_loss_workaround(struct e1000_hw *hw);
-+int32_t e1000_duplex_reversal(struct e1000_hw *hw);
-+int32_t e1000_init_lcd_from_nvm_config_region(struct e1000_hw *hw, uint32_t cnf_base_addr, uint32_t cnf_size);
-+int32_t e1000_init_lcd_from_nvm(struct e1000_hw *hw);
- int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
- int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
- int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-@@ -279,15 +338,93 @@ int32_t e1000_get_cable_length(struct e1
- int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
- int32_t e1000_check_downshift(struct e1000_hw *hw);
- int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
-+int32_t e1000_read_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *data);
-+int32_t e1000_write_kmrn_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
-
- /* EEPROM Functions */
--void e1000_init_eeprom_params(struct e1000_hw *hw);
-+int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
-+boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-+int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-+int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-+int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
-+
-+/* MNG HOST IF functions */
-+uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
-+
-+#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64
-+#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */
-+
-+#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */
-+#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */
-+#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */
-+#define E1000_MNG_IAMT_MODE 0x3
-+#define E1000_MNG_ICH_IAMT_MODE 0x2
-+#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */
-+
-+#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */
-+#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */
-+#define E1000_VFTA_ENTRY_SHIFT 0x5
-+#define E1000_VFTA_ENTRY_MASK 0x7F
-+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
-+
-+struct e1000_host_mng_command_header {
-+ uint8_t command_id;
-+ uint8_t checksum;
-+ uint16_t reserved1;
-+ uint16_t reserved2;
-+ uint16_t command_length;
-+};
-+
-+struct e1000_host_mng_command_info {
-+ struct e1000_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
-+ uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/
-+};
-+#ifdef E1000_BIG_ENDIAN
-+struct e1000_host_mng_dhcp_cookie{
-+ uint32_t signature;
-+ uint16_t vlan_id;
-+ uint8_t reserved0;
-+ uint8_t status;
-+ uint32_t reserved1;
-+ uint8_t checksum;
-+ uint8_t reserved3;
-+ uint16_t reserved2;
-+};
-+#else
-+struct e1000_host_mng_dhcp_cookie{
-+ uint32_t signature;
-+ uint8_t status;
-+ uint8_t reserved0;
-+ uint16_t vlan_id;
-+ uint32_t reserved1;
-+ uint16_t reserved2;
-+ uint8_t reserved3;
-+ uint8_t checksum;
-+};
-+#endif
-+
-+int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer,
-+ uint16_t length);
-+boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
-+boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-+int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
-+int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
-+ uint16_t length, uint16_t offset, uint8_t *sum);
-+int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw,
-+ struct e1000_host_mng_command_header* hdr);
-+
-+int32_t e1000_mng_write_commit(struct e1000_hw *hw);
-+
- int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
- int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
- int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw);
- int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
- int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num);
- int32_t e1000_read_mac_addr(struct e1000_hw * hw);
-+int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask);
-+void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
-+void e1000_release_software_flag(struct e1000_hw *hw);
-+int32_t e1000_get_software_flag(struct e1000_hw *hw);
-
- /* Filters (multicast, vlan, receive) */
- void e1000_init_rx_addrs(struct e1000_hw *hw);
-@@ -303,11 +440,11 @@ int32_t e1000_setup_led(struct e1000_hw
- int32_t e1000_cleanup_led(struct e1000_hw *hw);
- int32_t e1000_led_on(struct e1000_hw *hw);
- int32_t e1000_led_off(struct e1000_hw *hw);
-+int32_t e1000_blink_led_start(struct e1000_hw *hw);
-
- /* Adaptive IFS Functions */
-
- /* Everything else */
--uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
- void e1000_clear_hw_cntrs(struct e1000_hw *hw);
- void e1000_reset_adaptive(struct e1000_hw *hw);
- void e1000_update_adaptive(struct e1000_hw *hw);
-@@ -324,6 +461,46 @@ void e1000_io_write(struct e1000_hw *hw,
- void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
- int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
- int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-+int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-+void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
-+void e1000_enable_pciex_master(struct e1000_hw *hw);
-+int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
-+int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-+int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
-+int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
-+void e1000_release_software_semaphore(struct e1000_hw *hw);
-+int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
-+int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-+void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-+int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-+uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-+int32_t e1000_set_pci_ex_no_snoop(struct e1000_hw *hw, uint32_t no_snoop);
-+
-+int32_t e1000_read_ich8_byte(struct e1000_hw *hw, uint32_t index,
-+ uint8_t *data);
-+int32_t e1000_verify_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
-+ uint8_t byte);
-+int32_t e1000_write_ich8_byte(struct e1000_hw *hw, uint32_t index,
-+ uint8_t byte);
-+int32_t e1000_read_ich8_word(struct e1000_hw *hw, uint32_t index,
-+ uint16_t *data);
-+int32_t e1000_write_ich8_word(struct e1000_hw *hw, uint32_t index,
-+ uint16_t word);
-+int32_t e1000_read_ich8_data(struct e1000_hw *hw, uint32_t index,
-+ uint32_t size, uint16_t *data);
-+int32_t e1000_write_ich8_data(struct e1000_hw *hw, uint32_t index,
-+ uint32_t size, uint16_t data);
-+int32_t e1000_read_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-+ uint16_t words, uint16_t *data);
-+int32_t e1000_write_eeprom_ich8(struct e1000_hw *hw, uint16_t offset,
-+ uint16_t words, uint16_t *data);
-+int32_t e1000_erase_ich8_4k_segment(struct e1000_hw *hw, uint32_t segment);
-+int32_t e1000_ich8_cycle_init(struct e1000_hw *hw);
-+int32_t e1000_ich8_flash_cycle(struct e1000_hw *hw, uint32_t timeout);
-+int32_t e1000_phy_ife_get_info(struct e1000_hw *hw,
-+ struct e1000_phy_info *phy_info);
-+int32_t e1000_ife_disable_dynamic_power_down(struct e1000_hw *hw);
-+int32_t e1000_ife_enable_dynamic_power_down(struct e1000_hw *hw);
-
- #define E1000_READ_REG_IO(a, reg) \
- e1000_read_reg_io((a), E1000_##reg)
-@@ -353,14 +530,42 @@ int32_t e1000_set_d3_lplu_state(struct e
- #define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
- #define E1000_DEV_ID_82541EI 0x1013
- #define E1000_DEV_ID_82541EI_MOBILE 0x1018
-+#define E1000_DEV_ID_82541ER_LOM 0x1014
- #define E1000_DEV_ID_82541ER 0x1078
- #define E1000_DEV_ID_82547GI 0x1075
- #define E1000_DEV_ID_82541GI 0x1076
- #define E1000_DEV_ID_82541GI_MOBILE 0x1077
-+#define E1000_DEV_ID_82541GI_LF 0x107C
- #define E1000_DEV_ID_82546GB_COPPER 0x1079
- #define E1000_DEV_ID_82546GB_FIBER 0x107A
- #define E1000_DEV_ID_82546GB_SERDES 0x107B
-+#define E1000_DEV_ID_82546GB_PCIE 0x108A
-+#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
- #define E1000_DEV_ID_82547EI 0x1019
-+#define E1000_DEV_ID_82547EI_MOBILE 0x101A
-+#define E1000_DEV_ID_82571EB_COPPER 0x105E
-+#define E1000_DEV_ID_82571EB_FIBER 0x105F
-+#define E1000_DEV_ID_82571EB_SERDES 0x1060
-+#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
-+#define E1000_DEV_ID_82572EI_COPPER 0x107D
-+#define E1000_DEV_ID_82572EI_FIBER 0x107E
-+#define E1000_DEV_ID_82572EI_SERDES 0x107F
-+#define E1000_DEV_ID_82572EI 0x10B9
-+#define E1000_DEV_ID_82573E 0x108B
-+#define E1000_DEV_ID_82573E_IAMT 0x108C
-+#define E1000_DEV_ID_82573L 0x109A
-+#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
-+#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096
-+#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098
-+#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA
-+#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT 0x10BB
-+
-+#define E1000_DEV_ID_ICH8_IGP_M_AMT 0x1049
-+#define E1000_DEV_ID_ICH8_IGP_AMT 0x104A
-+#define E1000_DEV_ID_ICH8_IGP_C 0x104B
-+#define E1000_DEV_ID_ICH8_IFE 0x104C
-+#define E1000_DEV_ID_ICH8_IGP_M 0x104D
-+
-
- #define NODE_ADDRESS_SIZE 6
- #define ETH_LENGTH_OF_ADDRESS 6
-@@ -373,6 +578,7 @@ int32_t e1000_set_d3_lplu_state(struct e
- #define E1000_REVISION_0 0
- #define E1000_REVISION_1 1
- #define E1000_REVISION_2 2
-+#define E1000_REVISION_3 3
-
- #define SPEED_10 10
- #define SPEED_100 100
-@@ -394,7 +600,7 @@ int32_t e1000_set_d3_lplu_state(struct e
-
-
- /* 802.1q VLAN Packet Sizes */
--#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
-+#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMAed) */
-
- /* Ethertype field values */
- #define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */
-@@ -429,12 +635,22 @@ int32_t e1000_set_d3_lplu_state(struct e
- E1000_IMS_RXSEQ | \
- E1000_IMS_LSC)
-
-+/* Additional interrupts need to be handled for e1000_ich8lan:
-+ DSW = The FW changed the status of the DISSW bit in FWSM
-+ PHYINT = The LAN connected device generates an interrupt
-+ EPRST = Manageability reset event */
-+#define IMS_ICH8LAN_ENABLE_MASK (\
-+ E1000_IMS_DSW | \
-+ E1000_IMS_PHYINT | \
-+ E1000_IMS_EPRST)
-+
- /* Number of high/low register pairs in the RAR. The RAR (Receive Address
- * Registers) holds the directed and multicast addresses that we monitor. We
- * reserve one of these spots for our directed address, allowing us room for
- * E1000_RAR_ENTRIES - 1 multicast addresses.
- */
- #define E1000_RAR_ENTRIES 15
-+#define E1000_RAR_ENTRIES_ICH8LAN 7
-
- #define MIN_NUMBER_OF_DESCRIPTORS 8
- #define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
-@@ -449,14 +665,74 @@ struct e1000_rx_desc {
- uint16_t special;
- };
-
-+/* Receive Descriptor - Extended */
-+union e1000_rx_desc_extended {
-+ struct {
-+ uint64_t buffer_addr;
-+ uint64_t reserved;
-+ } read;
-+ struct {
-+ struct {
-+ uint32_t mrq; /* Multiple Rx Queues */
-+ union {
-+ uint32_t rss; /* RSS Hash */
-+ struct {
-+ uint16_t ip_id; /* IP id */
-+ uint16_t csum; /* Packet Checksum */
-+ } csum_ip;
-+ } hi_dword;
-+ } lower;
-+ struct {
-+ uint32_t status_error; /* ext status/error */
-+ uint16_t length;
-+ uint16_t vlan; /* VLAN tag */
-+ } upper;
-+ } wb; /* writeback */
-+};
-+
-+#define MAX_PS_BUFFERS 4
-+/* Receive Descriptor - Packet Split */
-+union e1000_rx_desc_packet_split {
-+ struct {
-+ /* one buffer for protocol header(s), three data buffers */
-+ uint64_t buffer_addr[MAX_PS_BUFFERS];
-+ } read;
-+ struct {
-+ struct {
-+ uint32_t mrq; /* Multiple Rx Queues */
-+ union {
-+ uint32_t rss; /* RSS Hash */
-+ struct {
-+ uint16_t ip_id; /* IP id */
-+ uint16_t csum; /* Packet Checksum */
-+ } csum_ip;
-+ } hi_dword;
-+ } lower;
-+ struct {
-+ uint32_t status_error; /* ext status/error */
-+ uint16_t length0; /* length of buffer 0 */
-+ uint16_t vlan; /* VLAN tag */
-+ } middle;
-+ struct {
-+ uint16_t header_status;
-+ uint16_t length[3]; /* length of buffers 1-3 */
-+ } upper;
-+ uint64_t reserved;
-+ } wb; /* writeback */
-+};
-+
- /* Receive Decriptor bit definitions */
- #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
- #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */
- #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */
- #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */
-+#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */
- #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */
- #define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */
- #define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */
-+#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */
-+#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */
-+#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */
- #define E1000_RXD_ERR_CE 0x01 /* CRC Error */
- #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */
- #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */
-@@ -466,9 +742,20 @@ struct e1000_rx_desc {
- #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */
- #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */
- #define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */
--#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */
-+#define E1000_RXD_SPC_PRI_SHIFT 13
- #define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */
--#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */
-+#define E1000_RXD_SPC_CFI_SHIFT 12
-+
-+#define E1000_RXDEXT_STATERR_CE 0x01000000
-+#define E1000_RXDEXT_STATERR_SE 0x02000000
-+#define E1000_RXDEXT_STATERR_SEQ 0x04000000
-+#define E1000_RXDEXT_STATERR_CXE 0x10000000
-+#define E1000_RXDEXT_STATERR_TCPE 0x20000000
-+#define E1000_RXDEXT_STATERR_IPE 0x40000000
-+#define E1000_RXDEXT_STATERR_RXE 0x80000000
-+
-+#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000
-+#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
-
- /* mask to determine if packets should be dropped due to frame errors */
- #define E1000_RXD_ERR_FRAME_ERR_MASK ( \
-@@ -478,6 +765,16 @@ struct e1000_rx_desc {
- E1000_RXD_ERR_CXE | \
- E1000_RXD_ERR_RXE)
-
-+
-+/* Same mask, but for extended and packet split descriptors */
-+#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
-+ E1000_RXDEXT_STATERR_CE | \
-+ E1000_RXDEXT_STATERR_SE | \
-+ E1000_RXDEXT_STATERR_SEQ | \
-+ E1000_RXDEXT_STATERR_CXE | \
-+ E1000_RXDEXT_STATERR_RXE)
-+
-+
- /* Transmit Descriptor */
- struct e1000_tx_desc {
- uint64_t buffer_addr; /* Address of the descriptor's data buffer */
-@@ -576,6 +873,9 @@ struct e1000_data_desc {
- #define E1000_MC_TBL_SIZE 128 /* Multicast Filter Table (4096 bits) */
- #define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */
-
-+#define E1000_NUM_UNICAST_ICH8LAN 7
-+#define E1000_MC_TBL_SIZE_ICH8LAN 32
-+
-
- /* Receive Address Register */
- struct e1000_rar {
-@@ -585,6 +885,7 @@ struct e1000_rar {
-
- /* Number of entries in the Multicast Table Array (MTA). */
- #define E1000_NUM_MTA_REGISTERS 128
-+#define E1000_NUM_MTA_REGISTERS_ICH8LAN 32
-
- /* IPv4 Address Table Entry */
- struct e1000_ipv4_at_entry {
-@@ -595,6 +896,7 @@ struct e1000_ipv4_at_entry {
- /* Four wakeup IP addresses are supported */
- #define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
- #define E1000_IP4AT_SIZE E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
-+#define E1000_IP4AT_SIZE_ICH8LAN 3
- #define E1000_IP6AT_SIZE 1
-
- /* IPv6 Address Table Entry */
-@@ -630,6 +932,8 @@ struct e1000_ffvt_entry {
- #define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
- #define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
-
-+#define E1000_DISABLE_SERDES_LOOPBACK 0x0400
-+
- /* Register Set. (82543, 82544)
- *
- * Registers are defined to be 32 bits and should be accessed as 32 bit values.
-@@ -650,6 +954,8 @@ struct e1000_ffvt_entry {
- #define E1000_CTRL_EXT 0x00018 /* Extended Device Control - RW */
- #define E1000_FLA 0x0001C /* Flash Access - RW */
- #define E1000_MDIC 0x00020 /* MDI Control - RW */
-+#define E1000_SCTL 0x00024 /* SerDes Control - RW */
-+#define E1000_FEXTNVM 0x00028 /* Future Extended NVM register */
- #define E1000_FCAL 0x00028 /* Flow Control Address Low - RW */
- #define E1000_FCAH 0x0002C /* Flow Control Address High -RW */
- #define E1000_FCT 0x00030 /* Flow Control Type - RW */
-@@ -659,28 +965,61 @@ struct e1000_ffvt_entry {
- #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */
- #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */
- #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */
-+#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */
- #define E1000_RCTL 0x00100 /* RX Control - RW */
-+#define E1000_RDTR1 0x02820 /* RX Delay Timer (1) - RW */
-+#define E1000_RDBAL1 0x02900 /* RX Descriptor Base Address Low (1) - RW */
-+#define E1000_RDBAH1 0x02904 /* RX Descriptor Base Address High (1) - RW */
-+#define E1000_RDLEN1 0x02908 /* RX Descriptor Length (1) - RW */
-+#define E1000_RDH1 0x02910 /* RX Descriptor Head (1) - RW */
-+#define E1000_RDT1 0x02918 /* RX Descriptor Tail (1) - RW */
- #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */
- #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */
- #define E1000_RXCW 0x00180 /* RX Configuration Word - RO */
- #define E1000_TCTL 0x00400 /* TX Control - RW */
-+#define E1000_TCTL_EXT 0x00404 /* Extended TX Control - RW */
- #define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
- #define E1000_TBT 0x00448 /* TX Burst Timer - RW */
- #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
- #define E1000_LEDCTL 0x00E00 /* LED Control - RW */
-+#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */
-+#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */
-+#define E1000_PHY_CTRL 0x00F10 /* PHY Control Register in CSR */
-+#define FEXTNVM_SW_CONFIG 0x0001
- #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
-+#define E1000_PBS 0x01008 /* Packet Buffer Size */
-+#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
-+#define E1000_FLASH_UPDATES 1000
-+#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */
-+#define E1000_FLASHT 0x01028 /* FLASH Timer Register */
-+#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */
-+#define E1000_FLSWCTL 0x01030 /* FLASH control register */
-+#define E1000_FLSWDATA 0x01034 /* FLASH data register */
-+#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */
-+#define E1000_FLOP 0x0103C /* FLASH Opcode Register */
-+#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */
- #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */
- #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */
-+#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */
- #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */
- #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */
- #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */
- #define E1000_RDH 0x02810 /* RX Descriptor Head - RW */
- #define E1000_RDT 0x02818 /* RX Descriptor Tail - RW */
- #define E1000_RDTR 0x02820 /* RX Delay Timer - RW */
--#define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */
-+#define E1000_RDBAL0 E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
-+#define E1000_RDBAH0 E1000_RDBAH /* RX Desc Base Address High (0) - RW */
-+#define E1000_RDLEN0 E1000_RDLEN /* RX Desc Length (0) - RW */
-+#define E1000_RDH0 E1000_RDH /* RX Desc Head (0) - RW */
-+#define E1000_RDT0 E1000_RDT /* RX Desc Tail (0) - RW */
-+#define E1000_RDTR0 E1000_RDTR /* RX Delay Timer (0) - RW */
-+#define E1000_RXDCTL 0x02828 /* RX Descriptor Control queue 0 - RW */
-+#define E1000_RXDCTL1 0x02928 /* RX Descriptor Control queue 1 - RW */
- #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */
- #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */
-+#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */
- #define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */
-+#define E1000_KABGTXD 0x03004 /* AFE Band Gap Transmit Ref Data */
- #define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */
- #define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */
- #define E1000_TDFHS 0x03420 /* TX Data FIFO Head Saved - RW */
-@@ -695,6 +1034,14 @@ struct e1000_ffvt_entry {
- #define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */
- #define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */
- #define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */
-+#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */
-+#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */
-+#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */
-+#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */
-+#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */
-+#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */
-+#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */
-+#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */
- #define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */
- #define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */
- #define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */
-@@ -753,7 +1100,17 @@ struct e1000_ffvt_entry {
- #define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */
- #define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */
- #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */
-+#define E1000_IAC 0x04100 /* Interrupt Assertion Count */
-+#define E1000_ICRXPTC 0x04104 /* Interrupt Cause Rx Packet Timer Expire Count */
-+#define E1000_ICRXATC 0x04108 /* Interrupt Cause Rx Absolute Timer Expire Count */
-+#define E1000_ICTXPTC 0x0410C /* Interrupt Cause Tx Packet Timer Expire Count */
-+#define E1000_ICTXATC 0x04110 /* Interrupt Cause Tx Absolute Timer Expire Count */
-+#define E1000_ICTXQEC 0x04118 /* Interrupt Cause Tx Queue Empty Count */
-+#define E1000_ICTXQMTC 0x0411C /* Interrupt Cause Tx Queue Minimum Threshold Count */
-+#define E1000_ICRXDMTC 0x04120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-+#define E1000_ICRXOC 0x04124 /* Interrupt Cause Receiver Overrun Count */
- #define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */
-+#define E1000_RFCTL 0x05008 /* Receive Filter Control*/
- #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */
- #define E1000_RA 0x05400 /* Receive Address - RW Array */
- #define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */
-@@ -771,6 +1128,29 @@ struct e1000_ffvt_entry {
- #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */
- #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */
-
-+#define E1000_KUMCTRLSTA 0x00034 /* MAC-PHY interface - RW */
-+#define E1000_MDPHYA 0x0003C /* PHY address - RW */
-+#define E1000_MANC2H 0x05860 /* Managment Control To Host - RW */
-+#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */
-+
-+#define E1000_GCR 0x05B00 /* PCI-Ex Control */
-+#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */
-+#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */
-+#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */
-+#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */
-+#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */
-+#define E1000_SWSM 0x05B50 /* SW Semaphore */
-+#define E1000_FWSM 0x05B54 /* FW Semaphore */
-+#define E1000_FFLT_DBG 0x05F04 /* Debug Register */
-+#define E1000_HICR 0x08F00 /* Host Inteface Control */
-+
-+/* RSS registers */
-+#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */
-+#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */
-+#define E1000_RETA 0x05C00 /* Redirection Table - RW Array */
-+#define E1000_RSSRK 0x05C80 /* RSS Random Key - RW Array */
-+#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */
-+#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */
- /* Register Set (82542)
- *
- * Some of the 82542 registers are located at different offsets than they are
-@@ -785,6 +1165,8 @@ struct e1000_ffvt_entry {
- #define E1000_82542_CTRL_EXT E1000_CTRL_EXT
- #define E1000_82542_FLA E1000_FLA
- #define E1000_82542_MDIC E1000_MDIC
-+#define E1000_82542_SCTL E1000_SCTL
-+#define E1000_82542_FEXTNVM E1000_FEXTNVM
- #define E1000_82542_FCAL E1000_FCAL
- #define E1000_82542_FCAH E1000_FCAH
- #define E1000_82542_FCT E1000_FCT
-@@ -802,6 +1184,31 @@ struct e1000_ffvt_entry {
- #define E1000_82542_RDLEN 0x00118
- #define E1000_82542_RDH 0x00120
- #define E1000_82542_RDT 0x00128
-+#define E1000_82542_RDTR0 E1000_82542_RDTR
-+#define E1000_82542_RDBAL0 E1000_82542_RDBAL
-+#define E1000_82542_RDBAH0 E1000_82542_RDBAH
-+#define E1000_82542_RDLEN0 E1000_82542_RDLEN
-+#define E1000_82542_RDH0 E1000_82542_RDH
-+#define E1000_82542_RDT0 E1000_82542_RDT
-+#define E1000_82542_SRRCTL(_n) (0x280C + ((_n) << 8)) /* Split and Replication
-+ * RX Control - RW */
-+#define E1000_82542_DCA_RXCTRL(_n) (0x02814 + ((_n) << 8))
-+#define E1000_82542_RDBAH3 0x02B04 /* RX Desc Base High Queue 3 - RW */
-+#define E1000_82542_RDBAL3 0x02B00 /* RX Desc Low Queue 3 - RW */
-+#define E1000_82542_RDLEN3 0x02B08 /* RX Desc Length Queue 3 - RW */
-+#define E1000_82542_RDH3 0x02B10 /* RX Desc Head Queue 3 - RW */
-+#define E1000_82542_RDT3 0x02B18 /* RX Desc Tail Queue 3 - RW */
-+#define E1000_82542_RDBAL2 0x02A00 /* RX Desc Base Low Queue 2 - RW */
-+#define E1000_82542_RDBAH2 0x02A04 /* RX Desc Base High Queue 2 - RW */
-+#define E1000_82542_RDLEN2 0x02A08 /* RX Desc Length Queue 2 - RW */
-+#define E1000_82542_RDH2 0x02A10 /* RX Desc Head Queue 2 - RW */
-+#define E1000_82542_RDT2 0x02A18 /* RX Desc Tail Queue 2 - RW */
-+#define E1000_82542_RDTR1 0x00130
-+#define E1000_82542_RDBAL1 0x00138
-+#define E1000_82542_RDBAH1 0x0013C
-+#define E1000_82542_RDLEN1 0x00140
-+#define E1000_82542_RDH1 0x00148
-+#define E1000_82542_RDT1 0x00150
- #define E1000_82542_FCRTH 0x00160
- #define E1000_82542_FCRTL 0x00168
- #define E1000_82542_FCTTV E1000_FCTTV
-@@ -809,6 +1216,7 @@ struct e1000_ffvt_entry {
- #define E1000_82542_RXCW E1000_RXCW
- #define E1000_82542_MTA 0x00200
- #define E1000_82542_TCTL E1000_TCTL
-+#define E1000_82542_TCTL_EXT E1000_TCTL_EXT
- #define E1000_82542_TIPG E1000_TIPG
- #define E1000_82542_TDBAL 0x00420
- #define E1000_82542_TDBAH 0x00424
-@@ -821,10 +1229,25 @@ struct e1000_ffvt_entry {
- #define E1000_82542_VFTA 0x00600
- #define E1000_82542_LEDCTL E1000_LEDCTL
- #define E1000_82542_PBA E1000_PBA
-+#define E1000_82542_PBS E1000_PBS
-+#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-+#define E1000_82542_EEARBC E1000_EEARBC
-+#define E1000_82542_FLASHT E1000_FLASHT
-+#define E1000_82542_EEWR E1000_EEWR
-+#define E1000_82542_FLSWCTL E1000_FLSWCTL
-+#define E1000_82542_FLSWDATA E1000_FLSWDATA
-+#define E1000_82542_FLSWCNT E1000_FLSWCNT
-+#define E1000_82542_FLOP E1000_FLOP
-+#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL
-+#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE
-+#define E1000_82542_PHY_CTRL E1000_PHY_CTRL
-+#define E1000_82542_ERT E1000_ERT
- #define E1000_82542_RXDCTL E1000_RXDCTL
-+#define E1000_82542_RXDCTL1 E1000_RXDCTL1
- #define E1000_82542_RADV E1000_RADV
- #define E1000_82542_RSRPD E1000_RSRPD
- #define E1000_82542_TXDMAC E1000_TXDMAC
-+#define E1000_82542_KABGTXD E1000_KABGTXD
- #define E1000_82542_TDFHS E1000_TDFHS
- #define E1000_82542_TDFTS E1000_TDFTS
- #define E1000_82542_TDFPC E1000_TDFPC
-@@ -905,6 +1328,47 @@ struct e1000_ffvt_entry {
- #define E1000_82542_FFMT E1000_FFMT
- #define E1000_82542_FFVT E1000_FFVT
- #define E1000_82542_HOST_IF E1000_HOST_IF
-+#define E1000_82542_IAM E1000_IAM
-+#define E1000_82542_EEMNGCTL E1000_EEMNGCTL
-+#define E1000_82542_PSRCTL E1000_PSRCTL
-+#define E1000_82542_RAID E1000_RAID
-+#define E1000_82542_TARC0 E1000_TARC0
-+#define E1000_82542_TDBAL1 E1000_TDBAL1
-+#define E1000_82542_TDBAH1 E1000_TDBAH1
-+#define E1000_82542_TDLEN1 E1000_TDLEN1
-+#define E1000_82542_TDH1 E1000_TDH1
-+#define E1000_82542_TDT1 E1000_TDT1
-+#define E1000_82542_TXDCTL1 E1000_TXDCTL1
-+#define E1000_82542_TARC1 E1000_TARC1
-+#define E1000_82542_RFCTL E1000_RFCTL
-+#define E1000_82542_GCR E1000_GCR
-+#define E1000_82542_GSCL_1 E1000_GSCL_1
-+#define E1000_82542_GSCL_2 E1000_GSCL_2
-+#define E1000_82542_GSCL_3 E1000_GSCL_3
-+#define E1000_82542_GSCL_4 E1000_GSCL_4
-+#define E1000_82542_FACTPS E1000_FACTPS
-+#define E1000_82542_SWSM E1000_SWSM
-+#define E1000_82542_FWSM E1000_FWSM
-+#define E1000_82542_FFLT_DBG E1000_FFLT_DBG
-+#define E1000_82542_IAC E1000_IAC
-+#define E1000_82542_ICRXPTC E1000_ICRXPTC
-+#define E1000_82542_ICRXATC E1000_ICRXATC
-+#define E1000_82542_ICTXPTC E1000_ICTXPTC
-+#define E1000_82542_ICTXATC E1000_ICTXATC
-+#define E1000_82542_ICTXQEC E1000_ICTXQEC
-+#define E1000_82542_ICTXQMTC E1000_ICTXQMTC
-+#define E1000_82542_ICRXDMTC E1000_ICRXDMTC
-+#define E1000_82542_ICRXOC E1000_ICRXOC
-+#define E1000_82542_HICR E1000_HICR
-+
-+#define E1000_82542_CPUVEC E1000_CPUVEC
-+#define E1000_82542_MRQC E1000_MRQC
-+#define E1000_82542_RETA E1000_RETA
-+#define E1000_82542_RSSRK E1000_RSSRK
-+#define E1000_82542_RSSIM E1000_RSSIM
-+#define E1000_82542_RSSIR E1000_RSSIR
-+#define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA
-+#define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC
-
- /* Statistics counters collected by the MAC */
- struct e1000_hw_stats {
-@@ -966,16 +1430,29 @@ struct e1000_hw_stats {
- uint64_t bptc;
- uint64_t tsctc;
- uint64_t tsctfc;
-+ uint64_t iac;
-+ uint64_t icrxptc;
-+ uint64_t icrxatc;
-+ uint64_t ictxptc;
-+ uint64_t ictxatc;
-+ uint64_t ictxqec;
-+ uint64_t ictxqmtc;
-+ uint64_t icrxdmtc;
-+ uint64_t icrxoc;
- };
-
- /* Structure containing variables used by the shared code (e1000_hw.c) */
- struct e1000_hw {
- uint8_t *hw_addr;
-+ uint8_t *flash_address;
- e1000_mac_type mac_type;
- e1000_phy_type phy_type;
- uint32_t phy_init_script;
- e1000_media_type media_type;
- void *back;
-+ struct e1000_shadow_ram *eeprom_shadow_ram;
-+ uint32_t flash_bank_size;
-+ uint32_t flash_base_addr;
- e1000_fc_type fc;
- e1000_bus_speed bus_speed;
- e1000_bus_width bus_width;
-@@ -985,6 +1462,9 @@ struct e1000_hw {
- e1000_ms_type original_master_slave;
- e1000_ffe_config ffe_config_state;
- uint32_t asf_firmware_present;
-+ uint32_t eeprom_semaphore_present;
-+ uint32_t swfw_sync_present;
-+ uint32_t swfwhw_semaphore_present;
- unsigned long io_base;
- uint32_t phy_id;
- uint32_t phy_revision;
-@@ -1001,6 +1481,8 @@ struct e1000_hw {
- uint32_t ledctl_default;
- uint32_t ledctl_mode1;
- uint32_t ledctl_mode2;
-+ boolean_t tx_pkt_filtering;
-+ struct e1000_host_mng_dhcp_cookie mng_cookie;
- uint16_t phy_spd_default;
- uint16_t autoneg_advertised;
- uint16_t pci_cmd_word;
-@@ -1026,11 +1508,13 @@ struct e1000_hw {
- uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
- boolean_t disable_polarity_correction;
- boolean_t speed_downgraded;
-+ e1000_smart_speed smart_speed;
- e1000_dsp_config dsp_config_state;
- boolean_t get_link_status;
- boolean_t serdes_link_down;
- boolean_t tbi_compatibility_en;
- boolean_t tbi_compatibility_on;
-+ boolean_t laa_is_present;
- boolean_t phy_reset_disable;
- boolean_t fc_send_xon;
- boolean_t fc_strict_ieee;
-@@ -1038,17 +1522,26 @@ struct e1000_hw {
- boolean_t adaptive_ifs;
- boolean_t ifs_params_forced;
- boolean_t in_ifs_mode;
-+ boolean_t mng_reg_access_disabled;
-+ boolean_t leave_av_bit_off;
-+ boolean_t kmrn_lock_loss_workaround_disabled;
- };
-
-
- #define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */
- #define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */
--
-+#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */
-+#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */
-+#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */
-+#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */
-+#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */
-+#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */
- /* Register Bit Masks */
- /* Device Control */
- #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */
- #define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */
- #define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */
-+#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */
- #define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */
- #define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */
- #define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */
-@@ -1062,6 +1555,10 @@ struct e1000_hw {
- #define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */
- #define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */
- #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */
-+#define E1000_CTRL_D_UD_EN 0x00002000 /* Dock/Undock enable */
-+#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
-+#define E1000_CTRL_FORCE_PHY_RESET 0x00008000 /* Reset both PHY ports, through PHYRST_N pin */
-+#define E1000_CTRL_EXT_LINK_EN 0x00010000 /* enable link status from external LINK_0 and LINK_1 pins */
- #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */
- #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */
- #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */
-@@ -1076,11 +1573,13 @@ struct e1000_hw {
- #define E1000_CTRL_RTE 0x20000000 /* Routing tag enable */
- #define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */
- #define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */
-+#define E1000_CTRL_SW2FW_INT 0x02000000 /* Initiate an interrupt to manageability engine */
-
- /* Device Status */
- #define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */
- #define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */
- #define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */
-+#define E1000_STATUS_FUNC_SHIFT 2
- #define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */
- #define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */
- #define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */
-@@ -1089,12 +1588,26 @@ struct e1000_hw {
- #define E1000_STATUS_SPEED_10 0x00000000 /* Speed 10Mb/s */
- #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */
- #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */
-+#define E1000_STATUS_LAN_INIT_DONE 0x00000200 /* Lan Init Completion
-+ by EEPROM/Flash */
- #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */
-+#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */
-+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */
- #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */
- #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */
- #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */
- #define E1000_STATUS_PCIX_MODE 0x00002000 /* PCI-X mode */
- #define E1000_STATUS_PCIX_SPEED 0x0000C000 /* PCI-X bus speed */
-+#define E1000_STATUS_BMC_SKU_0 0x00100000 /* BMC USB redirect disabled */
-+#define E1000_STATUS_BMC_SKU_1 0x00200000 /* BMC SRAM disabled */
-+#define E1000_STATUS_BMC_SKU_2 0x00400000 /* BMC SDRAM disabled */
-+#define E1000_STATUS_BMC_CRYPTO 0x00800000 /* BMC crypto disabled */
-+#define E1000_STATUS_BMC_LITE 0x01000000 /* BMC external code execution disabled */
-+#define E1000_STATUS_RGMII_ENABLE 0x02000000 /* RGMII disabled */
-+#define E1000_STATUS_FUSE_8 0x04000000
-+#define E1000_STATUS_FUSE_9 0x08000000
-+#define E1000_STATUS_SERDES0_DIS 0x10000000 /* SERDES disabled on port 0 */
-+#define E1000_STATUS_SERDES1_DIS 0x20000000 /* SERDES disabled on port 1 */
-
- /* Constants used to intrepret the masked PCI-X bus speed. */
- #define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */
-@@ -1120,6 +1633,23 @@ struct e1000_hw {
- #ifndef E1000_EEPROM_GRANT_ATTEMPTS
- #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
- #endif
-+#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */
-+#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */
-+#define E1000_EECD_SIZE_EX_SHIFT 11
-+#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */
-+#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */
-+#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */
-+#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */
-+#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */
-+#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */
-+#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */
-+#define E1000_EECD_SECVAL_SHIFT 22
-+#define E1000_STM_OPCODE 0xDB00
-+#define E1000_HICR_FW_RESET 0xC0
-+
-+#define E1000_SHADOW_RAM_WORDS 2048
-+#define E1000_ICH8_NVM_SIG_WORD 0x13
-+#define E1000_ICH8_NVM_SIG_MASK 0xC0
-
- /* EEPROM Read */
- #define E1000_EERD_START 0x00000001 /* Start Read */
-@@ -1155,14 +1685,23 @@ struct e1000_hw {
- #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
- #define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */
- #define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
-+#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
- #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
- #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
- #define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000
-+#define E1000_CTRL_EXT_LINK_MODE_KMRN 0x00000000
-+#define E1000_CTRL_EXT_LINK_MODE_SERDES 0x00C00000
- #define E1000_CTRL_EXT_WR_WMARK_MASK 0x03000000
- #define E1000_CTRL_EXT_WR_WMARK_256 0x00000000
- #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000
- #define E1000_CTRL_EXT_WR_WMARK_384 0x02000000
- #define E1000_CTRL_EXT_WR_WMARK_448 0x03000000
-+#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */
-+#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */
-+#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */
-+#define E1000_CRTL_EXT_PB_PAREN 0x01000000 /* packet buffer parity error detection enabled */
-+#define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */
-+#define E1000_CTRL_EXT_GHOST_PAREN 0x40000000
-
- /* MDI Control */
- #define E1000_MDIC_DATA_MASK 0x0000FFFF
-@@ -1176,21 +1715,70 @@ struct e1000_hw {
- #define E1000_MDIC_INT_EN 0x20000000
- #define E1000_MDIC_ERROR 0x40000000
-
-+#define E1000_KUMCTRLSTA_MASK 0x0000FFFF
-+#define E1000_KUMCTRLSTA_OFFSET 0x001F0000
-+#define E1000_KUMCTRLSTA_OFFSET_SHIFT 16
-+#define E1000_KUMCTRLSTA_REN 0x00200000
-+
-+#define E1000_KUMCTRLSTA_OFFSET_FIFO_CTRL 0x00000000
-+#define E1000_KUMCTRLSTA_OFFSET_CTRL 0x00000001
-+#define E1000_KUMCTRLSTA_OFFSET_INB_CTRL 0x00000002
-+#define E1000_KUMCTRLSTA_OFFSET_DIAG 0x00000003
-+#define E1000_KUMCTRLSTA_OFFSET_TIMEOUTS 0x00000004
-+#define E1000_KUMCTRLSTA_OFFSET_INB_PARAM 0x00000009
-+#define E1000_KUMCTRLSTA_OFFSET_HD_CTRL 0x00000010
-+#define E1000_KUMCTRLSTA_OFFSET_M2P_SERDES 0x0000001E
-+#define E1000_KUMCTRLSTA_OFFSET_M2P_MODES 0x0000001F
-+
-+/* FIFO Control */
-+#define E1000_KUMCTRLSTA_FIFO_CTRL_RX_BYPASS 0x00000008
-+#define E1000_KUMCTRLSTA_FIFO_CTRL_TX_BYPASS 0x00000800
-+
-+/* In-Band Control */
-+#define E1000_KUMCTRLSTA_INB_CTRL_LINK_STATUS_TX_TIMEOUT_DEFAULT 0x00000500
-+#define E1000_KUMCTRLSTA_INB_CTRL_DIS_PADDING 0x00000010
-+
-+/* Half-Duplex Control */
-+#define E1000_KUMCTRLSTA_HD_CTRL_10_100_DEFAULT 0x00000004
-+#define E1000_KUMCTRLSTA_HD_CTRL_1000_DEFAULT 0x00000000
-+
-+#define E1000_KUMCTRLSTA_OFFSET_K0S_CTRL 0x0000001E
-+
-+#define E1000_KUMCTRLSTA_DIAG_FELPBK 0x2000
-+#define E1000_KUMCTRLSTA_DIAG_NELPBK 0x1000
-+
-+#define E1000_KUMCTRLSTA_K0S_100_EN 0x2000
-+#define E1000_KUMCTRLSTA_K0S_GBE_EN 0x1000
-+#define E1000_KUMCTRLSTA_K0S_ENTRY_LATENCY_MASK 0x0003
-+
-+#define E1000_KABGTXD_BGSQLBIAS 0x00050000
-+
-+#define E1000_PHY_CTRL_SPD_EN 0x00000001
-+#define E1000_PHY_CTRL_D0A_LPLU 0x00000002
-+#define E1000_PHY_CTRL_NOND0A_LPLU 0x00000004
-+#define E1000_PHY_CTRL_NOND0A_GBE_DISABLE 0x00000008
-+#define E1000_PHY_CTRL_GBE_DISABLE 0x00000040
-+#define E1000_PHY_CTRL_B2B_EN 0x00000080
-+
- /* LED Control */
- #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F
- #define E1000_LEDCTL_LED0_MODE_SHIFT 0
-+#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020
- #define E1000_LEDCTL_LED0_IVRT 0x00000040
- #define E1000_LEDCTL_LED0_BLINK 0x00000080
- #define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00
- #define E1000_LEDCTL_LED1_MODE_SHIFT 8
-+#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000
- #define E1000_LEDCTL_LED1_IVRT 0x00004000
- #define E1000_LEDCTL_LED1_BLINK 0x00008000
- #define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000
- #define E1000_LEDCTL_LED2_MODE_SHIFT 16
-+#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000
- #define E1000_LEDCTL_LED2_IVRT 0x00400000
- #define E1000_LEDCTL_LED2_BLINK 0x00800000
- #define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000
- #define E1000_LEDCTL_LED3_MODE_SHIFT 24
-+#define E1000_LEDCTL_LED3_BLINK_RATE 0x20000000
- #define E1000_LEDCTL_LED3_IVRT 0x40000000
- #define E1000_LEDCTL_LED3_BLINK 0x80000000
-
-@@ -1230,6 +1818,20 @@ struct e1000_hw {
- #define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */
- #define E1000_ICR_TXD_LOW 0x00008000
- #define E1000_ICR_SRPD 0x00010000
-+#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */
-+#define E1000_ICR_MNG 0x00040000 /* Manageability event */
-+#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */
-+#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */
-+#define E1000_ICR_RXD_FIFO_PAR0 0x00100000 /* queue 0 Rx descriptor FIFO parity error */
-+#define E1000_ICR_TXD_FIFO_PAR0 0x00200000 /* queue 0 Tx descriptor FIFO parity error */
-+#define E1000_ICR_HOST_ARB_PAR 0x00400000 /* host arb read buffer parity error */
-+#define E1000_ICR_PB_PAR 0x00800000 /* packet buffer parity error */
-+#define E1000_ICR_RXD_FIFO_PAR1 0x01000000 /* queue 1 Rx descriptor FIFO parity error */
-+#define E1000_ICR_TXD_FIFO_PAR1 0x02000000 /* queue 1 Tx descriptor FIFO parity error */
-+#define E1000_ICR_ALL_PARITY 0x03F00000 /* all parity error bits */
-+#define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */
-+#define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */
-+#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
-
- /* Interrupt Cause Set */
- #define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-@@ -1247,6 +1849,18 @@ struct e1000_hw {
- #define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
- #define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
- #define E1000_ICS_SRPD E1000_ICR_SRPD
-+#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */
-+#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */
-+#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-+#define E1000_ICS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-+#define E1000_ICS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-+#define E1000_ICS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-+#define E1000_ICS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-+#define E1000_ICS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-+#define E1000_ICS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-+#define E1000_ICS_DSW E1000_ICR_DSW
-+#define E1000_ICS_PHYINT E1000_ICR_PHYINT
-+#define E1000_ICS_EPRST E1000_ICR_EPRST
-
- /* Interrupt Mask Set */
- #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-@@ -1264,6 +1878,18 @@ struct e1000_hw {
- #define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
- #define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
- #define E1000_IMS_SRPD E1000_ICR_SRPD
-+#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */
-+#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */
-+#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */
-+#define E1000_IMS_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-+#define E1000_IMS_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-+#define E1000_IMS_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-+#define E1000_IMS_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-+#define E1000_IMS_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-+#define E1000_IMS_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-+#define E1000_IMS_DSW E1000_ICR_DSW
-+#define E1000_IMS_PHYINT E1000_ICR_PHYINT
-+#define E1000_IMS_EPRST E1000_ICR_EPRST
-
- /* Interrupt Mask Clear */
- #define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */
-@@ -1281,6 +1907,18 @@ struct e1000_hw {
- #define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */
- #define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
- #define E1000_IMC_SRPD E1000_ICR_SRPD
-+#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */
-+#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */
-+#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */
-+#define E1000_IMC_RXD_FIFO_PAR0 E1000_ICR_RXD_FIFO_PAR0 /* queue 0 Rx descriptor FIFO parity error */
-+#define E1000_IMC_TXD_FIFO_PAR0 E1000_ICR_TXD_FIFO_PAR0 /* queue 0 Tx descriptor FIFO parity error */
-+#define E1000_IMC_HOST_ARB_PAR E1000_ICR_HOST_ARB_PAR /* host arb read buffer parity error */
-+#define E1000_IMC_PB_PAR E1000_ICR_PB_PAR /* packet buffer parity error */
-+#define E1000_IMC_RXD_FIFO_PAR1 E1000_ICR_RXD_FIFO_PAR1 /* queue 1 Rx descriptor FIFO parity error */
-+#define E1000_IMC_TXD_FIFO_PAR1 E1000_ICR_TXD_FIFO_PAR1 /* queue 1 Tx descriptor FIFO parity error */
-+#define E1000_IMC_DSW E1000_ICR_DSW
-+#define E1000_IMC_PHYINT E1000_ICR_PHYINT
-+#define E1000_IMC_EPRST E1000_ICR_EPRST
-
- /* Receive Control */
- #define E1000_RCTL_RST 0x00000001 /* Software reset */
-@@ -1293,6 +1931,8 @@ struct e1000_hw {
- #define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */
- #define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */
- #define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */
-+#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */
-+#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */
- #define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */
- #define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */
- #define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */
-@@ -1319,6 +1959,40 @@ struct e1000_hw {
- #define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */
- #define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */
- #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */
-+#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */
-+#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */
-+
-+/* Use byte values for the following shift parameters
-+ * Usage:
-+ * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
-+ * E1000_PSRCTL_BSIZE0_MASK) |
-+ * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) &
-+ * E1000_PSRCTL_BSIZE1_MASK) |
-+ * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) &
-+ * E1000_PSRCTL_BSIZE2_MASK) |
-+ * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |;
-+ * E1000_PSRCTL_BSIZE3_MASK))
-+ * where value0 = [128..16256], default=256
-+ * value1 = [1024..64512], default=4096
-+ * value2 = [0..64512], default=4096
-+ * value3 = [0..64512], default=0
-+ */
-+
-+#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F
-+#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00
-+#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000
-+#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000
-+
-+#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */
-+#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */
-+#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */
-+#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */
-+
-+/* SW_W_SYNC definitions */
-+#define E1000_SWFW_EEP_SM 0x0001
-+#define E1000_SWFW_PHY0_SM 0x0002
-+#define E1000_SWFW_PHY1_SM 0x0004
-+#define E1000_SWFW_MAC_CSR_SM 0x0008
-
- /* Receive Descriptor */
- #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */
-@@ -1333,6 +2007,23 @@ struct e1000_hw {
- #define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */
- #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */
-
-+/* Header split receive */
-+#define E1000_RFCTL_ISCSI_DIS 0x00000001
-+#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E
-+#define E1000_RFCTL_ISCSI_DWC_SHIFT 1
-+#define E1000_RFCTL_NFSW_DIS 0x00000040
-+#define E1000_RFCTL_NFSR_DIS 0x00000080
-+#define E1000_RFCTL_NFS_VER_MASK 0x00000300
-+#define E1000_RFCTL_NFS_VER_SHIFT 8
-+#define E1000_RFCTL_IPV6_DIS 0x00000400
-+#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800
-+#define E1000_RFCTL_ACK_DIS 0x00001000
-+#define E1000_RFCTL_ACKD_DIS 0x00002000
-+#define E1000_RFCTL_IPFRSP_DIS 0x00004000
-+#define E1000_RFCTL_EXTEN 0x00008000
-+#define E1000_RFCTL_IPV6_EX_DIS 0x00010000
-+#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000
-+
- /* Receive Descriptor Control */
- #define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
- #define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
-@@ -1346,7 +2037,8 @@ struct e1000_hw {
- #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */
- #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
- #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
--
-+#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
-+ still to be processed. */
- /* Transmit Configuration Word */
- #define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */
- #define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */
-@@ -1379,12 +2071,32 @@ struct e1000_hw {
- #define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */
- #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
- #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */
-+#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */
-+/* Extended Transmit Control */
-+#define E1000_TCTL_EXT_BST_MASK 0x000003FF /* Backoff Slot Time */
-+#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
-+
-+#define DEFAULT_80003ES2LAN_TCTL_EXT_GCEX 0x00010000
-
- /* Receive Checksum Control */
- #define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */
- #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */
- #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */
- #define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */
-+#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */
-+#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */
-+
-+/* Multiple Receive Queue Control */
-+#define E1000_MRQC_ENABLE_MASK 0x00000003
-+#define E1000_MRQC_ENABLE_RSS_2Q 0x00000001
-+#define E1000_MRQC_ENABLE_RSS_INT 0x00000004
-+#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000
-+#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
-+#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
-+#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000
-+#define E1000_MRQC_RSS_FIELD_IPV6_EX 0x00080000
-+#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000
-+#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000
-
- /* Definitions for power management and wakeup registers */
- /* Wake Up Control */
-@@ -1403,6 +2115,7 @@ struct e1000_hw {
- #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */
- #define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
- #define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
-+#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */
- #define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
- #define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
- #define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
-@@ -1438,13 +2151,20 @@ struct e1000_hw {
- #define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */
- #define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery
- * Filtering */
-+#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */
- #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */
- #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */
- #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
-+#define E1000_MANC_RCV_ALL 0x00080000 /* Receive All Enabled */
-+#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */
- #define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address
- * filtering */
- #define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host
- * memory */
-+#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address
-+ * filtering */
-+#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */
-+#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */
- #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */
- #define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */
- #define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */
-@@ -1455,11 +2175,125 @@ struct e1000_hw {
- #define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */
- #define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */
-
-+/* SW Semaphore Register */
-+#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
-+#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
-+#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */
-+#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */
-+
-+/* FW Semaphore Register */
-+#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */
-+#define E1000_FWSM_MODE_SHIFT 1
-+#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */
-+
-+#define E1000_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI reset */
-+#define E1000_FWSM_DISSW 0x10000000 /* FW disable SW Write Access */
-+#define E1000_FWSM_SKUSEL_MASK 0x60000000 /* LAN SKU select */
-+#define E1000_FWSM_SKUEL_SHIFT 29
-+#define E1000_FWSM_SKUSEL_EMB 0x0 /* Embedded SKU */
-+#define E1000_FWSM_SKUSEL_CONS 0x1 /* Consumer SKU */
-+#define E1000_FWSM_SKUSEL_PERF_100 0x2 /* Perf & Corp 10/100 SKU */
-+#define E1000_FWSM_SKUSEL_PERF_GBE 0x3 /* Perf & Copr GbE SKU */
-+
-+/* FFLT Debug Register */
-+#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */
-+
-+typedef enum {
-+ e1000_mng_mode_none = 0,
-+ e1000_mng_mode_asf,
-+ e1000_mng_mode_pt,
-+ e1000_mng_mode_ipmi,
-+ e1000_mng_mode_host_interface_only
-+} e1000_mng_mode;
-+
-+/* Host Inteface Control Register */
-+#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */
-+#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done
-+ * to put command in RAM */
-+#define E1000_HICR_SV 0x00000004 /* Status Validity */
-+#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */
-+
-+/* Host Interface Command Interface - Address range 0x8800-0x8EFF */
-+#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */
-+#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */
-+#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */
-+#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */
-+
-+struct e1000_host_command_header {
-+ uint8_t command_id;
-+ uint8_t command_length;
-+ uint8_t command_options; /* I/F bits for command, status for return */
-+ uint8_t checksum;
-+};
-+struct e1000_host_command_info {
-+ struct e1000_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */
-+ uint8_t command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */
-+};
-+
-+/* Host SMB register #0 */
-+#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */
-+#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */
-+#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */
-+#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */
-+
-+/* Host SMB register #1 */
-+#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN
-+#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN
-+#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT
-+#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT
-+
-+/* FW Status Register */
-+#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */
-+
- /* Wake Up Packet Length */
- #define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */
-
- #define E1000_MDALIGN 4096
-
-+/* PCI-Ex registers*/
-+
-+/* PCI-Ex Control Register */
-+#define E1000_GCR_RXD_NO_SNOOP 0x00000001
-+#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002
-+#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004
-+#define E1000_GCR_TXD_NO_SNOOP 0x00000008
-+#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010
-+#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020
-+
-+#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \
-+ E1000_GCR_RXDSCW_NO_SNOOP | \
-+ E1000_GCR_RXDSCR_NO_SNOOP | \
-+ E1000_GCR_TXD_NO_SNOOP | \
-+ E1000_GCR_TXDSCW_NO_SNOOP | \
-+ E1000_GCR_TXDSCR_NO_SNOOP)
-+
-+#define PCI_EX_82566_SNOOP_ALL PCI_EX_NO_SNOOP_ALL
-+
-+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
-+/* Function Active and Power State to MNG */
-+#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003
-+#define E1000_FACTPS_LAN0_VALID 0x00000004
-+#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008
-+#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0
-+#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6
-+#define E1000_FACTPS_LAN1_VALID 0x00000100
-+#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200
-+#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000
-+#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12
-+#define E1000_FACTPS_IDE_ENABLE 0x00004000
-+#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000
-+#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000
-+#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18
-+#define E1000_FACTPS_SP_ENABLE 0x00100000
-+#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000
-+#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000
-+#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24
-+#define E1000_FACTPS_IPMI_ENABLE 0x04000000
-+#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000
-+#define E1000_FACTPS_MNGCG 0x20000000
-+#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000
-+#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000
-+
- /* EEPROM Commands - Microwire */
- #define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */
- #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */
-@@ -1468,45 +2302,56 @@ struct e1000_hw {
- #define EEPROM_EWDS_OPCODE_MICROWIRE 0x10 /* EEPROM erast/write disable */
-
- /* EEPROM Commands - SPI */
--#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
--#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */
--#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */
--#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */
--#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */
--#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */
--#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */
--#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */
-+#define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */
-+#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */
-+#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */
-+#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */
-+#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */
-+#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */
-+#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */
-+#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */
-+#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */
-+#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */
-+#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */
-
- /* EEPROM Size definitions */
--#define EEPROM_SIZE_16KB 0x1800
--#define EEPROM_SIZE_8KB 0x1400
--#define EEPROM_SIZE_4KB 0x1000
--#define EEPROM_SIZE_2KB 0x0C00
--#define EEPROM_SIZE_1KB 0x0800
--#define EEPROM_SIZE_512B 0x0400
--#define EEPROM_SIZE_128B 0x0000
-+#define EEPROM_WORD_SIZE_SHIFT 6
-+#define EEPROM_SIZE_SHIFT 10
- #define EEPROM_SIZE_MASK 0x1C00
-
- /* EEPROM Word Offsets */
- #define EEPROM_COMPAT 0x0003
- #define EEPROM_ID_LED_SETTINGS 0x0004
-+#define EEPROM_VERSION 0x0005
- #define EEPROM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */
- #define EEPROM_PHY_CLASS_WORD 0x0007
- #define EEPROM_INIT_CONTROL1_REG 0x000A
- #define EEPROM_INIT_CONTROL2_REG 0x000F
-+#define EEPROM_SWDEF_PINS_CTRL_PORT_1 0x0010
- #define EEPROM_INIT_CONTROL3_PORT_B 0x0014
-+#define EEPROM_INIT_3GIO_3 0x001A
-+#define EEPROM_SWDEF_PINS_CTRL_PORT_0 0x0020
- #define EEPROM_INIT_CONTROL3_PORT_A 0x0024
- #define EEPROM_CFG 0x0012
- #define EEPROM_FLASH_VERSION 0x0032
- #define EEPROM_CHECKSUM_REG 0x003F
-
-+#define E1000_EEPROM_CFG_DONE 0x00040000 /* MNG config cycle done */
-+#define E1000_EEPROM_CFG_DONE_PORT_1 0x00080000 /* ...for second port */
-+
- /* Word definitions for ID LED Settings */
- #define ID_LED_RESERVED_0000 0x0000
- #define ID_LED_RESERVED_FFFF 0xFFFF
-+#define ID_LED_RESERVED_82573 0xF746
-+#define ID_LED_DEFAULT_82573 0x1811
- #define ID_LED_DEFAULT ((ID_LED_OFF1_ON2 << 12) | \
- (ID_LED_OFF1_OFF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_DEF1_DEF2))
-+#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \
-+ (ID_LED_DEF1_OFF2 << 8) | \
-+ (ID_LED_DEF1_ON2 << 4) | \
-+ (ID_LED_DEF1_DEF2))
- #define ID_LED_DEF1_DEF2 0x1
- #define ID_LED_DEF1_ON2 0x2
- #define ID_LED_DEF1_OFF2 0x3
-@@ -1541,6 +2386,14 @@ struct e1000_hw {
- #define EEPROM_WORD0F_ASM_DIR 0x2000
- #define EEPROM_WORD0F_ANE 0x0800
- #define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
-+#define EEPROM_WORD0F_LPLU 0x0001
-+
-+/* Mask bits for fields in Word 0x10/0x20 of the EEPROM */
-+#define EEPROM_WORD1020_GIGA_DISABLE 0x0010
-+#define EEPROM_WORD1020_GIGA_DISABLE_NON_D0A 0x0008
-+
-+/* Mask bits for fields in Word 0x1a of the EEPROM */
-+#define EEPROM_WORD1A_ASPM_MASK 0x000C
-
- /* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
- #define EEPROM_SUM 0xBABA
-@@ -1557,7 +2410,10 @@ struct e1000_hw {
- /* Collision related configuration parameters */
- #define E1000_COLLISION_THRESHOLD 15
- #define E1000_CT_SHIFT 4
--#define E1000_COLLISION_DISTANCE 64
-+/* Collision distance is a 0-based value that applies to
-+ * half-duplex-capable hardware only. */
-+#define E1000_COLLISION_DISTANCE 63
-+#define E1000_COLLISION_DISTANCE_82542 64
- #define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
- #define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE
- #define E1000_COLD_SHIFT 12
-@@ -1581,8 +2437,11 @@ struct e1000_hw {
-
- #define DEFAULT_82542_TIPG_IPGR2 10
- #define DEFAULT_82543_TIPG_IPGR2 6
-+#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7
- #define E1000_TIPG_IPGR2_SHIFT 20
-
-+#define DEFAULT_80003ES2LAN_TIPG_IPGT_10_100 0x00000009
-+#define DEFAULT_80003ES2LAN_TIPG_IPGT_1000 0x00000008
- #define E1000_TXDMAC_DPP 0x00000001
-
- /* Adaptive IFS defines */
-@@ -1598,14 +2457,37 @@ struct e1000_hw {
- #define IFS_MIN 40
- #define IFS_RATIO 4
-
-+/* Extended Configuration Control and Size */
-+#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001
-+#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002
-+#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004
-+#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008
-+#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010
-+#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
-+#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040
-+#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x0FFF0000
-+
-+#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF
-+#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00
-+#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000
-+#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
-+#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
-+
- /* PBA constants */
-+#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */
-+#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */
- #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */
- #define E1000_PBA_22K 0x0016
- #define E1000_PBA_24K 0x0018
- #define E1000_PBA_30K 0x001E
-+#define E1000_PBA_32K 0x0020
-+#define E1000_PBA_34K 0x0022
-+#define E1000_PBA_38K 0x0026
- #define E1000_PBA_40K 0x0028
- #define E1000_PBA_48K 0x0030 /* 48KB, default RX allocation */
-
-+#define E1000_PBS_16K E1000_PBA_16K
-+
- /* Flow Control Constants */
- #define FLOW_CONTROL_ADDRESS_LOW 0x00C28001
- #define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
-@@ -1655,6 +2537,13 @@ struct e1000_hw {
- /* Number of milliseconds we wait for auto-negotiation to complete */
- #define LINK_UP_TIMEOUT 500
-
-+/* Number of 100 microseconds we wait for PCI Express master disable */
-+#define MASTER_DISABLE_TIMEOUT 800
-+/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */
-+#define AUTO_READ_DONE_TIMEOUT 10
-+/* Number of milliseconds we wait for PHY configuration done after MAC reset */
-+#define PHY_CFG_TIMEOUT 100
-+
- #define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
-
- /* The carrier extension symbol, as received by the NIC. */
-@@ -1727,6 +2616,9 @@ struct e1000_hw {
- #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
- #define PHY_EXT_STATUS 0x0F /* Extended Status Reg */
-
-+#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
-+#define MAX_PHY_MULTI_PAGE_REG 0xF /* Registers equal on all pages */
-+
- /* M88E1000 Specific Registers */
- #define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
- #define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */
-@@ -1752,6 +2644,7 @@ struct e1000_hw {
- #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
- #define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */
- #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
-+#define IGP02E1000_PHY_POWER_MGMT 0x19
- #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */
-
- /* IGP01E1000 AGC Registers - stores the cable length values*/
-@@ -1760,12 +2653,20 @@ struct e1000_hw {
- #define IGP01E1000_PHY_AGC_C 0x1472
- #define IGP01E1000_PHY_AGC_D 0x1872
-
-+/* IGP02E1000 AGC Registers for cable length values */
-+#define IGP02E1000_PHY_AGC_A 0x11B1
-+#define IGP02E1000_PHY_AGC_B 0x12B1
-+#define IGP02E1000_PHY_AGC_C 0x14B1
-+#define IGP02E1000_PHY_AGC_D 0x18B1
-+
- /* IGP01E1000 DSP Reset Register */
- #define IGP01E1000_PHY_DSP_RESET 0x1F33
- #define IGP01E1000_PHY_DSP_SET 0x1F71
- #define IGP01E1000_PHY_DSP_FFE 0x1F35
-
- #define IGP01E1000_PHY_CHANNEL_NUM 4
-+#define IGP02E1000_PHY_CHANNEL_NUM 4
-+
- #define IGP01E1000_PHY_AGC_PARAM_A 0x1171
- #define IGP01E1000_PHY_AGC_PARAM_B 0x1271
- #define IGP01E1000_PHY_AGC_PARAM_C 0x1471
-@@ -1787,8 +2688,79 @@ struct e1000_hw {
-
- #define IGP01E1000_ANALOG_REGS_PAGE 0x20C0
-
--#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */
--#define MAX_PHY_MULTI_PAGE_REG 0xF /*Registers that are equal on all pages*/
-+/* Bits...
-+ * 15-5: page
-+ * 4-0: register offset
-+ */
-+#define GG82563_PAGE_SHIFT 5
-+#define GG82563_REG(page, reg) \
-+ (((page) << GG82563_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
-+#define GG82563_MIN_ALT_REG 30
-+
-+/* GG82563 Specific Registers */
-+#define GG82563_PHY_SPEC_CTRL \
-+ GG82563_REG(0, 16) /* PHY Specific Control */
-+#define GG82563_PHY_SPEC_STATUS \
-+ GG82563_REG(0, 17) /* PHY Specific Status */
-+#define GG82563_PHY_INT_ENABLE \
-+ GG82563_REG(0, 18) /* Interrupt Enable */
-+#define GG82563_PHY_SPEC_STATUS_2 \
-+ GG82563_REG(0, 19) /* PHY Specific Status 2 */
-+#define GG82563_PHY_RX_ERR_CNTR \
-+ GG82563_REG(0, 21) /* Receive Error Counter */
-+#define GG82563_PHY_PAGE_SELECT \
-+ GG82563_REG(0, 22) /* Page Select */
-+#define GG82563_PHY_SPEC_CTRL_2 \
-+ GG82563_REG(0, 26) /* PHY Specific Control 2 */
-+#define GG82563_PHY_PAGE_SELECT_ALT \
-+ GG82563_REG(0, 29) /* Alternate Page Select */
-+#define GG82563_PHY_TEST_CLK_CTRL \
-+ GG82563_REG(0, 30) /* Test Clock Control (use reg. 29 to select) */
-+
-+#define GG82563_PHY_MAC_SPEC_CTRL \
-+ GG82563_REG(2, 21) /* MAC Specific Control Register */
-+#define GG82563_PHY_MAC_SPEC_CTRL_2 \
-+ GG82563_REG(2, 26) /* MAC Specific Control 2 */
-+
-+#define GG82563_PHY_DSP_DISTANCE \
-+ GG82563_REG(5, 26) /* DSP Distance */
-+
-+/* Page 193 - Port Control Registers */
-+#define GG82563_PHY_KMRN_MODE_CTRL \
-+ GG82563_REG(193, 16) /* Kumeran Mode Control */
-+#define GG82563_PHY_PORT_RESET \
-+ GG82563_REG(193, 17) /* Port Reset */
-+#define GG82563_PHY_REVISION_ID \
-+ GG82563_REG(193, 18) /* Revision ID */
-+#define GG82563_PHY_DEVICE_ID \
-+ GG82563_REG(193, 19) /* Device ID */
-+#define GG82563_PHY_PWR_MGMT_CTRL \
-+ GG82563_REG(193, 20) /* Power Management Control */
-+#define GG82563_PHY_RATE_ADAPT_CTRL \
-+ GG82563_REG(193, 25) /* Rate Adaptation Control */
-+
-+/* Page 194 - KMRN Registers */
-+#define GG82563_PHY_KMRN_FIFO_CTRL_STAT \
-+ GG82563_REG(194, 16) /* FIFO's Control/Status */
-+#define GG82563_PHY_KMRN_CTRL \
-+ GG82563_REG(194, 17) /* Control */
-+#define GG82563_PHY_INBAND_CTRL \
-+ GG82563_REG(194, 18) /* Inband Control */
-+#define GG82563_PHY_KMRN_DIAGNOSTIC \
-+ GG82563_REG(194, 19) /* Diagnostic */
-+#define GG82563_PHY_ACK_TIMEOUTS \
-+ GG82563_REG(194, 20) /* Acknowledge Timeouts */
-+#define GG82563_PHY_ADV_ABILITY \
-+ GG82563_REG(194, 21) /* Advertised Ability */
-+#define GG82563_PHY_LINK_PARTNER_ADV_ABILITY \
-+ GG82563_REG(194, 23) /* Link Partner Advertised Ability */
-+#define GG82563_PHY_ADV_NEXT_PAGE \
-+ GG82563_REG(194, 24) /* Advertised Next Page */
-+#define GG82563_PHY_LINK_PARTNER_ADV_NEXT_PAGE \
-+ GG82563_REG(194, 25) /* Link Partner Advertised Next page */
-+#define GG82563_PHY_KMRN_MISC \
-+ GG82563_REG(194, 26) /* Misc. */
-+
- /* PHY Control Register */
- #define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */
- #define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */
-@@ -1998,6 +2970,17 @@ struct e1000_hw {
- #define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */
- #define M88E1000_EPSCR_TX_CLK_0 0x0000 /* NO TX_CLK */
-
-+/* M88EC018 Rev 2 specific DownShift settings */
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_1X 0x0000
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_2X 0x0200
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_3X 0x0400
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_4X 0x0600
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_6X 0x0A00
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_7X 0x0C00
-+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_8X 0x0E00
-+
- /* IGP01E1000 Specific Port Config Register - R/W */
- #define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT 0x0010
- #define IGP01E1000_PSCFR_PRE_EN 0x0020
-@@ -2050,20 +3033,30 @@ struct e1000_hw {
- #define IGP01E1000_MSE_CHANNEL_B 0x0F00
- #define IGP01E1000_MSE_CHANNEL_A 0xF000
-
-+#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */
-+#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */
-+#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */
-+
- /* IGP01E1000 DSP reset macros */
- #define DSP_RESET_ENABLE 0x0
- #define DSP_RESET_DISABLE 0x2
- #define E1000_MAX_DSP_RESETS 10
-
--/* IGP01E1000 AGC Registers */
-+/* IGP01E1000 & IGP02E1000 AGC Registers */
-
- #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */
-+#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */
-+
-+/* IGP02E1000 AGC Register Length 9-bit mask */
-+#define IGP02E1000_AGC_LENGTH_MASK 0x7F
-
- /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
- #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-+#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
-
--/* The precision of the length is +/- 10 meters */
-+/* The precision error of the cable length is +/- 10 meters */
- #define IGP01E1000_AGC_RANGE 10
-+#define IGP02E1000_AGC_RANGE 15
-
- /* IGP01E1000 PCS Initialization register */
- /* bits 3:6 in the PCS registers stores the channels polarity */
-@@ -2091,7 +3084,118 @@ struct e1000_hw {
- #define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080
- #define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500
-
-+/* GG82563 PHY Specific Status Register (Page 0, Register 16 */
-+#define GG82563_PSCR_DISABLE_JABBER 0x0001 /* 1=Disable Jabber */
-+#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Polarity Reversal Disabled */
-+#define GG82563_PSCR_POWER_DOWN 0x0004 /* 1=Power Down */
-+#define GG82563_PSCR_COPPER_TRANSMITER_DISABLE 0x0008 /* 1=Transmitter Disabled */
-+#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060
-+#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI configuration */
-+#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX configuration */
-+#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Automatic crossover */
-+#define GG82563_PSCR_ENALBE_EXTENDED_DISTANCE 0x0080 /* 1=Enable Extended Distance */
-+#define GG82563_PSCR_ENERGY_DETECT_MASK 0x0300
-+#define GG82563_PSCR_ENERGY_DETECT_OFF 0x0000 /* 00,01=Off */
-+#define GG82563_PSCR_ENERGY_DETECT_RX 0x0200 /* 10=Sense on Rx only (Energy Detect) */
-+#define GG82563_PSCR_ENERGY_DETECT_RX_TM 0x0300 /* 11=Sense and Tx NLP */
-+#define GG82563_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force Link Good */
-+#define GG82563_PSCR_DOWNSHIFT_ENABLE 0x0800 /* 1=Enable Downshift */
-+#define GG82563_PSCR_DOWNSHIFT_COUNTER_MASK 0x7000
-+#define GG82563_PSCR_DOWNSHIFT_COUNTER_SHIFT 12
-+
-+/* PHY Specific Status Register (Page 0, Register 17) */
-+#define GG82563_PSSR_JABBER 0x0001 /* 1=Jabber */
-+#define GG82563_PSSR_POLARITY 0x0002 /* 1=Polarity Reversed */
-+#define GG82563_PSSR_LINK 0x0008 /* 1=Link is Up */
-+#define GG82563_PSSR_ENERGY_DETECT 0x0010 /* 1=Sleep, 0=Active */
-+#define GG82563_PSSR_DOWNSHIFT 0x0020 /* 1=Downshift */
-+#define GG82563_PSSR_CROSSOVER_STATUS 0x0040 /* 1=MDIX, 0=MDI */
-+#define GG82563_PSSR_RX_PAUSE_ENABLED 0x0100 /* 1=Receive Pause Enabled */
-+#define GG82563_PSSR_TX_PAUSE_ENABLED 0x0200 /* 1=Transmit Pause Enabled */
-+#define GG82563_PSSR_LINK_UP 0x0400 /* 1=Link Up */
-+#define GG82563_PSSR_SPEED_DUPLEX_RESOLVED 0x0800 /* 1=Resolved */
-+#define GG82563_PSSR_PAGE_RECEIVED 0x1000 /* 1=Page Received */
-+#define GG82563_PSSR_DUPLEX 0x2000 /* 1-Full-Duplex */
-+#define GG82563_PSSR_SPEED_MASK 0xC000
-+#define GG82563_PSSR_SPEED_10MBPS 0x0000 /* 00=10Mbps */
-+#define GG82563_PSSR_SPEED_100MBPS 0x4000 /* 01=100Mbps */
-+#define GG82563_PSSR_SPEED_1000MBPS 0x8000 /* 10=1000Mbps */
-+
-+/* PHY Specific Status Register 2 (Page 0, Register 19) */
-+#define GG82563_PSSR2_JABBER 0x0001 /* 1=Jabber */
-+#define GG82563_PSSR2_POLARITY_CHANGED 0x0002 /* 1=Polarity Changed */
-+#define GG82563_PSSR2_ENERGY_DETECT_CHANGED 0x0010 /* 1=Energy Detect Changed */
-+#define GG82563_PSSR2_DOWNSHIFT_INTERRUPT 0x0020 /* 1=Downshift Detected */
-+#define GG82563_PSSR2_MDI_CROSSOVER_CHANGE 0x0040 /* 1=Crossover Changed */
-+#define GG82563_PSSR2_FALSE_CARRIER 0x0100 /* 1=False Carrier */
-+#define GG82563_PSSR2_SYMBOL_ERROR 0x0200 /* 1=Symbol Error */
-+#define GG82563_PSSR2_LINK_STATUS_CHANGED 0x0400 /* 1=Link Status Changed */
-+#define GG82563_PSSR2_AUTO_NEG_COMPLETED 0x0800 /* 1=Auto-Neg Completed */
-+#define GG82563_PSSR2_PAGE_RECEIVED 0x1000 /* 1=Page Received */
-+#define GG82563_PSSR2_DUPLEX_CHANGED 0x2000 /* 1=Duplex Changed */
-+#define GG82563_PSSR2_SPEED_CHANGED 0x4000 /* 1=Speed Changed */
-+#define GG82563_PSSR2_AUTO_NEG_ERROR 0x8000 /* 1=Auto-Neg Error */
-+
-+/* PHY Specific Control Register 2 (Page 0, Register 26) */
-+#define GG82563_PSCR2_10BT_POLARITY_FORCE 0x0002 /* 1=Force Negative Polarity */
-+#define GG82563_PSCR2_1000MB_TEST_SELECT_MASK 0x000C
-+#define GG82563_PSCR2_1000MB_TEST_SELECT_NORMAL 0x0000 /* 00,01=Normal Operation */
-+#define GG82563_PSCR2_1000MB_TEST_SELECT_112NS 0x0008 /* 10=Select 112ns Sequence */
-+#define GG82563_PSCR2_1000MB_TEST_SELECT_16NS 0x000C /* 11=Select 16ns Sequence */
-+#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 /* 1=Reverse Auto-Negotiation */
-+#define GG82563_PSCR2_1000BT_DISABLE 0x4000 /* 1=Disable 1000BASE-T */
-+#define GG82563_PSCR2_TRANSMITER_TYPE_MASK 0x8000
-+#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_B 0x0000 /* 0=Class B */
-+#define GG82563_PSCR2_TRANSMITTER_TYPE_CLASS_A 0x8000 /* 1=Class A */
-+
-+/* MAC Specific Control Register (Page 2, Register 21) */
-+/* Tx clock speed for Link Down and 1000BASE-T for the following speeds */
-+#define GG82563_MSCR_TX_CLK_MASK 0x0007
-+#define GG82563_MSCR_TX_CLK_10MBPS_2_5MHZ 0x0004
-+#define GG82563_MSCR_TX_CLK_100MBPS_25MHZ 0x0005
-+#define GG82563_MSCR_TX_CLK_1000MBPS_2_5MHZ 0x0006
-+#define GG82563_MSCR_TX_CLK_1000MBPS_25MHZ 0x0007
-+
-+#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */
-+
-+/* DSP Distance Register (Page 5, Register 26) */
-+#define GG82563_DSPD_CABLE_LENGTH 0x0007 /* 0 = <50M;
-+ 1 = 50-80M;
-+ 2 = 80-110M;
-+ 3 = 110-140M;
-+ 4 = >140M */
-+
-+/* Kumeran Mode Control Register (Page 193, Register 16) */
-+#define GG82563_KMCR_PHY_LEDS_EN 0x0020 /* 1=PHY LEDs, 0=Kumeran Inband LEDs */
-+#define GG82563_KMCR_FORCE_LINK_UP 0x0040 /* 1=Force Link Up */
-+#define GG82563_KMCR_SUPPRESS_SGMII_EPD_EXT 0x0080
-+#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT_MASK 0x0400
-+#define GG82563_KMCR_MDIO_BUS_SPEED_SELECT 0x0400 /* 1=6.25MHz, 0=0.8MHz */
-+#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800
-+
-+/* Power Management Control Register (Page 193, Register 20) */
-+#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 /* 1=Enalbe SERDES Electrical Idle */
-+#define GG82563_PMCR_DISABLE_PORT 0x0002 /* 1=Disable Port */
-+#define GG82563_PMCR_DISABLE_SERDES 0x0004 /* 1=Disable SERDES */
-+#define GG82563_PMCR_REVERSE_AUTO_NEG 0x0008 /* 1=Enable Reverse Auto-Negotiation */
-+#define GG82563_PMCR_DISABLE_1000_NON_D0 0x0010 /* 1=Disable 1000Mbps Auto-Neg in non D0 */
-+#define GG82563_PMCR_DISABLE_1000 0x0020 /* 1=Disable 1000Mbps Auto-Neg Always */
-+#define GG82563_PMCR_REVERSE_AUTO_NEG_D0A 0x0040 /* 1=Enable D0a Reverse Auto-Negotiation */
-+#define GG82563_PMCR_FORCE_POWER_STATE 0x0080 /* 1=Force Power State */
-+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_MASK 0x0300
-+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_DR 0x0000 /* 00=Dr */
-+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0U 0x0100 /* 01=D0u */
-+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D0A 0x0200 /* 10=D0a */
-+#define GG82563_PMCR_PROGRAMMED_POWER_STATE_D3 0x0300 /* 11=D3 */
-+
-+/* In-Band Control Register (Page 194, Register 18) */
-+#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding Use */
-+
-+
- /* Bit definitions for valid PHY IDs. */
-+/* I = Integrated
-+ * E = External
-+ */
- #define M88E1000_E_PHY_ID 0x01410C50
- #define M88E1000_I_PHY_ID 0x01410C30
- #define M88E1011_I_PHY_ID 0x01410C20
-@@ -2099,6 +3203,224 @@ struct e1000_hw {
- #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
- #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
- #define M88E1011_I_REV_4 0x04
-+#define M88E1111_I_PHY_ID 0x01410CC0
-+#define L1LXT971A_PHY_ID 0x001378E0
-+#define GG82563_E_PHY_ID 0x01410CA0
-+
-+
-+/* Bits...
-+ * 15-5: page
-+ * 4-0: register offset
-+ */
-+#define PHY_PAGE_SHIFT 5
-+#define PHY_REG(page, reg) \
-+ (((page) << PHY_PAGE_SHIFT) | ((reg) & MAX_PHY_REG_ADDRESS))
-+
-+#define IGP3_PHY_PORT_CTRL \
-+ PHY_REG(769, 17) /* Port General Configuration */
-+#define IGP3_PHY_RATE_ADAPT_CTRL \
-+ PHY_REG(769, 25) /* Rate Adapter Control Register */
-+
-+#define IGP3_KMRN_FIFO_CTRL_STATS \
-+ PHY_REG(770, 16) /* KMRN FIFO's control/status register */
-+#define IGP3_KMRN_POWER_MNG_CTRL \
-+ PHY_REG(770, 17) /* KMRN Power Management Control Register */
-+#define IGP3_KMRN_INBAND_CTRL \
-+ PHY_REG(770, 18) /* KMRN Inband Control Register */
-+#define IGP3_KMRN_DIAG \
-+ PHY_REG(770, 19) /* KMRN Diagnostic register */
-+#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 /* RX PCS is not synced */
-+#define IGP3_KMRN_ACK_TIMEOUT \
-+ PHY_REG(770, 20) /* KMRN Acknowledge Timeouts register */
-+
-+#define IGP3_VR_CTRL \
-+ PHY_REG(776, 18) /* Voltage regulator control register */
-+#define IGP3_VR_CTRL_MODE_SHUT 0x0200 /* Enter powerdown, shutdown VRs */
-+
-+#define IGP3_CAPABILITY \
-+ PHY_REG(776, 19) /* IGP3 Capability Register */
-+
-+/* Capabilities for SKU Control */
-+#define IGP3_CAP_INITIATE_TEAM 0x0001 /* Able to initiate a team */
-+#define IGP3_CAP_WFM 0x0002 /* Support WoL and PXE */
-+#define IGP3_CAP_ASF 0x0004 /* Support ASF */
-+#define IGP3_CAP_LPLU 0x0008 /* Support Low Power Link Up */
-+#define IGP3_CAP_DC_AUTO_SPEED 0x0010 /* Support AC/DC Auto Link Speed */
-+#define IGP3_CAP_SPD 0x0020 /* Support Smart Power Down */
-+#define IGP3_CAP_MULT_QUEUE 0x0040 /* Support 2 tx & 2 rx queues */
-+#define IGP3_CAP_RSS 0x0080 /* Support RSS */
-+#define IGP3_CAP_8021PQ 0x0100 /* Support 802.1Q & 802.1p */
-+#define IGP3_CAP_AMT_CB 0x0200 /* Support active manageability and circuit breaker */
-+
-+#define IGP3_PPC_JORDAN_EN 0x0001
-+#define IGP3_PPC_JORDAN_GIGA_SPEED 0x0002
-+
-+#define IGP3_KMRN_PMC_EE_IDLE_LINK_DIS 0x0001
-+#define IGP3_KMRN_PMC_K0S_ENTRY_LATENCY_MASK 0x001E
-+#define IGP3_KMRN_PMC_K0S_MODE1_EN_GIGA 0x0020
-+#define IGP3_KMRN_PMC_K0S_MODE1_EN_100 0x0040
-+
-+#define IGP3E1000_PHY_MISC_CTRL 0x1B /* Misc. Ctrl register */
-+#define IGP3_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Duplex Manual Set */
-+
-+#define IGP3_KMRN_EXT_CTRL PHY_REG(770, 18)
-+#define IGP3_KMRN_EC_DIS_INBAND 0x0080
-+
-+#define IGP03E1000_E_PHY_ID 0x02A80390
-+#define IFE_E_PHY_ID 0x02A80330 /* 10/100 PHY */
-+#define IFE_PLUS_E_PHY_ID 0x02A80320
-+#define IFE_C_E_PHY_ID 0x02A80310
-+
-+#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 /* 100BaseTx Extended Status, Control and Address */
-+#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY special control register */
-+#define IFE_PHY_RCV_FALSE_CARRIER 0x13 /* 100BaseTx Receive False Carrier Counter */
-+#define IFE_PHY_RCV_DISCONNECT 0x14 /* 100BaseTx Receive Disconnet Counter */
-+#define IFE_PHY_RCV_ERROT_FRAME 0x15 /* 100BaseTx Receive Error Frame Counter */
-+#define IFE_PHY_RCV_SYMBOL_ERR 0x16 /* Receive Symbol Error Counter */
-+#define IFE_PHY_PREM_EOF_ERR 0x17 /* 100BaseTx Receive Premature End Of Frame Error Counter */
-+#define IFE_PHY_RCV_EOF_ERR 0x18 /* 10BaseT Receive End Of Frame Error Counter */
-+#define IFE_PHY_TX_JABBER_DETECT 0x19 /* 10BaseT Transmit Jabber Detect Counter */
-+#define IFE_PHY_EQUALIZER 0x1A /* PHY Equalizer Control and Status */
-+#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY special control and LED configuration */
-+#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control register */
-+#define IFE_PHY_HWI_CONTROL 0x1D /* Hardware Integrity Control (HWI) */
-+
-+#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE 0x2000 /* Defaut 1 = Disable auto reduced power down */
-+#define IFE_PESC_100BTX_POWER_DOWN 0x0400 /* Indicates the power state of 100BASE-TX */
-+#define IFE_PESC_10BTX_POWER_DOWN 0x0200 /* Indicates the power state of 10BASE-T */
-+#define IFE_PESC_POLARITY_REVERSED 0x0100 /* Indicates 10BASE-T polarity */
-+#define IFE_PESC_PHY_ADDR_MASK 0x007C /* Bit 6:2 for sampled PHY address */
-+#define IFE_PESC_SPEED 0x0002 /* Auto-negotiation speed result 1=100Mbs, 0=10Mbs */
-+#define IFE_PESC_DUPLEX 0x0001 /* Auto-negotiation duplex result 1=Full, 0=Half */
-+#define IFE_PESC_POLARITY_REVERSED_SHIFT 8
-+
-+#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 /* 1 = Dyanmic Power Down disabled */
-+#define IFE_PSC_FORCE_POLARITY 0x0020 /* 1=Reversed Polarity, 0=Normal */
-+#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 /* 1=Auto Polarity Disabled, 0=Enabled */
-+#define IFE_PSC_JABBER_FUNC_DISABLE 0x0001 /* 1=Jabber Disabled, 0=Normal Jabber Operation */
-+#define IFE_PSC_FORCE_POLARITY_SHIFT 5
-+#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT 4
-+
-+#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable MDI/MDI-X feature, default 0=disabled */
-+#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDIX-X, 0=force MDI */
-+#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */
-+#define IFE_PMC_AUTO_MDIX_COMPLETE 0x0010 /* Resolution algorthm is completed */
-+#define IFE_PMC_MDIX_MODE_SHIFT 6
-+#define IFE_PHC_MDIX_RESET_ALL_MASK 0x0000 /* Disable auto MDI-X */
-+
-+#define IFE_PHC_HWI_ENABLE 0x8000 /* Enable the HWI feature */
-+#define IFE_PHC_ABILITY_CHECK 0x4000 /* 1= Test Passed, 0=failed */
-+#define IFE_PHC_TEST_EXEC 0x2000 /* PHY launch test pulses on the wire */
-+#define IFE_PHC_HIGHZ 0x0200 /* 1 = Open Circuit */
-+#define IFE_PHC_LOWZ 0x0400 /* 1 = Short Circuit */
-+#define IFE_PHC_LOW_HIGH_Z_MASK 0x0600 /* Mask for indication type of problem on the line */
-+#define IFE_PHC_DISTANCE_MASK 0x01FF /* Mask for distance to the cable problem, in 80cm granularity */
-+#define IFE_PHC_RESET_ALL_MASK 0x0000 /* Disable HWI */
-+#define IFE_PSCL_PROBE_MODE 0x0020 /* LED Probe mode */
-+#define IFE_PSCL_PROBE_LEDS_OFF 0x0006 /* Force LEDs 0 and 2 off */
-+#define IFE_PSCL_PROBE_LEDS_ON 0x0007 /* Force LEDs 0 and 2 on */
-+
-+#define ICH8_FLASH_COMMAND_TIMEOUT 500 /* 500 ms , should be adjusted */
-+#define ICH8_FLASH_CYCLE_REPEAT_COUNT 10 /* 10 cycles , should be adjusted */
-+#define ICH8_FLASH_SEG_SIZE_256 256
-+#define ICH8_FLASH_SEG_SIZE_4K 4096
-+#define ICH8_FLASH_SEG_SIZE_64K 65536
-+
-+#define ICH8_CYCLE_READ 0x0
-+#define ICH8_CYCLE_RESERVED 0x1
-+#define ICH8_CYCLE_WRITE 0x2
-+#define ICH8_CYCLE_ERASE 0x3
-+
-+#define ICH8_FLASH_GFPREG 0x0000
-+#define ICH8_FLASH_HSFSTS 0x0004
-+#define ICH8_FLASH_HSFCTL 0x0006
-+#define ICH8_FLASH_FADDR 0x0008
-+#define ICH8_FLASH_FDATA0 0x0010
-+#define ICH8_FLASH_FRACC 0x0050
-+#define ICH8_FLASH_FREG0 0x0054
-+#define ICH8_FLASH_FREG1 0x0058
-+#define ICH8_FLASH_FREG2 0x005C
-+#define ICH8_FLASH_FREG3 0x0060
-+#define ICH8_FLASH_FPR0 0x0074
-+#define ICH8_FLASH_FPR1 0x0078
-+#define ICH8_FLASH_SSFSTS 0x0090
-+#define ICH8_FLASH_SSFCTL 0x0092
-+#define ICH8_FLASH_PREOP 0x0094
-+#define ICH8_FLASH_OPTYPE 0x0096
-+#define ICH8_FLASH_OPMENU 0x0098
-+
-+#define ICH8_FLASH_REG_MAPSIZE 0x00A0
-+#define ICH8_FLASH_SECTOR_SIZE 4096
-+#define ICH8_GFPREG_BASE_MASK 0x1FFF
-+#define ICH8_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF
-+
-+/* ICH8 GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
-+/* Offset 04h HSFSTS */
-+union ich8_hws_flash_status {
-+ struct ich8_hsfsts {
-+#ifdef E1000_BIG_ENDIAN
-+ uint16_t reserved2 :6;
-+ uint16_t fldesvalid :1;
-+ uint16_t flockdn :1;
-+ uint16_t flcdone :1;
-+ uint16_t flcerr :1;
-+ uint16_t dael :1;
-+ uint16_t berasesz :2;
-+ uint16_t flcinprog :1;
-+ uint16_t reserved1 :2;
-+#else
-+ uint16_t flcdone :1; /* bit 0 Flash Cycle Done */
-+ uint16_t flcerr :1; /* bit 1 Flash Cycle Error */
-+ uint16_t dael :1; /* bit 2 Direct Access error Log */
-+ uint16_t berasesz :2; /* bit 4:3 Block/Sector Erase Size */
-+ uint16_t flcinprog :1; /* bit 5 flash SPI cycle in Progress */
-+ uint16_t reserved1 :2; /* bit 13:6 Reserved */
-+ uint16_t reserved2 :6; /* bit 13:6 Reserved */
-+ uint16_t fldesvalid :1; /* bit 14 Flash Descriptor Valid */
-+ uint16_t flockdn :1; /* bit 15 Flash Configuration Lock-Down */
-+#endif
-+ } hsf_status;
-+ uint16_t regval;
-+};
-+
-+/* ICH8 GbE Flash Hardware Sequencing Flash control Register bit breakdown */
-+/* Offset 06h FLCTL */
-+union ich8_hws_flash_ctrl {
-+ struct ich8_hsflctl {
-+#ifdef E1000_BIG_ENDIAN
-+ uint16_t fldbcount :2;
-+ uint16_t flockdn :6;
-+ uint16_t flcgo :1;
-+ uint16_t flcycle :2;
-+ uint16_t reserved :5;
-+#else
-+ uint16_t flcgo :1; /* 0 Flash Cycle Go */
-+ uint16_t flcycle :2; /* 2:1 Flash Cycle */
-+ uint16_t reserved :5; /* 7:3 Reserved */
-+ uint16_t fldbcount :2; /* 9:8 Flash Data Byte Count */
-+ uint16_t flockdn :6; /* 15:10 Reserved */
-+#endif
-+ } hsf_ctrl;
-+ uint16_t regval;
-+};
-+
-+/* ICH8 Flash Region Access Permissions */
-+union ich8_hws_flash_regacc {
-+ struct ich8_flracc {
-+#ifdef E1000_BIG_ENDIAN
-+ uint32_t gmwag :8;
-+ uint32_t gmrag :8;
-+ uint32_t grwa :8;
-+ uint32_t grra :8;
-+#else
-+ uint32_t grra :8; /* 0:7 GbE region Read Access */
-+ uint32_t grwa :8; /* 8:15 GbE region Write Access */
-+ uint32_t gmrag :8; /* 23:16 GbE Master Read Access Grant */
-+ uint32_t gmwag :8; /* 31:24 GbE Master Write Access Grant */
-+#endif
-+ } hsf_flregacc;
-+ uint16_t regval;
-+};
-
- /* Miscellaneous PHY bit definitions. */
- #define PHY_PREAMBLE 0xFFFFFFFF
-diff -pruN ./drivers/net/e1000.orig/e1000_main.c ./drivers/net/e1000/e1000_main.c
---- ./drivers/net/e1000.orig/e1000_main.c 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_main.c 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,78 +22,132 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-
- #include "e1000.h"
--#include <linux/rtnetlink.h>
-
- /* Change Log
-- *
-- * 5.2.51 5/14/04
-- * o set default configuration to 'NAPI disabled'. NAPI enabled driver
-- * causes kernel panic when the interface is shutdown while data is being
-- * transferred.
-- * 5.2.47 5/04/04
-- * o fixed ethtool -t implementation
-- * 5.2.45 4/29/04
-- * o fixed ethtool -e implementation
-- * o Support for ethtool ops [Stephen Hemminger (shemminger@osdl.org)]
-- * 5.2.42 4/26/04
-- * o Added support for the DPRINTK macro for enhanced error logging. Some
-- * parts of the patch were supplied by Jon Mason.
-- * o Move the register_netdevice() donw in the probe routine due to a
-- * loading/unloading test issue.
-- * o Added a long RX byte count the the extra ethtool data members for BER
-- * testing purposes.
-- * 5.2.39 3/12/04
-+ * 7.0.36 10-Mar-2006
-+ * o fixups for compilation issues on older kernels
-+ * 7.0.35 3-Mar-2006
-+ * 7.0.34
-+ * o Major performance fixes by understanding relationship of rx_buffer_len
-+ * to window size growth. _ps and legacy receive paths changed
-+ * o merge with kernel changes
-+ * o legacy receive path went back to single descriptor model for jumbos
-+ * 7.0.33 3-Feb-2006
-+ * o Added another fix for the pass false carrier bit
-+ * 7.0.32 24-Jan-2006
-+ * o Need to rebuild with noew version number for the pass false carrier
-+ * fix in e1000_hw.c
-+ * 7.0.30 18-Jan-2006
-+ * o fixup for tso workaround to disable it for pci-x
-+ * o fix mem leak on 82542
-+ * o fixes for 10 Mb/s connections and incorrect stats
-+ * 7.0.28 01/06/2006
-+ * o hardware workaround to only set "speed mode" bit for 1G link.
-+ * 7.0.26 12/23/2005
-+ * o wake on lan support modified for device ID 10B5
-+ * o fix dhcp + vlan issue not making it to the iAMT firmware
-+ * 7.0.24 12/9/2005
-+ * o New hardware support for the Gigabit NIC embedded in the south bridge
-+ * o Fixes to the recycling logic (skb->tail) from IBM LTC
-+ * 6.3.7 11/18/2005
-+ * o Honor eeprom setting for enabling/disabling Wake On Lan
-+ * 6.3.5 11/17/2005
-+ * o Fix memory leak in rx ring handling for PCI Express adapters
-+ * 6.3.4 11/8/05
-+ * o Patch from Jesper Juhl to remove redundant NULL checks for kfree
-+ * 6.3.2 9/20/05
-+ * o Render logic that sets/resets DRV_LOAD as inline functions to
-+ * avoid code replication. If f/w is AMT then set DRV_LOAD only when
-+ * network interface is open.
-+ * o Handle DRV_LOAD set/reset in cases where AMT uses VLANs.
-+ * o Adjust PBA partioning for Jumbo frames using MTU size and not
-+ * rx_buffer_len
-+ * 6.3.1 9/19/05
-+ * o Use adapter->tx_timeout_factor in Tx Hung Detect logic
-+ * (e1000_clean_tx_irq)
-+ * o Support for 8086:10B5 device (Quad Port)
- */
-
- char e1000_driver_name[] = "e1000";
--char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
--char e1000_driver_version[] = "5.2.52-k4";
--char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation.";
-+static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
-+#ifndef CONFIG_E1000_NAPI
-+#define DRIVERNAPI
-+#else
-+#define DRIVERNAPI "-NAPI"
-+#endif
-+#define DRV_VERSION "7.2.7"DRIVERNAPI
-+char e1000_driver_version[] = DRV_VERSION;
-+static char e1000_copyright[] = "Copyright (c) 1999-2006 Intel Corporation.";
-
- /* e1000_pci_tbl - PCI Device ID Table
- *
-- * Wildcard entries (PCI_ANY_ID) should come last
- * Last entry must be all 0s
- *
-- * { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
-- * Class, Class Mask, private data (not used) }
-+ * Macro expands to...
-+ * {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
- */
- static struct pci_device_id e1000_pci_tbl[] = {
-- {0x8086, 0x1000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x100C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x100D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x100E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x100F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x101D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x101E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1075, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1076, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1077, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x1079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x107A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-- {0x8086, 0x107B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-+ INTEL_E1000_ETHERNET_DEVICE(0x1001),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1004),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1008),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1009),
-+ INTEL_E1000_ETHERNET_DEVICE(0x100C),
-+ INTEL_E1000_ETHERNET_DEVICE(0x100D),
-+ INTEL_E1000_ETHERNET_DEVICE(0x100E),
-+ INTEL_E1000_ETHERNET_DEVICE(0x100F),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1010),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1011),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1012),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1013),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1014),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1015),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1016),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1017),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1018),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1019),
-+ INTEL_E1000_ETHERNET_DEVICE(0x101A),
-+ INTEL_E1000_ETHERNET_DEVICE(0x101D),
-+ INTEL_E1000_ETHERNET_DEVICE(0x101E),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1026),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1027),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1028),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1049),
-+ INTEL_E1000_ETHERNET_DEVICE(0x104A),
-+ INTEL_E1000_ETHERNET_DEVICE(0x104B),
-+ INTEL_E1000_ETHERNET_DEVICE(0x104C),
-+ INTEL_E1000_ETHERNET_DEVICE(0x104D),
-+ INTEL_E1000_ETHERNET_DEVICE(0x105E),
-+ INTEL_E1000_ETHERNET_DEVICE(0x105F),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1060),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1075),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1076),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1077),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1078),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1079),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107A),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107B),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107C),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107D),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107E),
-+ INTEL_E1000_ETHERNET_DEVICE(0x107F),
-+ INTEL_E1000_ETHERNET_DEVICE(0x108A),
-+ INTEL_E1000_ETHERNET_DEVICE(0x108B),
-+ INTEL_E1000_ETHERNET_DEVICE(0x108C),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1096),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1098),
-+ INTEL_E1000_ETHERNET_DEVICE(0x1099),
-+ INTEL_E1000_ETHERNET_DEVICE(0x109A),
-+ INTEL_E1000_ETHERNET_DEVICE(0x10A4),
-+ INTEL_E1000_ETHERNET_DEVICE(0x10B5),
-+ INTEL_E1000_ETHERNET_DEVICE(0x10B9),
-+ INTEL_E1000_ETHERNET_DEVICE(0x10BA),
-+ INTEL_E1000_ETHERNET_DEVICE(0x10BB),
- /* required last entry */
- {0,}
- };
-@@ -102,28 +156,40 @@ MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
-
- int e1000_up(struct e1000_adapter *adapter);
- void e1000_down(struct e1000_adapter *adapter);
-+void e1000_reinit_locked(struct e1000_adapter *adapter);
- void e1000_reset(struct e1000_adapter *adapter);
- int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
--int e1000_setup_tx_resources(struct e1000_adapter *adapter);
--int e1000_setup_rx_resources(struct e1000_adapter *adapter);
--void e1000_free_tx_resources(struct e1000_adapter *adapter);
--void e1000_free_rx_resources(struct e1000_adapter *adapter);
-+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
-+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
-+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
-+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *txdr);
-+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rxdr);
-+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring);
-+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring);
- void e1000_update_stats(struct e1000_adapter *adapter);
-
--/* Local Function Prototypes */
--
- static int e1000_init_module(void);
- static void e1000_exit_module(void);
- static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
- static void __devexit e1000_remove(struct pci_dev *pdev);
-+static int e1000_alloc_queues(struct e1000_adapter *adapter);
- static int e1000_sw_init(struct e1000_adapter *adapter);
- static int e1000_open(struct net_device *netdev);
- static int e1000_close(struct net_device *netdev);
- static void e1000_configure_tx(struct e1000_adapter *adapter);
- static void e1000_configure_rx(struct e1000_adapter *adapter);
- static void e1000_setup_rctl(struct e1000_adapter *adapter);
--static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
--static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
-+static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
-+static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
-+static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring);
-+static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring);
- static void e1000_set_multi(struct net_device *netdev);
- static void e1000_update_phy_info(unsigned long data);
- static void e1000_watchdog(unsigned long data);
-@@ -132,60 +198,78 @@ static int e1000_xmit_frame(struct sk_bu
- static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
- static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
- static int e1000_set_mac(struct net_device *netdev, void *p);
--static inline void e1000_irq_disable(struct e1000_adapter *adapter);
--static inline void e1000_irq_enable(struct e1000_adapter *adapter);
- static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
--static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
-+static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring);
- #ifdef CONFIG_E1000_NAPI
--static int e1000_clean(struct net_device *netdev, int *budget);
-+static int e1000_clean(struct net_device *poll_dev, int *budget);
- static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
- int *work_done, int work_to_do);
-+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int *work_done, int work_to_do);
- #else
--static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
-+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring);
-+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring);
- #endif
--static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
-+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int cleaned_count);
-+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int cleaned_count);
- static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
-+#ifdef SIOCGMIIPHY
- static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
- int cmd);
--void set_ethtool_ops(struct net_device *netdev);
-+#endif
-+void e1000_set_ethtool_ops(struct net_device *netdev);
-+#ifdef ETHTOOL_OPS_COMPAT
-+extern int ethtool_ioctl(struct ifreq *ifr);
-+#endif
- static void e1000_enter_82542_rst(struct e1000_adapter *adapter);
- static void e1000_leave_82542_rst(struct e1000_adapter *adapter);
--static inline void e1000_rx_checksum(struct e1000_adapter *adapter,
-- struct e1000_rx_desc *rx_desc,
-- struct sk_buff *skb);
- static void e1000_tx_timeout(struct net_device *dev);
--static void e1000_tx_timeout_task(struct net_device *dev);
-+static void e1000_reset_task(struct net_device *dev);
- static void e1000_smartspeed(struct e1000_adapter *adapter);
--static inline int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
-- struct sk_buff *skb);
-+static int e1000_82547_fifo_workaround(struct e1000_adapter *adapter,
-+ struct sk_buff *skb);
-
-+#ifdef NETIF_F_HW_VLAN_TX
- static void e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp);
- static void e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid);
- static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
- static void e1000_restore_vlan(struct e1000_adapter *adapter);
-+#endif
-
--static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
--static int e1000_suspend(struct pci_dev *pdev, uint32_t state);
-+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
- #ifdef CONFIG_PM
- static int e1000_resume(struct pci_dev *pdev);
- #endif
-
- #ifdef CONFIG_NET_POLL_CONTROLLER
- /* for netdump / net console */
--static void e1000_netpoll (struct net_device *dev);
-+static void e1000_netpoll (struct net_device *netdev);
- #endif
-
--struct notifier_block e1000_notifier_reboot = {
-+#ifdef USE_DRIVER_SHUTDOWN_HANDLER
-+static void e1000_shutdown(struct pci_dev *pdev);
-+#else
-+static int e1000_notify_reboot(struct notifier_block *, unsigned long event, void *ptr);
-+static struct notifier_block e1000_notifier_reboot = {
- .notifier_call = e1000_notify_reboot,
- .next = NULL,
- .priority = 0
- };
-+#endif
-
- /* Exported from other modules */
-
- extern void e1000_check_options(struct e1000_adapter *adapter);
-
--
- static struct pci_driver e1000_driver = {
- .name = e1000_driver_name,
- .id_table = e1000_pci_tbl,
-@@ -194,15 +278,19 @@ static struct pci_driver e1000_driver =
- /* Power Managment Hooks */
- #ifdef CONFIG_PM
- .suspend = e1000_suspend,
-- .resume = e1000_resume
-+ .resume = e1000_resume,
-+#endif
-+#ifdef USE_DRIVER_SHUTDOWN_HANDLER
-+ .shutdown = e1000_shutdown
- #endif
- };
-
- MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
- MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver");
- MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
-
--static int debug = 3;
-+static int debug = NETIF_MSG_DRV | NETIF_MSG_PROBE;
- module_param(debug, int, 0);
- MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
-
-@@ -223,9 +311,11 @@ e1000_init_module(void)
- printk(KERN_INFO "%s\n", e1000_copyright);
-
- ret = pci_module_init(&e1000_driver);
-- if(ret >= 0) {
-+#ifndef USE_DRIVER_SHUTDOWN_HANDLER
-+ if (ret >= 0) {
- register_reboot_notifier(&e1000_notifier_reboot);
- }
-+#endif
- return ret;
- }
-
-@@ -241,108 +331,407 @@ module_init(e1000_init_module);
- static void __exit
- e1000_exit_module(void)
- {
-+#ifndef USE_DRIVER_SHUTDOWN_HANDLER
- unregister_reboot_notifier(&e1000_notifier_reboot);
-+#endif
- pci_unregister_driver(&e1000_driver);
- }
-
- module_exit(e1000_exit_module);
-
-+static int e1000_request_irq(struct e1000_adapter *adapter)
-+{
-+ struct net_device *netdev = adapter->netdev;
-+ int flags, err = 0;
-+
-+ flags = SA_SHIRQ | SA_SAMPLE_RANDOM;
-+#ifdef CONFIG_PCI_MSI
-+ if (adapter->hw.mac_type > e1000_82547_rev_2) {
-+ adapter->have_msi = TRUE;
-+ if ((err = pci_enable_msi(adapter->pdev))) {
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate MSI interrupt Error: %d\n", err);
-+ adapter->have_msi = FALSE;
-+ }
-+ }
-+ if (adapter->have_msi)
-+ flags &= ~SA_SHIRQ;
-+#endif
-+ if ((err = request_irq(adapter->pdev->irq, &e1000_intr, flags,
-+ netdev->name, netdev)))
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate interrupt Error: %d\n", err);
-+
-+ return err;
-+}
-+
-+static void e1000_free_irq(struct e1000_adapter *adapter)
-+{
-+ struct net_device *netdev = adapter->netdev;
-+
-+ free_irq(adapter->pdev->irq, netdev);
-+
-+#ifdef CONFIG_PCI_MSI
-+ if (adapter->have_msi)
-+ pci_disable_msi(adapter->pdev);
-+#endif
-+}
-+
-+/**
-+ * e1000_irq_disable - Mask off interrupt generation on the NIC
-+ * @adapter: board private structure
-+ **/
-+
-+static void
-+e1000_irq_disable(struct e1000_adapter *adapter)
-+{
-+ atomic_inc(&adapter->irq_sem);
-+ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
-+ E1000_WRITE_FLUSH(&adapter->hw);
-+ synchronize_irq(adapter->pdev->irq);
-+}
-+
-+/**
-+ * e1000_irq_enable - Enable default interrupt generation settings
-+ * @adapter: board private structure
-+ **/
-+
-+static void
-+e1000_irq_enable(struct e1000_adapter *adapter)
-+{
-+ if (likely(atomic_dec_and_test(&adapter->irq_sem))) {
-+ E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
-+ E1000_WRITE_FLUSH(&adapter->hw);
-+ }
-+}
-+#ifdef NETIF_F_HW_VLAN_TX
-+
-+static void
-+e1000_update_mng_vlan(struct e1000_adapter *adapter)
-+{
-+ struct net_device *netdev = adapter->netdev;
-+ uint16_t vid = adapter->hw.mng_cookie.vlan_id;
-+ uint16_t old_vid = adapter->mng_vlan_id;
-+ if (adapter->vlgrp) {
-+ if (!adapter->vlgrp->vlan_devices[vid]) {
-+ if (adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) {
-+ e1000_vlan_rx_add_vid(netdev, vid);
-+ adapter->mng_vlan_id = vid;
-+ } else
-+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-+
-+ if ((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) &&
-+ (vid != old_vid) &&
-+ !adapter->vlgrp->vlan_devices[old_vid])
-+ e1000_vlan_rx_kill_vid(netdev, old_vid);
-+ } else
-+ adapter->mng_vlan_id = vid;
-+ }
-+}
-+#endif
-+
-+/**
-+ * e1000_release_hw_control - release control of the h/w to f/w
-+ * @adapter: address of board private structure
-+ *
-+ * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit.
-+ * For ASF and Pass Through versions of f/w this means that the
-+ * driver is no longer loaded. For AMT version (only with 82573) i
-+ * of the f/w this means that the netowrk i/f is closed.
-+ *
-+ **/
-+
-+static void
-+e1000_release_hw_control(struct e1000_adapter *adapter)
-+{
-+ uint32_t ctrl_ext;
-+ uint32_t swsm;
-+ uint32_t extcnf;
-+
-+ /* Let firmware taken over control of h/w */
-+ switch (adapter->hw.mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
-+ break;
-+ case e1000_82573:
-+ swsm = E1000_READ_REG(&adapter->hw, SWSM);
-+ E1000_WRITE_REG(&adapter->hw, SWSM,
-+ swsm & ~E1000_SWSM_DRV_LOAD);
-+ case e1000_ich8lan:
-+ extcnf = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-+ extcnf & ~E1000_CTRL_EXT_DRV_LOAD);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-+
-+/**
-+ * e1000_get_hw_control - get control of the h/w from f/w
-+ * @adapter: address of board private structure
-+ *
-+ * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit.
-+ * For ASF and Pass Through versions of f/w this means that
-+ * the driver is loaded. For AMT version (only with 82573)
-+ * of the f/w this means that the netowrk i/f is open.
-+ *
-+ **/
-+
-+static void
-+e1000_get_hw_control(struct e1000_adapter *adapter)
-+{
-+ uint32_t ctrl_ext;
-+ uint32_t swsm;
-+ uint32_t extcnf;
-+ /* Let firmware know the driver has taken over */
-+ switch (adapter->hw.mac_type) {
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+ ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-+ E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
-+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
-+ break;
-+ case e1000_82573:
-+ swsm = E1000_READ_REG(&adapter->hw, SWSM);
-+ E1000_WRITE_REG(&adapter->hw, SWSM,
-+ swsm | E1000_SWSM_DRV_LOAD);
-+ break;
-+ case e1000_ich8lan:
-+ extcnf = E1000_READ_REG(&adapter->hw, EXTCNF_CTRL);
-+ E1000_WRITE_REG(&adapter->hw, EXTCNF_CTRL,
-+ extcnf | E1000_EXTCNF_CTRL_SWFLAG);
-+ break;
-+ default:
-+ break;
-+ }
-+}
-
- int
- e1000_up(struct e1000_adapter *adapter)
- {
- struct net_device *netdev = adapter->netdev;
-- int err;
-+ int i;
-
- /* hardware has been reset, we need to reload some things */
-
- e1000_set_multi(netdev);
-
-+#ifdef NETIF_F_HW_VLAN_TX
- e1000_restore_vlan(adapter);
-+#endif
-
- e1000_configure_tx(adapter);
- e1000_setup_rctl(adapter);
- e1000_configure_rx(adapter);
-- e1000_alloc_rx_buffers(adapter);
-+ /* call E1000_DESC_UNUSED which always leaves
-+ * at least 1 descriptor unused to make sure
-+ * next_to_use != next_to_clean */
-+ for (i = 0; i < adapter->num_rx_queues; i++) {
-+ struct e1000_rx_ring *ring = &adapter->rx_ring[i];
-+ adapter->alloc_rx_buf(adapter, ring,
-+ E1000_DESC_UNUSED(ring));
-+ }
-
-- if((err = request_irq(adapter->pdev->irq, &e1000_intr,
-- SA_SHIRQ | SA_SAMPLE_RANDOM,
-- netdev->name, netdev)))
-- return err;
-+ adapter->tx_queue_len = netdev->tx_queue_len;
-
- mod_timer(&adapter->watchdog_timer, jiffies);
-+
-+#ifdef CONFIG_E1000_NAPI
-+ netif_poll_enable(netdev);
-+#endif
- e1000_irq_enable(adapter);
-
- return 0;
- }
-
-+/**
-+ * e1000_power_up_phy - restore link in case the phy was powered down
-+ * @adapter: address of board private structure
-+ *
-+ * The phy may be powered down to save power and turn off link when the
-+ * driver is unloaded and wake on lan is not enabled (among others)
-+ * *** this routine MUST be followed by a call to e1000_reset ***
-+ *
-+ **/
-+
-+void e1000_power_up_phy(struct e1000_adapter *adapter)
-+{
-+ uint16_t mii_reg = 0;
-+
-+ /* Just clear the power down bit to wake the phy back up */
-+ if (adapter->hw.media_type == e1000_media_type_copper) {
-+ /* according to the manual, the phy will retain its
-+ * settings across a power-down/up cycle */
-+ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
-+ mii_reg &= ~MII_CR_POWER_DOWN;
-+ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
-+ }
-+}
-+
-+static void e1000_power_down_phy(struct e1000_adapter *adapter)
-+{
-+ boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) &&
-+ e1000_check_mng_mode(&adapter->hw);
-+ /* Power down the PHY so no link is implied when interface is down *
-+ * The PHY cannot be powered down if any of the following is TRUE *
-+ * (a) WoL is enabled
-+ * (b) AMT is active
-+ * (c) SoL/IDER session is active */
-+ if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
-+ adapter->hw.mac_type != e1000_ich8lan &&
-+ adapter->hw.media_type == e1000_media_type_copper &&
-+ !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) &&
-+ !mng_mode_enabled &&
-+ !e1000_check_phy_reset_block(&adapter->hw)) {
-+ uint16_t mii_reg = 0;
-+ e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg);
-+ mii_reg |= MII_CR_POWER_DOWN;
-+ e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg);
-+ mdelay(1);
-+ }
-+}
-+
- void
- e1000_down(struct e1000_adapter *adapter)
- {
- struct net_device *netdev = adapter->netdev;
-
- e1000_irq_disable(adapter);
-- free_irq(adapter->pdev->irq, netdev);
-+
- del_timer_sync(&adapter->tx_fifo_stall_timer);
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_info_timer);
-+
-+#ifdef CONFIG_E1000_NAPI
-+ netif_poll_disable(netdev);
-+#endif
-+ netdev->tx_queue_len = adapter->tx_queue_len;
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- e1000_reset(adapter);
-- e1000_clean_tx_ring(adapter);
-- e1000_clean_rx_ring(adapter);
-+ e1000_clean_all_tx_rings(adapter);
-+ e1000_clean_all_rx_rings(adapter);
-+}
-+
-+void
-+e1000_reinit_locked(struct e1000_adapter *adapter)
-+{
-+ WARN_ON(in_interrupt());
-+ while (test_and_set_bit(__E1000_RESETTING, &adapter->flags))
-+ msleep(1);
-+ e1000_down(adapter);
-+ e1000_up(adapter);
-+ clear_bit(__E1000_RESETTING, &adapter->flags);
- }
-
- void
- e1000_reset(struct e1000_adapter *adapter)
- {
- uint32_t pba, manc;
-+ uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF;
-+
- /* Repartition Pba for greater than 9k mtu
- * To take effect CTRL.RST is required.
- */
-
-- if(adapter->hw.mac_type < e1000_82547) {
-- if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
-- pba = E1000_PBA_40K;
-- else
-- pba = E1000_PBA_48K;
-- } else {
-- if(adapter->rx_buffer_len > E1000_RXBUFFER_8192)
-- pba = E1000_PBA_22K;
-- else
-- pba = E1000_PBA_30K;
-+ switch (adapter->hw.mac_type) {
-+ case e1000_82547:
-+ case e1000_82547_rev_2:
-+ pba = E1000_PBA_30K;
-+ break;
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+ pba = E1000_PBA_38K;
-+ break;
-+ case e1000_82573:
-+ pba = E1000_PBA_12K;
-+ break;
-+ case e1000_ich8lan:
-+ pba = E1000_PBA_8K;
-+ break;
-+ default:
-+ pba = E1000_PBA_48K;
-+ break;
-+ }
-+
-+ if ((adapter->hw.mac_type != e1000_82573) &&
-+ (adapter->netdev->mtu > E1000_RXBUFFER_8192))
-+ pba -= 8; /* allocate more FIFO for Tx */
-+
-+
-+ if (adapter->hw.mac_type == e1000_82547) {
- adapter->tx_fifo_head = 0;
- adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT;
- adapter->tx_fifo_size =
- (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT;
- atomic_set(&adapter->tx_fifo_stall, 0);
- }
-+
- E1000_WRITE_REG(&adapter->hw, PBA, pba);
-
- /* flow control settings */
-- adapter->hw.fc_high_water =
-- (pba << E1000_PBA_BYTES_SHIFT) - E1000_FC_HIGH_DIFF;
-- adapter->hw.fc_low_water =
-- (pba << E1000_PBA_BYTES_SHIFT) - E1000_FC_LOW_DIFF;
-- adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
-+ /* Set the FC high water mark to 90% of the FIFO size.
-+ * Required to clear last 3 LSB */
-+ fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8;
-+ /* We can't use 90% on small FIFOs because the remainder
-+ * would be less than 1 full frame. In this case, we size
-+ * it to allow at least a full frame above the high water
-+ * mark. */
-+ if (pba < E1000_PBA_16K)
-+ fc_high_water_mark = (pba * 1024) - 1600;
-+
-+ adapter->hw.fc_high_water = fc_high_water_mark;
-+ adapter->hw.fc_low_water = fc_high_water_mark - 8;
-+ if (adapter->hw.mac_type == e1000_80003es2lan)
-+ adapter->hw.fc_pause_time = 0xFFFF;
-+ else
-+ adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME;
- adapter->hw.fc_send_xon = 1;
- adapter->hw.fc = adapter->hw.original_fc;
-
-+ /* Allow time for pending master requests to run */
- e1000_reset_hw(&adapter->hw);
-- if(adapter->hw.mac_type >= e1000_82544)
-+ if (adapter->hw.mac_type >= e1000_82544)
- E1000_WRITE_REG(&adapter->hw, WUC, 0);
-- e1000_init_hw(&adapter->hw);
--
-+ if (e1000_init_hw(&adapter->hw))
-+ DPRINTK(PROBE, ERR, "Hardware Error\n");
-+#ifdef NETIF_F_HW_VLAN_TX
-+ e1000_update_mng_vlan(adapter);
-+#endif
- /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
- E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);
-
- e1000_reset_adaptive(&adapter->hw);
- e1000_phy_get_info(&adapter->hw, &adapter->phy_info);
-
-- if(adapter->en_mng_pt) {
-+ if (!adapter->smart_power_down &&
-+ (adapter->hw.mac_type == e1000_82571 ||
-+ adapter->hw.mac_type == e1000_82572)) {
-+ uint16_t phy_data = 0;
-+ /* speed up time to link by disabling smart power down, ignore
-+ * the return value of this function because there is nothing
-+ * different we would do if it failed */
-+ e1000_read_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
-+ &phy_data);
-+ phy_data &= ~IGP02E1000_PM_SPD;
-+ e1000_write_phy_reg(&adapter->hw, IGP02E1000_PHY_POWER_MGMT,
-+ phy_data);
-+ }
-+
-+ if (adapter->hw.mac_type < e1000_ich8lan)
-+ /* FIXME: this code is duplicate and wrong for PCI Express */
-+ if (adapter->en_mng_pt) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST);
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
-@@ -367,34 +756,36 @@ e1000_probe(struct pci_dev *pdev,
- {
- struct net_device *netdev;
- struct e1000_adapter *adapter;
-- static int cards_found = 0;
-- unsigned long mmio_start;
-- int mmio_len;
-- int pci_using_dac;
-- int i;
-- int err;
-- uint16_t eeprom_data;
-+ unsigned long mmio_start, mmio_len;
-+ unsigned long flash_start, flash_len;
-
-- if((err = pci_enable_device(pdev)))
-+ static int cards_found = 0;
-+ static int global_quad_port_a = 0; /* global ksp3 port a indication */
-+ int i, err, pci_using_dac;
-+ uint16_t eeprom_data = 0;
-+ uint16_t eeprom_apme_mask = E1000_EEPROM_APME;
-+ if ((err = pci_enable_device(pdev)))
- return err;
-
-- if(!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
-+ if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
-+ !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
- pci_using_dac = 1;
- } else {
-- if((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK))) {
-+ if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) &&
-+ (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) {
- E1000_ERR("No usable DMA configuration, aborting\n");
- return err;
- }
- pci_using_dac = 0;
- }
-
-- if((err = pci_request_regions(pdev, e1000_driver_name)))
-+ if ((err = pci_request_regions(pdev, e1000_driver_name)))
- return err;
-
- pci_set_master(pdev);
-
- netdev = alloc_etherdev(sizeof(struct e1000_adapter));
-- if(!netdev) {
-+ if (!netdev) {
- err = -ENOMEM;
- goto err_alloc_etherdev;
- }
-@@ -403,30 +794,25 @@ e1000_probe(struct pci_dev *pdev,
- SET_NETDEV_DEV(netdev, &pdev->dev);
-
- pci_set_drvdata(pdev, netdev);
-- adapter = netdev->priv;
-+ adapter = netdev_priv(netdev);
- adapter->netdev = netdev;
- adapter->pdev = pdev;
- adapter->hw.back = adapter;
- adapter->msg_enable = (1 << debug) - 1;
-
-- rtnl_lock();
-- /* we need to set the name early since the DPRINTK macro needs it set */
-- if (dev_alloc_name(netdev, netdev->name) < 0)
-- goto err_free_unlock;
--
- mmio_start = pci_resource_start(pdev, BAR_0);
- mmio_len = pci_resource_len(pdev, BAR_0);
-
- adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
-- if(!adapter->hw.hw_addr) {
-+ if (!adapter->hw.hw_addr) {
- err = -EIO;
- goto err_ioremap;
- }
-
-- for(i = BAR_1; i <= BAR_5; i++) {
-- if(pci_resource_len(pdev, i) == 0)
-+ for (i = BAR_1; i <= BAR_5; i++) {
-+ if (pci_resource_len(pdev, i) == 0)
- continue;
-- if(pci_resource_flags(pdev, i) & IORESOURCE_IO) {
-+ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
- adapter->hw.io_base = pci_resource_start(pdev, i);
- break;
- }
-@@ -440,19 +826,24 @@ e1000_probe(struct pci_dev *pdev,
- netdev->set_mac_address = &e1000_set_mac;
- netdev->change_mtu = &e1000_change_mtu;
- netdev->do_ioctl = &e1000_ioctl;
-- set_ethtool_ops(netdev);
-+ e1000_set_ethtool_ops(netdev);
-+#ifdef HAVE_TX_TIMEOUT
- netdev->tx_timeout = &e1000_tx_timeout;
- netdev->watchdog_timeo = 5 * HZ;
-+#endif
- #ifdef CONFIG_E1000_NAPI
- netdev->poll = &e1000_clean;
- netdev->weight = 64;
- #endif
-+#ifdef NETIF_F_HW_VLAN_TX
- netdev->vlan_rx_register = e1000_vlan_rx_register;
- netdev->vlan_rx_add_vid = e1000_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = e1000_vlan_rx_kill_vid;
-+#endif
- #ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = e1000_netpoll;
- #endif
-+ strcpy(netdev->name, pci_name(pdev));
-
- netdev->mem_start = mmio_start;
- netdev->mem_end = mmio_start + mmio_len;
-@@ -462,43 +853,75 @@ e1000_probe(struct pci_dev *pdev,
-
- /* setup the private structure */
-
-- if((err = e1000_sw_init(adapter)))
-+ if ((err = e1000_sw_init(adapter)))
- goto err_sw_init;
-
-- if(adapter->hw.mac_type >= e1000_82543) {
-+ /* Flash BAR mapping must happen after e1000_sw_init
-+ * because it depends on mac_type */
-+ if ((adapter->hw.mac_type == e1000_ich8lan) &&
-+ (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-+ flash_start = pci_resource_start(pdev, 1);
-+ flash_len = pci_resource_len(pdev, 1);
-+ adapter->hw.flash_address = ioremap(flash_start, flash_len);
-+ if (!adapter->hw.flash_address) {
-+ err = -EIO;
-+ goto err_flashmap;
-+ }
-+ }
-+
-+ if ((err = e1000_check_phy_reset_block(&adapter->hw)))
-+ DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n");
-+
-+#ifdef MAX_SKB_FRAGS
-+ if (adapter->hw.mac_type >= e1000_82543) {
-+#ifdef NETIF_F_HW_VLAN_TX
- netdev->features = NETIF_F_SG |
- NETIF_F_HW_CSUM |
- NETIF_F_HW_VLAN_TX |
- NETIF_F_HW_VLAN_RX |
- NETIF_F_HW_VLAN_FILTER;
-- } else {
-- netdev->features = NETIF_F_SG;
-+ if (adapter->hw.mac_type == e1000_ich8lan)
-+ netdev->features &= ~NETIF_F_HW_VLAN_FILTER;
-+#else
-+ netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM;
-+#endif
- }
-
- #ifdef NETIF_F_TSO
--#ifdef BROKEN_ON_NON_IA_ARCHS
-- /* Disbaled for now until root-cause is found for
-- * hangs reported against non-IA archs. TSO can be
-- * enabled using ethtool -K eth<x> tso on */
-- if((adapter->hw.mac_type >= e1000_82544) &&
-+ if ((adapter->hw.mac_type >= e1000_82544) &&
- (adapter->hw.mac_type != e1000_82547))
- netdev->features |= NETIF_F_TSO;
-+
-+#ifdef NETIF_F_TSO_IPV6
-+ if (adapter->hw.mac_type > e1000_82547_rev_2)
-+ netdev->features |= NETIF_F_TSO_IPV6;
- #endif
- #endif
--
-- if(pci_using_dac)
-+ if (pci_using_dac)
- netdev->features |= NETIF_F_HIGHDMA;
-
-+#endif
-+#ifdef NETIF_F_LLTX
-+ netdev->features |= NETIF_F_LLTX;
-+#endif
-+
- adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
-
-- /* before reading the EEPROM, reset the controller to
-+ /* initialize eeprom parameters */
-+
-+ if (e1000_init_eeprom_params(&adapter->hw)) {
-+ E1000_ERR("EEPROM initialization failed\n");
-+ return -EIO;
-+ }
-+
-+ /* before reading the EEPROM, reset the controller to
- * put the device in a known good starting state */
--
-+
- e1000_reset_hw(&adapter->hw);
-
- /* make sure the EEPROM is good */
-
-- if(e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
-+ if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
- DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
- err = -EIO;
- goto err_eeprom;
-@@ -506,16 +929,21 @@ e1000_probe(struct pci_dev *pdev,
-
- /* copy the MAC address out of the EEPROM */
-
-- e1000_read_mac_addr(&adapter->hw);
-+ if (e1000_read_mac_addr(&adapter->hw))
-+ DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
- memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
-+#ifdef ETHTOOL_GPERMADDR
-+ memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
-
-- if(!is_valid_ether_addr(netdev->dev_addr)) {
-+ if (!is_valid_ether_addr(netdev->perm_addr)) {
-+#else
-+ if (!is_valid_ether_addr(netdev->dev_addr)) {
-+#endif
-+ DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
- err = -EIO;
- goto err_eeprom;
- }
-
-- e1000_read_part_num(&adapter->hw, &(adapter->part_num));
--
- e1000_get_bus_info(&adapter->hw);
-
- init_timer(&adapter->tx_fifo_stall_timer);
-@@ -530,15 +958,14 @@ e1000_probe(struct pci_dev *pdev,
- adapter->phy_info_timer.function = &e1000_update_phy_info;
- adapter->phy_info_timer.data = (unsigned long) adapter;
-
-- INIT_WORK(&adapter->tx_timeout_task,
-- (void (*)(void *))e1000_tx_timeout_task, netdev);
-+ INIT_WORK(&adapter->reset_task,
-+ (void (*)(void *))e1000_reset_task, netdev);
-
- /* we're going to reset, so assume we have no link for now */
-
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
-- DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
- e1000_check_options(adapter);
-
- /* Initial Wake on LAN setting
-@@ -546,15 +973,26 @@ e1000_probe(struct pci_dev *pdev,
- * enable the ACPI Magic Packet filter
- */
-
-- switch(adapter->hw.mac_type) {
-+ switch (adapter->hw.mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- case e1000_82543:
- break;
-+ case e1000_82544:
-+ e1000_read_eeprom(&adapter->hw,
-+ EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data);
-+ eeprom_apme_mask = E1000_EEPROM_82544_APM;
-+ break;
-+ case e1000_ich8lan:
-+ e1000_read_eeprom(&adapter->hw,
-+ EEPROM_INIT_CONTROL1_REG, 1, &eeprom_data);
-+ eeprom_apme_mask = E1000_EEPROM_ICH8_APME;
-+ break;
- case e1000_82546:
- case e1000_82546_rev_3:
-- if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
-- && (adapter->hw.media_type == e1000_media_type_copper)) {
-+ case e1000_82571:
-+ case e1000_80003es2lan:
-+ if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){
- e1000_read_eeprom(&adapter->hw,
- EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
- break;
-@@ -565,28 +1003,88 @@ e1000_probe(struct pci_dev *pdev,
- EEPROM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
- break;
- }
-- if(eeprom_data & E1000_EEPROM_APME)
-- adapter->wol |= E1000_WUFC_MAG;
-+ if (eeprom_data & eeprom_apme_mask)
-+ adapter->eeprom_wol |= E1000_WUFC_MAG;
-
-- /* reset the hardware with the new settings */
-+ /* now that we have the eeprom settings, apply the special cases
-+ * where the eeprom may be wrong or the board simply won't support
-+ * wake on lan on a particular port */
-+ switch (pdev->device) {
-+ case E1000_DEV_ID_82546GB_PCIE:
-+ adapter->eeprom_wol = 0;
-+ break;
-+ case E1000_DEV_ID_82546EB_FIBER:
-+ case E1000_DEV_ID_82546GB_FIBER:
-+ case E1000_DEV_ID_82571EB_FIBER:
-+ /* Wake events only supported on port A for dual fiber
-+ * regardless of eeprom setting */
-+ if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1)
-+ adapter->eeprom_wol = 0;
-+ break;
-+ case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
-+ case E1000_DEV_ID_82571EB_QUAD_COPPER:
-+ /* if quad port adapter, disable WoL on all but port A */
-+ if (global_quad_port_a != 0)
-+ adapter->eeprom_wol = 0;
-+ else
-+ adapter->quad_port_a = 1;
-+ /* Reset for multiple quad port adapters */
-+ if (++global_quad_port_a == 4)
-+ global_quad_port_a = 0;
-+ break;
-+ }
-+
-+ /* initialize the wol settings based on the eeprom settings */
-+ adapter->wol = adapter->eeprom_wol;
-+
-+ /* print bus type/speed/width info */
-+ {
-+ struct e1000_hw *hw = &adapter->hw;
-+ DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ",
-+ ((hw->bus_type == e1000_bus_type_pcix) ? "-X" :
-+ (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")),
-+ ((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" :
-+ (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" :
-+ (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" :
-+ (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" :
-+ (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"),
-+ ((hw->bus_width == e1000_bus_width_64) ? "64-bit" :
-+ (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" :
-+ (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" :
-+ "32-bit"));
-+ }
-
-+ for (i = 0; i < 6; i++)
-+ printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':');
-+
-+ /* reset the hardware with the new settings */
- e1000_reset(adapter);
-
-- /* since we are holding the rtnl lock already, call the no-lock version */
-- if((err = register_netdevice(netdev)))
-+ /* If the controller is 82573 and f/w is AMT, do not set
-+ * DRV_LOAD until the interface is up. For all other cases,
-+ * let the f/w know that the h/w is now under the control
-+ * of the driver. */
-+ if (adapter->hw.mac_type != e1000_82573 ||
-+ !e1000_check_mng_mode(&adapter->hw))
-+ e1000_get_hw_control(adapter);
-+
-+ strcpy(netdev->name, "eth%d");
-+ if ((err = register_netdev(netdev)))
- goto err_register;
-
-+ DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
-+
- cards_found++;
-- rtnl_unlock();
- return 0;
-
- err_register:
-+ if (adapter->hw.flash_address)
-+ iounmap(adapter->hw.flash_address);
-+err_flashmap:
- err_sw_init:
- err_eeprom:
- iounmap(adapter->hw.hw_addr);
- err_ioremap:
--err_free_unlock:
-- rtnl_unlock();
- free_netdev(netdev);
- err_alloc_etherdev:
- pci_release_regions(pdev);
-@@ -607,26 +1105,51 @@ static void __devexit
- e1000_remove(struct pci_dev *pdev)
- {
- struct net_device *netdev = pci_get_drvdata(pdev);
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t manc;
-+#ifdef CONFIG_E1000_NAPI
-+ int i;
-+#endif
-
-- if(adapter->hw.mac_type >= e1000_82540 &&
-+ flush_scheduled_work();
-+
-+ if (adapter->hw.mac_type >= e1000_82540 &&
-+ adapter->hw.mac_type != e1000_ich8lan &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
-- if(manc & E1000_MANC_SMBUS_EN) {
-+ if (manc & E1000_MANC_SMBUS_EN) {
- manc |= E1000_MANC_ARP_EN;
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
- }
-
-+ /* Release control of h/w to f/w. If f/w is AMT enabled, this
-+ * would have already happened in close and is redundant. */
-+ e1000_release_hw_control(adapter);
-+
- unregister_netdev(netdev);
-+#ifdef CONFIG_E1000_NAPI
-+ for (i = 0; i < adapter->num_rx_queues; i++)
-+ dev_put(&adapter->polling_netdev[i]);
-+#endif
-
-- e1000_phy_hw_reset(&adapter->hw);
-+ if (!e1000_check_phy_reset_block(&adapter->hw))
-+ e1000_phy_hw_reset(&adapter->hw);
-+
-+ kfree(adapter->tx_ring);
-+ kfree(adapter->rx_ring);
-+#ifdef CONFIG_E1000_NAPI
-+ kfree(adapter->polling_netdev);
-+#endif
-
- iounmap(adapter->hw.hw_addr);
-+ if (adapter->hw.flash_address)
-+ iounmap(adapter->hw.flash_address);
- pci_release_regions(pdev);
-
- free_netdev(netdev);
-+
-+ pci_disable_device(pdev);
- }
-
- /**
-@@ -644,6 +1167,9 @@ e1000_sw_init(struct e1000_adapter *adap
- struct e1000_hw *hw = &adapter->hw;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
-+#ifdef CONFIG_E1000_NAPI
-+ int i;
-+#endif
-
- /* PCI config space info */
-
-@@ -656,7 +1182,8 @@ e1000_sw_init(struct e1000_adapter *adap
-
- pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
-
-- adapter->rx_buffer_len = E1000_RXBUFFER_2048;
-+ adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-+ adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
- hw->max_frame_size = netdev->mtu +
- ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
- hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
-@@ -668,80 +1195,159 @@ e1000_sw_init(struct e1000_adapter *adap
- return -EIO;
- }
-
-- /* initialize eeprom parameters */
--
-- e1000_init_eeprom_params(hw);
--
-- if((hw->mac_type == e1000_82541) ||
-- (hw->mac_type == e1000_82547) ||
-- (hw->mac_type == e1000_82541_rev_2) ||
-- (hw->mac_type == e1000_82547_rev_2))
-+ switch (hw->mac_type) {
-+ default:
-+ break;
-+ case e1000_82541:
-+ case e1000_82547:
-+ case e1000_82541_rev_2:
-+ case e1000_82547_rev_2:
- hw->phy_init_script = 1;
-+ break;
-+ }
-
- e1000_set_media_type(hw);
-
-- if(hw->mac_type < e1000_82543)
-- hw->report_tx_early = 0;
-- else
-- hw->report_tx_early = 1;
--
- hw->wait_autoneg_complete = FALSE;
- hw->tbi_compatibility_en = TRUE;
- hw->adaptive_ifs = TRUE;
-
- /* Copper options */
-
-- if(hw->media_type == e1000_media_type_copper) {
-+ if (hw->media_type == e1000_media_type_copper) {
- hw->mdix = AUTO_ALL_MODES;
- hw->disable_polarity_correction = FALSE;
- hw->master_slave = E1000_MASTER_SLAVE;
- }
-
-+ adapter->num_tx_queues = 1;
-+ adapter->num_rx_queues = 1;
-+
-+ if (e1000_alloc_queues(adapter)) {
-+ DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
-+ return -ENOMEM;
-+ }
-+
-+#ifdef CONFIG_E1000_NAPI
-+ for (i = 0; i < adapter->num_rx_queues; i++) {
-+ adapter->polling_netdev[i].priv = adapter;
-+ adapter->polling_netdev[i].poll = &e1000_clean;
-+ adapter->polling_netdev[i].weight = 64;
-+ dev_hold(&adapter->polling_netdev[i]);
-+ set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
-+ }
-+ spin_lock_init(&adapter->tx_queue_lock);
-+#endif
-+
- atomic_set(&adapter->irq_sem, 1);
- spin_lock_init(&adapter->stats_lock);
-- spin_lock_init(&adapter->tx_lock);
-
- return 0;
- }
-
- /**
-- * e1000_open - Called when a network interface is made active
-- * @netdev: network interface device structure
-- *
-- * Returns 0 on success, negative value on failure
-+ * e1000_alloc_queues - Allocate memory for all rings
-+ * @adapter: board private structure to initialize
- *
-- * The open entry point is called when a network interface is made
-- * active by the system (IFF_UP). At this point all resources needed
-- * for transmit and receive operations are allocated, the interrupt
-- * handler is registered with the OS, the watchdog timer is started,
-- * and the stack is notified that the interface is ready.
-+ * We allocate one ring per queue at run-time since we don't know the
-+ * number of queues at compile-time. The polling_netdev array is
-+ * intended for Multiqueue, but should work fine with a single queue.
- **/
-
--static int
--e1000_open(struct net_device *netdev)
-+static int __devinit
-+e1000_alloc_queues(struct e1000_adapter *adapter)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-- int err;
-+ int size;
-
-- /* allocate transmit descriptors */
-+ size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues;
-+ adapter->tx_ring = kmalloc(size, GFP_KERNEL);
-+ if (!adapter->tx_ring)
-+ return -ENOMEM;
-+ memset(adapter->tx_ring, 0, size);
-
-- if((err = e1000_setup_tx_resources(adapter)))
-- goto err_setup_tx;
-+ size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues;
-+ adapter->rx_ring = kmalloc(size, GFP_KERNEL);
-+ if (!adapter->rx_ring) {
-+ kfree(adapter->tx_ring);
-+ return -ENOMEM;
-+ }
-+ memset(adapter->rx_ring, 0, size);
-+
-+#ifdef CONFIG_E1000_NAPI
-+ size = sizeof(struct net_device) * adapter->num_rx_queues;
-+ adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
-+ if (!adapter->polling_netdev) {
-+ kfree(adapter->tx_ring);
-+ kfree(adapter->rx_ring);
-+ return -ENOMEM;
-+ }
-+ memset(adapter->polling_netdev, 0, size);
-+#endif
-+
-+ return E1000_SUCCESS;
-+}
-+
-+/**
-+ * e1000_open - Called when a network interface is made active
-+ * @netdev: network interface device structure
-+ *
-+ * Returns 0 on success, negative value on failure
-+ *
-+ * The open entry point is called when a network interface is made
-+ * active by the system (IFF_UP). At this point all resources needed
-+ * for transmit and receive operations are allocated, the interrupt
-+ * handler is registered with the OS, the watchdog timer is started,
-+ * and the stack is notified that the interface is ready.
-+ **/
-+
-+static int
-+e1000_open(struct net_device *netdev)
-+{
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+ int err;
-+
-+ /* disallow open during test */
-+ if (test_bit(__E1000_DRIVER_TESTING, &adapter->flags))
-+ return -EBUSY;
-+
-+ /* allocate transmit descriptors */
-+
-+ if ((err = e1000_setup_all_tx_resources(adapter)))
-+ goto err_setup_tx;
-
- /* allocate receive descriptors */
-
-- if((err = e1000_setup_rx_resources(adapter)))
-+ if ((err = e1000_setup_all_rx_resources(adapter)))
- goto err_setup_rx;
-
-- if((err = e1000_up(adapter)))
-+ err = e1000_request_irq(adapter);
-+ if (err)
- goto err_up;
-
-- return 0;
-+ e1000_power_up_phy(adapter);
-+
-+ if ((err = e1000_up(adapter)))
-+ goto err_up;
-+#ifdef NETIF_F_HW_VLAN_TX
-+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-+ if ((adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
-+ e1000_update_mng_vlan(adapter);
-+ }
-+#endif
-+
-+ /* If AMT is enabled, let the firmware know that the network
-+ * interface is now open */
-+ if (adapter->hw.mac_type == e1000_82573 &&
-+ e1000_check_mng_mode(&adapter->hw))
-+ e1000_get_hw_control(adapter);
-+
-+ return E1000_SUCCESS;
-
- err_up:
-- e1000_free_rx_resources(adapter);
-+ e1000_free_all_rx_resources(adapter);
- err_setup_rx:
-- e1000_free_tx_resources(adapter);
-+ e1000_free_all_tx_resources(adapter);
- err_setup_tx:
- e1000_reset(adapter);
-
-@@ -763,33 +1369,75 @@ err_setup_tx:
- static int
- e1000_close(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
-+ WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
- e1000_down(adapter);
-+ e1000_power_down_phy(adapter);
-+ e1000_free_irq(adapter);
-+
-+ e1000_free_all_tx_resources(adapter);
-+ e1000_free_all_rx_resources(adapter);
-
-- e1000_free_tx_resources(adapter);
-- e1000_free_rx_resources(adapter);
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if ((adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
-+ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
-+ }
-+#endif
-+
-+ /* If AMT is enabled, let the firmware know that the network
-+ * interface is now closed */
-+ if (adapter->hw.mac_type == e1000_82573 &&
-+ e1000_check_mng_mode(&adapter->hw))
-+ e1000_release_hw_control(adapter);
-
- return 0;
- }
-
- /**
-+ * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary
-+ * @adapter: address of board private structure
-+ * @start: address of beginning of memory
-+ * @len: length of memory
-+ **/
-+static boolean_t
-+e1000_check_64k_bound(struct e1000_adapter *adapter,
-+ void *start, unsigned long len)
-+{
-+ unsigned long begin = (unsigned long) start;
-+ unsigned long end = begin + len;
-+
-+ /* First rev 82545 and 82546 need to not allow any memory
-+ * write location to cross 64k boundary due to errata 23 */
-+ if (adapter->hw.mac_type == e1000_82545 ||
-+ adapter->hw.mac_type == e1000_82546) {
-+ return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE;
-+ }
-+
-+ return TRUE;
-+}
-+
-+/**
- * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
- * @adapter: board private structure
-+ * @txdr: tx descriptor ring (for a specific queue) to setup
- *
- * Return 0 on success, negative on failure
- **/
-
--int
--e1000_setup_tx_resources(struct e1000_adapter *adapter)
-+static int
-+e1000_setup_tx_resources(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *txdr)
- {
-- struct e1000_desc_ring *txdr = &adapter->tx_ring;
- struct pci_dev *pdev = adapter->pdev;
- int size;
-
- size = sizeof(struct e1000_buffer) * txdr->count;
-- txdr->buffer_info = kmalloc(size, GFP_KERNEL);
-- if(!txdr->buffer_info) {
-+ txdr->buffer_info = vmalloc(size);
-+ if (!txdr->buffer_info) {
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the transmit descriptor ring\n");
- return -ENOMEM;
- }
- memset(txdr->buffer_info, 0, size);
-@@ -800,19 +1448,82 @@ e1000_setup_tx_resources(struct e1000_ad
- E1000_ROUNDUP(txdr->size, 4096);
-
- txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-- if(!txdr->desc) {
-- kfree(txdr->buffer_info);
-+ if (!txdr->desc) {
-+setup_tx_desc_die:
-+ vfree(txdr->buffer_info);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the transmit descriptor ring\n");
- return -ENOMEM;
- }
-+
-+ /* Fix for errata 23, can't cross 64kB boundary */
-+ if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
-+ void *olddesc = txdr->desc;
-+ dma_addr_t olddma = txdr->dma;
-+ DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes "
-+ "at %p\n", txdr->size, txdr->desc);
-+ /* Try again, without freeing the previous */
-+ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma);
-+ /* Failed allocation, critical failure */
-+ if (!txdr->desc) {
-+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
-+ goto setup_tx_desc_die;
-+ }
-+
-+ if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) {
-+ /* give up */
-+ pci_free_consistent(pdev, txdr->size, txdr->desc,
-+ txdr->dma);
-+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate aligned memory "
-+ "for the transmit descriptor ring\n");
-+ vfree(txdr->buffer_info);
-+ return -ENOMEM;
-+ } else {
-+ /* Free old allocation, new allocation was successful */
-+ pci_free_consistent(pdev, txdr->size, olddesc, olddma);
-+ }
-+ }
- memset(txdr->desc, 0, txdr->size);
-
- txdr->next_to_use = 0;
- txdr->next_to_clean = 0;
-+ spin_lock_init(&txdr->tx_lock);
-
- return 0;
- }
-
- /**
-+ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
-+ * (Descriptors) for all queues
-+ * @adapter: board private structure
-+ *
-+ * If this function returns with an error, then it's possible one or
-+ * more of the rings is populated (while the rest are not). It is the
-+ * callers duty to clean those orphaned rings.
-+ *
-+ * Return 0 on success, negative on failure
-+ **/
-+
-+int
-+e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
-+{
-+ int i, err = 0;
-+
-+ for (i = 0; i < adapter->num_tx_queues; i++) {
-+ err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
-+ if (err) {
-+ DPRINTK(PROBE, ERR,
-+ "Allocation for Tx Queue %u failed\n", i);
-+ break;
-+ }
-+ }
-+
-+ return err;
-+}
-+
-+/**
- * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
- * @adapter: board private structure
- *
-@@ -822,106 +1533,215 @@ e1000_setup_tx_resources(struct e1000_ad
- static void
- e1000_configure_tx(struct e1000_adapter *adapter)
- {
-- uint64_t tdba = adapter->tx_ring.dma;
-- uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
-- uint32_t tctl, tipg;
--
-- E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL));
-- E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
--
-- E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen);
-+ uint64_t tdba;
-+ struct e1000_hw *hw = &adapter->hw;
-+ uint32_t tdlen, tctl, tipg, tarc;
-+ uint32_t ipgr1, ipgr2;
-
- /* Setup the HW Tx Head and Tail descriptor pointers */
-
-- E1000_WRITE_REG(&adapter->hw, TDH, 0);
-- E1000_WRITE_REG(&adapter->hw, TDT, 0);
-+ switch (adapter->num_tx_queues) {
-+ case 1:
-+ default:
-+ tdba = adapter->tx_ring[0].dma;
-+ tdlen = adapter->tx_ring[0].count *
-+ sizeof(struct e1000_tx_desc);
-+ E1000_WRITE_REG(hw, TDLEN, tdlen);
-+ E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
-+ E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
-+ E1000_WRITE_REG(hw, TDT, 0);
-+ E1000_WRITE_REG(hw, TDH, 0);
-+ adapter->tx_ring[0].tdh = E1000_TDH;
-+ adapter->tx_ring[0].tdt = E1000_TDT;
-+ break;
-+ }
-
- /* Set the default values for the Tx Inter Packet Gap timer */
-
-- switch (adapter->hw.mac_type) {
-+ if (hw->media_type == e1000_media_type_fiber ||
-+ hw->media_type == e1000_media_type_internal_serdes)
-+ tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
-+ else
-+ tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
-+
-+ switch (hw->mac_type) {
- case e1000_82542_rev2_0:
- case e1000_82542_rev2_1:
- tipg = DEFAULT_82542_TIPG_IPGT;
-- tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-- tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
-+ ipgr1 = DEFAULT_82542_TIPG_IPGR1;
-+ ipgr2 = DEFAULT_82542_TIPG_IPGR2;
-+ break;
-+ case e1000_80003es2lan:
-+ ipgr1 = DEFAULT_82543_TIPG_IPGR1;
-+ ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2;
- break;
- default:
-- if(adapter->hw.media_type == e1000_media_type_fiber ||
-- adapter->hw.media_type == e1000_media_type_internal_serdes)
-- tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
-- else
-- tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
-- tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
-- tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
-+ ipgr1 = DEFAULT_82543_TIPG_IPGR1;
-+ ipgr2 = DEFAULT_82543_TIPG_IPGR2;
-+ break;
- }
-- E1000_WRITE_REG(&adapter->hw, TIPG, tipg);
-+ tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT;
-+ tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT;
-+ E1000_WRITE_REG(hw, TIPG, tipg);
-
- /* Set the Tx Interrupt Delay register */
-
-- E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
-- if(adapter->hw.mac_type >= e1000_82540)
-- E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay);
-+ E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
-+ if (hw->mac_type >= e1000_82540)
-+ E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
-
- /* Program the Transmit Control Register */
-
-- tctl = E1000_READ_REG(&adapter->hw, TCTL);
-+ tctl = E1000_READ_REG(hw, TCTL);
-
- tctl &= ~E1000_TCTL_CT;
-- tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
-+ tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC |
- (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
-
-- E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
-+#ifdef DISABLE_MULR
-+ /* disable Multiple Reads for debugging */
-+ tctl &= ~E1000_TCTL_MULR;
-+#endif
-+
-+ if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
-+ tarc = E1000_READ_REG(hw, TARC0);
-+ tarc |= ((1 << 25) | (1 << 21));
-+ E1000_WRITE_REG(hw, TARC0, tarc);
-+ tarc = E1000_READ_REG(hw, TARC1);
-+ tarc |= (1 << 25);
-+ if (tctl & E1000_TCTL_MULR)
-+ tarc &= ~(1 << 28);
-+ else
-+ tarc |= (1 << 28);
-+ E1000_WRITE_REG(hw, TARC1, tarc);
-+ } else if (hw->mac_type == e1000_80003es2lan) {
-+ tarc = E1000_READ_REG(hw, TARC0);
-+ tarc |= 1;
-+ E1000_WRITE_REG(hw, TARC0, tarc);
-+ tarc = E1000_READ_REG(hw, TARC1);
-+ tarc |= 1;
-+ E1000_WRITE_REG(hw, TARC1, tarc);
-+ }
-
-- e1000_config_collision_dist(&adapter->hw);
-+ e1000_config_collision_dist(hw);
-
- /* Setup Transmit Descriptor Settings for eop descriptor */
- adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
- E1000_TXD_CMD_IFCS;
-
-- if(adapter->hw.report_tx_early == 1)
-- adapter->txd_cmd |= E1000_TXD_CMD_RS;
-- else
-+ if (hw->mac_type < e1000_82543)
- adapter->txd_cmd |= E1000_TXD_CMD_RPS;
-+ else
-+ adapter->txd_cmd |= E1000_TXD_CMD_RS;
-
- /* Cache if we're 82544 running in PCI-X because we'll
- * need this to apply a workaround later in the send path. */
-- if(adapter->hw.mac_type == e1000_82544 &&
-- adapter->hw.bus_type == e1000_bus_type_pcix)
-+ if (hw->mac_type == e1000_82544 &&
-+ hw->bus_type == e1000_bus_type_pcix)
- adapter->pcix_82544 = 1;
-+
-+ E1000_WRITE_REG(hw, TCTL, tctl);
-+
- }
-
- /**
- * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
- * @adapter: board private structure
-+ * @rxdr: rx descriptor ring (for a specific queue) to setup
- *
- * Returns 0 on success, negative on failure
- **/
-
--int
--e1000_setup_rx_resources(struct e1000_adapter *adapter)
-+static int
-+e1000_setup_rx_resources(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rxdr)
- {
-- struct e1000_desc_ring *rxdr = &adapter->rx_ring;
- struct pci_dev *pdev = adapter->pdev;
-- int size;
-+ int size, desc_len;
-
- size = sizeof(struct e1000_buffer) * rxdr->count;
-- rxdr->buffer_info = kmalloc(size, GFP_KERNEL);
-- if(!rxdr->buffer_info) {
-+ rxdr->buffer_info = vmalloc(size);
-+ if (!rxdr->buffer_info) {
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the receive descriptor ring\n");
- return -ENOMEM;
- }
- memset(rxdr->buffer_info, 0, size);
-
-+ size = sizeof(struct e1000_ps_page) * rxdr->count;
-+ rxdr->ps_page = kmalloc(size, GFP_KERNEL);
-+ if (!rxdr->ps_page) {
-+ vfree(rxdr->buffer_info);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the receive descriptor ring\n");
-+ return -ENOMEM;
-+ }
-+ memset(rxdr->ps_page, 0, size);
-+
-+ size = sizeof(struct e1000_ps_page_dma) * rxdr->count;
-+ rxdr->ps_page_dma = kmalloc(size, GFP_KERNEL);
-+ if (!rxdr->ps_page_dma) {
-+ vfree(rxdr->buffer_info);
-+ kfree(rxdr->ps_page);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the receive descriptor ring\n");
-+ return -ENOMEM;
-+ }
-+ memset(rxdr->ps_page_dma, 0, size);
-+
-+ if (adapter->hw.mac_type <= e1000_82547_rev_2)
-+ desc_len = sizeof(struct e1000_rx_desc);
-+ else
-+ desc_len = sizeof(union e1000_rx_desc_packet_split);
-+
- /* Round up to nearest 4K */
-
-- rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc);
-+ rxdr->size = rxdr->count * desc_len;
- E1000_ROUNDUP(rxdr->size, 4096);
-
- rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
-
-- if(!rxdr->desc) {
-- kfree(rxdr->buffer_info);
-+ if (!rxdr->desc) {
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory for the receive descriptor ring\n");
-+setup_rx_desc_die:
-+ vfree(rxdr->buffer_info);
-+ kfree(rxdr->ps_page);
-+ kfree(rxdr->ps_page_dma);
- return -ENOMEM;
- }
-+
-+ /* Fix for errata 23, can't cross 64kB boundary */
-+ if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
-+ void *olddesc = rxdr->desc;
-+ dma_addr_t olddma = rxdr->dma;
-+ DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes "
-+ "at %p\n", rxdr->size, rxdr->desc);
-+ /* Try again, without freeing the previous */
-+ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
-+ /* Failed allocation, critical failure */
-+ if (!rxdr->desc) {
-+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate memory "
-+ "for the receive descriptor ring\n");
-+ goto setup_rx_desc_die;
-+ }
-+
-+ if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) {
-+ /* give up */
-+ pci_free_consistent(pdev, rxdr->size, rxdr->desc,
-+ rxdr->dma);
-+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
-+ DPRINTK(PROBE, ERR,
-+ "Unable to allocate aligned memory "
-+ "for the receive descriptor ring\n");
-+ goto setup_rx_desc_die;
-+ } else {
-+ /* Free old allocation, new allocation was successful */
-+ pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
-+ }
-+ }
- memset(rxdr->desc, 0, rxdr->size);
-
- rxdr->next_to_clean = 0;
-@@ -931,14 +1751,48 @@ e1000_setup_rx_resources(struct e1000_ad
- }
-
- /**
-- * e1000_setup_rctl - configure the receive control register
-- * @adapter: Board private structure
-+ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
-+ * (Descriptors) for all queues
-+ * @adapter: board private structure
-+ *
-+ * If this function returns with an error, then it's possible one or
-+ * more of the rings is populated (while the rest are not). It is the
-+ * callers duty to clean those orphaned rings.
-+ *
-+ * Return 0 on success, negative on failure
- **/
-
-+int
-+e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
-+{
-+ int i, err = 0;
-+
-+ for (i = 0; i < adapter->num_rx_queues; i++) {
-+ err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
-+ if (err) {
-+ DPRINTK(PROBE, ERR,
-+ "Allocation for Rx Queue %u failed\n", i);
-+ break;
-+ }
-+ }
-+
-+ return err;
-+}
-+
-+/**
-+ * e1000_setup_rctl - configure the receive control registers
-+ * @adapter: Board private structure
-+ **/
-+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
-+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
- static void
- e1000_setup_rctl(struct e1000_adapter *adapter)
- {
-- uint32_t rctl;
-+ uint32_t rctl, rfctl;
-+ uint32_t psrctl = 0;
-+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-+ uint32_t pages = 0;
-+#endif
-
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
-
-@@ -948,27 +1802,98 @@ e1000_setup_rctl(struct e1000_adapter *a
- E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
- (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT);
-
-- if(adapter->hw.tbi_compatibility_on == 1)
-+ /* disable the stripping of CRC because it breaks
-+ * BMC firmware connected over SMBUS
-+ if (adapter->hw.mac_type > e1000_82543)
-+ rctl |= E1000_RCTL_SECRC;
-+ */
-+
-+ if (adapter->hw.tbi_compatibility_on == 1)
- rctl |= E1000_RCTL_SBP;
- else
- rctl &= ~E1000_RCTL_SBP;
-
-- rctl &= ~(E1000_RCTL_SZ_4096);
-+ if (adapter->netdev->mtu <= ETH_DATA_LEN)
-+ rctl &= ~E1000_RCTL_LPE;
-+ else
-+ rctl |= E1000_RCTL_LPE;
-+
-+ /* Setup buffer sizes */
-+ rctl &= ~E1000_RCTL_SZ_4096;
-+ rctl |= E1000_RCTL_BSEX;
- switch (adapter->rx_buffer_len) {
-- case E1000_RXBUFFER_2048:
-- default:
-- rctl |= E1000_RCTL_SZ_2048;
-- rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE);
-- break;
-- case E1000_RXBUFFER_4096:
-- rctl |= E1000_RCTL_SZ_4096 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-- break;
-- case E1000_RXBUFFER_8192:
-- rctl |= E1000_RCTL_SZ_8192 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-- break;
-- case E1000_RXBUFFER_16384:
-- rctl |= E1000_RCTL_SZ_16384 | E1000_RCTL_BSEX | E1000_RCTL_LPE;
-- break;
-+ case E1000_RXBUFFER_256:
-+ rctl |= E1000_RCTL_SZ_256;
-+ rctl &= ~E1000_RCTL_BSEX;
-+ break;
-+ case E1000_RXBUFFER_512:
-+ rctl |= E1000_RCTL_SZ_512;
-+ rctl &= ~E1000_RCTL_BSEX;
-+ break;
-+ case E1000_RXBUFFER_1024:
-+ rctl |= E1000_RCTL_SZ_1024;
-+ rctl &= ~E1000_RCTL_BSEX;
-+ break;
-+ case E1000_RXBUFFER_2048:
-+ default:
-+ rctl |= E1000_RCTL_SZ_2048;
-+ rctl &= ~E1000_RCTL_BSEX;
-+ break;
-+ case E1000_RXBUFFER_4096:
-+ rctl |= E1000_RCTL_SZ_4096;
-+ break;
-+ case E1000_RXBUFFER_8192:
-+ rctl |= E1000_RCTL_SZ_8192;
-+ break;
-+ case E1000_RXBUFFER_16384:
-+ rctl |= E1000_RCTL_SZ_16384;
-+ break;
-+ }
-+
-+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-+ /* 82571 and greater support packet-split where the protocol
-+ * header is placed in skb->data and the packet data is
-+ * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
-+ * In the case of a non-split, skb->data is linearly filled,
-+ * followed by the page buffers. Therefore, skb->data is
-+ * sized to hold the largest protocol header.
-+ */
-+ pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-+ if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
-+ PAGE_SIZE <= 16384)
-+ adapter->rx_ps_pages = pages;
-+ else
-+ adapter->rx_ps_pages = 0;
-+#endif
-+ if (adapter->rx_ps_pages) {
-+ /* Configure extra packet-split registers */
-+ rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
-+ rfctl |= E1000_RFCTL_EXTEN;
-+ /* disable IPv6 packet split support */
-+ rfctl |= E1000_RFCTL_IPV6_DIS;
-+ E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl);
-+
-+ /* disable the stripping of CRC because it breaks
-+ * BMC firmware connected over SMBUS */
-+ rctl |= E1000_RCTL_DTYP_PS /* | E1000_RCTL_SECRC */;
-+
-+ psrctl |= adapter->rx_ps_bsize0 >>
-+ E1000_PSRCTL_BSIZE0_SHIFT;
-+
-+ switch (adapter->rx_ps_pages) {
-+ case 3:
-+ psrctl |= PAGE_SIZE <<
-+ E1000_PSRCTL_BSIZE3_SHIFT;
-+ case 2:
-+ psrctl |= PAGE_SIZE <<
-+ E1000_PSRCTL_BSIZE2_SHIFT;
-+ case 1:
-+ psrctl |= PAGE_SIZE >>
-+ E1000_PSRCTL_BSIZE1_SHIFT;
-+ break;
-+ }
-+
-+ E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
- }
-
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-@@ -984,103 +1909,164 @@ e1000_setup_rctl(struct e1000_adapter *a
- static void
- e1000_configure_rx(struct e1000_adapter *adapter)
- {
-- uint64_t rdba = adapter->rx_ring.dma;
-- uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
-- uint32_t rctl;
-- uint32_t rxcsum;
-+ uint64_t rdba;
-+ struct e1000_hw *hw = &adapter->hw;
-+ uint32_t rdlen, rctl, rxcsum, ctrl_ext;
-
-- /* make sure receives are disabled while setting up the descriptors */
-+ if (adapter->rx_ps_pages) {
-+ /* this is a 32 byte descriptor */
-+ rdlen = adapter->rx_ring[0].count *
-+ sizeof(union e1000_rx_desc_packet_split);
-+ adapter->clean_rx = e1000_clean_rx_irq_ps;
-+ adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
-+ } else {
-+ rdlen = adapter->rx_ring[0].count *
-+ sizeof(struct e1000_rx_desc);
-+ adapter->clean_rx = e1000_clean_rx_irq;
-+ adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
-+ }
-
-- rctl = E1000_READ_REG(&adapter->hw, RCTL);
-- E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
-+ /* disable receives while setting up the descriptors */
-+ rctl = E1000_READ_REG(hw, RCTL);
-+ E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
-
- /* set the Receive Delay Timer Register */
-+ E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
-
-- E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay);
--
-- if(adapter->hw.mac_type >= e1000_82540) {
-- E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
-- if(adapter->itr > 1)
-- E1000_WRITE_REG(&adapter->hw, ITR,
-+ if (hw->mac_type >= e1000_82540) {
-+ E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
-+ if (adapter->itr > 1)
-+ E1000_WRITE_REG(hw, ITR,
- 1000000000 / (adapter->itr * 256));
- }
-
-- /* Setup the Base and Length of the Rx Descriptor Ring */
--
-- E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL));
-- E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
--
-- E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen);
-+ if (hw->mac_type >= e1000_82571) {
-+ ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
-+ /* Reset delay timers after every interrupt */
-+ ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR;
-+#ifdef CONFIG_E1000_NAPI
-+ /* Auto-Mask interrupts upon ICR read. */
-+ ctrl_ext |= E1000_CTRL_EXT_IAME;
-+#endif
-+ E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
-+ E1000_WRITE_REG(hw, IAM, ~0);
-+ E1000_WRITE_FLUSH(hw);
-+ }
-
-- /* Setup the HW Rx Head and Tail Descriptor Pointers */
-- E1000_WRITE_REG(&adapter->hw, RDH, 0);
-- E1000_WRITE_REG(&adapter->hw, RDT, 0);
-+ /* Setup the HW Rx Head and Tail Descriptor Pointers and
-+ * the Base and Length of the Rx Descriptor Ring */
-+ switch (adapter->num_rx_queues) {
-+ case 1:
-+ default:
-+ rdba = adapter->rx_ring[0].dma;
-+ E1000_WRITE_REG(hw, RDLEN, rdlen);
-+ E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
-+ E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
-+ E1000_WRITE_REG(hw, RDT, 0);
-+ E1000_WRITE_REG(hw, RDH, 0);
-+ adapter->rx_ring[0].rdh = E1000_RDH;
-+ adapter->rx_ring[0].rdt = E1000_RDT;
-+ break;
-+ }
-
- /* Enable 82543 Receive Checksum Offload for TCP and UDP */
-- if((adapter->hw.mac_type >= e1000_82543) &&
-- (adapter->rx_csum == TRUE)) {
-- rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
-- rxcsum |= E1000_RXCSUM_TUOFL;
-- E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
-+ if (hw->mac_type >= e1000_82543) {
-+ rxcsum = E1000_READ_REG(hw, RXCSUM);
-+ if (adapter->rx_csum == TRUE) {
-+ rxcsum |= E1000_RXCSUM_TUOFL;
-+
-+ /* Enable 82571 IPv4 payload checksum for UDP fragments
-+ * Must be used in conjunction with packet-split. */
-+ if ((hw->mac_type >= e1000_82571) &&
-+ (adapter->rx_ps_pages)) {
-+ rxcsum |= E1000_RXCSUM_IPPCSE;
-+ }
-+ } else {
-+ rxcsum &= ~E1000_RXCSUM_TUOFL;
-+ /* don't need to clear IPPCSE as it defaults to 0 */
-+ }
-+ E1000_WRITE_REG(hw, RXCSUM, rxcsum);
- }
-
-- /* Enable Receives */
-
-- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-+ /* Enable Receives */
-+ E1000_WRITE_REG(hw, RCTL, rctl);
- }
-
- /**
-- * e1000_free_tx_resources - Free Tx Resources
-+ * e1000_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
-+ * @tx_ring: Tx descriptor ring for a specific queue
- *
- * Free all transmit software resources
- **/
-
--void
--e1000_free_tx_resources(struct e1000_adapter *adapter)
-+static void
-+e1000_free_tx_resources(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring)
- {
- struct pci_dev *pdev = adapter->pdev;
-
-- e1000_clean_tx_ring(adapter);
-+ e1000_clean_tx_ring(adapter, tx_ring);
-+
-+ vfree(tx_ring->buffer_info);
-+ tx_ring->buffer_info = NULL;
-+
-+ pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
-+
-+ tx_ring->desc = NULL;
-+}
-+
-+/**
-+ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
-+ * @adapter: board private structure
-+ *
-+ * Free all transmit software resources
-+ **/
-
-- kfree(adapter->tx_ring.buffer_info);
-- adapter->tx_ring.buffer_info = NULL;
-+void
-+e1000_free_all_tx_resources(struct e1000_adapter *adapter)
-+{
-+ int i;
-
-- pci_free_consistent(pdev, adapter->tx_ring.size,
-- adapter->tx_ring.desc, adapter->tx_ring.dma);
-+ for (i = 0; i < adapter->num_tx_queues; i++)
-+ e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
-+}
-
-- adapter->tx_ring.desc = NULL;
-+static void
-+e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
-+ struct e1000_buffer *buffer_info)
-+{
-+ if (buffer_info->dma) {
-+ pci_unmap_page(adapter->pdev,
-+ buffer_info->dma,
-+ buffer_info->length,
-+ PCI_DMA_TODEVICE);
-+ }
-+ if (buffer_info->skb)
-+ dev_kfree_skb_any(buffer_info->skb);
-+ memset(buffer_info, 0, sizeof(struct e1000_buffer));
- }
-
- /**
- * e1000_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
-+ * @tx_ring: ring to be cleaned
- **/
-
- static void
--e1000_clean_tx_ring(struct e1000_adapter *adapter)
-+e1000_clean_tx_ring(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring)
- {
-- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
- struct e1000_buffer *buffer_info;
-- struct pci_dev *pdev = adapter->pdev;
- unsigned long size;
- unsigned int i;
-
- /* Free all the Tx ring sk_buffs */
-
-- for(i = 0; i < tx_ring->count; i++) {
-+ for (i = 0; i < tx_ring->count; i++) {
- buffer_info = &tx_ring->buffer_info[i];
-- if(buffer_info->skb) {
--
-- pci_unmap_page(pdev,
-- buffer_info->dma,
-- buffer_info->length,
-- PCI_DMA_TODEVICE);
--
-- dev_kfree_skb(buffer_info->skb);
--
-- buffer_info->skb = NULL;
-- }
-+ e1000_unmap_and_free_tx_resource(adapter, buffer_info);
- }
-
- size = sizeof(struct e1000_buffer) * tx_ring->count;
-@@ -1092,28 +2078,48 @@ e1000_clean_tx_ring(struct e1000_adapter
-
- tx_ring->next_to_use = 0;
- tx_ring->next_to_clean = 0;
-+ tx_ring->last_tx_tso = 0;
-+
-+ writel(0, adapter->hw.hw_addr + tx_ring->tdh);
-+ writel(0, adapter->hw.hw_addr + tx_ring->tdt);
-+}
-+
-+/**
-+ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
-+ * @adapter: board private structure
-+ **/
-
-- E1000_WRITE_REG(&adapter->hw, TDH, 0);
-- E1000_WRITE_REG(&adapter->hw, TDT, 0);
-+static void
-+e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
-+{
-+ int i;
-+
-+ for (i = 0; i < adapter->num_tx_queues; i++)
-+ e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
- }
-
- /**
- * e1000_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
-+ * @rx_ring: ring to clean the resources from
- *
- * Free all receive software resources
- **/
-
--void
--e1000_free_rx_resources(struct e1000_adapter *adapter)
-+static void
-+e1000_free_rx_resources(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring)
- {
-- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
- struct pci_dev *pdev = adapter->pdev;
-
-- e1000_clean_rx_ring(adapter);
-+ e1000_clean_rx_ring(adapter, rx_ring);
-
-- kfree(rx_ring->buffer_info);
-+ vfree(rx_ring->buffer_info);
- rx_ring->buffer_info = NULL;
-+ kfree(rx_ring->ps_page);
-+ rx_ring->ps_page = NULL;
-+ kfree(rx_ring->ps_page_dma);
-+ rx_ring->ps_page_dma = NULL;
-
- pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
-
-@@ -1121,38 +2127,69 @@ e1000_free_rx_resources(struct e1000_ada
- }
-
- /**
-- * e1000_clean_rx_ring - Free Rx Buffers
-+ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
-+ * @adapter: board private structure
-+ *
-+ * Free all receive software resources
-+ **/
-+
-+void
-+e1000_free_all_rx_resources(struct e1000_adapter *adapter)
-+{
-+ int i;
-+
-+ for (i = 0; i < adapter->num_rx_queues; i++)
-+ e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
-+}
-+
-+/**
-+ * e1000_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
-+ * @rx_ring: ring to free buffers from
- **/
-
- static void
--e1000_clean_rx_ring(struct e1000_adapter *adapter)
-+e1000_clean_rx_ring(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring)
- {
-- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
- struct e1000_buffer *buffer_info;
-+ struct e1000_ps_page *ps_page;
-+ struct e1000_ps_page_dma *ps_page_dma;
- struct pci_dev *pdev = adapter->pdev;
- unsigned long size;
-- unsigned int i;
-+ unsigned int i, j;
-
- /* Free all the Rx ring sk_buffs */
--
-- for(i = 0; i < rx_ring->count; i++) {
-+ for (i = 0; i < rx_ring->count; i++) {
- buffer_info = &rx_ring->buffer_info[i];
-- if(buffer_info->skb) {
--
-+ if (buffer_info->skb) {
- pci_unmap_single(pdev,
-- buffer_info->dma,
-- buffer_info->length,
-- PCI_DMA_FROMDEVICE);
-+ buffer_info->dma,
-+ buffer_info->length,
-+ PCI_DMA_FROMDEVICE);
-
- dev_kfree_skb(buffer_info->skb);
--
- buffer_info->skb = NULL;
- }
-+ ps_page = &rx_ring->ps_page[i];
-+ ps_page_dma = &rx_ring->ps_page_dma[i];
-+ for (j = 0; j < adapter->rx_ps_pages; j++) {
-+ if (!ps_page->ps_page[j]) break;
-+ pci_unmap_page(pdev,
-+ ps_page_dma->ps_page_dma[j],
-+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
-+ ps_page_dma->ps_page_dma[j] = 0;
-+ put_page(ps_page->ps_page[j]);
-+ ps_page->ps_page[j] = NULL;
-+ }
- }
-
- size = sizeof(struct e1000_buffer) * rx_ring->count;
- memset(rx_ring->buffer_info, 0, size);
-+ size = sizeof(struct e1000_ps_page) * rx_ring->count;
-+ memset(rx_ring->ps_page, 0, size);
-+ size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
-+ memset(rx_ring->ps_page_dma, 0, size);
-
- /* Zero out the descriptor ring */
-
-@@ -1161,8 +2198,22 @@ e1000_clean_rx_ring(struct e1000_adapter
- rx_ring->next_to_clean = 0;
- rx_ring->next_to_use = 0;
-
-- E1000_WRITE_REG(&adapter->hw, RDH, 0);
-- E1000_WRITE_REG(&adapter->hw, RDT, 0);
-+ writel(0, adapter->hw.hw_addr + rx_ring->rdh);
-+ writel(0, adapter->hw.hw_addr + rx_ring->rdt);
-+}
-+
-+/**
-+ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
-+ * @adapter: board private structure
-+ **/
-+
-+static void
-+e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
-+{
-+ int i;
-+
-+ for (i = 0; i < adapter->num_rx_queues; i++)
-+ e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
- }
-
- /* The 82542 2.0 (revision 2) needs to have the receive unit in reset
-@@ -1182,8 +2233,8 @@ e1000_enter_82542_rst(struct e1000_adapt
- E1000_WRITE_FLUSH(&adapter->hw);
- mdelay(5);
-
-- if(netif_running(netdev))
-- e1000_clean_rx_ring(adapter);
-+ if (netif_running(netdev))
-+ e1000_clean_all_rx_rings(adapter);
- }
-
- static void
-@@ -1198,12 +2249,14 @@ e1000_leave_82542_rst(struct e1000_adapt
- E1000_WRITE_FLUSH(&adapter->hw);
- mdelay(5);
-
-- if(adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
-+ if (adapter->hw.pci_cmd_word & PCI_COMMAND_INVALIDATE)
- e1000_pci_set_mwi(&adapter->hw);
-
-- if(netif_running(netdev)) {
-+ if (netif_running(netdev)) {
-+ /* No need to loop, because 82542 supports only 1 queue */
-+ struct e1000_rx_ring *ring = &adapter->rx_ring[0];
- e1000_configure_rx(adapter);
-- e1000_alloc_rx_buffers(adapter);
-+ adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring));
- }
- }
-
-@@ -1218,15 +2271,15 @@ e1000_leave_82542_rst(struct e1000_adapt
- static int
- e1000_set_mac(struct net_device *netdev, void *p)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct sockaddr *addr = p;
-
-- if(!is_valid_ether_addr(addr->sa_data))
-+ if (!is_valid_ether_addr(addr->sa_data))
- return -EADDRNOTAVAIL;
-
- /* 82542 2.0 needs to be in reset to write receive address registers */
-
-- if(adapter->hw.mac_type == e1000_82542_rev2_0)
-+ if (adapter->hw.mac_type == e1000_82542_rev2_0)
- e1000_enter_82542_rst(adapter);
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-@@ -1234,7 +2287,23 @@ e1000_set_mac(struct net_device *netdev,
-
- e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
-
-- if(adapter->hw.mac_type == e1000_82542_rev2_0)
-+ /* With 82571 controllers, LAA may be overwritten (with the default)
-+ * due to controller reset from the other port. */
-+ if (adapter->hw.mac_type == e1000_82571) {
-+ /* activate the work around */
-+ adapter->hw.laa_is_present = 1;
-+
-+ /* Hold a copy of the LAA in RAR[14] This is done so that
-+ * between the time RAR[0] gets clobbered and the time it
-+ * gets fixed (in e1000_watchdog), the actual LAA is in one
-+ * of the RARs and no incoming packets directed to this port
-+ * are dropped. Eventaully the LAA will be in RAR[0] and
-+ * RAR[14] */
-+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr,
-+ E1000_RAR_ENTRIES - 1);
-+ }
-+
-+ if (adapter->hw.mac_type == e1000_82542_rev2_0)
- e1000_leave_82542_rst(adapter);
-
- return 0;
-@@ -1253,20 +2322,30 @@ e1000_set_mac(struct net_device *netdev,
- static void
- e1000_set_multi(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
- struct dev_mc_list *mc_ptr;
- uint32_t rctl;
- uint32_t hash_value;
-- int i;
-+ int i, rar_entries = E1000_RAR_ENTRIES;
-+ int mta_reg_count = (hw->mac_type == e1000_ich8lan) ?
-+ E1000_NUM_MTA_REGISTERS_ICH8LAN :
-+ E1000_NUM_MTA_REGISTERS;
-+
-+ if (adapter->hw.mac_type == e1000_ich8lan)
-+ rar_entries = E1000_RAR_ENTRIES_ICH8LAN;
-+
-+ /* reserve RAR[14] for LAA over-write work-around */
-+ if (adapter->hw.mac_type == e1000_82571)
-+ rar_entries--;
-
- /* Check for Promiscuous and All Multicast modes */
-
- rctl = E1000_READ_REG(hw, RCTL);
-
-- if(netdev->flags & IFF_PROMISC) {
-+ if (netdev->flags & IFF_PROMISC) {
- rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
-- } else if(netdev->flags & IFF_ALLMULTI) {
-+ } else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
- } else {
-@@ -1277,42 +2356,48 @@ e1000_set_multi(struct net_device *netde
-
- /* 82542 2.0 needs to be in reset to write receive address registers */
-
-- if(hw->mac_type == e1000_82542_rev2_0)
-+ if (hw->mac_type == e1000_82542_rev2_0)
- e1000_enter_82542_rst(adapter);
-
- /* load the first 14 multicast address into the exact filters 1-14
- * RAR 0 is used for the station MAC adddress
- * if there are not 14 addresses, go ahead and clear the filters
-+ * -- with 82571 controllers only 0-13 entries are filled here
- */
- mc_ptr = netdev->mc_list;
-
-- for(i = 1; i < E1000_RAR_ENTRIES; i++) {
-- if(mc_ptr) {
-+ for (i = 1; i < rar_entries; i++) {
-+ if (mc_ptr) {
- e1000_rar_set(hw, mc_ptr->dmi_addr, i);
- mc_ptr = mc_ptr->next;
- } else {
- E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
-+ E1000_WRITE_FLUSH(hw);
- E1000_WRITE_REG_ARRAY(hw, RA, (i << 1) + 1, 0);
-+ E1000_WRITE_FLUSH(hw);
- }
- }
-
- /* clear the old settings from the multicast hash table */
-
-- for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++)
-+ for (i = 0; i < mta_reg_count; i++) {
- E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
-+ E1000_WRITE_FLUSH(hw);
-+ }
-
- /* load any remaining addresses into the hash table */
-
-- for(; mc_ptr; mc_ptr = mc_ptr->next) {
-+ for (; mc_ptr; mc_ptr = mc_ptr->next) {
- hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr);
- e1000_mta_set(hw, hash_value);
- }
-
-- if(hw->mac_type == e1000_82542_rev2_0)
-+ if (hw->mac_type == e1000_82542_rev2_0)
- e1000_leave_82542_rst(adapter);
- }
-
--/* need to wait a few seconds after link up to get diagnostic information from the phy */
-+/* Need to wait a few seconds after link up to get diagnostic information from
-+ * the phy */
-
- static void
- e1000_update_phy_info(unsigned long data)
-@@ -1333,8 +2418,8 @@ e1000_82547_tx_fifo_stall(unsigned long
- struct net_device *netdev = adapter->netdev;
- uint32_t tctl;
-
-- if(atomic_read(&adapter->tx_fifo_stall)) {
-- if((E1000_READ_REG(&adapter->hw, TDT) ==
-+ if (atomic_read(&adapter->tx_fifo_stall)) {
-+ if ((E1000_READ_REG(&adapter->hw, TDT) ==
- E1000_READ_REG(&adapter->hw, TDH)) &&
- (E1000_READ_REG(&adapter->hw, TDFT) ==
- E1000_READ_REG(&adapter->hw, TDFH)) &&
-@@ -1365,28 +2450,42 @@ e1000_82547_tx_fifo_stall(unsigned long
-
- /**
- * e1000_watchdog - Timer Call-back
-- * @data: pointer to netdev cast into an unsigned long
-+ * @data: pointer to adapter cast into an unsigned long
- **/
--
- static void
- e1000_watchdog(unsigned long data)
- {
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
- struct net_device *netdev = adapter->netdev;
-- struct e1000_desc_ring *txdr = &adapter->tx_ring;
-- unsigned int i;
-- uint32_t link;
--
-- e1000_check_for_link(&adapter->hw);
-+ struct e1000_tx_ring *txdr = adapter->tx_ring;
-+ uint32_t link, tctl;
-+ int32_t ret_val;
-+
-+ ret_val = e1000_check_for_link(&adapter->hw);
-+ if ((ret_val == E1000_ERR_PHY) &&
-+ (adapter->hw.phy_type == e1000_phy_igp_3) &&
-+ (E1000_READ_REG(&adapter->hw, CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
-+ /* See e1000_kumeran_lock_loss_workaround() */
-+ DPRINTK(LINK, INFO,
-+ "Gigabit has been disabled, downgrading speed\n");
-+ }
-+ if (adapter->hw.mac_type == e1000_82573) {
-+ e1000_enable_tx_pkt_filtering(&adapter->hw);
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)
-+ e1000_update_mng_vlan(adapter);
-+#endif
-+ }
-
-- if((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-+ if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
- !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE))
- link = !adapter->hw.serdes_link_down;
- else
- link = E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU;
-
-- if(link) {
-- if(!netif_carrier_ok(netdev)) {
-+ if (link) {
-+ if (!netif_carrier_ok(netdev)) {
-+ boolean_t txb2b = 1;
- e1000_get_speed_and_duplex(&adapter->hw,
- &adapter->link_speed,
- &adapter->link_duplex);
-@@ -1396,19 +2495,83 @@ e1000_watchdog(unsigned long data)
- adapter->link_duplex == FULL_DUPLEX ?
- "Full Duplex" : "Half Duplex");
-
-+ /* tweak tx_queue_len according to speed/duplex
-+ * and adjust the timeout factor */
-+ netdev->tx_queue_len = adapter->tx_queue_len;
-+ adapter->tx_timeout_factor = 1;
-+ switch (adapter->link_speed) {
-+ case SPEED_10:
-+ txb2b = 0;
-+ netdev->tx_queue_len = 10;
-+ adapter->tx_timeout_factor = 8;
-+ break;
-+ case SPEED_100:
-+ txb2b = 0;
-+ netdev->tx_queue_len = 100;
-+ /* maybe add some timeout factor ? */
-+ break;
-+ }
-+
-+ if ((adapter->hw.mac_type == e1000_82571 ||
-+ adapter->hw.mac_type == e1000_82572) &&
-+ txb2b == 0) {
-+#define SPEED_MODE_BIT (1 << 21)
-+ uint32_t tarc0;
-+ tarc0 = E1000_READ_REG(&adapter->hw, TARC0);
-+ tarc0 &= ~SPEED_MODE_BIT;
-+ E1000_WRITE_REG(&adapter->hw, TARC0, tarc0);
-+ }
-+
-+#ifdef NETIF_F_TSO
-+ /* disable TSO for pcie and 10/100 speeds, to avoid
-+ * some hardware issues */
-+ if (!adapter->tso_force &&
-+ adapter->hw.bus_type == e1000_bus_type_pci_express){
-+ switch (adapter->link_speed) {
-+ case SPEED_10:
-+ case SPEED_100:
-+ DPRINTK(PROBE,INFO,
-+ "10/100 speed: disabling TSO\n");
-+ netdev->features &= ~NETIF_F_TSO;
-+ break;
-+ case SPEED_1000:
-+ netdev->features |= NETIF_F_TSO;
-+ break;
-+ default:
-+ /* oops */
-+ break;
-+ }
-+ }
-+#endif
-+
-+ /* enable transmits in the hardware, need to do this
-+ * after setting TARC0 */
-+ tctl = E1000_READ_REG(&adapter->hw, TCTL);
-+ tctl |= E1000_TCTL_EN;
-+ E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
-+
- netif_carrier_on(netdev);
- netif_wake_queue(netdev);
- mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
- adapter->smartspeed = 0;
- }
- } else {
-- if(netif_carrier_ok(netdev)) {
-+ if (netif_carrier_ok(netdev)) {
- adapter->link_speed = 0;
- adapter->link_duplex = 0;
- DPRINTK(LINK, INFO, "NIC Link is Down\n");
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ);
-+
-+ /* 80003ES2LAN workaround--
-+ * For packet buffer work-around on link down event;
-+ * disable receives in the ISR and
-+ * reset device here in the watchdog
-+ */
-+ if (adapter->hw.mac_type == e1000_80003es2lan)
-+ /* reset device */
-+ schedule_work(&adapter->reset_task);
- }
-
- e1000_smartspeed(adapter);
-@@ -1420,7 +2583,7 @@ e1000_watchdog(unsigned long data)
- adapter->tpt_old = adapter->stats.tpt;
- adapter->hw.collision_delta = adapter->stats.colc - adapter->colc_old;
- adapter->colc_old = adapter->stats.colc;
--
-+
- adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
- adapter->gorcl_old = adapter->stats.gorcl;
- adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
-@@ -1428,23 +2591,24 @@ e1000_watchdog(unsigned long data)
-
- e1000_update_adaptive(&adapter->hw);
-
-- if(!netif_carrier_ok(netdev)) {
-- if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
-+ if (!netif_carrier_ok(netdev)) {
-+ if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
- /* We've lost link, so the controller stops DMA,
- * but we've got queued Tx work that's never going
- * to get done, so reset controller to flush Tx.
- * (Do the reset outside of interrupt context). */
-- schedule_work(&adapter->tx_timeout_task);
-+ adapter->tx_timeout_count++;
-+ schedule_work(&adapter->reset_task);
- }
- }
-
- /* Dynamic mode for Interrupt Throttle Rate (ITR) */
-- if(adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
-+ if (adapter->hw.mac_type >= e1000_82540 && adapter->itr == 1) {
- /* Symmetric Tx/Rx gets a reduced ITR=2000; Total
- * asymmetrical Tx or Rx gets ITR=8000; everyone
- * else is between 2000-8000. */
- uint32_t goc = (adapter->gotcl + adapter->gorcl) / 10000;
-- uint32_t dif = (adapter->gotcl > adapter->gorcl ?
-+ uint32_t dif = (adapter->gotcl > adapter->gorcl ?
- adapter->gotcl - adapter->gorcl :
- adapter->gorcl - adapter->gotcl) / 10000;
- uint32_t itr = goc > 0 ? (dif * 6000 / goc + 2000) : 8000;
-@@ -1454,12 +2618,13 @@ e1000_watchdog(unsigned long data)
- /* Cause software interrupt to ensure rx ring is cleaned */
- E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0);
-
-- /* Early detection of hung controller */
-- i = txdr->next_to_clean;
-- if(txdr->buffer_info[i].dma &&
-- time_after(jiffies, txdr->buffer_info[i].time_stamp + HZ) &&
-- !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF))
-- netif_stop_queue(netdev);
-+ /* Force detection of hung controller every watchdog period */
-+ adapter->detect_tx_hung = TRUE;
-+
-+ /* With 82571 controllers, LAA may be overwritten due to controller
-+ * reset from the other port. Set the appropriate LAA in RAR[0] */
-+ if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
-+ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
-
- /* Reset the timer */
- mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-@@ -1468,37 +2633,67 @@ e1000_watchdog(unsigned long data)
- #define E1000_TX_FLAGS_CSUM 0x00000001
- #define E1000_TX_FLAGS_VLAN 0x00000002
- #define E1000_TX_FLAGS_TSO 0x00000004
-+#define E1000_TX_FLAGS_IPV4 0x00000008
- #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000
- #define E1000_TX_FLAGS_VLAN_SHIFT 16
-
--static inline boolean_t
--e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
-+static int
-+e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-+ struct sk_buff *skb)
- {
- #ifdef NETIF_F_TSO
- struct e1000_context_desc *context_desc;
-+ struct e1000_buffer *buffer_info;
- unsigned int i;
-+ uint32_t cmd_length = 0;
-+ uint16_t ipcse = 0, tucse, mss;
- uint8_t ipcss, ipcso, tucss, tucso, hdr_len;
-- uint16_t ipcse, tucse, mss;
-+ int err;
-+
-+ if (skb_shinfo(skb)->tso_size) {
-+ if (skb_header_cloned(skb)) {
-+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
-+ if (err)
-+ return err;
-+ }
-
-- if(skb_shinfo(skb)->tso_size) {
- hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
- mss = skb_shinfo(skb)->tso_size;
-- skb->nh.iph->tot_len = 0;
-- skb->nh.iph->check = 0;
-- skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr,
-- skb->nh.iph->daddr,
-- 0,
-- IPPROTO_TCP,
-- 0);
-+ if (skb->protocol == htons(ETH_P_IP)) {
-+ skb->nh.iph->tot_len = 0;
-+ skb->nh.iph->check = 0;
-+ skb->h.th->check =
-+ ~csum_tcpudp_magic(skb->nh.iph->saddr,
-+ skb->nh.iph->daddr,
-+ 0,
-+ IPPROTO_TCP,
-+ 0);
-+ cmd_length = E1000_TXD_CMD_IP;
-+ ipcse = skb->h.raw - skb->data - 1;
-+#ifdef NETIF_F_TSO_IPV6
-+ } else if (skb->protocol == ntohs(ETH_P_IPV6)) {
-+ skb->nh.ipv6h->payload_len = 0;
-+ skb->h.th->check =
-+ ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
-+ &skb->nh.ipv6h->daddr,
-+ 0,
-+ IPPROTO_TCP,
-+ 0);
-+ ipcse = 0;
-+#endif
-+ }
- ipcss = skb->nh.raw - skb->data;
- ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data;
-- ipcse = skb->h.raw - skb->data - 1;
- tucss = skb->h.raw - skb->data;
- tucso = (void *)&(skb->h.th->check) - (void *)skb->data;
- tucse = 0;
-
-- i = adapter->tx_ring.next_to_use;
-- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
-+ cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
-+ E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
-+
-+ i = tx_ring->next_to_use;
-+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
-+ buffer_info = &tx_ring->buffer_info[i];
-
- context_desc->lower_setup.ip_fields.ipcss = ipcss;
- context_desc->lower_setup.ip_fields.ipcso = ipcso;
-@@ -1508,13 +2703,12 @@ e1000_tso(struct e1000_adapter *adapter,
- context_desc->upper_setup.tcp_fields.tucse = cpu_to_le16(tucse);
- context_desc->tcp_seg_setup.fields.mss = cpu_to_le16(mss);
- context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
-- context_desc->cmd_and_length = cpu_to_le32(
-- E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
-- E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP |
-- (skb->len - (hdr_len)));
-+ context_desc->cmd_and_length = cpu_to_le32(cmd_length);
-+
-+ buffer_info->time_stamp = jiffies;
-
-- if(++i == adapter->tx_ring.count) i = 0;
-- adapter->tx_ring.next_to_use = i;
-+ if (++i == tx_ring->count) i = 0;
-+ tx_ring->next_to_use = i;
-
- return TRUE;
- }
-@@ -1523,28 +2717,32 @@ e1000_tso(struct e1000_adapter *adapter,
- return FALSE;
- }
-
--static inline boolean_t
--e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
-+static boolean_t
-+e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-+ struct sk_buff *skb)
- {
- struct e1000_context_desc *context_desc;
-+ struct e1000_buffer *buffer_info;
- unsigned int i;
-- uint8_t css, cso;
-+ uint8_t css;
-
-- if(skb->ip_summed == CHECKSUM_HW) {
-+ if (likely(skb->ip_summed == CHECKSUM_HW)) {
- css = skb->h.raw - skb->data;
-- cso = (skb->h.raw + skb->csum) - skb->data;
-
-- i = adapter->tx_ring.next_to_use;
-- context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
-+ i = tx_ring->next_to_use;
-+ buffer_info = &tx_ring->buffer_info[i];
-+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
-
- context_desc->upper_setup.tcp_fields.tucss = css;
-- context_desc->upper_setup.tcp_fields.tucso = cso;
-+ context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
- context_desc->upper_setup.tcp_fields.tucse = 0;
- context_desc->tcp_seg_setup.data = 0;
- context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
-
-- if(++i == adapter->tx_ring.count) i = 0;
-- adapter->tx_ring.next_to_use = i;
-+ buffer_info->time_stamp = jiffies;
-+
-+ if (unlikely(++i == tx_ring->count)) i = 0;
-+ tx_ring->next_to_use = i;
-
- return TRUE;
- }
-@@ -1555,35 +2753,54 @@ e1000_tx_csum(struct e1000_adapter *adap
- #define E1000_MAX_TXD_PWR 12
- #define E1000_MAX_DATA_PER_TXD (1<<E1000_MAX_TXD_PWR)
-
--static inline int
--e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
-- unsigned int first, unsigned int max_per_txd,
-- unsigned int nr_frags, unsigned int mss)
-+static int
-+e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-+ struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
-+ unsigned int nr_frags, unsigned int mss)
- {
-- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
- struct e1000_buffer *buffer_info;
- unsigned int len = skb->len;
- unsigned int offset = 0, size, count = 0, i;
-+#ifdef MAX_SKB_FRAGS
- unsigned int f;
- len -= skb->data_len;
--
-+#endif
-
- i = tx_ring->next_to_use;
-
-- while(len) {
-+ while (len) {
- buffer_info = &tx_ring->buffer_info[i];
- size = min(len, max_per_txd);
- #ifdef NETIF_F_TSO
-+ /* Workaround for Controller erratum --
-+ * descriptor for non-tso packet in a linear SKB that follows a
-+ * tso gets written back prematurely before the data is fully
-+ * DMA'd to the controller */
-+ if (!skb->data_len && tx_ring->last_tx_tso &&
-+ !skb_shinfo(skb)->tso_size) {
-+ tx_ring->last_tx_tso = 0;
-+ size -= 4;
-+ }
-+
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
-- if(mss && !nr_frags && size == len && size > 8)
-+ if (unlikely(mss && !nr_frags && size == len && size > 8))
- size -= 4;
- #endif
-+ /* work-around for errata 10 and it applies
-+ * to all controllers in PCI-X mode
-+ * The fix is to make sure that the first descriptor of a
-+ * packet is smaller than 2048 - 16 - 16 (or 2016) bytes
-+ */
-+ if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
-+ (size > 2015) && count == 0))
-+ size = 2015;
-+
- /* Workaround for potential 82544 hang in PCI-X. Avoid
- * terminating buffers within evenly-aligned dwords. */
-- if(adapter->pcix_82544 &&
-+ if (unlikely(adapter->pcix_82544 &&
- !((unsigned long)(skb->data + offset + size - 1) & 4) &&
-- size > 4)
-+ size > 4))
- size -= 4;
-
- buffer_info->length = size;
-@@ -1597,31 +2814,32 @@ e1000_tx_map(struct e1000_adapter *adapt
- len -= size;
- offset += size;
- count++;
-- if(++i == tx_ring->count) i = 0;
-+ if (unlikely(++i == tx_ring->count)) i = 0;
- }
-
-- for(f = 0; f < nr_frags; f++) {
-+#ifdef MAX_SKB_FRAGS
-+ for (f = 0; f < nr_frags; f++) {
- struct skb_frag_struct *frag;
-
- frag = &skb_shinfo(skb)->frags[f];
- len = frag->size;
- offset = frag->page_offset;
-
-- while(len) {
-+ while (len) {
- buffer_info = &tx_ring->buffer_info[i];
- size = min(len, max_per_txd);
- #ifdef NETIF_F_TSO
- /* Workaround for premature desc write-backs
- * in TSO mode. Append 4-byte sentinel desc */
-- if(mss && f == (nr_frags-1) && size == len && size > 8)
-+ if (unlikely(mss && f == (nr_frags-1) && size == len && size > 8))
- size -= 4;
- #endif
- /* Workaround for potential 82544 hang in PCI-X.
- * Avoid terminating buffers within evenly-aligned
- * dwords. */
-- if(adapter->pcix_82544 &&
-+ if (unlikely(adapter->pcix_82544 &&
- !((unsigned long)(frag->page+offset+size-1) & 4) &&
-- size > 4)
-+ size > 4))
- size -= 4;
-
- buffer_info->length = size;
-@@ -1636,51 +2854,56 @@ e1000_tx_map(struct e1000_adapter *adapt
- len -= size;
- offset += size;
- count++;
-- if(++i == tx_ring->count) i = 0;
-+ if (unlikely(++i == tx_ring->count)) i = 0;
- }
- }
-+#endif
-+
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
- tx_ring->buffer_info[i].skb = skb;
- tx_ring->buffer_info[first].next_to_watch = i;
--
-+
- return count;
- }
-
--static inline void
--e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
-+static void
-+e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
-+ int tx_flags, int count)
- {
-- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
- struct e1000_tx_desc *tx_desc = NULL;
- struct e1000_buffer *buffer_info;
- uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
- unsigned int i;
-
-- if(tx_flags & E1000_TX_FLAGS_TSO) {
-+ if (likely(tx_flags & E1000_TX_FLAGS_TSO)) {
- txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D |
- E1000_TXD_CMD_TSE;
-- txd_upper |= (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8;
-+ txd_upper |= E1000_TXD_POPTS_TXSM << 8;
-+
-+ if (likely(tx_flags & E1000_TX_FLAGS_IPV4))
-+ txd_upper |= E1000_TXD_POPTS_IXSM << 8;
- }
-
-- if(tx_flags & E1000_TX_FLAGS_CSUM) {
-+ if (likely(tx_flags & E1000_TX_FLAGS_CSUM)) {
- txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D;
- txd_upper |= E1000_TXD_POPTS_TXSM << 8;
- }
-
-- if(tx_flags & E1000_TX_FLAGS_VLAN) {
-+ if (unlikely(tx_flags & E1000_TX_FLAGS_VLAN)) {
- txd_lower |= E1000_TXD_CMD_VLE;
- txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK);
- }
-
- i = tx_ring->next_to_use;
-
-- while(count--) {
-+ while (count--) {
- buffer_info = &tx_ring->buffer_info[i];
- tx_desc = E1000_TX_DESC(*tx_ring, i);
- tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
- tx_desc->lower.data =
- cpu_to_le32(txd_lower | buffer_info->length);
- tx_desc->upper.data = cpu_to_le32(txd_upper);
-- if(++i == tx_ring->count) i = 0;
-+ if (unlikely(++i == tx_ring->count)) i = 0;
- }
-
- tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
-@@ -1692,7 +2915,7 @@ e1000_tx_queue(struct e1000_adapter *ada
- wmb();
-
- tx_ring->next_to_use = i;
-- E1000_WRITE_REG(&adapter->hw, TDT, i);
-+ writel(i, adapter->hw.hw_addr + tx_ring->tdt);
- }
-
- /**
-@@ -1707,7 +2930,7 @@ e1000_tx_queue(struct e1000_adapter *ada
- #define E1000_FIFO_HDR 0x10
- #define E1000_82547_PAD_LEN 0x3E0
-
--static inline int
-+static int
- e1000_82547_fifo_workaround(struct e1000_adapter *adapter, struct sk_buff *skb)
- {
- uint32_t fifo_space = adapter->tx_fifo_size - adapter->tx_fifo_head;
-@@ -1715,113 +2938,250 @@ e1000_82547_fifo_workaround(struct e1000
-
- E1000_ROUNDUP(skb_fifo_len, E1000_FIFO_HDR);
-
-- if(adapter->link_duplex != HALF_DUPLEX)
-+ if (adapter->link_duplex != HALF_DUPLEX)
- goto no_fifo_stall_required;
-
-- if(atomic_read(&adapter->tx_fifo_stall))
-+ if (atomic_read(&adapter->tx_fifo_stall))
- return 1;
-
-- if(skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
-+ if (skb_fifo_len >= (E1000_82547_PAD_LEN + fifo_space)) {
- atomic_set(&adapter->tx_fifo_stall, 1);
- return 1;
- }
-
- no_fifo_stall_required:
- adapter->tx_fifo_head += skb_fifo_len;
-- if(adapter->tx_fifo_head >= adapter->tx_fifo_size)
-+ if (adapter->tx_fifo_head >= adapter->tx_fifo_size)
- adapter->tx_fifo_head -= adapter->tx_fifo_size;
- return 0;
- }
-
--#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
-+#define MINIMUM_DHCP_PACKET_SIZE 282
-+static int
-+e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb)
-+{
-+ struct e1000_hw *hw = &adapter->hw;
-+ uint16_t length, offset;
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (vlan_tx_tag_present(skb)) {
-+ if (!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) &&
-+ ( adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) )
-+ return 0;
-+ }
-+#endif
-+ if (skb->len > MINIMUM_DHCP_PACKET_SIZE) {
-+ struct ethhdr *eth = (struct ethhdr *) skb->data;
-+ if ((htons(ETH_P_IP) == eth->h_proto)) {
-+ const struct iphdr *ip =
-+ (struct iphdr *)((uint8_t *)skb->data+14);
-+ if (IPPROTO_UDP == ip->protocol) {
-+ struct udphdr *udp =
-+ (struct udphdr *)((uint8_t *)ip +
-+ (ip->ihl << 2));
-+ if (ntohs(udp->dest) == 67) {
-+ offset = (uint8_t *)udp + 8 - skb->data;
-+ length = skb->len - offset;
-+
-+ return e1000_mng_write_dhcp_info(hw,
-+ (uint8_t *)udp + 8,
-+ length);
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
- static int
- e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+ struct e1000_tx_ring *tx_ring;
- unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
- unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
- unsigned int tx_flags = 0;
-- unsigned long flags;
- unsigned int len = skb->len;
-- int count = 0;
-- unsigned int mss = 0;
-+ unsigned long flags;
- unsigned int nr_frags = 0;
-+ unsigned int mss = 0;
-+ int count = 0;
-+ int tso;
-+#ifdef MAX_SKB_FRAGS
- unsigned int f;
-- nr_frags = skb_shinfo(skb)->nr_frags;
- len -= skb->data_len;
-- if(skb->len <= 0) {
-+#endif
-+
-+ /* This goes back to the question of how to logically map a tx queue
-+ * to a flow. Right now, performance is impacted slightly negatively
-+ * if using multiple tx queues. If the stack breaks away from a
-+ * single qdisc implementation, we can look at this again. */
-+ tx_ring = adapter->tx_ring;
-+
-+ if (unlikely(skb->len <= 0)) {
- dev_kfree_skb_any(skb);
-- return 0;
-+ return NETDEV_TX_OK;
- }
-
- #ifdef NETIF_F_TSO
- mss = skb_shinfo(skb)->tso_size;
-- /* The controller does a simple calculation to
-+ /* The controller does a simple calculation to
- * make sure there is enough room in the FIFO before
- * initiating the DMA for each buffer. The calc is:
- * 4 = ceil(buffer len/mss). To make sure we don't
- * overrun the FIFO, adjust the max buffer len if mss
- * drops. */
-- if(mss) {
-+ if (mss) {
-+ uint8_t hdr_len;
- max_per_txd = min(mss << 2, max_per_txd);
- max_txd_pwr = fls(max_per_txd) - 1;
-+
-+ /* TSO Workaround for 82571/2/3 Controllers -- if skb->data
-+ * points to just header, pull a few bytes of payload from
-+ * frags into skb->data */
-+ hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
-+ if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
-+ switch (adapter->hw.mac_type) {
-+ unsigned int pull_size;
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_82573:
-+ case e1000_ich8lan:
-+ pull_size = min((unsigned int)4, skb->data_len);
-+ if (!__pskb_pull_tail(skb, pull_size)) {
-+ DPRINTK(DRV, ERR,
-+ "__pskb_pull_tail failed.\n");
-+ dev_kfree_skb_any(skb);
-+ return NETDEV_TX_OK;
-+ }
-+ len = skb->len - skb->data_len;
-+ break;
-+ default:
-+ /* do nothing */
-+ break;
-+ }
-+ }
- }
-- if((mss) || (skb->ip_summed == CHECKSUM_HW))
-+
-+ /* reserve a descriptor for the offload context */
-+ if ((mss) || (skb->ip_summed == CHECKSUM_HW))
- count++;
-- count++; /*for sentinel desc*/
-+ count++;
- #else
-- if(skb->ip_summed == CHECKSUM_HW)
-+ if (skb->ip_summed == CHECKSUM_HW)
-+ count++;
-+#endif
-+
-+#ifdef NETIF_F_TSO
-+ /* Controller Erratum workaround */
-+ if (!skb->data_len && tx_ring->last_tx_tso &&
-+ !skb_shinfo(skb)->tso_size)
- count++;
- #endif
-
- count += TXD_USE_COUNT(len, max_txd_pwr);
-- if(adapter->pcix_82544)
-+
-+ if (adapter->pcix_82544)
- count++;
-
-+ /* work-around for errata 10 and it applies to all controllers
-+ * in PCI-X mode, so add one more descriptor to the count
-+ */
-+ if (unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) &&
-+ (len > 2015)))
-+ count++;
-+
-+#ifdef MAX_SKB_FRAGS
- nr_frags = skb_shinfo(skb)->nr_frags;
-- for(f = 0; f < nr_frags; f++)
-+ for (f = 0; f < nr_frags; f++)
- count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size,
-- max_txd_pwr);
-- if(adapter->pcix_82544)
-+ max_txd_pwr);
-+ if (adapter->pcix_82544)
- count += nr_frags;
--
-- spin_lock_irqsave(&adapter->tx_lock, flags);
-- /* need: count + 2 desc gap to keep tail from touching
-+
-+#endif
-+
-+ if (adapter->hw.tx_pkt_filtering &&
-+ (adapter->hw.mac_type == e1000_82573))
-+ e1000_transfer_dhcp_info(adapter, skb);
-+
-+#ifdef NETIF_F_LLTX
-+ local_irq_save(flags);
-+ if (!spin_trylock(&tx_ring->tx_lock)) {
-+ /* Collision - tell upper layer to requeue */
-+ local_irq_restore(flags);
-+ return NETDEV_TX_LOCKED;
-+ }
-+#else
-+ spin_lock_irqsave(&tx_ring->tx_lock, flags);
-+#endif
-+
-+ /* need: count + 2 desc gap to keep tail from touching
- * head, otherwise try next time */
-- if(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2 ) {
-+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
- netif_stop_queue(netdev);
-- spin_unlock_irqrestore(&adapter->tx_lock, flags);
-- return 1;
-+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-+ return NETDEV_TX_BUSY;
- }
-- spin_unlock_irqrestore(&adapter->tx_lock, flags);
-
-- if(adapter->hw.mac_type == e1000_82547) {
-- if(e1000_82547_fifo_workaround(adapter, skb)) {
-+ if (unlikely(adapter->hw.mac_type == e1000_82547)) {
-+ if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
- netif_stop_queue(netdev);
- mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
-- return 1;
-+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-+ return NETDEV_TX_BUSY;
- }
- }
-
-- if(adapter->vlgrp && vlan_tx_tag_present(skb)) {
-+#ifndef NETIF_F_LLTX
-+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-+
-+#endif
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (unlikely(adapter->vlgrp && vlan_tx_tag_present(skb))) {
- tx_flags |= E1000_TX_FLAGS_VLAN;
- tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
- }
-+#endif
-+
-+ first = tx_ring->next_to_use;
-+
-+ tso = e1000_tso(adapter, tx_ring, skb);
-+ if (tso < 0) {
-+ dev_kfree_skb_any(skb);
-+#ifdef NETIF_F_LLTX
-+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-+#endif
-+ return NETDEV_TX_OK;
-+ }
-
-- first = adapter->tx_ring.next_to_use;
--
-- if(e1000_tso(adapter, skb))
-+ if (likely(tso)) {
-+ tx_ring->last_tx_tso = 1;
- tx_flags |= E1000_TX_FLAGS_TSO;
-- else if(e1000_tx_csum(adapter, skb))
-+ } else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
- tx_flags |= E1000_TX_FLAGS_CSUM;
-
-- e1000_tx_queue(adapter,
-- e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
-- tx_flags);
-+ /* Old method was to assume IPv4 packet by default if TSO was enabled.
-+ * 82571 hardware supports TSO capabilities for IPv6 as well...
-+ * no longer assume, we must. */
-+ if (likely(skb->protocol == htons(ETH_P_IP)))
-+ tx_flags |= E1000_TX_FLAGS_IPV4;
-+
-+ e1000_tx_queue(adapter, tx_ring, tx_flags,
-+ e1000_tx_map(adapter, tx_ring, skb, first,
-+ max_per_txd, nr_frags, mss));
-
- netdev->trans_start = jiffies;
-
-- return 0;
-+#ifdef NETIF_F_LLTX
-+ /* Make sure there is space in the ring for the next send. */
-+ if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
-+ netif_stop_queue(netdev);
-+
-+ spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-+#endif
-+ return NETDEV_TX_OK;
- }
-
- /**
-@@ -1832,21 +3192,19 @@ e1000_xmit_frame(struct sk_buff *skb, st
- static void
- e1000_tx_timeout(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
- /* Do the reset outside of interrupt context */
-- schedule_work(&adapter->tx_timeout_task);
-+ adapter->tx_timeout_count++;
-+ schedule_work(&adapter->reset_task);
- }
-
- static void
--e1000_tx_timeout_task(struct net_device *netdev)
-+e1000_reset_task(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
-- netif_device_detach(netdev);
-- e1000_down(adapter);
-- e1000_up(adapter);
-- netif_device_attach(netdev);
-+ e1000_reinit_locked(adapter);
- }
-
- /**
-@@ -1860,9 +3218,9 @@ e1000_tx_timeout_task(struct net_device
- static struct net_device_stats *
- e1000_get_stats(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-
-- e1000_update_stats(adapter);
-+ /* only return the current stats */
- return &adapter->net_stats;
- }
-
-@@ -1877,40 +3235,84 @@ e1000_get_stats(struct net_device *netde
- static int
- e1000_change_mtu(struct net_device *netdev, int new_mtu)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-- int old_mtu = adapter->rx_buffer_len;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
-+ uint16_t eeprom_data = 0;
-
-- if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
-- (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-+ if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
-+ (max_frame > MAX_JUMBO_FRAME_SIZE)) {
- DPRINTK(PROBE, ERR, "Invalid MTU setting\n");
- return -EINVAL;
- }
-
-- if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) {
-- adapter->rx_buffer_len = E1000_RXBUFFER_2048;
--
-- } else if(adapter->hw.mac_type < e1000_82543) {
-- DPRINTK(PROBE, ERR, "Jumbo Frames not supported on 82542\n");
-- return -EINVAL;
-+ /* Adapter-specific max frame size limits. */
-+ switch (adapter->hw.mac_type) {
-+ case e1000_undefined ... e1000_82542_rev2_1:
-+ case e1000_ich8lan:
-+ if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
-+ DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n");
-+ return -EINVAL;
-+ }
-+ break;
-+ case e1000_82573:
-+ /* only enable jumbo frames if ASPM is disabled completely
-+ * this means both bits must be zero in 0x1A bits 3:2 */
-+ e1000_read_eeprom(&adapter->hw, EEPROM_INIT_3GIO_3, 1,
-+ &eeprom_data);
-+ if (eeprom_data & EEPROM_WORD1A_ASPM_MASK) {
-+ if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
-+ DPRINTK(PROBE, ERR,
-+ "Jumbo Frames not supported.\n");
-+ return -EINVAL;
-+ }
-+ break;
-+ }
-+ /* fall through to get support */
-+ case e1000_82571:
-+ case e1000_82572:
-+ case e1000_80003es2lan:
-+#define MAX_STD_JUMBO_FRAME_SIZE 9234
-+ if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-+ DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n");
-+ return -EINVAL;
-+ }
-+ break;
-+ default:
-+ /* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */
-+ break;
-+ }
-
-- } else if(max_frame <= E1000_RXBUFFER_4096) {
-+ /* NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
-+ * means we reserve 2 more, this pushes us to allocate from the next
-+ * larger slab size
-+ * i.e. RXBUFFER_2048 --> size-4096 slab */
-+
-+ if (max_frame <= E1000_RXBUFFER_256)
-+ adapter->rx_buffer_len = E1000_RXBUFFER_256;
-+ else if (max_frame <= E1000_RXBUFFER_512)
-+ adapter->rx_buffer_len = E1000_RXBUFFER_512;
-+ else if (max_frame <= E1000_RXBUFFER_1024)
-+ adapter->rx_buffer_len = E1000_RXBUFFER_1024;
-+ else if (max_frame <= E1000_RXBUFFER_2048)
-+ adapter->rx_buffer_len = E1000_RXBUFFER_2048;
-+ else if (max_frame <= E1000_RXBUFFER_4096)
- adapter->rx_buffer_len = E1000_RXBUFFER_4096;
--
-- } else if(max_frame <= E1000_RXBUFFER_8192) {
-+ else if (max_frame <= E1000_RXBUFFER_8192)
- adapter->rx_buffer_len = E1000_RXBUFFER_8192;
--
-- } else {
-+ else if (max_frame <= E1000_RXBUFFER_16384)
- adapter->rx_buffer_len = E1000_RXBUFFER_16384;
-- }
--
-- if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) {
-
-- e1000_down(adapter);
-- e1000_up(adapter);
-- }
-+ /* adjust allocation if LPE protects us, and we aren't using SBP */
-+ if (!adapter->hw.tbi_compatibility_on &&
-+ ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) ||
-+ (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE)))
-+ adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-
- netdev->mtu = new_mtu;
-+
-+ if (netif_running(netdev))
-+ e1000_reinit_locked(adapter);
-+
- adapter->hw.max_frame_size = max_frame;
-
- return 0;
-@@ -1944,14 +3346,15 @@ e1000_update_stats(struct e1000_adapter
- adapter->stats.bprc += E1000_READ_REG(hw, BPRC);
- adapter->stats.mprc += E1000_READ_REG(hw, MPRC);
- adapter->stats.roc += E1000_READ_REG(hw, ROC);
-+
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
- adapter->stats.prc64 += E1000_READ_REG(hw, PRC64);
- adapter->stats.prc127 += E1000_READ_REG(hw, PRC127);
- adapter->stats.prc255 += E1000_READ_REG(hw, PRC255);
- adapter->stats.prc511 += E1000_READ_REG(hw, PRC511);
- adapter->stats.prc1023 += E1000_READ_REG(hw, PRC1023);
- adapter->stats.prc1522 += E1000_READ_REG(hw, PRC1522);
--
-- /* the rest of the counters are only modified here */
-+ }
-
- adapter->stats.symerrs += E1000_READ_REG(hw, SYMERRS);
- adapter->stats.mpc += E1000_READ_REG(hw, MPC);
-@@ -1979,12 +3382,16 @@ e1000_update_stats(struct e1000_adapter
- adapter->stats.totl += E1000_READ_REG(hw, TOTL);
- adapter->stats.toth += E1000_READ_REG(hw, TOTH);
- adapter->stats.tpr += E1000_READ_REG(hw, TPR);
-+
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
- adapter->stats.ptc64 += E1000_READ_REG(hw, PTC64);
- adapter->stats.ptc127 += E1000_READ_REG(hw, PTC127);
- adapter->stats.ptc255 += E1000_READ_REG(hw, PTC255);
- adapter->stats.ptc511 += E1000_READ_REG(hw, PTC511);
- adapter->stats.ptc1023 += E1000_READ_REG(hw, PTC1023);
- adapter->stats.ptc1522 += E1000_READ_REG(hw, PTC1522);
-+ }
-+
- adapter->stats.mptc += E1000_READ_REG(hw, MPTC);
- adapter->stats.bptc += E1000_READ_REG(hw, BPTC);
-
-@@ -1995,7 +3402,7 @@ e1000_update_stats(struct e1000_adapter
- hw->collision_delta = E1000_READ_REG(hw, COLC);
- adapter->stats.colc += hw->collision_delta;
-
-- if(hw->mac_type >= e1000_82543) {
-+ if (hw->mac_type >= e1000_82543) {
- adapter->stats.algnerrc += E1000_READ_REG(hw, ALGNERRC);
- adapter->stats.rxerrc += E1000_READ_REG(hw, RXERRC);
- adapter->stats.tncrs += E1000_READ_REG(hw, TNCRS);
-@@ -2003,6 +3410,20 @@ e1000_update_stats(struct e1000_adapter
- adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC);
- adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC);
- }
-+ if (hw->mac_type > e1000_82547_rev_2) {
-+ adapter->stats.iac += E1000_READ_REG(hw, IAC);
-+ adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC);
-+
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
-+ adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC);
-+ adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC);
-+ adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC);
-+ adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC);
-+ adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC);
-+ adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC);
-+ adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC);
-+ }
-+ }
-
- /* Fill out the OS statistics structure */
-
-@@ -2015,15 +3436,16 @@ e1000_update_stats(struct e1000_adapter
-
- /* Rx Errors */
-
-+ /* RLEC on some newer hardware can be incorrect so build
-+ * our own version based on RUC and ROC */
- adapter->net_stats.rx_errors = adapter->stats.rxerrc +
- adapter->stats.crcerrs + adapter->stats.algnerrc +
-- adapter->stats.rlec + adapter->stats.rnbc +
-- adapter->stats.mpc + adapter->stats.cexterr;
-- adapter->net_stats.rx_dropped = adapter->stats.rnbc;
-- adapter->net_stats.rx_length_errors = adapter->stats.rlec;
-+ adapter->stats.ruc + adapter->stats.roc +
-+ adapter->stats.cexterr;
-+ adapter->net_stats.rx_length_errors = adapter->stats.ruc +
-+ adapter->stats.roc;
- adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
- adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
-- adapter->net_stats.rx_fifo_errors = adapter->stats.mpc;
- adapter->net_stats.rx_missed_errors = adapter->stats.mpc;
-
- /* Tx Errors */
-@@ -2038,14 +3460,14 @@ e1000_update_stats(struct e1000_adapter
-
- /* Phy Stats */
-
-- if(hw->media_type == e1000_media_type_copper) {
-- if((adapter->link_speed == SPEED_1000) &&
-+ if (hw->media_type == e1000_media_type_copper) {
-+ if ((adapter->link_speed == SPEED_1000) &&
- (!e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_tmp))) {
- phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
- adapter->phy_stats.idle_errors += phy_tmp;
- }
-
-- if((hw->mac_type <= e1000_82546) &&
-+ if ((hw->mac_type <= e1000_82546) &&
- (hw->phy_type == e1000_phy_m88) &&
- !e1000_read_phy_reg(hw, M88E1000_RX_ERR_CNTR, &phy_tmp))
- adapter->phy_stats.receive_errors += phy_tmp;
-@@ -2055,34 +3477,6 @@ e1000_update_stats(struct e1000_adapter
- }
-
- /**
-- * e1000_irq_disable - Mask off interrupt generation on the NIC
-- * @adapter: board private structure
-- **/
--
--static inline void
--e1000_irq_disable(struct e1000_adapter *adapter)
--{
-- atomic_inc(&adapter->irq_sem);
-- E1000_WRITE_REG(&adapter->hw, IMC, ~0);
-- E1000_WRITE_FLUSH(&adapter->hw);
-- synchronize_irq(adapter->pdev->irq);
--}
--
--/**
-- * e1000_irq_enable - Enable default interrupt generation settings
-- * @adapter: board private structure
-- **/
--
--static inline void
--e1000_irq_enable(struct e1000_adapter *adapter)
--{
-- if(atomic_dec_and_test(&adapter->irq_sem)) {
-- E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK);
-- E1000_WRITE_FLUSH(&adapter->hw);
-- }
--}
--
--/**
- * e1000_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
-@@ -2093,37 +3487,99 @@ static irqreturn_t
- e1000_intr(int irq, void *data, struct pt_regs *regs)
- {
- struct net_device *netdev = data;
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct e1000_hw *hw = &adapter->hw;
-- uint32_t icr = E1000_READ_REG(&adapter->hw, ICR);
-+ uint32_t rctl, icr = E1000_READ_REG(hw, ICR);
- #ifndef CONFIG_E1000_NAPI
-- unsigned int i;
-+ int i;
-+#else
-+ /* Interrupt Auto-Mask...upon reading ICR,
-+ * interrupts are masked. No need for the
-+ * IMC write, but it does mean we should
-+ * account for it ASAP. */
-+ if (likely(hw->mac_type >= e1000_82571))
-+ atomic_inc(&adapter->irq_sem);
- #endif
-
-- if(!icr)
-+ if (unlikely(!icr)) {
-+#ifdef CONFIG_E1000_NAPI
-+ if (hw->mac_type >= e1000_82571)
-+ e1000_irq_enable(adapter);
-+#endif
- return IRQ_NONE; /* Not our interrupt */
-+ }
-
-- if(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
-+ if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
- hw->get_link_status = 1;
-+ /* 80003ES2LAN workaround--
-+ * For packet buffer work-around on link down event;
-+ * disable receives here in the ISR and
-+ * reset adapter in watchdog
-+ */
-+ if (netif_carrier_ok(netdev) &&
-+ (adapter->hw.mac_type == e1000_80003es2lan)) {
-+ /* disable receives */
-+ rctl = E1000_READ_REG(hw, RCTL);
-+ E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
-+ }
- mod_timer(&adapter->watchdog_timer, jiffies);
- }
-
- #ifdef CONFIG_E1000_NAPI
-- if(netif_rx_schedule_prep(netdev)) {
--
-- /* Disable interrupts and register for poll. The flush
-- of the posted write is intentionally left out.
-- */
--
-+ if (unlikely(hw->mac_type < e1000_82571)) {
- atomic_inc(&adapter->irq_sem);
- E1000_WRITE_REG(hw, IMC, ~0);
-- __netif_rx_schedule(netdev);
-+ E1000_WRITE_FLUSH(hw);
- }
-+ if (likely(netif_rx_schedule_prep(netdev)))
-+ __netif_rx_schedule(netdev);
-+ else
-+ e1000_irq_enable(adapter);
- #else
-- for(i = 0; i < E1000_MAX_INTR; i++)
-- if(!e1000_clean_rx_irq(adapter) &
-- !e1000_clean_tx_irq(adapter))
-+ /* Writing IMC and IMS is needed for 82547.
-+ * Due to Hub Link bus being occupied, an interrupt
-+ * de-assertion message is not able to be sent.
-+ * When an interrupt assertion message is generated later,
-+ * two messages are re-ordered and sent out.
-+ * That causes APIC to think 82547 is in de-assertion
-+ * state, while 82547 is in assertion state, resulting
-+ * in dead lock. Writing IMC forces 82547 into
-+ * de-assertion state.
-+ */
-+ if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) {
-+ atomic_inc(&adapter->irq_sem);
-+ E1000_WRITE_REG(hw, IMC, ~0);
-+ }
-+
-+ for (i = 0; i < E1000_MAX_INTR; i++)
-+ if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
-+ !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
- break;
-+
-+ if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
-+ e1000_irq_enable(adapter);
-+
-+#endif
-+#ifdef E1000_COUNT_ICR
-+ adapter->icr_txdw += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_txqe += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_lsc += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_rxseq += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_rxdmt += icr & 0x01;
-+ icr >>= 2;
-+ adapter->icr_rxo += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_rxt += icr & 0x01;
-+ icr >>= 2;
-+ adapter->icr_mdac += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_rxcfg += icr & 0x01;
-+ icr >>= 1;
-+ adapter->icr_gpi += icr & 0x01;
- #endif
-
- return IRQ_HANDLED;
-@@ -2136,260 +3592,615 @@ e1000_intr(int irq, void *data, struct p
- **/
-
- static int
--e1000_clean(struct net_device *netdev, int *budget)
-+e1000_clean(struct net_device *poll_dev, int *budget)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-- int work_to_do = min(*budget, netdev->quota);
-- int work_done = 0;
--
-- e1000_clean_tx_irq(adapter);
-- e1000_clean_rx_irq(adapter, &work_done, work_to_do);
-+ struct e1000_adapter *adapter;
-+ int work_to_do = min(*budget, poll_dev->quota);
-+ int tx_cleaned = 0, work_done = 0;
-+
-+ /* Must NOT use netdev_priv macro here. */
-+ adapter = poll_dev->priv;
-+
-+ /* Keep link state information with original netdev */
-+ if (!netif_carrier_ok(poll_dev))
-+ goto quit_polling;
-+
-+ /* e1000_clean is called per-cpu. This lock protects
-+ * tx_ring[0] from being cleaned by multiple cpus
-+ * simultaneously. A failure obtaining the lock means
-+ * tx_ring[0] is currently being cleaned anyway. */
-+ if (spin_trylock(&adapter->tx_queue_lock)) {
-+ tx_cleaned = e1000_clean_tx_irq(adapter,
-+ &adapter->tx_ring[0]);
-+ spin_unlock(&adapter->tx_queue_lock);
-+ }
-+
-+ adapter->clean_rx(adapter, &adapter->rx_ring[0],
-+ &work_done, work_to_do);
-
- *budget -= work_done;
-- netdev->quota -= work_done;
--
-- if(work_done < work_to_do || !netif_running(netdev)) {
-- netif_rx_complete(netdev);
-+ poll_dev->quota -= work_done;
-+
-+ /* If no Tx and not enough Rx work done, exit the polling mode */
-+ if ((!tx_cleaned && (work_done == 0)) ||
-+ !netif_running(poll_dev)) {
-+quit_polling:
-+ netif_rx_complete(poll_dev);
- e1000_irq_enable(adapter);
- return 0;
- }
-
-- return (work_done >= work_to_do);
-+ return 1;
- }
--#endif
-
-+#endif
- /**
- * e1000_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
- **/
-
- static boolean_t
--e1000_clean_tx_irq(struct e1000_adapter *adapter)
-+e1000_clean_tx_irq(struct e1000_adapter *adapter,
-+ struct e1000_tx_ring *tx_ring)
- {
-- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
- struct net_device *netdev = adapter->netdev;
-- struct pci_dev *pdev = adapter->pdev;
- struct e1000_tx_desc *tx_desc, *eop_desc;
- struct e1000_buffer *buffer_info;
- unsigned int i, eop;
-+#ifdef CONFIG_E1000_NAPI
-+ unsigned int count = 0;
-+#endif
- boolean_t cleaned = FALSE;
-
--
- i = tx_ring->next_to_clean;
- eop = tx_ring->buffer_info[i].next_to_watch;
- eop_desc = E1000_TX_DESC(*tx_ring, eop);
-
-- while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
--
-- for(cleaned = FALSE; !cleaned; ) {
-+ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
-+ for (cleaned = FALSE; !cleaned; ) {
- tx_desc = E1000_TX_DESC(*tx_ring, i);
- buffer_info = &tx_ring->buffer_info[i];
-+ cleaned = (i == eop);
-
-- if(buffer_info->dma) {
--
-- pci_unmap_page(pdev,
-- buffer_info->dma,
-- buffer_info->length,
-- PCI_DMA_TODEVICE);
--
-- buffer_info->dma = 0;
-- }
--
-- if(buffer_info->skb) {
--
-- dev_kfree_skb_any(buffer_info->skb);
-+ e1000_unmap_and_free_tx_resource(adapter, buffer_info);
-+ memset(tx_desc, 0, sizeof(struct e1000_tx_desc));
-
-- buffer_info->skb = NULL;
-- }
-+ if (unlikely(++i == tx_ring->count)) i = 0;
-+ }
-
-- tx_desc->buffer_addr = 0;
-- tx_desc->lower.data = 0;
-- tx_desc->upper.data = 0;
-
-- cleaned = (i == eop);
-- if(++i == tx_ring->count) i = 0;
-- }
--
- eop = tx_ring->buffer_info[i].next_to_watch;
- eop_desc = E1000_TX_DESC(*tx_ring, eop);
-+#ifdef CONFIG_E1000_NAPI
-+#define E1000_TX_WEIGHT 64
-+ /* weight of a sort for tx, to avoid endless transmit cleanup */
-+ if (count++ == E1000_TX_WEIGHT) break;
-+#endif
- }
-
- tx_ring->next_to_clean = i;
-
-- spin_lock(&adapter->tx_lock);
-+#define TX_WAKE_THRESHOLD 32
-+ if (unlikely(cleaned && netif_queue_stopped(netdev) &&
-+ netif_carrier_ok(netdev))) {
-+ spin_lock(&tx_ring->tx_lock);
-+ if (netif_queue_stopped(netdev) &&
-+ (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD))
-+ netif_wake_queue(netdev);
-+ spin_unlock(&tx_ring->tx_lock);
-+ }
-+
-+ if (adapter->detect_tx_hung) {
-+ /* Detect a transmit hang in hardware, this serializes the
-+ * check with the clearing of time_stamp and movement of i */
-+ adapter->detect_tx_hung = FALSE;
-+ if (tx_ring->buffer_info[eop].dma &&
-+ time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
-+ (adapter->tx_timeout_factor * HZ))
-+ && !(E1000_READ_REG(&adapter->hw, STATUS) &
-+ E1000_STATUS_TXOFF)) {
-+
-+ /* detected Tx unit hang */
-+ DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n"
-+ " Tx Queue <%lu>\n"
-+ " TDH <%x>\n"
-+ " TDT <%x>\n"
-+ " next_to_use <%x>\n"
-+ " next_to_clean <%x>\n"
-+ "buffer_info[next_to_clean]\n"
-+ " time_stamp <%lx>\n"
-+ " next_to_watch <%x>\n"
-+ " jiffies <%lx>\n"
-+ " next_to_watch.status <%x>\n",
-+ (unsigned long)((tx_ring - adapter->tx_ring) /
-+ sizeof(struct e1000_tx_ring)),
-+ readl(adapter->hw.hw_addr + tx_ring->tdh),
-+ readl(adapter->hw.hw_addr + tx_ring->tdt),
-+ tx_ring->next_to_use,
-+ tx_ring->next_to_clean,
-+ tx_ring->buffer_info[eop].time_stamp,
-+ eop,
-+ jiffies,
-+ eop_desc->upper.fields.status);
-+ netif_stop_queue(netdev);
-+ }
-+ }
-+ return cleaned;
-+}
-
-- if(cleaned && netif_queue_stopped(netdev) && netif_carrier_ok(netdev))
-- netif_wake_queue(netdev);
-+/**
-+ * e1000_rx_checksum - Receive Checksum Offload for 82543
-+ * @adapter: board private structure
-+ * @status_err: receive descriptor status and error fields
-+ * @csum: receive descriptor csum field
-+ * @sk_buff: socket buffer with received data
-+ **/
-
-- spin_unlock(&adapter->tx_lock);
-+static void
-+e1000_rx_checksum(struct e1000_adapter *adapter,
-+ uint32_t status_err, uint32_t csum,
-+ struct sk_buff *skb)
-+{
-+ uint16_t status = (uint16_t)status_err;
-+ uint8_t errors = (uint8_t)(status_err >> 24);
-+ skb->ip_summed = CHECKSUM_NONE;
-
-- return cleaned;
-+ /* 82543 or newer only */
-+ if (unlikely(adapter->hw.mac_type < e1000_82543)) return;
-+ /* Ignore Checksum bit is set */
-+ if (unlikely(status & E1000_RXD_STAT_IXSM)) return;
-+ /* TCP/UDP checksum error bit is set */
-+ if (unlikely(errors & E1000_RXD_ERR_TCPE)) {
-+ /* let the stack verify checksum errors */
-+ adapter->hw_csum_err++;
-+ return;
-+ }
-+ /* TCP/UDP Checksum has not been calculated */
-+ if (adapter->hw.mac_type <= e1000_82547_rev_2) {
-+ if (!(status & E1000_RXD_STAT_TCPCS))
-+ return;
-+ } else {
-+ if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS)))
-+ return;
-+ }
-+ /* It must be a TCP or UDP packet with a valid checksum */
-+ if (likely(status & E1000_RXD_STAT_TCPCS)) {
-+ /* TCP checksum is good */
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+ } else if (adapter->hw.mac_type > e1000_82547_rev_2) {
-+ /* IP fragment with UDP payload */
-+ /* Hardware complements the payload checksum, so we undo it
-+ * and then put the value in host order for further stack use.
-+ */
-+ csum = ntohl(csum ^ 0xFFFF);
-+ skb->csum = csum;
-+ skb->ip_summed = CHECKSUM_HW;
-+ }
-+ adapter->hw_csum_good++;
- }
-
- /**
-- * e1000_clean_rx_irq - Send received data up the network stack,
-+ * e1000_clean_rx_irq - Send received data up the network stack; legacy
- * @adapter: board private structure
- **/
-
- static boolean_t
- #ifdef CONFIG_E1000_NAPI
--e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
-- int work_to_do)
-+e1000_clean_rx_irq(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int *work_done, int work_to_do)
- #else
--e1000_clean_rx_irq(struct e1000_adapter *adapter)
-+e1000_clean_rx_irq(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring)
- #endif
- {
-- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
-- struct e1000_rx_desc *rx_desc;
-- struct e1000_buffer *buffer_info;
-- struct sk_buff *skb;
-+ struct e1000_rx_desc *rx_desc, *next_rxd;
-+ struct e1000_buffer *buffer_info, *next_buffer;
- unsigned long flags;
- uint32_t length;
- uint8_t last_byte;
- unsigned int i;
-+ int cleaned_count = 0;
- boolean_t cleaned = FALSE;
-
- i = rx_ring->next_to_clean;
- rx_desc = E1000_RX_DESC(*rx_ring, i);
-+ buffer_info = &rx_ring->buffer_info[i];
-
-- while(rx_desc->status & E1000_RXD_STAT_DD) {
-- buffer_info = &rx_ring->buffer_info[i];
-+ while (rx_desc->status & E1000_RXD_STAT_DD) {
-+ struct sk_buff *skb, *next_skb;
-+ u8 status;
-
- #ifdef CONFIG_E1000_NAPI
-- if(*work_done >= work_to_do)
-+ if (*work_done >= work_to_do)
- break;
--
- (*work_done)++;
- #endif
-+ status = rx_desc->status;
-+ skb = buffer_info->skb;
-+ buffer_info->skb = NULL;
-
-- cleaned = TRUE;
-+ prefetch(skb->data - NET_IP_ALIGN);
-
-+ if (++i == rx_ring->count) i = 0;
-+ next_rxd = E1000_RX_DESC(*rx_ring, i);
-+ prefetch(next_rxd);
-+
-+ next_buffer = &rx_ring->buffer_info[i];
-+ next_skb = next_buffer->skb;
-+ prefetch(next_skb->data - NET_IP_ALIGN);
-+
-+ cleaned = TRUE;
-+ cleaned_count++;
- pci_unmap_single(pdev,
- buffer_info->dma,
- buffer_info->length,
- PCI_DMA_FROMDEVICE);
-
-- skb = buffer_info->skb;
- length = le16_to_cpu(rx_desc->length);
-
-- if(!(rx_desc->status & E1000_RXD_STAT_EOP)) {
-+ /* adjust length to remove Ethernet CRC */
-+ length -= 4;
-
-+ if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
- /* All receives must fit into a single buffer */
--
-- E1000_DBG("%s: Receive packet consumed multiple buffers\n",
-- netdev->name);
--
-- dev_kfree_skb_irq(skb);
-- rx_desc->status = 0;
-- buffer_info->skb = NULL;
--
-- if(++i == rx_ring->count) i = 0;
--
-- rx_desc = E1000_RX_DESC(*rx_ring, i);
-- continue;
-+ E1000_DBG("%s: Receive packet consumed multiple"
-+ " buffers\n", netdev->name);
-+ /* recycle */
-+ buffer_info->skb = skb;
-+ goto next_desc;
- }
-
-- if(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {
--
-+ if (unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
- last_byte = *(skb->data + length - 1);
--
-- if(TBI_ACCEPT(&adapter->hw, rx_desc->status,
-+ if (TBI_ACCEPT(&adapter->hw, status,
- rx_desc->errors, length, last_byte)) {
--
- spin_lock_irqsave(&adapter->stats_lock, flags);
--
- e1000_tbi_adjust_stats(&adapter->hw,
- &adapter->stats,
- length, skb->data);
--
- spin_unlock_irqrestore(&adapter->stats_lock,
- flags);
- length--;
- } else {
-+ /* recycle */
-+ buffer_info->skb = skb;
-+ goto next_desc;
-+ }
-+ }
-+
-+ /* code added for copybreak, this should improve
-+ * performance for small packets with large amounts
-+ * of reassembly being done in the stack */
-+#define E1000_CB_LENGTH 256
-+ if (length < E1000_CB_LENGTH) {
-+ struct sk_buff *new_skb =
-+ dev_alloc_skb(length + NET_IP_ALIGN);
-+ if (new_skb) {
-+ skb_reserve(new_skb, NET_IP_ALIGN);
-+ new_skb->dev = netdev;
-+ memcpy(new_skb->data - NET_IP_ALIGN,
-+ skb->data - NET_IP_ALIGN,
-+ length + NET_IP_ALIGN);
-+ /* save the skb in buffer_info as good */
-+ buffer_info->skb = skb;
-+ skb = new_skb;
-+ skb_put(skb, length);
-+ }
-+ } else
-+ skb_put(skb, length);
-
-- dev_kfree_skb_irq(skb);
-- rx_desc->status = 0;
-- buffer_info->skb = NULL;
-+ /* end copybreak code */
-
-- if(++i == rx_ring->count) i = 0;
-+ /* Receive Checksum Offload */
-+ e1000_rx_checksum(adapter,
-+ (uint32_t)(status) |
-+ ((uint32_t)(rx_desc->errors) << 24),
-+ le16_to_cpu(rx_desc->csum), skb);
-
-- rx_desc = E1000_RX_DESC(*rx_ring, i);
-- continue;
-- }
-+ skb->protocol = eth_type_trans(skb, netdev);
-+#ifdef CONFIG_E1000_NAPI
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (unlikely(adapter->vlgrp &&
-+ (status & E1000_RXD_STAT_VP))) {
-+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-+ le16_to_cpu(rx_desc->special) &
-+ E1000_RXD_SPC_VLAN_MASK);
-+ } else {
-+ netif_receive_skb(skb);
-+ }
-+#else
-+ netif_receive_skb(skb);
-+#endif
-+#else /* CONFIG_E1000_NAPI */
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (unlikely(adapter->vlgrp &&
-+ (status & E1000_RXD_STAT_VP))) {
-+ vlan_hwaccel_rx(skb, adapter->vlgrp,
-+ le16_to_cpu(rx_desc->special) &
-+ E1000_RXD_SPC_VLAN_MASK);
-+ } else {
-+ netif_rx(skb);
-+ }
-+#else
-+ netif_rx(skb);
-+#endif
-+#endif /* CONFIG_E1000_NAPI */
-+ netdev->last_rx = jiffies;
-+
-+next_desc:
-+ rx_desc->status = 0;
-+
-+ /* return some buffers to hardware, one at a time is too slow */
-+ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
-+ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-+ cleaned_count = 0;
-+ }
-+
-+ /* use prefetched values */
-+ rx_desc = next_rxd;
-+ buffer_info = next_buffer;
-+ }
-+ rx_ring->next_to_clean = i;
-+
-+ cleaned_count = E1000_DESC_UNUSED(rx_ring);
-+ if (cleaned_count)
-+ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-+
-+ return cleaned;
-+}
-+
-+/**
-+ * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
-+ * @adapter: board private structure
-+ **/
-+
-+static boolean_t
-+#ifdef CONFIG_E1000_NAPI
-+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int *work_done, int work_to_do)
-+#else
-+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring)
-+#endif
-+{
-+ union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
-+ struct net_device *netdev = adapter->netdev;
-+ struct pci_dev *pdev = adapter->pdev;
-+ struct e1000_buffer *buffer_info, *next_buffer;
-+ struct e1000_ps_page *ps_page;
-+ struct e1000_ps_page_dma *ps_page_dma;
-+ struct sk_buff *skb, *next_skb;
-+ unsigned int i, j;
-+ uint32_t length, staterr;
-+ int cleaned_count = 0;
-+ boolean_t cleaned = FALSE;
-+
-+ i = rx_ring->next_to_clean;
-+ rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-+ staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
-+ buffer_info = &rx_ring->buffer_info[i];
-+
-+ while (staterr & E1000_RXD_STAT_DD) {
-+ ps_page = &rx_ring->ps_page[i];
-+ ps_page_dma = &rx_ring->ps_page_dma[i];
-+#ifdef CONFIG_E1000_NAPI
-+ if (unlikely(*work_done >= work_to_do))
-+ break;
-+ (*work_done)++;
-+#endif
-+ skb = buffer_info->skb;
-+
-+ /* in the packet split case this is header only */
-+ prefetch(skb->data - NET_IP_ALIGN);
-+
-+ if (++i == rx_ring->count) i = 0;
-+ next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
-+ prefetch(next_rxd);
-+
-+ next_buffer = &rx_ring->buffer_info[i];
-+ next_skb = next_buffer->skb;
-+ prefetch(next_skb->data - NET_IP_ALIGN);
-+
-+ cleaned = TRUE;
-+ cleaned_count++;
-+ pci_unmap_single(pdev, buffer_info->dma,
-+ buffer_info->length,
-+ PCI_DMA_FROMDEVICE);
-+
-+ if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
-+ E1000_DBG("%s: Packet Split buffers didn't pick up"
-+ " the full packet\n", netdev->name);
-+ dev_kfree_skb_irq(skb);
-+ goto next_desc;
-+ }
-+
-+ if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
-+ dev_kfree_skb_irq(skb);
-+ goto next_desc;
-+ }
-+
-+ length = le16_to_cpu(rx_desc->wb.middle.length0);
-+
-+ if (unlikely(!length)) {
-+ E1000_DBG("%s: Last part of the packet spanning"
-+ " multiple descriptors\n", netdev->name);
-+ dev_kfree_skb_irq(skb);
-+ goto next_desc;
- }
-
- /* Good Receive */
-- skb_put(skb, length - ETHERNET_FCS_SIZE);
-+ skb_put(skb, length);
-
-- /* Receive Checksum Offload */
-- e1000_rx_checksum(adapter, rx_desc, skb);
-+ {
-+ /* this looks ugly, but it seems compiler issues make it
-+ more efficient than reusing j */
-+ int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
-+
-+ /* page alloc/put takes too long and effects small packet
-+ * throughput, so unsplit small packets and save the alloc/put*/
-+ if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) {
-+ u8 *vaddr;
-+ /* there is no documentation about how to call
-+ * kmap_atomic, so we can't hold the mapping
-+ * very long */
-+ pci_dma_sync_single_for_cpu(pdev,
-+ ps_page_dma->ps_page_dma[0],
-+ PAGE_SIZE,
-+ PCI_DMA_FROMDEVICE);
-+ vaddr = kmap_atomic(ps_page->ps_page[0],
-+ KM_SKB_DATA_SOFTIRQ);
-+ memcpy(skb->tail, vaddr, l1);
-+ kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
-+ pci_dma_sync_single_for_device(pdev,
-+ ps_page_dma->ps_page_dma[0],
-+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
-+ /* remove the CRC */
-+ l1 -= 4;
-+ skb_put(skb, l1);
-+ goto copydone;
-+ } /* if */
-+ }
-
-+ for (j = 0; j < adapter->rx_ps_pages; j++) {
-+ if (!(length= le16_to_cpu(rx_desc->wb.upper.length[j])))
-+ break;
-+ pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
-+ PAGE_SIZE, PCI_DMA_FROMDEVICE);
-+ ps_page_dma->ps_page_dma[j] = 0;
-+ skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
-+ length);
-+ ps_page->ps_page[j] = NULL;
-+ skb->len += length;
-+ skb->data_len += length;
-+ skb->truesize += length;
-+ }
-+
-+ /* strip the ethernet crc, problem is we're using pages now so
-+ * this whole operation can get a little cpu intensive */
-+ pskb_trim(skb, skb->len - 4);
-+
-+copydone:
-+ e1000_rx_checksum(adapter, staterr,
-+ le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
- skb->protocol = eth_type_trans(skb, netdev);
-+
-+ if (likely(rx_desc->wb.upper.header_status &
-+ cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
-+ adapter->rx_hdr_split++;
- #ifdef CONFIG_E1000_NAPI
-- if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-- le16_to_cpu(rx_desc->special &
-- E1000_RXD_SPC_VLAN_MASK));
-+ le16_to_cpu(rx_desc->wb.middle.vlan) &
-+ E1000_RXD_SPC_VLAN_MASK);
- } else {
- netif_receive_skb(skb);
- }
-+#else
-+ netif_receive_skb(skb);
-+#endif
- #else /* CONFIG_E1000_NAPI */
-- if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {
-+#ifdef NETIF_F_HW_VLAN_TX
-+ if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
- vlan_hwaccel_rx(skb, adapter->vlgrp,
-- le16_to_cpu(rx_desc->special &
-- E1000_RXD_SPC_VLAN_MASK));
-+ le16_to_cpu(rx_desc->wb.middle.vlan) &
-+ E1000_RXD_SPC_VLAN_MASK);
- } else {
- netif_rx(skb);
- }
-+#else
-+ netif_rx(skb);
-+#endif
- #endif /* CONFIG_E1000_NAPI */
- netdev->last_rx = jiffies;
-
-- rx_desc->status = 0;
-+next_desc:
-+ rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
- buffer_info->skb = NULL;
-
-- if(++i == rx_ring->count) i = 0;
-+ /* return some buffers to hardware, one at a time is too slow */
-+ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
-+ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-+ cleaned_count = 0;
-+ }
-
-- rx_desc = E1000_RX_DESC(*rx_ring, i);
-- }
-+ /* use prefetched values */
-+ rx_desc = next_rxd;
-+ buffer_info = next_buffer;
-
-+ staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
-+ }
- rx_ring->next_to_clean = i;
-
-- e1000_alloc_rx_buffers(adapter);
-+ cleaned_count = E1000_DESC_UNUSED(rx_ring);
-+ if (cleaned_count)
-+ adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-
- return cleaned;
- }
-
- /**
-- * e1000_alloc_rx_buffers - Replace used receive buffers
-+ * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
- * @adapter: address of board private structure
- **/
-
- static void
--e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
-+e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int cleaned_count)
- {
-- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
- struct net_device *netdev = adapter->netdev;
- struct pci_dev *pdev = adapter->pdev;
- struct e1000_rx_desc *rx_desc;
- struct e1000_buffer *buffer_info;
- struct sk_buff *skb;
- unsigned int i;
-+ unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN;
-
- i = rx_ring->next_to_use;
- buffer_info = &rx_ring->buffer_info[i];
-
-- while(!buffer_info->skb) {
-- rx_desc = E1000_RX_DESC(*rx_ring, i);
--
-- skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
-+ while (cleaned_count--) {
-+ if (!(skb = buffer_info->skb))
-+ skb = dev_alloc_skb(bufsz);
-+ else {
-+ skb_trim(skb, 0);
-+ goto map_skb;
-+ }
-
-- if(!skb) {
-+ if (unlikely(!skb)) {
- /* Better luck next round */
-+ adapter->alloc_rx_buff_failed++;
- break;
- }
-
-+ /* Fix for errata 23, can't cross 64kB boundary */
-+ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
-+ struct sk_buff *oldskb = skb;
-+ DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes "
-+ "at %p\n", bufsz, skb->data);
-+ /* Try again, without freeing the previous */
-+ skb = dev_alloc_skb(bufsz);
-+ /* Failed allocation, critical failure */
-+ if (!skb) {
-+ dev_kfree_skb(oldskb);
-+ break;
-+ }
-+
-+ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) {
-+ /* give up */
-+ dev_kfree_skb(skb);
-+ dev_kfree_skb(oldskb);
-+ break; /* while !buffer_info->skb */
-+ } else {
-+ /* Use new allocation */
-+ dev_kfree_skb(oldskb);
-+ }
-+ }
- /* Make buffer alignment 2 beyond a 16 byte boundary
- * this will result in a 16 byte aligned IP header after
- * the 14 byte MAC header is removed
-@@ -2400,29 +4211,148 @@ e1000_alloc_rx_buffers(struct e1000_adap
-
- buffer_info->skb = skb;
- buffer_info->length = adapter->rx_buffer_len;
-- buffer_info->dma =
-- pci_map_single(pdev,
-- skb->data,
-- adapter->rx_buffer_len,
-- PCI_DMA_FROMDEVICE);
-+map_skb:
-+ buffer_info->dma = pci_map_single(pdev,
-+ skb->data,
-+ adapter->rx_buffer_len,
-+ PCI_DMA_FROMDEVICE);
-+
-+ /* Fix for errata 23, can't cross 64kB boundary */
-+ if (!e1000_check_64k_bound(adapter,
-+ (void *)(unsigned long)buffer_info->dma,
-+ adapter->rx_buffer_len)) {
-+ DPRINTK(RX_ERR, ERR,
-+ "dma align check failed: %u bytes at %p\n",
-+ adapter->rx_buffer_len,
-+ (void *)(unsigned long)buffer_info->dma);
-+ dev_kfree_skb(skb);
-+ buffer_info->skb = NULL;
-
-+ pci_unmap_single(pdev, buffer_info->dma,
-+ adapter->rx_buffer_len,
-+ PCI_DMA_FROMDEVICE);
-+
-+ break; /* while !buffer_info->skb */
-+ }
-+ rx_desc = E1000_RX_DESC(*rx_ring, i);
- rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-
-- if((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i) {
-- /* Force memory writes to complete before letting h/w
-- * know there are new descriptors to fetch. (Only
-- * applicable for weak-ordered memory model archs,
-- * such as IA-64). */
-- wmb();
-+ if (unlikely(++i == rx_ring->count))
-+ i = 0;
-+ buffer_info = &rx_ring->buffer_info[i];
-+ }
-+
-+ if (likely(rx_ring->next_to_use != i)) {
-+ rx_ring->next_to_use = i;
-+ if (unlikely(i-- == 0))
-+ i = (rx_ring->count - 1);
-+
-+ /* Force memory writes to complete before letting h/w
-+ * know there are new descriptors to fetch. (Only
-+ * applicable for weak-ordered memory model archs,
-+ * such as IA-64). */
-+ wmb();
-+ writel(i, adapter->hw.hw_addr + rx_ring->rdt);
-+ }
-+}
-+
-+/**
-+ * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
-+ * @adapter: address of board private structure
-+ **/
-
-- E1000_WRITE_REG(&adapter->hw, RDT, i);
-+static void
-+e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-+ struct e1000_rx_ring *rx_ring,
-+ int cleaned_count)
-+{
-+ struct net_device *netdev = adapter->netdev;
-+ struct pci_dev *pdev = adapter->pdev;
-+ union e1000_rx_desc_packet_split *rx_desc;
-+ struct e1000_buffer *buffer_info;
-+ struct e1000_ps_page *ps_page;
-+ struct e1000_ps_page_dma *ps_page_dma;
-+ struct sk_buff *skb;
-+ unsigned int i, j;
-+
-+ i = rx_ring->next_to_use;
-+ buffer_info = &rx_ring->buffer_info[i];
-+ ps_page = &rx_ring->ps_page[i];
-+ ps_page_dma = &rx_ring->ps_page_dma[i];
-+
-+ while (cleaned_count--) {
-+ rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-+
-+ for (j = 0; j < PS_PAGE_BUFFERS; j++) {
-+ if (j < adapter->rx_ps_pages) {
-+ if (likely(!ps_page->ps_page[j])) {
-+ ps_page->ps_page[j] =
-+ alloc_page(GFP_ATOMIC);
-+ if (unlikely(!ps_page->ps_page[j])) {
-+ adapter->alloc_rx_buff_failed++;
-+ goto no_buffers;
-+ }
-+ ps_page_dma->ps_page_dma[j] =
-+ pci_map_page(pdev,
-+ ps_page->ps_page[j],
-+ 0, PAGE_SIZE,
-+ PCI_DMA_FROMDEVICE);
-+ }
-+ /* Refresh the desc even if buffer_addrs didn't
-+ * change because each write-back erases
-+ * this info.
-+ */
-+ rx_desc->read.buffer_addr[j+1] =
-+ cpu_to_le64(ps_page_dma->ps_page_dma[j]);
-+ } else
-+ rx_desc->read.buffer_addr[j+1] = ~0;
- }
-
-- if(++i == rx_ring->count) i = 0;
-+ skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
-+
-+ if (unlikely(!skb)) {
-+ adapter->alloc_rx_buff_failed++;
-+ break;
-+ }
-+
-+ /* Make buffer alignment 2 beyond a 16 byte boundary
-+ * this will result in a 16 byte aligned IP header after
-+ * the 14 byte MAC header is removed
-+ */
-+ skb_reserve(skb, NET_IP_ALIGN);
-+
-+ skb->dev = netdev;
-+
-+ buffer_info->skb = skb;
-+ buffer_info->length = adapter->rx_ps_bsize0;
-+ buffer_info->dma = pci_map_single(pdev, skb->data,
-+ adapter->rx_ps_bsize0,
-+ PCI_DMA_FROMDEVICE);
-+
-+ rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
-+
-+ if (unlikely(++i == rx_ring->count)) i = 0;
- buffer_info = &rx_ring->buffer_info[i];
-+ ps_page = &rx_ring->ps_page[i];
-+ ps_page_dma = &rx_ring->ps_page_dma[i];
- }
-
-- rx_ring->next_to_use = i;
-+no_buffers:
-+ if (likely(rx_ring->next_to_use != i)) {
-+ rx_ring->next_to_use = i;
-+ if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
-+
-+ /* Force memory writes to complete before letting h/w
-+ * know there are new descriptors to fetch. (Only
-+ * applicable for weak-ordered memory model archs,
-+ * such as IA-64). */
-+ wmb();
-+ /* Hardware increments by 16 bytes, but packet split
-+ * descriptors are 32 bytes...so we increment tail
-+ * twice as much.
-+ */
-+ writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
-+ }
- }
-
- /**
-@@ -2436,24 +4366,24 @@ e1000_smartspeed(struct e1000_adapter *a
- uint16_t phy_status;
- uint16_t phy_ctrl;
-
-- if((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
-+ if ((adapter->hw.phy_type != e1000_phy_igp) || !adapter->hw.autoneg ||
- !(adapter->hw.autoneg_advertised & ADVERTISE_1000_FULL))
- return;
-
-- if(adapter->smartspeed == 0) {
-+ if (adapter->smartspeed == 0) {
- /* If Master/Slave config fault is asserted twice,
- * we assume back-to-back */
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
-- if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
-+ if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_STATUS, &phy_status);
-- if(!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
-+ if (!(phy_status & SR_1000T_MS_CONFIG_FAULT)) return;
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
-- if(phy_ctrl & CR_1000T_MS_ENABLE) {
-+ if (phy_ctrl & CR_1000T_MS_ENABLE) {
- phy_ctrl &= ~CR_1000T_MS_ENABLE;
- e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL,
- phy_ctrl);
- adapter->smartspeed++;
-- if(!e1000_phy_setup_autoneg(&adapter->hw) &&
-+ if (!e1000_phy_setup_autoneg(&adapter->hw) &&
- !e1000_read_phy_reg(&adapter->hw, PHY_CTRL,
- &phy_ctrl)) {
- phy_ctrl |= (MII_CR_AUTO_NEG_EN |
-@@ -2463,12 +4393,12 @@ e1000_smartspeed(struct e1000_adapter *a
- }
- }
- return;
-- } else if(adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
-+ } else if (adapter->smartspeed == E1000_SMARTSPEED_DOWNSHIFT) {
- /* If still no link, perhaps using 2/3 pair cable */
- e1000_read_phy_reg(&adapter->hw, PHY_1000T_CTRL, &phy_ctrl);
- phy_ctrl |= CR_1000T_MS_ENABLE;
- e1000_write_phy_reg(&adapter->hw, PHY_1000T_CTRL, phy_ctrl);
-- if(!e1000_phy_setup_autoneg(&adapter->hw) &&
-+ if (!e1000_phy_setup_autoneg(&adapter->hw) &&
- !e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &phy_ctrl)) {
- phy_ctrl |= (MII_CR_AUTO_NEG_EN |
- MII_CR_RESTART_AUTO_NEG);
-@@ -2476,7 +4406,7 @@ e1000_smartspeed(struct e1000_adapter *a
- }
- }
- /* Restart process after E1000_SMARTSPEED_MAX iterations */
-- if(adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
-+ if (adapter->smartspeed++ == E1000_SMARTSPEED_MAX)
- adapter->smartspeed = 0;
- }
-
-@@ -2491,15 +4421,22 @@ static int
- e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
- {
- switch (cmd) {
-+#ifdef SIOCGMIIPHY
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
- case SIOCSMIIREG:
- return e1000_mii_ioctl(netdev, ifr, cmd);
-+#endif
-+#ifdef ETHTOOL_OPS_COMPAT
-+ case SIOCETHTOOL:
-+ return ethtool_ioctl(ifr);
-+#endif
- default:
- return -EOPNOTSUPP;
- }
- }
-
-+#ifdef SIOCGMIIPHY
- /**
- * e1000_mii_ioctl -
- * @netdev:
-@@ -2510,13 +4447,11 @@ e1000_ioctl(struct net_device *netdev, s
- static int
- e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- struct mii_ioctl_data *data = if_mii(ifr);
-- int retval;
-- uint16_t mii_reg;
-- uint16_t spddplx;
-+ unsigned long flags;
-
-- if(adapter->hw.media_type != e1000_media_type_copper)
-+ if (adapter->hw.media_type != e1000_media_type_copper)
- return -EOPNOTSUPP;
-
- switch (cmd) {
-@@ -2526,101 +4461,36 @@ e1000_mii_ioctl(struct net_device *netde
- case SIOCGMIIREG:
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-+ spin_lock_irqsave(&adapter->stats_lock, flags);
- if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
-- &data->val_out))
-- return -EIO;
-- break;
-- case SIOCSMIIREG:
-- if (!capable(CAP_NET_ADMIN))
-- return -EPERM;
-- if (data->reg_num & ~(0x1F))
-- return -EFAULT;
-- mii_reg = data->val_in;
-- if (e1000_write_phy_reg(&adapter->hw, data->reg_num,
-- data->val_in))
-+ &data->val_out)) {
-+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
- return -EIO;
-- if (adapter->hw.phy_type == e1000_phy_m88) {
-- switch (data->reg_num) {
-- case PHY_CTRL:
-- if(data->val_in & MII_CR_AUTO_NEG_EN) {
-- adapter->hw.autoneg = 1;
-- adapter->hw.autoneg_advertised = 0x2F;
-- } else {
-- if (data->val_in & 0x40)
-- spddplx = SPEED_1000;
-- else if (data->val_in & 0x2000)
-- spddplx = SPEED_100;
-- else
-- spddplx = SPEED_10;
-- spddplx += (data->val_in & 0x100)
-- ? FULL_DUPLEX :
-- HALF_DUPLEX;
-- retval = e1000_set_spd_dplx(adapter,
-- spddplx);
-- if(retval)
-- return retval;
-- }
-- if(netif_running(adapter->netdev)) {
-- e1000_down(adapter);
-- e1000_up(adapter);
-- } else
-- e1000_reset(adapter);
-- break;
-- case M88E1000_PHY_SPEC_CTRL:
-- case M88E1000_EXT_PHY_SPEC_CTRL:
-- if (e1000_phy_reset(&adapter->hw))
-- return -EIO;
-- break;
-- }
- }
-+ spin_unlock_irqrestore(&adapter->stats_lock, flags);
- break;
-+ case SIOCSMIIREG:
- default:
- return -EOPNOTSUPP;
- }
- return E1000_SUCCESS;
- }
--
--/**
-- * e1000_rx_checksum - Receive Checksum Offload for 82543
-- * @adapter: board private structure
-- * @rx_desc: receive descriptor
-- * @sk_buff: socket buffer with received data
-- **/
--
--static inline void
--e1000_rx_checksum(struct e1000_adapter *adapter,
-- struct e1000_rx_desc *rx_desc,
-- struct sk_buff *skb)
--{
-- /* 82543 or newer only */
-- if((adapter->hw.mac_type < e1000_82543) ||
-- /* Ignore Checksum bit is set */
-- (rx_desc->status & E1000_RXD_STAT_IXSM) ||
-- /* TCP Checksum has not been calculated */
-- (!(rx_desc->status & E1000_RXD_STAT_TCPCS))) {
-- skb->ip_summed = CHECKSUM_NONE;
-- return;
-- }
--
-- /* At this point we know the hardware did the TCP checksum */
-- /* now look at the TCP checksum error bit */
-- if(rx_desc->errors & E1000_RXD_ERR_TCPE) {
-- /* let the stack verify checksum errors */
-- skb->ip_summed = CHECKSUM_NONE;
-- adapter->hw_csum_err++;
-- } else {
-- /* TCP checksum is good */
-- skb->ip_summed = CHECKSUM_UNNECESSARY;
-- adapter->hw_csum_good++;
-- }
--}
-+#endif
-
- void
- e1000_pci_set_mwi(struct e1000_hw *hw)
- {
- struct e1000_adapter *adapter = hw->back;
-+#ifdef HAVE_PCI_SET_MWI
-+ int ret_val = pci_set_mwi(adapter->pdev);
-
-- pci_set_mwi(adapter->pdev);
-+ if (ret_val)
-+ DPRINTK(PROBE, ERR, "Error in setting MWI\n");
-+#else
-+ pci_write_config_word(adapter->pdev, PCI_COMMAND,
-+ adapter->hw.pci_cmd_word |
-+ PCI_COMMAND_INVALIDATE);
-+#endif
- }
-
- void
-@@ -2628,7 +4498,13 @@ e1000_pci_clear_mwi(struct e1000_hw *hw)
- {
- struct e1000_adapter *adapter = hw->back;
-
-+#ifdef HAVE_PCI_SET_MWI
- pci_clear_mwi(adapter->pdev);
-+#else
-+ pci_write_config_word(adapter->pdev, PCI_COMMAND,
-+ adapter->hw.pci_cmd_word &
-+ ~PCI_COMMAND_INVALIDATE);
-+#endif
- }
-
- void
-@@ -2659,40 +4535,46 @@ e1000_io_write(struct e1000_hw *hw, unsi
- outl(value, port);
- }
-
-+#ifdef NETIF_F_HW_VLAN_TX
- static void
- e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t ctrl, rctl;
-
- e1000_irq_disable(adapter);
- adapter->vlgrp = grp;
-
-- if(grp) {
-+ if (grp) {
- /* enable VLAN tag insert/strip */
--
- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
- ctrl |= E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
-
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
- /* enable VLAN receive filtering */
--
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- rctl |= E1000_RCTL_VFE;
- rctl &= ~E1000_RCTL_CFIEN;
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-+ e1000_update_mng_vlan(adapter);
-+ }
- } else {
- /* disable VLAN tag insert/strip */
--
- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
- ctrl &= ~E1000_CTRL_VME;
- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
-
-+ if (adapter->hw.mac_type != e1000_ich8lan) {
- /* disable VLAN filtering */
--
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- rctl &= ~E1000_RCTL_VFE;
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
-+ if (adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) {
-+ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
-+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-+ }
-+ }
- }
-
- e1000_irq_enable(adapter);
-@@ -2701,11 +4583,14 @@ e1000_vlan_rx_register(struct net_device
- static void
- e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t vfta, index;
-
-+ if ((adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
-+ (vid == adapter->mng_vlan_id))
-+ return;
- /* add VID to filter table */
--
- index = (vid >> 5) & 0x7F;
- vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
- vfta |= (1 << (vid & 0x1F));
-@@ -2715,18 +4600,25 @@ e1000_vlan_rx_add_vid(struct net_device
- static void
- e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid)
- {
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t vfta, index;
-
- e1000_irq_disable(adapter);
-
-- if(adapter->vlgrp)
-+ if (adapter->vlgrp)
- adapter->vlgrp->vlan_devices[vid] = NULL;
-
- e1000_irq_enable(adapter);
-
-- /* remove VID from filter table*/
-+ if ((adapter->hw.mng_cookie.status &
-+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) &&
-+ (vid == adapter->mng_vlan_id)) {
-+ /* release control to f/w */
-+ e1000_release_hw_control(adapter);
-+ return;
-+ }
-
-+ /* remove VID from filter table */
- index = (vid >> 5) & 0x7F;
- vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);
- vfta &= ~(1 << (vid & 0x1F));
-@@ -2738,22 +4630,30 @@ e1000_restore_vlan(struct e1000_adapter
- {
- e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-
-- if(adapter->vlgrp) {
-+ if (adapter->vlgrp) {
- uint16_t vid;
-- for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-- if(!adapter->vlgrp->vlan_devices[vid])
-+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {
-+ if (!adapter->vlgrp->vlan_devices[vid])
- continue;
- e1000_vlan_rx_add_vid(adapter->netdev, vid);
- }
- }
- }
-+#endif
-
- int
- e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
- {
- adapter->hw.autoneg = 0;
-
-- switch(spddplx) {
-+ /* Fiber NICs only allow 1000 gbps Full duplex */
-+ if ((adapter->hw.media_type == e1000_media_type_fiber) &&
-+ spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-+ DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
-+ return -EINVAL;
-+ }
-+
-+ switch (spddplx) {
- case SPEED_10 + DUPLEX_HALF:
- adapter->hw.forced_speed_duplex = e1000_10_half;
- break;
-@@ -2772,57 +4672,126 @@ e1000_set_spd_dplx(struct e1000_adapter
- break;
- case SPEED_1000 + DUPLEX_HALF: /* not supported */
- default:
-+ DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
- }
- return 0;
- }
-
-+#ifdef CONFIG_PM
-+/* Save/restore 16 or 64 dwords of PCI config space depending on which
-+ * bus we're on (PCI(X) vs. PCI-E)
-+ */
-+#define PCIE_CONFIG_SPACE_LEN 256
-+#define PCI_CONFIG_SPACE_LEN 64
-+static int
-+e1000_pci_save_state(struct e1000_adapter *adapter)
-+{
-+ struct pci_dev *dev = adapter->pdev;
-+ int size;
-+ int i;
-+
-+ if (adapter->hw.mac_type >= e1000_82571)
-+ size = PCIE_CONFIG_SPACE_LEN;
-+ else
-+ size = PCI_CONFIG_SPACE_LEN;
-+
-+ WARN_ON(adapter->config_space != NULL);
-+
-+ adapter->config_space = kmalloc(size, GFP_KERNEL);
-+ if (!adapter->config_space) {
-+ DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size);
-+ return -ENOMEM;
-+ }
-+ for (i = 0; i < (size / 4); i++)
-+ pci_read_config_dword(dev, i * 4, &adapter->config_space[i]);
-+ return 0;
-+}
-+
-+static void
-+e1000_pci_restore_state(struct e1000_adapter *adapter)
-+{
-+ struct pci_dev *dev = adapter->pdev;
-+ int size;
-+ int i;
-+
-+ if (adapter->config_space == NULL)
-+ return;
-+
-+ if (adapter->hw.mac_type >= e1000_82571)
-+ size = PCIE_CONFIG_SPACE_LEN;
-+ else
-+ size = PCI_CONFIG_SPACE_LEN;
-+ for (i = 0; i < (size / 4); i++)
-+ pci_write_config_dword(dev, i * 4, adapter->config_space[i]);
-+ kfree(adapter->config_space);
-+ adapter->config_space = NULL;
-+ return;
-+}
-+#endif /* CONFIG_PM */
-+
-+#ifndef USE_DRIVER_SHUTDOWN_HANDLER
-+/* only want to do this for 2.4 kernels? */
- static int
- e1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p)
- {
- struct pci_dev *pdev = NULL;
-
-- switch(event) {
-+ switch (event) {
- case SYS_DOWN:
- case SYS_HALT:
- case SYS_POWER_OFF:
-- while((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-- if(pci_dev_driver(pdev) == &e1000_driver)
-- e1000_suspend(pdev, 3);
-+ while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) {
-+ if (pci_dev_driver(pdev) == &e1000_driver)
-+ e1000_suspend(pdev, PMSG_SUSPEND);
- }
- }
- return NOTIFY_DONE;
- }
-+#endif
-
- static int
--e1000_suspend(struct pci_dev *pdev, uint32_t state)
-+e1000_suspend(struct pci_dev *pdev, pm_message_t state)
- {
- struct net_device *netdev = pci_get_drvdata(pdev);
-- struct e1000_adapter *adapter = netdev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
- uint32_t ctrl, ctrl_ext, rctl, manc, status;
- uint32_t wufc = adapter->wol;
-+#ifdef CONFIG_PM
-+ int retval = 0;
-+#endif
-
- netif_device_detach(netdev);
-
-- if(netif_running(netdev))
-+ if (netif_running(netdev)) {
-+ WARN_ON(test_bit(__E1000_RESETTING, &adapter->flags));
- e1000_down(adapter);
-+ }
-+
-+#ifdef CONFIG_PM
-+ /* Implement our own version of pci_save_state(pdev) because pci-
-+ * express adapters have 256-byte config spaces. */
-+ retval = e1000_pci_save_state(adapter);
-+ if (retval)
-+ return retval;
-+#endif
-
- status = E1000_READ_REG(&adapter->hw, STATUS);
-- if(status & E1000_STATUS_LU)
-+ if (status & E1000_STATUS_LU)
- wufc &= ~E1000_WUFC_LNKC;
-
-- if(wufc) {
-+ if (wufc) {
- e1000_setup_rctl(adapter);
- e1000_set_multi(netdev);
-
- /* turn on all-multi mode if wake on multicast is enabled */
-- if(adapter->wol & E1000_WUFC_MC) {
-+ if (wufc & E1000_WUFC_MC) {
- rctl = E1000_READ_REG(&adapter->hw, RCTL);
- rctl |= E1000_RCTL_MPE;
- E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
- }
-
-- if(adapter->hw.mac_type >= e1000_82540) {
-+ if (adapter->hw.mac_type >= e1000_82540) {
- ctrl = E1000_READ_REG(&adapter->hw, CTRL);
- /* advertise wake from D3Cold */
- #define E1000_CTRL_ADVD3WUC 0x00100000
-@@ -2833,7 +4802,7 @@ e1000_suspend(struct pci_dev *pdev, uint
- E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);
- }
-
-- if(adapter->hw.media_type == e1000_media_type_fiber ||
-+ if (adapter->hw.media_type == e1000_media_type_fiber ||
- adapter->hw.media_type == e1000_media_type_internal_serdes) {
- /* keep the laser running in D3 */
- ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
-@@ -2841,81 +4810,115 @@ e1000_suspend(struct pci_dev *pdev, uint
- E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);
- }
-
-+ /* Allow time for pending master requests to run */
-+ e1000_disable_pciex_master(&adapter->hw);
-+
- E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);
- E1000_WRITE_REG(&adapter->hw, WUFC, wufc);
-- pci_enable_wake(pdev, 3, 1);
-- pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
-+ pci_enable_wake(pdev, PCI_D3hot, 1);
-+ pci_enable_wake(pdev, PCI_D3cold, 1);
- } else {
- E1000_WRITE_REG(&adapter->hw, WUC, 0);
- E1000_WRITE_REG(&adapter->hw, WUFC, 0);
-- pci_enable_wake(pdev, 3, 0);
-- pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
-+ pci_enable_wake(pdev, PCI_D3hot, 0);
-+ pci_enable_wake(pdev, PCI_D3cold, 0);
- }
-
-- pci_save_state(pdev, adapter->pci_state);
--
-- if(adapter->hw.mac_type >= e1000_82540 &&
-+ /* FIXME: this code is incorrect for PCI Express */
-+ if (adapter->hw.mac_type >= e1000_82540 &&
-+ adapter->hw.mac_type != e1000_ich8lan &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
-- if(manc & E1000_MANC_SMBUS_EN) {
-+ if (manc & E1000_MANC_SMBUS_EN) {
- manc |= E1000_MANC_ARP_EN;
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
-- pci_enable_wake(pdev, 3, 1);
-- pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */
-+ pci_enable_wake(pdev, PCI_D3hot, 1);
-+ pci_enable_wake(pdev, PCI_D3cold, 1);
- }
- }
-
-- state = (state > 0) ? 3 : 0;
-- pci_set_power_state(pdev, state);
-+ if (adapter->hw.phy_type == e1000_phy_igp_3)
-+ e1000_phy_powerdown_workaround(&adapter->hw);
-+
-+ /* Release control of h/w to f/w. If f/w is AMT enabled, this
-+ * would have already happened in close and is redundant. */
-+ e1000_release_hw_control(adapter);
-+
-+ pci_disable_device(pdev);
-+
-+ pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
- return 0;
- }
-
-+#ifdef USE_DRIVER_SHUTDOWN_HANDLER
-+static void e1000_shutdown(struct pci_dev *pdev)
-+{
-+ e1000_suspend(pdev, PMSG_SUSPEND);
-+}
-+#endif
-+
- #ifdef CONFIG_PM
- static int
- e1000_resume(struct pci_dev *pdev)
- {
- struct net_device *netdev = pci_get_drvdata(pdev);
-- struct e1000_adapter *adapter = netdev->priv;
-- uint32_t manc;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+ uint32_t manc, ret_val;
-
-- pci_set_power_state(pdev, 0);
-- pci_restore_state(pdev, adapter->pci_state);
-+ pci_set_power_state(pdev, PCI_D0);
-+ e1000_pci_restore_state(adapter);
-+ ret_val = pci_enable_device(pdev);
-+ pci_set_master(pdev);
-
-- pci_enable_wake(pdev, 3, 0);
-- pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */
-+ pci_enable_wake(pdev, PCI_D3hot, 0);
-+ pci_enable_wake(pdev, PCI_D3cold, 0);
-
- e1000_reset(adapter);
- E1000_WRITE_REG(&adapter->hw, WUS, ~0);
-
-- if(netif_running(netdev))
-+ if (netif_running(netdev))
- e1000_up(adapter);
-
- netif_device_attach(netdev);
-
-- if(adapter->hw.mac_type >= e1000_82540 &&
-+ /* FIXME: this code is incorrect for PCI Express */
-+ if (adapter->hw.mac_type >= e1000_82540 &&
-+ adapter->hw.mac_type != e1000_ich8lan &&
- adapter->hw.media_type == e1000_media_type_copper) {
- manc = E1000_READ_REG(&adapter->hw, MANC);
- manc &= ~(E1000_MANC_ARP_EN);
- E1000_WRITE_REG(&adapter->hw, MANC, manc);
- }
-
-+ /* If the controller is 82573 and f/w is AMT, do not set
-+ * DRV_LOAD until the interface is up. For all other cases,
-+ * let the f/w know that the h/w is now under the control
-+ * of the driver. */
-+ if (adapter->hw.mac_type != e1000_82573 ||
-+ !e1000_check_mng_mode(&adapter->hw))
-+ e1000_get_hw_control(adapter);
-+
- return 0;
- }
- #endif
--
- #ifdef CONFIG_NET_POLL_CONTROLLER
- /*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
--
--static void e1000_netpoll (struct net_device *dev)
-+static void
-+e1000_netpoll(struct net_device *netdev)
- {
-- struct e1000_adapter *adapter = dev->priv;
-+ struct e1000_adapter *adapter = netdev_priv(netdev);
-+
- disable_irq(adapter->pdev->irq);
-- e1000_intr (adapter->pdev->irq, dev, NULL);
-+ e1000_intr(adapter->pdev->irq, netdev, NULL);
-+ e1000_clean_tx_irq(adapter, adapter->tx_ring);
-+#ifndef CONFIG_E1000_NAPI
-+ adapter->clean_rx(adapter, adapter->rx_ring);
-+#endif
- enable_irq(adapter->pdev->irq);
- }
- #endif
-diff -pruN ./drivers/net/e1000.orig/e1000_osdep.h ./drivers/net/e1000/e1000_osdep.h
---- ./drivers/net/e1000.orig/e1000_osdep.h 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_osdep.h 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -40,15 +41,23 @@
- #include <asm/io.h>
- #include <linux/interrupt.h>
- #include <linux/sched.h>
-+#include "kcompat.h"
-
-+#define usec_delay(x) udelay(x)
- #ifndef msec_delay
- #define msec_delay(x) do { if(in_interrupt()) { \
- /* Don't mdelay in interrupt context! */ \
- BUG(); \
- } else { \
-- set_current_state(TASK_UNINTERRUPTIBLE); \
-- schedule_timeout((x * HZ)/1000 + 2); \
-- } } while(0)
-+ msleep(x); \
-+ } } while (0)
-+
-+/* Some workarounds require millisecond delays and are run during interrupt
-+ * context. Most notably, when establishing link, the phy may need tweaking
-+ * but cannot process phy register reads/writes faster than millisecond
-+ * intervals...and we establish link due to a "link status change" interrupt.
-+ */
-+#define msec_delay_irq(x) mdelay(x)
- #endif
-
- #define PCI_COMMAND_REGISTER PCI_COMMAND
-@@ -76,6 +85,9 @@ typedef enum {
- #define DEBUGOUT3 DEBUGOUT2
- #define DEBUGOUT7 DEBUGOUT3
-
-+#ifdef __BIG_ENDIAN
-+#define E1000_BIG_ENDIAN __BIG_ENDIAN
-+#endif
-
- #define E1000_WRITE_REG(a, reg, value) ( \
- writel((value), ((a)->hw_addr + \
-@@ -95,6 +107,42 @@ typedef enum {
- (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
- ((offset) << 2)))
-
-+#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY
-+#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY
-+
-+#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \
-+ writew((value), ((a)->hw_addr + \
-+ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
-+ ((offset) << 1))))
-+
-+#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \
-+ readw((a)->hw_addr + \
-+ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
-+ ((offset) << 1)))
-+
-+#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \
-+ writeb((value), ((a)->hw_addr + \
-+ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
-+ (offset))))
-+
-+#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \
-+ readb((a)->hw_addr + \
-+ (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \
-+ (offset)))
-+
- #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS)
-
-+#define E1000_WRITE_ICH8_REG(a, reg, value) ( \
-+ writel((value), ((a)->flash_address + reg)))
-+
-+#define E1000_READ_ICH8_REG(a, reg) ( \
-+ readl((a)->flash_address + reg))
-+
-+#define E1000_WRITE_ICH8_REG16(a, reg, value) ( \
-+ writew((value), ((a)->flash_address + reg)))
-+
-+#define E1000_READ_ICH8_REG16(a, reg) ( \
-+ readw((a)->flash_address + reg))
-+
-+
- #endif /* _E1000_OSDEP_H_ */
-diff -pruN ./drivers/net/e1000.orig/e1000_param.c ./drivers/net/e1000/e1000_param.c
---- ./drivers/net/e1000.orig/e1000_param.c 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/e1000_param.c 2006-08-18 09:10:33.000000000 +0400
-@@ -1,7 +1,7 @@
- /*******************************************************************************
-
-
-- Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved.
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
-@@ -22,6 +22,7 @@
-
- Contact Information:
- Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
- *******************************************************************************/
-@@ -34,10 +35,17 @@
-
- #define E1000_MAX_NIC 32
-
--#define OPTION_UNSET -1
-+#define OPTION_UNSET -1
- #define OPTION_DISABLED 0
- #define OPTION_ENABLED 1
-
-+/* All parameters are treated the same, as an integer array of values.
-+ * This macro just reduces the need to repeat the same declaration code
-+ * over and over (plus this helps to avoid typo bugs).
-+ */
-+
-+#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
-+#ifndef module_param_array
- /* Module Parameters are always initialized to -1, so that the driver
- * can tell the difference between no user specified value or the
- * user asking for the default value.
-@@ -48,17 +56,17 @@
- * "Extensions to the C Language Family" of the GCC documentation.
- */
-
--#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET }
--
--/* All parameters are treated the same, as an integer array of values.
-- * This macro just reduces the need to repeat the same declaration code
-- * over and over (plus this helps to avoid typo bugs).
-- */
--
--#define E1000_PARAM(X, S) \
--static const int __devinitdata X[E1000_MAX_NIC + 1] = E1000_PARAM_INIT; \
--MODULE_PARM(X, "1-" __MODULE_STRING(E1000_MAX_NIC) "i"); \
--MODULE_PARM_DESC(X, S);
-+#define E1000_PARAM(X, desc) \
-+ static const int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
-+ MODULE_PARM(X, "1-" __MODULE_STRING(E1000_MAX_NIC) "i"); \
-+ MODULE_PARM_DESC(X, desc);
-+#else
-+#define E1000_PARAM(X, desc) \
-+ static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \
-+ static int num_##X = 0; \
-+ module_param_array_named(X, X, int, &num_##X, 0); \
-+ MODULE_PARM_DESC(X, desc);
-+#endif
-
- /* Transmit Descriptor Count
- *
-@@ -187,11 +195,29 @@ E1000_PARAM(RxAbsIntDelay, "Receive Abso
- *
- * Valid Range: 100-100000 (0=off, 1=dynamic)
- *
-- * Default Value: 1
-+ * Default Value: 8000
- */
-
- E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
-
-+/* Enable Smart Power Down of the PHY
-+ *
-+ * Valid Range: 0, 1
-+ *
-+ * Default Value: 0 (disabled)
-+ */
-+
-+E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
-+
-+/* Enable Kumeran Lock Loss workaround
-+ *
-+ * Valid Range: 0, 1
-+ *
-+ * Default Value: 1 (enabled)
-+ */
-+
-+E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround");
-+
- #define AUTONEG_ADV_DEFAULT 0x2F
- #define AUTONEG_ADV_MASK 0x2F
- #define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL
-@@ -212,7 +238,7 @@ E1000_PARAM(InterruptThrottleRate, "Inte
- #define MAX_TXABSDELAY 0xFFFF
- #define MIN_TXABSDELAY 0
-
--#define DEFAULT_ITR 1
-+#define DEFAULT_ITR 8000
- #define MAX_ITR 100000
- #define MIN_ITR 100
-
-@@ -235,9 +261,9 @@ struct e1000_option {
-
- static int __devinit
- e1000_validate_option(int *value, struct e1000_option *opt,
-- struct e1000_adapter *adapter)
-+ struct e1000_adapter *adapter)
- {
-- if(*value == OPTION_UNSET) {
-+ if (*value == OPTION_UNSET) {
- *value = opt->def;
- return 0;
- }
-@@ -254,9 +280,9 @@ e1000_validate_option(int *value, struct
- }
- break;
- case range_option:
-- if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
- DPRINTK(PROBE, INFO,
-- "%s set to %i\n", opt->name, *value);
-+ "%s set to %i\n", opt->name, *value);
- return 0;
- }
- break;
-@@ -264,10 +290,10 @@ e1000_validate_option(int *value, struct
- int i;
- struct e1000_opt_list *ent;
-
-- for(i = 0; i < opt->arg.l.nr; i++) {
-+ for (i = 0; i < opt->arg.l.nr; i++) {
- ent = &opt->arg.l.p[i];
-- if(*value == ent->i) {
-- if(ent->str[0] != '\0')
-+ if (*value == ent->i) {
-+ if (ent->str[0] != '\0')
- DPRINTK(PROBE, INFO, "%s\n", ent->str);
- return 0;
- }
-@@ -278,7 +304,7 @@ e1000_validate_option(int *value, struct
- BUG();
- }
-
-- DPRINTK(PROBE, INFO, "Invalid %s specified (%i) %s\n",
-+ DPRINTK(PROBE, INFO, "Invalid %s value specified (%i) %s\n",
- opt->name, *value, opt->err);
- *value = opt->def;
- return -1;
-@@ -301,11 +327,13 @@ void __devinit
- e1000_check_options(struct e1000_adapter *adapter)
- {
- int bd = adapter->bd_number;
-- if(bd >= E1000_MAX_NIC) {
-+ if (bd >= E1000_MAX_NIC) {
- DPRINTK(PROBE, NOTICE,
- "Warning: no configuration for board #%i\n", bd);
- DPRINTK(PROBE, NOTICE, "Using defaults for all values\n");
-+#ifndef module_param_array
- bd = E1000_MAX_NIC;
-+#endif
- }
-
- { /* Transmit Descriptor Count */
-@@ -317,14 +345,26 @@ e1000_check_options(struct e1000_adapter
- .def = E1000_DEFAULT_TXD,
- .arg = { .r = { .min = E1000_MIN_TXD }}
- };
-- struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
-+ struct e1000_tx_ring *tx_ring = adapter->tx_ring;
-+ int i;
- e1000_mac_type mac_type = adapter->hw.mac_type;
- opt.arg.r.max = mac_type < e1000_82544 ?
- E1000_MAX_TXD : E1000_MAX_82544_TXD;
-
-- tx_ring->count = TxDescriptors[bd];
-- e1000_validate_option(&tx_ring->count, &opt, adapter);
-- E1000_ROUNDUP(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE);
-+#ifdef module_param_array
-+ if (num_TxDescriptors > bd) {
-+#endif
-+ tx_ring->count = TxDescriptors[bd];
-+ e1000_validate_option(&tx_ring->count, &opt, adapter);
-+ E1000_ROUNDUP(tx_ring->count,
-+ REQ_TX_DESCRIPTOR_MULTIPLE);
-+#ifdef module_param_array
-+ } else {
-+ tx_ring->count = opt.def;
-+ }
-+#endif
-+ for (i = 0; i < adapter->num_tx_queues; i++)
-+ tx_ring[i].count = tx_ring->count;
- }
- { /* Receive Descriptor Count */
- struct e1000_option opt = {
-@@ -335,14 +375,26 @@ e1000_check_options(struct e1000_adapter
- .def = E1000_DEFAULT_RXD,
- .arg = { .r = { .min = E1000_MIN_RXD }}
- };
-- struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
-+ struct e1000_rx_ring *rx_ring = adapter->rx_ring;
-+ int i;
- e1000_mac_type mac_type = adapter->hw.mac_type;
- opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
- E1000_MAX_82544_RXD;
-
-- rx_ring->count = RxDescriptors[bd];
-- e1000_validate_option(&rx_ring->count, &opt, adapter);
-- E1000_ROUNDUP(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE);
-+#ifdef module_param_array
-+ if (num_RxDescriptors > bd) {
-+#endif
-+ rx_ring->count = RxDescriptors[bd];
-+ e1000_validate_option(&rx_ring->count, &opt, adapter);
-+ E1000_ROUNDUP(rx_ring->count,
-+ REQ_RX_DESCRIPTOR_MULTIPLE);
-+#ifdef module_param_array
-+ } else {
-+ rx_ring->count = opt.def;
-+ }
-+#endif
-+ for (i = 0; i < adapter->num_rx_queues; i++)
-+ rx_ring[i].count = rx_ring->count;
- }
- { /* Checksum Offload Enable/Disable */
- struct e1000_option opt = {
-@@ -352,9 +404,17 @@ e1000_check_options(struct e1000_adapter
- .def = OPTION_ENABLED
- };
-
-- int rx_csum = XsumRX[bd];
-- e1000_validate_option(&rx_csum, &opt, adapter);
-- adapter->rx_csum = rx_csum;
-+#ifdef module_param_array
-+ if (num_XsumRX > bd) {
-+#endif
-+ int rx_csum = XsumRX[bd];
-+ e1000_validate_option(&rx_csum, &opt, adapter);
-+ adapter->rx_csum = rx_csum;
-+#ifdef module_param_array
-+ } else {
-+ adapter->rx_csum = opt.def;
-+ }
-+#endif
- }
- { /* Flow Control */
-
-@@ -374,9 +434,17 @@ e1000_check_options(struct e1000_adapter
- .p = fc_list }}
- };
-
-- int fc = FlowControl[bd];
-- e1000_validate_option(&fc, &opt, adapter);
-- adapter->hw.fc = adapter->hw.original_fc = fc;
-+#ifdef module_param_array
-+ if (num_FlowControl > bd) {
-+#endif
-+ int fc = FlowControl[bd];
-+ e1000_validate_option(&fc, &opt, adapter);
-+ adapter->hw.fc = adapter->hw.original_fc = fc;
-+#ifdef module_param_array
-+ } else {
-+ adapter->hw.fc = adapter->hw.original_fc = opt.def;
-+ }
-+#endif
- }
- { /* Transmit Interrupt Delay */
- struct e1000_option opt = {
-@@ -388,8 +456,17 @@ e1000_check_options(struct e1000_adapter
- .max = MAX_TXDELAY }}
- };
-
-- adapter->tx_int_delay = TxIntDelay[bd];
-- e1000_validate_option(&adapter->tx_int_delay, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_TxIntDelay > bd) {
-+#endif
-+ adapter->tx_int_delay = TxIntDelay[bd];
-+ e1000_validate_option(&adapter->tx_int_delay, &opt,
-+ adapter);
-+#ifdef module_param_array
-+ } else {
-+ adapter->tx_int_delay = opt.def;
-+ }
-+#endif
- }
- { /* Transmit Absolute Interrupt Delay */
- struct e1000_option opt = {
-@@ -401,8 +478,17 @@ e1000_check_options(struct e1000_adapter
- .max = MAX_TXABSDELAY }}
- };
-
-- adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
-- e1000_validate_option(&adapter->tx_abs_int_delay, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_TxAbsIntDelay > bd) {
-+#endif
-+ adapter->tx_abs_int_delay = TxAbsIntDelay[bd];
-+ e1000_validate_option(&adapter->tx_abs_int_delay, &opt,
-+ adapter);
-+#ifdef module_param_array
-+ } else {
-+ adapter->tx_abs_int_delay = opt.def;
-+ }
-+#endif
- }
- { /* Receive Interrupt Delay */
- struct e1000_option opt = {
-@@ -414,8 +500,17 @@ e1000_check_options(struct e1000_adapter
- .max = MAX_RXDELAY }}
- };
-
-- adapter->rx_int_delay = RxIntDelay[bd];
-- e1000_validate_option(&adapter->rx_int_delay, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_RxIntDelay > bd) {
-+#endif
-+ adapter->rx_int_delay = RxIntDelay[bd];
-+ e1000_validate_option(&adapter->rx_int_delay, &opt,
-+ adapter);
-+#ifdef module_param_array
-+ } else {
-+ adapter->rx_int_delay = opt.def;
-+ }
-+#endif
- }
- { /* Receive Absolute Interrupt Delay */
- struct e1000_option opt = {
-@@ -427,8 +522,17 @@ e1000_check_options(struct e1000_adapter
- .max = MAX_RXABSDELAY }}
- };
-
-- adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
-- e1000_validate_option(&adapter->rx_abs_int_delay, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_RxAbsIntDelay > bd) {
-+#endif
-+ adapter->rx_abs_int_delay = RxAbsIntDelay[bd];
-+ e1000_validate_option(&adapter->rx_abs_int_delay, &opt,
-+ adapter);
-+#ifdef module_param_array
-+ } else {
-+ adapter->rx_abs_int_delay = opt.def;
-+ }
-+#endif
- }
- { /* Interrupt Throttling Rate */
- struct e1000_option opt = {
-@@ -440,25 +544,72 @@ e1000_check_options(struct e1000_adapter
- .max = MAX_ITR }}
- };
-
-- adapter->itr = InterruptThrottleRate[bd];
-- switch(adapter->itr) {
-- case -1:
-- adapter->itr = 1;
-- break;
-- case 0:
-- DPRINTK(PROBE, INFO, "%s turned off\n", opt.name);
-- break;
-- case 1:
-- DPRINTK(PROBE, INFO,
-- "%s set to dynamic mode\n", opt.name);
-- break;
-- default:
-- e1000_validate_option(&adapter->itr, &opt, adapter);
-- break;
-+#ifdef module_param_array
-+ if (num_InterruptThrottleRate > bd) {
-+#endif
-+ adapter->itr = InterruptThrottleRate[bd];
-+ switch (adapter->itr) {
-+ case 0:
-+ DPRINTK(PROBE, INFO, "%s turned off\n",
-+ opt.name);
-+ break;
-+ case 1:
-+ DPRINTK(PROBE, INFO, "%s set to dynamic mode\n",
-+ opt.name);
-+ break;
-+ default:
-+ e1000_validate_option(&adapter->itr, &opt,
-+ adapter);
-+ break;
-+ }
-+#ifdef module_param_array
-+ } else {
-+ adapter->itr = opt.def;
-+ }
-+#endif
-+ }
-+ { /* Smart Power Down */
-+ struct e1000_option opt = {
-+ .type = enable_option,
-+ .name = "PHY Smart Power Down",
-+ .err = "defaulting to Disabled",
-+ .def = OPTION_DISABLED
-+ };
-+
-+#ifdef module_param_array
-+ if (num_SmartPowerDownEnable > bd) {
-+#endif
-+ int spd = SmartPowerDownEnable[bd];
-+ e1000_validate_option(&spd, &opt, adapter);
-+ adapter->smart_power_down = spd;
-+#ifdef module_param_array
-+ } else {
-+ adapter->smart_power_down = opt.def;
-+ }
-+#endif
-+ }
-+ { /* Kumeran Lock Loss Workaround */
-+ struct e1000_option opt = {
-+ .type = enable_option,
-+ .name = "Kumeran Lock Loss Workaround",
-+ .err = "defaulting to Enabled",
-+ .def = OPTION_ENABLED
-+ };
-+
-+#ifdef module_param_array
-+ if (num_KumeranLockLoss > bd) {
-+#endif
-+ int kmrn_lock_loss = KumeranLockLoss[bd];
-+ e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
-+ adapter->hw.kmrn_lock_loss_workaround_disabled = !kmrn_lock_loss;
-+#ifdef module_param_array
-+ } else {
-+ adapter->hw.kmrn_lock_loss_workaround_disabled = !opt.def;
- }
-+#endif
- }
-
-- switch(adapter->hw.media_type) {
-+ switch (adapter->hw.media_type) {
- case e1000_media_type_fiber:
- case e1000_media_type_internal_serdes:
- e1000_check_fiber_options(adapter);
-@@ -482,19 +633,33 @@ static void __devinit
- e1000_check_fiber_options(struct e1000_adapter *adapter)
- {
- int bd = adapter->bd_number;
-+#ifndef module_param_array
- bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
--
-- if((Speed[bd] != OPTION_UNSET)) {
-+ if ((Speed[bd] != OPTION_UNSET)) {
-+#else
-+ if (num_Speed > bd) {
-+#endif
- DPRINTK(PROBE, INFO, "Speed not valid for fiber adapters, "
- "parameter ignored\n");
- }
-- if((Duplex[bd] != OPTION_UNSET)) {
-+
-+#ifndef module_param_array
-+ if ((Duplex[bd] != OPTION_UNSET)) {
-+#else
-+ if (num_Duplex > bd) {
-+#endif
- DPRINTK(PROBE, INFO, "Duplex not valid for fiber adapters, "
- "parameter ignored\n");
- }
-- if((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) {
-- DPRINTK(PROBE, INFO, "AutoNeg other than Full/1000 is "
-- "not valid for fiber adapters, parameter ignored\n");
-+
-+#ifndef module_param_array
-+ if ((AutoNeg[bd] != OPTION_UNSET) && (AutoNeg[bd] != 0x20)) {
-+#else
-+ if ((num_AutoNeg > bd) && (AutoNeg[bd] != 0x20)) {
-+#endif
-+ DPRINTK(PROBE, INFO, "AutoNeg other than 1000/Full is "
-+ "not valid for fiber adapters, "
-+ "parameter ignored\n");
- }
- }
-
-@@ -508,9 +673,11 @@ e1000_check_fiber_options(struct e1000_a
- static void __devinit
- e1000_check_copper_options(struct e1000_adapter *adapter)
- {
-- int speed, dplx;
-+ int speed, dplx, an;
- int bd = adapter->bd_number;
-+#ifndef module_param_array
- bd = bd > E1000_MAX_NIC ? E1000_MAX_NIC : bd;
-+#endif
-
- { /* Speed */
- struct e1000_opt_list speed_list[] = {{ 0, "" },
-@@ -527,8 +694,16 @@ e1000_check_copper_options(struct e1000_
- .p = speed_list }}
- };
-
-- speed = Speed[bd];
-- e1000_validate_option(&speed, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_Speed > bd) {
-+#endif
-+ speed = Speed[bd];
-+ e1000_validate_option(&speed, &opt, adapter);
-+#ifdef module_param_array
-+ } else {
-+ speed = opt.def;
-+ }
-+#endif
- }
- { /* Duplex */
- struct e1000_opt_list dplx_list[] = {{ 0, "" },
-@@ -544,11 +719,29 @@ e1000_check_copper_options(struct e1000_
- .p = dplx_list }}
- };
-
-- dplx = Duplex[bd];
-- e1000_validate_option(&dplx, &opt, adapter);
-+ if (e1000_check_phy_reset_block(&adapter->hw)) {
-+ DPRINTK(PROBE, INFO,
-+ "Link active due to SoL/IDER Session. "
-+ "Speed/Duplex/AutoNeg parameter ignored.\n");
-+ return;
-+ }
-+#ifdef module_param_array
-+ if (num_Duplex > bd) {
-+#endif
-+ dplx = Duplex[bd];
-+ e1000_validate_option(&dplx, &opt, adapter);
-+#ifdef module_param_array
-+ } else {
-+ dplx = opt.def;
-+ }
-+#endif
- }
-
-- if(AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
-+#ifdef module_param_array
-+ if ((num_AutoNeg > bd) && (speed != 0 || dplx != 0)) {
-+#else
-+ if (AutoNeg[bd] != OPTION_UNSET && (speed != 0 || dplx != 0)) {
-+#endif
- DPRINTK(PROBE, INFO,
- "AutoNeg specified along with Speed or Duplex, "
- "parameter ignored\n");
-@@ -597,38 +790,50 @@ e1000_check_copper_options(struct e1000_
- .p = an_list }}
- };
-
-- int an = AutoNeg[bd];
-- e1000_validate_option(&an, &opt, adapter);
-+#ifdef module_param_array
-+ if (num_AutoNeg > bd) {
-+#endif
-+ an = AutoNeg[bd];
-+ e1000_validate_option(&an, &opt, adapter);
-+#ifdef module_param_array
-+ } else {
-+ an = opt.def;
-+ }
-+#endif
- adapter->hw.autoneg_advertised = an;
- }
-
- switch (speed + dplx) {
- case 0:
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
-- if(Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
-+#ifdef module_param_array
-+ if ((num_Speed > bd) && (speed != 0 || dplx != 0))
-+#else
-+ if (Speed[bd] != OPTION_UNSET || Duplex[bd] != OPTION_UNSET)
-+#endif
- DPRINTK(PROBE, INFO,
- "Speed and duplex autonegotiation enabled\n");
- break;
- case HALF_DUPLEX:
- DPRINTK(PROBE, INFO, "Half Duplex specified without Speed\n");
-- DPRINTK(PROBE, INFO,
-- "Using Autonegotiation at Half Duplex only\n");
-+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
-+ "Half Duplex only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
- ADVERTISE_100_HALF;
- break;
- case FULL_DUPLEX:
- DPRINTK(PROBE, INFO, "Full Duplex specified without Speed\n");
-- DPRINTK(PROBE, INFO,
-- "Using Autonegotiation at Full Duplex only\n");
-+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
-+ "Full Duplex only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_10_FULL |
- ADVERTISE_100_FULL |
- ADVERTISE_1000_FULL;
- break;
- case SPEED_10:
-- DPRINTK(PROBE, INFO,
-- "10 Mbps Speed specified without Duplex\n");
-+ DPRINTK(PROBE, INFO, "10 Mbps Speed specified "
-+ "without Duplex\n");
- DPRINTK(PROBE, INFO, "Using Autonegotiation at 10 Mbps only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_10_HALF |
-@@ -647,10 +852,10 @@ e1000_check_copper_options(struct e1000_
- adapter->hw.autoneg_advertised = 0;
- break;
- case SPEED_100:
-- DPRINTK(PROBE, INFO,
-- "100 Mbps Speed specified without Duplex\n");
-- DPRINTK(PROBE, INFO,
-- "Using Autonegotiation at 100 Mbps only\n");
-+ DPRINTK(PROBE, INFO, "100 Mbps Speed specified "
-+ "without Duplex\n");
-+ DPRINTK(PROBE, INFO, "Using Autonegotiation at "
-+ "100 Mbps only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_100_HALF |
- ADVERTISE_100_FULL;
-@@ -668,10 +873,11 @@ e1000_check_copper_options(struct e1000_
- adapter->hw.autoneg_advertised = 0;
- break;
- case SPEED_1000:
-+ DPRINTK(PROBE, INFO, "1000 Mbps Speed specified without "
-+ "Duplex\n");
- DPRINTK(PROBE, INFO,
-- "1000 Mbps Speed specified without Duplex\n");
-- DPRINTK(PROBE, INFO,
-- "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
-+ "Using Autonegotiation at 1000 Mbps "
-+ "Full Duplex only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
- break;
-@@ -679,7 +885,8 @@ e1000_check_copper_options(struct e1000_
- DPRINTK(PROBE, INFO,
- "Half Duplex is not supported at 1000 Mbps\n");
- DPRINTK(PROBE, INFO,
-- "Using Autonegotiation at 1000 Mbps Full Duplex only\n");
-+ "Using Autonegotiation at 1000 Mbps "
-+ "Full Duplex only\n");
- adapter->hw.autoneg = adapter->fc_autoneg = 1;
- adapter->hw.autoneg_advertised = ADVERTISE_1000_FULL;
- break;
-@@ -696,8 +903,8 @@ e1000_check_copper_options(struct e1000_
- /* Speed, AutoNeg and MDI/MDI-X must all play nice */
- if (e1000_validate_mdi_setting(&(adapter->hw)) < 0) {
- DPRINTK(PROBE, INFO,
-- "Speed, AutoNeg and MDI-X specifications are "
-- "incompatible. Setting MDI-X to a compatible value.\n");
-+ "Speed, AutoNeg and MDI-X specifications are "
-+ "incompatible. Setting MDI-X to a compatible value.\n");
- }
- }
-
-diff -pruN ./drivers/net/e1000.orig/kcompat.c ./drivers/net/e1000/kcompat.c
---- ./drivers/net/e1000.orig/kcompat.c 1970-01-01 03:00:00.000000000 +0300
-+++ ./drivers/net/e1000/kcompat.c 2006-08-18 09:10:33.000000000 +0400
-@@ -0,0 +1,183 @@
-+/*******************************************************************************
-+
-+
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2 of the License, or (at your option)
-+ any later version.
-+
-+ This program is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ more details.
-+
-+ You should have received a copy of the GNU General Public License along with
-+ this program; if not, write to the Free Software Foundation, Inc., 59
-+ Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+ The full GNU General Public License is included in this distribution in the
-+ file called LICENSE.
-+
-+ Contact Information:
-+ Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-+
-+*******************************************************************************/
-+
-+#include "kcompat.h"
-+
-+/*****************************************************************************/
-+/* 2.4.13 => 2.4.3 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
-+
-+/**************************************/
-+/* PCI DMA MAPPING */
-+
-+#if defined(CONFIG_HIGHMEM)
-+
-+#ifndef PCI_DRAM_OFFSET
-+#define PCI_DRAM_OFFSET 0
-+#endif
-+
-+u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction)
-+{
-+ return (((u64)(page - mem_map) << PAGE_SHIFT) + offset + PCI_DRAM_OFFSET);
-+}
-+
-+#else /* CONFIG_HIGHMEM */
-+
-+u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction)
-+{
-+ return pci_map_single(dev, (void *)page_address(page) + offset, size, direction);
-+}
-+
-+#endif /* CONFIG_HIGHMEM */
-+
-+void _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, int direction)
-+{
-+ return pci_unmap_single(dev, dma_addr, size, direction);
-+}
-+
-+#endif /* 2.4.13 => 2.4.3 */
-+
-+
-+/*****************************************************************************/
-+/* 2.4.3 => 2.4.0 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
-+
-+/**************************************/
-+/* PCI DRIVER API */
-+
-+int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask)
-+{
-+ if (!pci_dma_supported(dev, mask))
-+ return -EIO;
-+ dev->dma_mask = mask;
-+ return 0;
-+}
-+
-+int _kc_pci_request_regions(struct pci_dev *dev, char *res_name)
-+{
-+ int i;
-+
-+ for (i = 0; i < 6; i++) {
-+ if (pci_resource_len(dev, i) == 0)
-+ continue;
-+
-+ if (pci_resource_flags(dev, i) & IORESOURCE_IO) {
-+ if (!request_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
-+ pci_release_regions(dev);
-+ return -EBUSY;
-+ }
-+ } else if (pci_resource_flags(dev, i) & IORESOURCE_MEM) {
-+ if (!request_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i), res_name)) {
-+ pci_release_regions(dev);
-+ return -EBUSY;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+void _kc_pci_release_regions(struct pci_dev *dev)
-+{
-+ int i;
-+
-+ for (i = 0; i < 6; i++) {
-+ if (pci_resource_len(dev, i) == 0)
-+ continue;
-+
-+ if (pci_resource_flags(dev, i) & IORESOURCE_IO)
-+ release_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
-+
-+ else if (pci_resource_flags(dev, i) & IORESOURCE_MEM)
-+ release_mem_region(pci_resource_start(dev, i), pci_resource_len(dev, i));
-+ }
-+}
-+
-+/**************************************/
-+/* NETWORK DRIVER API */
-+
-+struct net_device * _kc_alloc_etherdev(int sizeof_priv)
-+{
-+ struct net_device *dev;
-+ int alloc_size;
-+
-+ alloc_size = sizeof (*dev) + sizeof_priv + IFNAMSIZ + 31;
-+
-+ dev = kmalloc(alloc_size, GFP_KERNEL);
-+
-+ if (!dev) return NULL;
-+
-+ memset(dev, 0, alloc_size);
-+
-+ if (sizeof_priv)
-+ dev->priv = (void *) (((unsigned long)(dev + 1) + 31) & ~31);
-+
-+ dev->name[0] = '\0';
-+
-+ ether_setup(dev);
-+
-+ return dev;
-+}
-+
-+int _kc_is_valid_ether_addr(u8 *addr)
-+{
-+ const char zaddr[6] = {0,};
-+
-+ return !(addr[0]&1) && memcmp( addr, zaddr, 6);
-+}
-+
-+#endif /* 2.4.3 => 2.4.0 */
-+
-+
-+/*****************************************************************************/
-+/* 2.4.6 => 2.4.3 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
-+
-+int _kc_pci_set_power_state(struct pci_dev *dev, int state)
-+{ return 0; }
-+int _kc_pci_save_state(struct pci_dev *dev, u32 *buffer)
-+{ return 0; }
-+int _kc_pci_restore_state(struct pci_dev *pdev, u32 *buffer)
-+{ return 0; }
-+int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable)
-+{ return 0; }
-+
-+#endif /* 2.4.6 => 2.4.3 */
-+
-+/*****************************************************************************/
-+/* 2.6.0 => 2.4.6 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-+void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size)
-+{
-+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-+ frag->page = page;
-+ frag->page_offset = off;
-+ frag->size = size;
-+ skb_shinfo(skb)->nr_frags = i + 1;
-+}
-+#endif /* 2.6.0 => 2.4.6 */
-diff -pruN ./drivers/net/e1000.orig/kcompat_ethtool.c ./drivers/net/e1000/kcompat_ethtool.c
---- ./drivers/net/e1000.orig/kcompat_ethtool.c 1970-01-01 03:00:00.000000000 +0300
-+++ ./drivers/net/e1000/kcompat_ethtool.c 2006-08-18 09:10:33.000000000 +0400
-@@ -0,0 +1,851 @@
-+/*******************************************************************************
-+
-+
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2 of the License, or (at your option)
-+ any later version.
-+
-+ This program is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ more details.
-+
-+ You should have received a copy of the GNU General Public License along with
-+ this program; if not, write to the Free Software Foundation, Inc., 59
-+ Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+ The full GNU General Public License is included in this distribution in the
-+ file called LICENSE.
-+
-+ Contact Information:
-+ Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-+
-+*******************************************************************************/
-+
-+/*
-+ * net/core/ethtool.c - Ethtool ioctl handler
-+ * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
-+ *
-+ * This file is where we call all the ethtool_ops commands to get
-+ * the information ethtool needs. We fall back to calling do_ioctl()
-+ * for drivers which haven't been converted to ethtool_ops yet.
-+ *
-+ * It's GPL, stupid.
-+ *
-+ * Modification by sfeldma@pobox.com to work as backward compat
-+ * solution for pre-ethtool_ops kernels.
-+ * - copied struct ethtool_ops from ethtool.h
-+ * - defined SET_ETHTOOL_OPS
-+ * - put in some #ifndef NETIF_F_xxx wrappers
-+ * - changes refs to dev->ethtool_ops to ethtool_ops
-+ * - changed dev_ethtool to ethtool_ioctl
-+ * - remove EXPORT_SYMBOL()s
-+ * - added _kc_ prefix in built-in ethtool_op_xxx ops.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/ethtool.h>
-+#include <linux/netdevice.h>
-+#include <asm/uaccess.h>
-+
-+#ifndef ETH_GSTRING_LEN
-+#define ETH_GSTRING_LEN 32
-+#endif
-+
-+#undef ethtool_ops
-+#define ethtool_ops _kc_ethtool_ops
-+
-+struct _kc_ethtool_ops {
-+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
-+ int (*set_settings)(struct net_device *, struct ethtool_cmd *);
-+ void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
-+ int (*get_regs_len)(struct net_device *);
-+ void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);
-+ void (*get_wol)(struct net_device *, struct ethtool_wolinfo *);
-+ int (*set_wol)(struct net_device *, struct ethtool_wolinfo *);
-+ u32 (*get_msglevel)(struct net_device *);
-+ void (*set_msglevel)(struct net_device *, u32);
-+ int (*nway_reset)(struct net_device *);
-+ u32 (*get_link)(struct net_device *);
-+ int (*get_eeprom_len)(struct net_device *);
-+ int (*get_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
-+ int (*set_eeprom)(struct net_device *, struct ethtool_eeprom *, u8 *);
-+ int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *);
-+ int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *);
-+ void (*get_ringparam)(struct net_device *, struct ethtool_ringparam *);
-+ int (*set_ringparam)(struct net_device *, struct ethtool_ringparam *);
-+ void (*get_pauseparam)(struct net_device *, struct ethtool_pauseparam*);
-+ int (*set_pauseparam)(struct net_device *, struct ethtool_pauseparam*);
-+ u32 (*get_rx_csum)(struct net_device *);
-+ int (*set_rx_csum)(struct net_device *, u32);
-+ u32 (*get_tx_csum)(struct net_device *);
-+ int (*set_tx_csum)(struct net_device *, u32);
-+ u32 (*get_sg)(struct net_device *);
-+ int (*set_sg)(struct net_device *, u32);
-+ u32 (*get_tso)(struct net_device *);
-+ int (*set_tso)(struct net_device *, u32);
-+ int (*self_test_count)(struct net_device *);
-+ void (*self_test)(struct net_device *, struct ethtool_test *, u64 *);
-+ void (*get_strings)(struct net_device *, u32 stringset, u8 *);
-+ int (*phys_id)(struct net_device *, u32);
-+ int (*get_stats_count)(struct net_device *);
-+ void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
-+} *ethtool_ops = NULL;
-+
-+#undef SET_ETHTOOL_OPS
-+#define SET_ETHTOOL_OPS(netdev, ops) (ethtool_ops = (ops))
-+
-+/*
-+ * Some useful ethtool_ops methods that're device independent.
-+ * If we find that all drivers want to do the same thing here,
-+ * we can turn these into dev_() function calls.
-+ */
-+
-+#undef ethtool_op_get_link
-+#define ethtool_op_get_link _kc_ethtool_op_get_link
-+uint32_t _kc_ethtool_op_get_link(struct net_device *dev)
-+{
-+ return netif_carrier_ok(dev) ? 1 : 0;
-+}
-+
-+#undef ethtool_op_get_tx_csum
-+#define ethtool_op_get_tx_csum _kc_ethtool_op_get_tx_csum
-+uint32_t _kc_ethtool_op_get_tx_csum(struct net_device *dev)
-+{
-+#ifdef NETIF_F_IP_CSUM
-+ return (dev->features & NETIF_F_IP_CSUM) != 0;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+#undef ethtool_op_set_tx_csum
-+#define ethtool_op_set_tx_csum _kc_ethtool_op_set_tx_csum
-+int _kc_ethtool_op_set_tx_csum(struct net_device *dev, uint32_t data)
-+{
-+#ifdef NETIF_F_IP_CSUM
-+ if (data)
-+ dev->features |= NETIF_F_IP_CSUM;
-+ else
-+ dev->features &= ~NETIF_F_IP_CSUM;
-+#endif
-+
-+ return 0;
-+}
-+
-+#undef ethtool_op_get_sg
-+#define ethtool_op_get_sg _kc_ethtool_op_get_sg
-+uint32_t _kc_ethtool_op_get_sg(struct net_device *dev)
-+{
-+#ifdef NETIF_F_SG
-+ return (dev->features & NETIF_F_SG) != 0;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+#undef ethtool_op_set_sg
-+#define ethtool_op_set_sg _kc_ethtool_op_set_sg
-+int _kc_ethtool_op_set_sg(struct net_device *dev, uint32_t data)
-+{
-+#ifdef NETIF_F_SG
-+ if (data)
-+ dev->features |= NETIF_F_SG;
-+ else
-+ dev->features &= ~NETIF_F_SG;
-+#endif
-+
-+ return 0;
-+}
-+
-+#undef ethtool_op_get_tso
-+#define ethtool_op_get_tso _kc_ethtool_op_get_tso
-+uint32_t _kc_ethtool_op_get_tso(struct net_device *dev)
-+{
-+#ifdef NETIF_F_TSO
-+ return (dev->features & NETIF_F_TSO) != 0;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+#undef ethtool_op_set_tso
-+#define ethtool_op_set_tso _kc_ethtool_op_set_tso
-+int _kc_ethtool_op_set_tso(struct net_device *dev, uint32_t data)
-+{
-+#ifdef NETIF_F_TSO
-+ if (data)
-+ dev->features |= NETIF_F_TSO;
-+ else
-+ dev->features &= ~NETIF_F_TSO;
-+#endif
-+
-+ return 0;
-+}
-+
-+/* Handlers for each ethtool command */
-+
-+static int ethtool_get_settings(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_cmd cmd = { ETHTOOL_GSET };
-+ int err;
-+
-+ if (!ethtool_ops->get_settings)
-+ return -EOPNOTSUPP;
-+
-+ err = ethtool_ops->get_settings(dev, &cmd);
-+ if (err < 0)
-+ return err;
-+
-+ if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_settings(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_cmd cmd;
-+
-+ if (!ethtool_ops->set_settings)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_settings(dev, &cmd);
-+}
-+
-+static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_drvinfo info;
-+ struct ethtool_ops *ops = ethtool_ops;
-+
-+ if (!ops->get_drvinfo)
-+ return -EOPNOTSUPP;
-+
-+ memset(&info, 0, sizeof(info));
-+ info.cmd = ETHTOOL_GDRVINFO;
-+ ops->get_drvinfo(dev, &info);
-+
-+ if (ops->self_test_count)
-+ info.testinfo_len = ops->self_test_count(dev);
-+ if (ops->get_stats_count)
-+ info.n_stats = ops->get_stats_count(dev);
-+ if (ops->get_regs_len)
-+ info.regdump_len = ops->get_regs_len(dev);
-+ if (ops->get_eeprom_len)
-+ info.eedump_len = ops->get_eeprom_len(dev);
-+
-+ if (copy_to_user(useraddr, &info, sizeof(info)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_get_regs(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_regs regs;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ void *regbuf;
-+ int reglen, ret;
-+
-+ if (!ops->get_regs || !ops->get_regs_len)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&regs, useraddr, sizeof(regs)))
-+ return -EFAULT;
-+
-+ reglen = ops->get_regs_len(dev);
-+ if (regs.len > reglen)
-+ regs.len = reglen;
-+
-+ regbuf = kmalloc(reglen, GFP_USER);
-+ if (!regbuf)
-+ return -ENOMEM;
-+
-+ ops->get_regs(dev, &regs, regbuf);
-+
-+ ret = -EFAULT;
-+ if (copy_to_user(useraddr, &regs, sizeof(regs)))
-+ goto out;
-+ useraddr += offsetof(struct ethtool_regs, data);
-+ if (copy_to_user(useraddr, regbuf, reglen))
-+ goto out;
-+ ret = 0;
-+
-+out:
-+ kfree(regbuf);
-+ return ret;
-+}
-+
-+static int ethtool_get_wol(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_wolinfo wol = { ETHTOOL_GWOL };
-+
-+ if (!ethtool_ops->get_wol)
-+ return -EOPNOTSUPP;
-+
-+ ethtool_ops->get_wol(dev, &wol);
-+
-+ if (copy_to_user(useraddr, &wol, sizeof(wol)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_wol(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_wolinfo wol;
-+
-+ if (!ethtool_ops->set_wol)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&wol, useraddr, sizeof(wol)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_wol(dev, &wol);
-+}
-+
-+static int ethtool_get_msglevel(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GMSGLVL };
-+
-+ if (!ethtool_ops->get_msglevel)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_msglevel(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_msglevel(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata;
-+
-+ if (!ethtool_ops->set_msglevel)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+ return -EFAULT;
-+
-+ ethtool_ops->set_msglevel(dev, edata.data);
-+ return 0;
-+}
-+
-+static int ethtool_nway_reset(struct net_device *dev)
-+{
-+ if (!ethtool_ops->nway_reset)
-+ return -EOPNOTSUPP;
-+
-+ return ethtool_ops->nway_reset(dev);
-+}
-+
-+static int ethtool_get_link(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GLINK };
-+
-+ if (!ethtool_ops->get_link)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_link(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_get_eeprom(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_eeprom eeprom;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ uint8_t *data;
-+ int ret;
-+
-+ if (!ops->get_eeprom || !ops->get_eeprom_len)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
-+ return -EFAULT;
-+
-+ /* Check for wrap and zero */
-+ if (eeprom.offset + eeprom.len <= eeprom.offset)
-+ return -EINVAL;
-+
-+ /* Check for exceeding total eeprom len */
-+ if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
-+ return -EINVAL;
-+
-+ data = kmalloc(eeprom.len, GFP_USER);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ ret = -EFAULT;
-+ if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
-+ goto out;
-+
-+ ret = ops->get_eeprom(dev, &eeprom, data);
-+ if (ret)
-+ goto out;
-+
-+ ret = -EFAULT;
-+ if (copy_to_user(useraddr, &eeprom, sizeof(eeprom)))
-+ goto out;
-+ if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len))
-+ goto out;
-+ ret = 0;
-+
-+out:
-+ kfree(data);
-+ return ret;
-+}
-+
-+static int ethtool_set_eeprom(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_eeprom eeprom;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ uint8_t *data;
-+ int ret;
-+
-+ if (!ops->set_eeprom || !ops->get_eeprom_len)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom)))
-+ return -EFAULT;
-+
-+ /* Check for wrap and zero */
-+ if (eeprom.offset + eeprom.len <= eeprom.offset)
-+ return -EINVAL;
-+
-+ /* Check for exceeding total eeprom len */
-+ if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev))
-+ return -EINVAL;
-+
-+ data = kmalloc(eeprom.len, GFP_USER);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ ret = -EFAULT;
-+ if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len))
-+ goto out;
-+
-+ ret = ops->set_eeprom(dev, &eeprom, data);
-+ if (ret)
-+ goto out;
-+
-+ if (copy_to_user(useraddr + sizeof(eeprom), data, eeprom.len))
-+ ret = -EFAULT;
-+
-+out:
-+ kfree(data);
-+ return ret;
-+}
-+
-+static int ethtool_get_coalesce(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE };
-+
-+ if (!ethtool_ops->get_coalesce)
-+ return -EOPNOTSUPP;
-+
-+ ethtool_ops->get_coalesce(dev, &coalesce);
-+
-+ if (copy_to_user(useraddr, &coalesce, sizeof(coalesce)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_coalesce(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_coalesce coalesce;
-+
-+ if (!ethtool_ops->get_coalesce)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&coalesce, useraddr, sizeof(coalesce)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_coalesce(dev, &coalesce);
-+}
-+
-+static int ethtool_get_ringparam(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM };
-+
-+ if (!ethtool_ops->get_ringparam)
-+ return -EOPNOTSUPP;
-+
-+ ethtool_ops->get_ringparam(dev, &ringparam);
-+
-+ if (copy_to_user(useraddr, &ringparam, sizeof(ringparam)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_ringparam(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_ringparam ringparam;
-+
-+ if (!ethtool_ops->get_ringparam)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&ringparam, useraddr, sizeof(ringparam)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_ringparam(dev, &ringparam);
-+}
-+
-+static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM };
-+
-+ if (!ethtool_ops->get_pauseparam)
-+ return -EOPNOTSUPP;
-+
-+ ethtool_ops->get_pauseparam(dev, &pauseparam);
-+
-+ if (copy_to_user(useraddr, &pauseparam, sizeof(pauseparam)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_pauseparam pauseparam;
-+
-+ if (!ethtool_ops->get_pauseparam)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_pauseparam(dev, &pauseparam);
-+}
-+
-+static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GRXCSUM };
-+
-+ if (!ethtool_ops->get_rx_csum)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_rx_csum(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata;
-+
-+ if (!ethtool_ops->set_rx_csum)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+ return -EFAULT;
-+
-+ ethtool_ops->set_rx_csum(dev, edata.data);
-+ return 0;
-+}
-+
-+static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GTXCSUM };
-+
-+ if (!ethtool_ops->get_tx_csum)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_tx_csum(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata;
-+
-+ if (!ethtool_ops->set_tx_csum)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_tx_csum(dev, edata.data);
-+}
-+
-+static int ethtool_get_sg(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GSG };
-+
-+ if (!ethtool_ops->get_sg)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_sg(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_sg(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata;
-+
-+ if (!ethtool_ops->set_sg)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_sg(dev, edata.data);
-+}
-+
-+static int ethtool_get_tso(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata = { ETHTOOL_GTSO };
-+
-+ if (!ethtool_ops->get_tso)
-+ return -EOPNOTSUPP;
-+
-+ edata.data = ethtool_ops->get_tso(dev);
-+
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int ethtool_set_tso(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_value edata;
-+
-+ if (!ethtool_ops->set_tso)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&edata, useraddr, sizeof(edata)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->set_tso(dev, edata.data);
-+}
-+
-+static int ethtool_self_test(struct net_device *dev, char *useraddr)
-+{
-+ struct ethtool_test test;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ u64 *data;
-+ int ret;
-+
-+ if (!ops->self_test || !ops->self_test_count)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&test, useraddr, sizeof(test)))
-+ return -EFAULT;
-+
-+ test.len = ops->self_test_count(dev);
-+ data = kmalloc(test.len * sizeof(u64), GFP_USER);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ ops->self_test(dev, &test, data);
-+
-+ ret = -EFAULT;
-+ if (copy_to_user(useraddr, &test, sizeof(test)))
-+ goto out;
-+ useraddr += sizeof(test);
-+ if (copy_to_user(useraddr, data, test.len * sizeof(u64)))
-+ goto out;
-+ ret = 0;
-+
-+out:
-+ kfree(data);
-+ return ret;
-+}
-+
-+static int ethtool_get_strings(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_gstrings gstrings;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ uint8_t *data;
-+ int ret;
-+
-+ if (!ops->get_strings)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
-+ return -EFAULT;
-+
-+ switch (gstrings.string_set) {
-+ case ETH_SS_TEST:
-+ if (!ops->self_test_count)
-+ return -EOPNOTSUPP;
-+ gstrings.len = ops->self_test_count(dev);
-+ break;
-+ case ETH_SS_STATS:
-+ if (!ops->get_stats_count)
-+ return -EOPNOTSUPP;
-+ gstrings.len = ops->get_stats_count(dev);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ ops->get_strings(dev, gstrings.string_set, data);
-+
-+ ret = -EFAULT;
-+ if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
-+ goto out;
-+ useraddr += sizeof(gstrings);
-+ if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
-+ goto out;
-+ ret = 0;
-+
-+out:
-+ kfree(data);
-+ return ret;
-+}
-+
-+static int ethtool_phys_id(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_value id;
-+
-+ if (!ethtool_ops->phys_id)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&id, useraddr, sizeof(id)))
-+ return -EFAULT;
-+
-+ return ethtool_ops->phys_id(dev, id.data);
-+}
-+
-+static int ethtool_get_stats(struct net_device *dev, void *useraddr)
-+{
-+ struct ethtool_stats stats;
-+ struct ethtool_ops *ops = ethtool_ops;
-+ u64 *data;
-+ int ret;
-+
-+ if (!ops->get_ethtool_stats || !ops->get_stats_count)
-+ return -EOPNOTSUPP;
-+
-+ if (copy_from_user(&stats, useraddr, sizeof(stats)))
-+ return -EFAULT;
-+
-+ stats.n_stats = ops->get_stats_count(dev);
-+ data = kmalloc(stats.n_stats * sizeof(u64), GFP_USER);
-+ if (!data)
-+ return -ENOMEM;
-+
-+ ops->get_ethtool_stats(dev, &stats, data);
-+
-+ ret = -EFAULT;
-+ if (copy_to_user(useraddr, &stats, sizeof(stats)))
-+ goto out;
-+ useraddr += sizeof(stats);
-+ if (copy_to_user(useraddr, data, stats.n_stats * sizeof(u64)))
-+ goto out;
-+ ret = 0;
-+
-+out:
-+ kfree(data);
-+ return ret;
-+}
-+
-+/* The main entry point in this file. Called from net/core/dev.c */
-+
-+#define ETHTOOL_OPS_COMPAT
-+int ethtool_ioctl(struct ifreq *ifr)
-+{
-+ struct net_device *dev = __dev_get_by_name(ifr->ifr_name);
-+ void *useraddr = (void *) ifr->ifr_data;
-+ uint32_t ethcmd;
-+
-+ /*
-+ * XXX: This can be pushed down into the ethtool_* handlers that
-+ * need it. Keep existing behaviour for the moment.
-+ */
-+ if (!dev || !netif_device_present(dev))
-+ return -ENODEV;
-+
-+ if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
-+ return -EFAULT;
-+
-+ switch (ethcmd) {
-+ case ETHTOOL_GSET:
-+ return ethtool_get_settings(dev, useraddr);
-+ case ETHTOOL_SSET:
-+ return ethtool_set_settings(dev, useraddr);
-+ case ETHTOOL_GDRVINFO:
-+ return ethtool_get_drvinfo(dev, useraddr);
-+ case ETHTOOL_GREGS:
-+ return ethtool_get_regs(dev, useraddr);
-+ case ETHTOOL_GWOL:
-+ return ethtool_get_wol(dev, useraddr);
-+ case ETHTOOL_SWOL:
-+ return ethtool_set_wol(dev, useraddr);
-+ case ETHTOOL_GMSGLVL:
-+ return ethtool_get_msglevel(dev, useraddr);
-+ case ETHTOOL_SMSGLVL:
-+ return ethtool_set_msglevel(dev, useraddr);
-+ case ETHTOOL_NWAY_RST:
-+ return ethtool_nway_reset(dev);
-+ case ETHTOOL_GLINK:
-+ return ethtool_get_link(dev, useraddr);
-+ case ETHTOOL_GEEPROM:
-+ return ethtool_get_eeprom(dev, useraddr);
-+ case ETHTOOL_SEEPROM:
-+ return ethtool_set_eeprom(dev, useraddr);
-+ case ETHTOOL_GCOALESCE:
-+ return ethtool_get_coalesce(dev, useraddr);
-+ case ETHTOOL_SCOALESCE:
-+ return ethtool_set_coalesce(dev, useraddr);
-+ case ETHTOOL_GRINGPARAM:
-+ return ethtool_get_ringparam(dev, useraddr);
-+ case ETHTOOL_SRINGPARAM:
-+ return ethtool_set_ringparam(dev, useraddr);
-+ case ETHTOOL_GPAUSEPARAM:
-+ return ethtool_get_pauseparam(dev, useraddr);
-+ case ETHTOOL_SPAUSEPARAM:
-+ return ethtool_set_pauseparam(dev, useraddr);
-+ case ETHTOOL_GRXCSUM:
-+ return ethtool_get_rx_csum(dev, useraddr);
-+ case ETHTOOL_SRXCSUM:
-+ return ethtool_set_rx_csum(dev, useraddr);
-+ case ETHTOOL_GTXCSUM:
-+ return ethtool_get_tx_csum(dev, useraddr);
-+ case ETHTOOL_STXCSUM:
-+ return ethtool_set_tx_csum(dev, useraddr);
-+ case ETHTOOL_GSG:
-+ return ethtool_get_sg(dev, useraddr);
-+ case ETHTOOL_SSG:
-+ return ethtool_set_sg(dev, useraddr);
-+ case ETHTOOL_GTSO:
-+ return ethtool_get_tso(dev, useraddr);
-+ case ETHTOOL_STSO:
-+ return ethtool_set_tso(dev, useraddr);
-+ case ETHTOOL_TEST:
-+ return ethtool_self_test(dev, useraddr);
-+ case ETHTOOL_GSTRINGS:
-+ return ethtool_get_strings(dev, useraddr);
-+ case ETHTOOL_PHYS_ID:
-+ return ethtool_phys_id(dev, useraddr);
-+ case ETHTOOL_GSTATS:
-+ return ethtool_get_stats(dev, useraddr);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+
-+ return -EOPNOTSUPP;
-+}
-diff -pruN ./drivers/net/e1000.orig/kcompat.h ./drivers/net/e1000/kcompat.h
---- ./drivers/net/e1000.orig/kcompat.h 1970-01-01 03:00:00.000000000 +0300
-+++ ./drivers/net/e1000/kcompat.h 2006-08-18 09:10:33.000000000 +0400
-@@ -0,0 +1,802 @@
-+/*******************************************************************************
-+
-+
-+ Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify it
-+ under the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 2 of the License, or (at your option)
-+ any later version.
-+
-+ This program is distributed in the hope that it will be useful, but WITHOUT
-+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ more details.
-+
-+ You should have received a copy of the GNU General Public License along with
-+ this program; if not, write to the Free Software Foundation, Inc., 59
-+ Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+ The full GNU General Public License is included in this distribution in the
-+ file called LICENSE.
-+
-+ Contact Information:
-+ Linux NICS <linux.nics@intel.com>
-+ e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
-+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-+
-+*******************************************************************************/
-+
-+#ifndef _KCOMPAT_H_
-+#define _KCOMPAT_H_
-+
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/netdevice.h>
-+#include <linux/ioport.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
-+#include <linux/list.h>
-+#include <linux/sched.h>
-+#include <asm/io.h>
-+
-+#ifndef IRQ_HANDLED
-+#define irqreturn_t void
-+#define IRQ_HANDLED
-+#define IRQ_NONE
-+#endif
-+
-+#ifndef SET_NETDEV_DEV
-+#define SET_NETDEV_DEV(net, pdev)
-+#endif
-+
-+#ifndef HAVE_FREE_NETDEV
-+#define free_netdev(x) kfree(x)
-+#endif
-+
-+#ifdef HAVE_POLL_CONTROLLER
-+#define CONFIG_NET_POLL_CONTROLLER
-+#endif
-+
-+#ifdef E1000_NAPI
-+#undef CONFIG_E1000_NAPI
-+#define CONFIG_E1000_NAPI
-+#endif
-+
-+#ifdef E1000_NO_NAPI
-+#undef CONFIG_E1000_NAPI
-+#endif
-+
-+#ifdef DISABLE_PACKET_SPLIT
-+#undef CONFIG_E1000_DISABLE_PACKET_SPLIT
-+#define CONFIG_E1000_DISABLE_PACKET_SPLIT
-+#endif
-+
-+#ifdef DISABLE_PCI_MSI
-+#undef CONFIG_PCI_MSI
-+#endif
-+
-+#ifdef DISABLE_PM
-+#undef CONFIG_PM
-+#endif
-+
-+#ifdef DISABLE_NET_POLL_CONTROLLER
-+#undef CONFIG_NET_POLL_CONTROLLER
-+#endif
-+
-+#ifndef module_param
-+#define module_param(v,t,p) MODULE_PARM(v, "i");
-+#endif
-+
-+#ifndef DMA_64BIT_MASK
-+#define DMA_64BIT_MASK 0xffffffffffffffffULL
-+#endif
-+
-+#ifndef DMA_32BIT_MASK
-+#define DMA_32BIT_MASK 0x00000000ffffffffULL
-+#endif
-+
-+/*****************************************************************************/
-+#ifndef unlikely
-+#define unlikely(_x) _x
-+#define likely(_x) _x
-+#endif
-+/*****************************************************************************/
-+
-+#ifndef PCI_DEVICE
-+#define PCI_DEVICE(vend,dev) \
-+ .vendor = (vend), .device = (dev), \
-+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-+#endif
-+
-+/*****************************************************************************/
-+/* Installations with ethtool version without eeprom, adapter id, or statistics
-+ * support */
-+#ifndef ETHTOOL_GSTATS
-+#define ETHTOOL_GSTATS 0x1d
-+#undef ethtool_drvinfo
-+#define ethtool_drvinfo k_ethtool_drvinfo
-+struct k_ethtool_drvinfo {
-+ uint32_t cmd;
-+ char driver[32];
-+ char version[32];
-+ char fw_version[32];
-+ char bus_info[32];
-+ char reserved1[32];
-+ char reserved2[16];
-+ uint32_t n_stats;
-+ uint32_t testinfo_len;
-+ uint32_t eedump_len;
-+ uint32_t regdump_len;
-+};
-+
-+struct ethtool_stats {
-+ uint32_t cmd;
-+ uint32_t n_stats;
-+ uint64_t data[0];
-+};
-+
-+#ifndef ETHTOOL_PHYS_ID
-+#define ETHTOOL_PHYS_ID 0x1c
-+#ifndef ETHTOOL_GSTRINGS
-+#define ETHTOOL_GSTRINGS 0x1b
-+enum ethtool_stringset {
-+ ETH_SS_TEST = 0,
-+ ETH_SS_STATS,
-+};
-+struct ethtool_gstrings {
-+ u32 cmd; /* ETHTOOL_GSTRINGS */
-+ u32 string_set; /* string set id e.c. ETH_SS_TEST, etc*/
-+ u32 len; /* number of strings in the string set */
-+ u8 data[0];
-+};
-+#ifndef ETHTOOL_TEST
-+#define ETHTOOL_TEST 0x1a
-+enum ethtool_test_flags {
-+ ETH_TEST_FL_OFFLINE = (1 << 0),
-+ ETH_TEST_FL_FAILED = (1 << 1),
-+};
-+struct ethtool_test {
-+ uint32_t cmd;
-+ uint32_t flags;
-+ uint32_t reserved;
-+ uint32_t len;
-+ uint64_t data[0];
-+};
-+#ifndef ETHTOOL_GEEPROM
-+#define ETHTOOL_GEEPROM 0xb
-+#undef ETHTOOL_GREGS
-+struct ethtool_eeprom {
-+ uint32_t cmd;
-+ uint32_t magic;
-+ uint32_t offset;
-+ uint32_t len;
-+ uint8_t data[0];
-+};
-+
-+struct ethtool_value {
-+ uint32_t cmd;
-+ uint32_t data;
-+};
-+
-+#ifndef ETHTOOL_GLINK
-+#define ETHTOOL_GLINK 0xa
-+#endif /* Ethtool version without link support */
-+#endif /* Ethtool version without eeprom support */
-+#endif /* Ethtool version without test support */
-+#endif /* Ethtool version without strings support */
-+#endif /* Ethtool version wihtout adapter id support */
-+#endif /* Ethtool version without statistics support */
-+
-+#ifndef ETHTOOL_GREGS
-+#define ETHTOOL_GREGS 0x00000004 /* Get NIC registers */
-+#define ethtool_regs _kc_ethtool_regs
-+/* for passing big chunks of data */
-+struct _kc_ethtool_regs {
-+ u32 cmd;
-+ u32 version; /* driver-specific, indicates different chips/revs */
-+ u32 len; /* bytes */
-+ u8 data[0];
-+};
-+#endif
-+#ifndef ETHTOOL_GMSGLVL
-+#define ETHTOOL_GMSGLVL 0x00000007 /* Get driver message level */
-+#endif
-+#ifndef ETHTOOL_SMSGLVL
-+#define ETHTOOL_SMSGLVL 0x00000008 /* Set driver msg level, priv. */
-+#endif
-+#ifndef ETHTOOL_NWAY_RST
-+#define ETHTOOL_NWAY_RST 0x00000009 /* Restart autonegotiation, priv */
-+#endif
-+#ifndef ETHTOOL_GLINK
-+#define ETHTOOL_GLINK 0x0000000a /* Get link status */
-+#endif
-+#ifndef ETHTOOL_GEEPROM
-+#define ETHTOOL_GEEPROM 0x0000000b /* Get EEPROM data */
-+#endif
-+#ifndef ETHTOOL_SEEPROM
-+#define ETHTOOL_SEEPROM 0x0000000c /* Set EEPROM data */
-+#endif
-+#ifndef ETHTOOL_GCOALESCE
-+#define ETHTOOL_GCOALESCE 0x0000000e /* Get coalesce config */
-+/* for configuring coalescing parameters of chip */
-+#define ethtool_coalesce _kc_ethtool_coalesce
-+struct _kc_ethtool_coalesce {
-+ u32 cmd; /* ETHTOOL_{G,S}COALESCE */
-+
-+ /* How many usecs to delay an RX interrupt after
-+ * a packet arrives. If 0, only rx_max_coalesced_frames
-+ * is used.
-+ */
-+ u32 rx_coalesce_usecs;
-+
-+ /* How many packets to delay an RX interrupt after
-+ * a packet arrives. If 0, only rx_coalesce_usecs is
-+ * used. It is illegal to set both usecs and max frames
-+ * to zero as this would cause RX interrupts to never be
-+ * generated.
-+ */
-+ u32 rx_max_coalesced_frames;
-+
-+ /* Same as above two parameters, except that these values
-+ * apply while an IRQ is being serviced by the host. Not
-+ * all cards support this feature and the values are ignored
-+ * in that case.
-+ */
-+ u32 rx_coalesce_usecs_irq;
-+ u32 rx_max_coalesced_frames_irq;
-+
-+ /* How many usecs to delay a TX interrupt after
-+ * a packet is sent. If 0, only tx_max_coalesced_frames
-+ * is used.
-+ */
-+ u32 tx_coalesce_usecs;
-+
-+ /* How many packets to delay a TX interrupt after
-+ * a packet is sent. If 0, only tx_coalesce_usecs is
-+ * used. It is illegal to set both usecs and max frames
-+ * to zero as this would cause TX interrupts to never be
-+ * generated.
-+ */
-+ u32 tx_max_coalesced_frames;
-+
-+ /* Same as above two parameters, except that these values
-+ * apply while an IRQ is being serviced by the host. Not
-+ * all cards support this feature and the values are ignored
-+ * in that case.
-+ */
-+ u32 tx_coalesce_usecs_irq;
-+ u32 tx_max_coalesced_frames_irq;
-+
-+ /* How many usecs to delay in-memory statistics
-+ * block updates. Some drivers do not have an in-memory
-+ * statistic block, and in such cases this value is ignored.
-+ * This value must not be zero.
-+ */
-+ u32 stats_block_coalesce_usecs;
-+
-+ /* Adaptive RX/TX coalescing is an algorithm implemented by
-+ * some drivers to improve latency under low packet rates and
-+ * improve throughput under high packet rates. Some drivers
-+ * only implement one of RX or TX adaptive coalescing. Anything
-+ * not implemented by the driver causes these values to be
-+ * silently ignored.
-+ */
-+ u32 use_adaptive_rx_coalesce;
-+ u32 use_adaptive_tx_coalesce;
-+
-+ /* When the packet rate (measured in packets per second)
-+ * is below pkt_rate_low, the {rx,tx}_*_low parameters are
-+ * used.
-+ */
-+ u32 pkt_rate_low;
-+ u32 rx_coalesce_usecs_low;
-+ u32 rx_max_coalesced_frames_low;
-+ u32 tx_coalesce_usecs_low;
-+ u32 tx_max_coalesced_frames_low;
-+
-+ /* When the packet rate is below pkt_rate_high but above
-+ * pkt_rate_low (both measured in packets per second) the
-+ * normal {rx,tx}_* coalescing parameters are used.
-+ */
-+
-+ /* When the packet rate is (measured in packets per second)
-+ * is above pkt_rate_high, the {rx,tx}_*_high parameters are
-+ * used.
-+ */
-+ u32 pkt_rate_high;
-+ u32 rx_coalesce_usecs_high;
-+ u32 rx_max_coalesced_frames_high;
-+ u32 tx_coalesce_usecs_high;
-+ u32 tx_max_coalesced_frames_high;
-+
-+ /* How often to do adaptive coalescing packet rate sampling,
-+ * measured in seconds. Must not be zero.
-+ */
-+ u32 rate_sample_interval;
-+};
-+#endif
-+#ifndef ETHTOOL_SCOALESCE
-+#define ETHTOOL_SCOALESCE 0x0000000f /* Set coalesce config. */
-+#endif
-+#ifndef ETHTOOL_GRINGPARAM
-+#define ETHTOOL_GRINGPARAM 0x00000010 /* Get ring parameters */
-+/* for configuring RX/TX ring parameters */
-+#define ethtool_ringparam _kc_ethtool_ringparam
-+struct _kc_ethtool_ringparam {
-+ u32 cmd; /* ETHTOOL_{G,S}RINGPARAM */
-+
-+ /* Read only attributes. These indicate the maximum number
-+ * of pending RX/TX ring entries the driver will allow the
-+ * user to set.
-+ */
-+ u32 rx_max_pending;
-+ u32 rx_mini_max_pending;
-+ u32 rx_jumbo_max_pending;
-+ u32 tx_max_pending;
-+
-+ /* Values changeable by the user. The valid values are
-+ * in the range 1 to the "*_max_pending" counterpart above.
-+ */
-+ u32 rx_pending;
-+ u32 rx_mini_pending;
-+ u32 rx_jumbo_pending;
-+ u32 tx_pending;
-+};
-+#endif
-+#ifndef ETHTOOL_SRINGPARAM
-+#define ETHTOOL_SRINGPARAM 0x00000011 /* Set ring parameters, priv. */
-+#endif
-+#ifndef ETHTOOL_GPAUSEPARAM
-+#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
-+/* for configuring link flow control parameters */
-+#define ethtool_pauseparam _kc_ethtool_pauseparam
-+struct _kc_ethtool_pauseparam {
-+ u32 cmd; /* ETHTOOL_{G,S}PAUSEPARAM */
-+
-+ /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
-+ * being true) the user may set 'autonet' here non-zero to have the
-+ * pause parameters be auto-negotiated too. In such a case, the
-+ * {rx,tx}_pause values below determine what capabilities are
-+ * advertised.
-+ *
-+ * If 'autoneg' is zero or the link is not being auto-negotiated,
-+ * then {rx,tx}_pause force the driver to use/not-use pause
-+ * flow control.
-+ */
-+ u32 autoneg;
-+ u32 rx_pause;
-+ u32 tx_pause;
-+};
-+#endif
-+#ifndef ETHTOOL_SPAUSEPARAM
-+#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
-+#endif
-+#ifndef ETHTOOL_GRXCSUM
-+#define ETHTOOL_GRXCSUM 0x00000014 /* Get RX hw csum enable (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_SRXCSUM
-+#define ETHTOOL_SRXCSUM 0x00000015 /* Set RX hw csum enable (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_GTXCSUM
-+#define ETHTOOL_GTXCSUM 0x00000016 /* Get TX hw csum enable (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_STXCSUM
-+#define ETHTOOL_STXCSUM 0x00000017 /* Set TX hw csum enable (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_GSG
-+#define ETHTOOL_GSG 0x00000018 /* Get scatter-gather enable
-+ * (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_SSG
-+#define ETHTOOL_SSG 0x00000019 /* Set scatter-gather enable
-+ * (ethtool_value). */
-+#endif
-+#ifndef ETHTOOL_TEST
-+#define ETHTOOL_TEST 0x0000001a /* execute NIC self-test, priv. */
-+#endif
-+#ifndef ETHTOOL_GSTRINGS
-+#define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */
-+#endif
-+#ifndef ETHTOOL_PHYS_ID
-+#define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */
-+#endif
-+#ifndef ETHTOOL_GSTATS
-+#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
-+#endif
-+#ifndef ETHTOOL_GTSO
-+#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
-+#endif
-+#ifndef ETHTOOL_STSO
-+#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
-+#endif
-+
-+/*****************************************************************************/
-+/* 2.4.3 => 2.4.0 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) )
-+
-+/**************************************/
-+/* PCI DRIVER API */
-+
-+#ifndef pci_set_dma_mask
-+#define pci_set_dma_mask _kc_pci_set_dma_mask
-+extern int _kc_pci_set_dma_mask(struct pci_dev *dev, dma_addr_t mask);
-+#endif
-+
-+#ifndef pci_request_regions
-+#define pci_request_regions _kc_pci_request_regions
-+extern int _kc_pci_request_regions(struct pci_dev *pdev, char *res_name);
-+#endif
-+
-+#ifndef pci_release_regions
-+#define pci_release_regions _kc_pci_release_regions
-+extern void _kc_pci_release_regions(struct pci_dev *pdev);
-+#endif
-+
-+/**************************************/
-+/* NETWORK DRIVER API */
-+
-+#ifndef alloc_etherdev
-+#define alloc_etherdev _kc_alloc_etherdev
-+extern struct net_device * _kc_alloc_etherdev(int sizeof_priv);
-+#endif
-+
-+#ifndef is_valid_ether_addr
-+#define is_valid_ether_addr _kc_is_valid_ether_addr
-+extern int _kc_is_valid_ether_addr(u8 *addr);
-+#endif
-+
-+/**************************************/
-+/* MISCELLANEOUS */
-+
-+#ifndef INIT_TQUEUE
-+#define INIT_TQUEUE(_tq, _routine, _data) \
-+ do { \
-+ INIT_LIST_HEAD(&(_tq)->list); \
-+ (_tq)->sync = 0; \
-+ (_tq)->routine = _routine; \
-+ (_tq)->data = _data; \
-+ } while (0)
-+#endif
-+
-+#endif /* 2.4.3 => 2.4.0 */
-+
-+/*****************************************************************************/
-+/* 2.4.6 => 2.4.3 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) )
-+
-+#ifndef pci_set_power_state
-+#define pci_set_power_state _kc_pci_set_power_state
-+extern int _kc_pci_set_power_state(struct pci_dev *dev, int state);
-+#endif
-+
-+#ifndef pci_save_state
-+#define pci_save_state _kc_pci_save_state
-+extern int _kc_pci_save_state(struct pci_dev *dev, u32 *buffer);
-+#endif
-+
-+#ifndef pci_restore_state
-+#define pci_restore_state _kc_pci_restore_state
-+extern int _kc_pci_restore_state(struct pci_dev *pdev, u32 *buffer);
-+#endif
-+
-+#ifndef pci_enable_wake
-+#define pci_enable_wake _kc_pci_enable_wake
-+extern int _kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable);
-+#endif
-+
-+/* PCI PM entry point syntax changed, so don't support suspend/resume */
-+#undef CONFIG_PM
-+
-+#endif /* 2.4.6 => 2.4.3 */
-+
-+/*****************************************************************************/
-+/* 2.4.10 => 2.4.6 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) )
-+
-+/**************************************/
-+/* MODULE API */
-+
-+#ifndef MODULE_LICENSE
-+ #define MODULE_LICENSE(X)
-+#endif
-+
-+/**************************************/
-+/* OTHER */
-+
-+#define prefetch(x)
-+
-+#undef min
-+#define min(x,y) ({ \
-+ const typeof(x) _x = (x); \
-+ const typeof(y) _y = (y); \
-+ (void) (&_x == &_y); \
-+ _x < _y ? _x : _y; })
-+
-+#undef max
-+#define max(x,y) ({ \
-+ const typeof(x) _x = (x); \
-+ const typeof(y) _y = (y); \
-+ (void) (&_x == &_y); \
-+ _x > _y ? _x : _y; })
-+
-+#endif /* 2.4.10 -> 2.4.6 */
-+
-+
-+/*****************************************************************************/
-+/* 2.4.13 => 2.4.10 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) )
-+
-+/**************************************/
-+/* PCI DMA MAPPING */
-+
-+#ifndef virt_to_page
-+ #define virt_to_page(v) (mem_map + (virt_to_phys(v) >> PAGE_SHIFT))
-+#endif
-+
-+#ifndef pci_map_page
-+#define pci_map_page _kc_pci_map_page
-+extern u64 _kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, size_t size, int direction);
-+#endif
-+
-+#ifndef pci_unmap_page
-+#define pci_unmap_page _kc_pci_unmap_page
-+extern void _kc_pci_unmap_page(struct pci_dev *dev, u64 dma_addr, size_t size, int direction);
-+#endif
-+
-+/* pci_set_dma_mask takes dma_addr_t, which is only 32-bits prior to 2.4.13 */
-+
-+#undef DMA_32BIT_MASK
-+#define DMA_32BIT_MASK 0xffffffff
-+#undef DMA_64BIT_MASK
-+#define DMA_64BIT_MASK 0xffffffff
-+
-+#endif /* 2.4.13 => 2.4.10 */
-+
-+/*****************************************************************************/
-+/* 2.4.17 => 2.4.12 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17) )
-+
-+#ifndef __devexit_p
-+ #define __devexit_p(x) &(x)
-+#endif
-+
-+#endif /* 2.4.17 => 2.4.13 */
-+
-+/*****************************************************************************/
-+/* 2.4.22 => 2.4.17 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) )
-+#define pci_name(x) ((x)->slot_name)
-+#endif
-+
-+/*****************************************************************************/
-+/* 2.4.23 => 2.4.22 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) )
-+#ifdef CONFIG_E1000_NAPI
-+#ifndef netif_poll_disable
-+#define netif_poll_disable(x) _kc_netif_poll_disable(x)
-+static inline void _kc_netif_poll_disable(struct net_device *netdev)
-+{
-+ while (test_and_set_bit(__LINK_STATE_RX_SCHED, &netdev->state)) {
-+ /* No hurry */
-+ current->state = TASK_INTERRUPTIBLE;
-+ schedule_timeout(1);
-+ }
-+}
-+#endif
-+#ifndef netif_poll_enable
-+#define netif_poll_enable(x) _kc_netif_poll_enable(x)
-+static inline void _kc_netif_poll_enable(struct net_device *netdev)
-+{
-+ clear_bit(__LINK_STATE_RX_SCHED, &netdev->state);
-+}
-+#endif
-+#endif
-+#endif
-+
-+/*****************************************************************************/
-+/* 2.5.28 => 2.4.23 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) )
-+
-+static inline void _kc_synchronize_irq() { synchronize_irq(); }
-+#undef synchronize_irq
-+#define synchronize_irq(X) _kc_synchronize_irq()
-+
-+#include <linux/tqueue.h>
-+#define work_struct tq_struct
-+#define INIT_WORK INIT_TQUEUE
-+#define schedule_work schedule_task
-+#define flush_scheduled_work flush_scheduled_tasks
-+
-+#endif /* 2.5.28 => 2.4.17 */
-+
-+/*****************************************************************************/
-+/* 2.6.0 => 2.5.28 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) )
-+#define MODULE_INFO(version, _version)
-+#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-+#define CONFIG_E1000_DISABLE_PACKET_SPLIT 1
-+
-+#define pci_set_consistent_dma_mask(dev,mask) 1
-+#endif
-+
-+#undef dev_put
-+#define dev_put(dev) __dev_put(dev)
-+
-+#ifndef skb_fill_page_desc
-+#define skb_fill_page_desc _kc_skb_fill_page_desc
-+extern void _kc_skb_fill_page_desc(struct sk_buff *skb, int i, struct page *page, int off, int size);
-+#endif
-+#endif /* 2.6.0 => 2.5.28 */
-+
-+/*****************************************************************************/
-+/* 2.6.4 => 2.6.0 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) )
-+#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
-+#endif /* 2.6.4 => 2.6.0 */
-+
-+/*****************************************************************************/
-+/* 2.6.5 => 2.6.0 */
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) )
-+#define pci_dma_sync_single_for_cpu pci_dma_sync_single
-+#define pci_dma_sync_single_for_device pci_dma_sync_single_for_cpu
-+#endif /* 2.6.5 => 2.6.0 */
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25) || \
-+ ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \
-+ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4) ) )
-+#define ETHTOOL_OPS_COMPAT
-+#endif
-+
-+#ifndef HAVE_NETIF_MSG
-+#define HAVE_NETIF_MSG 1
-+enum {
-+ NETIF_MSG_DRV = 0x0001,
-+ NETIF_MSG_PROBE = 0x0002,
-+ NETIF_MSG_LINK = 0x0004,
-+ NETIF_MSG_TIMER = 0x0008,
-+ NETIF_MSG_IFDOWN = 0x0010,
-+ NETIF_MSG_IFUP = 0x0020,
-+ NETIF_MSG_RX_ERR = 0x0040,
-+ NETIF_MSG_TX_ERR = 0x0080,
-+ NETIF_MSG_TX_QUEUED = 0x0100,
-+ NETIF_MSG_INTR = 0x0200,
-+ NETIF_MSG_TX_DONE = 0x0400,
-+ NETIF_MSG_RX_STATUS = 0x0800,
-+ NETIF_MSG_PKTDATA = 0x1000,
-+ NETIF_MSG_HW = 0x2000,
-+ NETIF_MSG_WOL = 0x4000,
-+};
-+#endif /* ! HAVE_NETIF_MSG */
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) )
-+#undef if_mii
-+#define if_mii _kc_if_mii
-+static inline struct mii_ioctl_data *_kc_if_mii(struct ifreq *rq)
-+{
-+ return (struct mii_ioctl_data *) &rq->ifr_ifru;
-+}
-+#endif /* < 2.6.7 */
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) )
-+#define msleep(x) do { set_current_state(TASK_UNINTERRUPTIBLE); \
-+ schedule_timeout((x * HZ)/1000 + 2); \
-+ } while (0)
-+#endif
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9) )
-+#define msleep_interruptible(x) do {set_current_state(TASK_INTERRUPTIBLE); \
-+ schedule_timeout((x * HZ)/1000); \
-+ } while (0)
-+#endif
-+
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,6) && \
-+ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
-+#ifdef pci_save_state
-+#undef pci_save_state
-+#endif
-+#define pci_save_state(X) { \
-+ int i; \
-+ if (adapter->pci_state) { \
-+ for (i = 0; i < 16; i++) { \
-+ pci_read_config_dword((X), \
-+ i * 4, \
-+ &adapter->pci_state[i]); \
-+ } \
-+ } \
-+}
-+
-+#ifdef pci_restore_state
-+#undef pci_restore_state
-+#endif
-+#define pci_restore_state(X) { \
-+ int i; \
-+ if (adapter->pci_state) { \
-+ for (i = 0; i < 16; i++) { \
-+ pci_write_config_dword((X), \
-+ i * 4, \
-+ adapter->pci_state[i]); \
-+ } \
-+ } else { \
-+ for (i = 0; i < 6; i++) { \
-+ pci_write_config_dword((X), \
-+ PCI_BASE_ADDRESS_0 + (i * 4), \
-+ (X)->resource[i].start); \
-+ } \
-+ pci_write_config_byte((X), PCI_INTERRUPT_LINE, (X)->irq); \
-+ } \
-+}
-+#endif /* 2.4.6 <= x < 2.6.10 */
-+
-+#if (( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) ) || \
-+ (( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ) && \
-+ ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,3) )))
-+#define netdev_priv(x) x->priv
-+#endif
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) )
-+#ifdef module_param_array_named
-+#undef module_param_array_named
-+#define module_param_array_named(name, array, type, nump, perm) \
-+ static struct kparam_array __param_arr_##name \
-+ = { ARRAY_SIZE(array), nump, param_set_##type, param_get_##type, \
-+ sizeof(array[0]), array }; \
-+ module_param_call(name, param_array_set, param_array_get, \
-+ &__param_arr_##name, perm)
-+#endif /* module_param_array_named */
-+
-+#endif /* < 2.6.10 */
-+
-+#ifndef NET_IP_ALIGN
-+#define NET_IP_ALIGN 2
-+#endif
-+
-+#ifndef NETDEV_TX_OK
-+#define NETDEV_TX_OK 0 /* driver took care of the packet */
-+#endif
-+
-+#ifndef NETDEV_TX_BUSY
-+#define NETDEV_TX_BUSY 1 /* driver tx path was busy */
-+#endif
-+
-+#ifndef NETDEV_TX_LOCKED
-+#define NETDEV_TX_LOCKED -1 /* driver tx lock was already taken */
-+#endif
-+
-+/* if we do not have the infrastructure to detect if skb_header is cloned *
-+ * just return false in all cases */
-+#ifndef SKB_DATAREF_SHIFT
-+#define skb_header_cloned(x) 0
-+#endif /* SKB_DATAREF_SHIFT not defined */
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) )
-+#define PCI_D0 0
-+#define PCI_D1 1
-+#define PCI_D2 2
-+#define PCI_D3hot 3
-+#define PCI_D3cold 4
-+#define pci_choose_state(pdev,state) state
-+#define PMSG_SUSPEND 3
-+#endif
-+
-+#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) )
-+#define pm_message_t u32
-+#endif
-+
-+#ifndef WARN_ON
-+#define WARN_ON(x)
-+#endif
-+
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) )
-+#define USE_DRIVER_SHUTDOWN_HANDLER
-+#endif
-+
-+#ifndef SA_PROBEIRQ
-+#define SA_PROBEIRQ 0
-+#endif
-+
-+#endif /* _KCOMPAT_H_ */
-+
-diff -pruN ./drivers/net/e1000.orig/Makefile ./drivers/net/e1000/Makefile
---- ./drivers/net/e1000.orig/Makefile 2006-08-18 08:57:18.000000000 +0400
-+++ ./drivers/net/e1000/Makefile 2006-08-18 09:08:48.000000000 +0400
-@@ -32,4 +32,4 @@
-
- obj-$(CONFIG_E1000) += e1000.o
-
--e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o
-+e1000-objs := e1000_main.o e1000_hw.o e1000_ethtool.o e1000_param.o kcompat.o