diff options
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.patch | 20547 |
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), ®_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, ®_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, ®_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, ®_data); -+ if (ret_val) -+ return ret_val; -+ -+ ret_val = e1000_read_eeprom(hw, (word_addr + i*2 + 1), 1, ®_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(®s, 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, ®s, regbuf); -+ -+ ret = -EFAULT; -+ if (copy_to_user(useraddr, ®s, 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(ðcmd, 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 |