From 8321d03682685db4094d5132593e6d9515a6cca8 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Sun, 9 Nov 2008 23:46:37 +0000 Subject: [PATCH] Use Intel's e1000e driver with ICH10 support. --- linux-2.6-010-e1000e.patch | 37920 +++++++++++++++++++++-------------- 1 file changed, 23344 insertions(+), 14576 deletions(-) diff --git a/linux-2.6-010-e1000e.patch b/linux-2.6-010-e1000e.patch index 18dfdd713..d9deb5c10 100644 --- a/linux-2.6-010-e1000e.patch +++ b/linux-2.6-010-e1000e.patch @@ -1,11 +1,11 @@ -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/82571.c linux-2.6.22-10/drivers/net/e1000e/82571.c ---- linux-2.6.22-0/drivers/net/e1000e/82571.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/82571.c 2007-11-21 13:55:28.000000000 -0500 -@@ -0,0 +1,1351 @@ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_80003es2lan.c linux-2.6.22-10/drivers/net/e1000e/e1000_80003es2lan.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_80003es2lan.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_80003es2lan.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1545 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++ Copyright(c) 1999 - 2008 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, @@ -30,178 +30,195 @@ diff -Nurp linux-2.6.22-0/drivers/net/e1000e/82571.c linux-2.6.22-10/drivers/net + +*******************************************************************************/ + -+/* -+ * 82571EB Gigabit Ethernet Controller -+ * 82571EB Gigabit Ethernet Controller (Fiber) -+ * 82572EI Gigabit Ethernet Controller (Copper) -+ * 82572EI Gigabit Ethernet Controller (Fiber) -+ * 82572EI Gigabit Ethernet Controller -+ * 82573V Gigabit Ethernet Controller (Copper) -+ * 82573E Gigabit Ethernet Controller (Copper) -+ * 82573L Gigabit Ethernet Controller ++/* e1000_80003es2lan + */ + -+#include -+#include -+#include -+ -+#include "e1000.h" -+ -+#define ID_LED_RESERVED_F746 0xF746 -+#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \ -+ (ID_LED_OFF1_ON2 << 8) | \ -+ (ID_LED_DEF1_DEF2 << 4) | \ -+ (ID_LED_DEF1_DEF2)) -+ -+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 ++#include "e1000_hw.h" ++ ++static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw); ++static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); ++static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); ++static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ++ u32 offset, ++ u16 *data); ++static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ++ u32 offset, ++ u16 data); ++static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, ++ u16 *duplex); ++static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); ++static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); ++static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); ++static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw); ++static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data); ++static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data); ++static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); ++static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); ++static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); ++static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); ++static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); + -+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); -+static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); -+static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); -+static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, -+ u16 words, u16 *data); -+static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); -+static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); -+static s32 e1000_setup_link_82571(struct e1000_hw *hw); -+static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); ++/* ++ * A table for the GG82563 cable length where the range is defined ++ * with a lower bound at "index" and the upper bound at ++ * "index + 5". ++ */ ++static const u16 e1000_gg82563_cable_length_table[] = ++ { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; ++#define GG82563_CABLE_LENGTH_TABLE_SIZE \ ++ (sizeof(e1000_gg82563_cable_length_table) / \ ++ sizeof(e1000_gg82563_cable_length_table[0])) + +/** -+ * e1000_init_phy_params_82571 - Init PHY func ptrs. ++ * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. + * @hw: pointer to the HW structure + * + * This is a function pointer entry point called by the api module. + **/ -+static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) ++static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; ++ s32 ret_val = E1000_SUCCESS; + -+ if (hw->media_type != e1000_media_type_copper) { -+ phy->type = e1000_phy_none; -+ return 0; ++ DEBUGFUNC("e1000_init_phy_params_80003es2lan"); ++ ++ if (hw->phy.media_type != e1000_media_type_copper) { ++ phy->type = e1000_phy_none; ++ goto out; ++ } else { ++ phy->ops.power_up = e1000_power_up_phy_copper; ++ phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; + } + -+ phy->addr = 1; -+ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; -+ phy->reset_delay_us = 100; ++ phy->addr = 1; ++ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ++ phy->reset_delay_us = 100; ++ phy->type = e1000_phy_gg82563; ++ ++ phy->ops.acquire = e1000_acquire_phy_80003es2lan; ++ phy->ops.check_polarity = e1000_check_polarity_m88; ++ phy->ops.check_reset_block = e1000_check_reset_block_generic; ++ phy->ops.commit = e1000_phy_sw_reset_generic; ++ phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; ++ phy->ops.get_info = e1000_get_phy_info_m88; ++ phy->ops.release = e1000_release_phy_80003es2lan; ++ phy->ops.reset = e1000_phy_hw_reset_generic; ++ phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ phy->type = e1000_phy_igp_2; -+ break; -+ case e1000_82573: -+ phy->type = e1000_phy_m88; -+ break; -+ default: -+ return -E1000_ERR_PHY; -+ break; -+ } ++ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; ++ phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; ++ phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; ++ phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; ++ ++ phy->ops.cfg_on_link_up = e1000_cfg_on_link_up_80003es2lan; + + /* This can only be done after all function pointers are setup. */ -+ ret_val = e1000_get_phy_id_82571(hw); ++ ret_val = e1000_get_phy_id(hw); + + /* Verify phy id */ -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ if (phy->id != IGP01E1000_I_PHY_ID) -+ return -E1000_ERR_PHY; -+ break; -+ case e1000_82573: -+ if (phy->id != M88E1111_I_PHY_ID) -+ return -E1000_ERR_PHY; -+ break; -+ default: -+ return -E1000_ERR_PHY; -+ break; ++ if (phy->id != GG82563_E_PHY_ID) { ++ ret_val = -E1000_ERR_PHY; ++ goto out; + } + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_init_nvm_params_82571 - Init NVM func ptrs. ++ * e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs. + * @hw: pointer to the HW structure + * + * This is a function pointer entry point called by the api module. + **/ -+static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) ++static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 eecd = er32(EECD); ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); + u16 size; + -+ nvm->opcode_bits = 8; -+ nvm->delay_usec = 1; ++ DEBUGFUNC("e1000_init_nvm_params_80003es2lan"); ++ ++ nvm->opcode_bits = 8; ++ nvm->delay_usec = 1; + switch (nvm->override) { + case e1000_nvm_override_spi_large: -+ nvm->page_size = 32; ++ nvm->page_size = 32; + nvm->address_bits = 16; + break; + case e1000_nvm_override_spi_small: -+ nvm->page_size = 8; ++ nvm->page_size = 8; + nvm->address_bits = 8; + break; + default: -+ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; ++ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; + nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; + break; + } + -+ switch (hw->mac.type) { -+ case e1000_82573: -+ if (((eecd >> 15) & 0x3) == 0x3) { -+ nvm->type = e1000_nvm_flash_hw; -+ nvm->word_size = 2048; -+ /* Autonomous Flash update bit must be cleared due -+ * to Flash update issue. -+ */ -+ eecd &= ~E1000_EECD_AUPDEN; -+ ew32(EECD, eecd); -+ break; -+ } -+ /* Fall Through */ -+ default: -+ nvm->type = e1000_nvm_eeprom_spi; -+ size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> -+ E1000_EECD_SIZE_EX_SHIFT); -+ /* Added to a constant, "size" becomes the left-shift value -+ * for setting word_size. -+ */ -+ size += NVM_WORD_SIZE_BASE_SHIFT; -+ nvm->word_size = 1 << size; -+ break; -+ } ++ nvm->type = e1000_nvm_eeprom_spi; + -+ return 0; ++ size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> ++ E1000_EECD_SIZE_EX_SHIFT); ++ ++ /* ++ * Added to a constant, "size" becomes the left-shift value ++ * for setting word_size. ++ */ ++ size += NVM_WORD_SIZE_BASE_SHIFT; ++ ++ /* EEPROM access above 16k is unsupported */ ++ if (size > 14) ++ size = 14; ++ nvm->word_size = 1 << size; ++ ++ /* Function Pointers */ ++ nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; ++ nvm->ops.read = e1000_read_nvm_eerd; ++ nvm->ops.release = e1000_release_nvm_80003es2lan; ++ nvm->ops.update = e1000_update_nvm_checksum_generic; ++ nvm->ops.valid_led_default = e1000_valid_led_default_generic; ++ nvm->ops.validate = e1000_validate_nvm_checksum_generic; ++ nvm->ops.write = e1000_write_nvm_80003es2lan; ++ ++ return E1000_SUCCESS; +} + +/** -+ * e1000_init_mac_params_82571 - Init MAC func ptrs. ++ * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. + * @hw: pointer to the HW structure + * + * This is a function pointer entry point called by the api module. + **/ -+static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) ++static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; + struct e1000_mac_info *mac = &hw->mac; -+ struct e1000_mac_operations *func = &mac->ops; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_init_mac_params_80003es2lan"); + + /* Set media type */ -+ switch (adapter->pdev->device) { -+ case E1000_DEV_ID_82571EB_FIBER: -+ case E1000_DEV_ID_82572EI_FIBER: -+ case E1000_DEV_ID_82571EB_QUAD_FIBER: -+ hw->media_type = e1000_media_type_fiber; -+ break; -+ case E1000_DEV_ID_82571EB_SERDES: -+ case E1000_DEV_ID_82572EI_SERDES: -+ hw->media_type = e1000_media_type_internal_serdes; ++ switch (hw->device_id) { ++ case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: ++ hw->phy.media_type = e1000_media_type_internal_serdes; + break; + default: -+ hw->media_type = e1000_media_type_copper; ++ hw->phy.media_type = e1000_media_type_copper; + break; + } + @@ -209,1158 +226,1335 @@ diff -Nurp linux-2.6.22-0/drivers/net/e1000e/82571.c linux-2.6.22-10/drivers/net + mac->mta_reg_count = 128; + /* Set rar entry count */ + mac->rar_entry_count = E1000_RAR_ENTRIES; ++ /* Set if part includes ASF firmware */ ++ mac->asf_firmware_present = true; + /* Set if manageability features are enabled. */ + mac->arc_subsystem_valid = -+ (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0; -+ ++ (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) ++ ? true : false; ++ ++ /* Function pointers */ ++ ++ /* bus type/speed/width */ ++ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; ++ /* reset */ ++ mac->ops.reset_hw = e1000_reset_hw_80003es2lan; ++ /* hw initialization */ ++ mac->ops.init_hw = e1000_init_hw_80003es2lan; ++ /* link setup */ ++ mac->ops.setup_link = e1000_setup_link_generic; ++ /* physical interface link setup */ ++ mac->ops.setup_physical_interface = ++ (hw->phy.media_type == e1000_media_type_copper) ++ ? e1000_setup_copper_link_80003es2lan ++ : e1000_setup_fiber_serdes_link_generic; + /* check for link */ -+ switch (hw->media_type) { ++ switch (hw->phy.media_type) { + case e1000_media_type_copper: -+ func->setup_physical_interface = e1000_setup_copper_link_82571; -+ func->check_for_link = e1000e_check_for_copper_link; -+ func->get_link_up_info = e1000e_get_speed_and_duplex_copper; ++ mac->ops.check_for_link = e1000_check_for_copper_link_generic; + break; + case e1000_media_type_fiber: -+ func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571; -+ func->check_for_link = e1000e_check_for_fiber_link; -+ func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes; ++ mac->ops.check_for_link = e1000_check_for_fiber_link_generic; + break; + case e1000_media_type_internal_serdes: -+ func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571; -+ func->check_for_link = e1000e_check_for_serdes_link; -+ func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes; ++ mac->ops.check_for_link = e1000_check_for_serdes_link_generic; + break; + default: -+ return -E1000_ERR_CONFIG; ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; + break; + } ++ /* check management mode */ ++ mac->ops.check_mng_mode = e1000_check_mng_mode_generic; ++ /* multicast address update */ ++ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; ++ /* writing VFTA */ ++ mac->ops.write_vfta = e1000_write_vfta_generic; ++ /* clearing VFTA */ ++ mac->ops.clear_vfta = e1000_clear_vfta_generic; ++ /* setting MTA */ ++ mac->ops.mta_set = e1000_mta_set_generic; ++ /* read mac address */ ++ mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; ++ /* blink LED */ ++ mac->ops.blink_led = e1000_blink_led_generic; ++ /* setup LED */ ++ mac->ops.setup_led = e1000_setup_led_generic; ++ /* cleanup LED */ ++ mac->ops.cleanup_led = e1000_cleanup_led_generic; ++ /* turn on/off LED */ ++ mac->ops.led_on = e1000_led_on_generic; ++ mac->ops.led_off = e1000_led_off_generic; ++ /* remove device */ ++ mac->ops.remove_device = e1000_remove_device_generic; ++ /* clear hardware counters */ ++ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; ++ /* link info */ ++ mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; + -+ return 0; ++out: ++ return ret_val; +} + -+static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter) ++/** ++ * e1000_init_function_pointers_80003es2lan - Init ESB2 func ptrs. ++ * @hw: pointer to the HW structure ++ * ++ * The only function explicitly called by the api module to initialize ++ * all function pointers and parameters. ++ **/ ++void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ static int global_quad_port_a; /* global port a indication */ -+ struct pci_dev *pdev = adapter->pdev; -+ u16 eeprom_data = 0; -+ int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1; -+ s32 rc; -+ -+ rc = e1000_init_mac_params_82571(adapter); -+ if (rc) -+ return rc; -+ -+ rc = e1000_init_nvm_params_82571(hw); -+ if (rc) -+ return rc; -+ -+ rc = e1000_init_phy_params_82571(hw); -+ if (rc) -+ return rc; ++ DEBUGFUNC("e1000_init_function_pointers_80003es2lan"); + -+ /* tag quad port adapters first, it's used below */ -+ switch (pdev->device) { -+ case E1000_DEV_ID_82571EB_QUAD_COPPER: -+ case E1000_DEV_ID_82571EB_QUAD_FIBER: -+ case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: -+ adapter->flags |= FLAG_IS_QUAD_PORT; -+ /* mark the first port */ -+ if (global_quad_port_a == 0) -+ adapter->flags |= FLAG_IS_QUAD_PORT_A; -+ /* Reset for multiple quad port adapters */ -+ global_quad_port_a++; -+ if (global_quad_port_a == 4) -+ global_quad_port_a = 0; -+ break; -+ default: -+ break; -+ } ++ e1000_init_mac_ops_generic(hw); ++ e1000_init_nvm_ops_generic(hw); ++ hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; ++ hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; ++ hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; ++ e1000_get_bus_info_pcie_generic(hw); ++} + -+ switch (adapter->hw.mac.type) { -+ case e1000_82571: -+ /* these dual ports don't have WoL on port B at all */ -+ if (((pdev->device == E1000_DEV_ID_82571EB_FIBER) || -+ (pdev->device == E1000_DEV_ID_82571EB_SERDES) || -+ (pdev->device == E1000_DEV_ID_82571EB_COPPER)) && -+ (is_port_b)) -+ adapter->flags &= ~FLAG_HAS_WOL; -+ /* quad ports only support WoL on port A */ -+ if (adapter->flags & FLAG_IS_QUAD_PORT && -+ (!adapter->flags & FLAG_IS_QUAD_PORT_A)) -+ adapter->flags &= ~FLAG_HAS_WOL; -+ break; ++/** ++ * e1000_acquire_phy_80003es2lan - Acquire rights to access PHY ++ * @hw: pointer to the HW structure ++ * ++ * A wrapper to acquire access rights to the correct PHY. This is a ++ * function pointer entry point called by the api module. ++ **/ ++static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) ++{ ++ u16 mask; + -+ case e1000_82573: -+ if (pdev->device == E1000_DEV_ID_82573L) { -+ e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1, -+ &eeprom_data); -+ if (eeprom_data & NVM_WORD1A_ASPM_MASK) -+ adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; -+ } -+ break; -+ default: -+ break; -+ } ++ DEBUGFUNC("e1000_acquire_phy_80003es2lan"); + -+ return 0; ++ mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; ++ return e1000_acquire_swfw_sync_80003es2lan(hw, mask); +} + +/** -+ * e1000_get_phy_id_82571 - Retrieve the PHY ID and revision ++ * e1000_release_phy_80003es2lan - Release rights to access PHY + * @hw: pointer to the HW structure + * -+ * Reads the PHY registers and stores the PHY ID and possibly the PHY -+ * revision in the hardware structure. ++ * A wrapper to release access rights to the correct PHY. This is a ++ * function pointer entry point called by the api module. + **/ -+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) ++static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) +{ -+ struct e1000_phy_info *phy = &hw->phy; ++ u16 mask; + -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ /* 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 ID. */ -+ phy->id = IGP01E1000_I_PHY_ID; -+ break; -+ case e1000_82573: -+ return e1000e_get_phy_id(hw); -+ break; -+ default: -+ return -E1000_ERR_PHY; -+ break; -+ } ++ DEBUGFUNC("e1000_release_phy_80003es2lan"); + -+ return 0; ++ mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; ++ e1000_release_swfw_sync_80003es2lan(hw, mask); +} + ++ +/** -+ * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore ++ * e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register + * @hw: pointer to the HW structure + * -+ * Acquire the HW semaphore to access the PHY or NVM ++ * Acquire the semaphore to access the Kumeran interface. ++ * + **/ -+static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) ++static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw) +{ -+ u32 swsm; -+ s32 timeout = hw->nvm.word_size + 1; -+ s32 i = 0; -+ -+ /* Get the FW semaphore. */ -+ for (i = 0; i < timeout; i++) { -+ swsm = er32(SWSM); -+ ew32(SWSM, swsm | E1000_SWSM_SWESMBI); -+ -+ /* Semaphore acquired if bit latched */ -+ if (er32(SWSM) & E1000_SWSM_SWESMBI) -+ break; ++ u16 mask; + -+ udelay(50); -+ } ++ DEBUGFUNC("e1000_acquire_mac_csr_80003es2lan"); + -+ if (i == timeout) { -+ /* Release semaphores */ -+ e1000e_put_hw_semaphore(hw); -+ hw_dbg(hw, "Driver can't access the NVM\n"); -+ return -E1000_ERR_NVM; -+ } ++ mask = E1000_SWFW_CSR_SM; + -+ return 0; ++ return e1000_acquire_swfw_sync_80003es2lan(hw, mask); +} + +/** -+ * e1000_put_hw_semaphore_82571 - Release hardware semaphore ++ * e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register + * @hw: pointer to the HW structure + * -+ * Release hardware semaphore used to access the PHY or NVM ++ * Release the semaphore used to access the Kumeran interface + **/ -+static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) ++static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw) +{ -+ u32 swsm; ++ u16 mask; + -+ swsm = er32(SWSM); ++ DEBUGFUNC("e1000_release_mac_csr_80003es2lan"); + -+ swsm &= ~E1000_SWSM_SWESMBI; ++ mask = E1000_SWFW_CSR_SM; + -+ ew32(SWSM, swsm); ++ e1000_release_swfw_sync_80003es2lan(hw, mask); +} + +/** -+ * e1000_acquire_nvm_82571 - Request for access to the EEPROM ++ * e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM + * @hw: pointer to the HW structure + * -+ * To gain access to the EEPROM, first we must obtain a hardware semaphore. -+ * Then for non-82573 hardware, set the EEPROM access request bit and wait -+ * for EEPROM access grant bit. If the access grant bit is not set, release -+ * hardware semaphore. ++ * Acquire the semaphore to access the EEPROM. This is a function ++ * pointer entry point called by the api module. + **/ -+static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) ++static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) +{ + s32 ret_val; + -+ ret_val = e1000_get_hw_semaphore_82571(hw); ++ DEBUGFUNC("e1000_acquire_nvm_80003es2lan"); ++ ++ ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); + if (ret_val) -+ return ret_val; ++ goto out; + -+ if (hw->mac.type != e1000_82573) -+ ret_val = e1000e_acquire_nvm(hw); ++ ret_val = e1000_acquire_nvm_generic(hw); + + if (ret_val) -+ e1000_put_hw_semaphore_82571(hw); ++ e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); + ++out: + return ret_val; +} + +/** -+ * e1000_release_nvm_82571 - Release exclusive access to EEPROM ++ * e1000_release_nvm_80003es2lan - Relinquish rights to access NVM + * @hw: pointer to the HW structure + * -+ * Stop any current commands to the EEPROM and clear the EEPROM request bit. ++ * Release the semaphore used to access the EEPROM. This is a ++ * function pointer entry point called by the api module. + **/ -+static void e1000_release_nvm_82571(struct e1000_hw *hw) ++static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) +{ -+ e1000e_release_nvm(hw); -+ e1000_put_hw_semaphore_82571(hw); ++ DEBUGFUNC("e1000_release_nvm_80003es2lan"); ++ ++ e1000_release_nvm_generic(hw); ++ e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); +} + +/** -+ * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface ++ * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore + * @hw: pointer to the HW structure -+ * @offset: offset within the EEPROM to be written to -+ * @words: number of words to write -+ * @data: 16 bit word(s) to be written to the EEPROM -+ * -+ * For non-82573 silicon, write data to EEPROM at offset using SPI interface. ++ * @mask: specifies which semaphore to acquire + * -+ * If e1000e_update_nvm_checksum is not called after this function, the -+ * EEPROM will most likley contain an invalid checksum. ++ * Acquire the SW/FW semaphore to access the PHY or NVM. The mask ++ * will also specify which port we're acquiring the lock for. + **/ -+static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, -+ u16 *data) ++static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) +{ -+ s32 ret_val; ++ u32 swfw_sync; ++ u32 swmask = mask; ++ u32 fwmask = mask << 16; ++ s32 ret_val = E1000_SUCCESS; ++ s32 i = 0, timeout = 50; + -+ switch (hw->mac.type) { -+ case e1000_82573: -+ ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); -+ break; -+ case e1000_82571: -+ case e1000_82572: -+ ret_val = e1000e_write_nvm_spi(hw, offset, words, data); -+ break; -+ default: -+ ret_val = -E1000_ERR_NVM; -+ break; ++ DEBUGFUNC("e1000_acquire_swfw_sync_80003es2lan"); ++ ++ while (i < timeout) { ++ if (e1000_get_hw_semaphore_generic(hw)) { ++ ret_val = -E1000_ERR_SWFW_SYNC; ++ goto out; ++ } ++ ++ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); ++ if (!(swfw_sync & (fwmask | swmask))) ++ break; ++ ++ /* ++ * Firmware currently using resource (fwmask) ++ * or other software thread using resource (swmask) ++ */ ++ e1000_put_hw_semaphore_generic(hw); ++ msec_delay_irq(5); ++ i++; ++ } ++ ++ if (i == timeout) { ++ DEBUGOUT("Driver can't access resource, SW_FW_SYNC timeout.\n"); ++ ret_val = -E1000_ERR_SWFW_SYNC; ++ goto out; + } + ++ swfw_sync |= swmask; ++ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); ++ ++ e1000_put_hw_semaphore_generic(hw); ++ ++out: + return ret_val; +} + +/** -+ * e1000_update_nvm_checksum_82571 - Update EEPROM checksum ++ * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore + * @hw: pointer to the HW structure ++ * @mask: specifies which semaphore to acquire + * -+ * Updates the EEPROM checksum by reading/adding each word of the EEPROM -+ * up to the checksum. Then calculates the EEPROM checksum and writes the -+ * value to the EEPROM. ++ * Release the SW/FW semaphore used to access the PHY or NVM. The mask ++ * will also specify which port we're releasing the lock for. + **/ -+static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) ++static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) ++{ ++ u32 swfw_sync; ++ ++ DEBUGFUNC("e1000_release_swfw_sync_80003es2lan"); ++ ++ while (e1000_get_hw_semaphore_generic(hw) != E1000_SUCCESS); ++ /* Empty */ ++ ++ swfw_sync = E1000_READ_REG(hw, E1000_SW_FW_SYNC); ++ swfw_sync &= ~mask; ++ E1000_WRITE_REG(hw, E1000_SW_FW_SYNC, swfw_sync); ++ ++ e1000_put_hw_semaphore_generic(hw); ++} ++ ++/** ++ * e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register ++ * @hw: pointer to the HW structure ++ * @offset: offset of the register to read ++ * @data: pointer to the data returned from the operation ++ * ++ * Read the GG82563 PHY register. This is a function pointer entry ++ * point called by the api module. ++ **/ ++static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ++ u32 offset, u16 *data) +{ -+ u32 eecd; + s32 ret_val; -+ u16 i; ++ u32 page_select; ++ u16 temp; ++ ++ DEBUGFUNC("e1000_read_phy_reg_gg82563_80003es2lan"); + -+ ret_val = e1000e_update_nvm_checksum_generic(hw); ++ ret_val = e1000_acquire_phy_80003es2lan(hw); + if (ret_val) -+ return ret_val; ++ goto out; + -+ /* If our nvm is an EEPROM, then we're done -+ * otherwise, commit the checksum to the flash NVM. */ -+ if (hw->nvm.type != e1000_nvm_flash_hw) -+ return ret_val; ++ /* Select Configuration Page */ ++ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { ++ page_select = GG82563_PHY_PAGE_SELECT; ++ } else { ++ /* ++ * Use Alternative Page Select register to access ++ * registers 30 and 31 ++ */ ++ page_select = GG82563_PHY_PAGE_SELECT_ALT; ++ } + -+ /* Check for pending operations. */ -+ for (i = 0; i < E1000_FLASH_UPDATES; i++) { -+ msleep(1); -+ if ((er32(EECD) & E1000_EECD_FLUPD) == 0) -+ break; ++ temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); ++ ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); ++ if (ret_val) { ++ e1000_release_phy_80003es2lan(hw); ++ goto out; + } + -+ if (i == E1000_FLASH_UPDATES) -+ return -E1000_ERR_NVM; ++ /* ++ * The "ready" bit in the MDIC register may be incorrectly set ++ * before the device has completed the "Page Select" MDI ++ * transaction. So we wait 200us after each MDI command... ++ */ ++ usec_delay(200); ++ ++ /* ...and verify the command was successful. */ ++ ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); + -+ /* Reset the firmware if using STM opcode. */ -+ if ((er32(FLOP) & 0xFF00) == E1000_STM_OPCODE) { -+ /* The enabling of and the actual reset must be done -+ * in two write cycles. -+ */ -+ ew32(HICR, E1000_HICR_FW_RESET_ENABLE); -+ e1e_flush(); -+ ew32(HICR, E1000_HICR_FW_RESET); ++ if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { ++ ret_val = -E1000_ERR_PHY; ++ e1000_release_phy_80003es2lan(hw); ++ goto out; + } + -+ /* Commit the write to flash */ -+ eecd = er32(EECD) | E1000_EECD_FLUPD; -+ ew32(EECD, eecd); ++ usec_delay(200); + -+ for (i = 0; i < E1000_FLASH_UPDATES; i++) { -+ msleep(1); -+ if ((er32(EECD) & E1000_EECD_FLUPD) == 0) -+ break; -+ } ++ ret_val = e1000_read_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); + -+ if (i == E1000_FLASH_UPDATES) -+ return -E1000_ERR_NVM; ++ usec_delay(200); ++ e1000_release_phy_80003es2lan(hw); + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_validate_nvm_checksum_82571 - Validate EEPROM checksum ++ * e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register + * @hw: pointer to the HW structure ++ * @offset: offset of the register to read ++ * @data: value to write to the register + * -+ * Calculates the EEPROM checksum by reading/adding each word of the EEPROM -+ * and then verifies that the sum of the EEPROM is equal to 0xBABA. ++ * Write to the GG82563 PHY register. This is a function pointer entry ++ * point called by the api module. + **/ -+static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) ++static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, ++ u32 offset, u16 data) +{ -+ if (hw->nvm.type == e1000_nvm_flash_hw) -+ e1000_fix_nvm_checksum_82571(hw); ++ s32 ret_val; ++ u32 page_select; ++ u16 temp; + -+ return e1000e_validate_nvm_checksum_generic(hw); -+} ++ DEBUGFUNC("e1000_write_phy_reg_gg82563_80003es2lan"); + -+/** -+ * e1000_write_nvm_eewr_82571 - Write to EEPROM for 82573 silicon -+ * @hw: pointer to the HW structure -+ * @offset: offset within the EEPROM to be written to -+ * @words: number of words to write -+ * @data: 16 bit word(s) to be written to the EEPROM -+ * -+ * After checking for invalid values, poll the EEPROM to ensure the previous -+ * command has completed before trying to write the next word. After write -+ * poll for completion. -+ * -+ * If e1000e_update_nvm_checksum is not called after this function, the -+ * EEPROM will most likley contain an invalid checksum. -+ **/ -+static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, -+ u16 words, u16 *data) -+{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 i; -+ u32 eewr = 0; -+ s32 ret_val = 0; ++ ret_val = e1000_acquire_phy_80003es2lan(hw); ++ if (ret_val) ++ goto out; + -+ /* A check for invalid values: offset too large, too many words, -+ * and not enough words. */ -+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; ++ /* Select Configuration Page */ ++ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) { ++ page_select = GG82563_PHY_PAGE_SELECT; ++ } else { ++ /* ++ * Use Alternative Page Select register to access ++ * registers 30 and 31 ++ */ ++ page_select = GG82563_PHY_PAGE_SELECT_ALT; + } + -+ for (i = 0; i < words; i++) { -+ eewr = (data[i] << E1000_NVM_RW_REG_DATA) | -+ ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | -+ E1000_NVM_RW_REG_START; ++ temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); ++ ret_val = e1000_write_phy_reg_mdic(hw, page_select, temp); ++ if (ret_val) { ++ e1000_release_phy_80003es2lan(hw); ++ goto out; ++ } + -+ ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); -+ if (ret_val) -+ break; + -+ ew32(EEWR, eewr); ++ /* ++ * The "ready" bit in the MDIC register may be incorrectly set ++ * before the device has completed the "Page Select" MDI ++ * transaction. So we wait 200us after each MDI command... ++ */ ++ usec_delay(200); + -+ ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); -+ if (ret_val) -+ break; ++ /* ...and verify the command was successful. */ ++ ret_val = e1000_read_phy_reg_mdic(hw, page_select, &temp); ++ ++ if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { ++ ret_val = -E1000_ERR_PHY; ++ e1000_release_phy_80003es2lan(hw); ++ goto out; + } + ++ usec_delay(200); ++ ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ usec_delay(200); ++ e1000_release_phy_80003es2lan(hw); ++ ++out: + return ret_val; +} + +/** -+ * e1000_get_cfg_done_82571 - Poll for configuration done ++ * e1000_write_nvm_80003es2lan - Write to ESB2 NVM + * @hw: pointer to the HW structure ++ * @offset: offset of the register to read ++ * @words: number of words to write ++ * @data: buffer of data to write to the NVM + * -+ * Reads the management control register for the config done bit to be set. ++ * Write "words" of data to the ESB2 NVM. This is a function ++ * pointer entry point called by the api module. + **/ -+static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) ++static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data) ++{ ++ DEBUGFUNC("e1000_write_nvm_80003es2lan"); ++ ++ return e1000_write_nvm_spi(hw, offset, words, data); ++} ++ ++/** ++ * e1000_get_cfg_done_80003es2lan - Wait for configuration to complete ++ * @hw: pointer to the HW structure ++ * ++ * Wait a specific amount of time for manageability processes to complete. ++ * This is a function pointer entry point called by the phy module. ++ **/ ++static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) +{ + s32 timeout = PHY_CFG_TIMEOUT; ++ s32 ret_val = E1000_SUCCESS; ++ u32 mask = E1000_NVM_CFG_DONE_PORT_0; ++ ++ DEBUGFUNC("e1000_get_cfg_done_80003es2lan"); ++ ++ if (hw->bus.func == 1) ++ mask = E1000_NVM_CFG_DONE_PORT_1; + + while (timeout) { -+ if (er32(EEMNGCTL) & -+ E1000_NVM_CFG_DONE_PORT_0) ++ if (E1000_READ_REG(hw, E1000_EEMNGCTL) & mask) + break; -+ msleep(1); ++ msec_delay(1); + timeout--; + } + if (!timeout) { -+ hw_dbg(hw, "MNG configuration cycle has not completed.\n"); -+ return -E1000_ERR_RESET; ++ DEBUGOUT("MNG configuration cycle has not completed.\n"); ++ ret_val = -E1000_ERR_RESET; ++ goto out; + } + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state ++ * e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex + * @hw: pointer to the HW structure -+ * @active: TRUE to enable LPLU, FALSE to disable + * -+ * Sets the LPLU D0 state according to the active flag. When activating LPLU -+ * this function also disables smart speed and vice versa. LPLU will not be -+ * activated unless the device autonegotiation advertisement meets standards -+ * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function -+ * pointer entry point only called by PHY setup routines. ++ * Force the speed and duplex settings onto the PHY. This is a ++ * function pointer entry point called by the phy module. + **/ -+static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) ++static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_data; ++ bool link; ++ ++ DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); ++ ++ if (!(hw->phy.ops.read_reg)) ++ goto out; + -+ ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data); ++ /* ++ * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI ++ * forced whenever speed and duplex are forced. ++ */ ++ ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if (ret_val) -+ return ret_val; ++ goto out; + -+ if (active) { -+ data |= IGP02E1000_PM_D0_LPLU; -+ ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); -+ if (ret_val) -+ return ret_val; ++ phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); ++ if (ret_val) ++ goto out; + -+ /* When LPLU is enabled, we should disable SmartSpeed */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); -+ if (ret_val) -+ return ret_val; -+ } else { -+ data &= ~IGP02E1000_PM_D0_LPLU; -+ ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); -+ /* 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 (phy->smart_speed == e1000_smart_speed_on) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); + -+ data |= IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } else if (phy->smart_speed == e1000_smart_speed_off) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data); ++ if (ret_val) ++ goto out; + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); ++ e1000_phy_force_speed_duplex_setup(hw, &phy_data); ++ ++ /* Reset the phy to commit changes. */ ++ phy_data |= MII_CR_RESET; ++ ++ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data); ++ if (ret_val) ++ goto out; ++ ++ usec_delay(1); ++ ++ if (hw->phy.autoneg_wait_to_complete) { ++ DEBUGOUT("Waiting for forced speed/duplex link " ++ "on GG82563 phy.\n"); ++ ++ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, ++ 100000, &link); ++ if (ret_val) ++ goto out; ++ ++ if (!link) { ++ /* ++ * We didn't get link. ++ * Reset the DSP and cross our fingers. ++ */ ++ ret_val = e1000_phy_reset_dsp_generic(hw); + if (ret_val) -+ return ret_val; ++ goto out; + } ++ ++ /* Try once more */ ++ ret_val = e1000_phy_has_link_generic(hw, PHY_FORCE_LIMIT, ++ 100000, &link); ++ if (ret_val) ++ goto out; + } + -+ return 0; ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Resetting the phy means we need to verify the TX_CLK corresponds ++ * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. ++ */ ++ phy_data &= ~GG82563_MSCR_TX_CLK_MASK; ++ if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED) ++ phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5; ++ else ++ phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; ++ ++ /* ++ * In addition, we must re-enable CRS on Tx for both half and full ++ * duplex. ++ */ ++ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_reset_hw_82571 - Reset hardware ++ * e1000_get_cable_length_80003es2lan - Set approximate cable length + * @hw: pointer to the HW structure + * -+ * This resets the hardware into a known state. This is a -+ * function pointer entry point called by the api module. ++ * Find the approximate cable length as measured by the GG82563 PHY. ++ * This is a function pointer entry point called by the phy module. + **/ -+static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ++static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) +{ -+ u32 ctrl; -+ u32 extcnf_ctrl; -+ u32 ctrl_ext; -+ u32 icr; -+ s32 ret_val; -+ u16 i = 0; ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_data, index; + -+ /* Prevent the PCI-E bus from sticking if there is no TLP connection -+ * on the last TLP read/write transaction when MAC is reset. -+ */ -+ ret_val = e1000e_disable_pcie_master(hw); -+ if (ret_val) -+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); ++ DEBUGFUNC("e1000_get_cable_length_80003es2lan"); + -+ hw_dbg(hw, "Masking off all interrupts\n"); -+ ew32(IMC, 0xffffffff); ++ if (!(hw->phy.ops.read_reg)) ++ goto out; + -+ ew32(RCTL, 0); -+ ew32(TCTL, E1000_TCTL_PSP); -+ e1e_flush(); ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); ++ if (ret_val) ++ goto out; + -+ msleep(10); ++ index = phy_data & GG82563_DSPD_CABLE_LENGTH; ++ phy->min_cable_length = e1000_gg82563_cable_length_table[index]; ++ phy->max_cable_length = e1000_gg82563_cable_length_table[index+5]; + -+ /* Must acquire the MDIO ownership before MAC reset. -+ * Ownership defaults to firmware after a reset. */ -+ if (hw->mac.type == e1000_82573) { -+ extcnf_ctrl = er32(EXTCNF_CTRL); -+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; ++ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; + -+ do { -+ ew32(EXTCNF_CTRL, extcnf_ctrl); -+ extcnf_ctrl = er32(EXTCNF_CTRL); ++out: ++ return ret_val; ++} + -+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) -+ break; ++/** ++ * e1000_get_link_up_info_80003es2lan - Report speed and duplex ++ * @hw: pointer to the HW structure ++ * @speed: pointer to speed buffer ++ * @duplex: pointer to duplex buffer ++ * ++ * Retrieve the current speed and duplex configuration. ++ * This is a function pointer entry point called by the api module. ++ **/ ++static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, ++ u16 *duplex) ++{ ++ s32 ret_val; + -+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; ++ DEBUGFUNC("e1000_get_link_up_info_80003es2lan"); + -+ msleep(2); -+ i++; -+ } while (i < MDIO_OWNERSHIP_TIMEOUT); ++ if (hw->phy.media_type == e1000_media_type_copper) { ++ ret_val = e1000_get_speed_and_duplex_copper_generic(hw, ++ speed, ++ duplex); ++ } else { ++ ret_val = e1000_get_speed_and_duplex_fiber_serdes_generic(hw, ++ speed, ++ duplex); + } + -+ ctrl = er32(CTRL); ++ return ret_val; ++} ++ ++/** ++ * e1000_reset_hw_80003es2lan - Reset the ESB2 controller ++ * @hw: pointer to the HW structure ++ * ++ * Perform a global reset to the ESB2 controller. ++ * This is a function pointer entry point called by the api module. ++ **/ ++static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) ++{ ++ u32 ctrl, icr; ++ s32 ret_val; + -+ hw_dbg(hw, "Issuing a global reset to MAC\n"); -+ ew32(CTRL, ctrl | E1000_CTRL_RST); ++ DEBUGFUNC("e1000_reset_hw_80003es2lan"); + -+ if (hw->nvm.type == e1000_nvm_flash_hw) { -+ udelay(10); -+ ctrl_ext = er32(CTRL_EXT); -+ ctrl_ext |= E1000_CTRL_EXT_EE_RST; -+ ew32(CTRL_EXT, ctrl_ext); -+ e1e_flush(); ++ /* ++ * Prevent the PCI-E bus from sticking if there is no TLP connection ++ * on the last TLP read/write transaction when MAC is reset. ++ */ ++ ret_val = e1000_disable_pcie_master_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("PCI-E Master disable polling has failed.\n"); + } + -+ ret_val = e1000e_get_auto_rd_done(hw); ++ DEBUGOUT("Masking off all interrupts\n"); ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); ++ ++ E1000_WRITE_REG(hw, E1000_RCTL, 0); ++ E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); ++ E1000_WRITE_FLUSH(hw); ++ ++ msec_delay(10); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ++ ret_val = e1000_acquire_phy_80003es2lan(hw); ++ DEBUGOUT("Issuing a global reset to MAC\n"); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); ++ e1000_release_phy_80003es2lan(hw); ++ ++ ret_val = e1000_get_auto_rd_done_generic(hw); + if (ret_val) + /* We don't want to continue accessing MAC registers. */ -+ return ret_val; -+ -+ /* Phy configuration from NVM just starts after EECD_AUTO_RD is set. -+ * Need to wait for Phy configuration completion before accessing -+ * NVM and Phy. -+ */ -+ if (hw->mac.type == e1000_82573) -+ msleep(25); ++ goto out; + + /* Clear any pending interrupt events. */ -+ ew32(IMC, 0xffffffff); -+ icr = er32(ICR); ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); ++ icr = E1000_READ_REG(hw, E1000_ICR); + -+ return 0; ++ e1000_check_alt_mac_addr_generic(hw); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_init_hw_82571 - Initialize hardware ++ * e1000_init_hw_80003es2lan - Initialize the ESB2 controller + * @hw: pointer to the HW structure + * -+ * This inits the hardware readying it for operation. ++ * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. ++ * This is a function pointer entry point called by the api module. + **/ -+static s32 e1000_init_hw_82571(struct e1000_hw *hw) ++static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 reg_data; + s32 ret_val; + u16 i; -+ u16 rar_count = mac->rar_entry_count; + -+ e1000_initialize_hw_bits_82571(hw); ++ DEBUGFUNC("e1000_init_hw_80003es2lan"); ++ ++ e1000_initialize_hw_bits_80003es2lan(hw); + + /* Initialize identification LED */ -+ ret_val = e1000e_id_led_init(hw); ++ ret_val = e1000_id_led_init_generic(hw); + if (ret_val) { -+ hw_dbg(hw, "Error initializing identification LED\n"); -+ return ret_val; ++ DEBUGOUT("Error initializing identification LED\n"); ++ /* This is not fatal and we should not stop init due to this */ + } + + /* Disabling VLAN filtering */ -+ hw_dbg(hw, "Initializing the IEEE VLAN\n"); -+ e1000e_clear_vfta(hw); ++ DEBUGOUT("Initializing the IEEE VLAN\n"); ++ mac->ops.clear_vfta(hw); + + /* Setup the receive address. */ -+ /* If, however, a locally administered address was assigned to the -+ * 82571, we must reserve a RAR for it to work around an issue where -+ * resetting one port will reload the MAC on the other port. -+ */ -+ if (e1000e_get_laa_state_82571(hw)) -+ rar_count--; -+ e1000e_init_rx_addrs(hw, rar_count); ++ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); + + /* Zero out the Multicast HASH table */ -+ hw_dbg(hw, "Zeroing the MTA\n"); ++ DEBUGOUT("Zeroing the MTA\n"); + for (i = 0; i < mac->mta_reg_count; i++) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); + + /* Setup link and flow control */ -+ ret_val = e1000_setup_link_82571(hw); ++ ret_val = mac->ops.setup_link(hw); + + /* Set the transmit descriptor write-back policy */ -+ reg_data = er32(TXDCTL); ++ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); + reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB | -+ E1000_TXDCTL_COUNT_DESC; -+ ew32(TXDCTL, reg_data); ++ E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); + + /* ...for both queues. */ -+ if (mac->type != e1000_82573) { -+ reg_data = er32(TXDCTL1); -+ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB | -+ E1000_TXDCTL_COUNT_DESC; -+ ew32(TXDCTL1, reg_data); -+ } else { -+ e1000e_enable_tx_pkt_filtering(hw); -+ reg_data = er32(GCR); -+ reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; -+ ew32(GCR, reg_data); -+ } ++ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); ++ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | ++ E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); ++ ++ /* Enable retransmit on late collisions */ ++ reg_data = E1000_READ_REG(hw, E1000_TCTL); ++ reg_data |= E1000_TCTL_RTLC; ++ E1000_WRITE_REG(hw, E1000_TCTL, reg_data); ++ ++ /* Configure Gigabit Carry Extend Padding */ ++ reg_data = E1000_READ_REG(hw, E1000_TCTL_EXT); ++ reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; ++ reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN; ++ E1000_WRITE_REG(hw, E1000_TCTL_EXT, reg_data); ++ ++ /* Configure Transmit Inter-Packet Gap */ ++ reg_data = E1000_READ_REG(hw, E1000_TIPG); ++ reg_data &= ~E1000_TIPG_IPGT_MASK; ++ reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; ++ E1000_WRITE_REG(hw, E1000_TIPG, reg_data); ++ ++ reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001); ++ reg_data &= ~0x00100000; ++ E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); + -+ /* Clear all of the statistics registers (clear on read). It is ++ /* ++ * 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 + * is no link. + */ -+ e1000_clear_hw_cntrs_82571(hw); ++ e1000_clear_hw_cntrs_80003es2lan(hw); + + return ret_val; +} + +/** -+ * e1000_initialize_hw_bits_82571 - Initialize hardware-dependent bits ++ * e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2 + * @hw: pointer to the HW structure + * + * Initializes required hardware-dependent bits needed for normal operation. + **/ -+static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) ++static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) +{ + u32 reg; + ++ DEBUGFUNC("e1000_initialize_hw_bits_80003es2lan"); ++ ++ if (hw->mac.disable_hw_init_bits) ++ goto out; ++ + /* Transmit Descriptor Control 0 */ -+ reg = er32(TXDCTL); ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); + reg |= (1 << 22); -+ ew32(TXDCTL, reg); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); + + /* Transmit Descriptor Control 1 */ -+ reg = er32(TXDCTL1); ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); + reg |= (1 << 22); -+ ew32(TXDCTL1, reg); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); + + /* Transmit Arbitration Control 0 */ -+ reg = er32(TARC0); ++ reg = E1000_READ_REG(hw, E1000_TARC(0)); + reg &= ~(0xF << 27); /* 30:27 */ -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26); -+ break; -+ default: -+ break; -+ } -+ ew32(TARC0, reg); ++ if (hw->phy.media_type != e1000_media_type_copper) ++ reg &= ~(1 << 20); ++ E1000_WRITE_REG(hw, E1000_TARC(0), reg); + + /* Transmit Arbitration Control 1 */ -+ reg = er32(TARC1); -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ reg &= ~((1 << 29) | (1 << 30)); -+ reg |= (1 << 22) | (1 << 24) | (1 << 25) | (1 << 26); -+ if (er32(TCTL) & E1000_TCTL_MULR) -+ reg &= ~(1 << 28); -+ else -+ reg |= (1 << 28); -+ ew32(TARC1, reg); -+ break; -+ default: -+ break; -+ } -+ -+ /* Device Control */ -+ if (hw->mac.type == e1000_82573) { -+ reg = er32(CTRL); -+ reg &= ~(1 << 29); -+ ew32(CTRL, reg); -+ } ++ reg = E1000_READ_REG(hw, E1000_TARC(1)); ++ if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) ++ reg &= ~(1 << 28); ++ else ++ reg |= (1 << 28); ++ E1000_WRITE_REG(hw, E1000_TARC(1), reg); + -+ /* Extended Device Control */ -+ if (hw->mac.type == e1000_82573) { -+ reg = er32(CTRL_EXT); -+ reg &= ~(1 << 23); -+ reg |= (1 << 22); -+ ew32(CTRL_EXT, reg); -+ } ++out: ++ return; +} + +/** -+ * e1000e_clear_vfta - Clear VLAN filter table ++ * e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link + * @hw: pointer to the HW structure + * -+ * Clears the register array which contains the VLAN filter table by -+ * setting all the values to 0. ++ * Setup some GG82563 PHY registers for obtaining link + **/ -+void e1000e_clear_vfta(struct e1000_hw *hw) ++static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) +{ -+ u32 offset; -+ u32 vfta_value = 0; -+ u32 vfta_offset = 0; -+ u32 vfta_bit_in_reg = 0; ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u32 ctrl_ext; ++ u16 data; + -+ 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. ++ DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); ++ ++ if (!phy->reset_disable) { ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, ++ &data); ++ if (ret_val) ++ goto out; ++ ++ data |= GG82563_MSCR_ASSERT_CRS_ON_TX; ++ /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ ++ data |= GG82563_MSCR_TX_CLK_1000MBPS_25; ++ ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, ++ data); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * 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) + */ -+ vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; -+ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, vfta_value); -+ e1e_flush(); -+ } -+} ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); ++ if (ret_val) ++ goto out; + -+/** -+ * e1000_mc_addr_list_update_82571 - Update Multicast addresses -+ * @hw: pointer to the HW structure -+ * @mc_addr_list: array of multicast addresses to program -+ * @mc_addr_count: number of multicast addresses to program -+ * @rar_used_count: the first RAR register free to program -+ * @rar_count: total number of supported Receive Address Registers -+ * -+ * Updates the Receive Address Registers and Multicast Table Array. -+ * The caller must have a packed mc_addr_list of multicast addresses. -+ * The parameter rar_count will usually be hw->mac.rar_entry_count -+ * unless there are workarounds that change this. -+ **/ -+static void e1000_mc_addr_list_update_82571(struct e1000_hw *hw, -+ u8 *mc_addr_list, -+ u32 mc_addr_count, -+ u32 rar_used_count, -+ u32 rar_count) -+{ -+ if (e1000e_get_laa_state_82571(hw)) -+ rar_count--; ++ data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; + -+ e1000e_mc_addr_list_update_generic(hw, mc_addr_list, mc_addr_count, -+ rar_used_count, rar_count); -+} ++ switch (phy->mdix) { ++ case 1: ++ data |= GG82563_PSCR_CROSSOVER_MODE_MDI; ++ break; ++ case 2: ++ data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; ++ break; ++ case 0: ++ default: ++ data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; ++ break; ++ } + -+/** -+ * e1000_setup_link_82571 - Setup flow control and link settings -+ * @hw: pointer to the HW structure -+ * -+ * Determines which flow control settings to use, then configures flow -+ * control. Calls the appropriate media-specific link configuration -+ * function. Assuming the adapter has a valid link partner, a valid link -+ * should be established. Assumes the hardware has previously been reset -+ * and the transmitter and receiver are not enabled. -+ **/ -+static s32 e1000_setup_link_82571(struct e1000_hw *hw) -+{ -+ /* 82573 does not have a word in the NVM to determine -+ * the default flow control setting, so we explicitly -+ * set it to full. ++ /* ++ * Options: ++ * disable_polarity_correction = 0 (default) ++ * Automatic Correction for Reversed Cable Polarity ++ * 0 - Disabled ++ * 1 - Enabled ++ */ ++ data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; ++ if (phy->disable_polarity_correction) ++ data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; ++ ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); ++ if (ret_val) ++ goto out; ++ ++ /* SW Reset the PHY so all changes take effect */ ++ ret_val = hw->phy.ops.commit(hw); ++ if (ret_val) { ++ DEBUGOUT("Error Resetting the PHY\n"); ++ goto out; ++ } ++ ++ } ++ ++ /* Bypass Rx and Tx FIFO's */ ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, ++ E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | ++ E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_read_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, ++ &data); ++ if (ret_val) ++ goto out; ++ data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE; ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE, ++ data); ++ if (ret_val) ++ goto out; ++ ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); ++ if (ret_val) ++ goto out; ++ ++ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); ++ ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * 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 (hw->mac.type == e1000_82573) -+ hw->mac.fc = e1000_fc_full; ++ if (!(hw->mac.ops.check_mng_mode(hw))) { ++ /* Enable Electrical Idle on the PHY */ ++ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; ++ ret_val = hw->phy.ops.write_reg(hw, ++ GG82563_PHY_PWR_MGMT_CTRL, ++ data); ++ if (ret_val) ++ goto out; ++ ret_val = hw->phy.ops.read_reg(hw, ++ GG82563_PHY_KMRN_MODE_CTRL, ++ &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ++ ret_val = hw->phy.ops.write_reg(hw, ++ GG82563_PHY_KMRN_MODE_CTRL, ++ data); ++ ++ if (ret_val) ++ goto out; ++ } ++ ++ /* ++ * Workaround: Disable padding in Kumeran interface in the MAC ++ * and in the PHY to avoid CRC errors. ++ */ ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data); ++ if (ret_val) ++ goto out; ++ ++ data |= GG82563_ICR_DIS_PADDING; ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data); ++ if (ret_val) ++ goto out; + -+ return e1000e_setup_link(hw); ++out: ++ return ret_val; +} + +/** -+ * e1000_setup_copper_link_82571 - Configure copper link settings ++ * e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2 + * @hw: pointer to the HW structure + * -+ * Configures the link for auto-neg or forced speed and duplex. Then we check -+ * for link, once link is established calls to configure collision distance -+ * and flow control are called. ++ * Essentially a wrapper for setting up all things "copper" related. ++ * This is a function pointer entry point called by the mac module. + **/ -+static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) ++static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) +{ + u32 ctrl; -+ u32 led_ctrl; -+ s32 ret_val; ++ s32 ret_val; ++ u16 reg_data; ++ ++ DEBUGFUNC("e1000_setup_copper_link_80003es2lan"); + -+ ctrl = er32(CTRL); ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); + ctrl |= E1000_CTRL_SLU; + ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); -+ ew32(CTRL, ctrl); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + -+ switch (hw->phy.type) { -+ case e1000_phy_m88: -+ ret_val = e1000e_copper_link_setup_m88(hw); -+ break; -+ case e1000_phy_igp_2: -+ ret_val = e1000e_copper_link_setup_igp(hw); -+ /* Setup activity LED */ -+ led_ctrl = er32(LEDCTL); -+ led_ctrl &= IGP_ACTIVITY_LED_MASK; -+ led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); -+ ew32(LEDCTL, led_ctrl); -+ break; -+ default: -+ return -E1000_ERR_PHY; -+ break; -+ } ++ /* ++ * 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_80003es2lan(hw, GG82563_REG(0x34, 4), ++ 0xFFFF); ++ if (ret_val) ++ goto out; ++ ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), ++ ®_data); ++ if (ret_val) ++ goto out; ++ reg_data |= 0x3F; ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9), ++ reg_data); ++ if (ret_val) ++ goto out; ++ ret_val = e1000_read_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, ++ ®_data); ++ if (ret_val) ++ goto out; ++ reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, ++ reg_data); ++ if (ret_val) ++ goto out; + ++ ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw); + if (ret_val) -+ return ret_val; ++ goto out; + -+ ret_val = e1000e_setup_copper_link(hw); ++ ret_val = e1000_setup_copper_link_generic(hw); + ++out: + return ret_val; +} + +/** -+ * e1000_setup_fiber_serdes_link_82571 - Setup link for fiber/serdes ++ * e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up + * @hw: pointer to the HW structure ++ * @duplex: current duplex setting + * -+ * Configures collision distance and flow control for fiber and serdes links. -+ * Upon successful setup, poll for link. ++ * Configure the KMRN interface by applying last minute quirks for ++ * 10/100 operation. + **/ -+static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) ++static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) +{ -+ switch (hw->mac.type) { -+ case e1000_82571: -+ case e1000_82572: -+ /* If SerDes loopback mode is entered, there is no form -+ * of reset to take the adapter out of that mode. So we -+ * have to explicitly take the adapter out of loopback -+ * mode. This prevents drivers from twidling their thumbs -+ * if another tool failed to take it out of loopback mode. -+ */ -+ ew32(SCTL, -+ E1000_SCTL_DISABLE_SERDES_LOOPBACK); -+ break; -+ default: -+ break; ++ s32 ret_val = E1000_SUCCESS; ++ u16 speed; ++ u16 duplex; ++ ++ DEBUGFUNC("e1000_configure_on_link_up"); ++ ++ if (hw->phy.media_type == e1000_media_type_copper) { ++ ++ ret_val = e1000_get_speed_and_duplex_copper_generic(hw, ++ &speed, ++ &duplex); ++ if (ret_val) ++ goto out; ++ ++ if (speed == SPEED_1000) ++ ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); ++ else ++ ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex); + } + -+ return e1000e_setup_fiber_serdes_link(hw); ++out: ++ return ret_val; +} + +/** -+ * e1000_valid_led_default_82571 - Verify a valid default LED config ++ * e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation + * @hw: pointer to the HW structure -+ * @data: pointer to the NVM (EEPROM) ++ * @duplex: current duplex setting + * -+ * Read the EEPROM for the current default LED configuration. If the -+ * LED configuration is not valid, set to a valid LED configuration. ++ * Configure the KMRN interface by applying last minute quirks for ++ * 10/100 operation. + **/ -+static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) ++static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) +{ -+ s32 ret_val; ++ s32 ret_val = E1000_SUCCESS; ++ u32 tipg; ++ u32 i = 0; ++ u16 reg_data, reg_data2; + -+ ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; -+ } ++ DEBUGFUNC("e1000_configure_kmrn_for_10_100"); + -+ if (hw->mac.type == e1000_82573 && -+ *data == ID_LED_RESERVED_F746) -+ *data = ID_LED_DEFAULT_82573; -+ else if (*data == ID_LED_RESERVED_0000 || -+ *data == ID_LED_RESERVED_FFFF) -+ *data = ID_LED_DEFAULT; ++ reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, ++ reg_data); ++ if (ret_val) ++ goto out; + -+ return 0; ++ /* Configure Transmit Inter-Packet Gap */ ++ tipg = E1000_READ_REG(hw, E1000_TIPG); ++ tipg &= ~E1000_TIPG_IPGT_MASK; ++ tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; ++ E1000_WRITE_REG(hw, E1000_TIPG, tipg); ++ ++ ++ do { ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ++ ®_data); ++ if (ret_val) ++ goto out; ++ ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ++ ®_data2); ++ if (ret_val) ++ goto out; ++ i++; ++ } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); ++ ++ if (duplex == HALF_DUPLEX) ++ reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; ++ else ++ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ++ ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000e_get_laa_state_82571 - Get locally administered address state ++ * e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation + * @hw: pointer to the HW structure + * -+ * Retrieve and return the current locally administed address state. ++ * Configure the KMRN interface by applying last minute quirks for ++ * gigabit operation. + **/ -+bool e1000e_get_laa_state_82571(struct e1000_hw *hw) ++static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) +{ -+ if (hw->mac.type != e1000_82571) -+ return 0; ++ s32 ret_val = E1000_SUCCESS; ++ u16 reg_data, reg_data2; ++ u32 tipg; ++ u32 i = 0; ++ ++ DEBUGFUNC("e1000_configure_kmrn_for_1000"); ++ ++ reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; ++ ret_val = e1000_write_kmrn_reg_80003es2lan(hw, ++ E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, ++ reg_data); ++ if (ret_val) ++ goto out; + -+ return hw->dev_spec.e82571.laa_is_present; ++ /* Configure Transmit Inter-Packet Gap */ ++ tipg = E1000_READ_REG(hw, E1000_TIPG); ++ tipg &= ~E1000_TIPG_IPGT_MASK; ++ tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; ++ E1000_WRITE_REG(hw, E1000_TIPG, tipg); ++ ++ ++ do { ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ++ ®_data); ++ if (ret_val) ++ goto out; ++ ++ ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ++ ®_data2); ++ if (ret_val) ++ goto out; ++ i++; ++ } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); ++ ++ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ++ ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000e_set_laa_state_82571 - Set locally administered address state ++ * e1000_read_kmrn_reg_80003es2lan - Read kumeran register + * @hw: pointer to the HW structure -+ * @state: enable/disable locally administered address ++ * @offset: register offset to be read ++ * @data: pointer to the read data + * -+ * Enable/Disable the current locally administed address state. ++ * Acquire semaphore, then read the PHY register at offset ++ * using the kumeran interface. The information retrieved is stored in data. ++ * Release the semaphore before exiting. + **/ -+void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state) ++s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data) +{ -+ if (hw->mac.type != e1000_82571) -+ return; ++ u32 kmrnctrlsta; ++ s32 ret_val = E1000_SUCCESS; + -+ hw->dev_spec.e82571.laa_is_present = state; ++ DEBUGFUNC("e1000_read_kmrn_reg_80003es2lan"); + -+ /* If workaround is activated... */ -+ if (state) -+ /* 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, the actual LAA is in one of the RARs and no -+ * incoming packets directed to this port are dropped. -+ * Eventually the LAA will be in RAR[0] and RAR[14]. -+ */ -+ e1000e_rar_set(hw, hw->mac.addr, hw->mac.rar_entry_count - 1); ++ ret_val = e1000_acquire_mac_csr_80003es2lan(hw); ++ if (ret_val) ++ goto out; ++ ++ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & ++ E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; ++ E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); ++ ++ usec_delay(2); ++ ++ kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); ++ *data = (u16)kmrnctrlsta; ++ ++ e1000_release_mac_csr_80003es2lan(hw); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_fix_nvm_checksum_82571 - Fix EEPROM checksum ++ * e1000_write_kmrn_reg_80003es2lan - Write kumeran register + * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write at register offset + * -+ * Verifies that the EEPROM has completed the update. After updating the -+ * EEPROM, we need to check bit 15 in work 0x23 for the checksum fix. If -+ * the checksum fix is not implemented, we need to set the bit and update -+ * the checksum. Otherwise, if bit 15 is set and the checksum is incorrect, -+ * we need to return bad checksum. ++ * Acquire semaphore, then write the data to PHY register ++ * at the offset using the kumeran interface. Release semaphore ++ * before exiting. + **/ -+static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) ++s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ s32 ret_val; -+ u16 data; ++ u32 kmrnctrlsta; ++ s32 ret_val = E1000_SUCCESS; + -+ if (nvm->type != e1000_nvm_flash_hw) -+ return 0; ++ DEBUGFUNC("e1000_write_kmrn_reg_80003es2lan"); + -+ /* Check bit 4 of word 10h. If it is 0, firmware is done updating -+ * 10h-12h. Checksum may need to be fixed. -+ */ -+ ret_val = e1000_read_nvm(hw, 0x10, 1, &data); ++ ret_val = e1000_acquire_mac_csr_80003es2lan(hw); + if (ret_val) -+ return ret_val; ++ goto out; + -+ if (!(data & 0x10)) { -+ /* 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. -+ */ -+ ret_val = e1000_read_nvm(hw, 0x23, 1, &data); -+ if (ret_val) -+ return ret_val; ++ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & ++ E1000_KMRNCTRLSTA_OFFSET) | data; ++ E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); + -+ if (!(data & 0x8000)) { -+ data |= 0x8000; -+ ret_val = e1000_write_nvm(hw, 0x23, 1, &data); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_update_nvm_checksum(hw); -+ } -+ } ++ usec_delay(2); + -+ return 0; ++ e1000_release_mac_csr_80003es2lan(hw); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters ++ * e1000_read_mac_addr_80003es2lan - Read device MAC address + * @hw: pointer to the HW structure -+ * -+ * Clears the hardware counters by reading the counter registers. + **/ -+static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) ++static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) +{ -+ u32 temp; -+ -+ e1000e_clear_hw_cntrs_base(hw); -+ -+ temp = er32(PRC64); -+ temp = er32(PRC127); -+ temp = er32(PRC255); -+ temp = er32(PRC511); -+ temp = er32(PRC1023); -+ temp = er32(PRC1522); -+ temp = er32(PTC64); -+ temp = er32(PTC127); -+ temp = er32(PTC255); -+ temp = er32(PTC511); -+ temp = er32(PTC1023); -+ temp = er32(PTC1522); -+ -+ temp = er32(ALGNERRC); -+ temp = er32(RXERRC); -+ temp = er32(TNCRS); -+ temp = er32(CEXTERR); -+ temp = er32(TSCTC); -+ temp = er32(TSCTFC); -+ -+ temp = er32(MGTPRC); -+ temp = er32(MGTPDC); -+ temp = er32(MGTPTC); -+ -+ temp = er32(IAC); -+ temp = er32(ICRXOC); -+ -+ temp = er32(ICRXPTC); -+ temp = er32(ICRXATC); -+ temp = er32(ICTXPTC); -+ temp = er32(ICTXATC); -+ temp = er32(ICTXQEC); -+ temp = er32(ICTXQMTC); -+ temp = er32(ICRXDMTC); -+} -+ -+static struct e1000_mac_operations e82571_mac_ops = { -+ .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, -+ /* .check_for_link: media type dependent */ -+ .cleanup_led = e1000e_cleanup_led_generic, -+ .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, -+ .get_bus_info = e1000e_get_bus_info_pcie, -+ /* .get_link_up_info: media type dependent */ -+ .led_on = e1000e_led_on_generic, -+ .led_off = e1000e_led_off_generic, -+ .mc_addr_list_update = e1000_mc_addr_list_update_82571, -+ .reset_hw = e1000_reset_hw_82571, -+ .init_hw = e1000_init_hw_82571, -+ .setup_link = e1000_setup_link_82571, -+ /* .setup_physical_interface: media type dependent */ -+}; -+ -+static struct e1000_phy_operations e82_phy_ops_igp = { -+ .acquire_phy = e1000_get_hw_semaphore_82571, -+ .check_reset_block = e1000e_check_reset_block_generic, -+ .commit_phy = NULL, -+ .force_speed_duplex = e1000e_phy_force_speed_duplex_igp, -+ .get_cfg_done = e1000_get_cfg_done_82571, -+ .get_cable_length = e1000e_get_cable_length_igp_2, -+ .get_phy_info = e1000e_get_phy_info_igp, -+ .read_phy_reg = e1000e_read_phy_reg_igp, -+ .release_phy = e1000_put_hw_semaphore_82571, -+ .reset_phy = e1000e_phy_hw_reset_generic, -+ .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, -+ .set_d3_lplu_state = e1000e_set_d3_lplu_state, -+ .write_phy_reg = e1000e_write_phy_reg_igp, -+}; -+ -+static struct e1000_phy_operations e82_phy_ops_m88 = { -+ .acquire_phy = e1000_get_hw_semaphore_82571, -+ .check_reset_block = e1000e_check_reset_block_generic, -+ .commit_phy = e1000e_phy_sw_reset, -+ .force_speed_duplex = e1000e_phy_force_speed_duplex_m88, -+ .get_cfg_done = e1000e_get_cfg_done, -+ .get_cable_length = e1000e_get_cable_length_m88, -+ .get_phy_info = e1000e_get_phy_info_m88, -+ .read_phy_reg = e1000e_read_phy_reg_m88, -+ .release_phy = e1000_put_hw_semaphore_82571, -+ .reset_phy = e1000e_phy_hw_reset_generic, -+ .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, -+ .set_d3_lplu_state = e1000e_set_d3_lplu_state, -+ .write_phy_reg = e1000e_write_phy_reg_m88, -+}; -+ -+static struct e1000_nvm_operations e82571_nvm_ops = { -+ .acquire_nvm = e1000_acquire_nvm_82571, -+ .read_nvm = e1000e_read_nvm_spi, -+ .release_nvm = e1000_release_nvm_82571, -+ .update_nvm = e1000_update_nvm_checksum_82571, -+ .valid_led_default = e1000_valid_led_default_82571, -+ .validate_nvm = e1000_validate_nvm_checksum_82571, -+ .write_nvm = e1000_write_nvm_82571, -+}; ++ s32 ret_val = E1000_SUCCESS; + -+static struct e1000_nvm_operations e82573_nvm_ops = { -+ .acquire_nvm = e1000_acquire_nvm_82571, -+ .read_nvm = e1000e_read_nvm_eerd, -+ .release_nvm = e1000_release_nvm_82571, -+ .update_nvm = e1000_update_nvm_checksum_82571, -+ .valid_led_default = e1000_valid_led_default_82571, -+ .validate_nvm = e1000_validate_nvm_checksum_82571, -+ .write_nvm = e1000_write_nvm_82571, -+}; ++ DEBUGFUNC("e1000_read_mac_addr_80003es2lan"); ++ if (e1000_check_alt_mac_addr_generic(hw)) ++ ret_val = e1000_read_mac_addr_generic(hw); + -+struct e1000_info e1000_82571_info = { -+ .mac = e1000_82571, -+ .flags = FLAG_HAS_HW_VLAN_FILTER -+ | FLAG_HAS_JUMBO_FRAMES -+ | FLAG_HAS_STATS_PTC_PRC -+ | FLAG_HAS_WOL -+ | FLAG_APME_IN_CTRL3 -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_CTRLEXT_ON_LOAD -+ | FLAG_HAS_STATS_ICR_ICT -+ | FLAG_HAS_SMART_POWER_DOWN -+ | FLAG_RESET_OVERWRITES_LAA /* errata */ -+ | FLAG_TARC_SPEED_MODE_BIT /* errata */ -+ | FLAG_APME_CHECK_PORT_B, -+ .pba = 38, -+ .get_invariants = e1000_get_invariants_82571, -+ .mac_ops = &e82571_mac_ops, -+ .phy_ops = &e82_phy_ops_igp, -+ .nvm_ops = &e82571_nvm_ops, -+}; ++ return ret_val; ++} + -+struct e1000_info e1000_82572_info = { -+ .mac = e1000_82572, -+ .flags = FLAG_HAS_HW_VLAN_FILTER -+ | FLAG_HAS_JUMBO_FRAMES -+ | FLAG_HAS_STATS_PTC_PRC -+ | FLAG_HAS_WOL -+ | FLAG_APME_IN_CTRL3 -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_CTRLEXT_ON_LOAD -+ | FLAG_HAS_STATS_ICR_ICT -+ | FLAG_TARC_SPEED_MODE_BIT, /* errata */ -+ .pba = 38, -+ .get_invariants = e1000_get_invariants_82571, -+ .mac_ops = &e82571_mac_ops, -+ .phy_ops = &e82_phy_ops_igp, -+ .nvm_ops = &e82571_nvm_ops, -+}; ++/** ++ * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down ++ * @hw: pointer to the HW structure ++ * ++ * In the case of a PHY power down to save power, or to turn off link during a ++ * driver unload, or wake on lan is not enabled, remove the link. ++ **/ ++static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) ++{ ++ /* If the management interface is not enabled, then power down */ ++ if (!(hw->mac.ops.check_mng_mode(hw) || ++ hw->phy.ops.check_reset_block(hw))) ++ e1000_power_down_phy_copper(hw); + -+struct e1000_info e1000_82573_info = { -+ .mac = e1000_82573, -+ .flags = FLAG_HAS_HW_VLAN_FILTER -+ | FLAG_HAS_JUMBO_FRAMES -+ | FLAG_HAS_STATS_PTC_PRC -+ | FLAG_HAS_WOL -+ | FLAG_APME_IN_CTRL3 -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_STATS_ICR_ICT -+ | FLAG_HAS_SMART_POWER_DOWN -+ | FLAG_HAS_AMT -+ | FLAG_HAS_ASPM -+ | FLAG_HAS_ERT -+ | FLAG_HAS_SWSM_ON_LOAD, -+ .pba = 20, -+ .get_invariants = e1000_get_invariants_82571, -+ .mac_ops = &e82571_mac_ops, -+ .phy_ops = &e82_phy_ops_m88, -+ .nvm_ops = &e82573_nvm_ops, -+}; ++ return; ++} + -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/defines.h linux-2.6.22-10/drivers/net/e1000e/defines.h ---- linux-2.6.22-0/drivers/net/e1000e/defines.h 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/defines.h 2007-11-21 13:55:18.000000000 -0500 -@@ -0,0 +1,737 @@ ++/** ++ * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters ++ * @hw: pointer to the HW structure ++ * ++ * Clears the hardware counters by reading the counter registers. ++ **/ ++static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) ++{ ++ volatile u32 temp; ++ ++ DEBUGFUNC("e1000_clear_hw_cntrs_80003es2lan"); ++ ++ e1000_clear_hw_cntrs_base_generic(hw); ++ ++ temp = E1000_READ_REG(hw, E1000_PRC64); ++ temp = E1000_READ_REG(hw, E1000_PRC127); ++ temp = E1000_READ_REG(hw, E1000_PRC255); ++ temp = E1000_READ_REG(hw, E1000_PRC511); ++ temp = E1000_READ_REG(hw, E1000_PRC1023); ++ temp = E1000_READ_REG(hw, E1000_PRC1522); ++ temp = E1000_READ_REG(hw, E1000_PTC64); ++ temp = E1000_READ_REG(hw, E1000_PTC127); ++ temp = E1000_READ_REG(hw, E1000_PTC255); ++ temp = E1000_READ_REG(hw, E1000_PTC511); ++ temp = E1000_READ_REG(hw, E1000_PTC1023); ++ temp = E1000_READ_REG(hw, E1000_PTC1522); ++ ++ temp = E1000_READ_REG(hw, E1000_ALGNERRC); ++ temp = E1000_READ_REG(hw, E1000_RXERRC); ++ temp = E1000_READ_REG(hw, E1000_TNCRS); ++ temp = E1000_READ_REG(hw, E1000_CEXTERR); ++ temp = E1000_READ_REG(hw, E1000_TSCTC); ++ temp = E1000_READ_REG(hw, E1000_TSCTFC); ++ ++ temp = E1000_READ_REG(hw, E1000_MGTPRC); ++ temp = E1000_READ_REG(hw, E1000_MGTPDC); ++ temp = E1000_READ_REG(hw, E1000_MGTPTC); ++ ++ temp = E1000_READ_REG(hw, E1000_IAC); ++ temp = E1000_READ_REG(hw, E1000_ICRXOC); ++ ++ temp = E1000_READ_REG(hw, E1000_ICRXPTC); ++ temp = E1000_READ_REG(hw, E1000_ICRXATC); ++ temp = E1000_READ_REG(hw, E1000_ICTXPTC); ++ temp = E1000_READ_REG(hw, E1000_ICTXATC); ++ temp = E1000_READ_REG(hw, E1000_ICTXQEC); ++ temp = E1000_READ_REG(hw, E1000_ICTXQMTC); ++ temp = E1000_READ_REG(hw, E1000_ICRXDMTC); ++} +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_80003es2lan.h linux-2.6.22-10/drivers/net/e1000e/e1000_80003es2lan.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_80003es2lan.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_80003es2lan.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,95 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++ Copyright(c) 1999 - 2008 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, @@ -1385,2482 +1579,3121 @@ diff -Nurp linux-2.6.22-0/drivers/net/e1000e/defines.h linux-2.6.22-10/drivers/n + +*******************************************************************************/ + -+#ifndef _E1000_DEFINES_H_ -+#define _E1000_DEFINES_H_ ++#ifndef _E1000_80003ES2LAN_H_ ++#define _E1000_80003ES2LAN_H_ + -+#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ -+#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -+#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -+#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -+#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ -+#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ -+#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ -+#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ -+#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ -+#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -+#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -+#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -+#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -+#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -+#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -+#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -+#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -+#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ ++#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 ++#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 ++#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 ++#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE 0x1F + -+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ -+#define REQ_TX_DESCRIPTOR_MULTIPLE 8 -+#define REQ_RX_DESCRIPTOR_MULTIPLE 8 ++#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 ++#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 ++#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010 + -+/* Definitions for power management and wakeup registers */ -+/* Wake Up Control */ -+#define E1000_WUC_APME 0x00000001 /* APM Enable */ -+#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ ++#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 ++#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 ++#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 + -+/* Wake Up Filter Control */ -+#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ -+#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ -+#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ -+#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ -+#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ ++#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ ++#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 + -+/* Extended Device Control */ -+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */ -+#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ -+#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ -+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 -+#define E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES 0x00C00000 -+#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 DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 ++#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 + -+/* 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_ERR_CE 0x01 /* CRC Error */ -+#define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ -+#define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ -+#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ -+#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ -+#define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ -+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ ++/* GG82563 PHY Specific Status Register (Page 0, Register 16 */ ++#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disabled */ ++#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 ++#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */ ++#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */ ++#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */ + -+#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_RXE 0x80000000 ++/* PHY Specific Control Register 2 (Page 0, Register 26) */ ++#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 ++ /* 1=Reverse Auto-Negotiation */ + -+/* mask to determine if packets should be dropped due to frame errors */ -+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \ -+ E1000_RXD_ERR_CE | \ -+ E1000_RXD_ERR_SE | \ -+ E1000_RXD_ERR_SEQ | \ -+ E1000_RXD_ERR_CXE | \ -+ E1000_RXD_ERR_RXE) ++/* 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_5 0x0004 ++#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 ++#define GG82563_MSCR_TX_CLK_1000MBPS_2_5 0x0006 ++#define GG82563_MSCR_TX_CLK_1000MBPS_25 0x0007 + -+/* 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) ++#define GG82563_MSCR_ASSERT_CRS_ON_TX 0x0010 /* 1=Assert */ + -+#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 ++/* DSP Distance Register (Page 5, Register 26) */ ++/* ++ * 0 = <50M ++ * 1 = 50-80M ++ * 2 = 80-100M ++ * 3 = 110-140M ++ * 4 = >140M ++ */ ++#define GG82563_DSPD_CABLE_LENGTH 0x0007 + -+/* Management Control */ -+#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ -+#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ -+#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ -+#define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets 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 */ ++/* Kumeran Mode Control Register (Page 193, Register 16) */ ++#define GG82563_KMCR_PASS_FALSE_CARRIER 0x0800 + -+/* Receive Control */ -+#define E1000_RCTL_EN 0x00000002 /* enable */ -+#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ -+#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ -+#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ -+#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ -+#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ -+#define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ -+#define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ -+#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ -+#define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ -+#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ -+#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ -+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ -+#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ -+#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ -+#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ -+#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ -+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ -+#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ -+#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ -+#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ -+#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ -+#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ -+#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ -+#define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ -+#define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ ++/* Max number of times Kumeran read/write should be validated */ ++#define GG82563_MAX_KMRN_RETRY 0x5 + -+/* 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 -+ */ ++/* Power Management Control Register (Page 193, Register 20) */ ++#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 ++ /* 1=Enable SERDES Electrical Idle */ + -+#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F -+#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 -+#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 -+#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 ++/* In-Band Control Register (Page 194, Register 18) */ ++#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ + -+#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 */ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_82571.c linux-2.6.22-10/drivers/net/e1000e/e1000_82571.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_82571.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_82571.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1538 @@ ++/******************************************************************************* + -+/* SWFW_SYNC Definitions */ -+#define E1000_SWFW_EEP_SM 0x1 -+#define E1000_SWFW_PHY0_SM 0x2 -+#define E1000_SWFW_PHY1_SM 0x4 ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+/* Device Control */ -+#define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ -+#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_ASDE 0x00000020 /* Auto-speed detect enable */ -+#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ -+#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ -+#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ -+#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ -+#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ -+#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ -+#define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ -+#define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ -+#define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ -+#define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ -+#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ -+#define E1000_CTRL_RST 0x04000000 /* Global reset */ -+#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ -+#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ -+#define E1000_CTRL_VME 0x40000000 /* IEEE VLAN mode enable */ -+#define E1000_CTRL_PHY_RST 0x80000000 /* PHY Reset */ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+/* Bit definitions for the Management Data IO (MDIO) and Management Data -+ * Clock (MDC) pins in the Device Control Register. -+ */ ++ This program is distributed in the hope 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. + -+/* 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_1 0x00000004 /* Function 1 */ -+#define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ -+#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 NVM */ -+#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+/* Constants used to intrepret the masked PCI-X bus speed. */ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+#define HALF_DUPLEX 1 -+#define FULL_DUPLEX 2 ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + ++*******************************************************************************/ + -+#define ADVERTISE_10_HALF 0x0001 -+#define ADVERTISE_10_FULL 0x0002 -+#define ADVERTISE_100_HALF 0x0004 -+#define ADVERTISE_100_FULL 0x0008 -+#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ -+#define ADVERTISE_1000_FULL 0x0020 ++/* e1000_82571 ++ * e1000_82572 ++ * e1000_82573 ++ * e1000_82574 ++ */ + -+/* 1000/H is not supported, nor spec-compliant. */ -+#define E1000_ALL_SPEED_DUPLEX ( ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ -+ ADVERTISE_100_HALF | ADVERTISE_100_FULL | \ -+ ADVERTISE_1000_FULL) -+#define E1000_ALL_NOT_GIG ( ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ -+ ADVERTISE_100_HALF | ADVERTISE_100_FULL) -+#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL) -+#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL) -+#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF) ++#include "e1000_hw.h" ++ ++static s32 e1000_init_phy_params_82571(struct e1000_hw *hw); ++static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw); ++static s32 e1000_init_mac_params_82571(struct e1000_hw *hw); ++static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw); ++static void e1000_release_nvm_82571(struct e1000_hw *hw); ++static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw); ++static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw); ++static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw); ++static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, ++ bool active); ++static s32 e1000_reset_hw_82571(struct e1000_hw *hw); ++static s32 e1000_init_hw_82571(struct e1000_hw *hw); ++static void e1000_clear_vfta_82571(struct e1000_hw *hw); ++static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); ++static s32 e1000_led_on_82574(struct e1000_hw *hw); ++static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, ++ u8 *mc_addr_list, u32 mc_addr_count, ++ u32 rar_used_count, u32 rar_count); ++static s32 e1000_setup_link_82571(struct e1000_hw *hw); ++static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); ++static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); ++static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data); ++static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); ++static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw); ++static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); ++static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); ++static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); ++static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); ++static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw); ++static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); + -+#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX ++struct e1000_dev_spec_82571 { ++ bool laa_is_present; ++}; + -+/* LED Control */ -+#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F -+#define E1000_LEDCTL_LED0_MODE_SHIFT 0 -+#define E1000_LEDCTL_LED0_IVRT 0x00000040 -+#define E1000_LEDCTL_LED0_BLINK 0x00000080 ++/** ++ * e1000_init_phy_params_82571 - Init PHY func ptrs. ++ * @hw: pointer to the HW structure ++ * ++ * This is a function pointer entry point called by the api module. ++ **/ ++static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; + -+#define E1000_LEDCTL_MODE_LED_ON 0xE -+#define E1000_LEDCTL_MODE_LED_OFF 0xF ++ DEBUGFUNC("e1000_init_phy_params_82571"); + -+/* Transmit Descriptor bit definitions */ -+#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ -+#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ -+#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ -+#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ -+#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ -+#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ -+#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ -+#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ -+#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ -+#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ -+#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ -+#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ -+#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ -+#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ -+#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ -+#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ -+#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ -+#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ -+#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ ++ if (hw->phy.media_type != e1000_media_type_copper) { ++ phy->type = e1000_phy_none; ++ goto out; ++ } + -+/* Transmit Control */ -+#define E1000_TCTL_EN 0x00000002 /* enable tx */ -+#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ -+#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ -+#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ -+#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ -+#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ ++ phy->addr = 1; ++ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ++ phy->reset_delay_us = 100; + -+/* Transmit Arbitration Count */ ++ phy->ops.acquire = e1000_get_hw_semaphore_82571; ++ phy->ops.check_polarity = e1000_check_polarity_igp; ++ phy->ops.check_reset_block = e1000_check_reset_block_generic; ++ phy->ops.release = e1000_put_hw_semaphore_82571; ++ phy->ops.reset = e1000_phy_hw_reset_generic; ++ phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82571; ++ phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; ++ phy->ops.power_up = e1000_power_up_phy_copper; ++ phy->ops.power_down = e1000_power_down_phy_copper_82571; + -+/* SerDes Control */ -+#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 ++ switch (hw->mac.type) { ++ case e1000_82571: ++ case e1000_82572: ++ phy->type = e1000_phy_igp_2; ++ phy->ops.get_cfg_done = e1000_get_cfg_done_82571; ++ phy->ops.get_info = e1000_get_phy_info_igp; ++ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; ++ phy->ops.get_cable_length = e1000_get_cable_length_igp_2; ++ phy->ops.read_reg = e1000_read_phy_reg_igp; ++ phy->ops.write_reg = e1000_write_phy_reg_igp; ++ ++ /* This uses above function pointers */ ++ ret_val = e1000_get_phy_id_82571(hw); ++ ++ /* Verify PHY ID */ ++ if (phy->id != IGP01E1000_I_PHY_ID) { ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ break; ++ case e1000_82573: ++ phy->type = e1000_phy_m88; ++ phy->ops.get_cfg_done = e1000_get_cfg_done_generic; ++ phy->ops.get_info = e1000_get_phy_info_m88; ++ phy->ops.commit = e1000_phy_sw_reset_generic; ++ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; ++ phy->ops.get_cable_length = e1000_get_cable_length_m88; ++ phy->ops.read_reg = e1000_read_phy_reg_m88; ++ phy->ops.write_reg = e1000_write_phy_reg_m88; ++ ++ /* This uses above function pointers */ ++ ret_val = e1000_get_phy_id_82571(hw); ++ ++ /* Verify PHY ID */ ++ if (phy->id != M88E1111_I_PHY_ID) { ++ ret_val = -E1000_ERR_PHY; ++ DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); ++ goto out; ++ } ++ break; ++ case e1000_82574: ++ phy->type = e1000_phy_bm; ++ phy->ops.get_cfg_done = e1000_get_cfg_done_generic; ++ phy->ops.get_info = e1000_get_phy_info_m88; ++ phy->ops.commit = e1000_phy_sw_reset_generic; ++ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; ++ phy->ops.get_cable_length = e1000_get_cable_length_m88; ++ phy->ops.read_reg = e1000_read_phy_reg_bm2; ++ phy->ops.write_reg = e1000_write_phy_reg_bm2; ++ ++ /* This uses above function pointers */ ++ ret_val = e1000_get_phy_id_82571(hw); ++ /* Verify PHY ID */ ++ if (phy->id != BME1000_E_PHY_ID_R2) { ++ ret_val = -E1000_ERR_PHY; ++ DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); ++ goto out; ++ } ++ break; ++ default: ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ break; ++ } + -+/* Receive Checksum Control */ -+#define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ -+#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ ++out: ++ return ret_val; ++} + -+/* Header split receive */ -+#define E1000_RFCTL_EXTEN 0x00008000 -+#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 -+#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 ++/** ++ * e1000_init_nvm_params_82571 - Init NVM func ptrs. ++ * @hw: pointer to the HW structure ++ * ++ * This is a function pointer entry point called by the api module. ++ **/ ++static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); ++ u16 size; + -+/* Collision related configuration parameters */ -+#define E1000_COLLISION_THRESHOLD 15 -+#define E1000_CT_SHIFT 4 -+#define E1000_COLLISION_DISTANCE 63 -+#define E1000_COLD_SHIFT 12 ++ DEBUGFUNC("e1000_init_nvm_params_82571"); + -+/* Default values for the transmit IPG register */ -+#define DEFAULT_82543_TIPG_IPGT_COPPER 8 ++ nvm->opcode_bits = 8; ++ nvm->delay_usec = 1; ++ switch (nvm->override) { ++ case e1000_nvm_override_spi_large: ++ nvm->page_size = 32; ++ nvm->address_bits = 16; ++ break; ++ case e1000_nvm_override_spi_small: ++ nvm->page_size = 8; ++ nvm->address_bits = 8; ++ break; ++ default: ++ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; ++ nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; ++ break; ++ } + -+#define E1000_TIPG_IPGT_MASK 0x000003FF ++ switch (hw->mac.type) { ++ case e1000_82573: ++ case e1000_82574: ++ if (((eecd >> 15) & 0x3) == 0x3) { ++ nvm->type = e1000_nvm_flash_hw; ++ nvm->word_size = 2048; ++ /* ++ * Autonomous Flash update bit must be cleared due ++ * to Flash update issue. ++ */ ++ eecd &= ~E1000_EECD_AUPDEN; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ break; ++ } ++ /* Fall Through */ ++ default: ++ nvm->type = e1000_nvm_eeprom_spi; ++ size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> ++ E1000_EECD_SIZE_EX_SHIFT); ++ /* ++ * Added to a constant, "size" becomes the left-shift value ++ * for setting word_size. ++ */ ++ size += NVM_WORD_SIZE_BASE_SHIFT; + -+#define DEFAULT_82543_TIPG_IPGR1 8 -+#define E1000_TIPG_IPGR1_SHIFT 10 ++ /* EEPROM access above 16k is unsupported */ ++ if (size > 14) ++ size = 14; ++ nvm->word_size = 1 << size; ++ break; ++ } + -+#define DEFAULT_82543_TIPG_IPGR2 6 -+#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 -+#define E1000_TIPG_IPGR2_SHIFT 20 ++ /* Function Pointers */ ++ nvm->ops.acquire = e1000_acquire_nvm_82571; ++ nvm->ops.read = e1000_read_nvm_eerd; ++ nvm->ops.release = e1000_release_nvm_82571; ++ nvm->ops.update = e1000_update_nvm_checksum_82571; ++ nvm->ops.validate = e1000_validate_nvm_checksum_82571; ++ nvm->ops.valid_led_default = e1000_valid_led_default_82571; ++ nvm->ops.write = e1000_write_nvm_82571; + -+#define MAX_JUMBO_FRAME_SIZE 0x3F00 ++ return E1000_SUCCESS; ++} + -+/* Extended Configuration Control and Size */ -+#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 -+#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 -+#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 -+#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 -+#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 -+#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000 -+#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16 ++/** ++ * e1000_init_mac_params_82571 - Init MAC func ptrs. ++ * @hw: pointer to the HW structure ++ * ++ * This is a function pointer entry point called by the api module. ++ **/ ++static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ s32 ret_val = E1000_SUCCESS; + -+#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 ++ DEBUGFUNC("e1000_init_mac_params_82571"); + -+#define E1000_KABGTXD_BGSQLBIAS 0x00050000 ++ /* Set media type */ ++ switch (hw->device_id) { ++ case E1000_DEV_ID_82571EB_FIBER: ++ case E1000_DEV_ID_82572EI_FIBER: ++ case E1000_DEV_ID_82571EB_QUAD_FIBER: ++ hw->phy.media_type = e1000_media_type_fiber; ++ break; ++ case E1000_DEV_ID_82571EB_SERDES: ++ case E1000_DEV_ID_82571EB_SERDES_DUAL: ++ case E1000_DEV_ID_82571EB_SERDES_QUAD: ++ case E1000_DEV_ID_82572EI_SERDES: ++ hw->phy.media_type = e1000_media_type_internal_serdes; ++ break; ++ default: ++ hw->phy.media_type = e1000_media_type_copper; ++ break; ++ } + -+/* PBA constants */ -+#define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ -+#define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ ++ /* Set mta register count */ ++ mac->mta_reg_count = 128; ++ /* Set rar entry count */ ++ mac->rar_entry_count = E1000_RAR_ENTRIES; ++ /* Set if part includes ASF firmware */ ++ mac->asf_firmware_present = true; ++ /* Set if manageability features are enabled. */ ++ mac->arc_subsystem_valid = ++ (E1000_READ_REG(hw, E1000_FWSM) & E1000_FWSM_MODE_MASK) ++ ? true : false; ++ ++ /* Function pointers */ ++ ++ /* bus type/speed/width */ ++ mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; ++ /* reset */ ++ mac->ops.reset_hw = e1000_reset_hw_82571; ++ /* hw initialization */ ++ mac->ops.init_hw = e1000_init_hw_82571; ++ /* link setup */ ++ mac->ops.setup_link = e1000_setup_link_82571; ++ /* physical interface link setup */ ++ mac->ops.setup_physical_interface = ++ (hw->phy.media_type == e1000_media_type_copper) ++ ? e1000_setup_copper_link_82571 ++ : e1000_setup_fiber_serdes_link_82571; ++ /* check for link */ ++ switch (hw->phy.media_type) { ++ case e1000_media_type_copper: ++ mac->ops.check_for_link = e1000_check_for_copper_link_generic; ++ break; ++ case e1000_media_type_fiber: ++ mac->ops.check_for_link = e1000_check_for_fiber_link_generic; ++ break; ++ case e1000_media_type_internal_serdes: ++ mac->ops.check_for_link = e1000_check_for_serdes_link_generic; ++ break; ++ default: ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ break; ++ } ++ /* check management mode */ ++ switch (hw->mac.type) { ++ case e1000_82574: ++ mac->ops.check_mng_mode = e1000_check_mng_mode_82574; ++ break; ++ default: ++ mac->ops.check_mng_mode = e1000_check_mng_mode_generic; ++ break; ++ } ++ /* multicast address update */ ++ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82571; ++ /* writing VFTA */ ++ mac->ops.write_vfta = e1000_write_vfta_generic; ++ /* clearing VFTA */ ++ mac->ops.clear_vfta = e1000_clear_vfta_82571; ++ /* setting MTA */ ++ mac->ops.mta_set = e1000_mta_set_generic; ++ /* read mac address */ ++ mac->ops.read_mac_addr = e1000_read_mac_addr_82571; ++ /* blink LED */ ++ mac->ops.blink_led = e1000_blink_led_generic; ++ /* setup LED */ ++ mac->ops.setup_led = e1000_setup_led_generic; ++ /* cleanup LED */ ++ mac->ops.cleanup_led = e1000_cleanup_led_generic; ++ /* turn on/off LED */ ++ switch (hw->mac.type) { ++ case e1000_82574: ++ mac->ops.led_on = e1000_led_on_82574; ++ break; ++ default: ++ mac->ops.led_on = e1000_led_on_generic; ++ break; ++ } ++ mac->ops.led_off = e1000_led_off_generic; ++ /* remove device */ ++ mac->ops.remove_device = e1000_remove_device_generic; ++ /* clear hardware counters */ ++ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82571; ++ /* link info */ ++ mac->ops.get_link_up_info = ++ (hw->phy.media_type == e1000_media_type_copper) ++ ? e1000_get_speed_and_duplex_copper_generic ++ : e1000_get_speed_and_duplex_fiber_serdes_generic; + -+#define E1000_PBS_16K E1000_PBA_16K ++ hw->dev_spec_size = sizeof(struct e1000_dev_spec_82571); + -+#define IFS_MAX 80 -+#define IFS_MIN 40 -+#define IFS_RATIO 4 -+#define IFS_STEP 10 -+#define MIN_NUM_XMITS 1000 ++ /* Device-specific structure allocation */ ++ ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size); + -+/* SW Semaphore Register */ -+#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ -+#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ -+#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ ++out: ++ return ret_val; ++} + -+/* Interrupt Cause Read */ -+#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ -+#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ -+#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ -+#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ -+#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ -+#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ ++/** ++ * e1000_init_function_pointers_82571 - Init func ptrs. ++ * @hw: pointer to the HW structure ++ * ++ * The only function explicitly called by the api module to initialize ++ * all function pointers and parameters. ++ **/ ++void e1000_init_function_pointers_82571(struct e1000_hw *hw) ++{ ++ DEBUGFUNC("e1000_init_function_pointers_82571"); + -+/* This defines the bits that are set in the Interrupt Mask -+ * Set/Read Register. Each bit is documented below: -+ * o RXT0 = Receiver Timer Interrupt (ring 0) -+ * o TXDW = Transmit Descriptor Written Back -+ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) -+ * o RXSEQ = Receive Sequence Error -+ * o LSC = Link Status Change -+ */ -+#define IMS_ENABLE_MASK ( \ -+ E1000_IMS_RXT0 | \ -+ E1000_IMS_TXDW | \ -+ E1000_IMS_RXDMT0 | \ -+ E1000_IMS_RXSEQ | \ -+ E1000_IMS_LSC) ++ e1000_init_mac_ops_generic(hw); ++ e1000_init_nvm_ops_generic(hw); ++ hw->mac.ops.init_params = e1000_init_mac_params_82571; ++ hw->nvm.ops.init_params = e1000_init_nvm_params_82571; ++ hw->phy.ops.init_params = e1000_init_phy_params_82571; ++} + -+/* Interrupt Mask Set */ -+#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ -+#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ -+#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ -+#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ -+#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ ++/** ++ * e1000_get_phy_id_82571 - Retrieve the PHY ID and revision ++ * @hw: pointer to the HW structure ++ * ++ * Reads the PHY registers and stores the PHY ID and possibly the PHY ++ * revision in the hardware structure. ++ **/ ++static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_id = 0; + -+/* Interrupt Cause Set */ -+#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ -+#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ ++ DEBUGFUNC("e1000_get_phy_id_82571"); + -+/* Transmit Descriptor Control */ -+#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ -+#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ -+#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ -+#define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ -+#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. -+ still to be processed. */ ++ switch (hw->mac.type) { ++ case e1000_82571: ++ case e1000_82572: ++ /* ++ * 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 ID. ++ */ ++ phy->id = IGP01E1000_I_PHY_ID; ++ break; ++ case e1000_82573: ++ ret_val = e1000_get_phy_id(hw); ++ break; ++ case e1000_82574: ++ ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); ++ if (ret_val) ++ goto out; + -+/* Flow Control Constants */ -+#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 -+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100 -+#define FLOW_CONTROL_TYPE 0x8808 ++ phy->id = (u32)(phy_id << 16); ++ usec_delay(20); ++ ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); ++ if (ret_val) ++ goto out; + -+/* 802.1q VLAN Packet Size */ -+#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ ++ phy->id |= (u32)(phy_id); ++ phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); ++ break; ++ default: ++ ret_val = -E1000_ERR_PHY; ++ break; ++ } + -+/* Receive Address */ -+/* Number of high/low register pairs in the RAR. The RAR (Receive Address -+ * Registers) holds the directed and multicast addresses that we monitor. -+ * Technically, we have 16 spots. However, we reserve one of these spots -+ * (RAR[15]) for our directed address used by controllers with -+ * manageability enabled, allowing us room for 15 multicast addresses. -+ */ -+#define E1000_RAR_ENTRIES 15 -+#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ ++out: ++ return ret_val; ++} + -+/* Error Codes */ -+#define E1000_ERR_NVM 1 -+#define E1000_ERR_PHY 2 -+#define E1000_ERR_CONFIG 3 -+#define E1000_ERR_PARAM 4 -+#define E1000_ERR_MAC_INIT 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 -+#define E1000_NOT_IMPLEMENTED 14 ++/** ++ * e1000_get_hw_semaphore_82571 - Acquire hardware semaphore ++ * @hw: pointer to the HW structure ++ * ++ * Acquire the HW semaphore to access the PHY or NVM ++ **/ ++static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) ++{ ++ u32 swsm; ++ s32 ret_val = E1000_SUCCESS; ++ s32 timeout = hw->nvm.word_size + 1; ++ s32 i = 0; + -+/* Loop limit on how long we wait for auto-negotiation to complete */ -+#define FIBER_LINK_UP_LIMIT 50 -+#define COPPER_LINK_UP_LIMIT 10 -+#define PHY_AUTO_NEG_LIMIT 45 -+#define PHY_FORCE_LIMIT 20 -+/* Number of 100 microseconds we wait for PCI Express master disable */ -+#define MASTER_DISABLE_TIMEOUT 800 -+/* Number of milliseconds we wait for PHY configuration done after MAC reset */ -+#define PHY_CFG_TIMEOUT 100 -+/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */ -+#define MDIO_OWNERSHIP_TIMEOUT 10 -+/* Number of milliseconds for NVM auto read done after MAC reset. */ -+#define AUTO_READ_DONE_TIMEOUT 10 ++ DEBUGFUNC("e1000_get_hw_semaphore_82571"); + -+/* Flow Control */ -+#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ ++ /* Get the FW semaphore. */ ++ for (i = 0; i < timeout; i++) { ++ swsm = E1000_READ_REG(hw, E1000_SWSM); ++ E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); + -+/* Transmit Configuration Word */ -+#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ -+#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */ -+#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */ -+#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */ -+#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ ++ /* Semaphore acquired if bit latched */ ++ if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) ++ break; + -+/* Receive Configuration Word */ -+#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ -+#define E1000_RXCW_C 0x20000000 /* Receive config */ -+#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ ++ usec_delay(50); ++ } + -+/* PCI Express Control */ -+#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 ++ if (i == timeout) { ++ /* Release semaphores */ ++ e1000_put_hw_semaphore_generic(hw); ++ DEBUGOUT("Driver can't access the NVM\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } + -+#define PCIE_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) ++out: ++ return ret_val; ++} + -+/* PHY Control Register */ -+#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ -+#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ -+#define MII_CR_POWER_DOWN 0x0800 /* Power down */ -+#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ -+#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ -+#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ -+#define MII_CR_SPEED_1000 0x0040 -+#define MII_CR_SPEED_100 0x2000 -+#define MII_CR_SPEED_10 0x0000 ++/** ++ * e1000_put_hw_semaphore_82571 - Release hardware semaphore ++ * @hw: pointer to the HW structure ++ * ++ * Release hardware semaphore used to access the PHY or NVM ++ **/ ++static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) ++{ ++ u32 swsm; + -+/* PHY Status Register */ -+#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ -+#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ ++ DEBUGFUNC("e1000_put_hw_semaphore_82571"); + -+/* Autoneg Advertisement Register */ -+#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ -+#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ -+#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ -+#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ -+#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ -+#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ ++ swsm = E1000_READ_REG(hw, E1000_SWSM); + -+/* Link Partner Ability Register (Base Page) */ -+#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */ -+#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */ ++ swsm &= ~E1000_SWSM_SWESMBI; + -+/* Autoneg Expansion Register */ ++ E1000_WRITE_REG(hw, E1000_SWSM, swsm); ++} + -+/* 1000BASE-T Control Register */ -+#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ -+#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ -+ /* 0=DTE device */ -+#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ -+ /* 0=Configure PHY as Slave */ -+#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ -+ /* 0=Automatic Master/Slave config */ ++/** ++ * e1000_acquire_nvm_82571 - Request for access to the EEPROM ++ * @hw: pointer to the HW structure ++ * ++ * To gain access to the EEPROM, first we must obtain a hardware semaphore. ++ * Then for non-82573 hardware, set the EEPROM access request bit and wait ++ * for EEPROM access grant bit. If the access grant bit is not set, release ++ * hardware semaphore. ++ **/ ++static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) ++{ ++ s32 ret_val; + -+/* 1000BASE-T Status Register */ -+#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ -+#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ ++ DEBUGFUNC("e1000_acquire_nvm_82571"); + ++ ret_val = e1000_get_hw_semaphore_82571(hw); ++ if (ret_val) ++ goto out; + -+/* PHY 1000 MII Register/Bit Definitions */ -+/* PHY Registers defined by IEEE */ -+#define PHY_CONTROL 0x00 /* Control Register */ -+#define PHY_STATUS 0x01 /* Status Regiser */ -+#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ -+#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ -+#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ -+#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ -+#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ -+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ ++ if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574) ++ ret_val = e1000_acquire_nvm_generic(hw); + -+/* NVM Control */ -+#define E1000_EECD_SK 0x00000001 /* NVM Clock */ -+#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ -+#define E1000_EECD_DI 0x00000004 /* NVM Data In */ -+#define E1000_EECD_DO 0x00000008 /* NVM Data Out */ -+#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */ -+#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */ -+#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */ -+#define E1000_EECD_ADDR_BITS 0x00000400 /* NVM Addressing bits based on type -+ * (0-small, 1-large) */ -+#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */ -+#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ -+#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM Size */ -+#define E1000_EECD_SIZE_EX_SHIFT 11 -+#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ -+#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ -+#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ ++ if (ret_val) ++ e1000_put_hw_semaphore_82571(hw); + -+#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */ -+#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ -+#define E1000_NVM_RW_REG_START 1 /* Start operation */ -+#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ -+#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ -+#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ -+#define E1000_FLASH_UPDATES 2000 ++out: ++ return ret_val; ++} + -+/* NVM Word Offsets */ -+#define NVM_ID_LED_SETTINGS 0x0004 -+#define NVM_INIT_CONTROL2_REG 0x000F -+#define NVM_INIT_CONTROL3_PORT_B 0x0014 -+#define NVM_INIT_3GIO_3 0x001A -+#define NVM_INIT_CONTROL3_PORT_A 0x0024 -+#define NVM_CFG 0x0012 -+#define NVM_CHECKSUM_REG 0x003F -+ -+#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ -+#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */ ++/** ++ * e1000_release_nvm_82571 - Release exclusive access to EEPROM ++ * @hw: pointer to the HW structure ++ * ++ * Stop any current commands to the EEPROM and clear the EEPROM request bit. ++ **/ ++static void e1000_release_nvm_82571(struct e1000_hw *hw) ++{ ++ DEBUGFUNC("e1000_release_nvm_82571"); + -+/* Mask bits for fields in Word 0x0f of the NVM */ -+#define NVM_WORD0F_PAUSE_MASK 0x3000 -+#define NVM_WORD0F_PAUSE 0x1000 -+#define NVM_WORD0F_ASM_DIR 0x2000 ++ e1000_release_nvm_generic(hw); ++ e1000_put_hw_semaphore_82571(hw); ++} + -+/* Mask bits for fields in Word 0x1a of the NVM */ -+#define NVM_WORD1A_ASPM_MASK 0x000C ++/** ++ * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface ++ * @hw: pointer to the HW structure ++ * @offset: offset within the EEPROM to be written to ++ * @words: number of words to write ++ * @data: 16 bit word(s) to be written to the EEPROM ++ * ++ * For non-82573 silicon, write data to EEPROM at offset using SPI interface. ++ * ++ * If e1000_update_nvm_checksum is not called after this function, the ++ * EEPROM will most likely contain an invalid checksum. ++ **/ ++static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data) ++{ ++ s32 ret_val = E1000_SUCCESS; + -+/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ -+#define NVM_SUM 0xBABA ++ DEBUGFUNC("e1000_write_nvm_82571"); + -+#define NVM_WORD_SIZE_BASE_SHIFT 6 ++ switch (hw->mac.type) { ++ case e1000_82573: ++ case e1000_82574: ++ ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); ++ break; ++ case e1000_82571: ++ case e1000_82572: ++ ret_val = e1000_write_nvm_spi(hw, offset, words, data); ++ break; ++ default: ++ ret_val = -E1000_ERR_NVM; ++ break; ++ } + -+/* NVM Commands - Microwire */ ++ return ret_val; ++} + -+/* NVM Commands - SPI */ -+#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ -+#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ -+#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ -+#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ -+#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ -+#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ ++/** ++ * e1000_update_nvm_checksum_82571 - Update EEPROM checksum ++ * @hw: pointer to the HW structure ++ * ++ * Updates the EEPROM checksum by reading/adding each word of the EEPROM ++ * up to the checksum. Then calculates the EEPROM checksum and writes the ++ * value to the EEPROM. ++ **/ ++static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) ++{ ++ u32 eecd; ++ s32 ret_val; ++ u16 i; + -+/* SPI NVM Status Register */ -+#define NVM_STATUS_RDY_SPI 0x01 ++ DEBUGFUNC("e1000_update_nvm_checksum_82571"); + -+/* Word definitions for ID LED Settings */ -+#define ID_LED_RESERVED_0000 0x0000 -+#define ID_LED_RESERVED_FFFF 0xFFFF -+#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_DEF1_DEF2 0x1 -+#define ID_LED_DEF1_ON2 0x2 -+#define ID_LED_DEF1_OFF2 0x3 -+#define ID_LED_ON1_DEF2 0x4 -+#define ID_LED_ON1_ON2 0x5 -+#define ID_LED_ON1_OFF2 0x6 -+#define ID_LED_OFF1_DEF2 0x7 -+#define ID_LED_OFF1_ON2 0x8 -+#define ID_LED_OFF1_OFF2 0x9 ++ ret_val = e1000_update_nvm_checksum_generic(hw); ++ if (ret_val) ++ goto out; + -+#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF -+#define IGP_ACTIVITY_LED_ENABLE 0x0300 -+#define IGP_LED3_MODE 0x07000000 ++ /* ++ * If our nvm is an EEPROM, then we're done ++ * otherwise, commit the checksum to the flash NVM. ++ */ ++ if (hw->nvm.type != e1000_nvm_flash_hw) ++ goto out; + -+/* PCI/PCI-X/PCI-EX Config space */ -+#define PCI_HEADER_TYPE_REGISTER 0x0E -+#define PCIE_LINK_STATUS 0x12 ++ /* Check for pending operations. */ ++ for (i = 0; i < E1000_FLASH_UPDATES; i++) { ++ msec_delay(1); ++ if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) ++ break; ++ } + -+#define PCI_HEADER_TYPE_MULTIFUNC 0x80 -+#define PCIE_LINK_WIDTH_MASK 0x3F0 -+#define PCIE_LINK_WIDTH_SHIFT 4 ++ if (i == E1000_FLASH_UPDATES) { ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } + -+#define PHY_REVISION_MASK 0xFFFFFFF0 -+#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ -+#define MAX_PHY_MULTI_PAGE_REG 0xF ++ /* Reset the firmware if using STM opcode. */ ++ if ((E1000_READ_REG(hw, E1000_FLOP) & 0xFF00) == E1000_STM_OPCODE) { ++ /* ++ * The enabling of and the actual reset must be done ++ * in two write cycles. ++ */ ++ E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET_ENABLE); ++ E1000_WRITE_FLUSH(hw); ++ E1000_WRITE_REG(hw, E1000_HICR, E1000_HICR_FW_RESET); ++ } + -+/* 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 -+#define IGP01E1000_I_PHY_ID 0x02A80380 -+#define M88E1111_I_PHY_ID 0x01410CC0 -+#define GG82563_E_PHY_ID 0x01410CA0 -+#define IGP03E1000_E_PHY_ID 0x02A80390 -+#define IFE_E_PHY_ID 0x02A80330 -+#define IFE_PLUS_E_PHY_ID 0x02A80320 -+#define IFE_C_E_PHY_ID 0x02A80310 ++ /* Commit the write to flash */ ++ eecd = E1000_READ_REG(hw, E1000_EECD) | E1000_EECD_FLUPD; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); + -+/* M88E1000 Specific Registers */ -+#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ -+#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ -+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ ++ for (i = 0; i < E1000_FLASH_UPDATES; i++) { ++ msec_delay(1); ++ if ((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_FLUPD) == 0) ++ break; ++ } + -+#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */ -+#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */ ++ if (i == E1000_FLASH_UPDATES) { ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } + -+/* M88E1000 PHY Specific Control Register */ -+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ -+#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */ -+ /* Manual MDI configuration */ -+#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ -+#define M88E1000_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, -+ * 100BASE-TX/10BASE-T: -+ * MDI Mode -+ */ -+#define M88E1000_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled -+ * all speeds. -+ */ -+ /* 1=Enable Extended 10BASE-T distance -+ * (Lower 10BASE-T RX Threshold) -+ * 0=Normal 10BASE-T RX Threshold */ -+ /* 1=5-Bit interface in 100BASE-TX -+ * 0=MII interface in 100BASE-TX */ -+#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ ++out: ++ return ret_val; ++} + -+/* M88E1000 PHY Specific Status Register */ -+#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ -+#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ -+#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ -+#define M88E1000_PSSR_CABLE_LENGTH 0x0380 /* 0=<50M;1=50-80M;2=80-110M; -+ * 3=110-140M;4=>140M */ -+#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ -+#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ ++/** ++ * e1000_validate_nvm_checksum_82571 - Validate EEPROM checksum ++ * @hw: pointer to the HW structure ++ * ++ * Calculates the EEPROM checksum by reading/adding each word of the EEPROM ++ * and then verifies that the sum of the EEPROM is equal to 0xBABA. ++ **/ ++static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) ++{ ++ DEBUGFUNC("e1000_validate_nvm_checksum_82571"); + -+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 ++ if (hw->nvm.type == e1000_nvm_flash_hw) ++ e1000_fix_nvm_checksum_82571(hw); + -+/* Number of times we will attempt to autonegotiate before downshifting if we -+ * are the master */ -+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 -+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 -+/* Number of times we will attempt to autonegotiate before downshifting if we -+ * are the slave */ -+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 -+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 -+#define M88E1000_EPSCR_TX_CLK_25 0x0070 /* 25 MHz TX_CLK */ ++ return e1000_validate_nvm_checksum_generic(hw); ++} + -+/* M88EC018 Rev 2 specific DownShift settings */ -+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK 0x0E00 -+#define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 ++/** ++ * e1000_write_nvm_eewr_82571 - Write to EEPROM for 82573 silicon ++ * @hw: pointer to the HW structure ++ * @offset: offset within the EEPROM to be written to ++ * @words: number of words to write ++ * @data: 16 bit word(s) to be written to the EEPROM ++ * ++ * After checking for invalid values, poll the EEPROM to ensure the previous ++ * command has completed before trying to write the next word. After write ++ * poll for completion. ++ * ++ * If e1000_update_nvm_checksum is not called after this function, the ++ * EEPROM will most likely contain an invalid checksum. ++ **/ ++static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 i, eewr = 0; ++ s32 ret_val = 0; + -+/* 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 ++ DEBUGFUNC("e1000_write_nvm_eewr_82571"); + -+/* GG82563 Specific Registers */ -+#define GG82563_PHY_SPEC_CTRL \ -+ GG82563_REG(0, 16) /* PHY Specific Control */ -+#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 */ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } + -+#define GG82563_PHY_MAC_SPEC_CTRL \ -+ GG82563_REG(2, 21) /* MAC Specific Control Register */ ++ for (i = 0; i < words; i++) { ++ eewr = (data[i] << E1000_NVM_RW_REG_DATA) | ++ ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) | ++ E1000_NVM_RW_REG_START; + -+#define GG82563_PHY_DSP_DISTANCE \ -+ GG82563_REG(5, 26) /* DSP Distance */ ++ ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); ++ if (ret_val) ++ break; + -+/* Page 193 - Port Control Registers */ -+#define GG82563_PHY_KMRN_MODE_CTRL \ -+ GG82563_REG(193, 16) /* Kumeran Mode Control */ -+#define GG82563_PHY_PWR_MGMT_CTRL \ -+ GG82563_REG(193, 20) /* Power Management Control */ ++ E1000_WRITE_REG(hw, E1000_EEWR, eewr); + -+/* Page 194 - KMRN Registers */ -+#define GG82563_PHY_INBAND_CTRL \ -+ GG82563_REG(194, 18) /* Inband Control */ ++ ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE); ++ if (ret_val) ++ break; ++ } + -+/* MDI Control */ -+#define E1000_MDIC_REG_SHIFT 16 -+#define E1000_MDIC_PHY_SHIFT 21 -+#define E1000_MDIC_OP_WRITE 0x04000000 -+#define E1000_MDIC_OP_READ 0x08000000 -+#define E1000_MDIC_READY 0x10000000 -+#define E1000_MDIC_ERROR 0x40000000 ++out: ++ return ret_val; ++} + -+/* SerDes Control */ -+#define E1000_GEN_POLL_TIMEOUT 640 ++/** ++ * e1000_get_cfg_done_82571 - Poll for configuration done ++ * @hw: pointer to the HW structure ++ * ++ * Reads the management control register for the config done bit to be set. ++ **/ ++static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) ++{ ++ s32 timeout = PHY_CFG_TIMEOUT; ++ s32 ret_val = E1000_SUCCESS; + -+#endif /* _E1000_DEFINES_H_ */ -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000.h linux-2.6.22-10/drivers/net/e1000e/e1000.h ---- linux-2.6.22-0/drivers/net/e1000e/e1000.h 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/e1000.h 2007-11-21 13:55:34.000000000 -0500 -@@ -0,0 +1,519 @@ -+/******************************************************************************* ++ DEBUGFUNC("e1000_get_cfg_done_82571"); + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. -+ -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. -+ -+ This program is distributed in the hope 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ while (timeout) { ++ if (E1000_READ_REG(hw, E1000_EEMNGCTL) & E1000_NVM_CFG_DONE_PORT_0) ++ break; ++ msec_delay(1); ++ timeout--; ++ } ++ if (!timeout) { ++ DEBUGOUT("MNG configuration cycle has not completed.\n"); ++ ret_val = -E1000_ERR_RESET; ++ goto out; ++ } + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++out: ++ return ret_val; ++} + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++/** ++ * e1000_set_d0_lplu_state_82571 - Set Low Power Linkup D0 state ++ * @hw: pointer to the HW structure ++ * @active: true to enable LPLU, false to disable ++ * ++ * Sets the LPLU D0 state according to the active flag. When activating LPLU ++ * this function also disables smart speed and vice versa. LPLU will not be ++ * activated unless the device autonegotiation advertisement meets standards ++ * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function ++ * pointer entry point only called by PHY setup routines. ++ **/ ++static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; + -+*******************************************************************************/ ++ DEBUGFUNC("e1000_set_d0_lplu_state_82571"); + -+/* Linux PRO/1000 Ethernet Driver main header file */ ++ if (!(phy->ops.read_reg)) ++ goto out; + -+#ifndef _E1000_H_ -+#define _E1000_H_ ++ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); ++ if (ret_val) ++ goto out; + -+#include -+#include -+#include -+#include -+#include ++ if (active) { ++ data |= IGP02E1000_PM_D0_LPLU; ++ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, ++ data); ++ if (ret_val) ++ goto out; + -+#include "hw.h" ++ /* When LPLU is enabled, we should disable SmartSpeed */ ++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else { ++ data &= ~IGP02E1000_PM_D0_LPLU; ++ ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, ++ data); ++ /* ++ * 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 (phy->smart_speed == e1000_smart_speed_on) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+struct e1000_info; ++ data |= IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else if (phy->smart_speed == e1000_smart_speed_off) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+#define ndev_printk(level, netdev, format, arg...) \ -+ printk(level "%s: %s: " format, (netdev)->dev.parent->bus_id, \ -+ (netdev)->name, ## arg) ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } ++ } + -+#ifdef DEBUG -+#define ndev_dbg(netdev, format, arg...) \ -+ ndev_printk(KERN_DEBUG , netdev, format, ## arg) -+#else -+#define ndev_dbg(netdev, format, arg...) do { (void)(netdev); } while (0) -+#endif ++out: ++ return ret_val; ++} + -+#define ndev_err(netdev, format, arg...) \ -+ ndev_printk(KERN_ERR , netdev, format, ## arg) -+#define ndev_info(netdev, format, arg...) \ -+ ndev_printk(KERN_INFO , netdev, format, ## arg) -+#define ndev_warn(netdev, format, arg...) \ -+ ndev_printk(KERN_WARNING , netdev, format, ## arg) -+#define ndev_notice(netdev, format, arg...) \ -+ ndev_printk(KERN_NOTICE , netdev, format, ## arg) ++/** ++ * e1000_reset_hw_82571 - Reset hardware ++ * @hw: pointer to the HW structure ++ * ++ * This resets the hardware into a known state. This is a ++ * function pointer entry point called by the api module. ++ **/ ++static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ++{ ++ u32 ctrl, extcnf_ctrl, ctrl_ext, icr; ++ s32 ret_val; ++ u16 i = 0; + ++ DEBUGFUNC("e1000_reset_hw_82571"); + -+/* TX/RX descriptor defines */ -+#define E1000_DEFAULT_TXD 256 -+#define E1000_MAX_TXD 4096 -+#define E1000_MIN_TXD 80 ++ /* ++ * Prevent the PCI-E bus from sticking if there is no TLP connection ++ * on the last TLP read/write transaction when MAC is reset. ++ */ ++ ret_val = e1000_disable_pcie_master_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("PCI-E Master disable polling has failed.\n"); ++ } + -+#define E1000_DEFAULT_RXD 256 -+#define E1000_MAX_RXD 4096 -+#define E1000_MIN_RXD 80 ++ DEBUGOUT("Masking off all interrupts\n"); ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); + -+/* Early Receive defines */ -+#define E1000_ERT_2048 0x100 ++ E1000_WRITE_REG(hw, E1000_RCTL, 0); ++ E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); ++ E1000_WRITE_FLUSH(hw); + -+#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */ ++ msec_delay(10); + -+/* How many Tx Descriptors do we need to call netif_wake_queue ? */ -+/* How many Rx Buffers do we bundle into one write to the hardware ? */ -+#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ ++ /* ++ * Must acquire the MDIO ownership before MAC reset. ++ * Ownership defaults to firmware after a reset. ++ */ ++ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { ++ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); ++ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + -+#define AUTO_ALL_MODES 0 -+#define E1000_EEPROM_APME 0x0400 ++ do { ++ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); ++ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); + -+#define E1000_MNG_VLAN_NONE (-1) ++ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) ++ break; + -+/* Number of packet split data buffers (not including the header buffer) */ -+#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) ++ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + -+enum e1000_boards { -+ board_82571, -+ board_82572, -+ board_82573, -+ board_80003es2lan, -+ board_ich8lan, -+ board_ich9lan, -+}; ++ msec_delay(2); ++ i++; ++ } while (i < MDIO_OWNERSHIP_TIMEOUT); ++ } + -+struct e1000_queue_stats { -+ u64 packets; -+ u64 bytes; -+}; ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); + -+struct e1000_ps_page { -+ struct page *page; -+ u64 dma; /* must be u64 - written to hw */ -+}; ++ DEBUGOUT("Issuing a global reset to MAC\n"); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); + -+/* -+ * wrappers around a pointer to a socket buffer, -+ * so a DMA handle can be stored along with the buffer -+ */ -+struct e1000_buffer { -+ dma_addr_t dma; -+ struct sk_buff *skb; -+ union { -+ /* TX */ -+ struct { -+ unsigned long time_stamp; -+ u16 length; -+ u16 next_to_watch; -+ }; -+ /* RX */ -+ struct page *page; -+ }; ++ if (hw->nvm.type == e1000_nvm_flash_hw) { ++ usec_delay(10); ++ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ ctrl_ext |= E1000_CTRL_EXT_EE_RST; ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); ++ E1000_WRITE_FLUSH(hw); ++ } + -+}; ++ ret_val = e1000_get_auto_rd_done_generic(hw); ++ if (ret_val) ++ /* We don't want to continue accessing MAC registers. */ ++ goto out; + -+struct e1000_ring { -+ void *desc; /* pointer to ring memory */ -+ dma_addr_t dma; /* phys address of ring */ -+ unsigned int size; /* length of ring in bytes */ -+ unsigned int count; /* number of desc. in ring */ ++ /* ++ * Phy configuration from NVM just starts after EECD_AUTO_RD is set. ++ * Need to wait for Phy configuration completion before accessing ++ * NVM and Phy. ++ */ ++ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) ++ msec_delay(25); + -+ u16 next_to_use; -+ u16 next_to_clean; ++ /* Clear any pending interrupt events. */ ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); ++ icr = E1000_READ_REG(hw, E1000_ICR); + -+ u16 head; -+ u16 tail; ++ if (!(e1000_check_alt_mac_addr_generic(hw))) ++ e1000_set_laa_state_82571(hw, true); + -+ /* array of buffer information structs */ -+ struct e1000_buffer *buffer_info; ++out: ++ return ret_val; ++} + -+ union { -+ /* for TX */ -+ struct { -+ bool last_tx_tso; /* used to mark tso desc. */ -+ }; -+ /* for RX */ -+ struct { -+ /* arrays of page information for packet split */ -+ struct e1000_ps_page *ps_pages; -+ struct sk_buff *rx_skb_top; -+ }; -+ }; ++/** ++ * e1000_init_hw_82571 - Initialize hardware ++ * @hw: pointer to the HW structure ++ * ++ * This inits the hardware readying it for operation. ++ **/ ++static s32 e1000_init_hw_82571(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 reg_data; ++ s32 ret_val; ++ u16 i, rar_count = mac->rar_entry_count; + -+ struct e1000_queue_stats stats; -+}; ++ DEBUGFUNC("e1000_init_hw_82571"); + -+/* board specific private data structure */ -+struct e1000_adapter { -+ struct timer_list watchdog_timer; -+ struct timer_list phy_info_timer; -+ struct timer_list blink_timer; ++ e1000_initialize_hw_bits_82571(hw); + -+ struct work_struct reset_task; -+ struct work_struct watchdog_task; ++ /* Initialize identification LED */ ++ ret_val = e1000_id_led_init_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error initializing identification LED\n"); ++ /* This is not fatal and we should not stop init due to this */ ++ } + -+ const struct e1000_info *ei; ++ /* Disabling VLAN filtering */ ++ DEBUGOUT("Initializing the IEEE VLAN\n"); ++ mac->ops.clear_vfta(hw); + -+ struct vlan_group *vlgrp; -+ u32 bd_number; -+ u32 rx_buffer_len; -+ u16 mng_vlan_id; -+ u16 link_speed; -+ u16 link_duplex; ++ /* Setup the receive address. */ ++ /* ++ * If, however, a locally administered address was assigned to the ++ * 82571, we must reserve a RAR for it to work around an issue where ++ * resetting one port will reload the MAC on the other port. ++ */ ++ if (e1000_get_laa_state_82571(hw)) ++ rar_count--; ++ e1000_init_rx_addrs_generic(hw, rar_count); + -+ spinlock_t tx_queue_lock; /* prevent concurrent tail updates */ ++ /* Zero out the Multicast HASH table */ ++ DEBUGOUT("Zeroing the MTA\n"); ++ for (i = 0; i < mac->mta_reg_count; i++) ++ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); + -+ /* this is still needed for 82571 and above */ -+ atomic_t irq_sem; ++ /* Setup link and flow control */ ++ ret_val = mac->ops.setup_link(hw); + -+ /* track device up/down/testing state */ -+ unsigned long state; ++ /* Set the transmit descriptor write-back policy */ ++ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); ++ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | ++ E1000_TXDCTL_FULL_TX_DESC_WB | ++ E1000_TXDCTL_COUNT_DESC; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); + -+ /* Interrupt Throttle Rate */ -+ u32 itr; -+ u32 itr_setting; -+ u16 tx_itr; -+ u16 rx_itr; ++ /* ...for both queues. */ ++ if (mac->type != e1000_82573 && mac->type != e1000_82574) { ++ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); ++ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | ++ E1000_TXDCTL_FULL_TX_DESC_WB | ++ E1000_TXDCTL_COUNT_DESC; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg_data); ++ } else { ++ e1000_enable_tx_pkt_filtering_generic(hw); ++ reg_data = E1000_READ_REG(hw, E1000_GCR); ++ reg_data |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX; ++ E1000_WRITE_REG(hw, E1000_GCR, reg_data); ++ } + + /* -+ * TX ++ * 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 ++ * is no link. + */ -+ struct e1000_ring *tx_ring /* One per active queue */ -+ ____cacheline_aligned_in_smp; ++ e1000_clear_hw_cntrs_82571(hw); + -+ unsigned long tx_queue_len; -+ unsigned int restart_queue; -+ u32 txd_cmd; ++ return ret_val; ++} + -+ bool detect_tx_hung; -+ u8 tx_timeout_factor; -+ -+ u32 tx_int_delay; -+ u32 tx_abs_int_delay; -+ -+ unsigned int total_tx_bytes; -+ unsigned int total_tx_packets; -+ unsigned int total_rx_bytes; -+ unsigned int total_rx_packets; -+ -+ /* TX stats */ -+ u64 tpt_old; -+ u64 colc_old; -+ u64 gotcl_old; -+ u32 gotcl; -+ u32 tx_timeout_count; -+ u32 tx_fifo_head; -+ u32 tx_head_addr; -+ u32 tx_fifo_size; -+ u32 tx_dma_failed; -+ -+ /* -+ * RX -+ */ -+ bool (*clean_rx) (struct e1000_adapter *adapter, -+ int *work_done, int work_to_do) -+ ____cacheline_aligned_in_smp; -+ void (*alloc_rx_buf) (struct e1000_adapter *adapter, -+ int cleaned_count); -+ struct e1000_ring *rx_ring; -+ -+ u32 rx_int_delay; -+ u32 rx_abs_int_delay; -+ -+ /* RX stats */ -+ u64 hw_csum_err; -+ u64 hw_csum_good; -+ u64 rx_hdr_split; -+ u64 gorcl_old; -+ u32 gorcl; -+ u32 alloc_rx_buff_failed; -+ u32 rx_dma_failed; -+ -+ unsigned int rx_ps_pages; -+ u16 rx_ps_bsize0; -+ -+ /* OS defined structs */ -+ struct net_device *netdev; -+ struct pci_dev *pdev; -+ struct net_device_stats net_stats; -+ spinlock_t stats_lock; /* prevent concurrent stats updates */ -+ -+ /* structs defined in e1000_hw.h */ -+ struct e1000_hw hw; -+ -+ struct e1000_hw_stats stats; -+ struct e1000_phy_info phy_info; -+ struct e1000_phy_stats phy_stats; -+ -+ struct e1000_ring test_tx_ring; -+ struct e1000_ring test_rx_ring; -+ u32 test_icr; -+ -+ u32 msg_enable; -+ -+ u32 eeprom_wol; -+ u32 wol; -+ u32 pba; -+ -+ u8 fc_autoneg; -+ -+ unsigned long led_status; ++/** ++ * e1000_initialize_hw_bits_82571 - Initialize hardware-dependent bits ++ * @hw: pointer to the HW structure ++ * ++ * Initializes required hardware-dependent bits needed for normal operation. ++ **/ ++static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) ++{ ++ u32 reg; + -+ unsigned int flags; -+}; ++ DEBUGFUNC("e1000_initialize_hw_bits_82571"); + -+struct e1000_info { -+ enum e1000_mac_type mac; -+ unsigned int flags; -+ u32 pba; -+ s32 (*get_invariants)(struct e1000_adapter *); -+ struct e1000_mac_operations *mac_ops; -+ struct e1000_phy_operations *phy_ops; -+ struct e1000_nvm_operations *nvm_ops; -+}; ++ if (hw->mac.disable_hw_init_bits) ++ goto out; + -+/* hardware capability, feature, and workaround flags */ -+#define FLAG_HAS_AMT (1 << 0) -+#define FLAG_HAS_FLASH (1 << 1) -+#define FLAG_HAS_HW_VLAN_FILTER (1 << 2) -+#define FLAG_HAS_WOL (1 << 3) -+#define FLAG_HAS_ERT (1 << 4) -+#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) -+#define FLAG_HAS_SWSM_ON_LOAD (1 << 6) -+#define FLAG_HAS_JUMBO_FRAMES (1 << 7) -+#define FLAG_HAS_ASPM (1 << 8) -+#define FLAG_HAS_STATS_ICR_ICT (1 << 9) -+#define FLAG_HAS_STATS_PTC_PRC (1 << 10) -+#define FLAG_HAS_SMART_POWER_DOWN (1 << 11) -+#define FLAG_IS_QUAD_PORT_A (1 << 12) -+#define FLAG_IS_QUAD_PORT (1 << 13) -+#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN (1 << 14) -+#define FLAG_APME_IN_WUC (1 << 15) -+#define FLAG_APME_IN_CTRL3 (1 << 16) -+#define FLAG_APME_CHECK_PORT_B (1 << 17) -+#define FLAG_DISABLE_FC_PAUSE_TIME (1 << 18) -+#define FLAG_NO_WAKE_UCAST (1 << 19) -+#define FLAG_MNG_PT_ENABLED (1 << 20) -+#define FLAG_RESET_OVERWRITES_LAA (1 << 21) -+#define FLAG_TARC_SPEED_MODE_BIT (1 << 22) -+#define FLAG_TARC_SET_BIT_ZERO (1 << 23) -+#define FLAG_RX_NEEDS_RESTART (1 << 24) -+#define FLAG_LSC_GIG_SPEED_DROP (1 << 25) -+#define FLAG_SMART_POWER_DOWN (1 << 26) -+#define FLAG_MSI_ENABLED (1 << 27) -+#define FLAG_RX_CSUM_ENABLED (1 << 28) -+#define FLAG_TSO_FORCE (1 << 29) ++ /* Transmit Descriptor Control 0 */ ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); + -+#define E1000_RX_DESC_PS(R, i) \ -+ (&(((union e1000_rx_desc_packet_split *)((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) -+#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc) ++ /* Transmit Descriptor Control 1 */ ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); + -+enum e1000_state_t { -+ __E1000_TESTING, -+ __E1000_RESETTING, -+ __E1000_DOWN -+}; ++ /* Transmit Arbitration Control 0 */ ++ reg = E1000_READ_REG(hw, E1000_TARC(0)); ++ reg &= ~(0xF << 27); /* 30:27 */ ++ switch (hw->mac.type) { ++ case e1000_82571: ++ case e1000_82572: ++ reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26); ++ break; ++ default: ++ break; ++ } ++ E1000_WRITE_REG(hw, E1000_TARC(0), reg); + -+enum latency_range { -+ lowest_latency = 0, -+ low_latency = 1, -+ bulk_latency = 2, -+ latency_invalid = 255 -+}; ++ /* Transmit Arbitration Control 1 */ ++ reg = E1000_READ_REG(hw, E1000_TARC(1)); ++ switch (hw->mac.type) { ++ case e1000_82571: ++ case e1000_82572: ++ reg &= ~((1 << 29) | (1 << 30)); ++ reg |= (1 << 22) | (1 << 24) | (1 << 25) | (1 << 26); ++ if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) ++ reg &= ~(1 << 28); ++ else ++ reg |= (1 << 28); ++ E1000_WRITE_REG(hw, E1000_TARC(1), reg); ++ break; ++ default: ++ break; ++ } + -+extern char e1000e_driver_name[]; -+extern const char e1000e_driver_version[]; ++ /* Device Control */ ++ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { ++ reg = E1000_READ_REG(hw, E1000_CTRL); ++ reg &= ~(1 << 29); ++ E1000_WRITE_REG(hw, E1000_CTRL, reg); ++ } + -+extern void e1000e_check_options(struct e1000_adapter *adapter); -+extern void e1000e_set_ethtool_ops(struct net_device *netdev); ++ /* Extended Device Control */ ++ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { ++ reg = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ reg &= ~(1 << 23); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); ++ } + -+extern int e1000e_up(struct e1000_adapter *adapter); -+extern void e1000e_down(struct e1000_adapter *adapter); -+extern void e1000e_reinit_locked(struct e1000_adapter *adapter); -+extern void e1000e_reset(struct e1000_adapter *adapter); -+extern void e1000e_power_up_phy(struct e1000_adapter *adapter); -+extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter); -+extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter); -+extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); -+extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); -+extern void e1000e_update_stats(struct e1000_adapter *adapter); ++ /* PCI-Ex Control Register */ ++ if (hw->mac.type == e1000_82574) { ++ reg = E1000_READ_REG(hw, E1000_GCR); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_GCR, reg); ++ } + -+extern unsigned int copybreak; ++out: ++ return; ++} + -+extern char *e1000e_get_hw_dev_name(struct e1000_hw *hw); -+ -+extern struct e1000_info e1000_82571_info; -+extern struct e1000_info e1000_82572_info; -+extern struct e1000_info e1000_82573_info; -+extern struct e1000_info e1000_ich8_info; -+extern struct e1000_info e1000_ich9_info; -+extern struct e1000_info e1000_es2_info; -+ -+extern s32 e1000e_commit_phy(struct e1000_hw *hw); -+ -+extern bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw); -+ -+extern bool e1000e_get_laa_state_82571(struct e1000_hw *hw); -+extern void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state); -+ -+extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, -+ bool state); -+extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); -+extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); -+ -+extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw); -+extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw); -+extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw); -+extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw); -+extern s32 e1000e_led_on_generic(struct e1000_hw *hw); -+extern s32 e1000e_led_off_generic(struct e1000_hw *hw); -+extern s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw); -+extern s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex); -+extern s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex); -+extern s32 e1000e_disable_pcie_master(struct e1000_hw *hw); -+extern s32 e1000e_get_auto_rd_done(struct e1000_hw *hw); -+extern s32 e1000e_id_led_init(struct e1000_hw *hw); -+extern void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw); -+extern s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw); -+extern s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw); -+extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw); -+extern s32 e1000e_setup_link(struct e1000_hw *hw); -+extern void e1000e_clear_vfta(struct e1000_hw *hw); -+extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count); -+extern void e1000e_mc_addr_list_update_generic(struct e1000_hw *hw, -+ u8 *mc_addr_list, u32 mc_addr_count, -+ u32 rar_used_count, u32 rar_count); -+extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); -+extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw); -+extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop); -+extern s32 e1000e_get_hw_semaphore(struct e1000_hw *hw); -+extern s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data); -+extern void e1000e_config_collision_dist(struct e1000_hw *hw); -+extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw); -+extern s32 e1000e_force_mac_fc(struct e1000_hw *hw); -+extern s32 e1000e_blink_led(struct e1000_hw *hw); -+extern void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value); -+extern void e1000e_reset_adaptive(struct e1000_hw *hw); -+extern void e1000e_update_adaptive(struct e1000_hw *hw); ++/** ++ * e1000_clear_vfta_82571 - Clear VLAN filter table ++ * @hw: pointer to the HW structure ++ * ++ * Clears the register array which contains the VLAN filter table by ++ * setting all the values to 0. ++ **/ ++static void e1000_clear_vfta_82571(struct e1000_hw *hw) ++{ ++ u32 offset; ++ u32 vfta_value = 0; ++ u32 vfta_offset = 0; ++ u32 vfta_bit_in_reg = 0; + -+extern s32 e1000e_setup_copper_link(struct e1000_hw *hw); -+extern s32 e1000e_get_phy_id(struct e1000_hw *hw); -+extern void e1000e_put_hw_semaphore(struct e1000_hw *hw); -+extern s32 e1000e_check_reset_block_generic(struct e1000_hw *hw); -+extern s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw); -+extern s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw); -+extern s32 e1000e_get_phy_info_igp(struct e1000_hw *hw); -+extern s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); -+extern s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw); -+extern s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active); -+extern s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); -+extern s32 e1000e_phy_sw_reset(struct e1000_hw *hw); -+extern s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw); -+extern s32 e1000e_get_cfg_done(struct e1000_hw *hw); -+extern s32 e1000e_get_cable_length_m88(struct e1000_hw *hw); -+extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw); -+extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); -+extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); -+extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id); -+extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); -+extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data); -+extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data); -+extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, -+ u32 usec_interval, bool *success); -+extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw); -+extern s32 e1000e_check_downshift(struct e1000_hw *hw); ++ DEBUGFUNC("e1000_clear_vfta_82571"); + -+static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw) -+{ -+ return hw->phy.ops.reset_phy(hw); ++ if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { ++ 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, E1000_VFTA, offset, vfta_value); ++ E1000_WRITE_FLUSH(hw); ++ } +} + -+static inline s32 e1000_check_reset_block(struct e1000_hw *hw) ++/** ++ * e1000_check_mng_mode_82574 - Check manageability is enabled ++ * @hw: pointer to the HW structure ++ * ++ * Reads the NVM Initialization Control Word 2 and returns true ++ * (>0) if any manageability is enabled, else false (0). ++ **/ ++static bool e1000_check_mng_mode_82574(struct e1000_hw *hw) +{ -+ return hw->phy.ops.check_reset_block(hw); -+} ++ u16 data; + -+static inline s32 e1e_rphy(struct e1000_hw *hw, u32 offset, u16 *data) -+{ -+ return hw->phy.ops.read_phy_reg(hw, offset, data); -+} ++ DEBUGFUNC("e1000_check_mng_mode_82574"); + -+static inline s32 e1e_wphy(struct e1000_hw *hw, u32 offset, u16 data) -+{ -+ return hw->phy.ops.write_phy_reg(hw, offset, data); ++ hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data); ++ return ((data & E1000_NVM_INIT_CTRL2_MNGM) != 0); +} + -+static inline s32 e1000_get_cable_length(struct e1000_hw *hw) ++/** ++ * e1000_led_on_82574 - Turn LED on ++ * @hw: pointer to the HW structure ++ * ++ * Turn LED on. ++ **/ ++static s32 e1000_led_on_82574(struct e1000_hw *hw) +{ -+ return hw->phy.ops.get_cable_length(hw); -+} ++ u32 ctrl; ++ u32 i; + -+extern s32 e1000e_acquire_nvm(struct e1000_hw *hw); -+extern s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -+extern s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw); -+extern s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg); -+extern s32 e1000e_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -+extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -+extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw); -+extern void e1000e_release_nvm(struct e1000_hw *hw); -+extern void e1000e_reload_nvm(struct e1000_hw *hw); -+extern s32 e1000e_read_mac_addr(struct e1000_hw *hw); ++ DEBUGFUNC("e1000_led_on_82574"); + -+static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) -+{ -+ return hw->nvm.ops.validate_nvm(hw); -+} ++ ctrl = hw->mac.ledctl_mode2; ++ if (!(E1000_STATUS_LU & E1000_READ_REG(hw, E1000_STATUS))) { ++ /* ++ * If no link, then turn LED on by setting the invert bit ++ * for each LED that's "on" (0x0E) in ledctl_mode2. ++ */ ++ for (i = 0; i < 4; i++) ++ if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == ++ E1000_LEDCTL_MODE_LED_ON) ++ ctrl |= (E1000_LEDCTL_LED0_IVRT << (i * 8)); ++ } ++ E1000_WRITE_REG(hw, E1000_LEDCTL, ctrl); + -+static inline s32 e1000e_update_nvm_checksum(struct e1000_hw *hw) -+{ -+ return hw->nvm.ops.update_nvm(hw); ++ return E1000_SUCCESS; +} + -+static inline s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++/** ++ * e1000_update_mc_addr_list_82571 - Update Multicast addresses ++ * @hw: pointer to the HW structure ++ * @mc_addr_list: array of multicast addresses to program ++ * @mc_addr_count: number of multicast addresses to program ++ * @rar_used_count: the first RAR register free to program ++ * @rar_count: total number of supported Receive Address Registers ++ * ++ * Updates the Receive Address Registers and Multicast Table Array. ++ * The caller must have a packed mc_addr_list of multicast addresses. ++ * The parameter rar_count will usually be hw->mac.rar_entry_count ++ * unless there are workarounds that change this. ++ **/ ++static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, ++ u8 *mc_addr_list, u32 mc_addr_count, ++ u32 rar_used_count, u32 rar_count) +{ -+ return hw->nvm.ops.read_nvm(hw, offset, words, data); -+} ++ DEBUGFUNC("e1000_update_mc_addr_list_82571"); + -+static inline s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) -+{ -+ return hw->nvm.ops.write_nvm(hw, offset, words, data); ++ if (e1000_get_laa_state_82571(hw)) ++ rar_count--; ++ ++ e1000_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count, ++ rar_used_count, rar_count); +} + -+static inline s32 e1000_get_phy_info(struct e1000_hw *hw) ++/** ++ * e1000_setup_link_82571 - Setup flow control and link settings ++ * @hw: pointer to the HW structure ++ * ++ * Determines which flow control settings to use, then configures flow ++ * control. Calls the appropriate media-specific link configuration ++ * function. Assuming the adapter has a valid link partner, a valid link ++ * should be established. Assumes the hardware has previously been reset ++ * and the transmitter and receiver are not enabled. ++ **/ ++static s32 e1000_setup_link_82571(struct e1000_hw *hw) +{ -+ return hw->phy.ops.get_phy_info(hw); -+} ++ DEBUGFUNC("e1000_setup_link_82571"); + -+extern bool e1000e_check_mng_mode(struct e1000_hw *hw); -+extern bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw); -+extern s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length); ++ /* ++ * 82573 does not have a word in the NVM to determine ++ * the default flow control setting, so we explicitly ++ * set it to full. ++ */ ++ if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && ++ hw->fc.type == e1000_fc_default) ++ hw->fc.type = e1000_fc_full; + -+static inline u32 __er32(struct e1000_hw *hw, unsigned long reg) -+{ -+ return readl(hw->hw_addr + reg); ++ return e1000_setup_link_generic(hw); +} + -+static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val) -+{ -+ writel(val, hw->hw_addr + reg); -+} -+ -+#endif /* _E1000_H_ */ -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/es2lan.c linux-2.6.22-10/drivers/net/e1000e/es2lan.c ---- linux-2.6.22-0/drivers/net/e1000e/es2lan.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/es2lan.c 2007-11-21 13:55:28.000000000 -0500 -@@ -0,0 +1,1232 @@ -+/******************************************************************************* -+ -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. -+ -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. -+ -+ This program is distributed in the hope 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+ -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". -+ -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 -+ -+*******************************************************************************/ -+ -+/* -+ * 80003ES2LAN Gigabit Ethernet Controller (Copper) -+ * 80003ES2LAN Gigabit Ethernet Controller (Serdes) -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include "e1000.h" -+ -+#define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL 0x00 -+#define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL 0x02 -+#define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL 0x10 -+ -+#define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS 0x0008 -+#define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS 0x0800 -+#define E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING 0x0010 -+ -+#define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004 -+#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 -+ -+#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ -+#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 -+ -+#define DEFAULT_TIPG_IPGT_1000_80003ES2LAN 0x8 -+#define DEFAULT_TIPG_IPGT_10_100_80003ES2LAN 0x9 -+ -+/* GG82563 PHY Specific Status Register (Page 0, Register 16 */ -+#define GG82563_PSCR_POLARITY_REVERSAL_DISABLE 0x0002 /* 1=Reversal Disab. */ -+#define GG82563_PSCR_CROSSOVER_MODE_MASK 0x0060 -+#define GG82563_PSCR_CROSSOVER_MODE_MDI 0x0000 /* 00=Manual MDI */ -+#define GG82563_PSCR_CROSSOVER_MODE_MDIX 0x0020 /* 01=Manual MDIX */ -+#define GG82563_PSCR_CROSSOVER_MODE_AUTO 0x0060 /* 11=Auto crossover */ -+ -+/* PHY Specific Control Register 2 (Page 0, Register 26) */ -+#define GG82563_PSCR2_REVERSE_AUTO_NEG 0x2000 -+ /* 1=Reverse Auto-Negotiation */ -+ -+/* 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_5 0x0004 -+#define GG82563_MSCR_TX_CLK_100MBPS_25 0x0005 -+#define GG82563_MSCR_TX_CLK_1000MBPS_25 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_PASS_FALSE_CARRIER 0x0800 -+ -+/* Power Management Control Register (Page 193, Register 20) */ -+#define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE 0x0001 -+ /* 1=Enable SERDES Electrical Idle */ -+ -+/* In-Band Control Register (Page 194, Register 18) */ -+#define GG82563_ICR_DIS_PADDING 0x0010 /* Disable Padding */ -+ -+/* A table for the GG82563 cable length where the range is defined -+ * with a lower bound at "index" and the upper bound at -+ * "index + 5". -+ */ -+static const u16 e1000_gg82563_cable_length_table[] = -+ { 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; -+ -+static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); -+static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); -+static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); -+static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); -+static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); -+static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); -+static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); -+ +/** -+ * e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs. ++ * e1000_setup_copper_link_82571 - Configure copper link settings + * @hw: pointer to the HW structure + * -+ * This is a function pointer entry point called by the api module. ++ * Configures the link for auto-neg or forced speed and duplex. Then we check ++ * for link, once link is established calls to configure collision distance ++ * and flow control are called. + **/ -+static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) ++static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; ++ u32 ctrl, led_ctrl; ++ s32 ret_val; + -+ if (hw->media_type != e1000_media_type_copper) { -+ phy->type = e1000_phy_none; -+ return 0; -+ } ++ DEBUGFUNC("e1000_setup_copper_link_82571"); + -+ phy->addr = 1; -+ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; -+ phy->reset_delay_us = 100; -+ phy->type = e1000_phy_gg82563; ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= E1000_CTRL_SLU; ++ ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); + -+ /* This can only be done after all function pointers are setup. */ -+ ret_val = e1000e_get_phy_id(hw); ++ switch (hw->phy.type) { ++ case e1000_phy_m88: ++ case e1000_phy_bm: ++ ret_val = e1000_copper_link_setup_m88(hw); ++ break; ++ case e1000_phy_igp_2: ++ ret_val = e1000_copper_link_setup_igp(hw); ++ /* Setup activity LED */ ++ led_ctrl = E1000_READ_REG(hw, E1000_LEDCTL); ++ led_ctrl &= IGP_ACTIVITY_LED_MASK; ++ led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); ++ E1000_WRITE_REG(hw, E1000_LEDCTL, led_ctrl); ++ break; ++ default: ++ ret_val = -E1000_ERR_PHY; ++ break; ++ } + -+ /* Verify phy id */ -+ if (phy->id != GG82563_E_PHY_ID) -+ return -E1000_ERR_PHY; ++ if (ret_val) ++ goto out; + ++ ret_val = e1000_setup_copper_link_generic(hw); ++ ++out: + return ret_val; +} + +/** -+ * e1000_init_nvm_params_80003es2lan - Init ESB2 NVM func ptrs. ++ * e1000_setup_fiber_serdes_link_82571 - Setup link for fiber/serdes + * @hw: pointer to the HW structure + * -+ * This is a function pointer entry point called by the api module. ++ * Configures collision distance and flow control for fiber and serdes links. ++ * Upon successful setup, poll for link. + **/ -+static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) ++static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 eecd = er32(EECD); -+ u16 size; ++ DEBUGFUNC("e1000_setup_fiber_serdes_link_82571"); + -+ nvm->opcode_bits = 8; -+ nvm->delay_usec = 1; -+ switch (nvm->override) { -+ case e1000_nvm_override_spi_large: -+ nvm->page_size = 32; -+ nvm->address_bits = 16; -+ break; -+ case e1000_nvm_override_spi_small: -+ nvm->page_size = 8; -+ nvm->address_bits = 8; ++ switch (hw->mac.type) { ++ case e1000_82571: ++ case e1000_82572: ++ /* ++ * If SerDes loopback mode is entered, there is no form ++ * of reset to take the adapter out of that mode. So we ++ * have to explicitly take the adapter out of loopback ++ * mode. This prevents drivers from twiddling their thumbs ++ * if another tool failed to take it out of loopback mode. ++ */ ++ E1000_WRITE_REG(hw, E1000_SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK); + break; + default: -+ nvm->page_size = eecd & E1000_EECD_ADDR_BITS ? 32 : 8; -+ nvm->address_bits = eecd & E1000_EECD_ADDR_BITS ? 16 : 8; + break; + } + -+ nvm->type = e1000_nvm_eeprom_spi; -+ -+ size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >> -+ E1000_EECD_SIZE_EX_SHIFT); -+ -+ /* Added to a constant, "size" becomes the left-shift value -+ * for setting word_size. -+ */ -+ size += NVM_WORD_SIZE_BASE_SHIFT; -+ nvm->word_size = 1 << size; -+ -+ return 0; ++ return e1000_setup_fiber_serdes_link_generic(hw); +} + +/** -+ * e1000_init_mac_params_80003es2lan - Init ESB2 MAC func ptrs. ++ * e1000_valid_led_default_82571 - Verify a valid default LED config + * @hw: pointer to the HW structure ++ * @data: pointer to the NVM (EEPROM) + * -+ * This is a function pointer entry point called by the api module. ++ * Read the EEPROM for the current default LED configuration. If the ++ * LED configuration is not valid, set to a valid LED configuration. + **/ -+static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) ++static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_mac_info *mac = &hw->mac; -+ struct e1000_mac_operations *func = &mac->ops; -+ -+ /* Set media type */ -+ switch (adapter->pdev->device) { -+ case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: -+ hw->media_type = e1000_media_type_internal_serdes; -+ break; -+ default: -+ hw->media_type = e1000_media_type_copper; -+ break; -+ } ++ s32 ret_val; + -+ /* Set mta register count */ -+ mac->mta_reg_count = 128; -+ /* Set rar entry count */ -+ mac->rar_entry_count = E1000_RAR_ENTRIES; -+ /* Set if manageability features are enabled. */ -+ mac->arc_subsystem_valid = -+ (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0; ++ DEBUGFUNC("e1000_valid_led_default_82571"); + -+ /* check for link */ -+ switch (hw->media_type) { -+ case e1000_media_type_copper: -+ func->setup_physical_interface = e1000_setup_copper_link_80003es2lan; -+ func->check_for_link = e1000e_check_for_copper_link; -+ break; -+ case e1000_media_type_fiber: -+ func->setup_physical_interface = e1000e_setup_fiber_serdes_link; -+ func->check_for_link = e1000e_check_for_fiber_link; -+ break; -+ case e1000_media_type_internal_serdes: -+ func->setup_physical_interface = e1000e_setup_fiber_serdes_link; -+ func->check_for_link = e1000e_check_for_serdes_link; -+ break; -+ default: -+ return -E1000_ERR_CONFIG; -+ break; ++ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; + } + -+ return 0; ++ if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && ++ *data == ID_LED_RESERVED_F746) ++ *data = ID_LED_DEFAULT_82573; ++ else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) ++ *data = ID_LED_DEFAULT; ++out: ++ return ret_val; +} + -+static s32 e1000_get_invariants_80003es2lan(struct e1000_adapter *adapter) ++/** ++ * e1000_get_laa_state_82571 - Get locally administered address state ++ * @hw: pointer to the HW structure ++ * ++ * Retrieve and return the current locally administered address state. ++ **/ ++bool e1000_get_laa_state_82571(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ s32 rc; ++ struct e1000_dev_spec_82571 *dev_spec; ++ bool state = false; + -+ rc = e1000_init_mac_params_80003es2lan(adapter); -+ if (rc) -+ return rc; ++ DEBUGFUNC("e1000_get_laa_state_82571"); + -+ rc = e1000_init_nvm_params_80003es2lan(hw); -+ if (rc) -+ return rc; ++ if (hw->mac.type != e1000_82571) ++ goto out; + -+ rc = e1000_init_phy_params_80003es2lan(hw); -+ if (rc) -+ return rc; ++ dev_spec = (struct e1000_dev_spec_82571 *)hw->dev_spec; + -+ return 0; ++ state = dev_spec->laa_is_present; ++ ++out: ++ return state; +} + +/** -+ * e1000_acquire_phy_80003es2lan - Acquire rights to access PHY ++ * e1000_set_laa_state_82571 - Set locally administered address state + * @hw: pointer to the HW structure ++ * @state: enable/disable locally administered address + * -+ * A wrapper to acquire access rights to the correct PHY. This is a -+ * function pointer entry point called by the api module. ++ * Enable/Disable the current locally administered address state. + **/ -+static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) ++void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state) +{ -+ u16 mask; ++ struct e1000_dev_spec_82571 *dev_spec; + -+ mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; ++ DEBUGFUNC("e1000_set_laa_state_82571"); + -+ return e1000_acquire_swfw_sync_80003es2lan(hw, mask); -+} ++ if (hw->mac.type != e1000_82571) ++ goto out; + -+/** -+ * e1000_release_phy_80003es2lan - Release rights to access PHY -+ * @hw: pointer to the HW structure -+ * -+ * A wrapper to release access rights to the correct PHY. This is a -+ * function pointer entry point called by the api module. -+ **/ -+static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) -+{ -+ u16 mask; ++ dev_spec = (struct e1000_dev_spec_82571 *)hw->dev_spec; + -+ mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM; -+ e1000_release_swfw_sync_80003es2lan(hw, mask); ++ dev_spec->laa_is_present = state; ++ ++ /* If workaround is activated... */ ++ if (state) { ++ /* ++ * 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, the actual LAA is in one of the RARs and no ++ * incoming packets directed to this port are dropped. ++ * Eventually the LAA will be in RAR[0] and RAR[14]. ++ */ ++ e1000_rar_set_generic(hw, hw->mac.addr, ++ hw->mac.rar_entry_count - 1); ++ } ++ ++out: ++ return; +} + +/** -+ * e1000_acquire_nvm_80003es2lan - Acquire rights to access NVM ++ * e1000_fix_nvm_checksum_82571 - Fix EEPROM checksum + * @hw: pointer to the HW structure + * -+ * Acquire the semaphore to access the EEPROM. This is a function -+ * pointer entry point called by the api module. ++ * Verifies that the EEPROM has completed the update. After updating the ++ * EEPROM, we need to check bit 15 in work 0x23 for the checksum fix. If ++ * the checksum fix is not implemented, we need to set the bit and update ++ * the checksum. Otherwise, if bit 15 is set and the checksum is incorrect, ++ * we need to return bad checksum. + **/ -+static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) ++static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) +{ -+ s32 ret_val; ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; + -+ ret_val = e1000_acquire_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); -+ if (ret_val) -+ return ret_val; ++ DEBUGFUNC("e1000_fix_nvm_checksum_82571"); + -+ ret_val = e1000e_acquire_nvm(hw); ++ if (nvm->type != e1000_nvm_flash_hw) ++ goto out; + -+ if (ret_val) -+ e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); -+ -+ return ret_val; -+} -+ -+/** -+ * e1000_release_nvm_80003es2lan - Relinquish rights to access NVM -+ * @hw: pointer to the HW structure -+ * -+ * Release the semaphore used to access the EEPROM. This is a -+ * function pointer entry point called by the api module. -+ **/ -+static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) -+{ -+ e1000e_release_nvm(hw); -+ e1000_release_swfw_sync_80003es2lan(hw, E1000_SWFW_EEP_SM); -+} -+ -+/** -+ * e1000_acquire_swfw_sync_80003es2lan - Acquire SW/FW semaphore -+ * @hw: pointer to the HW structure -+ * @mask: specifies which semaphore to acquire -+ * -+ * Acquire the SW/FW semaphore to access the PHY or NVM. The mask -+ * will also specify which port we're acquiring the lock for. -+ **/ -+static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) -+{ -+ u32 swfw_sync; -+ u32 swmask = mask; -+ u32 fwmask = mask << 16; -+ s32 i = 0; -+ s32 timeout = 200; -+ -+ while (i < timeout) { -+ if (e1000e_get_hw_semaphore(hw)) -+ return -E1000_ERR_SWFW_SYNC; -+ -+ swfw_sync = er32(SW_FW_SYNC); -+ if (!(swfw_sync & (fwmask | swmask))) -+ break; ++ /* ++ * Check bit 4 of word 10h. If it is 0, firmware is done updating ++ * 10h-12h. Checksum may need to be fixed. ++ */ ++ ret_val = nvm->ops.read(hw, 0x10, 1, &data); ++ if (ret_val) ++ goto out; + -+ /* Firmware currently using resource (fwmask) -+ * or other software thread using resource (swmask) */ -+ e1000e_put_hw_semaphore(hw); -+ mdelay(5); -+ i++; -+ } ++ if (!(data & 0x10)) { ++ /* ++ * 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. ++ */ ++ ret_val = nvm->ops.read(hw, 0x23, 1, &data); ++ if (ret_val) ++ goto out; + -+ if (i == timeout) { -+ hw_dbg(hw, -+ "Driver can't access resource, SW_FW_SYNC timeout.\n"); -+ return -E1000_ERR_SWFW_SYNC; ++ if (!(data & 0x8000)) { ++ data |= 0x8000; ++ ret_val = nvm->ops.write(hw, 0x23, 1, &data); ++ if (ret_val) ++ goto out; ++ ret_val = nvm->ops.update(hw); ++ } + } + -+ swfw_sync |= swmask; -+ ew32(SW_FW_SYNC, swfw_sync); -+ -+ e1000e_put_hw_semaphore(hw); -+ -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_release_swfw_sync_80003es2lan - Release SW/FW semaphore ++ * e1000_read_mac_addr_82571 - Read device MAC address + * @hw: pointer to the HW structure -+ * @mask: specifies which semaphore to acquire -+ * -+ * Release the SW/FW semaphore used to access the PHY or NVM. The mask -+ * will also specify which port we're releasing the lock for. + **/ -+static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) ++static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) +{ -+ u32 swfw_sync; -+ -+ while (e1000e_get_hw_semaphore(hw) != 0); -+ /* Empty */ ++ s32 ret_val = E1000_SUCCESS; + -+ swfw_sync = er32(SW_FW_SYNC); -+ swfw_sync &= ~mask; -+ ew32(SW_FW_SYNC, swfw_sync); ++ DEBUGFUNC("e1000_read_mac_addr_82571"); ++ if (e1000_check_alt_mac_addr_generic(hw)) ++ ret_val = e1000_read_mac_addr_generic(hw); + -+ e1000e_put_hw_semaphore(hw); ++ return ret_val; +} + +/** -+ * e1000_read_phy_reg_gg82563_80003es2lan - Read GG82563 PHY register -+ * @hw: pointer to the HW structure -+ * @offset: offset of the register to read -+ * @data: pointer to the data returned from the operation ++ * e1000_power_down_phy_copper_82571 - Remove link during PHY power down ++ * @hw: pointer to the HW structure + * -+ * Read the GG82563 PHY register. This is a function pointer entry -+ * point called by the api module. ++ * In the case of a PHY power down to save power, or to turn off link during a ++ * driver unload, or wake on lan is not enabled, remove the link. + **/ -+static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, -+ u32 offset, u16 *data) ++static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) +{ -+ s32 ret_val; -+ u32 page_select; -+ u16 temp; -+ -+ /* Select Configuration Page */ -+ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) -+ page_select = GG82563_PHY_PAGE_SELECT; -+ else -+ /* Use Alternative Page Select register to access -+ * registers 30 and 31 -+ */ -+ page_select = GG82563_PHY_PAGE_SELECT_ALT; -+ -+ temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); -+ ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); -+ if (ret_val) -+ return ret_val; -+ -+ /* The "ready" bit in the MDIC register may be incorrectly set -+ * before the device has completed the "Page Select" MDI -+ * transaction. So we wait 200us after each MDI command... -+ */ -+ udelay(200); -+ -+ /* ...and verify the command was successful. */ -+ ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); -+ -+ if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { -+ ret_val = -E1000_ERR_PHY; -+ return ret_val; -+ } -+ -+ udelay(200); ++ struct e1000_phy_info *phy = &hw->phy; ++ struct e1000_mac_info *mac = &hw->mac; + -+ ret_val = e1000e_read_phy_reg_m88(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++ if (!(phy->ops.check_reset_block)) ++ return; + -+ udelay(200); ++ /* If the management interface is not enabled, then power down */ ++ if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) ++ e1000_power_down_phy_copper(hw); + -+ return ret_val; ++ return; +} + +/** -+ * e1000_write_phy_reg_gg82563_80003es2lan - Write GG82563 PHY register ++ * e1000_clear_hw_cntrs_82571 - Clear device specific hardware counters + * @hw: pointer to the HW structure -+ * @offset: offset of the register to read -+ * @data: value to write to the register + * -+ * Write to the GG82563 PHY register. This is a function pointer entry -+ * point called by the api module. ++ * Clears the hardware counters by reading the counter registers. + **/ -+static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, -+ u32 offset, u16 data) ++static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) +{ -+ s32 ret_val; -+ u32 page_select; -+ u16 temp; ++ volatile u32 temp; ++ ++ DEBUGFUNC("e1000_clear_hw_cntrs_82571"); ++ ++ e1000_clear_hw_cntrs_base_generic(hw); ++ temp = E1000_READ_REG(hw, E1000_PRC64); ++ temp = E1000_READ_REG(hw, E1000_PRC127); ++ temp = E1000_READ_REG(hw, E1000_PRC255); ++ temp = E1000_READ_REG(hw, E1000_PRC511); ++ temp = E1000_READ_REG(hw, E1000_PRC1023); ++ temp = E1000_READ_REG(hw, E1000_PRC1522); ++ temp = E1000_READ_REG(hw, E1000_PTC64); ++ temp = E1000_READ_REG(hw, E1000_PTC127); ++ temp = E1000_READ_REG(hw, E1000_PTC255); ++ temp = E1000_READ_REG(hw, E1000_PTC511); ++ temp = E1000_READ_REG(hw, E1000_PTC1023); ++ temp = E1000_READ_REG(hw, E1000_PTC1522); ++ ++ temp = E1000_READ_REG(hw, E1000_ALGNERRC); ++ temp = E1000_READ_REG(hw, E1000_RXERRC); ++ temp = E1000_READ_REG(hw, E1000_TNCRS); ++ temp = E1000_READ_REG(hw, E1000_CEXTERR); ++ temp = E1000_READ_REG(hw, E1000_TSCTC); ++ temp = E1000_READ_REG(hw, E1000_TSCTFC); ++ ++ temp = E1000_READ_REG(hw, E1000_MGTPRC); ++ temp = E1000_READ_REG(hw, E1000_MGTPDC); ++ temp = E1000_READ_REG(hw, E1000_MGTPTC); ++ ++ temp = E1000_READ_REG(hw, E1000_IAC); ++ temp = E1000_READ_REG(hw, E1000_ICRXOC); ++ ++ temp = E1000_READ_REG(hw, E1000_ICRXPTC); ++ temp = E1000_READ_REG(hw, E1000_ICRXATC); ++ temp = E1000_READ_REG(hw, E1000_ICTXPTC); ++ temp = E1000_READ_REG(hw, E1000_ICTXATC); ++ temp = E1000_READ_REG(hw, E1000_ICTXQEC); ++ temp = E1000_READ_REG(hw, E1000_ICTXQMTC); ++ temp = E1000_READ_REG(hw, E1000_ICRXDMTC); ++} +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_82571.h linux-2.6.22-10/drivers/net/e1000e/e1000_82571.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_82571.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_82571.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,53 @@ ++/******************************************************************************* + -+ /* Select Configuration Page */ -+ if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) -+ page_select = GG82563_PHY_PAGE_SELECT; -+ else -+ /* Use Alternative Page Select register to access -+ * registers 30 and 31 -+ */ -+ page_select = GG82563_PHY_PAGE_SELECT_ALT; ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT); -+ ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp); -+ if (ret_val) -+ return ret_val; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + ++ This program is distributed in the hope 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. + -+ /* The "ready" bit in the MDIC register may be incorrectly set -+ * before the device has completed the "Page Select" MDI -+ * transaction. So we wait 200us after each MDI command... -+ */ -+ udelay(200); ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ /* ...and verify the command was successful. */ -+ ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp); ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) -+ return -E1000_ERR_PHY; ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ udelay(200); ++*******************************************************************************/ + -+ ret_val = e1000e_write_phy_reg_m88(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++#ifndef _E1000_82571_H_ ++#define _E1000_82571_H_ + -+ udelay(200); ++#define ID_LED_RESERVED_F746 0xF746 ++#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \ ++ (ID_LED_OFF1_ON2 << 8) | \ ++ (ID_LED_DEF1_DEF2 << 4) | \ ++ (ID_LED_DEF1_DEF2)) + -+ return ret_val; -+} ++#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 + -+/** -+ * e1000_write_nvm_80003es2lan - Write to ESB2 NVM -+ * @hw: pointer to the HW structure -+ * @offset: offset of the register to read -+ * @words: number of words to write -+ * @data: buffer of data to write to the NVM -+ * -+ * Write "words" of data to the ESB2 NVM. This is a function -+ * pointer entry point called by the api module. -+ **/ -+static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, -+ u16 words, u16 *data) -+{ -+ return e1000e_write_nvm_spi(hw, offset, words, data); -+} ++/* Intr Throttling - RW */ ++#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n))) + -+/** -+ * e1000_get_cfg_done_80003es2lan - Wait for configuration to complete -+ * @hw: pointer to the HW structure -+ * -+ * Wait a specific amount of time for manageability processes to complete. -+ * This is a function pointer entry point called by the phy module. -+ **/ -+static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) -+{ -+ s32 timeout = PHY_CFG_TIMEOUT; -+ u32 mask = E1000_NVM_CFG_DONE_PORT_0; ++#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */ ++#define E1000_EIAC_MASK_82574 0x01F00000 + -+ if (hw->bus.func == 1) -+ mask = E1000_NVM_CFG_DONE_PORT_1; ++#define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */ + -+ while (timeout) { -+ if (er32(EEMNGCTL) & mask) -+ break; -+ msleep(1); -+ timeout--; -+ } -+ if (!timeout) { -+ hw_dbg(hw, "MNG configuration cycle has not completed.\n"); -+ return -E1000_ERR_RESET; -+ } ++#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */ + -+ return 0; -+} ++bool e1000_get_laa_state_82571(struct e1000_hw *hw); ++void e1000_set_laa_state_82571(struct e1000_hw *hw, bool state); + -+/** -+ * e1000_phy_force_speed_duplex_80003es2lan - Force PHY speed and duplex -+ * @hw: pointer to the HW structure -+ * -+ * Force the speed and duplex settings onto the PHY. This is a -+ * function pointer entry point called by the phy module. -+ **/ -+static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) -+{ -+ s32 ret_val; -+ u16 phy_data; -+ bool link; ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_defines.h linux-2.6.22-10/drivers/net/e1000e/e1000_defines.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_defines.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_defines.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1437 @@ ++/******************************************************************************* + -+ /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI -+ * forced whenever speed and duplex are forced. -+ */ -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; -+ ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ hw_dbg(hw, "GG82563 PSCR: %X\n", phy_data); ++ This program is distributed in the hope 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. + -+ ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ e1000e_phy_force_speed_duplex_setup(hw, &phy_data); ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ /* Reset the phy to commit changes. */ -+ phy_data |= MII_CR_RESET; ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data); -+ if (ret_val) -+ return ret_val; ++*******************************************************************************/ + -+ udelay(1); ++#ifndef _E1000_DEFINES_H_ ++#define _E1000_DEFINES_H_ + -+ if (hw->phy.wait_for_link) { -+ hw_dbg(hw, "Waiting for forced speed/duplex link " -+ "on GG82563 phy.\n"); ++/* Number of Transmit and Receive Descriptors must be a multiple of 8 */ ++#define REQ_TX_DESCRIPTOR_MULTIPLE 8 ++#define REQ_RX_DESCRIPTOR_MULTIPLE 8 + -+ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, -+ 100000, &link); -+ if (ret_val) -+ return ret_val; ++/* Definitions for power management and wakeup registers */ ++/* Wake Up Control */ ++#define E1000_WUC_APME 0x00000001 /* APM Enable */ ++#define E1000_WUC_PME_EN 0x00000002 /* PME Enable */ ++#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */ ++#define E1000_WUC_APMPME 0x00000008 /* Assert PME on APM Wakeup */ ++#define E1000_WUC_LSCWE 0x00000010 /* Link Status wake up enable */ ++#define E1000_WUC_LSCWO 0x00000020 /* Link Status wake up override */ ++#define E1000_WUC_SPM 0x80000000 /* Enable SPM */ ++#define E1000_WUC_PHY_WAKE 0x00000100 /* if PHY supports wakeup */ + -+ if (!link) { -+ /* We didn't get link. -+ * Reset the DSP and cross our fingers. -+ */ -+ ret_val = e1000e_phy_reset_dsp(hw); -+ if (ret_val) -+ return ret_val; -+ } ++/* Wake Up Filter Control */ ++#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ ++#define E1000_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ ++#define E1000_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ ++#define E1000_WUFC_MC 0x00000008 /* Directed Multicast Wakeup Enable */ ++#define E1000_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ ++#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_BM 0x00000800 /* Ignore WakeOn TCO packets */ ++#define E1000_WUFC_FLX0_BM 0x00001000 /* Flexible Filter 0 Enable */ ++#define E1000_WUFC_FLX1_BM 0x00002000 /* Flexible Filter 1 Enable */ ++#define E1000_WUFC_FLX2_BM 0x00004000 /* Flexible Filter 2 Enable */ ++#define E1000_WUFC_FLX3_BM 0x00008000 /* Flexible Filter 3 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 */ ++#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ ++#define E1000_WUFC_ALL_FILTERS_BM 0x0000F0FF /* Mask for all wakeup filters */ ++#define E1000_WUFC_FLX_OFFSET_BM 12 /* Offset to the Flexible Filters bits */ ++#define E1000_WUFC_FLX_FILTERS_BM 0x0000F000 /* Mask for the 4 flexible filters */ ++#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */ ++#define E1000_WUFC_FLX_OFFSET 16 /* Offset to the Flexible Filters bits */ ++#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */ ++ ++/* Wake Up Status */ ++#define E1000_WUS_LNKC E1000_WUFC_LNKC ++#define E1000_WUS_MAG E1000_WUFC_MAG ++#define E1000_WUS_EX E1000_WUFC_EX ++#define E1000_WUS_MC E1000_WUFC_MC ++#define E1000_WUS_BC E1000_WUFC_BC ++#define E1000_WUS_ARP E1000_WUFC_ARP ++#define E1000_WUS_IPV4 E1000_WUFC_IPV4 ++#define E1000_WUS_IPV6 E1000_WUFC_IPV6 ++#define E1000_WUS_FLX0_BM E1000_WUFC_FLX0_BM ++#define E1000_WUS_FLX1_BM E1000_WUFC_FLX1_BM ++#define E1000_WUS_FLX2_BM E1000_WUFC_FLX2_BM ++#define E1000_WUS_FLX3_BM E1000_WUFC_FLX3_BM ++#define E1000_WUS_FLX_FILTERS_BM E1000_WUFC_FLX_FILTERS_BM ++#define E1000_WUS_FLX0 E1000_WUFC_FLX0 ++#define E1000_WUS_FLX1 E1000_WUFC_FLX1 ++#define E1000_WUS_FLX2 E1000_WUFC_FLX2 ++#define E1000_WUS_FLX3 E1000_WUFC_FLX3 ++#define E1000_WUS_FLX_FILTERS E1000_WUFC_FLX_FILTERS ++ ++/* Wake Up Packet Length */ ++#define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ ++ ++/* Four Flexible Filters are supported */ ++#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4 ++ ++/* Each Flexible Filter is at most 128 (0x80) bytes in length */ ++#define E1000_FLEXIBLE_FILTER_SIZE_MAX 128 ++ ++#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX ++#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX ++#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX + -+ /* Try once more */ -+ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, -+ 100000, &link); -+ if (ret_val) -+ return ret_val; -+ } -+ -+ ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++/* Extended Device Control */ ++#define E1000_CTRL_EXT_GPI0_EN 0x00000001 /* Maps SDP4 to GPI0 */ ++#define E1000_CTRL_EXT_GPI1_EN 0x00000002 /* Maps SDP5 to GPI1 */ ++#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN ++#define E1000_CTRL_EXT_GPI2_EN 0x00000004 /* Maps SDP6 to GPI2 */ ++#define E1000_CTRL_EXT_GPI3_EN 0x00000008 /* Maps SDP7 to GPI3 */ ++/* Reserved (bits 4,5) in >= 82575 */ ++#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Definable Pin 4 */ ++#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Definable Pin 5 */ ++#define E1000_CTRL_EXT_PHY_INT E1000_CTRL_EXT_SDP5_DATA ++#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Definable Pin 6 */ ++#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */ ++/* SDP 4/5 (bits 8,9) are reserved in >= 82575 */ ++#define E1000_CTRL_EXT_SDP4_DIR 0x00000100 /* Direction of SDP4 0=in 1=out */ ++#define E1000_CTRL_EXT_SDP5_DIR 0x00000200 /* Direction of SDP5 0=in 1=out */ ++#define E1000_CTRL_EXT_SDP6_DIR 0x00000400 /* Direction of SDP6 0=in 1=out */ ++#define E1000_CTRL_EXT_SDP7_DIR 0x00000800 /* Direction of SDP7 0=in 1=out */ ++#define E1000_CTRL_EXT_ASDCHK 0x00001000 /* Initiate an ASD sequence */ ++#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_PCIE_SERDES 0x00C00000 ++#define E1000_CTRL_EXT_LINK_MODE_PCIX_SERDES 0x00800000 ++#define E1000_CTRL_EXT_LINK_MODE_SGMII 0x00800000 ++#define E1000_CTRL_EXT_EIAME 0x01000000 ++#define E1000_CTRL_EXT_IRCA 0x00000001 ++#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_CANC 0x04000000 /* Interrupt delay cancellation */ ++#define E1000_CTRL_EXT_DRV_LOAD 0x10000000 /* Driver loaded bit for FW */ ++/* IAME enable bit (27) was removed in >= 82575 */ ++#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 ++#define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ ++#define E1000_CTRL_EXT_LSECCK 0x00001000 ++#define E1000_I2CCMD_REG_ADDR_SHIFT 16 ++#define E1000_I2CCMD_REG_ADDR 0x00FF0000 ++#define E1000_I2CCMD_PHY_ADDR_SHIFT 24 ++#define E1000_I2CCMD_PHY_ADDR 0x07000000 ++#define E1000_I2CCMD_OPCODE_READ 0x08000000 ++#define E1000_I2CCMD_OPCODE_WRITE 0x00000000 ++#define E1000_I2CCMD_RESET 0x10000000 ++#define E1000_I2CCMD_READY 0x20000000 ++#define E1000_I2CCMD_INTERRUPT_ENA 0x40000000 ++#define E1000_I2CCMD_ERROR 0x80000000 ++#define E1000_MAX_SGMII_PHY_REG_ADDR 255 ++#define E1000_I2CCMD_PHY_TIMEOUT 200 ++ ++/* Receive Descriptor 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 calculated */ ++#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_CRCV 0x100 /* Speculative CRC Valid */ ++#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ ++#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ ++#define E1000_RXD_STAT_DYNINT 0x800 /* Pkt caused INT via DYNINT */ ++#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 */ ++#define E1000_RXD_ERR_CXE 0x10 /* Carrier Extension Error */ ++#define E1000_RXD_ERR_TCPE 0x20 /* TCP/UDP Checksum Error */ ++#define E1000_RXD_ERR_IPE 0x40 /* IP Checksum Error */ ++#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 13 ++#define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ ++#define E1000_RXD_SPC_CFI_SHIFT 12 + -+ /* Resetting the phy means we need to verify the TX_CLK corresponds -+ * to the link speed. 10Mbps -> 2.5MHz, else 25MHz. -+ */ -+ phy_data &= ~GG82563_MSCR_TX_CLK_MASK; -+ if (hw->mac.forced_speed_duplex & E1000_ALL_10_SPEED) -+ phy_data |= GG82563_MSCR_TX_CLK_10MBPS_2_5; -+ else -+ phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25; ++#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 + -+ /* In addition, we must re-enable CRS on Tx for both half and full -+ * duplex. -+ */ -+ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; -+ ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); ++#define E1000_RXDEXT_LSECH 0x01000000 ++#define E1000_RXDEXT_LSECE_MASK 0x60000000 ++#define E1000_RXDEXT_LSECE_NO_ERROR 0x00000000 ++#define E1000_RXDEXT_LSECE_NO_SA_MATCH 0x20000000 ++#define E1000_RXDEXT_LSECE_REPLAY_DETECT 0x40000000 ++#define E1000_RXDEXT_LSECE_BAD_SIG 0x60000000 + -+ return ret_val; -+} ++/* mask to determine if packets should be dropped due to frame errors */ ++#define E1000_RXD_ERR_FRAME_ERR_MASK ( \ ++ E1000_RXD_ERR_CE | \ ++ E1000_RXD_ERR_SE | \ ++ E1000_RXD_ERR_SEQ | \ ++ E1000_RXD_ERR_CXE | \ ++ E1000_RXD_ERR_RXE) + -+/** -+ * e1000_get_cable_length_80003es2lan - Set approximate cable length -+ * @hw: pointer to the HW structure -+ * -+ * Find the approximate cable length as measured by the GG82563 PHY. -+ * This is a function pointer entry point called by the phy module. -+ **/ -+static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data; -+ u16 index; ++/* 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) + -+ ret_val = e1e_rphy(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); -+ if (ret_val) -+ return ret_val; ++#define E1000_MRQC_ENABLE_MASK 0x00000007 ++#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 + -+ index = phy_data & GG82563_DSPD_CABLE_LENGTH; -+ phy->min_cable_length = e1000_gg82563_cable_length_table[index]; -+ phy->max_cable_length = e1000_gg82563_cable_length_table[index+5]; ++#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 ++#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF + -+ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; ++/* Management Control */ ++#define E1000_MANC_SMBUS_EN 0x00000001 /* SMBus Enabled - RO */ ++#define E1000_MANC_ASF_EN 0x00000002 /* ASF Enabled - RO */ ++#define E1000_MANC_R_ON_FORCE 0x00000004 /* Reset on Force TCO - RO */ ++#define E1000_MANC_RMCP_EN 0x00000100 /* Enable RCMP 026Fh Filtering */ ++#define E1000_MANC_0298_EN 0x00000200 /* Enable RCMP 0298h Filtering */ ++#define E1000_MANC_IPV4_EN 0x00000400 /* Enable IPv4 */ ++#define E1000_MANC_IPV6_EN 0x00000800 /* Enable IPv6 */ ++#define E1000_MANC_SNAP_EN 0x00001000 /* Accept LLC/SNAP */ ++#define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ ++/* Enable Neighbor Discovery Filtering */ ++#define E1000_MANC_NEIGHBOR_EN 0x00004000 ++#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 */ ++/* Enable MAC address filtering */ ++#define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 ++/* Enable MNG packets to host memory */ ++#define E1000_MANC_EN_MNG2HOST 0x00200000 ++/* Enable IP address filtering */ ++#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 ++#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 */ ++#define E1000_MANC_SMB_DATA_IN 0x08000000 /* SMBus Data In */ ++#define E1000_MANC_SMB_DATA_OUT 0x10000000 /* SMBus Data Out */ ++#define E1000_MANC_SMB_CLK_OUT 0x20000000 /* SMBus Clock Out */ ++ ++#define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ ++#define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ + -+ return 0; -+} ++/* Receive Control */ ++#define E1000_RCTL_RST 0x00000001 /* Software reset */ ++#define E1000_RCTL_EN 0x00000002 /* enable */ ++#define E1000_RCTL_SBP 0x00000004 /* store bad packet */ ++#define E1000_RCTL_UPE 0x00000008 /* unicast promiscuous enable */ ++#define E1000_RCTL_MPE 0x00000010 /* multicast promiscuous enab */ ++#define E1000_RCTL_LPE 0x00000020 /* long packet enable */ ++#define E1000_RCTL_LBM_NO 0x00000000 /* no loopback mode */ ++#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 */ ++#define E1000_RCTL_MO_SHIFT 12 /* multicast offset shift */ ++#define E1000_RCTL_MO_0 0x00000000 /* multicast offset 11:0 */ ++#define E1000_RCTL_MO_1 0x00001000 /* multicast offset 12:1 */ ++#define E1000_RCTL_MO_2 0x00002000 /* multicast offset 13:2 */ ++#define E1000_RCTL_MO_3 0x00003000 /* multicast offset 15:4 */ ++#define E1000_RCTL_MDR 0x00004000 /* multicast desc ring 0 */ ++#define E1000_RCTL_BAM 0x00008000 /* broadcast enable */ ++/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */ ++#define E1000_RCTL_SZ_2048 0x00000000 /* rx buffer size 2048 */ ++#define E1000_RCTL_SZ_1024 0x00010000 /* rx buffer size 1024 */ ++#define E1000_RCTL_SZ_512 0x00020000 /* rx buffer size 512 */ ++#define E1000_RCTL_SZ_256 0x00030000 /* rx buffer size 256 */ ++/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */ ++#define E1000_RCTL_SZ_16384 0x00010000 /* rx buffer size 16384 */ ++#define E1000_RCTL_SZ_8192 0x00020000 /* rx buffer size 8192 */ ++#define E1000_RCTL_SZ_4096 0x00030000 /* rx buffer size 4096 */ ++#define E1000_RCTL_VFE 0x00040000 /* vlan filter enable */ ++#define E1000_RCTL_CFIEN 0x00080000 /* canonical form enable */ ++#define E1000_RCTL_CFI 0x00100000 /* canonical form indicator */ ++#define E1000_RCTL_DPF 0x00400000 /* discard pause frames */ ++#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 */ + -+/** -+ * e1000_get_link_up_info_80003es2lan - Report speed and duplex -+ * @hw: pointer to the HW structure -+ * @speed: pointer to speed buffer -+ * @duplex: pointer to duplex buffer -+ * -+ * Retrieve the current speed and duplex configuration. -+ * This is a function pointer entry point called by the api module. -+ **/ -+static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, -+ u16 *duplex) -+{ -+ s32 ret_val; ++/* ++ * 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 ++ */ + -+ if (hw->media_type == e1000_media_type_copper) { -+ ret_val = e1000e_get_speed_and_duplex_copper(hw, -+ speed, -+ duplex); -+ if (ret_val) -+ return ret_val; -+ if (*speed == SPEED_1000) -+ ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw); -+ else -+ ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, -+ *duplex); -+ } else { -+ ret_val = e1000e_get_speed_and_duplex_fiber_serdes(hw, -+ speed, -+ duplex); -+ } ++#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F ++#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 ++#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 ++#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 + -+ return ret_val; -+} ++#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 */ + -+/** -+ * e1000_reset_hw_80003es2lan - Reset the ESB2 controller -+ * @hw: pointer to the HW structure -+ * -+ * Perform a global reset to the ESB2 controller. -+ * This is a function pointer entry point called by the api module. -+ **/ -+static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) -+{ -+ u32 ctrl; -+ u32 icr; -+ s32 ret_val; ++/* SWFW_SYNC Definitions */ ++#define E1000_SWFW_EEP_SM 0x1 ++#define E1000_SWFW_PHY0_SM 0x2 ++#define E1000_SWFW_PHY1_SM 0x4 ++#define E1000_SWFW_CSR_SM 0x8 + -+ /* Prevent the PCI-E bus from sticking if there is no TLP connection -+ * on the last TLP read/write transaction when MAC is reset. -+ */ -+ ret_val = e1000e_disable_pcie_master(hw); -+ if (ret_val) -+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); ++/* FACTPS Definitions */ ++#define E1000_FACTPS_LFS 0x40000000 /* LAN Function Select */ ++/* 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 */ ++#define E1000_CTRL_ASDE 0x00000020 /* Auto-speed detect enable */ ++#define E1000_CTRL_SLU 0x00000040 /* Set link up (Force Link) */ ++#define E1000_CTRL_ILOS 0x00000080 /* Invert Loss-Of Signal */ ++#define E1000_CTRL_SPD_SEL 0x00000300 /* Speed Select Mask */ ++#define E1000_CTRL_SPD_10 0x00000000 /* Force 10Mb */ ++#define E1000_CTRL_SPD_100 0x00000100 /* Force 100Mb */ ++#define E1000_CTRL_SPD_1000 0x00000200 /* Force 1Gb */ ++#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 */ ++#define E1000_CTRL_SWDPIN3 0x00200000 /* SWDPIN 3 value */ ++#define E1000_CTRL_SWDPIO0 0x00400000 /* SWDPIN 0 Input or output */ ++#define E1000_CTRL_SWDPIO1 0x00800000 /* SWDPIN 1 input or output */ ++#define E1000_CTRL_SWDPIO2 0x01000000 /* SWDPIN 2 input or output */ ++#define E1000_CTRL_SWDPIO3 0x02000000 /* SWDPIN 3 input or output */ ++#define E1000_CTRL_RST 0x04000000 /* Global reset */ ++#define E1000_CTRL_RFCE 0x08000000 /* Receive Flow Control enable */ ++#define E1000_CTRL_TFCE 0x10000000 /* Transmit flow control enable */ ++#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 */ ++#define E1000_CTRL_I2C_ENA 0x02000000 /* I2C enable */ + -+ hw_dbg(hw, "Masking off all interrupts\n"); -+ ew32(IMC, 0xffffffff); ++/* Bit definitions for the Management Data IO (MDIO) and Management Data ++ * Clock (MDC) pins in the Device Control Register. ++ */ ++#define E1000_CTRL_PHY_RESET_DIR E1000_CTRL_SWDPIO0 ++#define E1000_CTRL_PHY_RESET E1000_CTRL_SWDPIN0 ++#define E1000_CTRL_MDIO_DIR E1000_CTRL_SWDPIO2 ++#define E1000_CTRL_MDIO E1000_CTRL_SWDPIN2 ++#define E1000_CTRL_MDC_DIR E1000_CTRL_SWDPIO3 ++#define E1000_CTRL_MDC E1000_CTRL_SWDPIN3 ++#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR ++#define E1000_CTRL_PHY_RESET4 E1000_CTRL_EXT_SDP4_DATA ++ ++#define E1000_CONNSW_ENRGSRC 0x4 ++#define E1000_PCS_CFG_PCS_EN 8 ++#define E1000_PCS_LCTL_FLV_LINK_UP 1 ++#define E1000_PCS_LCTL_FSV_10 0 ++#define E1000_PCS_LCTL_FSV_100 2 ++#define E1000_PCS_LCTL_FSV_1000 4 ++#define E1000_PCS_LCTL_FDV_FULL 8 ++#define E1000_PCS_LCTL_FSD 0x10 ++#define E1000_PCS_LCTL_FORCE_LINK 0x20 ++#define E1000_PCS_LCTL_LOW_LINK_LATCH 0x40 ++#define E1000_PCS_LCTL_FORCE_FCTRL 0x80 ++#define E1000_PCS_LCTL_AN_ENABLE 0x10000 ++#define E1000_PCS_LCTL_AN_RESTART 0x20000 ++#define E1000_PCS_LCTL_AN_TIMEOUT 0x40000 ++#define E1000_PCS_LCTL_AN_SGMII_BYPASS 0x80000 ++#define E1000_PCS_LCTL_AN_SGMII_TRIGGER 0x100000 ++#define E1000_PCS_LCTL_FAST_LINK_TIMER 0x1000000 ++#define E1000_PCS_LCTL_LINK_OK_FIX 0x2000000 ++#define E1000_PCS_LCTL_CRS_ON_NI 0x4000000 ++#define E1000_ENABLE_SERDES_LOOPBACK 0x0410 ++ ++#define E1000_PCS_LSTS_LINK_OK 1 ++#define E1000_PCS_LSTS_SPEED_10 0 ++#define E1000_PCS_LSTS_SPEED_100 2 ++#define E1000_PCS_LSTS_SPEED_1000 4 ++#define E1000_PCS_LSTS_DUPLEX_FULL 8 ++#define E1000_PCS_LSTS_SYNK_OK 0x10 ++#define E1000_PCS_LSTS_AN_COMPLETE 0x10000 ++#define E1000_PCS_LSTS_AN_PAGE_RX 0x20000 ++#define E1000_PCS_LSTS_AN_TIMED_OUT 0x40000 ++#define E1000_PCS_LSTS_AN_REMOTE_FAULT 0x80000 ++#define E1000_PCS_LSTS_AN_ERROR_RWS 0x100000 + -+ ew32(RCTL, 0); -+ ew32(TCTL, E1000_TCTL_PSP); -+ e1e_flush(); ++/* 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 */ ++#define E1000_STATUS_TBIMODE 0x00000020 /* TBI mode */ ++#define E1000_STATUS_SPEED_MASK 0x000000C0 ++#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 NVM */ ++#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 interpret the masked PCI-X bus speed. */ ++#define E1000_STATUS_PCIX_SPEED_66 0x00000000 /* PCI-X bus speed 50-66 MHz */ ++#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed 66-100 MHz */ ++#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz */ ++ ++#define SPEED_10 10 ++#define SPEED_100 100 ++#define SPEED_1000 1000 ++#define HALF_DUPLEX 1 ++#define FULL_DUPLEX 2 + -+ msleep(10); ++#define PHY_FORCE_TIME 20 + -+ ctrl = er32(CTRL); ++#define ADVERTISE_10_HALF 0x0001 ++#define ADVERTISE_10_FULL 0x0002 ++#define ADVERTISE_100_HALF 0x0004 ++#define ADVERTISE_100_FULL 0x0008 ++#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ ++#define ADVERTISE_1000_FULL 0x0020 + -+ hw_dbg(hw, "Issuing a global reset to MAC\n"); -+ ew32(CTRL, ctrl | E1000_CTRL_RST); ++/* 1000/H is not supported, nor spec-compliant. */ ++#define E1000_ALL_SPEED_DUPLEX ( ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ ++ ADVERTISE_100_HALF | ADVERTISE_100_FULL | \ ++ ADVERTISE_1000_FULL) ++#define E1000_ALL_NOT_GIG ( ADVERTISE_10_HALF | ADVERTISE_10_FULL | \ ++ ADVERTISE_100_HALF | ADVERTISE_100_FULL) ++#define E1000_ALL_100_SPEED (ADVERTISE_100_HALF | ADVERTISE_100_FULL) ++#define E1000_ALL_10_SPEED (ADVERTISE_10_HALF | ADVERTISE_10_FULL) ++#define E1000_ALL_FULL_DUPLEX (ADVERTISE_10_FULL | ADVERTISE_100_FULL | \ ++ ADVERTISE_1000_FULL) ++#define E1000_ALL_HALF_DUPLEX (ADVERTISE_10_HALF | ADVERTISE_100_HALF) + -+ ret_val = e1000e_get_auto_rd_done(hw); -+ if (ret_val) -+ /* We don't want to continue accessing MAC registers. */ -+ return ret_val; ++#define AUTONEG_ADVERTISE_SPEED_DEFAULT E1000_ALL_SPEED_DUPLEX + -+ /* Clear any pending interrupt events. */ -+ ew32(IMC, 0xffffffff); -+ icr = er32(ICR); ++/* LED Control */ ++#define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F ++#define E1000_LEDCTL_LED0_MODE_SHIFT 0 ++#define E1000_LEDCTL_LED0_BLINK_RATE 0x00000020 ++#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 0x00002000 ++#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 ++ ++#define E1000_LEDCTL_MODE_LINK_10_1000 0x0 ++#define E1000_LEDCTL_MODE_LINK_100_1000 0x1 ++#define E1000_LEDCTL_MODE_LINK_UP 0x2 ++#define E1000_LEDCTL_MODE_ACTIVITY 0x3 ++#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4 ++#define E1000_LEDCTL_MODE_LINK_10 0x5 ++#define E1000_LEDCTL_MODE_LINK_100 0x6 ++#define E1000_LEDCTL_MODE_LINK_1000 0x7 ++#define E1000_LEDCTL_MODE_PCIX_MODE 0x8 ++#define E1000_LEDCTL_MODE_FULL_DUPLEX 0x9 ++#define E1000_LEDCTL_MODE_COLLISION 0xA ++#define E1000_LEDCTL_MODE_BUS_SPEED 0xB ++#define E1000_LEDCTL_MODE_BUS_SIZE 0xC ++#define E1000_LEDCTL_MODE_PAUSED 0xD ++#define E1000_LEDCTL_MODE_LED_ON 0xE ++#define E1000_LEDCTL_MODE_LED_OFF 0xF + -+ return 0; -+} ++/* Transmit Descriptor bit definitions */ ++#define E1000_TXD_DTYP_D 0x00100000 /* Data Descriptor */ ++#define E1000_TXD_DTYP_C 0x00000000 /* Context Descriptor */ ++#define E1000_TXD_POPTS_SHIFT 8 /* POPTS shift */ ++#define E1000_TXD_POPTS_IXSM 0x01 /* Insert IP checksum */ ++#define E1000_TXD_POPTS_TXSM 0x02 /* Insert TCP/UDP checksum */ ++#define E1000_TXD_CMD_EOP 0x01000000 /* End of Packet */ ++#define E1000_TXD_CMD_IFCS 0x02000000 /* Insert FCS (Ethernet CRC) */ ++#define E1000_TXD_CMD_IC 0x04000000 /* Insert Checksum */ ++#define E1000_TXD_CMD_RS 0x08000000 /* Report Status */ ++#define E1000_TXD_CMD_RPS 0x10000000 /* Report Packet Sent */ ++#define E1000_TXD_CMD_DEXT 0x20000000 /* Descriptor extension (0 = legacy) */ ++#define E1000_TXD_CMD_VLE 0x40000000 /* Add VLAN tag */ ++#define E1000_TXD_CMD_IDE 0x80000000 /* Enable Tidv register */ ++#define E1000_TXD_STAT_DD 0x00000001 /* Descriptor Done */ ++#define E1000_TXD_STAT_EC 0x00000002 /* Excess Collisions */ ++#define E1000_TXD_STAT_LC 0x00000004 /* Late Collisions */ ++#define E1000_TXD_STAT_TU 0x00000008 /* Transmit underrun */ ++#define E1000_TXD_CMD_TCP 0x01000000 /* TCP packet */ ++#define E1000_TXD_CMD_IP 0x02000000 /* IP packet */ ++#define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ ++#define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ ++/* Extended desc bits for Linksec and timesync */ ++#define E1000_TXD_CMD_LINKSEC 0x10000000 /* Apply LinkSec on packet */ ++#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ + -+/** -+ * e1000_init_hw_80003es2lan - Initialize the ESB2 controller -+ * @hw: pointer to the HW structure -+ * -+ * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. -+ * This is a function pointer entry point called by the api module. -+ **/ -+static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 reg_data; -+ s32 ret_val; -+ u16 i; -+ -+ e1000_initialize_hw_bits_80003es2lan(hw); ++/* Transmit Control */ ++#define E1000_TCTL_RST 0x00000001 /* software reset */ ++#define E1000_TCTL_EN 0x00000002 /* enable tx */ ++#define E1000_TCTL_BCE 0x00000004 /* busy check enable */ ++#define E1000_TCTL_PSP 0x00000008 /* pad short packets */ ++#define E1000_TCTL_CT 0x00000ff0 /* collision threshold */ ++#define E1000_TCTL_COLD 0x003ff000 /* collision distance */ ++#define E1000_TCTL_SWXOFF 0x00400000 /* SW Xoff transmission */ ++#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 */ + -+ /* Initialize identification LED */ -+ ret_val = e1000e_id_led_init(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error initializing identification LED\n"); -+ return ret_val; -+ } ++/* Transmit Arbitration Count */ ++#define E1000_TARC0_ENABLE 0x00000400 /* Enable Tx Queue 0 */ + -+ /* Disabling VLAN filtering */ -+ hw_dbg(hw, "Initializing the IEEE VLAN\n"); -+ e1000e_clear_vfta(hw); ++/* SerDes Control */ ++#define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400 + -+ /* Setup the receive address. */ -+ e1000e_init_rx_addrs(hw, mac->rar_entry_count); ++/* 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_CRCOFL 0x00000800 /* CRC32 offload enable */ ++#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ ++#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ + -+ /* Zero out the Multicast HASH table */ -+ hw_dbg(hw, "Zeroing the MTA\n"); -+ for (i = 0; i < mac->mta_reg_count; i++) -+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); ++/* 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 ++#define E1000_RFCTL_LEF 0x00040000 + -+ /* Setup link and flow control */ -+ ret_val = e1000e_setup_link(hw); ++/* Collision related configuration parameters */ ++#define E1000_COLLISION_THRESHOLD 15 ++#define E1000_CT_SHIFT 4 ++#define E1000_COLLISION_DISTANCE 63 ++#define E1000_COLD_SHIFT 12 + -+ /* Set the transmit descriptor write-back policy */ -+ reg_data = er32(TXDCTL); -+ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; -+ ew32(TXDCTL, reg_data); ++/* Default values for the transmit IPG register */ ++#define DEFAULT_82543_TIPG_IPGT_FIBER 9 ++#define DEFAULT_82543_TIPG_IPGT_COPPER 8 + -+ /* ...for both queues. */ -+ reg_data = er32(TXDCTL1); -+ reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB | E1000_TXDCTL_COUNT_DESC; -+ ew32(TXDCTL1, reg_data); ++#define E1000_TIPG_IPGT_MASK 0x000003FF ++#define E1000_TIPG_IPGR1_MASK 0x000FFC00 ++#define E1000_TIPG_IPGR2_MASK 0x3FF00000 + -+ /* Enable retransmit on late collisions */ -+ reg_data = er32(TCTL); -+ reg_data |= E1000_TCTL_RTLC; -+ ew32(TCTL, reg_data); ++#define DEFAULT_82543_TIPG_IPGR1 8 ++#define E1000_TIPG_IPGR1_SHIFT 10 + -+ /* Configure Gigabit Carry Extend Padding */ -+ reg_data = er32(TCTL_EXT); -+ reg_data &= ~E1000_TCTL_EXT_GCEX_MASK; -+ reg_data |= DEFAULT_TCTL_EXT_GCEX_80003ES2LAN; -+ ew32(TCTL_EXT, reg_data); ++#define DEFAULT_82543_TIPG_IPGR2 6 ++#define DEFAULT_80003ES2LAN_TIPG_IPGR2 7 ++#define E1000_TIPG_IPGR2_SHIFT 20 + -+ /* Configure Transmit Inter-Packet Gap */ -+ reg_data = er32(TIPG); -+ reg_data &= ~E1000_TIPG_IPGT_MASK; -+ reg_data |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; -+ ew32(TIPG, reg_data); ++/* Ethertype field values */ ++#define ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.3ac packet */ + -+ reg_data = E1000_READ_REG_ARRAY(hw, E1000_FFLT, 0x0001); -+ reg_data &= ~0x00100000; -+ E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); ++#define ETHERNET_FCS_SIZE 4 ++#define MAX_JUMBO_FRAME_SIZE 0x3F00 + -+ /* 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 -+ * is no link. -+ */ -+ e1000_clear_hw_cntrs_80003es2lan(hw); ++/* Extended Configuration Control and Size */ ++#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 ++#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001 ++#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020 ++#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000 ++#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16 ++#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK 0x0FFF0000 ++#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT 16 + -+ return ret_val; -+} ++#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 + -+/** -+ * e1000_initialize_hw_bits_80003es2lan - Init hw bits of ESB2 -+ * @hw: pointer to the HW structure -+ * -+ * Initializes required hardware-dependent bits needed for normal operation. -+ **/ -+static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw) -+{ -+ u32 reg; ++#define E1000_KABGTXD_BGSQLBIAS 0x00050000 + -+ /* Transmit Descriptor Control 0 */ -+ reg = er32(TXDCTL); -+ reg |= (1 << 22); -+ ew32(TXDCTL, reg); ++/* PBA constants */ ++#define E1000_PBA_6K 0x0006 /* 6KB */ ++#define E1000_PBA_8K 0x0008 /* 8KB */ ++#define E1000_PBA_12K 0x000C /* 12KB */ ++#define E1000_PBA_16K 0x0010 /* 16KB */ ++#define E1000_PBA_20K 0x0014 ++#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 */ ++#define E1000_PBA_64K 0x0040 /* 64KB */ + -+ /* Transmit Descriptor Control 1 */ -+ reg = er32(TXDCTL1); -+ reg |= (1 << 22); -+ ew32(TXDCTL1, reg); ++#define E1000_PBS_16K E1000_PBA_16K ++#define E1000_PBS_24K E1000_PBA_24K + -+ /* Transmit Arbitration Control 0 */ -+ reg = er32(TARC0); -+ reg &= ~(0xF << 27); /* 30:27 */ -+ if (hw->media_type != e1000_media_type_copper) -+ reg &= ~(1 << 20); -+ ew32(TARC0, reg); ++#define IFS_MAX 80 ++#define IFS_MIN 40 ++#define IFS_RATIO 4 ++#define IFS_STEP 10 ++#define MIN_NUM_XMITS 1000 + -+ /* Transmit Arbitration Control 1 */ -+ reg = er32(TARC1); -+ if (er32(TCTL) & E1000_TCTL_MULR) -+ reg &= ~(1 << 28); -+ else -+ reg |= (1 << 28); -+ ew32(TARC1, reg); -+} ++/* 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 */ + -+/** -+ * e1000_copper_link_setup_gg82563_80003es2lan - Configure GG82563 Link -+ * @hw: pointer to the HW structure -+ * -+ * Setup some GG82563 PHY registers for obtaining link -+ **/ -+static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u32 ctrl_ext; -+ u16 data; ++/* Interrupt Cause Read */ ++#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */ ++#define E1000_ICR_TXQE 0x00000002 /* Transmit Queue empty */ ++#define E1000_ICR_LSC 0x00000004 /* Link Status Change */ ++#define E1000_ICR_RXSEQ 0x00000008 /* rx sequence error */ ++#define E1000_ICR_RXDMT0 0x00000010 /* rx desc min. threshold (0) */ ++#define E1000_ICR_RXO 0x00000040 /* rx overrun */ ++#define E1000_ICR_RXT0 0x00000080 /* rx timer intr (ring 0) */ ++#define E1000_ICR_VMMB 0x00000100 /* VM MB event */ ++#define E1000_ICR_MDAC 0x00000200 /* MDIO access complete */ ++#define E1000_ICR_RXCFG 0x00000400 /* Rx /c/ ordered set */ ++#define E1000_ICR_GPI_EN0 0x00000800 /* GP Int 0 */ ++#define E1000_ICR_GPI_EN1 0x00001000 /* GP Int 1 */ ++#define E1000_ICR_GPI_EN2 0x00002000 /* GP Int 2 */ ++#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 hardware reset occurs */ ++#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ ++#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ ++#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ ++#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ ++#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ ++ ++/* Extended Interrupt Cause Read */ ++#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ ++#define E1000_EICR_RX_QUEUE1 0x00000002 /* Rx Queue 1 Interrupt */ ++#define E1000_EICR_RX_QUEUE2 0x00000004 /* Rx Queue 2 Interrupt */ ++#define E1000_EICR_RX_QUEUE3 0x00000008 /* Rx Queue 3 Interrupt */ ++#define E1000_EICR_TX_QUEUE0 0x00000100 /* Tx Queue 0 Interrupt */ ++#define E1000_EICR_TX_QUEUE1 0x00000200 /* Tx Queue 1 Interrupt */ ++#define E1000_EICR_TX_QUEUE2 0x00000400 /* Tx Queue 2 Interrupt */ ++#define E1000_EICR_TX_QUEUE3 0x00000800 /* Tx Queue 3 Interrupt */ ++#define E1000_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ ++#define E1000_EICR_OTHER 0x80000000 /* Interrupt Cause Active */ ++/* TCP Timer */ ++#define E1000_TCPTIMER_KS 0x00000100 /* KickStart */ ++#define E1000_TCPTIMER_COUNT_ENABLE 0x00000200 /* Count Enable */ ++#define E1000_TCPTIMER_COUNT_FINISH 0x00000400 /* Count finish */ ++#define E1000_TCPTIMER_LOOP 0x00000800 /* Loop */ + -+ ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, -+ &data); -+ if (ret_val) -+ return ret_val; ++/* ++ * This defines the bits that are set in the Interrupt Mask ++ * Set/Read Register. Each bit is documented below: ++ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) ++ * o RXSEQ = Receive Sequence Error ++ */ ++#define POLL_IMS_ENABLE_MASK ( \ ++ E1000_IMS_RXDMT0 | \ ++ E1000_IMS_RXSEQ) + -+ data |= GG82563_MSCR_ASSERT_CRS_ON_TX; -+ /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ -+ data |= GG82563_MSCR_TX_CLK_1000MBPS_25; ++/* ++ * This defines the bits that are set in the Interrupt Mask ++ * Set/Read Register. Each bit is documented below: ++ * o RXT0 = Receiver Timer Interrupt (ring 0) ++ * o TXDW = Transmit Descriptor Written Back ++ * o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0) ++ * o RXSEQ = Receive Sequence Error ++ * o LSC = Link Status Change ++ */ ++#define IMS_ENABLE_MASK ( \ ++ E1000_IMS_RXT0 | \ ++ E1000_IMS_TXDW | \ ++ E1000_IMS_RXDMT0 | \ ++ E1000_IMS_RXSEQ | \ ++ E1000_IMS_LSC) + -+ ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, -+ data); -+ if (ret_val) -+ return ret_val; ++/* Interrupt Mask Set */ ++#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ ++#define E1000_IMS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ ++#define E1000_IMS_LSC E1000_ICR_LSC /* Link Status Change */ ++#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ ++#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ ++#define E1000_IMS_RXO E1000_ICR_RXO /* rx overrun */ ++#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ ++#define E1000_IMS_MDAC E1000_ICR_MDAC /* MDIO access complete */ ++#define E1000_IMS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ ++#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ ++#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ ++#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ ++#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 ++#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ ++#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ ++#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ ++#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ ++#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ ++ ++/* Extended Interrupt Mask Set */ ++#define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ ++#define E1000_EIMS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ ++#define E1000_EIMS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ ++#define E1000_EIMS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ ++#define E1000_EIMS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ ++#define E1000_EIMS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ ++#define E1000_EIMS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ ++#define E1000_EIMS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ ++#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ ++#define E1000_EIMS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ + -+ /* 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 = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++/* Interrupt Cause Set */ ++#define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ ++#define E1000_ICS_TXQE E1000_ICR_TXQE /* Transmit Queue empty */ ++#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ ++#define E1000_ICS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ ++#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ ++#define E1000_ICS_RXO E1000_ICR_RXO /* rx overrun */ ++#define E1000_ICS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ ++#define E1000_ICS_MDAC E1000_ICR_MDAC /* MDIO access complete */ ++#define E1000_ICS_RXCFG E1000_ICR_RXCFG /* Rx /c/ ordered set */ ++#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0 /* GP Int 0 */ ++#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1 /* GP Int 1 */ ++#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2 /* GP Int 2 */ ++#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 ++ ++/* Extended Interrupt Cause Set */ ++#define E1000_EICS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ ++#define E1000_EICS_RX_QUEUE1 E1000_EICR_RX_QUEUE1 /* Rx Queue 1 Interrupt */ ++#define E1000_EICS_RX_QUEUE2 E1000_EICR_RX_QUEUE2 /* Rx Queue 2 Interrupt */ ++#define E1000_EICS_RX_QUEUE3 E1000_EICR_RX_QUEUE3 /* Rx Queue 3 Interrupt */ ++#define E1000_EICS_TX_QUEUE0 E1000_EICR_TX_QUEUE0 /* Tx Queue 0 Interrupt */ ++#define E1000_EICS_TX_QUEUE1 E1000_EICR_TX_QUEUE1 /* Tx Queue 1 Interrupt */ ++#define E1000_EICS_TX_QUEUE2 E1000_EICR_TX_QUEUE2 /* Tx Queue 2 Interrupt */ ++#define E1000_EICS_TX_QUEUE3 E1000_EICR_TX_QUEUE3 /* Tx Queue 3 Interrupt */ ++#define E1000_EICS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ ++#define E1000_EICS_OTHER E1000_EICR_OTHER /* Interrupt Cause Active */ + -+ data &= ~GG82563_PSCR_CROSSOVER_MODE_MASK; ++/* Transmit Descriptor Control */ ++#define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */ ++#define E1000_TXDCTL_HTHRESH 0x00003F00 /* TXDCTL Host Threshold */ ++#define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */ ++#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_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */ ++/* Enable the counting of descriptors still to be processed. */ ++#define E1000_TXDCTL_COUNT_DESC 0x00400000 + -+ switch (phy->mdix) { -+ case 1: -+ data |= GG82563_PSCR_CROSSOVER_MODE_MDI; -+ break; -+ case 2: -+ data |= GG82563_PSCR_CROSSOVER_MODE_MDIX; -+ break; -+ case 0: -+ default: -+ data |= GG82563_PSCR_CROSSOVER_MODE_AUTO; -+ break; -+ } ++/* Flow Control Constants */ ++#define FLOW_CONTROL_ADDRESS_LOW 0x00C28001 ++#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100 ++#define FLOW_CONTROL_TYPE 0x8808 + -+ /* Options: -+ * disable_polarity_correction = 0 (default) -+ * Automatic Correction for Reversed Cable Polarity -+ * 0 - Disabled -+ * 1 - Enabled -+ */ -+ data &= ~GG82563_PSCR_POLARITY_REVERSAL_DISABLE; -+ if (phy->disable_polarity_correction) -+ data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; ++/* 802.1q VLAN Packet Size */ ++#define VLAN_TAG_SIZE 4 /* 802.3ac tag (not DMA'd) */ ++#define E1000_VLAN_FILTER_TBL_SIZE 128 /* VLAN Filter Table (4096 bits) */ + -+ ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL, data); -+ if (ret_val) -+ return ret_val; ++/* Receive Address */ ++/* ++ * Number of high/low register pairs in the RAR. The RAR (Receive Address ++ * Registers) holds the directed and multicast addresses that we monitor. ++ * Technically, we have 16 spots. However, we reserve one of these spots ++ * (RAR[15]) for our directed address used by controllers with ++ * manageability enabled, allowing us room for 15 multicast addresses. ++ */ ++#define E1000_RAR_ENTRIES 15 ++#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ + -+ /* SW Reset the PHY so all changes take effect */ -+ ret_val = e1000e_commit_phy(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error Resetting the PHY\n"); -+ return ret_val; -+ } ++/* Error Codes */ ++#define E1000_SUCCESS 0 ++#define E1000_ERR_NVM 1 ++#define E1000_ERR_PHY 2 ++#define E1000_ERR_CONFIG 3 ++#define E1000_ERR_PARAM 4 ++#define E1000_ERR_MAC_INIT 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 ++#define E1000_NOT_IMPLEMENTED 14 + -+ /* Bypass RX and TX FIFO's */ -+ ret_val = e1000e_write_kmrn_reg(hw, -+ E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL, -+ E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS | -+ E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS); -+ if (ret_val) -+ return ret_val; ++/* Loop limit on how long we wait for auto-negotiation to complete */ ++#define FIBER_LINK_UP_LIMIT 50 ++#define COPPER_LINK_UP_LIMIT 10 ++#define PHY_AUTO_NEG_LIMIT 45 ++#define PHY_FORCE_LIMIT 20 ++/* Number of 100 microseconds we wait for PCI Express master disable */ ++#define MASTER_DISABLE_TIMEOUT 800 ++/* Number of milliseconds we wait for PHY configuration done after MAC reset */ ++#define PHY_CFG_TIMEOUT 100 ++/* Number of 2 milliseconds we wait for acquiring MDIO ownership. */ ++#define MDIO_OWNERSHIP_TIMEOUT 10 ++/* Number of milliseconds for NVM auto read done after MAC reset. */ ++#define AUTO_READ_DONE_TIMEOUT 10 + -+ ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data); -+ if (ret_val) -+ return ret_val; ++/* Flow Control */ ++#define E1000_FCRTH_RTH 0x0000FFF8 /* Mask Bits[15:3] for RTH */ ++#define E1000_FCRTH_XFCE 0x80000000 /* External Flow Control Enable */ ++#define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ ++#define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ + -+ data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; -+ ret_val = e1e_wphy(hw, GG82563_PHY_SPEC_CTRL_2, data); -+ if (ret_val) -+ return ret_val; ++/* Transmit Configuration Word */ ++#define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ ++#define E1000_TXCW_HD 0x00000040 /* TXCW half duplex */ ++#define E1000_TXCW_PAUSE 0x00000080 /* TXCW sym pause request */ ++#define E1000_TXCW_ASM_DIR 0x00000100 /* TXCW astm pause direction */ ++#define E1000_TXCW_PAUSE_MASK 0x00000180 /* TXCW pause request mask */ ++#define E1000_TXCW_RF 0x00003000 /* TXCW remote fault */ ++#define E1000_TXCW_NP 0x00008000 /* TXCW next page */ ++#define E1000_TXCW_CW 0x0000ffff /* TxConfigWord mask */ ++#define E1000_TXCW_TXC 0x40000000 /* Transmit Config control */ ++#define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ + -+ ctrl_ext = er32(CTRL_EXT); -+ ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); -+ ew32(CTRL_EXT, ctrl_ext); ++/* Receive Configuration Word */ ++#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ ++#define E1000_RXCW_NC 0x04000000 /* Receive config no carrier */ ++#define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ ++#define E1000_RXCW_CC 0x10000000 /* Receive config change */ ++#define E1000_RXCW_C 0x20000000 /* Receive config */ ++#define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ ++#define E1000_RXCW_ANC 0x80000000 /* Auto-neg complete */ + -+ ret_val = e1e_rphy(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++/* PCI Express Control */ ++#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 + -+ /* 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 (!e1000e_check_mng_mode(hw)) { -+ /* Enable Electrical Idle on the PHY */ -+ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; -+ ret_val = e1e_wphy(hw, GG82563_PHY_PWR_MGMT_CTRL, data); -+ if (ret_val) -+ return ret_val; ++#define PCIE_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) + -+ ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++/* 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 */ ++#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ ++#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ ++#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ ++#define MII_CR_POWER_DOWN 0x0800 /* Power down */ ++#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ ++#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ ++#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ ++#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ ++#define MII_CR_SPEED_1000 0x0040 ++#define MII_CR_SPEED_100 0x2000 ++#define MII_CR_SPEED_10 0x0000 + -+ data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; -+ ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data); -+ if (ret_val) -+ return ret_val; -+ } ++/* PHY Status Register */ ++#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ ++#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ ++#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ ++#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ ++#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ ++#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ ++#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ ++#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ ++#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ ++#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ ++#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ ++#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ ++#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ ++#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ ++#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + -+ /* Workaround: Disable padding in Kumeran interface in the MAC -+ * and in the PHY to avoid CRC errors. -+ */ -+ ret_val = e1e_rphy(hw, GG82563_PHY_INBAND_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++/* Autoneg Advertisement Register */ ++#define NWAY_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ ++#define NWAY_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ ++#define NWAY_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ ++#define NWAY_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ ++#define NWAY_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ ++#define NWAY_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ ++#define NWAY_AR_PAUSE 0x0400 /* Pause operation desired */ ++#define NWAY_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ ++#define NWAY_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ ++#define NWAY_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ + -+ data |= GG82563_ICR_DIS_PADDING; -+ ret_val = e1e_wphy(hw, GG82563_PHY_INBAND_CTRL, data); -+ if (ret_val) -+ return ret_val; ++/* Link Partner Ability Register (Base Page) */ ++#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */ ++#define NWAY_LPAR_10T_HD_CAPS 0x0020 /* LP is 10T Half Duplex Capable */ ++#define NWAY_LPAR_10T_FD_CAPS 0x0040 /* LP is 10T Full Duplex Capable */ ++#define NWAY_LPAR_100TX_HD_CAPS 0x0080 /* LP is 100TX Half Duplex Capable */ ++#define NWAY_LPAR_100TX_FD_CAPS 0x0100 /* LP is 100TX Full Duplex Capable */ ++#define NWAY_LPAR_100T4_CAPS 0x0200 /* LP is 100T4 Capable */ ++#define NWAY_LPAR_PAUSE 0x0400 /* LP Pause operation desired */ ++#define NWAY_LPAR_ASM_DIR 0x0800 /* LP Asymmetric Pause Direction bit */ ++#define NWAY_LPAR_REMOTE_FAULT 0x2000 /* LP has detected Remote Fault */ ++#define NWAY_LPAR_ACKNOWLEDGE 0x4000 /* LP has rx'd link code word */ ++#define NWAY_LPAR_NEXT_PAGE 0x8000 /* Next Page ability supported */ + -+ return 0; -+} ++/* Autoneg Expansion Register */ ++#define NWAY_ER_LP_NWAY_CAPS 0x0001 /* LP has Auto Neg Capability */ ++#define NWAY_ER_PAGE_RXD 0x0002 /* LP is 10T Half Duplex Capable */ ++#define NWAY_ER_NEXT_PAGE_CAPS 0x0004 /* LP is 10T Full Duplex Capable */ ++#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */ ++#define NWAY_ER_PAR_DETECT_FAULT 0x0010 /* LP is 100TX Full Duplex Capable */ + -+/** -+ * e1000_setup_copper_link_80003es2lan - Setup Copper Link for ESB2 -+ * @hw: pointer to the HW structure -+ * -+ * Essentially a wrapper for setting up all things "copper" related. -+ * This is a function pointer entry point called by the mac module. -+ **/ -+static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) -+{ -+ u32 ctrl; -+ s32 ret_val; -+ u16 reg_data; ++/* 1000BASE-T Control Register */ ++#define CR_1000T_ASYM_PAUSE 0x0080 /* Advertise asymmetric pause bit */ ++#define CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ ++#define CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ ++#define CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port */ ++ /* 0=DTE device */ ++#define CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master */ ++ /* 0=Configure PHY as Slave */ ++#define CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value */ ++ /* 0=Automatic Master/Slave config */ ++#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ ++#define CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ ++#define CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ ++#define CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ ++#define CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ + -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_SLU; -+ ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); -+ ew32(CTRL, ctrl); ++/* 1000BASE-T Status Register */ ++#define SR_1000T_IDLE_ERROR_CNT 0x00FF /* Num idle errors since last read */ ++#define SR_1000T_ASYM_PAUSE_DIR 0x0100 /* LP asymmetric pause direction bit */ ++#define SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ ++#define SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ ++#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ ++#define SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ ++#define SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local Tx is Master, 0=Slave */ ++#define SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ + -+ /* 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 = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), ®_data); -+ if (ret_val) -+ return ret_val; -+ reg_data |= 0x3F; -+ ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_read_kmrn_reg(hw, -+ E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, -+ ®_data); -+ if (ret_val) -+ return ret_val; -+ reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING; -+ ret_val = e1000e_write_kmrn_reg(hw, -+ E1000_KMRNCTRLSTA_OFFSET_INB_CTRL, -+ reg_data); -+ if (ret_val) -+ return ret_val; ++#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT 5 + -+ ret_val = e1000_copper_link_setup_gg82563_80003es2lan(hw); -+ if (ret_val) -+ return ret_val; ++/* PHY 1000 MII Register/Bit Definitions */ ++/* PHY Registers defined by IEEE */ ++#define PHY_CONTROL 0x00 /* Control Register */ ++#define PHY_STATUS 0x01 /* Status Register */ ++#define PHY_ID1 0x02 /* Phy Id Reg (word 1) */ ++#define PHY_ID2 0x03 /* Phy Id Reg (word 2) */ ++#define PHY_AUTONEG_ADV 0x04 /* Autoneg Advertisement */ ++#define PHY_LP_ABILITY 0x05 /* Link Partner Ability (Base Page) */ ++#define PHY_AUTONEG_EXP 0x06 /* Autoneg Expansion Reg */ ++#define PHY_NEXT_PAGE_TX 0x07 /* Next Page Tx */ ++#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */ ++#define PHY_1000T_CTRL 0x09 /* 1000Base-T Control Reg */ ++#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */ ++#define PHY_EXT_STATUS 0x0F /* Extended Status Reg */ + -+ ret_val = e1000e_setup_copper_link(hw); ++/* NVM Control */ ++#define E1000_EECD_SK 0x00000001 /* NVM Clock */ ++#define E1000_EECD_CS 0x00000002 /* NVM Chip Select */ ++#define E1000_EECD_DI 0x00000004 /* NVM Data In */ ++#define E1000_EECD_DO 0x00000008 /* NVM Data Out */ ++#define E1000_EECD_FWE_MASK 0x00000030 ++#define E1000_EECD_FWE_DIS 0x00000010 /* Disable FLASH writes */ ++#define E1000_EECD_FWE_EN 0x00000020 /* Enable FLASH writes */ ++#define E1000_EECD_FWE_SHIFT 4 ++#define E1000_EECD_REQ 0x00000040 /* NVM Access Request */ ++#define E1000_EECD_GNT 0x00000080 /* NVM Access Grant */ ++#define E1000_EECD_PRES 0x00000100 /* NVM Present */ ++#define E1000_EECD_SIZE 0x00000200 /* NVM Size (0=64 word 1=256 word) */ ++/* NVM Addressing bits based on type 0=small, 1=large */ ++#define E1000_EECD_ADDR_BITS 0x00000400 ++#define E1000_EECD_TYPE 0x00002000 /* NVM Type (1-SPI, 0-Microwire) */ ++#define E1000_NVM_GRANT_ATTEMPTS 1000 /* NVM # attempts to gain grant */ ++#define E1000_EECD_AUTO_RD 0x00000200 /* NVM Auto Read done */ ++#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* NVM 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 + -+ return 0; -+} ++#define E1000_NVM_SWDPIN0 0x0001 /* SWDPIN 0 NVM Value */ ++#define E1000_NVM_LED_LOGIC 0x0020 /* Led Logic Word */ ++#define E1000_NVM_RW_REG_DATA 16 /* Offset to data in NVM read/write registers */ ++#define E1000_NVM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ ++#define E1000_NVM_RW_REG_START 1 /* Start operation */ ++#define E1000_NVM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ ++#define E1000_NVM_POLL_WRITE 1 /* Flag for polling for write complete */ ++#define E1000_NVM_POLL_READ 0 /* Flag for polling for read complete */ ++#define E1000_FLASH_UPDATES 2000 + -+/** -+ * e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation -+ * @hw: pointer to the HW structure -+ * @duplex: current duplex setting -+ * -+ * Configure the KMRN interface by applying last minute quirks for -+ * 10/100 operation. -+ **/ -+static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) -+{ -+ s32 ret_val; -+ u32 tipg; -+ u16 reg_data; ++/* NVM Word Offsets */ ++#define NVM_COMPAT 0x0003 ++#define NVM_ID_LED_SETTINGS 0x0004 ++#define NVM_VERSION 0x0005 ++#define NVM_SERDES_AMPLITUDE 0x0006 /* For SERDES output amplitude adjustment. */ ++#define NVM_PHY_CLASS_WORD 0x0007 ++#define NVM_INIT_CONTROL1_REG 0x000A ++#define NVM_INIT_CONTROL2_REG 0x000F ++#define NVM_SWDEF_PINS_CTRL_PORT_1 0x0010 ++#define NVM_INIT_CONTROL3_PORT_B 0x0014 ++#define NVM_INIT_3GIO_3 0x001A ++#define NVM_SWDEF_PINS_CTRL_PORT_0 0x0020 ++#define NVM_INIT_CONTROL3_PORT_A 0x0024 ++#define NVM_CFG 0x0012 ++#define NVM_FLASH_VERSION 0x0032 ++#define NVM_ALT_MAC_ADDR_PTR 0x0037 ++#define NVM_CHECKSUM_REG 0x003F + -+ reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT; -+ ret_val = e1000e_write_kmrn_reg(hw, -+ E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, -+ reg_data); -+ if (ret_val) -+ return ret_val; ++#define E1000_NVM_CFG_DONE_PORT_0 0x40000 /* MNG config cycle done */ ++#define E1000_NVM_CFG_DONE_PORT_1 0x80000 /* ...for second port */ + -+ /* Configure Transmit Inter-Packet Gap */ -+ tipg = er32(TIPG); -+ tipg &= ~E1000_TIPG_IPGT_MASK; -+ tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN; -+ ew32(TIPG, tipg); ++/* Mask bits for fields in Word 0x0f of the NVM */ ++#define NVM_WORD0F_PAUSE_MASK 0x3000 ++#define NVM_WORD0F_PAUSE 0x1000 ++#define NVM_WORD0F_ASM_DIR 0x2000 ++#define NVM_WORD0F_ANE 0x0800 ++#define NVM_WORD0F_SWPDIO_EXT_MASK 0x00F0 ++#define NVM_WORD0F_LPLU 0x0001 + -+ ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); -+ if (ret_val) -+ return ret_val; ++/* Mask bits for fields in Word 0x1a of the NVM */ ++#define NVM_WORD1A_ASPM_MASK 0x000C + -+ if (duplex == HALF_DUPLEX) -+ reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER; -+ else -+ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; ++/* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ ++#define NVM_SUM 0xBABA + -+ ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); ++#define NVM_MAC_ADDR_OFFSET 0 ++#define NVM_PBA_OFFSET_0 8 ++#define NVM_PBA_OFFSET_1 9 ++#define NVM_RESERVED_WORD 0xFFFF ++#define NVM_PHY_CLASS_A 0x8000 ++#define NVM_SERDES_AMPLITUDE_MASK 0x000F ++#define NVM_SIZE_MASK 0x1C00 ++#define NVM_SIZE_SHIFT 10 ++#define NVM_WORD_SIZE_BASE_SHIFT 6 ++#define NVM_SWDPIO_EXT_SHIFT 4 + -+ return 0; -+} ++/* NVM Commands - Microwire */ ++#define NVM_READ_OPCODE_MICROWIRE 0x6 /* NVM read opcode */ ++#define NVM_WRITE_OPCODE_MICROWIRE 0x5 /* NVM write opcode */ ++#define NVM_ERASE_OPCODE_MICROWIRE 0x7 /* NVM erase opcode */ ++#define NVM_EWEN_OPCODE_MICROWIRE 0x13 /* NVM erase/write enable */ ++#define NVM_EWDS_OPCODE_MICROWIRE 0x10 /* NVM erase/write disable */ + -+/** -+ * e1000_cfg_kmrn_1000_80003es2lan - Apply "quirks" for gigabit operation -+ * @hw: pointer to the HW structure -+ * -+ * Configure the KMRN interface by applying last minute quirks for -+ * gigabit operation. -+ **/ -+static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) -+{ -+ s32 ret_val; -+ u16 reg_data; -+ u32 tipg; ++/* NVM Commands - SPI */ ++#define NVM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ ++#define NVM_READ_OPCODE_SPI 0x03 /* NVM read opcode */ ++#define NVM_WRITE_OPCODE_SPI 0x02 /* NVM write opcode */ ++#define NVM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ ++#define NVM_WREN_OPCODE_SPI 0x06 /* NVM set Write Enable latch */ ++#define NVM_WRDI_OPCODE_SPI 0x04 /* NVM reset Write Enable latch */ ++#define NVM_RDSR_OPCODE_SPI 0x05 /* NVM read Status register */ ++#define NVM_WRSR_OPCODE_SPI 0x01 /* NVM write Status register */ + -+ reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT; -+ ret_val = e1000e_write_kmrn_reg(hw, -+ E1000_KMRNCTRLSTA_OFFSET_HD_CTRL, -+ reg_data); -+ if (ret_val) -+ return ret_val; ++/* SPI NVM Status Register */ ++#define NVM_STATUS_RDY_SPI 0x01 ++#define NVM_STATUS_WEN_SPI 0x02 ++#define NVM_STATUS_BP0_SPI 0x04 ++#define NVM_STATUS_BP1_SPI 0x08 ++#define NVM_STATUS_WPEN_SPI 0x80 + -+ /* Configure Transmit Inter-Packet Gap */ -+ tipg = er32(TIPG); -+ tipg &= ~E1000_TIPG_IPGT_MASK; -+ tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN; -+ ew32(TIPG, tipg); ++/* Word definitions for ID LED Settings */ ++#define ID_LED_RESERVED_0000 0x0000 ++#define ID_LED_RESERVED_FFFF 0xFFFF ++#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_DEF1_DEF2 0x1 ++#define ID_LED_DEF1_ON2 0x2 ++#define ID_LED_DEF1_OFF2 0x3 ++#define ID_LED_ON1_DEF2 0x4 ++#define ID_LED_ON1_ON2 0x5 ++#define ID_LED_ON1_OFF2 0x6 ++#define ID_LED_OFF1_DEF2 0x7 ++#define ID_LED_OFF1_ON2 0x8 ++#define ID_LED_OFF1_OFF2 0x9 + -+ ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); -+ if (ret_val) -+ return ret_val; ++#define IGP_ACTIVITY_LED_MASK 0xFFFFF0FF ++#define IGP_ACTIVITY_LED_ENABLE 0x0300 ++#define IGP_LED3_MODE 0x07000000 + -+ reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; -+ ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); ++/* PCI/PCI-X/PCI-EX Config space */ ++#define PCIX_COMMAND_REGISTER 0xE6 ++#define PCIX_STATUS_REGISTER_LO 0xE8 ++#define PCIX_STATUS_REGISTER_HI 0xEA ++#define PCI_HEADER_TYPE_REGISTER 0x0E ++#define PCIE_LINK_STATUS 0x12 + -+ return ret_val; -+} ++#define PCIX_COMMAND_MMRBC_MASK 0x000C ++#define PCIX_COMMAND_MMRBC_SHIFT 0x2 ++#define PCIX_STATUS_HI_MMRBC_MASK 0x0060 ++#define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 ++#define PCIX_STATUS_HI_MMRBC_4K 0x3 ++#define PCIX_STATUS_HI_MMRBC_2K 0x2 ++#define PCIX_STATUS_LO_FUNC_MASK 0x7 ++#define PCI_HEADER_TYPE_MULTIFUNC 0x80 ++#define PCIE_LINK_WIDTH_MASK 0x3F0 ++#define PCIE_LINK_WIDTH_SHIFT 4 + -+/** -+ * e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters -+ * @hw: pointer to the HW structure -+ * -+ * Clears the hardware counters by reading the counter registers. -+ **/ -+static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) -+{ -+ u32 temp; -+ -+ e1000e_clear_hw_cntrs_base(hw); -+ -+ temp = er32(PRC64); -+ temp = er32(PRC127); -+ temp = er32(PRC255); -+ temp = er32(PRC511); -+ temp = er32(PRC1023); -+ temp = er32(PRC1522); -+ temp = er32(PTC64); -+ temp = er32(PTC127); -+ temp = er32(PTC255); -+ temp = er32(PTC511); -+ temp = er32(PTC1023); -+ temp = er32(PTC1522); -+ -+ temp = er32(ALGNERRC); -+ temp = er32(RXERRC); -+ temp = er32(TNCRS); -+ temp = er32(CEXTERR); -+ temp = er32(TSCTC); -+ temp = er32(TSCTFC); -+ -+ temp = er32(MGTPRC); -+ temp = er32(MGTPDC); -+ temp = er32(MGTPTC); -+ -+ temp = er32(IAC); -+ temp = er32(ICRXOC); -+ -+ temp = er32(ICRXPTC); -+ temp = er32(ICRXATC); -+ temp = er32(ICTXPTC); -+ temp = er32(ICTXATC); -+ temp = er32(ICTXQEC); -+ temp = er32(ICTXQMTC); -+ temp = er32(ICRXDMTC); -+} -+ -+static struct e1000_mac_operations es2_mac_ops = { -+ .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, -+ /* check_for_link dependent on media type */ -+ .cleanup_led = e1000e_cleanup_led_generic, -+ .clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan, -+ .get_bus_info = e1000e_get_bus_info_pcie, -+ .get_link_up_info = e1000_get_link_up_info_80003es2lan, -+ .led_on = e1000e_led_on_generic, -+ .led_off = e1000e_led_off_generic, -+ .mc_addr_list_update = e1000e_mc_addr_list_update_generic, -+ .reset_hw = e1000_reset_hw_80003es2lan, -+ .init_hw = e1000_init_hw_80003es2lan, -+ .setup_link = e1000e_setup_link, -+ /* setup_physical_interface dependent on media type */ -+}; ++#ifndef ETH_ADDR_LEN ++#define ETH_ADDR_LEN 6 ++#endif + -+static struct e1000_phy_operations es2_phy_ops = { -+ .acquire_phy = e1000_acquire_phy_80003es2lan, -+ .check_reset_block = e1000e_check_reset_block_generic, -+ .commit_phy = e1000e_phy_sw_reset, -+ .force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan, -+ .get_cfg_done = e1000_get_cfg_done_80003es2lan, -+ .get_cable_length = e1000_get_cable_length_80003es2lan, -+ .get_phy_info = e1000e_get_phy_info_m88, -+ .read_phy_reg = e1000_read_phy_reg_gg82563_80003es2lan, -+ .release_phy = e1000_release_phy_80003es2lan, -+ .reset_phy = e1000e_phy_hw_reset_generic, -+ .set_d0_lplu_state = NULL, -+ .set_d3_lplu_state = e1000e_set_d3_lplu_state, -+ .write_phy_reg = e1000_write_phy_reg_gg82563_80003es2lan, -+}; ++#define PHY_REVISION_MASK 0xFFFFFFF0 ++#define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ ++#define MAX_PHY_MULTI_PAGE_REG 0xF + -+static struct e1000_nvm_operations es2_nvm_ops = { -+ .acquire_nvm = e1000_acquire_nvm_80003es2lan, -+ .read_nvm = e1000e_read_nvm_eerd, -+ .release_nvm = e1000_release_nvm_80003es2lan, -+ .update_nvm = e1000e_update_nvm_checksum_generic, -+ .valid_led_default = e1000e_valid_led_default, -+ .validate_nvm = e1000e_validate_nvm_checksum_generic, -+ .write_nvm = e1000_write_nvm_80003es2lan, -+}; ++/* 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 ++#define IGP01E1000_I_PHY_ID 0x02A80380 ++#define M88E1011_I_REV_4 0x04 ++#define M88E1111_I_PHY_ID 0x01410CC0 ++#define GG82563_E_PHY_ID 0x01410CA0 ++#define IGP03E1000_E_PHY_ID 0x02A80390 ++#define IFE_E_PHY_ID 0x02A80330 ++#define IFE_PLUS_E_PHY_ID 0x02A80320 ++#define IFE_C_E_PHY_ID 0x02A80310 ++#define BME1000_E_PHY_ID 0x01410CB0 ++#define BME1000_E_PHY_ID_R2 0x01410CB1 ++#define M88_VENDOR 0x0141 + -+struct e1000_info e1000_es2_info = { -+ .mac = e1000_80003es2lan, -+ .flags = FLAG_HAS_HW_VLAN_FILTER -+ | FLAG_HAS_JUMBO_FRAMES -+ | FLAG_HAS_STATS_PTC_PRC -+ | FLAG_HAS_WOL -+ | FLAG_APME_IN_CTRL3 -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_CTRLEXT_ON_LOAD -+ | FLAG_HAS_STATS_ICR_ICT -+ | FLAG_RX_NEEDS_RESTART /* errata */ -+ | FLAG_TARC_SET_BIT_ZERO /* errata */ -+ | FLAG_APME_CHECK_PORT_B -+ | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ -+ | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, -+ .pba = 38, -+ .get_invariants = e1000_get_invariants_80003es2lan, -+ .mac_ops = &es2_mac_ops, -+ .phy_ops = &es2_phy_ops, -+ .nvm_ops = &es2_nvm_ops, -+}; ++/* M88E1000 Specific Registers */ ++#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */ ++#define M88E1000_PHY_SPEC_STATUS 0x11 /* PHY Specific Status Register */ ++#define M88E1000_INT_ENABLE 0x12 /* Interrupt Enable Register */ ++#define M88E1000_INT_STATUS 0x13 /* Interrupt Status Register */ ++#define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ ++#define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ + -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/ethtool.c linux-2.6.22-10/drivers/net/e1000e/ethtool.c ---- linux-2.6.22-0/drivers/net/e1000e/ethtool.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/ethtool.c 2007-11-21 13:55:34.000000000 -0500 -@@ -0,0 +1,1774 @@ ++#define M88E1000_PHY_EXT_CTRL 0x1A /* PHY extend control register */ ++#define M88E1000_PHY_PAGE_SELECT 0x1D /* Reg 29 for page number setting */ ++#define M88E1000_PHY_GEN_CONTROL 0x1E /* Its meaning depends on reg 29 */ ++#define M88E1000_PHY_VCO_REG_BIT8 0x100 /* Bits 8 & 11 are adjusted for */ ++#define M88E1000_PHY_VCO_REG_BIT11 0x800 /* improved BER performance */ ++ ++/* M88E1000 PHY Specific Control Register */ ++#define M88E1000_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ ++#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ ++#define M88E1000_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled */ ++/* 1=CLK125 low, 0=CLK125 toggling */ ++#define M88E1000_PSCR_CLK125_DISABLE 0x0010 ++#define M88E1000_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5 */ ++ /* Manual MDI configuration */ ++#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ ++/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ ++#define M88E1000_PSCR_AUTO_X_1000T 0x0040 ++/* Auto crossover enabled all speeds */ ++#define M88E1000_PSCR_AUTO_X_MODE 0x0060 ++/* ++ * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold ++ * 0=Normal 10BASE-T Rx Threshold ++ */ ++#define M88E1000_PSCR_EN_10BT_EXT_DIST 0x0080 ++/* 1=5-bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ ++#define M88E1000_PSCR_MII_5BIT_ENABLE 0x0100 ++#define M88E1000_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ ++#define M88E1000_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ ++#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ ++ ++/* M88E1000 PHY Specific Status Register */ ++#define M88E1000_PSSR_JABBER 0x0001 /* 1=Jabber */ ++#define M88E1000_PSSR_REV_POLARITY 0x0002 /* 1=Polarity reversed */ ++#define M88E1000_PSSR_DOWNSHIFT 0x0020 /* 1=Downshifted */ ++#define M88E1000_PSSR_MDIX 0x0040 /* 1=MDIX; 0=MDI */ ++/* ++ * 0 = <50M ++ * 1 = 50-80M ++ * 2 = 80-110M ++ * 3 = 110-140M ++ * 4 = >140M ++ */ ++#define M88E1000_PSSR_CABLE_LENGTH 0x0380 ++#define M88E1000_PSSR_LINK 0x0400 /* 1=Link up, 0=Link down */ ++#define M88E1000_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ ++#define M88E1000_PSSR_PAGE_RCVD 0x1000 /* 1=Page received */ ++#define M88E1000_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ ++#define M88E1000_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ ++#define M88E1000_PSSR_10MBS 0x0000 /* 00=10Mbs */ ++#define M88E1000_PSSR_100MBS 0x4000 /* 01=100Mbs */ ++#define M88E1000_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ ++ ++#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7 ++ ++/* M88E1000 Extended PHY Specific Control Register */ ++#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */ ++/* ++ * 1 = Lost lock detect enabled. ++ * Will assert lost lock and bring ++ * link down if idle not seen ++ * within 1ms in 1000BASE-T ++ */ ++#define M88E1000_EPSCR_DOWN_NO_IDLE 0x8000 ++/* ++ * Number of times we will attempt to autonegotiate before downshifting if we ++ * are the master ++ */ ++#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00 ++#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X 0x0000 ++#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X 0x0400 ++#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X 0x0800 ++#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X 0x0C00 ++/* ++ * Number of times we will attempt to autonegotiate before downshifting if we ++ * are the slave ++ */ ++#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK 0x0300 ++#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS 0x0000 ++#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X 0x0100 ++#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X 0x0200 ++#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X 0x0300 ++#define M88E1000_EPSCR_TX_CLK_2_5 0x0060 /* 2.5 MHz TX_CLK */ ++#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 ++ ++/* BME1000 PHY Specific Control Register */ ++#define BME1000_PSCR_ENABLE_DOWNSHIFT 0x0800 /* 1 = enable downshift */ ++ ++/* ++ * 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. */ ++ ++/* MDI Control */ ++#define E1000_MDIC_DATA_MASK 0x0000FFFF ++#define E1000_MDIC_REG_MASK 0x001F0000 ++#define E1000_MDIC_REG_SHIFT 16 ++#define E1000_MDIC_PHY_MASK 0x03E00000 ++#define E1000_MDIC_PHY_SHIFT 21 ++#define E1000_MDIC_OP_WRITE 0x04000000 ++#define E1000_MDIC_OP_READ 0x08000000 ++#define E1000_MDIC_READY 0x10000000 ++#define E1000_MDIC_INT_EN 0x20000000 ++#define E1000_MDIC_ERROR 0x40000000 ++ ++/* SerDes Control */ ++#define E1000_GEN_CTL_READY 0x80000000 ++#define E1000_GEN_CTL_ADDRESS_SHIFT 8 ++#define E1000_GEN_POLL_TIMEOUT 640 ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000.h linux-2.6.22-10/drivers/net/e1000e/e1000.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,447 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++ Copyright(c) 1999 - 2008 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, @@ -3885,13990 +4718,21925 @@ diff -Nurp linux-2.6.22-0/drivers/net/e1000e/ethtool.c linux-2.6.22-10/drivers/n + +*******************************************************************************/ + -+/* ethtool support for e1000 */ ++/* Linux PRO/1000 Ethernet Driver main header file */ ++ ++#ifndef _E1000_H_ ++#define _E1000_H_ + ++#include ++#include ++#include +#include -+#include -+#include -+#include + -+#include "e1000.h" ++#include "kcompat.h" + -+struct e1000_stats { -+ char stat_string[ETH_GSTRING_LEN]; -+ int sizeof_stat; -+ int stat_offset; -+}; ++#include "e1000_hw.h" + -+#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ -+ offsetof(struct e1000_adapter, m) -+static const struct e1000_stats e1000_gstrings_stats[] = { -+ { "rx_packets", E1000_STAT(stats.gprc) }, -+ { "tx_packets", E1000_STAT(stats.gptc) }, -+ { "rx_bytes", E1000_STAT(stats.gorcl) }, -+ { "tx_bytes", E1000_STAT(stats.gotcl) }, -+ { "rx_broadcast", E1000_STAT(stats.bprc) }, -+ { "tx_broadcast", E1000_STAT(stats.bptc) }, -+ { "rx_multicast", E1000_STAT(stats.mprc) }, -+ { "tx_multicast", E1000_STAT(stats.mptc) }, -+ { "rx_errors", E1000_STAT(net_stats.rx_errors) }, -+ { "tx_errors", E1000_STAT(net_stats.tx_errors) }, -+ { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, -+ { "multicast", E1000_STAT(stats.mprc) }, -+ { "collisions", E1000_STAT(stats.colc) }, -+ { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, -+ { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, -+ { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, -+ { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, -+ { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, -+ { "rx_missed_errors", E1000_STAT(stats.mpc) }, -+ { "tx_aborted_errors", E1000_STAT(stats.ecol) }, -+ { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, -+ { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, -+ { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, -+ { "tx_window_errors", E1000_STAT(stats.latecol) }, -+ { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, -+ { "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) }, -+ { "tx_restart_queue", E1000_STAT(restart_queue) }, -+ { "rx_long_length_errors", E1000_STAT(stats.roc) }, -+ { "rx_short_length_errors", E1000_STAT(stats.ruc) }, -+ { "rx_align_errors", E1000_STAT(stats.algnerrc) }, -+ { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) }, -+ { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) }, -+ { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) }, -+ { "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_header_split", E1000_STAT(rx_hdr_split) }, -+ { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, -+ { "tx_smbus", E1000_STAT(stats.mgptc) }, -+ { "rx_smbus", E1000_STAT(stats.mgprc) }, -+ { "dropped_smbus", E1000_STAT(stats.mgpdc) }, -+ { "rx_dma_failed", E1000_STAT(rx_dma_failed) }, -+ { "tx_dma_failed", E1000_STAT(tx_dma_failed) }, -+}; ++struct e1000_info; + -+#define E1000_GLOBAL_STATS_LEN \ -+ sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) -+#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN) -+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 ++#define e_printk(level, adapter, format, arg...) \ ++ printk(level "%s: %s: " format, pci_name(adapter->pdev), \ ++ (strchr(adapter->netdev->name, '%') ? "" : \ ++ adapter->netdev->name), ## arg) + -+static int e1000_get_settings(struct net_device *netdev, -+ struct ethtool_cmd *ecmd) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; ++#define e_dbg(format, arg...) do { (void)(adapter); } while (0) + -+ if (hw->media_type == e1000_media_type_copper) { ++#define e_err(format, arg...) \ ++ e_printk(KERN_ERR, adapter, format, ## arg) ++#define e_info(format, arg...) \ ++ e_printk(KERN_INFO, adapter, format, ## arg) ++#define e_warn(format, arg...) \ ++ e_printk(KERN_WARNING, adapter, format, ## arg) ++#define e_notice(format, arg...) \ ++ e_printk(KERN_NOTICE, adapter, format, ## arg) + -+ ecmd->supported = (SUPPORTED_10baseT_Half | -+ SUPPORTED_10baseT_Full | -+ SUPPORTED_100baseT_Half | -+ SUPPORTED_100baseT_Full | -+ 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->mac.autoneg == 1) { -+ ecmd->advertising |= ADVERTISED_Autoneg; -+ /* the e1000 autoneg seems to match ethtool nicely */ -+ ecmd->advertising |= hw->phy.autoneg_advertised; -+ } ++#ifdef CONFIG_E1000E_MSIX ++/* Interrupt modes, as used by the IntMode paramter */ ++#define E1000E_INT_MODE_LEGACY 0 ++#define E1000E_INT_MODE_MSI 1 ++#define E1000E_INT_MODE_MSIX 2 + -+ ecmd->port = PORT_TP; -+ ecmd->phy_address = hw->phy.addr; -+ ecmd->transceiver = XCVR_INTERNAL; ++#endif /* CONFIG_E1000E_MSIX */ + -+ } else { -+ ecmd->supported = (SUPPORTED_1000baseT_Full | -+ SUPPORTED_FIBRE | -+ SUPPORTED_Autoneg); ++#define E1000_MAX_INTR 10 + -+ ecmd->advertising = (ADVERTISED_1000baseT_Full | -+ ADVERTISED_FIBRE | -+ ADVERTISED_Autoneg); ++/* Tx/Rx descriptor defines */ ++#define E1000_DEFAULT_TXD 256 ++#define E1000_MAX_TXD 4096 ++#define E1000_MIN_TXD 80 + -+ ecmd->port = PORT_FIBRE; -+ ecmd->transceiver = XCVR_EXTERNAL; -+ } ++#define E1000_DEFAULT_RXD 256 ++#define E1000_MAX_RXD 4096 ++#define E1000_MIN_RXD 80 + -+ if (er32(STATUS) & E1000_STATUS_LU) { ++#define E1000_MIN_ITR_USECS 10 /* 100000 irq/sec */ ++#define E1000_MAX_ITR_USECS 10000 /* 100 irq/sec */ + -+ adapter->hw.mac.ops.get_link_up_info(hw, &adapter->link_speed, -+ &adapter->link_duplex); -+ ecmd->speed = adapter->link_speed; ++/* Early Receive defines */ ++#define E1000_ERT_2048 0x100 + -+ /* unfortunately FULL_DUPLEX != DUPLEX_FULL -+ * and HALF_DUPLEX != DUPLEX_HALF */ ++#define E1000_FC_PAUSE_TIME 0x0680 /* 858 usec */ + -+ if (adapter->link_duplex == FULL_DUPLEX) -+ ecmd->duplex = DUPLEX_FULL; -+ else -+ ecmd->duplex = DUPLEX_HALF; -+ } else { -+ ecmd->speed = -1; -+ ecmd->duplex = -1; -+ } ++/* How many Tx Descriptors do we need to call netif_wake_queue ? */ ++/* How many Rx Buffers do we bundle into one write to the hardware ? */ ++#define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ + -+ ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) || -+ hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; -+ return 0; -+} ++#define AUTO_ALL_MODES 0 ++#define E1000_EEPROM_APME 0x0400 + -+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) -+{ -+ struct e1000_mac_info *mac = &adapter->hw.mac; ++#define E1000_MNG_VLAN_NONE (-1) + -+ mac->autoneg = 0; ++/* Number of packet split data buffers (not including the header buffer) */ ++#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) + -+ /* Fiber NICs only allow 1000 gbps Full duplex */ -+ if ((adapter->hw.media_type == e1000_media_type_fiber) && -+ spddplx != (SPEED_1000 + DUPLEX_FULL)) { -+ ndev_err(adapter->netdev, "Unsupported Speed/Duplex " -+ "configuration\n"); -+ return -EINVAL; -+ } ++enum e1000_boards { ++ board_82571, ++ board_82572, ++ board_82573, ++ board_82574, ++ board_80003es2lan, ++ board_ich8lan, ++ board_ich9lan, ++ board_ich10lan, ++}; + -+ switch (spddplx) { -+ case SPEED_10 + DUPLEX_HALF: -+ mac->forced_speed_duplex = ADVERTISE_10_HALF; -+ break; -+ case SPEED_10 + DUPLEX_FULL: -+ mac->forced_speed_duplex = ADVERTISE_10_FULL; -+ break; -+ case SPEED_100 + DUPLEX_HALF: -+ mac->forced_speed_duplex = ADVERTISE_100_HALF; -+ break; -+ case SPEED_100 + DUPLEX_FULL: -+ mac->forced_speed_duplex = ADVERTISE_100_FULL; -+ break; -+ case SPEED_1000 + DUPLEX_FULL: -+ mac->autoneg = 1; -+ adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL; -+ break; -+ case SPEED_1000 + DUPLEX_HALF: /* not supported */ -+ default: -+ ndev_err(adapter->netdev, "Unsupported Speed/Duplex " -+ "configuration\n"); -+ return -EINVAL; -+ } -+ return 0; -+} ++struct e1000_queue_stats { ++ u64 packets; ++ u64 bytes; ++}; + -+static int e1000_set_settings(struct net_device *netdev, -+ struct ethtool_cmd *ecmd) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; ++struct e1000_ps_page { ++ struct page *page; ++ u64 dma; /* must be u64 - written to hw */ ++}; + -+ /* When SoL/IDER sessions are active, autoneg/speed/duplex -+ * cannot be changed */ -+ if (e1000_check_reset_block(hw)) { -+ ndev_err(netdev, "Cannot change link " -+ "characteristics when SoL/IDER is active.\n"); -+ return -EINVAL; -+ } ++/* ++ * wrappers around a pointer to a socket buffer, ++ * so a DMA handle can be stored along with the buffer ++ */ ++struct e1000_buffer { ++ dma_addr_t dma; ++ struct sk_buff *skb; ++ union { ++ /* Tx */ ++ struct { ++ unsigned long time_stamp; ++ u16 length; ++ u16 next_to_watch; ++ }; ++ /* Rx */ ++ /* arrays of page information for packet split */ ++ struct e1000_ps_page *ps_pages; ++ }; ++ struct page *page; ++}; + -+ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) -+ msleep(1); ++struct e1000_ring { ++ void *desc; /* pointer to ring memory */ ++ dma_addr_t dma; /* phys address of ring */ ++ unsigned int size; /* length of ring in bytes */ ++ unsigned int count; /* number of desc. in ring */ + -+ if (ecmd->autoneg == AUTONEG_ENABLE) { -+ hw->mac.autoneg = 1; -+ if (hw->media_type == e1000_media_type_fiber) -+ hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full | -+ ADVERTISED_FIBRE | -+ ADVERTISED_Autoneg; -+ else -+ hw->phy.autoneg_advertised = ecmd->advertising | -+ ADVERTISED_TP | -+ ADVERTISED_Autoneg; -+ ecmd->advertising = hw->phy.autoneg_advertised; -+ } else { -+ if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { -+ clear_bit(__E1000_RESETTING, &adapter->state); -+ return -EINVAL; -+ } -+ } ++ u16 next_to_use; ++ u16 next_to_clean; + -+ /* reset the link */ ++ u16 head; ++ u16 tail; + -+ if (netif_running(adapter->netdev)) { -+ e1000e_down(adapter); -+ e1000e_up(adapter); -+ } else { -+ e1000e_reset(adapter); -+ } ++ /* array of buffer information structs */ ++ struct e1000_buffer *buffer_info; + -+ clear_bit(__E1000_RESETTING, &adapter->state); -+ return 0; -+} ++#ifdef CONFIG_E1000E_MSIX ++ char name[IFNAMSIZ + 5]; ++ u32 ims_val; ++ u32 itr_val; ++ u16 itr_register; ++ int set_itr; + -+static void e1000_get_pauseparam(struct net_device *netdev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; ++#endif /* CONFIG_E1000E_MSIX */ ++ struct sk_buff *rx_skb_top; + -+ pause->autoneg = -+ (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); ++ struct e1000_queue_stats stats; ++}; + -+ if (hw->mac.fc == e1000_fc_rx_pause) { -+ pause->rx_pause = 1; -+ } else if (hw->mac.fc == e1000_fc_tx_pause) { -+ pause->tx_pause = 1; -+ } else if (hw->mac.fc == e1000_fc_full) { -+ pause->rx_pause = 1; -+ pause->tx_pause = 1; -+ } -+} ++#ifdef SIOCGMIIPHY ++/* PHY register snapshot values */ ++struct e1000_phy_regs { ++ u16 bmcr; /* basic mode control register */ ++ u16 bmsr; /* basic mode status register */ ++ u16 advertise; /* auto-negotiation advertisement */ ++ u16 lpa; /* link partner ability register */ ++ u16 expansion; /* auto-negotiation expansion reg */ ++ u16 ctrl1000; /* 1000BASE-T control register */ ++ u16 stat1000; /* 1000BASE-T status register */ ++ u16 estatus; /* extended status register */ ++}; ++#endif + -+static int e1000_set_pauseparam(struct net_device *netdev, -+ struct ethtool_pauseparam *pause) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ int retval = 0; ++/* board specific private data structure */ ++struct e1000_adapter { ++ struct timer_list watchdog_timer; ++ struct timer_list phy_info_timer; ++ struct timer_list blink_timer; + -+ adapter->fc_autoneg = pause->autoneg; ++ struct work_struct reset_task; ++ struct work_struct watchdog_task; + -+ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) -+ msleep(1); ++ const struct e1000_info *ei; + -+ if (pause->rx_pause && pause->tx_pause) -+ hw->mac.fc = e1000_fc_full; -+ else if (pause->rx_pause && !pause->tx_pause) -+ hw->mac.fc = e1000_fc_rx_pause; -+ else if (!pause->rx_pause && pause->tx_pause) -+ hw->mac.fc = e1000_fc_tx_pause; -+ else if (!pause->rx_pause && !pause->tx_pause) -+ hw->mac.fc = e1000_fc_none; ++ struct vlan_group *vlgrp; ++ u32 bd_number; ++ u32 rx_buffer_len; ++ u16 mng_vlan_id; ++ u16 link_speed; ++ u16 link_duplex; + -+ hw->mac.original_fc = hw->mac.fc; ++ spinlock_t tx_queue_lock; /* prevent concurrent tail updates */ + -+ if (adapter->fc_autoneg == AUTONEG_ENABLE) { -+ if (netif_running(adapter->netdev)) { -+ e1000e_down(adapter); -+ e1000e_up(adapter); -+ } else { -+ e1000e_reset(adapter); -+ } -+ } else { -+ retval = ((hw->media_type == e1000_media_type_fiber) ? -+ hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw)); -+ } ++ /* track device up/down/testing state */ ++ unsigned long state; + -+ clear_bit(__E1000_RESETTING, &adapter->state); -+ return retval; -+} ++ /* Interrupt Throttle Rate */ ++ u32 itr; ++ u32 itr_setting; ++ u16 tx_itr; ++ u16 rx_itr; + -+static u32 e1000_get_rx_csum(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ return (adapter->flags & FLAG_RX_CSUM_ENABLED); -+} ++ /* ++ * Tx ++ */ ++ struct e1000_ring *tx_ring /* One per active queue */ ++ ____cacheline_aligned_in_smp; + -+static int e1000_set_rx_csum(struct net_device *netdev, u32 data) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++#ifdef CONFIG_E1000E_NAPI ++ struct napi_struct napi; ++#endif + -+ if (data) -+ adapter->flags |= FLAG_RX_CSUM_ENABLED; -+ else -+ adapter->flags &= ~FLAG_RX_CSUM_ENABLED; ++ unsigned long tx_queue_len; ++ unsigned int restart_queue; ++ u32 txd_cmd; + -+ if (netif_running(netdev)) -+ e1000e_reinit_locked(adapter); -+ else -+ e1000e_reset(adapter); -+ return 0; -+} ++ bool detect_tx_hung; ++ u8 tx_timeout_factor; + -+static u32 e1000_get_tx_csum(struct net_device *netdev) -+{ -+ return ((netdev->features & NETIF_F_HW_CSUM) != 0); -+} ++ u32 tx_int_delay; ++ u32 tx_abs_int_delay; + -+static int e1000_set_tx_csum(struct net_device *netdev, u32 data) -+{ -+ if (data) -+ netdev->features |= NETIF_F_HW_CSUM; -+ else -+ netdev->features &= ~NETIF_F_HW_CSUM; ++ unsigned int total_tx_bytes; ++ unsigned int total_tx_packets; ++ unsigned int total_rx_bytes; ++ unsigned int total_rx_packets; + -+ return 0; -+} ++ /* Tx stats */ ++ u64 tpt_old; ++ u64 colc_old; ++ u32 gotc; ++ u64 gotc_old; ++ u32 tx_timeout_count; ++ u32 tx_fifo_head; ++ u32 tx_head_addr; ++ u32 tx_fifo_size; ++ u32 tx_dma_failed; + -+static int e1000_set_tso(struct net_device *netdev, u32 data) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ /* ++ * Rx ++ */ ++#ifdef CONFIG_E1000E_NAPI ++ bool (*clean_rx) (struct e1000_adapter *adapter, ++ int *work_done, int work_to_do) ++ ____cacheline_aligned_in_smp; ++#else ++ bool (*clean_rx) (struct e1000_adapter *adapter) ++ ____cacheline_aligned_in_smp; ++#endif ++ void (*alloc_rx_buf) (struct e1000_adapter *adapter, ++ int cleaned_count); ++ struct e1000_ring *rx_ring; + -+ if (data) { -+ netdev->features |= NETIF_F_TSO; -+ netdev->features |= NETIF_F_TSO6; -+ } else { -+ netdev->features &= ~NETIF_F_TSO; -+ netdev->features &= ~NETIF_F_TSO6; -+ } ++ u32 rx_int_delay; ++ u32 rx_abs_int_delay; + -+ ndev_info(netdev, "TSO is %s\n", -+ data ? "Enabled" : "Disabled"); -+ adapter->flags |= FLAG_TSO_FORCE; -+ return 0; -+} ++ /* Rx stats */ ++ u64 hw_csum_err; ++ u64 hw_csum_good; ++ u64 rx_hdr_split; ++ u32 gorc; ++ u64 gorc_old; ++ u32 alloc_rx_buff_failed; ++ u32 rx_dma_failed; + -+static u32 e1000_get_msglevel(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ return adapter->msg_enable; -+} ++ unsigned int rx_ps_pages; ++ u16 rx_ps_bsize0; ++ u32 max_frame_size; ++ u32 min_frame_size; + -+static void e1000_set_msglevel(struct net_device *netdev, u32 data) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ adapter->msg_enable = data; -+} ++ /* OS defined structs */ ++ struct net_device *netdev; ++ struct pci_dev *pdev; ++ struct net_device_stats net_stats; ++ spinlock_t stats_lock; /* prevent concurrent stats updates */ + -+static int e1000_get_regs_len(struct net_device *netdev) -+{ -+#define E1000_REGS_LEN 32 /* overestimate */ -+ return E1000_REGS_LEN * sizeof(u32); -+} ++ /* structs defined in e1000_hw.h */ ++ struct e1000_hw hw; + -+static void e1000_get_regs(struct net_device *netdev, -+ struct ethtool_regs *regs, void *p) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u32 *regs_buff = p; -+ u16 phy_data; -+ u8 revision_id; ++ struct e1000_hw_stats stats; ++ struct e1000_phy_info phy_info; ++ struct e1000_phy_stats phy_stats; + -+ memset(p, 0, E1000_REGS_LEN * sizeof(u32)); ++#ifdef SIOCGMIIPHY ++ /* Snapshot of PHY registers */ ++ struct e1000_phy_regs phy_regs; ++#endif + -+ pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); ++ struct e1000_ring test_tx_ring; ++ struct e1000_ring test_rx_ring; ++ u32 test_icr; + -+ regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; ++ u32 msg_enable; ++#ifdef CONFIG_E1000E_MSIX ++ struct msix_entry *msix_entries; ++ int int_mode; ++ u32 eiac_mask; ++#endif /* CONFIG_E1000E_MSIX */ + -+ regs_buff[0] = er32(CTRL); -+ regs_buff[1] = er32(STATUS); ++ u32 eeprom_wol; ++ u32 wol; ++ u32 pba; + -+ regs_buff[2] = er32(RCTL); -+ regs_buff[3] = er32(RDLEN); -+ regs_buff[4] = er32(RDH); -+ regs_buff[5] = er32(RDT); -+ regs_buff[6] = er32(RDTR); ++ bool fc_autoneg; + -+ regs_buff[7] = er32(TCTL); -+ regs_buff[8] = er32(TDLEN); -+ regs_buff[9] = er32(TDH); -+ regs_buff[10] = er32(TDT); -+ regs_buff[11] = er32(TIDV); ++ unsigned long led_status; + -+ regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ -+ if (hw->phy.type == e1000_phy_m88) { -+ e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); -+ regs_buff[13] = (u32)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) */ -+ e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ regs_buff[17] = (u32)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) */ -+ regs_buff[20] = regs_buff[17]; /* polarity correction */ -+ /* phy receive errors */ -+ regs_buff[22] = adapter->phy_stats.receive_errors; -+ regs_buff[23] = regs_buff[13]; /* mdix mode */ -+ } -+ regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ -+ e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); -+ regs_buff[24] = (u32)phy_data; /* phy local receiver status */ -+ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ -+} ++ unsigned int flags; ++ unsigned int flags2; ++ u32 *config_space; ++ u32 stats_freq_us; /* stats update freq (microseconds) */ ++}; + -+static int e1000_get_eeprom_len(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ return adapter->hw.nvm.word_size * 2; -+} ++struct e1000_info { ++ e1000_mac_type mac; ++ unsigned int flags; ++ unsigned int flags2; ++ u32 pba; ++ void (*init_ops)(struct e1000_hw *); ++ s32 (*get_variants)(struct e1000_adapter *); ++}; + -+static int e1000_get_eeprom(struct net_device *netdev, -+ struct ethtool_eeprom *eeprom, u8 *bytes) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u16 *eeprom_buff; -+ int first_word; -+ int last_word; -+ int ret_val = 0; -+ u16 i; ++/* hardware capability, feature, and workaround flags */ ++#define FLAG_HAS_AMT (1 << 0) ++#define FLAG_HAS_FLASH (1 << 1) ++#define FLAG_HAS_HW_VLAN_FILTER (1 << 2) ++#define FLAG_HAS_WOL (1 << 3) ++#define FLAG_HAS_ERT (1 << 4) ++#define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) ++#define FLAG_HAS_SWSM_ON_LOAD (1 << 6) ++#define FLAG_HAS_JUMBO_FRAMES (1 << 7) ++#define FLAG_HAS_ASPM (1 << 8) ++#define FLAG_IS_ICH (1 << 9) ++#define FLAG_HAS_MSIX (1 << 10) ++#define FLAG_HAS_SMART_POWER_DOWN (1 << 11) ++#define FLAG_IS_QUAD_PORT_A (1 << 12) ++#define FLAG_IS_QUAD_PORT (1 << 13) ++#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN (1 << 14) ++#define FLAG_APME_IN_WUC (1 << 15) ++#define FLAG_APME_IN_CTRL3 (1 << 16) ++#define FLAG_APME_CHECK_PORT_B (1 << 17) ++#define FLAG_DISABLE_FC_PAUSE_TIME (1 << 18) ++#define FLAG_NO_WAKE_UCAST (1 << 19) ++#define FLAG_MNG_PT_ENABLED (1 << 20) ++#define FLAG_RESET_OVERWRITES_LAA (1 << 21) ++#define FLAG_TARC_SPEED_MODE_BIT (1 << 22) ++#define FLAG_TARC_SET_BIT_ZERO (1 << 23) ++#define FLAG_RX_NEEDS_RESTART (1 << 24) ++#define FLAG_LSC_GIG_SPEED_DROP (1 << 25) ++#define FLAG_SMART_POWER_DOWN (1 << 26) ++#define FLAG_MSI_ENABLED (1 << 27) ++#define FLAG_RX_CSUM_ENABLED (1 << 28) ++#define FLAG_TSO_FORCE (1 << 29) ++#define FLAG_MSI_TEST_FAILED (1 << 30) ++#define FLAG_RX_RESTART_NOW (1 << 31) + -+ if (eeprom->len == 0) -+ return -EINVAL; ++#define FLAG2_READ_ONLY_NVM (1 << 1) + -+ eeprom->magic = adapter->pdev->vendor | (adapter->pdev->device << 16); ++#define E1000_RX_DESC_PS(R, i) \ ++ (&(((union e1000_rx_desc_packet_split *)((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) ++#define E1000_CONTEXT_DESC(R, i) E1000_GET_DESC(R, i, e1000_context_desc) + -+ first_word = eeprom->offset >> 1; -+ last_word = (eeprom->offset + eeprom->len - 1) >> 1; ++enum e1000_state_t { ++ __E1000_TESTING, ++ __E1000_RESETTING, ++ __E1000_DOWN ++}; + -+ eeprom_buff = kmalloc(sizeof(u16) * -+ (last_word - first_word + 1), GFP_KERNEL); -+ if (!eeprom_buff) -+ return -ENOMEM; ++enum latency_range { ++ lowest_latency = 0, ++ low_latency = 1, ++ bulk_latency = 2, ++ latency_invalid = 255 ++}; + -+ if (hw->nvm.type == e1000_nvm_eeprom_spi) { -+ ret_val = e1000_read_nvm(hw, first_word, -+ last_word - first_word + 1, -+ eeprom_buff); -+ } else { -+ for (i = 0; i < last_word - first_word + 1; i++) { -+ ret_val = e1000_read_nvm(hw, first_word + i, 1, -+ &eeprom_buff[i]); -+ if (ret_val) -+ break; -+ } -+ } ++extern char e1000e_driver_name[]; ++extern const char e1000e_driver_version[]; + -+ /* Device's eeprom is always little-endian, word addressable */ -+ for (i = 0; i < last_word - first_word + 1; i++) -+ le16_to_cpus(&eeprom_buff[i]); ++extern void e1000_check_options(struct e1000_adapter *adapter); ++extern void e1000_set_ethtool_ops(struct net_device *netdev); ++#ifdef ETHTOOL_OPS_COMPAT ++extern int ethtool_ioctl(struct ifreq *ifr); ++#endif + -+ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); -+ kfree(eeprom_buff); ++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_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 void e1000_update_stats(struct e1000_adapter *adapter); ++#ifdef CONFIG_E1000E_MSIX ++extern void e1000_set_interrupt_capability(struct e1000_adapter *adapter); ++extern void e1000_reset_interrupt_capability(struct e1000_adapter *adapter); ++#endif + -+ return ret_val; ++extern unsigned int copybreak; ++ ++static inline u32 __er32(struct e1000_hw *hw, unsigned long reg) ++{ ++ return readl(hw->hw_addr + reg); +} + -+static int e1000_set_eeprom(struct net_device *netdev, -+ struct ethtool_eeprom *eeprom, u8 *bytes) ++static inline void __ew32(struct e1000_hw *hw, unsigned long reg, u32 val) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u16 *eeprom_buff; -+ void *ptr; -+ int max_len; -+ int first_word; -+ int last_word; -+ int ret_val = 0; -+ u16 i; ++ writel(val, hw->hw_addr + reg); ++} ++#define er32(reg) E1000_READ_REG(hw, E1000_##reg) ++#define ew32(reg,val) E1000_WRITE_REG(hw, E1000_##reg, (val)) ++#define e1e_flush() er32(STATUS) + -+ if (eeprom->len == 0) -+ return -EOPNOTSUPP; ++extern void e1000_init_function_pointers_82571(struct e1000_hw *hw); ++extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw); ++extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); + -+ if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) -+ return -EFAULT; ++static inline s32 e1000_read_mac_addr(struct e1000_hw *hw) ++{ ++ if (hw->mac.ops.read_mac_addr) ++ return hw->mac.ops.read_mac_addr(hw); + -+ max_len = hw->nvm.word_size * 2; ++ return e1000_read_mac_addr_generic(hw); ++} + -+ first_word = eeprom->offset >> 1; -+ last_word = (eeprom->offset + eeprom->len - 1) >> 1; -+ eeprom_buff = kmalloc(max_len, GFP_KERNEL); -+ if (!eeprom_buff) -+ return -ENOMEM; ++static inline void e1000_power_up_phy(struct e1000_hw *hw) ++{ ++ if(hw->phy.ops.power_up) ++ hw->phy.ops.power_up(hw); ++ hw->mac.ops.setup_link(hw); ++} + -+ ptr = (void *)eeprom_buff; ++#endif /* _E1000_H_ */ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_hw.h linux-2.6.22-10/drivers/net/e1000e/e1000_hw.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_hw.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_hw.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,671 @@ ++/******************************************************************************* + -+ 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_nvm(hw, first_word, 1, &eeprom_buff[0]); -+ ptr++; -+ } -+ 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_nvm(hw, last_word, 1, -+ &eeprom_buff[last_word - first_word]); ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ /* Device's eeprom is always little-endian, word addressable */ -+ for (i = 0; i < last_word - first_word + 1; i++) -+ le16_to_cpus(&eeprom_buff[i]); ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ memcpy(ptr, bytes, eeprom->len); ++ This program is distributed in the hope 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. + -+ for (i = 0; i < last_word - first_word + 1; i++) -+ eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ ret_val = e1000_write_nvm(hw, first_word, -+ last_word - first_word + 1, eeprom_buff); ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ /* Update the checksum over the first part of the EEPROM if needed -+ * and flush shadow RAM for 82573 controllers */ -+ if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) || -+ (hw->mac.type == e1000_82573))) -+ e1000e_update_nvm_checksum(hw); ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ kfree(eeprom_buff); -+ return ret_val; -+} ++*******************************************************************************/ + -+static void e1000_get_drvinfo(struct net_device *netdev, -+ struct ethtool_drvinfo *drvinfo) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ char firmware_version[32]; -+ u16 eeprom_data; ++#ifndef _E1000_HW_H_ ++#define _E1000_HW_H_ + -+ strncpy(drvinfo->driver, e1000e_driver_name, 32); -+ strncpy(drvinfo->version, e1000e_driver_version, 32); ++#include "e1000_osdep.h" ++#include "e1000_regs.h" ++#include "e1000_defines.h" + -+ /* EEPROM image version # is reported as firmware version # for -+ * PCI-E controllers */ -+ e1000_read_nvm(&adapter->hw, 5, 1, &eeprom_data); -+ sprintf(firmware_version, "%d.%d-%d", -+ (eeprom_data & 0xF000) >> 12, -+ (eeprom_data & 0x0FF0) >> 4, -+ eeprom_data & 0x000F); ++struct e1000_hw; + -+ 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; -+ drvinfo->regdump_len = e1000_get_regs_len(netdev); -+ drvinfo->eedump_len = e1000_get_eeprom_len(netdev); -+} ++#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_SERDES_DUAL 0x10D9 ++#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA ++#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4 ++#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5 ++#define E1000_DEV_ID_82571EB_QUAD_FIBER 0x10A5 ++#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC ++#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_82574L 0x10D3 ++#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_IFE_GT 0x10C4 ++#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 ++#define E1000_DEV_ID_ICH8_IGP_M 0x104D ++#define E1000_DEV_ID_ICH9_IGP_M 0x10BF ++#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 ++#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB ++#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD ++#define E1000_DEV_ID_ICH9_BM 0x10E5 ++#define E1000_DEV_ID_ICH9_IGP_C 0x294C ++#define E1000_DEV_ID_ICH9_IFE 0x10C0 ++#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 ++#define E1000_DEV_ID_ICH9_IFE_G 0x10C2 ++#define E1000_DEV_ID_ICH10_R_BM_LM 0x10CC ++#define E1000_DEV_ID_ICH10_R_BM_LF 0x10CD ++#define E1000_DEV_ID_ICH10_R_BM_V 0x10CE ++#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE ++#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF ++ ++#define E1000_REVISION_0 0 ++#define E1000_REVISION_1 1 ++#define E1000_REVISION_2 2 ++#define E1000_REVISION_3 3 ++#define E1000_REVISION_4 4 ++ ++#define E1000_FUNC_0 0 ++#define E1000_FUNC_1 1 ++ ++typedef enum { ++ e1000_undefined = 0, ++ e1000_82571, ++ e1000_82572, ++ e1000_82573, ++ e1000_82574, ++ e1000_80003es2lan, ++ e1000_ich8lan, ++ e1000_ich9lan, ++ e1000_ich10lan, ++ e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ ++} e1000_mac_type; + -+static void e1000_get_ringparam(struct net_device *netdev, -+ struct ethtool_ringparam *ring) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_ring *rx_ring = adapter->rx_ring; ++typedef enum { ++ e1000_media_type_unknown = 0, ++ e1000_media_type_copper = 1, ++ e1000_media_type_fiber = 2, ++ e1000_media_type_internal_serdes = 3, ++ e1000_num_media_types ++} e1000_media_type; + -+ ring->rx_max_pending = E1000_MAX_RXD; -+ ring->tx_max_pending = E1000_MAX_TXD; -+ ring->rx_mini_max_pending = 0; -+ ring->rx_jumbo_max_pending = 0; -+ ring->rx_pending = rx_ring->count; -+ ring->tx_pending = tx_ring->count; -+ ring->rx_mini_pending = 0; -+ ring->rx_jumbo_pending = 0; -+} ++typedef enum { ++ e1000_nvm_unknown = 0, ++ e1000_nvm_none, ++ e1000_nvm_eeprom_spi, ++ e1000_nvm_eeprom_microwire, ++ e1000_nvm_flash_hw, ++ e1000_nvm_flash_sw ++} e1000_nvm_type; + -+static int e1000_set_ringparam(struct net_device *netdev, -+ struct ethtool_ringparam *ring) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_ring *tx_ring, *tx_old; -+ struct e1000_ring *rx_ring, *rx_old; -+ int err; ++typedef enum { ++ e1000_nvm_override_none = 0, ++ e1000_nvm_override_spi_small, ++ e1000_nvm_override_spi_large, ++ e1000_nvm_override_microwire_small, ++ e1000_nvm_override_microwire_large ++} e1000_nvm_override; + -+ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) -+ return -EINVAL; -+ -+ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) -+ msleep(1); -+ -+ if (netif_running(adapter->netdev)) -+ e1000e_down(adapter); -+ -+ tx_old = adapter->tx_ring; -+ rx_old = adapter->rx_ring; -+ -+ err = -ENOMEM; -+ tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); -+ if (!tx_ring) -+ goto err_alloc_tx; -+ -+ rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); -+ if (!rx_ring) -+ goto err_alloc_rx; -+ -+ adapter->tx_ring = tx_ring; -+ adapter->rx_ring = rx_ring; -+ -+ rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD); -+ rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD)); -+ rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); -+ -+ tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD); -+ tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD)); -+ tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); ++typedef enum { ++ e1000_phy_unknown = 0, ++ e1000_phy_none, ++ e1000_phy_m88, ++ e1000_phy_igp, ++ e1000_phy_igp_2, ++ e1000_phy_gg82563, ++ e1000_phy_igp_3, ++ e1000_phy_ife, ++ e1000_phy_bm, ++} e1000_phy_type; ++ ++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; ++ ++typedef enum { ++ e1000_bus_speed_unknown = 0, ++ e1000_bus_speed_33, ++ e1000_bus_speed_66, ++ e1000_bus_speed_100, ++ e1000_bus_speed_120, ++ e1000_bus_speed_133, ++ e1000_bus_speed_2500, ++ e1000_bus_speed_5000, ++ e1000_bus_speed_reserved ++} e1000_bus_speed; ++ ++typedef enum { ++ e1000_bus_width_unknown = 0, ++ e1000_bus_width_pcie_x1, ++ e1000_bus_width_pcie_x2, ++ e1000_bus_width_pcie_x4 = 4, ++ e1000_bus_width_pcie_x8 = 8, ++ e1000_bus_width_32, ++ e1000_bus_width_64, ++ e1000_bus_width_reserved ++} e1000_bus_width; + -+ if (netif_running(adapter->netdev)) { -+ /* Try to get new resources before deleting old */ -+ err = e1000e_setup_rx_resources(adapter); -+ if (err) -+ goto err_setup_rx; -+ err = e1000e_setup_tx_resources(adapter); -+ if (err) -+ goto err_setup_tx; ++typedef enum { ++ e1000_1000t_rx_status_not_ok = 0, ++ e1000_1000t_rx_status_ok, ++ e1000_1000t_rx_status_undefined = 0xFF ++} e1000_1000t_rx_status; + -+ /* save the new, restore the old in order to free it, -+ * then restore the new back again */ -+ adapter->rx_ring = rx_old; -+ adapter->tx_ring = tx_old; -+ e1000e_free_rx_resources(adapter); -+ e1000e_free_tx_resources(adapter); -+ kfree(tx_old); -+ kfree(rx_old); -+ adapter->rx_ring = rx_ring; -+ adapter->tx_ring = tx_ring; -+ err = e1000e_up(adapter); -+ if (err) -+ goto err_setup; -+ } ++typedef enum { ++ e1000_rev_polarity_normal = 0, ++ e1000_rev_polarity_reversed, ++ e1000_rev_polarity_undefined = 0xFF ++} e1000_rev_polarity; + -+ clear_bit(__E1000_RESETTING, &adapter->state); -+ return 0; -+err_setup_tx: -+ e1000e_free_rx_resources(adapter); -+err_setup_rx: -+ adapter->rx_ring = rx_old; -+ adapter->tx_ring = tx_old; -+ kfree(rx_ring); -+err_alloc_rx: -+ kfree(tx_ring); -+err_alloc_tx: -+ e1000e_up(adapter); -+err_setup: -+ clear_bit(__E1000_RESETTING, &adapter->state); -+ return err; -+} ++typedef enum { ++ e1000_fc_none = 0, ++ e1000_fc_rx_pause, ++ e1000_fc_tx_pause, ++ e1000_fc_full, ++ e1000_fc_default = 0xFF ++} e1000_fc_type; + -+#define REG_PATTERN_TEST(R, M, W) REG_PATTERN_TEST_ARRAY(R, 0, M, W) -+#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, writeable) \ -+{ \ -+ u32 _pat; \ -+ u32 _value; \ -+ u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \ -+ for (_pat = 0; _pat < ARRAY_SIZE(_test); _pat++) { \ -+ E1000_WRITE_REG_ARRAY(hw, reg, offset, \ -+ (_test[_pat] & writeable)); \ -+ _value = E1000_READ_REG_ARRAY(hw, reg, offset); \ -+ if (_value != (_test[_pat] & writeable & mask)) { \ -+ ndev_err(netdev, "pattern test reg %04X " \ -+ "failed: got 0x%08X expected 0x%08X\n", \ -+ reg + offset, \ -+ value, (_test[_pat] & writeable & mask)); \ -+ *data = reg; \ -+ return 1; \ -+ } \ -+ } \ -+} -+ -+#define REG_SET_AND_CHECK(R, M, W) \ -+{ \ -+ u32 _value; \ -+ __ew32(hw, R, W & M); \ -+ _value = __er32(hw, R); \ -+ if ((W & M) != (_value & M)) { \ -+ ndev_err(netdev, "set/check reg %04X test failed: " \ -+ "got 0x%08X expected 0x%08X\n", R, (_value & M), \ -+ (W & M)); \ -+ *data = R; \ -+ return 1; \ -+ } \ -+} + -+static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_mac_info *mac = &adapter->hw.mac; -+ struct net_device *netdev = adapter->netdev; -+ u32 value; -+ u32 before; -+ u32 after; -+ u32 i; -+ u32 toggle; ++/* Receive Descriptor */ ++struct e1000_rx_desc { ++ u64 buffer_addr; /* Address of the descriptor's data buffer */ ++ u16 length; /* Length of data DMAed into data buffer */ ++ u16 csum; /* Packet checksum */ ++ u8 status; /* Descriptor status */ ++ u8 errors; /* Descriptor Errors */ ++ u16 special; ++}; + -+ /* The status register is Read Only, so a write should fail. -+ * Some bits that get toggled are ignored. -+ */ -+ switch (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: -+ case e1000_ich9lan: -+ toggle = 0x7FFFF033; -+ break; -+ default: -+ toggle = 0xFFFFF833; -+ break; -+ } ++/* Receive Descriptor - Extended */ ++union e1000_rx_desc_extended { ++ struct { ++ u64 buffer_addr; ++ u64 reserved; ++ } read; ++ struct { ++ struct { ++ u32 mrq; /* Multiple Rx Queues */ ++ union { ++ u32 rss; /* RSS Hash */ ++ struct { ++ u16 ip_id; /* IP id */ ++ u16 csum; /* Packet Checksum */ ++ } csum_ip; ++ } hi_dword; ++ } lower; ++ struct { ++ u32 status_error; /* ext status/error */ ++ u16 length; ++ u16 vlan; /* VLAN tag */ ++ } upper; ++ } wb; /* writeback */ ++}; + -+ before = er32(STATUS); -+ value = (er32(STATUS) & toggle); -+ ew32(STATUS, toggle); -+ after = er32(STATUS) & toggle; -+ if (value != after) { -+ ndev_err(netdev, "failed STATUS register test got: " -+ "0x%08X expected: 0x%08X\n", after, value); -+ *data = 1; -+ return 1; -+ } -+ /* restore previous status */ -+ ew32(STATUS, before); ++#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 */ ++ u64 buffer_addr[MAX_PS_BUFFERS]; ++ } read; ++ struct { ++ struct { ++ u32 mrq; /* Multiple Rx Queues */ ++ union { ++ u32 rss; /* RSS Hash */ ++ struct { ++ u16 ip_id; /* IP id */ ++ u16 csum; /* Packet Checksum */ ++ } csum_ip; ++ } hi_dword; ++ } lower; ++ struct { ++ u32 status_error; /* ext status/error */ ++ u16 length0; /* length of buffer 0 */ ++ u16 vlan; /* VLAN tag */ ++ } middle; ++ struct { ++ u16 header_status; ++ u16 length[3]; /* length of buffers 1-3 */ ++ } upper; ++ u64 reserved; ++ } wb; /* writeback */ ++}; + -+ if ((mac->type != e1000_ich8lan) && -+ (mac->type != e1000_ich9lan)) { -+ REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_VET, 0x0000FFFF, 0xFFFFFFFF); -+ } ++/* Transmit Descriptor */ ++struct e1000_tx_desc { ++ u64 buffer_addr; /* Address of the descriptor's data buffer */ ++ union { ++ u32 data; ++ struct { ++ u16 length; /* Data buffer length */ ++ u8 cso; /* Checksum offset */ ++ u8 cmd; /* Descriptor control */ ++ } flags; ++ } lower; ++ union { ++ u32 data; ++ struct { ++ u8 status; /* Descriptor status */ ++ u8 css; /* Checksum start */ ++ u16 special; ++ } fields; ++ } upper; ++}; + -+ REG_PATTERN_TEST(E1000_RDTR, 0x0000FFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_RDBAH, 0xFFFFFFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_RDLEN, 0x000FFF80, 0x000FFFFF); -+ REG_PATTERN_TEST(E1000_RDH, 0x0000FFFF, 0x0000FFFF); -+ REG_PATTERN_TEST(E1000_RDT, 0x0000FFFF, 0x0000FFFF); -+ REG_PATTERN_TEST(E1000_FCRTH, 0x0000FFF8, 0x0000FFF8); -+ REG_PATTERN_TEST(E1000_FCTTV, 0x0000FFFF, 0x0000FFFF); -+ REG_PATTERN_TEST(E1000_TIPG, 0x3FFFFFFF, 0x3FFFFFFF); -+ REG_PATTERN_TEST(E1000_TDBAH, 0xFFFFFFFF, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_TDLEN, 0x000FFF80, 0x000FFFFF); ++/* Offload Context Descriptor */ ++struct e1000_context_desc { ++ union { ++ u32 ip_config; ++ struct { ++ u8 ipcss; /* IP checksum start */ ++ u8 ipcso; /* IP checksum offset */ ++ u16 ipcse; /* IP checksum end */ ++ } ip_fields; ++ } lower_setup; ++ union { ++ u32 tcp_config; ++ struct { ++ u8 tucss; /* TCP checksum start */ ++ u8 tucso; /* TCP checksum offset */ ++ u16 tucse; /* TCP checksum end */ ++ } tcp_fields; ++ } upper_setup; ++ u32 cmd_and_length; ++ union { ++ u32 data; ++ struct { ++ u8 status; /* Descriptor status */ ++ u8 hdr_len; /* Header length */ ++ u16 mss; /* Maximum segment size */ ++ } fields; ++ } tcp_seg_setup; ++}; + -+ REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); ++/* Offload data descriptor */ ++struct e1000_data_desc { ++ u64 buffer_addr; /* Address of the descriptor's buffer address */ ++ union { ++ u32 data; ++ struct { ++ u16 length; /* Data buffer length */ ++ u8 typ_len_ext; ++ u8 cmd; ++ } flags; ++ } lower; ++ union { ++ u32 data; ++ struct { ++ u8 status; /* Descriptor status */ ++ u8 popts; /* Packet Options */ ++ u16 special; ++ } fields; ++ } upper; ++}; + -+ before = (((mac->type == e1000_ich8lan) || -+ (mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE); -+ REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); -+ REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); ++/* Statistics counters collected by the MAC */ ++struct e1000_hw_stats { ++ u64 crcerrs; ++ u64 algnerrc; ++ u64 symerrs; ++ u64 rxerrc; ++ u64 mpc; ++ u64 scc; ++ u64 ecol; ++ u64 mcc; ++ u64 latecol; ++ u64 colc; ++ u64 dc; ++ u64 tncrs; ++ u64 sec; ++ u64 cexterr; ++ u64 rlec; ++ u64 xonrxc; ++ u64 xontxc; ++ u64 xoffrxc; ++ u64 xofftxc; ++ u64 fcruc; ++ u64 prc64; ++ u64 prc127; ++ u64 prc255; ++ u64 prc511; ++ u64 prc1023; ++ u64 prc1522; ++ u64 gprc; ++ u64 bprc; ++ u64 mprc; ++ u64 gptc; ++ u64 gorc; ++ u64 gotc; ++ u64 rnbc; ++ u64 ruc; ++ u64 rfc; ++ u64 roc; ++ u64 rjc; ++ u64 mgprc; ++ u64 mgpdc; ++ u64 mgptc; ++ u64 tor; ++ u64 tot; ++ u64 tpr; ++ u64 tpt; ++ u64 ptc64; ++ u64 ptc127; ++ u64 ptc255; ++ u64 ptc511; ++ u64 ptc1023; ++ u64 ptc1522; ++ u64 mptc; ++ u64 bptc; ++ u64 tsctc; ++ u64 tsctfc; ++ u64 iac; ++ u64 icrxptc; ++ u64 icrxatc; ++ u64 ictxptc; ++ u64 ictxatc; ++ u64 ictxqec; ++ u64 ictxqmtc; ++ u64 icrxdmtc; ++ u64 icrxoc; ++ u64 cbtmpc; ++ u64 htdpmc; ++ u64 cbrdpc; ++ u64 cbrmpc; ++ u64 rpthc; ++ u64 hgptc; ++ u64 htcbdpc; ++ u64 hgorc; ++ u64 hgotc; ++ u64 lenerrs; ++ u64 scvpc; ++ u64 hrmpc; ++}; + -+ REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x01FFFFFF); -+ REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFF000, 0xFFFFFFFF); -+ REG_PATTERN_TEST(E1000_TXCW, 0x0000FFFF, 0x0000FFFF); -+ REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFF000, 0xFFFFFFFF); ++struct e1000_phy_stats { ++ u32 idle_errors; ++ u32 receive_errors; ++}; + -+ for (i = 0; i < mac->mta_reg_count; i++) -+ REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF); ++struct e1000_host_mng_dhcp_cookie { ++ u32 signature; ++ u8 status; ++ u8 reserved0; ++ u16 vlan_id; ++ u32 reserved1; ++ u16 reserved2; ++ u8 reserved3; ++ u8 checksum; ++}; + -+ *data = 0; -+ return 0; -+} ++/* Host Interface "Rev 1" */ ++struct e1000_host_command_header { ++ u8 command_id; ++ u8 command_length; ++ u8 command_options; ++ u8 checksum; ++}; + -+static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) -+{ -+ u16 temp; -+ u16 checksum = 0; -+ u16 i; ++#define E1000_HI_MAX_DATA_LENGTH 252 ++struct e1000_host_command_info { ++ struct e1000_host_command_header command_header; ++ u8 command_data[E1000_HI_MAX_DATA_LENGTH]; ++}; + -+ *data = 0; -+ /* Read and add up the contents of the EEPROM */ -+ for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { -+ if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) { -+ *data = 1; -+ break; -+ } -+ checksum += temp; -+ } ++/* Host Interface "Rev 2" */ ++struct e1000_host_mng_command_header { ++ u8 command_id; ++ u8 checksum; ++ u16 reserved1; ++ u16 reserved2; ++ u16 command_length; ++}; + -+ /* If Checksum is not Correct return error else test passed */ -+ if ((checksum != (u16) NVM_SUM) && !(*data)) -+ *data = 2; ++#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 ++struct e1000_host_mng_command_info { ++ struct e1000_host_mng_command_header command_header; ++ u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; ++}; + -+ return *data; -+} ++#include "e1000_mac.h" ++#include "e1000_phy.h" ++#include "e1000_nvm.h" ++#include "e1000_manage.h" + -+static irqreturn_t e1000_test_intr(int irq, void *data) -+{ -+ struct net_device *netdev = (struct net_device *) data; -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; ++struct e1000_mac_operations { ++ /* Function pointers for the MAC. */ ++ s32 (*init_params)(struct e1000_hw *); ++ s32 (*blink_led)(struct e1000_hw *); ++ s32 (*check_for_link)(struct e1000_hw *); ++ bool (*check_mng_mode)(struct e1000_hw *hw); ++ s32 (*cleanup_led)(struct e1000_hw *); ++ void (*clear_hw_cntrs)(struct e1000_hw *); ++ void (*clear_vfta)(struct e1000_hw *); ++ s32 (*get_bus_info)(struct e1000_hw *); ++ s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); ++ s32 (*led_on)(struct e1000_hw *); ++ s32 (*led_off)(struct e1000_hw *); ++ void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, ++ u32); ++ void (*remove_device)(struct e1000_hw *); ++ s32 (*reset_hw)(struct e1000_hw *); ++ s32 (*init_hw)(struct e1000_hw *); ++ s32 (*setup_link)(struct e1000_hw *); ++ s32 (*setup_physical_interface)(struct e1000_hw *); ++ s32 (*setup_led)(struct e1000_hw *); ++ void (*write_vfta)(struct e1000_hw *, u32, u32); ++ void (*mta_set)(struct e1000_hw *, u32); ++ void (*config_collision_dist)(struct e1000_hw*); ++ void (*rar_set)(struct e1000_hw*, u8*, u32); ++ s32 (*read_mac_addr)(struct e1000_hw*); ++ s32 (*validate_mdi_setting)(struct e1000_hw*); ++ s32 (*mng_host_if_write)(struct e1000_hw*, u8*, u16, u16, u8*); ++ s32 (*mng_write_cmd_header)(struct e1000_hw *hw, ++ struct e1000_host_mng_command_header*); ++ s32 (*mng_enable_host_if)(struct e1000_hw*); ++ s32 (*wait_autoneg)(struct e1000_hw*); ++}; + -+ adapter->test_icr |= er32(ICR); ++struct e1000_phy_operations { ++ s32 (*init_params)(struct e1000_hw *); ++ s32 (*acquire)(struct e1000_hw *); ++ s32 (*cfg_on_link_up)(struct e1000_hw *); ++ s32 (*check_polarity)(struct e1000_hw *); ++ s32 (*check_reset_block)(struct e1000_hw *); ++ s32 (*commit)(struct e1000_hw *); ++ s32 (*force_speed_duplex)(struct e1000_hw *); ++ s32 (*get_cfg_done)(struct e1000_hw *hw); ++ s32 (*get_cable_length)(struct e1000_hw *); ++ s32 (*get_info)(struct e1000_hw *); ++ s32 (*read_reg)(struct e1000_hw *, u32, u16 *); ++ void (*release)(struct e1000_hw *); ++ s32 (*reset)(struct e1000_hw *); ++ s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); ++ s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); ++ s32 (*write_reg)(struct e1000_hw *, u32, u16); ++ void (*power_up)(struct e1000_hw *); ++ void (*power_down)(struct e1000_hw *); ++}; + -+ return IRQ_HANDLED; -+} ++struct e1000_nvm_operations { ++ s32 (*init_params)(struct e1000_hw *); ++ s32 (*acquire)(struct e1000_hw *); ++ s32 (*read)(struct e1000_hw *, u16, u16, u16 *); ++ void (*release)(struct e1000_hw *); ++ void (*reload)(struct e1000_hw *); ++ s32 (*update)(struct e1000_hw *); ++ s32 (*valid_led_default)(struct e1000_hw *, u16 *); ++ s32 (*validate)(struct e1000_hw *); ++ s32 (*write)(struct e1000_hw *, u16, u16, u16 *); ++}; + -+static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) -+{ -+ struct net_device *netdev = adapter->netdev; -+ struct e1000_hw *hw = &adapter->hw; -+ u32 mask; -+ u32 shared_int = 1; -+ u32 irq = adapter->pdev->irq; -+ int i; ++struct e1000_mac_info { ++ struct e1000_mac_operations ops; ++ u8 addr[6]; ++ u8 perm_addr[6]; + -+ *data = 0; ++ e1000_mac_type type; + -+ /* NOTE: we don't test MSI interrupts here, yet */ -+ /* Hook up test interrupt handler just for this test */ -+ if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, -+ netdev)) { -+ shared_int = 0; -+ } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, -+ netdev->name, netdev)) { -+ *data = 1; -+ return -1; -+ } -+ ndev_info(netdev, "testing %s interrupt\n", -+ (shared_int ? "shared" : "unshared")); ++ u32 collision_delta; ++ u32 ledctl_default; ++ u32 ledctl_mode1; ++ u32 ledctl_mode2; ++ u32 mc_filter_type; ++ u32 tx_packet_delta; ++ u32 txcw; + -+ /* Disable all the interrupts */ -+ ew32(IMC, 0xFFFFFFFF); -+ msleep(10); ++ u16 current_ifs_val; ++ u16 ifs_max_val; ++ u16 ifs_min_val; ++ u16 ifs_ratio; ++ u16 ifs_step_size; ++ u16 mta_reg_count; ++ u16 rar_entry_count; + -+ /* Test each interrupt */ -+ for (i = 0; i < 10; i++) { ++ u8 forced_speed_duplex; + -+ if (((adapter->hw.mac.type == e1000_ich8lan) || -+ (adapter->hw.mac.type == e1000_ich9lan)) && i == 8) -+ continue; ++ bool adaptive_ifs; ++ bool arc_subsystem_valid; ++ bool asf_firmware_present; ++ bool autoneg; ++ bool autoneg_failed; ++ bool disable_av; ++ bool disable_hw_init_bits; ++ bool get_link_status; ++ bool ifs_params_forced; ++ bool in_ifs_mode; ++ bool report_tx_early; ++ bool serdes_has_link; ++ bool tx_pkt_filtering; ++}; + -+ /* Interrupt to test */ -+ mask = 1 << i; ++struct e1000_phy_info { ++ struct e1000_phy_operations ops; ++ e1000_phy_type type; + -+ 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; -+ ew32(IMC, mask); -+ ew32(ICS, mask); -+ msleep(10); ++ e1000_1000t_rx_status local_rx; ++ e1000_1000t_rx_status remote_rx; ++ e1000_ms_type ms_type; ++ e1000_ms_type original_ms_type; ++ e1000_rev_polarity cable_polarity; ++ e1000_smart_speed smart_speed; + -+ if (adapter->test_icr & mask) { -+ *data = 3; -+ break; -+ } -+ } ++ u32 addr; ++ u32 id; ++ u32 reset_delay_us; /* in usec */ ++ u32 revision; + -+ /* Enable 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 not posted to the bus, the -+ * test failed. -+ */ -+ adapter->test_icr = 0; -+ ew32(IMS, mask); -+ ew32(ICS, mask); -+ msleep(10); ++ e1000_media_type media_type; + -+ if (!(adapter->test_icr & mask)) { -+ *data = 4; -+ break; -+ } ++ u16 autoneg_advertised; ++ u16 autoneg_mask; ++ u16 cable_length; ++ u16 max_cable_length; ++ u16 min_cable_length; + -+ 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; -+ ew32(IMC, ~mask & 0x00007FFF); -+ ew32(ICS, ~mask & 0x00007FFF); -+ msleep(10); ++ u8 mdix; + -+ if (adapter->test_icr) { -+ *data = 5; -+ break; -+ } -+ } -+ } ++ bool disable_polarity_correction; ++ bool is_mdix; ++ bool polarity_correction; ++ bool reset_disable; ++ bool speed_downgraded; ++ bool autoneg_wait_to_complete; ++}; + -+ /* Disable all the interrupts */ -+ ew32(IMC, 0xFFFFFFFF); -+ msleep(10); ++struct e1000_nvm_info { ++ struct e1000_nvm_operations ops; ++ e1000_nvm_type type; ++ e1000_nvm_override override; + -+ /* Unhook test interrupt handler */ -+ free_irq(irq, netdev); ++ u32 flash_bank_size; ++ u32 flash_base_addr; ++ u32 semaphore_delay; + -+ return *data; -+} ++ u16 word_size; ++ u16 delay_usec; ++ u16 address_bits; ++ u16 opcode_bits; ++ u16 page_size; ++}; + -+static void e1000_free_desc_rings(struct e1000_adapter *adapter) -+{ -+ struct e1000_ring *tx_ring = &adapter->test_tx_ring; -+ struct e1000_ring *rx_ring = &adapter->test_rx_ring; -+ struct pci_dev *pdev = adapter->pdev; -+ int i; ++struct e1000_bus_info { ++ e1000_bus_type type; ++ e1000_bus_speed speed; ++ e1000_bus_width width; + -+ if (tx_ring->desc && tx_ring->buffer_info) { -+ for (i = 0; i < tx_ring->count; i++) { -+ if (tx_ring->buffer_info[i].dma) -+ pci_unmap_single(pdev, -+ tx_ring->buffer_info[i].dma, -+ tx_ring->buffer_info[i].length, -+ PCI_DMA_TODEVICE); -+ if (tx_ring->buffer_info[i].skb) -+ dev_kfree_skb(tx_ring->buffer_info[i].skb); -+ } -+ } ++ u32 snoop; + -+ if (rx_ring->desc && rx_ring->buffer_info) { -+ for (i = 0; i < rx_ring->count; i++) { -+ if (rx_ring->buffer_info[i].dma) -+ pci_unmap_single(pdev, -+ rx_ring->buffer_info[i].dma, -+ 2048, PCI_DMA_FROMDEVICE); -+ if (rx_ring->buffer_info[i].skb) -+ dev_kfree_skb(rx_ring->buffer_info[i].skb); -+ } -+ } ++ u16 func; ++ u16 pci_cmd_word; ++}; + -+ if (tx_ring->desc) { -+ dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, -+ tx_ring->dma); -+ tx_ring->desc = NULL; -+ } -+ if (rx_ring->desc) { -+ dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, -+ rx_ring->dma); -+ rx_ring->desc = NULL; -+ } ++struct e1000_fc_info { ++ u32 high_water; /* Flow control high-water mark */ ++ u32 low_water; /* Flow control low-water mark */ ++ u16 pause_time; /* Flow control pause timer */ ++ bool send_xon; /* Flow control send XON */ ++ bool strict_ieee; /* Strict IEEE mode */ ++ e1000_fc_type type; /* Type of flow control */ ++ e1000_fc_type original_type; ++}; + -+ kfree(tx_ring->buffer_info); -+ tx_ring->buffer_info = NULL; -+ kfree(rx_ring->buffer_info); -+ rx_ring->buffer_info = NULL; -+} ++struct e1000_hw { ++ void *back; ++ void *dev_spec; + -+static int e1000_setup_desc_rings(struct e1000_adapter *adapter) -+{ -+ struct e1000_ring *tx_ring = &adapter->test_tx_ring; -+ struct e1000_ring *rx_ring = &adapter->test_rx_ring; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_hw *hw = &adapter->hw; -+ u32 rctl; -+ int size; -+ int i; -+ int ret_val; ++ u8 __iomem *hw_addr; ++ u8 __iomem *flash_address; ++ unsigned long io_base; + -+ /* Setup Tx descriptor ring and Tx buffers */ ++ struct e1000_mac_info mac; ++ struct e1000_fc_info fc; ++ struct e1000_phy_info phy; ++ struct e1000_nvm_info nvm; ++ struct e1000_bus_info bus; ++ struct e1000_host_mng_dhcp_cookie mng_cookie; + -+ if (!tx_ring->count) -+ tx_ring->count = E1000_DEFAULT_TXD; ++ u32 dev_spec_size; + -+ size = tx_ring->count * sizeof(struct e1000_buffer); -+ tx_ring->buffer_info = kmalloc(size, GFP_KERNEL); -+ if (!tx_ring->buffer_info) { -+ ret_val = 1; -+ goto err_nomem; -+ } -+ memset(tx_ring->buffer_info, 0, size); ++ u16 device_id; ++ u16 subsystem_vendor_id; ++ u16 subsystem_device_id; ++ u16 vendor_id; + -+ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); -+ tx_ring->size = ALIGN(tx_ring->size, 4096); -+ tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, -+ &tx_ring->dma, GFP_KERNEL); -+ if (!tx_ring->desc) { -+ ret_val = 2; -+ goto err_nomem; -+ } -+ memset(tx_ring->desc, 0, tx_ring->size); -+ tx_ring->next_to_use = 0; -+ tx_ring->next_to_clean = 0; ++ u8 revision_id; ++}; + -+ ew32(TDBAL, -+ ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); -+ ew32(TDBAH, ((u64) tx_ring->dma >> 32)); -+ ew32(TDLEN, -+ tx_ring->count * sizeof(struct e1000_tx_desc)); -+ ew32(TDH, 0); -+ ew32(TDT, 0); -+ ew32(TCTL, -+ E1000_TCTL_PSP | E1000_TCTL_EN | -+ E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | -+ E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT); ++#include "e1000_82571.h" ++#include "e1000_80003es2lan.h" ++#include "e1000_ich8lan.h" + -+ for (i = 0; i < tx_ring->count; i++) { -+ struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); -+ struct sk_buff *skb; -+ unsigned int skb_size = 1024; ++/* These functions must be implemented by drivers */ ++s32 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size); ++s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value); ++void e1000_free_dev_spec_struct(struct e1000_hw *hw); ++void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value); + -+ skb = alloc_skb(skb_size, GFP_KERNEL); -+ if (!skb) { -+ ret_val = 3; -+ goto err_nomem; -+ } -+ skb_put(skb, skb_size); -+ tx_ring->buffer_info[i].skb = skb; -+ tx_ring->buffer_info[i].length = skb->len; -+ tx_ring->buffer_info[i].dma = -+ pci_map_single(pdev, skb->data, skb->len, -+ PCI_DMA_TODEVICE); -+ if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) { -+ ret_val = 4; -+ goto err_nomem; -+ } -+ tx_desc->buffer_addr = cpu_to_le64( -+ tx_ring->buffer_info[i].dma); -+ tx_desc->lower.data = cpu_to_le32(skb->len); -+ tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | -+ E1000_TXD_CMD_IFCS | -+ E1000_TXD_CMD_RPS); -+ tx_desc->upper.data = 0; -+ } ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_ich8lan.c linux-2.6.22-10/drivers/net/e1000e/e1000_ich8lan.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_ich8lan.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_ich8lan.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,2757 @@ ++/******************************************************************************* + -+ /* Setup Rx descriptor ring and Rx buffers */ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ if (!rx_ring->count) -+ rx_ring->count = E1000_DEFAULT_RXD; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ size = rx_ring->count * sizeof(struct e1000_buffer); -+ rx_ring->buffer_info = kmalloc(size, GFP_KERNEL); -+ if (!rx_ring->buffer_info) { -+ ret_val = 5; -+ goto err_nomem; -+ } -+ memset(rx_ring->buffer_info, 0, size); ++ This program is distributed in the hope 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. + -+ rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc); -+ rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, -+ &rx_ring->dma, GFP_KERNEL); -+ if (!rx_ring->desc) { -+ ret_val = 6; -+ goto err_nomem; -+ } -+ memset(rx_ring->desc, 0, rx_ring->size); -+ rx_ring->next_to_use = 0; -+ rx_ring->next_to_clean = 0; ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ rctl = er32(RCTL); -+ ew32(RCTL, rctl & ~E1000_RCTL_EN); -+ ew32(RDBAL, ((u64) rx_ring->dma & 0xFFFFFFFF)); -+ ew32(RDBAH, ((u64) rx_ring->dma >> 32)); -+ ew32(RDLEN, rx_ring->size); -+ ew32(RDH, 0); -+ ew32(RDT, 0); -+ rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | -+ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | -+ (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); -+ ew32(RCTL, rctl); ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ for (i = 0; i < rx_ring->count; i++) { -+ struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); -+ struct sk_buff *skb; ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL); -+ if (!skb) { -+ ret_val = 7; -+ goto err_nomem; -+ } -+ skb_reserve(skb, NET_IP_ALIGN); -+ rx_ring->buffer_info[i].skb = skb; -+ rx_ring->buffer_info[i].dma = -+ pci_map_single(pdev, skb->data, 2048, -+ PCI_DMA_FROMDEVICE); -+ if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) { -+ ret_val = 8; -+ goto err_nomem; -+ } -+ rx_desc->buffer_addr = -+ cpu_to_le64(rx_ring->buffer_info[i].dma); -+ memset(skb->data, 0x00, skb->len); -+ } ++*******************************************************************************/ + -+ return 0; ++/* e1000_ich8lan ++ * e1000_ich9lan ++ */ + -+err_nomem: -+ e1000_free_desc_rings(adapter); -+ return ret_val; -+} ++#include "e1000_hw.h" ++ ++static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw); ++static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); ++static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); ++static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); ++static void e1000_release_swflag_ich8lan(struct e1000_hw *hw); ++static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); ++static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); ++static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); ++static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw); ++static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); ++static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); ++static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, ++ bool active); ++static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, ++ bool active); ++static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); ++static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); ++static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, ++ u16 *data); ++static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); ++static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); ++static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); ++static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); ++static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); ++static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, ++ u16 *speed, u16 *duplex); ++static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); ++static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); ++static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); ++static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); ++static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); ++static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout); ++static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); ++static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw); ++static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); ++static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); ++static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, ++ u32 offset, u8* data); ++static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8 size, u16* data); ++static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, ++ u32 offset, u16 *data); ++static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, ++ u32 offset, u8 byte); ++static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, ++ u32 offset, u8 data); ++static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8 size, u16 data); ++static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); ++static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); + -+static void e1000_phy_disable_receiver(struct e1000_adapter *adapter) -+{ -+ /* Write out to PHY registers 29 and 30 to disable the Receiver. */ -+ e1e_wphy(&adapter->hw, 29, 0x001F); -+ e1e_wphy(&adapter->hw, 30, 0x8FFC); -+ e1e_wphy(&adapter->hw, 29, 0x001A); -+ e1e_wphy(&adapter->hw, 30, 0x8FF0); -+} ++/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ ++/* Offset 04h HSFSTS */ ++union ich8_hws_flash_status { ++ struct ich8_hsfsts { ++ u16 flcdone :1; /* bit 0 Flash Cycle Done */ ++ u16 flcerr :1; /* bit 1 Flash Cycle Error */ ++ u16 dael :1; /* bit 2 Direct Access error Log */ ++ u16 berasesz :2; /* bit 4:3 Sector Erase Size */ ++ u16 flcinprog :1; /* bit 5 flash cycle in Progress */ ++ u16 reserved1 :2; /* bit 13:6 Reserved */ ++ u16 reserved2 :6; /* bit 13:6 Reserved */ ++ u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */ ++ u16 flockdn :1; /* bit 15 Flash Config Lock-Down */ ++ } hsf_status; ++ u16 regval; ++}; + -+static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl_reg = 0; -+ u32 stat_reg = 0; ++/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */ ++/* Offset 06h FLCTL */ ++union ich8_hws_flash_ctrl { ++ struct ich8_hsflctl { ++ u16 flcgo :1; /* 0 Flash Cycle Go */ ++ u16 flcycle :2; /* 2:1 Flash Cycle */ ++ u16 reserved :5; /* 7:3 Reserved */ ++ u16 fldbcount :2; /* 9:8 Flash Data Byte Count */ ++ u16 flockdn :6; /* 15:10 Reserved */ ++ } hsf_ctrl; ++ u16 regval; ++}; + -+ adapter->hw.mac.autoneg = 0; ++/* ICH Flash Region Access Permissions */ ++union ich8_hws_flash_regacc { ++ struct ich8_flracc { ++ u32 grra :8; /* 0:7 GbE region Read Access */ ++ u32 grwa :8; /* 8:15 GbE region Write Access */ ++ u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */ ++ u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */ ++ } hsf_flregacc; ++ u16 regval; ++}; + -+ if (adapter->hw.phy.type == e1000_phy_m88) { -+ /* Auto-MDI/MDIX Off */ -+ e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); -+ /* reset to update Auto-MDI/MDIX */ -+ e1e_wphy(hw, PHY_CONTROL, 0x9140); -+ /* autoneg off */ -+ e1e_wphy(hw, PHY_CONTROL, 0x8140); -+ } else if (adapter->hw.phy.type == e1000_phy_gg82563) -+ e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); ++struct e1000_shadow_ram { ++ u16 value; ++ bool modified; ++}; + -+ ctrl_reg = er32(CTRL); ++struct e1000_dev_spec_ich8lan { ++ bool kmrn_lock_loss_workaround_enabled; ++ struct e1000_shadow_ram shadow_ram[E1000_SHADOW_RAM_WORDS]; ++}; + -+ if (adapter->hw.phy.type == e1000_phy_ife) { -+ /* force 100, set loopback */ -+ e1e_wphy(hw, PHY_CONTROL, 0x6100); ++/** ++ * e1000_init_phy_params_ich8lan - Initialize PHY function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Initialize family-specific PHY parameters and function pointers. ++ **/ ++static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i = 0; + -+ /* 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 */ -+ e1e_wphy(hw, PHY_CONTROL, 0x4140); ++ DEBUGFUNC("e1000_init_phy_params_ich8lan"); ++ ++ phy->addr = 1; ++ phy->reset_delay_us = 100; ++ ++ phy->ops.acquire = e1000_acquire_swflag_ich8lan; ++ phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; ++ phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; ++ phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan; ++ phy->ops.get_cable_length = e1000_get_cable_length_igp_2; ++ phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; ++ phy->ops.get_info = e1000_get_phy_info_ich8lan; ++ phy->ops.read_reg = e1000_read_phy_reg_igp; ++ phy->ops.release = e1000_release_swflag_ich8lan; ++ phy->ops.reset = e1000_phy_hw_reset_ich8lan; ++ phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; ++ phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; ++ phy->ops.write_reg = e1000_write_phy_reg_igp; ++ phy->ops.power_up = e1000_power_up_phy_copper; ++ phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; + -+ /* Now set up the MAC to the same speed/duplex as the PHY. */ -+ ctrl_reg = er32(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 */ ++ /* ++ * We may need to do this twice - once for IGP and if that fails, ++ * we'll set BM func pointers and try again ++ */ ++ ret_val = e1000_determine_phy_address(hw); ++ if (ret_val) { ++ phy->ops.write_reg = e1000_write_phy_reg_bm; ++ phy->ops.read_reg = e1000_read_phy_reg_bm; ++ ret_val = e1000_determine_phy_address(hw); ++ if (ret_val) { ++ DEBUGOUT("Cannot determine PHY address. Erroring out\n"); ++ goto out; ++ } + } + -+ 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 if half duplex link is -+ * detected. */ -+ stat_reg = er32(STATUS); -+ if ((stat_reg & E1000_STATUS_FD) == 0) -+ ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); ++ phy->id = 0; ++ while ((e1000_phy_unknown == e1000_get_phy_type_from_id(phy->id)) && ++ (i++ < 100)) { ++ msec_delay(1); ++ ret_val = e1000_get_phy_id(hw); ++ if (ret_val) ++ goto out; + } + -+ ew32(CTRL, ctrl_reg); -+ -+ /* 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) -+ e1000_phy_disable_receiver(adapter); -+ -+ udelay(500); ++ /* Verify phy id */ ++ switch (phy->id) { ++ case IGP03E1000_E_PHY_ID: ++ phy->type = e1000_phy_igp_3; ++ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ++ break; ++ case IFE_E_PHY_ID: ++ case IFE_PLUS_E_PHY_ID: ++ case IFE_C_E_PHY_ID: ++ phy->type = e1000_phy_ife; ++ phy->autoneg_mask = E1000_ALL_NOT_GIG; ++ break; ++ case BME1000_E_PHY_ID: ++ phy->type = e1000_phy_bm; ++ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ++ phy->ops.read_reg = e1000_read_phy_reg_bm; ++ phy->ops.write_reg = e1000_write_phy_reg_bm; ++ phy->ops.commit = e1000_phy_sw_reset_generic; ++ break; ++ default: ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } + -+ return 0; ++out: ++ return ret_val; +} + -+static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) ++/** ++ * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Initialize family-specific NVM parameters and function ++ * pointers. ++ **/ ++static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl = er32(CTRL); -+ int link = 0; ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ u32 gfpreg, sector_base_addr, sector_end_addr; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i; + -+ /* special requirements for 82571/82572 fiber adapters */ ++ DEBUGFUNC("e1000_init_nvm_params_ich8lan"); + -+ /* jump through hoops to make sure link is up because serdes -+ * link is hardwired up */ -+ ctrl |= E1000_CTRL_SLU; -+ ew32(CTRL, ctrl); ++ /* Can't read flash registers if the register set isn't mapped. */ ++ if (!hw->flash_address) { ++ DEBUGOUT("ERROR: Flash registers not mapped\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } + -+ /* disable autoneg */ -+ ctrl = er32(TXCW); -+ ctrl &= ~(1 << 31); -+ ew32(TXCW, ctrl); ++ nvm->type = e1000_nvm_flash_sw; + -+ link = (er32(STATUS) & E1000_STATUS_LU); ++ gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); + -+ if (!link) { -+ /* set invert loss of signal */ -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_ILOS; -+ ew32(CTRL, ctrl); ++ /* ++ * sector_X_addr is a "sector"-aligned address (4096 bytes) ++ * Add 1 to sector_end_addr since this sector is included in ++ * the overall size. ++ */ ++ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; ++ sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1; ++ ++ /* flash_base_addr is byte-aligned */ ++ nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT; ++ ++ /* ++ * find total size of the NVM, then cut in half since the total ++ * size represents two separate NVM banks. ++ */ ++ nvm->flash_bank_size = (sector_end_addr - sector_base_addr) ++ << FLASH_SECTOR_ADDR_SHIFT; ++ nvm->flash_bank_size /= 2; ++ /* Adjust to word count */ ++ nvm->flash_bank_size /= sizeof(u16); ++ ++ nvm->word_size = E1000_SHADOW_RAM_WORDS; ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ if (!dev_spec) { ++ DEBUGOUT("dev_spec pointer is set to NULL.\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; + } + -+ /* special write to serdes control register to enable SerDes analog -+ * loopback */ -+#define E1000_SERDES_LB_ON 0x410 -+ ew32(SCTL, E1000_SERDES_LB_ON); -+ msleep(10); ++ /* Clear shadow ram */ ++ for (i = 0; i < nvm->word_size; i++) { ++ dev_spec->shadow_ram[i].modified = false; ++ dev_spec->shadow_ram[i].value = 0xFFFF; ++ } + -+ return 0; ++ /* Function Pointers */ ++ nvm->ops.acquire = e1000_acquire_swflag_ich8lan; ++ nvm->ops.read = e1000_read_nvm_ich8lan; ++ nvm->ops.release = e1000_release_swflag_ich8lan; ++ nvm->ops.update = e1000_update_nvm_checksum_ich8lan; ++ nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan; ++ nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; ++ nvm->ops.write = e1000_write_nvm_ich8lan; ++ ++out: ++ return ret_val; +} + -+/* only call this for fiber/serdes connections to es2lan */ -+static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter) ++/** ++ * e1000_init_mac_params_ich8lan - Initialize MAC function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Initialize family-specific MAC parameters and function ++ * pointers. ++ **/ ++static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrlext = er32(CTRL_EXT); -+ u32 ctrl = er32(CTRL); ++ struct e1000_mac_info *mac = &hw->mac; ++ s32 ret_val = E1000_SUCCESS; + -+ /* save CTRL_EXT to restore later, reuse an empty variable (unused -+ on mac_type 80003es2lan) */ -+ adapter->tx_fifo_head = ctrlext; ++ DEBUGFUNC("e1000_init_mac_params_ich8lan"); + -+ /* clear the serdes mode bits, putting the device into mac loopback */ -+ ctrlext &= ~E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; -+ ew32(CTRL_EXT, ctrlext); ++ /* Set media type function pointer */ ++ hw->phy.media_type = e1000_media_type_copper; + -+ /* force speed to 1000/FD, link up */ -+ ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); -+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | -+ E1000_CTRL_SPD_1000 | E1000_CTRL_FD); -+ ew32(CTRL, ctrl); ++ /* Set mta register count */ ++ mac->mta_reg_count = 32; ++ /* Set rar entry count */ ++ mac->rar_entry_count = E1000_ICH_RAR_ENTRIES; ++ if (mac->type == e1000_ich8lan) ++ mac->rar_entry_count--; ++ /* Set if part includes ASF firmware */ ++ mac->asf_firmware_present = true; ++ /* Set if manageability features are enabled. */ ++ mac->arc_subsystem_valid = true; ++ ++ /* Function pointers */ ++ ++ /* bus type/speed/width */ ++ mac->ops.get_bus_info = e1000_get_bus_info_ich8lan; ++ /* reset */ ++ mac->ops.reset_hw = e1000_reset_hw_ich8lan; ++ /* hw initialization */ ++ mac->ops.init_hw = e1000_init_hw_ich8lan; ++ /* link setup */ ++ mac->ops.setup_link = e1000_setup_link_ich8lan; ++ /* physical interface setup */ ++ mac->ops.setup_physical_interface = e1000_setup_copper_link_ich8lan; ++ /* check for link */ ++ mac->ops.check_for_link = e1000_check_for_copper_link_generic; ++ /* check management mode */ ++ mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan; ++ /* link info */ ++ mac->ops.get_link_up_info = e1000_get_link_up_info_ich8lan; ++ /* multicast address update */ ++ mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; ++ /* setting MTA */ ++ mac->ops.mta_set = e1000_mta_set_generic; ++ /* blink LED */ ++ mac->ops.blink_led = e1000_blink_led_generic; ++ /* setup LED */ ++ mac->ops.setup_led = e1000_setup_led_generic; ++ /* cleanup LED */ ++ mac->ops.cleanup_led = e1000_cleanup_led_ich8lan; ++ /* turn on/off LED */ ++ mac->ops.led_on = e1000_led_on_ich8lan; ++ mac->ops.led_off = e1000_led_off_ich8lan; ++ /* remove device */ ++ mac->ops.remove_device = e1000_remove_device_generic; ++ /* clear hardware counters */ ++ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan; ++ ++ hw->dev_spec_size = sizeof(struct e1000_dev_spec_ich8lan); ++ ++ /* Device-specific structure allocation */ ++ ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size); ++ if (ret_val) ++ goto out; + -+ /* set mac loopback */ -+ ctrl = er32(RCTL); -+ ctrl |= E1000_RCTL_LBM_MAC; -+ ew32(RCTL, ctrl); ++ /* Enable PCS Lock-loss workaround for ICH8 */ ++ if (mac->type == e1000_ich8lan) ++ e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, true); + -+ /* set testing mode parameters (no need to reset later) */ -+#define KMRNCTRLSTA_OPMODE (0x1F << 16) -+#define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582 -+ ew32(KMRNCTRLSTA, -+ (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII)); + -+ return 0; ++out: ++ return ret_val; +} + -+static int e1000_setup_loopback_test(struct e1000_adapter *adapter) ++/** ++ * e1000_init_function_pointers_ich8lan - Initialize ICH8 function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Initialize family-specific function pointers for PHY, MAC, and NVM. ++ **/ ++void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 rctl; -+ -+ if (hw->media_type == e1000_media_type_fiber || -+ hw->media_type == e1000_media_type_internal_serdes) { -+ switch (hw->mac.type) { -+ case e1000_80003es2lan: -+ return e1000_set_es2lan_mac_loopback(adapter); -+ break; -+ case e1000_82571: -+ case e1000_82572: -+ return e1000_set_82571_fiber_loopback(adapter); -+ break; -+ default: -+ rctl = er32(RCTL); -+ rctl |= E1000_RCTL_LBM_TCVR; -+ ew32(RCTL, rctl); -+ return 0; -+ } -+ } else if (hw->media_type == e1000_media_type_copper) { -+ return e1000_integrated_phy_loopback(adapter); -+ } ++ DEBUGFUNC("e1000_init_function_pointers_ich8lan"); + -+ return 7; ++ e1000_init_mac_ops_generic(hw); ++ e1000_init_nvm_ops_generic(hw); ++ hw->mac.ops.init_params = e1000_init_mac_params_ich8lan; ++ hw->nvm.ops.init_params = e1000_init_nvm_params_ich8lan; ++ hw->phy.ops.init_params = e1000_init_phy_params_ich8lan; +} + -+static void e1000_loopback_cleanup(struct e1000_adapter *adapter) ++/** ++ * e1000_acquire_swflag_ich8lan - Acquire software control flag ++ * @hw: pointer to the HW structure ++ * ++ * Acquires the software control flag for performing NVM and PHY ++ * operations. This is a function pointer entry point only called by ++ * read/write routines for the PHY and NVM parts. ++ **/ ++static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 rctl; -+ u16 phy_reg; ++ u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT; ++ s32 ret_val = E1000_SUCCESS; + -+ rctl = er32(RCTL); -+ rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); -+ ew32(RCTL, rctl); ++ DEBUGFUNC("e1000_acquire_swflag_ich8lan"); + -+ switch (hw->mac.type) { -+ case e1000_80003es2lan: -+ if (hw->media_type == e1000_media_type_fiber || -+ hw->media_type == e1000_media_type_internal_serdes) { -+ /* restore CTRL_EXT, stealing space from tx_fifo_head */ -+ ew32(CTRL_EXT, -+ adapter->tx_fifo_head); -+ adapter->tx_fifo_head = 0; -+ } -+ /* fall through */ -+ 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 -+ ew32(SCTL, E1000_SERDES_LB_OFF); -+ msleep(10); ++ while (timeout) { ++ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); ++ extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; ++ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); ++ ++ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); ++ if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) + break; -+ } -+ /* Fall Through */ -+ default: -+ hw->mac.autoneg = 1; -+ if (hw->phy.type == e1000_phy_gg82563) -+ e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x180); -+ e1e_rphy(hw, PHY_CONTROL, &phy_reg); -+ if (phy_reg & MII_CR_LOOPBACK) { -+ phy_reg &= ~MII_CR_LOOPBACK; -+ e1e_wphy(hw, PHY_CONTROL, phy_reg); -+ e1000e_commit_phy(hw); -+ } -+ break; ++ msec_delay_irq(1); ++ timeout--; ++ } ++ ++ if (!timeout) { ++ DEBUGOUT("FW or HW has locked the resource for too long.\n"); ++ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ++ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; + } ++ ++out: ++ return ret_val; +} + -+static void e1000_create_lbtest_frame(struct sk_buff *skb, -+ unsigned int frame_size) -+{ -+ memset(skb->data, 0xFF, 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); -+} -+ -+static int e1000_check_lbtest_frame(struct sk_buff *skb, -+ unsigned int frame_size) -+{ -+ 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; -+ return 13; -+} -+ -+static int e1000_run_loopback_test(struct e1000_adapter *adapter) ++/** ++ * e1000_release_swflag_ich8lan - Release software control flag ++ * @hw: pointer to the HW structure ++ * ++ * Releases the software control flag for performing NVM and PHY operations. ++ * This is a function pointer entry point only called by read/write ++ * routines for the PHY and NVM parts. ++ **/ ++static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_ring *tx_ring = &adapter->test_tx_ring; -+ struct e1000_ring *rx_ring = &adapter->test_rx_ring; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_hw *hw = &adapter->hw; -+ int i, j, k, l; -+ int lc; -+ int good_cnt; -+ int ret_val = 0; -+ unsigned long time; -+ -+ ew32(RDT, rx_ring->count - 1); -+ -+ /* 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 -+ */ ++ u32 extcnf_ctrl; + -+ if (rx_ring->count <= tx_ring->count) -+ lc = ((tx_ring->count / 64) * 2) + 1; -+ else -+ lc = ((rx_ring->count / 64) * 2) + 1; ++ DEBUGFUNC("e1000_release_swflag_ich8lan"); + -+ k = 0; -+ l = 0; -+ for (j = 0; j <= lc; j++) { /* loop count loop */ -+ for (i = 0; i < 64; i++) { /* send the packets */ -+ e1000_create_lbtest_frame( -+ tx_ring->buffer_info[i].skb, 1024); -+ pci_dma_sync_single_for_device(pdev, -+ tx_ring->buffer_info[k].dma, -+ tx_ring->buffer_info[k].length, -+ PCI_DMA_TODEVICE); -+ k++; -+ if (k == tx_ring->count) -+ k = 0; -+ } -+ ew32(TDT, k); -+ msleep(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, -+ rx_ring->buffer_info[l].dma, 2048, -+ PCI_DMA_FROMDEVICE); ++ extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); ++ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ++ E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); + -+ ret_val = e1000_check_lbtest_frame( -+ rx_ring->buffer_info[l].skb, 1024); -+ if (!ret_val) -+ good_cnt++; -+ l++; -+ if (l == rx_ring->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) && !time_after(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; ++ return; +} + -+static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data) ++/** ++ * e1000_check_mng_mode_ich8lan - Checks management mode ++ * @hw: pointer to the HW structure ++ * ++ * This checks if the adapter has manageability enabled. ++ * This is a function pointer entry point only called by read/write ++ * routines for the PHY and NVM parts. ++ **/ ++static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) +{ -+ /* PHY loopback cannot be performed if SoL/IDER -+ * sessions are active */ -+ if (e1000_check_reset_block(&adapter->hw)) { -+ ndev_err(adapter->netdev, "Cannot do PHY loopback test " -+ "when SoL/IDER is active.\n"); -+ *data = 0; -+ goto out; -+ } -+ -+ *data = e1000_setup_desc_rings(adapter); -+ if (data) -+ goto out; ++ u32 fwsm; + -+ *data = e1000_setup_loopback_test(adapter); -+ if (data) -+ goto err_loopback; ++ DEBUGFUNC("e1000_check_mng_mode_ich8lan"); + -+ *data = e1000_run_loopback_test(adapter); -+ e1000_loopback_cleanup(adapter); ++ fwsm = E1000_READ_REG(hw, E1000_FWSM); + -+err_loopback: -+ e1000_free_desc_rings(adapter); -+out: -+ return *data; ++ return ((fwsm & E1000_FWSM_MODE_MASK) == ++ (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); +} + -+static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) ++/** ++ * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked ++ * @hw: pointer to the HW structure ++ * ++ * Checks if firmware is blocking the reset of the PHY. ++ * This is a function pointer entry point only called by ++ * reset routines. ++ **/ ++static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ -+ *data = 0; -+ if (hw->media_type == e1000_media_type_internal_serdes) { -+ int i = 0; -+ hw->mac.serdes_has_link = 0; -+ -+ /* On some blade server designs, link establishment -+ * could take as long as 2-3 minutes */ -+ do { -+ hw->mac.ops.check_for_link(hw); -+ if (hw->mac.serdes_has_link) -+ return *data; -+ msleep(20); -+ } while (i++ < 3750); ++ u32 fwsm; + -+ *data = 1; -+ } else { -+ hw->mac.ops.check_for_link(hw); -+ if (hw->mac.autoneg) -+ msleep(4000); ++ DEBUGFUNC("e1000_check_reset_block_ich8lan"); + -+ if (!(er32(STATUS) & -+ E1000_STATUS_LU)) -+ *data = 1; -+ } -+ return *data; -+} ++ fwsm = E1000_READ_REG(hw, E1000_FWSM); + -+static int e1000_diag_test_count(struct net_device *netdev) -+{ -+ return E1000_TEST_LEN; ++ return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? E1000_SUCCESS ++ : E1000_BLK_PHY_RESET; +} + -+static void e1000_diag_test(struct net_device *netdev, -+ struct ethtool_test *eth_test, u64 *data) ++/** ++ * e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex ++ * @hw: pointer to the HW structure ++ * ++ * Forces the speed and duplex settings of the PHY. ++ * This is a function pointer entry point only called by ++ * PHY setup routines. ++ **/ ++static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ u16 autoneg_advertised; -+ u8 forced_speed_duplex; -+ u8 autoneg; -+ bool if_running = netif_running(netdev); ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 data; ++ bool link; + -+ set_bit(__E1000_TESTING, &adapter->state); -+ if (eth_test->flags == ETH_TEST_FL_OFFLINE) { -+ /* Offline tests */ ++ DEBUGFUNC("e1000_phy_force_speed_duplex_ich8lan"); + -+ /* save speed, duplex, autoneg settings */ -+ autoneg_advertised = adapter->hw.phy.autoneg_advertised; -+ forced_speed_duplex = adapter->hw.mac.forced_speed_duplex; -+ autoneg = adapter->hw.mac.autoneg; ++ if (phy->type != e1000_phy_ife) { ++ ret_val = e1000_phy_force_speed_duplex_igp(hw); ++ goto out; ++ } + -+ ndev_info(netdev, "offline testing starting\n"); ++ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data); ++ if (ret_val) ++ goto out; + -+ /* Link test performed before hardware reset so autoneg doesn't -+ * interfere with test result */ -+ if (e1000_link_test(adapter, &data[4])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ e1000_phy_force_speed_duplex_setup(hw, &data); + -+ if (if_running) -+ /* indicate we're in test mode */ -+ dev_close(netdev); -+ else -+ e1000e_reset(adapter); ++ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data); ++ if (ret_val) ++ goto out; + -+ if (e1000_reg_test(adapter, &data[0])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ /* Disable MDI-X support for 10/100 */ ++ ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); ++ if (ret_val) ++ goto out; + -+ e1000e_reset(adapter); -+ if (e1000_eeprom_test(adapter, &data[1])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ data &= ~IFE_PMC_AUTO_MDIX; ++ data &= ~IFE_PMC_FORCE_MDIX; + -+ e1000e_reset(adapter); -+ if (e1000_intr_test(adapter, &data[2])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data); ++ if (ret_val) ++ goto out; + -+ e1000e_reset(adapter); -+ /* make sure the phy is powered up */ -+ e1000e_power_up_phy(adapter); -+ if (e1000_loopback_test(adapter, &data[3])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ DEBUGOUT1("IFE PMC: %X\n", data); + -+ /* restore speed, duplex, autoneg settings */ -+ adapter->hw.phy.autoneg_advertised = autoneg_advertised; -+ adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; -+ adapter->hw.mac.autoneg = autoneg; ++ usec_delay(1); + -+ /* force this routine to wait until autoneg complete/timeout */ -+ adapter->hw.phy.wait_for_link = 1; -+ e1000e_reset(adapter); -+ adapter->hw.phy.wait_for_link = 0; ++ if (phy->autoneg_wait_to_complete) { ++ DEBUGOUT("Waiting for forced speed/duplex link on IFE phy.\n"); + -+ clear_bit(__E1000_TESTING, &adapter->state); -+ if (if_running) -+ dev_open(netdev); -+ } else { -+ ndev_info(netdev, "online testing starting\n"); -+ /* Online tests */ -+ if (e1000_link_test(adapter, &data[4])) -+ eth_test->flags |= ETH_TEST_FL_FAILED; ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; + -+ /* Online tests aren't run; pass by default */ -+ data[0] = 0; -+ data[1] = 0; -+ data[2] = 0; -+ data[3] = 0; ++ if (!link) { ++ DEBUGOUT("Link taking longer than expected.\n"); ++ } + -+ clear_bit(__E1000_TESTING, &adapter->state); ++ /* Try once more */ ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; + } -+ msleep_interruptible(4 * 1000); ++ ++out: ++ return ret_val; +} + -+static void e1000_get_wol(struct net_device *netdev, -+ struct ethtool_wolinfo *wol) ++/** ++ * e1000_phy_hw_reset_ich8lan - Performs a PHY reset ++ * @hw: pointer to the HW structure ++ * ++ * Resets the PHY ++ * This is a function pointer entry point called by drivers ++ * or other shared routines. ++ **/ ++static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ -+ wol->supported = 0; -+ wol->wolopts = 0; ++ struct e1000_phy_info *phy = &hw->phy; ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; ++ s32 ret_val; ++ u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT; ++ u16 word_addr, reg_data, reg_addr, phy_page = 0; + -+ if (!(adapter->flags & FLAG_HAS_WOL)) -+ return; ++ DEBUGFUNC("e1000_phy_hw_reset_ich8lan"); + -+ wol->supported = WAKE_UCAST | WAKE_MCAST | -+ WAKE_BCAST | WAKE_MAGIC; ++ ret_val = e1000_phy_hw_reset_generic(hw); ++ if (ret_val) ++ goto out; + -+ /* apply any specific unsupported masks here */ -+ if (adapter->flags & FLAG_NO_WAKE_UCAST) { -+ wol->supported &= ~WAKE_UCAST; -+ -+ if (adapter->wol & E1000_WUFC_EX) -+ ndev_err(netdev, "Interface does not support " -+ "directed (unicast) frame wake-up packets\n"); -+ } -+ -+ 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; -+} ++ /* ++ * Initialize the PHY from the NVM on ICH 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. ++ */ ++ if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { ++ /* Check if SW needs configure the PHY */ ++ if ((hw->device_id == E1000_DEV_ID_ICH8_IGP_M_AMT) || ++ (hw->device_id == E1000_DEV_ID_ICH8_IGP_M)) ++ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; ++ else ++ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; + -+static int e1000_set_wol(struct net_device *netdev, -+ struct ethtool_wolinfo *wol) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ data = E1000_READ_REG(hw, E1000_FEXTNVM); ++ if (!(data & sw_cfg_mask)) ++ goto out; + -+ if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) -+ return -EOPNOTSUPP; ++ /* Wait for basic configuration completes before proceeding*/ ++ do { ++ data = E1000_READ_REG(hw, E1000_STATUS); ++ data &= E1000_STATUS_LAN_INIT_DONE; ++ usec_delay(100); ++ } while ((!data) && --loop); + -+ if (!(adapter->flags & FLAG_HAS_WOL)) -+ return wol->wolopts ? -EOPNOTSUPP : 0; ++ /* ++ * If basic configuration is incomplete before the above loop ++ * count reaches 0, loading the configuration from NVM will ++ * leave the PHY in a bad state possibly resulting in no link. ++ */ ++ if (loop == 0) { ++ DEBUGOUT("LAN_INIT_DONE not set, increase timeout\n"); ++ } + -+ /* these settings will always override what we currently have */ -+ adapter->wol = 0; ++ /* Clear the Init Done bit for the next init event */ ++ data = E1000_READ_REG(hw, E1000_STATUS); ++ data &= ~E1000_STATUS_LAN_INIT_DONE; ++ E1000_WRITE_REG(hw, E1000_STATUS, data); + -+ 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; ++ /* ++ * Make sure HW does not configure LCD from PHY ++ * extended configuration before SW configuration ++ */ ++ data = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); ++ if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) ++ goto out; + -+ return 0; -+} ++ cnf_size = E1000_READ_REG(hw, E1000_EXTCNF_SIZE); ++ cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; ++ cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; ++ if (!cnf_size) ++ goto out; + -+/* toggle LED 4 times per second = 2 "blinks" per second */ -+#define E1000_ID_INTERVAL (HZ/4) ++ cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; ++ cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; + -+/* bit defines for adapter->led_status */ -+#define E1000_LED_ON 0 ++ /* ++ * Configure LCD from extended configuration ++ * region. ++ */ + -+static void e1000_led_blink_callback(unsigned long data) -+{ -+ struct e1000_adapter *adapter = (struct e1000_adapter *) data; ++ /* cnf_base_addr is in DWORD */ ++ word_addr = (u16)(cnf_base_addr << 1); + -+ if (test_and_change_bit(E1000_LED_ON, &adapter->led_status)) -+ adapter->hw.mac.ops.led_off(&adapter->hw); -+ else -+ adapter->hw.mac.ops.led_on(&adapter->hw); ++ for (i = 0; i < cnf_size; i++) { ++ ret_val = nvm->ops.read(hw, ++ (word_addr + i * 2), ++ 1, ++ ®_data); ++ if (ret_val) ++ goto out; + -+ mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL); -+} ++ ret_val = nvm->ops.read(hw, ++ (word_addr + i * 2 + 1), ++ 1, ++ ®_addr); ++ if (ret_val) ++ goto out; + -+static int e1000_phys_id(struct net_device *netdev, u32 data) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ /* Save off the PHY page for future writes. */ ++ if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { ++ phy_page = reg_data; ++ continue; ++ } + -+ if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) -+ data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); ++ reg_addr |= phy_page; + -+ 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; ++ ret_val = phy->ops.write_reg(hw, ++ (u32)reg_addr, ++ reg_data); ++ if (ret_val) ++ goto out; + } -+ mod_timer(&adapter->blink_timer, jiffies); -+ msleep_interruptible(data * 1000); -+ del_timer_sync(&adapter->blink_timer); -+ e1e_wphy(&adapter->hw, -+ IFE_PHY_SPECIAL_CONTROL_LED, 0); -+ } else { -+ e1000e_blink_led(&adapter->hw); -+ msleep_interruptible(data * 1000); + } + -+ adapter->hw.mac.ops.led_off(&adapter->hw); -+ clear_bit(E1000_LED_ON, &adapter->led_status); -+ adapter->hw.mac.ops.cleanup_led(&adapter->hw); -+ -+ return 0; -+} -+ -+static int e1000_nway_reset(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ if (netif_running(netdev)) -+ e1000e_reinit_locked(adapter); -+ return 0; -+} -+ -+static int e1000_get_stats_count(struct net_device *netdev) -+{ -+ return E1000_STATS_LEN; ++out: ++ return ret_val; +} + -+static void e1000_get_ethtool_stats(struct net_device *netdev, -+ struct ethtool_stats *stats, -+ u64 *data) ++/** ++ * e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info ++ * @hw: pointer to the HW structure ++ * ++ * Wrapper for calling the get_phy_info routines for the appropriate phy type. ++ * This is a function pointer entry point called by drivers ++ * or other shared routines. ++ **/ ++static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ int i; -+ -+ e1000e_update_stats(adapter); -+ 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(u64)) ? *(u64 *)p : *(u32 *)p; -+ } -+} ++ s32 ret_val = -E1000_ERR_PHY_TYPE; + -+static void e1000_get_strings(struct net_device *netdev, u32 stringset, -+ u8 *data) -+{ -+ u8 *p = data; -+ int i; ++ DEBUGFUNC("e1000_get_phy_info_ich8lan"); + -+ switch (stringset) { -+ case ETH_SS_TEST: -+ memcpy(data, *e1000_gstrings_test, -+ E1000_TEST_LEN*ETH_GSTRING_LEN); ++ switch (hw->phy.type) { ++ case e1000_phy_ife: ++ ret_val = e1000_get_phy_info_ife_ich8lan(hw); + break; -+ case ETH_SS_STATS: -+ for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { -+ memcpy(p, e1000_gstrings_stats[i].stat_string, -+ ETH_GSTRING_LEN); -+ p += ETH_GSTRING_LEN; -+ } ++ case e1000_phy_igp_3: ++ case e1000_phy_bm: ++ ret_val = e1000_get_phy_info_igp(hw); ++ break; ++ default: + break; + } -+} -+ -+static const struct ethtool_ops e1000_ethtool_ops = { -+ .get_settings = e1000_get_settings, -+ .set_settings = e1000_set_settings, -+ .get_drvinfo = e1000_get_drvinfo, -+ .get_regs_len = e1000_get_regs_len, -+ .get_regs = e1000_get_regs, -+ .get_wol = e1000_get_wol, -+ .set_wol = e1000_set_wol, -+ .get_msglevel = e1000_get_msglevel, -+ .set_msglevel = e1000_set_msglevel, -+ .nway_reset = e1000_nway_reset, -+ .get_link = ethtool_op_get_link, -+ .get_eeprom_len = e1000_get_eeprom_len, -+ .get_eeprom = e1000_get_eeprom, -+ .set_eeprom = e1000_set_eeprom, -+ .get_ringparam = e1000_get_ringparam, -+ .set_ringparam = e1000_set_ringparam, -+ .get_pauseparam = e1000_get_pauseparam, -+ .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, -+ .set_tx_csum = e1000_set_tx_csum, -+ .get_sg = ethtool_op_get_sg, -+ .set_sg = ethtool_op_set_sg, -+ .get_tso = ethtool_op_get_tso, -+ .set_tso = e1000_set_tso, -+ .self_test_count = e1000_diag_test_count, -+ .self_test = e1000_diag_test, -+ .get_strings = e1000_get_strings, -+ .phys_id = e1000_phys_id, -+ .get_stats_count = e1000_get_stats_count, -+ .get_ethtool_stats = e1000_get_ethtool_stats, -+}; + -+void e1000e_set_ethtool_ops(struct net_device *netdev) -+{ -+ SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops); ++ return ret_val; +} -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/hw.h linux-2.6.22-10/drivers/net/e1000e/hw.h ---- linux-2.6.22-0/drivers/net/e1000e/hw.h 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/hw.h 2007-11-21 13:55:23.000000000 -0500 -@@ -0,0 +1,864 @@ -+/******************************************************************************* + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++/** ++ * e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states ++ * @hw: pointer to the HW structure ++ * ++ * Populates "phy" structure with various feature states. ++ * This function is only called by other family-specific ++ * routines. ++ **/ ++static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 data; ++ bool link; + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ DEBUGFUNC("e1000_get_phy_info_ife_ich8lan"); + -+ This program is distributed in the hope 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. ++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); ++ if (ret_val) ++ goto out; + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ if (!link) { ++ DEBUGOUT("Phy info is only valid if link is up\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++ ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); ++ if (ret_val) ++ goto out; ++ phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE) ++ ? false : true; + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ if (phy->polarity_correction) { ++ ret_val = e1000_check_polarity_ife_ich8lan(hw); ++ if (ret_val) ++ goto out; ++ } else { ++ /* Polarity is forced */ ++ phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) ++ ? e1000_rev_polarity_reversed ++ : e1000_rev_polarity_normal; ++ } + -+*******************************************************************************/ ++ ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); ++ if (ret_val) ++ goto out; + -+#ifndef _E1000_HW_H_ -+#define _E1000_HW_H_ ++ phy->is_mdix = (data & IFE_PMC_MDIX_STATUS) ? true : false; + -+#include ++ /* The following parameters are undefined for 10/100 operation. */ ++ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; ++ phy->local_rx = e1000_1000t_rx_status_undefined; ++ phy->remote_rx = e1000_1000t_rx_status_undefined; + -+struct e1000_hw; -+struct e1000_adapter; ++out: ++ return ret_val; ++} + -+#include "defines.h" ++/** ++ * e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY ++ * @hw: pointer to the HW structure ++ * ++ * Polarity is determined on the polarity reversal feature being enabled. ++ * This function is only called by other family-specific ++ * routines. ++ **/ ++static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_data, offset, mask; + -+#define er32(reg) __er32(hw, E1000_##reg) -+#define ew32(reg,val) __ew32(hw, E1000_##reg, (val)) -+#define e1e_flush() er32(STATUS) ++ DEBUGFUNC("e1000_check_polarity_ife_ich8lan"); + -+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \ -+ (writel((value), ((a)->hw_addr + reg + ((offset) << 2)))) -+ -+#define E1000_READ_REG_ARRAY(a, reg, offset) \ -+ (readl((a)->hw_addr + reg + ((offset) << 2))) -+ -+enum e1e_registers { -+ E1000_CTRL = 0x00000, /* Device Control - RW */ -+ E1000_STATUS = 0x00008, /* Device Status - RO */ -+ E1000_EECD = 0x00010, /* EEPROM/Flash Control - RW */ -+ E1000_EERD = 0x00014, /* EEPROM Read - RW */ -+ E1000_CTRL_EXT = 0x00018, /* Extended Device Control - RW */ -+ E1000_FLA = 0x0001C, /* Flash Access - RW */ -+ E1000_MDIC = 0x00020, /* MDI Control - RW */ -+ E1000_SCTL = 0x00024, /* SerDes Control - RW */ -+ E1000_FCAL = 0x00028, /* Flow Control Address Low - RW */ -+ E1000_FCAH = 0x0002C, /* Flow Control Address High -RW */ -+ E1000_FEXTNVM = 0x00028, /* Future Extended NVM - RW */ -+ E1000_FCT = 0x00030, /* Flow Control Type - RW */ -+ E1000_VET = 0x00038, /* VLAN Ether Type - RW */ -+ E1000_ICR = 0x000C0, /* Interrupt Cause Read - R/clr */ -+ E1000_ITR = 0x000C4, /* Interrupt Throttling Rate - RW */ -+ E1000_ICS = 0x000C8, /* Interrupt Cause Set - WO */ -+ E1000_IMS = 0x000D0, /* Interrupt Mask Set - RW */ -+ E1000_IMC = 0x000D8, /* Interrupt Mask Clear - WO */ -+ E1000_IAM = 0x000E0, /* Interrupt Acknowledge Auto Mask */ -+ E1000_RCTL = 0x00100, /* RX Control - RW */ -+ E1000_FCTTV = 0x00170, /* Flow Control Transmit Timer Value - RW */ -+ E1000_TXCW = 0x00178, /* TX Configuration Word - RW */ -+ E1000_RXCW = 0x00180, /* RX Configuration Word - RO */ -+ E1000_TCTL = 0x00400, /* TX Control - RW */ -+ E1000_TCTL_EXT = 0x00404, /* Extended TX Control - RW */ -+ E1000_TIPG = 0x00410, /* TX Inter-packet gap -RW */ -+ E1000_AIT = 0x00458, /* Adaptive Interframe Spacing Throttle - RW */ -+ E1000_LEDCTL = 0x00E00, /* LED Control - RW */ -+ E1000_EXTCNF_CTRL = 0x00F00, /* Extended Configuration Control */ -+ E1000_EXTCNF_SIZE = 0x00F08, /* Extended Configuration Size */ -+ E1000_PHY_CTRL = 0x00F10, /* PHY Control Register in CSR */ -+ E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ -+ E1000_PBS = 0x01008, /* Packet Buffer Size */ -+ E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ -+ E1000_EEWR = 0x0102C, /* EEPROM Write Register - RW */ -+ E1000_FLOP = 0x0103C, /* FLASH Opcode Register */ -+ E1000_ERT = 0x02008, /* Early Rx Threshold - RW */ -+ E1000_FCRTL = 0x02160, /* Flow Control Receive Threshold Low - RW */ -+ E1000_FCRTH = 0x02168, /* Flow Control Receive Threshold High - RW */ -+ E1000_PSRCTL = 0x02170, /* Packet Split Receive Control - RW */ -+ E1000_RDBAL = 0x02800, /* RX Descriptor Base Address Low - RW */ -+ E1000_RDBAH = 0x02804, /* RX Descriptor Base Address High - RW */ -+ E1000_RDLEN = 0x02808, /* RX Descriptor Length - RW */ -+ E1000_RDH = 0x02810, /* RX Descriptor Head - RW */ -+ E1000_RDT = 0x02818, /* RX Descriptor Tail - RW */ -+ E1000_RDTR = 0x02820, /* RX Delay Timer - RW */ -+ E1000_RADV = 0x0282C, /* RX Interrupt Absolute Delay Timer - RW */ -+ -+/* Convenience macros -+ * -+ * Note: "_n" is the queue number of the register to be written to. -+ * -+ * Example usage: -+ * E1000_RDBAL_REG(current_rx_queue) -+ * -+ */ -+#define E1000_RDBAL_REG(_n) (E1000_RDBAL + (_n << 8)) -+ E1000_KABGTXD = 0x03004, /* AFE Band Gap Transmit Ref Data */ -+ E1000_TDBAL = 0x03800, /* TX Descriptor Base Address Low - RW */ -+ E1000_TDBAH = 0x03804, /* TX Descriptor Base Address High - RW */ -+ E1000_TDLEN = 0x03808, /* TX Descriptor Length - RW */ -+ E1000_TDH = 0x03810, /* TX Descriptor Head - RW */ -+ E1000_TDT = 0x03818, /* TX Descriptor Tail - RW */ -+ E1000_TIDV = 0x03820, /* TX Interrupt Delay Value - RW */ -+ E1000_TXDCTL = 0x03828, /* TX Descriptor Control - RW */ -+ E1000_TADV = 0x0382C, /* TX Interrupt Absolute Delay Val - RW */ -+ E1000_TARC0 = 0x03840, /* TX Arbitration Count (0) */ -+ E1000_TXDCTL1 = 0x03928, /* TX Descriptor Control (1) - RW */ -+ E1000_TARC1 = 0x03940, /* TX Arbitration Count (1) */ -+ E1000_CRCERRS = 0x04000, /* CRC Error Count - R/clr */ -+ E1000_ALGNERRC = 0x04004, /* Alignment Error Count - R/clr */ -+ E1000_SYMERRS = 0x04008, /* Symbol Error Count - R/clr */ -+ E1000_RXERRC = 0x0400C, /* Receive Error Count - R/clr */ -+ E1000_MPC = 0x04010, /* Missed Packet Count - R/clr */ -+ E1000_SCC = 0x04014, /* Single Collision Count - R/clr */ -+ E1000_ECOL = 0x04018, /* Excessive Collision Count - R/clr */ -+ E1000_MCC = 0x0401C, /* Multiple Collision Count - R/clr */ -+ E1000_LATECOL = 0x04020, /* Late Collision Count - R/clr */ -+ E1000_COLC = 0x04028, /* Collision Count - R/clr */ -+ E1000_DC = 0x04030, /* Defer Count - R/clr */ -+ E1000_TNCRS = 0x04034, /* TX-No CRS - R/clr */ -+ E1000_SEC = 0x04038, /* Sequence Error Count - R/clr */ -+ E1000_CEXTERR = 0x0403C, /* Carrier Extension Error Count - R/clr */ -+ E1000_RLEC = 0x04040, /* Receive Length Error Count - R/clr */ -+ E1000_XONRXC = 0x04048, /* XON RX Count - R/clr */ -+ E1000_XONTXC = 0x0404C, /* XON TX Count - R/clr */ -+ E1000_XOFFRXC = 0x04050, /* XOFF RX Count - R/clr */ -+ E1000_XOFFTXC = 0x04054, /* XOFF TX Count - R/clr */ -+ E1000_FCRUC = 0x04058, /* Flow Control RX Unsupported Count- R/clr */ -+ E1000_PRC64 = 0x0405C, /* Packets RX (64 bytes) - R/clr */ -+ E1000_PRC127 = 0x04060, /* Packets RX (65-127 bytes) - R/clr */ -+ E1000_PRC255 = 0x04064, /* Packets RX (128-255 bytes) - R/clr */ -+ E1000_PRC511 = 0x04068, /* Packets RX (255-511 bytes) - R/clr */ -+ E1000_PRC1023 = 0x0406C, /* Packets RX (512-1023 bytes) - R/clr */ -+ E1000_PRC1522 = 0x04070, /* Packets RX (1024-1522 bytes) - R/clr */ -+ E1000_GPRC = 0x04074, /* Good Packets RX Count - R/clr */ -+ E1000_BPRC = 0x04078, /* Broadcast Packets RX Count - R/clr */ -+ E1000_MPRC = 0x0407C, /* Multicast Packets RX Count - R/clr */ -+ E1000_GPTC = 0x04080, /* Good Packets TX Count - R/clr */ -+ E1000_GORCL = 0x04088, /* Good Octets RX Count Low - R/clr */ -+ E1000_GORCH = 0x0408C, /* Good Octets RX Count High - R/clr */ -+ E1000_GOTCL = 0x04090, /* Good Octets TX Count Low - R/clr */ -+ E1000_GOTCH = 0x04094, /* Good Octets TX Count High - R/clr */ -+ E1000_RNBC = 0x040A0, /* RX No Buffers Count - R/clr */ -+ E1000_RUC = 0x040A4, /* RX Undersize Count - R/clr */ -+ E1000_RFC = 0x040A8, /* RX Fragment Count - R/clr */ -+ E1000_ROC = 0x040AC, /* RX Oversize Count - R/clr */ -+ E1000_RJC = 0x040B0, /* RX Jabber Count - R/clr */ -+ E1000_MGTPRC = 0x040B4, /* Management Packets RX Count - R/clr */ -+ E1000_MGTPDC = 0x040B8, /* Management Packets Dropped Count - R/clr */ -+ E1000_MGTPTC = 0x040BC, /* Management Packets TX Count - R/clr */ -+ E1000_TORL = 0x040C0, /* Total Octets RX Low - R/clr */ -+ E1000_TORH = 0x040C4, /* Total Octets RX High - R/clr */ -+ E1000_TOTL = 0x040C8, /* Total Octets TX Low - R/clr */ -+ E1000_TOTH = 0x040CC, /* Total Octets TX High - R/clr */ -+ E1000_TPR = 0x040D0, /* Total Packets RX - R/clr */ -+ E1000_TPT = 0x040D4, /* Total Packets TX - R/clr */ -+ E1000_PTC64 = 0x040D8, /* Packets TX (64 bytes) - R/clr */ -+ E1000_PTC127 = 0x040DC, /* Packets TX (65-127 bytes) - R/clr */ -+ E1000_PTC255 = 0x040E0, /* Packets TX (128-255 bytes) - R/clr */ -+ E1000_PTC511 = 0x040E4, /* Packets TX (256-511 bytes) - R/clr */ -+ E1000_PTC1023 = 0x040E8, /* Packets TX (512-1023 bytes) - R/clr */ -+ E1000_PTC1522 = 0x040EC, /* Packets TX (1024-1522 Bytes) - R/clr */ -+ E1000_MPTC = 0x040F0, /* Multicast Packets TX Count - R/clr */ -+ E1000_BPTC = 0x040F4, /* Broadcast Packets TX Count - R/clr */ -+ E1000_TSCTC = 0x040F8, /* TCP Segmentation Context TX - R/clr */ -+ E1000_TSCTFC = 0x040FC, /* TCP Segmentation Context TX Fail - R/clr */ -+ E1000_IAC = 0x04100, /* Interrupt Assertion Count */ -+ E1000_ICRXPTC = 0x04104, /* Irq Cause Rx Packet Timer Expire Count */ -+ E1000_ICRXATC = 0x04108, /* Irq Cause Rx Abs Timer Expire Count */ -+ E1000_ICTXPTC = 0x0410C, /* Irq Cause Tx Packet Timer Expire Count */ -+ E1000_ICTXATC = 0x04110, /* Irq Cause Tx Abs Timer Expire Count */ -+ E1000_ICTXQEC = 0x04118, /* Irq Cause Tx Queue Empty Count */ -+ E1000_ICTXQMTC = 0x0411C, /* Irq Cause Tx Queue MinThreshold Count */ -+ E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */ -+ E1000_ICRXOC = 0x04124, /* Irq Cause Receiver Overrun Count */ -+ E1000_RXCSUM = 0x05000, /* RX Checksum Control - RW */ -+ E1000_RFCTL = 0x05008, /* Receive Filter Control*/ -+ E1000_MTA = 0x05200, /* Multicast Table Array - RW Array */ -+ E1000_RA = 0x05400, /* Receive Address - RW Array */ -+ E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */ -+ E1000_WUC = 0x05800, /* Wakeup Control - RW */ -+ E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */ -+ E1000_WUS = 0x05810, /* Wakeup Status - RO */ -+ E1000_MANC = 0x05820, /* Management Control - RW */ -+ E1000_FFLT = 0x05F00, /* Flexible Filter Length Table - RW Array */ -+ E1000_HOST_IF = 0x08800, /* Host Interface */ -+ -+ E1000_KMRNCTRLSTA = 0x00034, /* MAC-PHY interface - RW */ -+ E1000_MANC2H = 0x05860, /* Management Control To Host - RW */ -+ E1000_SW_FW_SYNC = 0x05B5C, /* Software-Firmware Synchronization - RW */ -+ E1000_GCR = 0x05B00, /* PCI-Ex Control */ -+ E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */ -+ E1000_SWSM = 0x05B50, /* SW Semaphore */ -+ E1000_FWSM = 0x05B54, /* FW Semaphore */ -+ E1000_HICR = 0x08F00, /* Host Inteface Control */ -+}; ++ /* ++ * Polarity is determined based on the reversal feature ++ * being enabled. ++ */ ++ if (phy->polarity_correction) { ++ offset = IFE_PHY_EXTENDED_STATUS_CONTROL; ++ mask = IFE_PESC_POLARITY_REVERSED; ++ } else { ++ offset = IFE_PHY_SPECIAL_CONTROL; ++ mask = IFE_PSC_FORCE_POLARITY; ++ } + -+/* RSS registers */ ++ ret_val = phy->ops.read_reg(hw, offset, &phy_data); + -+/* IGP01E1000 Specific Registers */ -+#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ -+#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ -+#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ -+#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ -+#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ -+#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ -+ -+#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 -+#define IGP01E1000_PHY_POLARITY_MASK 0x0078 -+ -+#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 -+#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ -+ -+#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 -+ -+#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ -+#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ -+#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ -+ -+#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 -+ -+#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 -+#define IGP01E1000_PSSR_MDIX 0x0008 -+#define IGP01E1000_PSSR_SPEED_MASK 0xC000 -+#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 -+ -+#define IGP02E1000_PHY_CHANNEL_NUM 4 -+#define IGP02E1000_PHY_AGC_A 0x11B1 -+#define IGP02E1000_PHY_AGC_B 0x12B1 -+#define IGP02E1000_PHY_AGC_C 0x14B1 -+#define IGP02E1000_PHY_AGC_D 0x18B1 -+ -+#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ -+#define IGP02E1000_AGC_LENGTH_MASK 0x7F -+#define IGP02E1000_AGC_RANGE 15 -+ -+/* manage.c */ -+#define E1000_VFTA_ENTRY_SHIFT 5 -+#define E1000_VFTA_ENTRY_MASK 0x7F -+#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F -+ -+#define E1000_HICR_EN 0x01 /* Enable bit - RO */ -+#define E1000_HICR_C 0x02 /* Driver sets this bit when done -+ * to put command in RAM */ -+#define E1000_HICR_FW_RESET_ENABLE 0x40 -+#define E1000_HICR_FW_RESET 0x80 -+ -+#define E1000_FWSM_MODE_MASK 0xE -+#define E1000_FWSM_MODE_SHIFT 1 -+ -+#define E1000_MNG_IAMT_MODE 0x3 -+#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 -+#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 -+#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 -+#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 -+#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1 -+#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2 -+ -+/* nvm.c */ -+#define E1000_STM_OPCODE 0xDB00 ++ if (!ret_val) ++ phy->cable_polarity = (phy_data & mask) ++ ? e1000_rev_polarity_reversed ++ : e1000_rev_polarity_normal; + -+#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000 -+#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16 -+#define E1000_KMRNCTRLSTA_REN 0x00200000 -+#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ -+#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ ++ return ret_val; ++} + -+#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 -+#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ -+#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */ -+#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */ ++/** ++ * e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state ++ * @hw: pointer to the HW structure ++ * @active: true to enable LPLU, false to disable ++ * ++ * Sets the LPLU D0 state according to the active flag. When ++ * activating LPLU this function also disables smart speed ++ * and vice versa. LPLU will not be activated unless the ++ * device autonegotiation advertisement meets standards of ++ * either 10 or 10/100 or 10/100/1000 at all duplexes. ++ * This is a function pointer entry point only called by ++ * PHY setup routines. ++ **/ ++static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, ++ bool active) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ u32 phy_ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; + -+/* IFE PHY Extended Status Control */ -+#define IFE_PESC_POLARITY_REVERSED 0x0100 ++ DEBUGFUNC("e1000_set_d0_lplu_state_ich8lan"); + -+/* IFE PHY Special Control */ -+#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 -+#define IFE_PSC_FORCE_POLARITY 0x0020 ++ if (phy->type == e1000_phy_ife) ++ goto out; + -+/* IFE PHY Special Control and LED Control */ -+#define IFE_PSCL_PROBE_MODE 0x0020 -+#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 */ ++ phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); + -+/* IFE PHY MDIX Control */ -+#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */ -+#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */ -+#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */ -+ -+#define E1000_CABLE_LENGTH_UNDEFINED 0xFF -+ -+#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_82571EB_QUAD_FIBER 0x10A5 -+#define E1000_DEV_ID_82571EB_QUAD_COPPER_LP 0x10BC -+#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_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_IFE_GT 0x10C4 -+#define E1000_DEV_ID_ICH8_IFE_G 0x10C5 -+#define E1000_DEV_ID_ICH8_IGP_M 0x104D -+#define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD -+#define E1000_DEV_ID_ICH9_IGP_C 0x294C -+#define E1000_DEV_ID_ICH9_IFE 0x10C0 -+#define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 -+#define E1000_DEV_ID_ICH9_IFE_G 0x10C2 -+ -+#define E1000_FUNC_1 1 -+ -+enum e1000_mac_type { -+ e1000_82571, -+ e1000_82572, -+ e1000_82573, -+ e1000_80003es2lan, -+ e1000_ich8lan, -+ e1000_ich9lan, -+}; ++ if (active) { ++ phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); + -+enum e1000_media_type { -+ e1000_media_type_unknown = 0, -+ e1000_media_type_copper = 1, -+ e1000_media_type_fiber = 2, -+ e1000_media_type_internal_serdes = 3, -+ e1000_num_media_types -+}; ++ /* ++ * Call gig speed drop workaround on LPLU before accessing ++ * any PHY registers ++ */ ++ if ((hw->mac.type == e1000_ich8lan) && ++ (hw->phy.type == e1000_phy_igp_3)) ++ e1000_gig_downshift_workaround_ich8lan(hw); + -+enum e1000_nvm_type { -+ e1000_nvm_unknown = 0, -+ e1000_nvm_none, -+ e1000_nvm_eeprom_spi, -+ e1000_nvm_flash_hw, -+ e1000_nvm_flash_sw -+}; ++ /* When LPLU is enabled, we should disable SmartSpeed */ ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else { ++ phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); + -+enum e1000_nvm_override { -+ e1000_nvm_override_none = 0, -+ e1000_nvm_override_spi_small, -+ e1000_nvm_override_spi_large -+}; ++ /* ++ * 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 (phy->smart_speed == e1000_smart_speed_on) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+enum e1000_phy_type { -+ e1000_phy_unknown = 0, -+ e1000_phy_none, -+ e1000_phy_m88, -+ e1000_phy_igp, -+ e1000_phy_igp_2, -+ e1000_phy_gg82563, -+ e1000_phy_igp_3, -+ e1000_phy_ife, -+}; ++ data |= IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else if (phy->smart_speed == e1000_smart_speed_off) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+enum e1000_bus_width { -+ e1000_bus_width_unknown = 0, -+ e1000_bus_width_pcie_x1, -+ e1000_bus_width_pcie_x2, -+ e1000_bus_width_pcie_x4 = 4, -+ e1000_bus_width_32, -+ e1000_bus_width_64, -+ e1000_bus_width_reserved -+}; ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } ++ } + -+enum e1000_1000t_rx_status { -+ e1000_1000t_rx_status_not_ok = 0, -+ e1000_1000t_rx_status_ok, -+ e1000_1000t_rx_status_undefined = 0xFF -+}; ++out: ++ return ret_val; ++} + -+enum e1000_rev_polarity{ -+ e1000_rev_polarity_normal = 0, -+ e1000_rev_polarity_reversed, -+ e1000_rev_polarity_undefined = 0xFF -+}; ++/** ++ * e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state ++ * @hw: pointer to the HW structure ++ * @active: true to enable LPLU, false to disable ++ * ++ * Sets the LPLU D3 state according to the active flag. When ++ * activating LPLU this function also disables smart speed ++ * and vice versa. LPLU will not be activated unless the ++ * device autonegotiation advertisement meets standards of ++ * either 10 or 10/100 or 10/100/1000 at all duplexes. ++ * This is a function pointer entry point only called by ++ * PHY setup routines. ++ **/ ++static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, ++ bool active) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ u32 phy_ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; + -+enum e1000_fc_mode { -+ e1000_fc_none = 0, -+ e1000_fc_rx_pause, -+ e1000_fc_tx_pause, -+ e1000_fc_full, -+ e1000_fc_default = 0xFF -+}; ++ DEBUGFUNC("e1000_set_d3_lplu_state_ich8lan"); + -+enum e1000_ms_type { -+ e1000_ms_hw_default = 0, -+ e1000_ms_force_master, -+ e1000_ms_force_slave, -+ e1000_ms_auto -+}; ++ phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); + -+enum e1000_smart_speed { -+ e1000_smart_speed_default = 0, -+ e1000_smart_speed_on, -+ e1000_smart_speed_off -+}; ++ if (!active) { ++ phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); ++ /* ++ * 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 (phy->smart_speed == e1000_smart_speed_on) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+/* Receive Descriptor */ -+struct e1000_rx_desc { -+ u64 buffer_addr; /* Address of the descriptor's data buffer */ -+ u16 length; /* Length of data DMAed into data buffer */ -+ u16 csum; /* Packet checksum */ -+ u8 status; /* Descriptor status */ -+ u8 errors; /* Descriptor Errors */ -+ u16 special; -+}; ++ data |= IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else if (phy->smart_speed == e1000_smart_speed_off) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+/* Receive Descriptor - Extended */ -+union e1000_rx_desc_extended { -+ struct { -+ u64 buffer_addr; -+ u64 reserved; -+ } read; -+ struct { -+ struct { -+ u32 mrq; /* Multiple Rx Queues */ -+ union { -+ u32 rss; /* RSS Hash */ -+ struct { -+ u16 ip_id; /* IP id */ -+ u16 csum; /* Packet Checksum */ -+ } csum_ip; -+ } hi_dword; -+ } lower; -+ struct { -+ u32 status_error; /* ext status/error */ -+ u16 length; -+ u16 vlan; /* VLAN tag */ -+ } upper; -+ } wb; /* writeback */ -+}; ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } ++ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || ++ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || ++ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { ++ phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); + -+#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 */ -+ u64 buffer_addr[MAX_PS_BUFFERS]; -+ } read; -+ struct { -+ struct { -+ u32 mrq; /* Multiple Rx Queues */ -+ union { -+ u32 rss; /* RSS Hash */ -+ struct { -+ u16 ip_id; /* IP id */ -+ u16 csum; /* Packet Checksum */ -+ } csum_ip; -+ } hi_dword; -+ } lower; -+ struct { -+ u32 status_error; /* ext status/error */ -+ u16 length0; /* length of buffer 0 */ -+ u16 vlan; /* VLAN tag */ -+ } middle; -+ struct { -+ u16 header_status; -+ u16 length[3]; /* length of buffers 1-3 */ -+ } upper; -+ u64 reserved; -+ } wb; /* writeback */ -+}; ++ /* ++ * Call gig speed drop workaround on LPLU before accessing ++ * any PHY registers ++ */ ++ if ((hw->mac.type == e1000_ich8lan) && ++ (hw->phy.type == e1000_phy_igp_3)) ++ e1000_gig_downshift_workaround_ich8lan(hw); + -+/* Transmit Descriptor */ -+struct e1000_tx_desc { -+ u64 buffer_addr; /* Address of the descriptor's data buffer */ -+ union { -+ u32 data; -+ struct { -+ u16 length; /* Data buffer length */ -+ u8 cso; /* Checksum offset */ -+ u8 cmd; /* Descriptor control */ -+ } flags; -+ } lower; -+ union { -+ u32 data; -+ struct { -+ u8 status; /* Descriptor status */ -+ u8 css; /* Checksum start */ -+ u16 special; -+ } fields; -+ } upper; ++ /* When LPLU is enabled, we should disable SmartSpeed */ ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_valid_nvm_bank_detect_ich8lan - finds out the valid bank 0 or 1 ++ * @hw: pointer to the HW structure ++ * @bank: pointer to the variable that returns the active bank ++ * ++ * Reads signature byte from the NVM using the flash access registers. ++ **/ ++static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ /* flash bank size is in words */ ++ u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); ++ u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; ++ u8 bank_high_byte = 0; ++ ++ if (hw->mac.type != e1000_ich10lan) { ++ if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL) ++ *bank = 1; ++ else ++ *bank = 0; ++ } else if (hw->dev_spec != NULL) { ++ /* ++ * Make sure the signature for bank 0 is valid, ++ * if not check for bank1 ++ */ ++ e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte); ++ if ((bank_high_byte & 0xC0) == 0x80) { ++ *bank = 0; ++ } else { ++ /* ++ * find if segment 1 is valid by verifying ++ * bit 15:14 = 10b in word 0x13 ++ */ ++ e1000_read_flash_byte_ich8lan(hw, ++ act_offset + bank1_offset, ++ &bank_high_byte); ++ ++ /* bank1 has a valid signature equivalent to SEC1V */ ++ if ((bank_high_byte & 0xC0) == 0x80) { ++ *bank = 1; ++ } else { ++ DEBUGOUT("ERROR: EEPROM not present\n"); ++ ret_val = -E1000_ERR_NVM; ++ } ++ } ++ } else { ++ DEBUGOUT("DEV SPEC is NULL\n"); ++ ret_val = -E1000_ERR_NVM; ++ } ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_read_nvm_ich8lan - Read word(s) from the NVM ++ * @hw: pointer to the HW structure ++ * @offset: The offset (in bytes) of the word(s) to read. ++ * @words: Size of data to read in words ++ * @data: Pointer to the word(s) to read at offset. ++ * ++ * Reads a word(s) from the NVM using the flash access registers. ++ **/ ++static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ u32 act_offset; ++ s32 ret_val = E1000_SUCCESS; ++ u32 bank = 0; ++ u16 i, word; ++ ++ DEBUGFUNC("e1000_read_nvm_ich8lan"); ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ if (!dev_spec) { ++ DEBUGOUT("dev_spec pointer is set to NULL.\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); ++ if (ret_val != E1000_SUCCESS) ++ goto out; ++ ++ act_offset = (bank) ? nvm->flash_bank_size : 0; ++ act_offset += offset; ++ ++ for (i = 0; i < words; i++) { ++ if ((dev_spec->shadow_ram) && ++ (dev_spec->shadow_ram[offset+i].modified)) { ++ data[i] = dev_spec->shadow_ram[offset+i].value; ++ } else { ++ ret_val = e1000_read_flash_word_ich8lan(hw, ++ act_offset + i, ++ &word); ++ if (ret_val) ++ break; ++ data[i] = word; ++ } ++ } ++ ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_flash_cycle_init_ich8lan - Initialize flash ++ * @hw: pointer to the HW structure ++ * ++ * This function does initial flash setup so that a new read/write/erase cycle ++ * can be started. ++ **/ ++static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) ++{ ++ union ich8_hws_flash_status hsfsts; ++ s32 ret_val = -E1000_ERR_NVM; ++ s32 i = 0; ++ ++ DEBUGFUNC("e1000_flash_cycle_init_ich8lan"); ++ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); ++ ++ /* Check if the flash descriptor is valid */ ++ if (hsfsts.hsf_status.fldesvalid == 0) { ++ DEBUGOUT("Flash descriptor invalid. " ++ "SW Sequencing must be used."); ++ goto out; ++ } ++ ++ /* Clear FCERR and DAEL in hw status by writing 1 */ ++ hsfsts.hsf_status.flcerr = 1; ++ hsfsts.hsf_status.dael = 1; ++ ++ E1000_WRITE_FLASH_REG16(hw, ICH_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 hardware reset, which can then be used as an ++ * indication whether a cycle is in progress or has been ++ * completed. ++ */ ++ ++ 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_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); ++ ret_val = E1000_SUCCESS; ++ } else { ++ /* ++ * Otherwise poll for sometime so the current ++ * cycle has a chance to end before giving up. ++ */ ++ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ++ ICH_FLASH_HSFSTS); ++ if (hsfsts.hsf_status.flcinprog == 0) { ++ ret_val = E1000_SUCCESS; ++ break; ++ } ++ usec_delay(1); ++ } ++ if (ret_val == E1000_SUCCESS) { ++ /* ++ * Successful in waiting for previous cycle to timeout, ++ * now set the Flash Cycle Done. ++ */ ++ hsfsts.hsf_status.flcdone = 1; ++ E1000_WRITE_FLASH_REG16(hw, ++ ICH_FLASH_HSFSTS, ++ hsfsts.regval); ++ } else { ++ DEBUGOUT("Flash controller busy, cannot get access"); ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase) ++ * @hw: pointer to the HW structure ++ * @timeout: maximum time to wait for completion ++ * ++ * This function starts a flash cycle and waits for its completion. ++ **/ ++static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) ++{ ++ union ich8_hws_flash_ctrl hsflctl; ++ union ich8_hws_flash_status hsfsts; ++ s32 ret_val = -E1000_ERR_NVM; ++ u32 i = 0; ++ ++ DEBUGFUNC("e1000_flash_cycle_ich8lan"); ++ ++ /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ ++ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); ++ hsflctl.hsf_ctrl.flcgo = 1; ++ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); ++ ++ /* wait till FDONE bit is set to 1 */ ++ do { ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); ++ if (hsfsts.hsf_status.flcdone == 1) ++ break; ++ usec_delay(1); ++ } while (i++ < timeout); ++ ++ if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) ++ ret_val = E1000_SUCCESS; ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_read_flash_word_ich8lan - Read word from flash ++ * @hw: pointer to the HW structure ++ * @offset: offset to data location ++ * @data: pointer to the location for storing the data ++ * ++ * Reads the flash word at offset into data. Offset is converted ++ * to bytes before read. ++ **/ ++static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, ++ u16 *data) ++{ ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_read_flash_word_ich8lan"); ++ ++ if (!data) { ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ /* Must convert offset into bytes. */ ++ offset <<= 1; ++ ++ ret_val = e1000_read_flash_data_ich8lan(hw, offset, 2, data); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_flash_byte_ich8lan - Read byte from flash ++ * @hw: pointer to the HW structure ++ * @offset: The offset of the byte to read. ++ * @data: Pointer to a byte to store the value read. ++ * ++ * Reads a single byte from the NVM using the flash access registers. ++ **/ ++static s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8* data) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 word = 0; ++ ++ ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word); ++ if (ret_val) ++ goto out; ++ ++ *data = (u8)word; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_flash_data_ich8lan - Read byte or word from NVM ++ * @hw: pointer to the HW structure ++ * @offset: The offset (in bytes) 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. ++ * ++ * Reads a byte or word from the NVM using the flash access registers. ++ **/ ++static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8 size, u16* data) ++{ ++ union ich8_hws_flash_status hsfsts; ++ union ich8_hws_flash_ctrl hsflctl; ++ u32 flash_linear_addr; ++ u32 flash_data = 0; ++ s32 ret_val = -E1000_ERR_NVM; ++ u8 count = 0; ++ ++ DEBUGFUNC("e1000_read_flash_data_ich8lan"); ++ ++ if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) ++ goto out; ++ ++ flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + ++ hw->nvm.flash_base_addr; ++ ++ do { ++ usec_delay(1); ++ /* Steps */ ++ ret_val = e1000_flash_cycle_init_ich8lan(hw); ++ if (ret_val != E1000_SUCCESS) ++ break; ++ ++ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); ++ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ ++ hsflctl.hsf_ctrl.fldbcount = size - 1; ++ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; ++ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); ++ ++ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); ++ ++ ret_val = e1000_flash_cycle_ich8lan(hw, ++ ICH_FLASH_READ_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 (ret_val == E1000_SUCCESS) { ++ flash_data = E1000_READ_FLASH_REG(hw, ICH_FLASH_FDATA0); ++ if (size == 1) { ++ *data = (u8)(flash_data & 0x000000FF); ++ } else if (size == 2) { ++ *data = (u16)(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... ++ * ICH_FLASH_CYCLE_REPEAT_COUNT times. ++ */ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ++ ICH_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++ < ICH_FLASH_CYCLE_REPEAT_COUNT); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_nvm_ich8lan - Write word(s) to the NVM ++ * @hw: pointer to the HW structure ++ * @offset: The offset (in bytes) of the word(s) to write. ++ * @words: Size of data to write in words ++ * @data: Pointer to the word(s) to write at offset. ++ * ++ * Writes a byte or word to the NVM using the flash access registers. ++ **/ ++static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i; ++ ++ DEBUGFUNC("e1000_write_nvm_ich8lan"); ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ if (!dev_spec) { ++ DEBUGOUT("dev_spec pointer is set to NULL.\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ for (i = 0; i < words; i++) { ++ dev_spec->shadow_ram[offset+i].modified = true; ++ dev_spec->shadow_ram[offset+i].value = data[i]; ++ } ++ ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM ++ * @hw: pointer to the HW structure ++ * ++ * The NVM checksum is updated by calling the generic update_nvm_checksum, ++ * which writes the checksum to the shadow ram. The changes in the shadow ++ * ram are then committed to the EEPROM by processing each bank at a time ++ * checking for the modified bit and writing only the pending changes. ++ * After a successful commit, the shadow ram is cleared and is ready for ++ * future writes. ++ **/ ++static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ u32 i, act_offset, new_bank_offset, old_bank_offset, bank; ++ s32 ret_val; ++ u16 data; ++ ++ DEBUGFUNC("e1000_update_nvm_checksum_ich8lan"); ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ ret_val = e1000_update_nvm_checksum_generic(hw); ++ if (ret_val) ++ goto out; ++ ++ if (nvm->type != e1000_nvm_flash_sw) ++ goto out; ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * 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 ++ */ ++ ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); ++ if (ret_val != E1000_SUCCESS) ++ goto out; ++ ++ if (bank == 0) { ++ new_bank_offset = nvm->flash_bank_size; ++ old_bank_offset = 0; ++ e1000_erase_flash_bank_ich8lan(hw, 1); ++ } else { ++ old_bank_offset = nvm->flash_bank_size; ++ new_bank_offset = 0; ++ e1000_erase_flash_bank_ich8lan(hw, 0); ++ } ++ ++ 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 (dev_spec->shadow_ram[i].modified) { ++ data = dev_spec->shadow_ram[i].value; ++ } else { ++ e1000_read_flash_word_ich8lan(hw, ++ i + old_bank_offset, ++ &data); ++ } ++ ++ /* ++ * 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_ICH_NVM_SIG_WORD) ++ data |= E1000_ICH_NVM_SIG_MASK; ++ ++ /* Convert offset to bytes. */ ++ act_offset = (i + new_bank_offset) << 1; ++ ++ usec_delay(100); ++ /* Write the bytes to the new bank. */ ++ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, ++ act_offset, ++ (u8)data); ++ if (ret_val) ++ break; ++ ++ usec_delay(100); ++ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, ++ act_offset + 1, ++ (u8)(data >> 8)); ++ if (ret_val) ++ break; ++ } ++ ++ /* ++ * Don't bother writing the segment valid bits if sector ++ * programming failed. ++ */ ++ if (ret_val) { ++ /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */ ++ DEBUGOUT("Flash commit failed.\n"); ++ nvm->ops.release(hw); ++ goto out; ++ } ++ ++ /* ++ * 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 ++ */ ++ act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; ++ e1000_read_flash_word_ich8lan(hw, act_offset, &data); ++ data &= 0xBFFF; ++ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, ++ act_offset * 2 + 1, ++ (u8)(data >> 8)); ++ if (ret_val) { ++ nvm->ops.release(hw); ++ goto out; ++ } ++ ++ /* ++ * 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 ++ */ ++ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; ++ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); ++ if (ret_val) { ++ nvm->ops.release(hw); ++ goto out; ++ } ++ ++ /* Great! Everything worked, we can now clear the cached entries. */ ++ for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) { ++ dev_spec->shadow_ram[i].modified = false; ++ dev_spec->shadow_ram[i].value = 0xFFFF; ++ } ++ ++ nvm->ops.release(hw); ++ ++ /* ++ * Reload the EEPROM, or else modifications will not appear ++ * until after the next adapter reset. ++ */ ++ nvm->ops.reload(hw); ++ msec_delay(10); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum ++ * @hw: pointer to the HW structure ++ * ++ * Check to see if checksum needs to be fixed by reading bit 6 in word 0x19. ++ * If the bit is 0, that the EEPROM had been modified, but the checksum was ++ * not calculated, in which case we need to calculate the checksum and set ++ * bit 6. ++ **/ ++static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; ++ ++ DEBUGFUNC("e1000_validate_nvm_checksum_ich8lan"); ++ ++ /* ++ * Read 0x19 and check bit 6. If this bit is 0, the checksum ++ * needs to be fixed. This bit is an indication that the NVM ++ * was prepared by OEM software and did not calculate the ++ * checksum...a likely scenario. ++ */ ++ ret_val = hw->nvm.ops.read(hw, 0x19, 1, &data); ++ if (ret_val) ++ goto out; ++ ++ if ((data & 0x40) == 0) { ++ data |= 0x40; ++ ret_val = hw->nvm.ops.write(hw, 0x19, 1, &data); ++ if (ret_val) ++ goto out; ++ ret_val = hw->nvm.ops.update(hw); ++ if (ret_val) ++ goto out; ++ } ++ ++ ret_val = e1000_validate_nvm_checksum_generic(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000e_write_protect_nvm_ich8lan - Make the NVM read-only ++ * @hw: pointer to the HW structure ++ * ++ * To prevent malicious write/erase of the NVM, set it to be read-only ++ * so that the hardware ignores all write/erase cycles of the NVM via ++ * the flash control registers. The shadow-ram copy of the NVM will ++ * still be updated, however any updates to this copy will not stick ++ * across driver reloads. ++ **/ ++void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw) ++{ ++ union ich8_flash_protected_range pr0; ++ union ich8_hws_flash_status hsfsts; ++ u32 gfpreg; ++ s32 ret_val; ++ ++ ret_val = e1000_acquire_swflag_ich8lan(hw); ++ if (ret_val) ++ return; ++ ++ gfpreg = E1000_READ_FLASH_REG(hw, ICH_FLASH_GFPREG); ++ ++ /* Write-protect GbE Sector of NVM */ ++ pr0.regval = E1000_READ_FLASH_REG(hw, ICH_FLASH_PR0); ++ pr0.range.base = gfpreg & FLASH_GFPREG_BASE_MASK; ++ pr0.range.limit = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK); ++ pr0.range.wpe = true; ++ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_PR0, pr0.regval); ++ ++ /* ++ * Lock down a subset of GbE Flash Control Registers, e.g. ++ * PR0 to prevent the write-protection from being lifted. ++ * Once FLOCKDN is set, the registers protected by it cannot ++ * be written until FLOCKDN is cleared by a hardware reset. ++ */ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFSTS); ++ hsfsts.hsf_status.flockdn = true; ++ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFSTS, hsfsts.regval); ++ ++ e1000_release_swflag_ich8lan(hw); ++} ++ ++/** ++ * e1000_write_flash_data_ich8lan - Writes bytes to the NVM ++ * @hw: pointer to the HW structure ++ * @offset: The offset (in bytes) 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. ++ * ++ * Writes one/two bytes to the NVM using the flash access registers. ++ **/ ++static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8 size, u16 data) ++{ ++ union ich8_hws_flash_status hsfsts; ++ union ich8_hws_flash_ctrl hsflctl; ++ u32 flash_linear_addr; ++ u32 flash_data = 0; ++ s32 ret_val = -E1000_ERR_NVM; ++ u8 count = 0; ++ ++ DEBUGFUNC("e1000_write_ich8_data"); ++ ++ if (size < 1 || size > 2 || data > size * 0xff || ++ offset > ICH_FLASH_LINEAR_ADDR_MASK) ++ goto out; ++ ++ flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + ++ hw->nvm.flash_base_addr; ++ ++ do { ++ usec_delay(1); ++ /* Steps */ ++ ret_val = e1000_flash_cycle_init_ich8lan(hw); ++ if (ret_val != E1000_SUCCESS) ++ break; ++ ++ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ICH_FLASH_HSFCTL); ++ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ ++ hsflctl.hsf_ctrl.fldbcount = size -1; ++ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; ++ E1000_WRITE_FLASH_REG16(hw, ICH_FLASH_HSFCTL, hsflctl.regval); ++ ++ E1000_WRITE_FLASH_REG(hw, ICH_FLASH_FADDR, flash_linear_addr); ++ ++ if (size == 1) ++ flash_data = (u32)data & 0x00FF; ++ else ++ flash_data = (u32)data; ++ ++ E1000_WRITE_FLASH_REG(hw, ICH_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 ++ */ ++ ret_val = e1000_flash_cycle_ich8lan(hw, ++ ICH_FLASH_WRITE_COMMAND_TIMEOUT); ++ if (ret_val == 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...ICH_FLASH_CYCLE_REPEAT_COUNT times. ++ */ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ++ ICH_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++ < ICH_FLASH_CYCLE_REPEAT_COUNT); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_flash_byte_ich8lan - Write a single byte to NVM ++ * @hw: pointer to the HW structure ++ * @offset: The index of the byte to read. ++ * @data: The byte to write to the NVM. ++ * ++ * Writes a single byte to the NVM using the flash access registers. ++ **/ ++static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, ++ u8 data) ++{ ++ u16 word = (u16)data; ++ ++ DEBUGFUNC("e1000_write_flash_byte_ich8lan"); ++ ++ return e1000_write_flash_data_ich8lan(hw, offset, 1, word); ++} ++ ++/** ++ * e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM ++ * @hw: pointer to the HW structure ++ * @offset: The offset of the byte to write. ++ * @byte: The byte to write to the NVM. ++ * ++ * Writes a single byte to the NVM using the flash access registers. ++ * Goes through a retry algorithm before giving up. ++ **/ ++static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, ++ u32 offset, u8 byte) ++{ ++ s32 ret_val; ++ u16 program_retries; ++ ++ DEBUGFUNC("e1000_retry_write_flash_byte_ich8lan"); ++ ++ ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); ++ if (ret_val == E1000_SUCCESS) ++ goto out; ++ ++ for (program_retries = 0; program_retries < 100; program_retries++) { ++ DEBUGOUT2("Retrying Byte %2.2X at offset %u\n", byte, offset); ++ usec_delay(100); ++ ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); ++ if (ret_val == E1000_SUCCESS) ++ break; ++ } ++ if (program_retries == 100) { ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM ++ * @hw: pointer to the HW structure ++ * @bank: 0 for first bank, 1 for second bank, etc. ++ * ++ * Erases the bank specified. Each bank is a 4k block. Banks are 0 based. ++ * bank N is 4096 * N + flash_reg_addr. ++ **/ ++static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ union ich8_hws_flash_status hsfsts; ++ union ich8_hws_flash_ctrl hsflctl; ++ u32 flash_linear_addr; ++ /* bank size is in 16bit words - adjust to bytes */ ++ u32 flash_bank_size = nvm->flash_bank_size * 2; ++ s32 ret_val = E1000_SUCCESS; ++ s32 count = 0; ++ s32 j, iteration, sector_size; ++ ++ DEBUGFUNC("e1000_erase_flash_bank_ich8lan"); ++ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ICH_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 = bank * 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 = bank * 4096 ++ * 10: The Hw sector is 8K bytes, nth sector = bank * 8192 ++ * (ich9 only, otherwise error condition) ++ * 11: The Hw sector is 64K bytes, nth sector = bank * 65536 ++ */ ++ switch (hsfsts.hsf_status.berasesz) { ++ case 0: ++ /* Hw sector size 256 */ ++ sector_size = ICH_FLASH_SEG_SIZE_256; ++ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256; ++ break; ++ case 1: ++ sector_size = ICH_FLASH_SEG_SIZE_4K; ++ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K; ++ break; ++ case 2: ++ if (hw->mac.type == e1000_ich9lan) { ++ sector_size = ICH_FLASH_SEG_SIZE_8K; ++ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K; ++ } else { ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ break; ++ case 3: ++ sector_size = ICH_FLASH_SEG_SIZE_64K; ++ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K; ++ break; ++ default: ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ /* Start with the base address, then add the sector offset. */ ++ flash_linear_addr = hw->nvm.flash_base_addr; ++ flash_linear_addr += (bank) ? (sector_size * iteration) : 0; ++ ++ for (j = 0; j < iteration ; j++) { ++ do { ++ /* Steps */ ++ ret_val = e1000_flash_cycle_init_ich8lan(hw); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Write a value 11 (block Erase) in Flash ++ * Cycle field in hw flash control ++ */ ++ hsflctl.regval = E1000_READ_FLASH_REG16(hw, ++ ICH_FLASH_HSFCTL); ++ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; ++ E1000_WRITE_FLASH_REG16(hw, ++ ICH_FLASH_HSFCTL, ++ hsflctl.regval); ++ ++ /* ++ * Write the last 24 bits of an index within the ++ * block into Flash Linear address field in Flash ++ * Address. ++ */ ++ flash_linear_addr += (j * sector_size); ++ E1000_WRITE_FLASH_REG(hw, ++ ICH_FLASH_FADDR, ++ flash_linear_addr); ++ ++ ret_val = e1000_flash_cycle_ich8lan(hw, ++ ICH_FLASH_ERASE_COMMAND_TIMEOUT); ++ if (ret_val == E1000_SUCCESS) { ++ break; ++ } else { ++ /* ++ * Check if FCERR is set to 1. If 1, ++ * clear it and try the whole sequence ++ * a few more times else Done ++ */ ++ hsfsts.regval = E1000_READ_FLASH_REG16(hw, ++ ICH_FLASH_HSFSTS); ++ if (hsfsts.hsf_status.flcerr == 1) { ++ /* ++ * repeat for some time before ++ * giving up ++ */ ++ continue; ++ } else if (hsfsts.hsf_status.flcdone == 0) ++ goto out; ++ } ++ } while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_valid_led_default_ich8lan - Set the default LED settings ++ * @hw: pointer to the HW structure ++ * @data: Pointer to the LED settings ++ * ++ * Reads the LED default settings from the NVM to data. If the NVM LED ++ * settings is all 0's or F's, set the LED default to a valid LED default ++ * setting. ++ **/ ++static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) ++{ ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_valid_led_default_ich8lan"); ++ ++ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ ++ if (*data == ID_LED_RESERVED_0000 || ++ *data == ID_LED_RESERVED_FFFF) ++ *data = ID_LED_DEFAULT_ICH8LAN; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_get_bus_info_ich8lan - Get/Set the bus type and width ++ * @hw: pointer to the HW structure ++ * ++ * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability ++ * register, so the the bus width is hard coded. ++ **/ ++static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_bus_info *bus = &hw->bus; ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_get_bus_info_ich8lan"); ++ ++ ret_val = e1000_get_bus_info_pcie_generic(hw); ++ ++ /* ++ * ICH devices are "PCI Express"-ish. They have ++ * a configuration space, but do not contain ++ * PCI Express Capability registers, so bus width ++ * must be hardcoded. ++ */ ++ if (bus->width == e1000_bus_width_unknown) ++ bus->width = e1000_bus_width_pcie_x1; ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_reset_hw_ich8lan - Reset the hardware ++ * @hw: pointer to the HW structure ++ * ++ * Does a full reset of the hardware which includes a reset of the PHY and ++ * MAC. ++ **/ ++static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ++{ ++ u32 ctrl, icr, kab; ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_reset_hw_ich8lan"); ++ ++ /* ++ * Prevent the PCI-E bus from sticking if there is no TLP connection ++ * on the last TLP read/write transaction when MAC is reset. ++ */ ++ ret_val = e1000_disable_pcie_master_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("PCI-E Master disable polling has failed.\n"); ++ } ++ ++ DEBUGOUT("Masking off all interrupts\n"); ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); ++ ++ /* ++ * Disable the Transmit and Receive units. Then delay to allow ++ * any pending transactions to complete before we hit the MAC ++ * with the global reset. ++ */ ++ E1000_WRITE_REG(hw, E1000_RCTL, 0); ++ E1000_WRITE_REG(hw, E1000_TCTL, E1000_TCTL_PSP); ++ E1000_WRITE_FLUSH(hw); ++ ++ msec_delay(10); ++ ++ /* 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, E1000_PBA, E1000_PBA_8K); ++ /* Set Packet Buffer Size to 16k. */ ++ E1000_WRITE_REG(hw, E1000_PBS, E1000_PBS_16K); ++ } ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ++ if (!hw->phy.ops.check_reset_block(hw) && !hw->phy.reset_disable) { ++ /* ++ * 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; ++ } ++ ret_val = e1000_acquire_swflag_ich8lan(hw); ++ DEBUGOUT("Issuing a global reset to ich8lan"); ++ E1000_WRITE_REG(hw, E1000_CTRL, (ctrl | E1000_CTRL_RST)); ++ msec_delay(20); ++ ++ ret_val = e1000_get_auto_rd_done_generic(hw); ++ if (ret_val) { ++ /* ++ * When auto config read does not complete, do not ++ * return with an error. This can happen in situations ++ * where there is no eeprom and prevents getting link. ++ */ ++ DEBUGOUT("Auto Read Done did not complete\n"); ++ } ++ ++ E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); ++ icr = E1000_READ_REG(hw, E1000_ICR); ++ ++ kab = E1000_READ_REG(hw, E1000_KABGTXD); ++ kab |= E1000_KABGTXD_BGSQLBIAS; ++ E1000_WRITE_REG(hw, E1000_KABGTXD, kab); ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_init_hw_ich8lan - Initialize the hardware ++ * @hw: pointer to the HW structure ++ * ++ * Prepares the hardware for transmit and receive by doing the following: ++ * - initialize hardware bits ++ * - initialize LED identification ++ * - setup receive address registers ++ * - setup flow control ++ * - setup transmit descriptors ++ * - clear statistics ++ **/ ++static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 ctrl_ext, txdctl, snoop; ++ s32 ret_val; ++ u16 i; ++ ++ DEBUGFUNC("e1000_init_hw_ich8lan"); ++ ++ e1000_initialize_hw_bits_ich8lan(hw); ++ ++ /* Initialize identification LED */ ++ ret_val = e1000_id_led_init_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error initializing identification LED\n"); ++ /* This is not fatal and we should not stop init due to this */ ++ } ++ ++ /* Setup the receive address. */ ++ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); ++ ++ /* Zero out the Multicast HASH table */ ++ DEBUGOUT("Zeroing the MTA\n"); ++ for (i = 0; i < mac->mta_reg_count; i++) ++ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); ++ ++ /* Setup link and flow control */ ++ ret_val = mac->ops.setup_link(hw); ++ ++ /* Set the transmit descriptor write-back policy for both queues */ ++ txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); ++ txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | ++ E1000_TXDCTL_FULL_TX_DESC_WB; ++ txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | ++ E1000_TXDCTL_MAX_TX_DESC_PREFETCH; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), txdctl); ++ txdctl = E1000_READ_REG(hw, E1000_TXDCTL(1)); ++ txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | ++ E1000_TXDCTL_FULL_TX_DESC_WB; ++ txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | ++ E1000_TXDCTL_MAX_TX_DESC_PREFETCH; ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), txdctl); ++ ++ /* ++ * ICH8 has opposite polarity of no_snoop bits. ++ * By default, we should use snoop behavior. ++ */ ++ if (mac->type == e1000_ich8lan) ++ snoop = PCIE_ICH8_SNOOP_ALL; ++ else ++ snoop = (u32)~(PCIE_NO_SNOOP_ALL); ++ e1000_set_pcie_no_snoop_generic(hw, snoop); ++ ++ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ ctrl_ext |= E1000_CTRL_EXT_RO_DIS; ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); ++ ++ /* ++ * 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 ++ * is no link. ++ */ ++ e1000_clear_hw_cntrs_ich8lan(hw); ++ ++ return ret_val; ++} ++/** ++ * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits ++ * @hw: pointer to the HW structure ++ * ++ * Sets/Clears required hardware bits necessary for correctly setting up the ++ * hardware for transmit and receive. ++ **/ ++static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) ++{ ++ u32 reg; ++ ++ DEBUGFUNC("e1000_initialize_hw_bits_ich8lan"); ++ ++ if (hw->mac.disable_hw_init_bits) ++ goto out; ++ ++ /* Extended Device Control */ ++ reg = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, reg); ++ ++ /* Transmit Descriptor Control 0 */ ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(0)); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg); ++ ++ /* Transmit Descriptor Control 1 */ ++ reg = E1000_READ_REG(hw, E1000_TXDCTL(1)); ++ reg |= (1 << 22); ++ E1000_WRITE_REG(hw, E1000_TXDCTL(1), reg); ++ ++ /* Transmit Arbitration Control 0 */ ++ reg = E1000_READ_REG(hw, E1000_TARC(0)); ++ if (hw->mac.type == e1000_ich8lan) ++ reg |= (1 << 28) | (1 << 29); ++ reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27); ++ E1000_WRITE_REG(hw, E1000_TARC(0), reg); ++ ++ /* Transmit Arbitration Control 1 */ ++ reg = E1000_READ_REG(hw, E1000_TARC(1)); ++ if (E1000_READ_REG(hw, E1000_TCTL) & E1000_TCTL_MULR) ++ reg &= ~(1 << 28); ++ else ++ reg |= (1 << 28); ++ reg |= (1 << 24) | (1 << 26) | (1 << 30); ++ E1000_WRITE_REG(hw, E1000_TARC(1), reg); ++ ++ /* Device Status */ ++ if (hw->mac.type == e1000_ich8lan) { ++ reg = E1000_READ_REG(hw, E1000_STATUS); ++ reg &= ~(1 << 31); ++ E1000_WRITE_REG(hw, E1000_STATUS, reg); ++ } ++ ++out: ++ return; ++} ++ ++/** ++ * e1000_setup_link_ich8lan - Setup flow control and link settings ++ * @hw: pointer to the HW structure ++ * ++ * Determines which flow control settings to use, then configures flow ++ * control. Calls the appropriate media-specific link configuration ++ * function. Assuming the adapter has a valid link partner, a valid link ++ * should be established. Assumes the hardware has previously been reset ++ * and the transmitter and receiver are not enabled. ++ **/ ++static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_setup_link_ich8lan"); ++ ++ if (hw->phy.ops.check_reset_block(hw)) ++ goto out; ++ ++ /* ++ * ICH parts do not have a word in the NVM to determine ++ * the default flow control setting, so we explicitly ++ * set it to full. ++ */ ++ if (hw->fc.type == e1000_fc_default) ++ hw->fc.type = e1000_fc_full; ++ ++ hw->fc.original_type = hw->fc.type; ++ ++ DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); ++ ++ /* Continue to configure the copper link. */ ++ ret_val = hw->mac.ops.setup_physical_interface(hw); ++ if (ret_val) ++ goto out; ++ ++ E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); ++ ++ ret_val = e1000_set_fc_watermarks_generic(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface ++ * @hw: pointer to the HW structure ++ * ++ * Configures the kumeran interface to the PHY to wait the appropriate time ++ * when polling the PHY, then call the generic setup_copper_link to finish ++ * configuring the copper link. ++ **/ ++static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ s32 ret_val; ++ u16 reg_data; ++ ++ DEBUGFUNC("e1000_setup_copper_link_ich8lan"); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= E1000_CTRL_SLU; ++ ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ ++ /* ++ * 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_generic(hw, GG82563_REG(0x34, 4), ++ 0xFFFF); ++ if (ret_val) ++ goto out; ++ ret_val = e1000_read_kmrn_reg_generic(hw, GG82563_REG(0x34, 9), ++ ®_data); ++ if (ret_val) ++ goto out; ++ reg_data |= 0x3F; ++ ret_val = e1000_write_kmrn_reg_generic(hw, GG82563_REG(0x34, 9), ++ reg_data); ++ if (ret_val) ++ goto out; ++ ++ if (hw->phy.type == e1000_phy_igp_3) { ++ ret_val = e1000_copper_link_setup_igp(hw); ++ if (ret_val) ++ goto out; ++ } else if (hw->phy.type == e1000_phy_bm) { ++ ret_val = e1000_copper_link_setup_m88(hw); ++ if (ret_val) ++ goto out; ++ } ++ ++ if (hw->phy.type == e1000_phy_ife) { ++ ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, ++ ®_data); ++ if (ret_val) ++ goto out; ++ ++ reg_data &= ~IFE_PMC_AUTO_MDIX; ++ ++ switch (hw->phy.mdix) { ++ case 1: ++ reg_data &= ~IFE_PMC_FORCE_MDIX; ++ break; ++ case 2: ++ reg_data |= IFE_PMC_FORCE_MDIX; ++ break; ++ case 0: ++ default: ++ reg_data |= IFE_PMC_AUTO_MDIX; ++ break; ++ } ++ ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, ++ reg_data); ++ if (ret_val) ++ goto out; ++ } ++ ret_val = e1000_setup_copper_link_generic(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_get_link_up_info_ich8lan - Get current link speed and duplex ++ * @hw: pointer to the HW structure ++ * @speed: pointer to store current link speed ++ * @duplex: pointer to store the current link duplex ++ * ++ * Calls the generic get_speed_and_duplex to retrieve the current link ++ * information and then calls the Kumeran lock loss workaround for links at ++ * gigabit speeds. ++ **/ ++static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, ++ u16 *duplex) ++{ ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_get_link_up_info_ich8lan"); ++ ++ ret_val = e1000_get_speed_and_duplex_copper_generic(hw, speed, duplex); ++ if (ret_val) ++ goto out; ++ ++ if ((hw->mac.type == e1000_ich8lan) && ++ (hw->phy.type == e1000_phy_igp_3) && ++ (*speed == SPEED_1000)) { ++ ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround ++ * @hw: pointer to the HW structure ++ * ++ * 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. ++ **/ ++static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ u32 phy_ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i, data; ++ bool link; ++ ++ DEBUGFUNC("e1000_kmrn_lock_loss_workaround_ich8lan"); ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ if (!dev_spec) { ++ DEBUGOUT("dev_spec pointer is set to NULL.\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ if (!(dev_spec->kmrn_lock_loss_workaround_enabled)) ++ goto out; ++ ++ /* ++ * Make sure link is up before proceeding. If not just return. ++ * Attempting this while link is negotiating fouled up link ++ * stability ++ */ ++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); ++ if (!link) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ ++ for (i = 0; i < 10; i++) { ++ /* read once to clear */ ++ ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); ++ if (ret_val) ++ goto out; ++ /* and again to get new status */ ++ ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); ++ if (ret_val) ++ goto out; ++ ++ /* check for PCS lock */ ++ if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS)) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ ++ /* Issue PHY reset */ ++ hw->phy.ops.reset(hw); ++ msec_delay_irq(5); ++ } ++ /* Disable GigE link negotiation */ ++ phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); ++ phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE | ++ E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); ++ ++ /* ++ * Call gig speed drop workaround on Gig disable before accessing ++ * any PHY registers ++ */ ++ e1000_gig_downshift_workaround_ich8lan(hw); ++ ++ /* unable to acquire PCS lock */ ++ ret_val = -E1000_ERR_PHY; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state ++ * @hw: pointer to the HW structure ++ * @state: boolean value used to set the current Kumeran workaround state ++ * ++ * If ICH8, set the current Kumeran workaround state (enabled - true ++ * /disabled - false). ++ **/ ++void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, ++ bool state) ++{ ++ struct e1000_dev_spec_ich8lan *dev_spec; ++ ++ DEBUGFUNC("e1000_set_kmrn_lock_loss_workaround_ich8lan"); ++ ++ if (hw->mac.type != e1000_ich8lan) { ++ DEBUGOUT("Workaround applies to ICH8 only.\n"); ++ goto out; ++ } ++ ++ dev_spec = (struct e1000_dev_spec_ich8lan *)hw->dev_spec; ++ ++ if (!dev_spec) { ++ DEBUGOUT("dev_spec pointer is set to NULL.\n"); ++ goto out; ++ } ++ ++ dev_spec->kmrn_lock_loss_workaround_enabled = state; ++ ++out: ++ return; ++} ++ ++/** ++ * e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3 ++ * @hw: pointer to the HW structure ++ * ++ * Workaround for 82566 power-down on D3 entry: ++ * 1) disable gigabit link ++ * 2) write VR power-down enable ++ * 3) read it back ++ * Continue if successful, else issue LCD reset and repeat ++ **/ ++void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) ++{ ++ u32 reg; ++ u16 data; ++ u8 retry = 0; ++ ++ DEBUGFUNC("e1000_igp3_phy_powerdown_workaround_ich8lan"); ++ ++ if (hw->phy.type != e1000_phy_igp_3) ++ goto out; ++ ++ /* Try the workaround twice (if needed) */ ++ do { ++ /* Disable link */ ++ reg = E1000_READ_REG(hw, E1000_PHY_CTRL); ++ reg |= (E1000_PHY_CTRL_GBE_DISABLE | ++ E1000_PHY_CTRL_NOND0A_GBE_DISABLE); ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, reg); ++ ++ /* ++ * Call gig speed drop workaround on Gig disable before ++ * accessing any PHY registers ++ */ ++ if (hw->mac.type == e1000_ich8lan) ++ e1000_gig_downshift_workaround_ich8lan(hw); ++ ++ /* Write VR power-down enable */ ++ hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); ++ data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; ++ hw->phy.ops.write_reg(hw, ++ IGP3_VR_CTRL, ++ data | IGP3_VR_CTRL_MODE_SHUTDOWN); ++ ++ /* Read it back and test */ ++ hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); ++ data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; ++ if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry) ++ break; ++ ++ /* Issue PHY reset and repeat at most one more time */ ++ reg = E1000_READ_REG(hw, E1000_CTRL); ++ E1000_WRITE_REG(hw, E1000_CTRL, reg | E1000_CTRL_PHY_RST); ++ retry++; ++ } while (retry); ++ ++out: ++ return; ++} ++ ++/** ++ * e1000_gig_downshift_workaround_ich8lan - WoL from S5 stops working ++ * @hw: pointer to the HW structure ++ * ++ * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), ++ * LPLU, Gig disable, MDIC PHY reset): ++ * 1) Set Kumeran Near-end loopback ++ * 2) Clear Kumeran Near-end loopback ++ * Should only be called for ICH8[m] devices with IGP_3 Phy. ++ **/ ++void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 reg_data; ++ ++ DEBUGFUNC("e1000_gig_downshift_workaround_ich8lan"); ++ ++ if ((hw->mac.type != e1000_ich8lan) || ++ (hw->phy.type != e1000_phy_igp_3)) ++ goto out; ++ ++ ret_val = e1000_read_kmrn_reg_generic(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, ++ ®_data); ++ if (ret_val) ++ goto out; ++ reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK; ++ ret_val = e1000_write_kmrn_reg_generic(hw, ++ E1000_KMRNCTRLSTA_DIAG_OFFSET, ++ reg_data); ++ if (ret_val) ++ goto out; ++ reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK; ++ ret_val = e1000_write_kmrn_reg_generic(hw, ++ E1000_KMRNCTRLSTA_DIAG_OFFSET, ++ reg_data); ++out: ++ return; ++} ++ ++/** ++ * e1000_disable_gig_wol_ich8lan - disable gig during WoL ++ * @hw: pointer to the HW structure ++ * ++ * During S0 to Sx transition, it is possible the link remains at gig ++ * instead of negotiating to a lower speed. Before going to Sx, set ++ * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation ++ * to a lower speed. ++ * ++ * Should only be called for ICH9 and ICH10 devices. ++ **/ ++void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) ++{ ++ u32 phy_ctrl; ++ ++ if ((hw->mac.type == e1000_ich10lan) || ++ (hw->mac.type == e1000_ich9lan)) { ++ phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); ++ phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | ++ E1000_PHY_CTRL_GBE_DISABLE; ++ E1000_WRITE_REG(hw, E1000_PHY_CTRL, phy_ctrl); ++ } ++ ++ return; ++} ++ ++/** ++ * e1000_cleanup_led_ich8lan - Restore the default LED operation ++ * @hw: pointer to the HW structure ++ * ++ * Return the LED back to the default configuration. ++ **/ ++static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_cleanup_led_ich8lan"); ++ ++ if (hw->phy.type == e1000_phy_ife) ++ ret_val = hw->phy.ops.write_reg(hw, ++ IFE_PHY_SPECIAL_CONTROL_LED, ++ 0); ++ else ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_led_on_ich8lan - Turn LEDs on ++ * @hw: pointer to the HW structure ++ * ++ * Turn on the LEDs. ++ **/ ++static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_led_on_ich8lan"); ++ ++ if (hw->phy.type == e1000_phy_ife) ++ ret_val = hw->phy.ops.write_reg(hw, ++ IFE_PHY_SPECIAL_CONTROL_LED, ++ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); ++ else ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_led_off_ich8lan - Turn LEDs off ++ * @hw: pointer to the HW structure ++ * ++ * Turn off the LEDs. ++ **/ ++static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_led_off_ich8lan"); ++ ++ if (hw->phy.type == e1000_phy_ife) ++ ret_val = hw->phy.ops.write_reg(hw, ++ IFE_PHY_SPECIAL_CONTROL_LED, ++ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); ++ else ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_get_cfg_done_ich8lan - Read config done bit ++ * @hw: pointer to the HW structure ++ * ++ * Read the management control register for the config done bit for ++ * completion status. NOTE: silicon which is EEPROM-less will fail trying ++ * to read the config done bit, so an error is *ONLY* logged and returns ++ * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon ++ * would not be able to be reset or change link. ++ **/ ++static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u32 bank = 0; ++ ++ e1000_get_cfg_done_generic(hw); ++ ++ /* If EEPROM is not marked present, init the IGP 3 PHY manually */ ++ if (hw->mac.type != e1000_ich10lan) { ++ if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && ++ (hw->phy.type == e1000_phy_igp_3)) { ++ e1000_phy_init_script_igp3(hw); ++ } ++ } else { ++ if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) { ++ /* Maybe we should do a basic Boazman config */ ++ DEBUGOUT("EEPROM not present\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ } ++ } ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_power_down_phy_copper_ich8lan - Remove link during PHY power down ++ * @hw: pointer to the HW structure ++ * ++ * In the case of a PHY power down to save power, or to turn off link during a ++ * driver unload, or wake on lan is not enabled, remove the link. ++ **/ ++static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ struct e1000_mac_info *mac = &hw->mac; ++ ++ /* If the management interface is not enabled, then power down */ ++ if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) ++ e1000_power_down_phy_copper(hw); ++ ++ return; ++} ++ ++/** ++ * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters ++ * @hw: pointer to the HW structure ++ * ++ * Clears hardware counters specific to the silicon family and calls ++ * clear_hw_cntrs_generic to clear all general purpose counters. ++ **/ ++static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) ++{ ++ volatile u32 temp; ++ ++ DEBUGFUNC("e1000_clear_hw_cntrs_ich8lan"); ++ ++ e1000_clear_hw_cntrs_base_generic(hw); ++ ++ temp = E1000_READ_REG(hw, E1000_ALGNERRC); ++ temp = E1000_READ_REG(hw, E1000_RXERRC); ++ temp = E1000_READ_REG(hw, E1000_TNCRS); ++ temp = E1000_READ_REG(hw, E1000_CEXTERR); ++ temp = E1000_READ_REG(hw, E1000_TSCTC); ++ temp = E1000_READ_REG(hw, E1000_TSCTFC); ++ ++ temp = E1000_READ_REG(hw, E1000_MGTPRC); ++ temp = E1000_READ_REG(hw, E1000_MGTPDC); ++ temp = E1000_READ_REG(hw, E1000_MGTPTC); ++ ++ temp = E1000_READ_REG(hw, E1000_IAC); ++ temp = E1000_READ_REG(hw, E1000_ICRXOC); ++} ++ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_ich8lan.h linux-2.6.22-10/drivers/net/e1000e/e1000_ich8lan.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_ich8lan.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_ich8lan.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,144 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _E1000_ICH8LAN_H_ ++#define _E1000_ICH8LAN_H_ ++ ++#define ICH_FLASH_GFPREG 0x0000 ++#define ICH_FLASH_HSFSTS 0x0004 ++#define ICH_FLASH_HSFCTL 0x0006 ++#define ICH_FLASH_FADDR 0x0008 ++#define ICH_FLASH_FDATA0 0x0010 ++#define ICH_FLASH_PR0 0x0074 ++ ++#define ICH_FLASH_READ_COMMAND_TIMEOUT 500 ++#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 ++#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000 ++#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF ++#define ICH_FLASH_CYCLE_REPEAT_COUNT 10 ++ ++#define ICH_CYCLE_READ 0 ++#define ICH_CYCLE_WRITE 2 ++#define ICH_CYCLE_ERASE 3 ++ ++#define FLASH_GFPREG_BASE_MASK 0x1FFF ++#define FLASH_SECTOR_ADDR_SHIFT 12 ++ ++#define E1000_SHADOW_RAM_WORDS 2048 ++ ++#define ICH_FLASH_SEG_SIZE_256 256 ++#define ICH_FLASH_SEG_SIZE_4K 4096 ++#define ICH_FLASH_SEG_SIZE_8K 8192 ++#define ICH_FLASH_SEG_SIZE_64K 65536 ++#define ICH_FLASH_SECTOR_SIZE 4096 ++ ++#define ICH_FLASH_REG_MAPSIZE 0x00A0 ++ ++#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ ++#define E1000_ICH_FWSM_DISSW 0x10000000 /* FW Disables SW Writes */ ++/* FW established a valid mode */ ++#define E1000_ICH_FWSM_FW_VALID 0x00008000 ++ ++#define E1000_ICH_MNG_IAMT_MODE 0x2 ++ ++#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 E1000_ICH_NVM_SIG_WORD 0x13 ++#define E1000_ICH_NVM_SIG_MASK 0xC000 ++ ++#define E1000_ICH8_LAN_INIT_TIMEOUT 1500 ++ ++#define E1000_FEXTNVM_SW_CONFIG 1 ++#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M */ ++ ++#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL ++ ++#define E1000_ICH_RAR_ENTRIES 7 ++ ++#define PHY_PAGE_SHIFT 5 ++#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ ++ ((reg) & MAX_PHY_REG_ADDRESS)) ++#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ ++#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ ++#define IGP3_CAPABILITY PHY_REG(776, 19) /* Capability */ ++#define IGP3_PM_CTRL PHY_REG(769, 20) /* Power Management Control */ ++ ++#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 ++#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 ++#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 ++#define IGP3_PM_CTRL_FORCE_PWR_DOWN 0x0020 ++ ++/* ++ * Additional interrupts need to be handled for ICH family: ++ * 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_ICH_ENABLE_MASK (\ ++ E1000_IMS_DSW | \ ++ E1000_IMS_PHYINT | \ ++ E1000_IMS_EPRST) ++ ++/* Additional interrupt register bit definitions */ ++#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */ ++#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ ++#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ ++ ++/* Security Processing bit Indication */ ++#define E1000_RXDEXT_LINKSEC_STATUS_LSECH 0x01000000 ++#define E1000_RXDEXT_LINKSEC_ERROR_BIT_MASK 0x60000000 ++#define E1000_RXDEXT_LINKSEC_ERROR_NO_SA_MATCH 0x20000000 ++#define E1000_RXDEXT_LINKSEC_ERROR_REPLAY_ERROR 0x40000000 ++#define E1000_RXDEXT_LINKSEC_ERROR_BAD_SIG 0x60000000 ++ ++ ++/* ICH Flash Protected Region */ ++union ich8_flash_protected_range { ++ struct ich8_pr { ++ u32 base:13; /* 0:12 Protected Range Base */ ++ u32 reserved1:2; /* 13:14 Reserved */ ++ u32 rpe:1; /* 15 Read Protection Enable */ ++ u32 limit:13; /* 16:28 Protected Range Limit */ ++ u32 reserved2:2; /* 29:30 Reserved */ ++ u32 wpe:1; /* 31 Write Protection Enable */ ++ } range; ++ u32 regval; +}; + -+/* Offload Context Descriptor */ -+struct e1000_context_desc { -+ union { -+ u32 ip_config; -+ struct { -+ u8 ipcss; /* IP checksum start */ -+ u8 ipcso; /* IP checksum offset */ -+ u16 ipcse; /* IP checksum end */ -+ } ip_fields; -+ } lower_setup; -+ union { -+ u32 tcp_config; -+ struct { -+ u8 tucss; /* TCP checksum start */ -+ u8 tucso; /* TCP checksum offset */ -+ u16 tucse; /* TCP checksum end */ -+ } tcp_fields; -+ } upper_setup; -+ u32 cmd_and_length; -+ union { -+ u32 data; -+ struct { -+ u8 status; /* Descriptor status */ -+ u8 hdr_len; /* Header length */ -+ u16 mss; /* Maximum segment size */ -+ } fields; -+ } tcp_seg_setup; -+}; ++void e1000_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, ++ bool state); ++void e1000e_write_protect_nvm_ich8lan(struct e1000_hw *hw); ++ ++void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw); ++void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw); ++void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw); ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_mac.c linux-2.6.22-10/drivers/net/e1000e/e1000_mac.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_mac.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_mac.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1988 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#include "e1000_hw.h" ++ ++/** ++ * e1000_init_mac_ops_generic - Initialize MAC function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Setups up the function pointers to no-op functions ++ **/ ++void e1000_init_mac_ops_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ DEBUGFUNC("e1000_init_mac_ops_generic"); ++ ++ /* General Setup */ ++ mac->ops.read_mac_addr = e1000_read_mac_addr_generic; ++ mac->ops.remove_device = e1000_remove_device_generic; ++ mac->ops.config_collision_dist = e1000_config_collision_dist_generic; ++ /* LINK */ ++ mac->ops.wait_autoneg = e1000_wait_autoneg_generic; ++ /* Management */ ++ mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic; ++ mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic; ++ mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic; ++ /* VLAN, MC, etc. */ ++ mac->ops.rar_set = e1000_rar_set_generic; ++ mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic; ++} ++ ++/** ++ * e1000_remove_device_generic - Free device specific structure ++ * @hw: pointer to the HW structure ++ * ++ * If a device specific structure was allocated, this function will ++ * free it. ++ **/ ++void e1000_remove_device_generic(struct e1000_hw *hw) ++{ ++ DEBUGFUNC("e1000_remove_device_generic"); ++ ++ /* Freeing the dev_spec member of e1000_hw structure */ ++ e1000_free_dev_spec_struct(hw); ++} ++ ++/** ++ * e1000_get_bus_info_pcie_generic - Get PCIe bus information ++ * @hw: pointer to the HW structure ++ * ++ * Determines and stores the system bus information for a particular ++ * network interface. The following bus information is determined and stored: ++ * bus speed, bus width, type (PCIe), and PCIe function. ++ **/ ++s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw) ++{ ++ struct e1000_bus_info *bus = &hw->bus; ++ s32 ret_val; ++ u32 status; ++ u16 pcie_link_status, pci_header_type; ++ ++ DEBUGFUNC("e1000_get_bus_info_pcie_generic"); ++ ++ bus->type = e1000_bus_type_pci_express; ++ bus->speed = e1000_bus_speed_2500; ++ ++ ret_val = e1000_read_pcie_cap_reg(hw, ++ PCIE_LINK_STATUS, ++ &pcie_link_status); ++ if (ret_val) ++ bus->width = e1000_bus_width_unknown; ++ else ++ bus->width = (e1000_bus_width)((pcie_link_status & ++ PCIE_LINK_WIDTH_MASK) >> ++ PCIE_LINK_WIDTH_SHIFT); ++ ++ e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type); ++ if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) { ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ bus->func = (status & E1000_STATUS_FUNC_MASK) ++ >> E1000_STATUS_FUNC_SHIFT; ++ } else { ++ bus->func = 0; ++ } ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_clear_vfta_generic - Clear VLAN filter table ++ * @hw: pointer to the HW structure ++ * ++ * Clears the register array which contains the VLAN filter table by ++ * setting all the values to 0. ++ **/ ++void e1000_clear_vfta_generic(struct e1000_hw *hw) ++{ ++ u32 offset; ++ ++ DEBUGFUNC("e1000_clear_vfta_generic"); ++ ++ for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { ++ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); ++ E1000_WRITE_FLUSH(hw); ++ } ++} ++ ++/** ++ * e1000_write_vfta_generic - Write value to VLAN filter table ++ * @hw: pointer to the HW structure ++ * @offset: register offset in VLAN filter table ++ * @value: register value written to VLAN filter table ++ * ++ * Writes value at the given offset in the register array which stores ++ * the VLAN filter table. ++ **/ ++void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) ++{ ++ DEBUGFUNC("e1000_write_vfta_generic"); ++ ++ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); ++ E1000_WRITE_FLUSH(hw); ++} ++ ++/** ++ * e1000_init_rx_addrs_generic - Initialize receive address's ++ * @hw: pointer to the HW structure ++ * @rar_count: receive address registers ++ * ++ * Setups the receive address registers by setting the base receive address ++ * register to the devices MAC address and clearing all the other receive ++ * address registers to 0. ++ **/ ++void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) ++{ ++ u32 i; ++ ++ DEBUGFUNC("e1000_init_rx_addrs_generic"); ++ ++ /* Setup the receive address */ ++ DEBUGOUT("Programming MAC Address into RAR[0]\n"); ++ ++ hw->mac.ops.rar_set(hw, hw->mac.addr, 0); ++ ++ /* Zero out the other (rar_entry_count - 1) receive addresses */ ++ DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1); ++ for (i = 1; i < rar_count; i++) { ++ E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); ++ E1000_WRITE_FLUSH(hw); ++ E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); ++ E1000_WRITE_FLUSH(hw); ++ } ++} ++ ++/** ++ * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr ++ * @hw: pointer to the HW structure ++ * ++ * Checks the nvm for an alternate MAC address. An alternate MAC address ++ * can be setup by pre-boot software and must be treated like a permanent ++ * address and must override the actual permanent MAC address. If an ++ * alternate MAC address is found it is saved in the hw struct and ++ * programmed into RAR0 and the function returns success, otherwise the ++ * function returns an error. ++ **/ ++s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) ++{ ++ u32 i; ++ s32 ret_val = E1000_SUCCESS; ++ u16 offset, nvm_alt_mac_addr_offset, nvm_data; ++ u8 alt_mac_addr[ETH_ADDR_LEN]; ++ ++ DEBUGFUNC("e1000_check_alt_mac_addr_generic"); ++ ++ ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1, ++ &nvm_alt_mac_addr_offset); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ ++ if (nvm_alt_mac_addr_offset == 0xFFFF) { ++ ret_val = -(E1000_NOT_IMPLEMENTED); ++ goto out; ++ } ++ ++ if (hw->bus.func == E1000_FUNC_1) ++ nvm_alt_mac_addr_offset += ETH_ADDR_LEN/sizeof(u16); ++ ++ for (i = 0; i < ETH_ADDR_LEN; i += 2) { ++ offset = nvm_alt_mac_addr_offset + (i >> 1); ++ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ ++ alt_mac_addr[i] = (u8)(nvm_data & 0xFF); ++ alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); ++ } ++ ++ /* if multicast bit is set, the alternate address will not be used */ ++ if (alt_mac_addr[0] & 0x01) { ++ ret_val = -(E1000_NOT_IMPLEMENTED); ++ goto out; ++ } ++ ++ for (i = 0; i < ETH_ADDR_LEN; i++) ++ hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; ++ ++ hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_rar_set_generic - Set receive address register ++ * @hw: pointer to the HW structure ++ * @addr: pointer to the receive address ++ * @index: receive address array register ++ * ++ * Sets the receive address array register at index to the address passed ++ * in by addr. ++ **/ ++void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) ++{ ++ u32 rar_low, rar_high; ++ ++ DEBUGFUNC("e1000_rar_set_generic"); ++ ++ /* ++ * HW expects these in little endian so we reverse the byte order ++ * from network order (big endian) to little endian ++ */ ++ rar_low = ((u32) addr[0] | ++ ((u32) addr[1] << 8) | ++ ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); ++ ++ rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); ++ ++ /* If MAC address zero, no need to set the AV bit */ ++ if (rar_low || rar_high) { ++ if (!hw->mac.disable_av) ++ rar_high |= E1000_RAH_AV; ++ } ++ ++ E1000_WRITE_REG(hw, E1000_RAL(index), rar_low); ++ E1000_WRITE_REG(hw, E1000_RAH(index), rar_high); ++} ++ ++/** ++ * e1000_mta_set_generic - Set multicast filter table address ++ * @hw: pointer to the HW structure ++ * @hash_value: determines the MTA register and bit to set ++ * ++ * The multicast table address is a register array of 32-bit registers. ++ * The hash_value is used to determine what register the bit is in, the ++ * current value is read, the new bit is OR'd in and the new value is ++ * written back into the register. ++ **/ ++void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value) ++{ ++ u32 hash_bit, hash_reg, mta; ++ ++ DEBUGFUNC("e1000_mta_set_generic"); ++ /* ++ * The MTA is a register array of 32-bit registers. It is ++ * treated like an array of (32*mta_reg_count) bits. We want to ++ * set bit BitArray[hash_value]. So we figure out what register ++ * the bit is in, read it, OR in the new bit, then write ++ * back the new value. The (hw->mac.mta_reg_count - 1) serves as a ++ * mask to bits 31:5 of the hash value which gives us the ++ * register we're modifying. The hash bit within that register ++ * is determined by the lower 5 bits of the hash value. ++ */ ++ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); ++ hash_bit = hash_value & 0x1F; ++ ++ mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); ++ ++ mta |= (1 << hash_bit); ++ ++ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); ++ E1000_WRITE_FLUSH(hw); ++} ++ ++/** ++ * e1000_update_mc_addr_list_generic - Update Multicast addresses ++ * @hw: pointer to the HW structure ++ * @mc_addr_list: array of multicast addresses to program ++ * @mc_addr_count: number of multicast addresses to program ++ * @rar_used_count: the first RAR register free to program ++ * @rar_count: total number of supported Receive Address Registers ++ * ++ * Updates the Receive Address Registers and Multicast Table Array. ++ * The caller must have a packed mc_addr_list of multicast addresses. ++ * The parameter rar_count will usually be hw->mac.rar_entry_count ++ * unless there are workarounds that change this. ++ **/ ++void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, ++ u8 *mc_addr_list, u32 mc_addr_count, ++ u32 rar_used_count, u32 rar_count) ++{ ++ u32 hash_value; ++ u32 i; ++ ++ DEBUGFUNC("e1000_update_mc_addr_list_generic"); ++ ++ /* ++ * Load the first set of multicast addresses into the exact ++ * filters (RAR). If there are not enough to fill the RAR ++ * array, clear the filters. ++ */ ++ for (i = rar_used_count; i < rar_count; i++) { ++ if (mc_addr_count) { ++ hw->mac.ops.rar_set(hw, mc_addr_list, i); ++ mc_addr_count--; ++ mc_addr_list += ETH_ADDR_LEN; ++ } else { ++ E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0); ++ E1000_WRITE_FLUSH(hw); ++ E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0); ++ E1000_WRITE_FLUSH(hw); ++ } ++ } ++ ++ /* Clear the old settings from the MTA */ ++ DEBUGOUT("Clearing MTA\n"); ++ for (i = 0; i < hw->mac.mta_reg_count; i++) { ++ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); ++ E1000_WRITE_FLUSH(hw); ++ } ++ ++ /* Load any remaining multicast addresses into the hash table. */ ++ for (; mc_addr_count > 0; mc_addr_count--) { ++ hash_value = e1000_hash_mc_addr_generic(hw, mc_addr_list); ++ DEBUGOUT1("Hash value = 0x%03X\n", hash_value); ++ hw->mac.ops.mta_set(hw, hash_value); ++ mc_addr_list += ETH_ADDR_LEN; ++ } ++} ++ ++/** ++ * e1000_hash_mc_addr_generic - Generate a multicast hash value ++ * @hw: pointer to the HW structure ++ * @mc_addr: pointer to a multicast address ++ * ++ * Generates a multicast address hash value which is used to determine ++ * the multicast filter table array address and new table value. See ++ * e1000_mta_set_generic() ++ **/ ++u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr) ++{ ++ u32 hash_value, hash_mask; ++ u8 bit_shift = 0; ++ ++ DEBUGFUNC("e1000_hash_mc_addr_generic"); ++ ++ /* Register count multiplied by bits per register */ ++ hash_mask = (hw->mac.mta_reg_count * 32) - 1; ++ ++ /* ++ * For a mc_filter_type of 0, bit_shift is the number of left-shifts ++ * where 0xFF would still fall within the hash mask. ++ */ ++ while (hash_mask >> bit_shift != 0xFF) ++ bit_shift++; ++ ++ /* ++ * The portion of the address that is used for the hash table ++ * is determined by the mc_filter_type setting. ++ * The algorithm is such that there is a total of 8 bits of shifting. ++ * The bit_shift for a mc_filter_type of 0 represents the number of ++ * left-shifts where the MSB of mc_addr[5] would still fall within ++ * the hash_mask. Case 0 does this exactly. Since there are a total ++ * of 8 bits of shifting, then mc_addr[4] will shift right the ++ * remaining number of bits. Thus 8 - bit_shift. The rest of the ++ * cases are a variation of this algorithm...essentially raising the ++ * number of bits to shift mc_addr[5] left, while still keeping the ++ * 8-bit shifting total. ++ * ++ * For example, given the following Destination MAC Address and an ++ * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), ++ * we can see that the bit_shift for case 0 is 4. These are the hash ++ * values resulting from each mc_filter_type... ++ * [0] [1] [2] [3] [4] [5] ++ * 01 AA 00 12 34 56 ++ * LSB MSB ++ * ++ * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 ++ * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 ++ * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 ++ * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 ++ */ ++ switch (hw->mac.mc_filter_type) { ++ default: ++ case 0: ++ break; ++ case 1: ++ bit_shift += 1; ++ break; ++ case 2: ++ bit_shift += 2; ++ break; ++ case 3: ++ bit_shift += 4; ++ break; ++ } ++ ++ hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | ++ (((u16) mc_addr[5]) << bit_shift))); ++ ++ return hash_value; ++} ++ ++/** ++ * e1000_clear_hw_cntrs_base_generic - Clear base hardware counters ++ * @hw: pointer to the HW structure ++ * ++ * Clears the base hardware counters by reading the counter registers. ++ **/ ++void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw) ++{ ++ volatile u32 temp; ++ ++ DEBUGFUNC("e1000_clear_hw_cntrs_base_generic"); ++ ++ temp = E1000_READ_REG(hw, E1000_CRCERRS); ++ temp = E1000_READ_REG(hw, E1000_SYMERRS); ++ temp = E1000_READ_REG(hw, E1000_MPC); ++ temp = E1000_READ_REG(hw, E1000_SCC); ++ temp = E1000_READ_REG(hw, E1000_ECOL); ++ temp = E1000_READ_REG(hw, E1000_MCC); ++ temp = E1000_READ_REG(hw, E1000_LATECOL); ++ temp = E1000_READ_REG(hw, E1000_COLC); ++ temp = E1000_READ_REG(hw, E1000_DC); ++ temp = E1000_READ_REG(hw, E1000_SEC); ++ temp = E1000_READ_REG(hw, E1000_RLEC); ++ temp = E1000_READ_REG(hw, E1000_XONRXC); ++ temp = E1000_READ_REG(hw, E1000_XONTXC); ++ temp = E1000_READ_REG(hw, E1000_XOFFRXC); ++ temp = E1000_READ_REG(hw, E1000_XOFFTXC); ++ temp = E1000_READ_REG(hw, E1000_FCRUC); ++ temp = E1000_READ_REG(hw, E1000_GPRC); ++ temp = E1000_READ_REG(hw, E1000_BPRC); ++ temp = E1000_READ_REG(hw, E1000_MPRC); ++ temp = E1000_READ_REG(hw, E1000_GPTC); ++ temp = E1000_READ_REG(hw, E1000_GORCL); ++ temp = E1000_READ_REG(hw, E1000_GORCH); ++ temp = E1000_READ_REG(hw, E1000_GOTCL); ++ temp = E1000_READ_REG(hw, E1000_GOTCH); ++ temp = E1000_READ_REG(hw, E1000_RNBC); ++ temp = E1000_READ_REG(hw, E1000_RUC); ++ temp = E1000_READ_REG(hw, E1000_RFC); ++ temp = E1000_READ_REG(hw, E1000_ROC); ++ temp = E1000_READ_REG(hw, E1000_RJC); ++ temp = E1000_READ_REG(hw, E1000_TORL); ++ temp = E1000_READ_REG(hw, E1000_TORH); ++ temp = E1000_READ_REG(hw, E1000_TOTL); ++ temp = E1000_READ_REG(hw, E1000_TOTH); ++ temp = E1000_READ_REG(hw, E1000_TPR); ++ temp = E1000_READ_REG(hw, E1000_TPT); ++ temp = E1000_READ_REG(hw, E1000_MPTC); ++ temp = E1000_READ_REG(hw, E1000_BPTC); ++} ++ ++/** ++ * e1000_check_for_copper_link_generic - Check for link (Copper) ++ * @hw: pointer to the HW structure ++ * ++ * Checks to see of the link status of the hardware has changed. If a ++ * change in link status has been detected, then we read the PHY registers ++ * to get the current speed/duplex if link exists. ++ **/ ++s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ s32 ret_val; ++ bool link; ++ ++ DEBUGFUNC("e1000_check_for_copper_link"); ++ ++ /* ++ * We only want to go out to the PHY registers to see if Auto-Neg ++ * has completed and/or if our link status has changed. The ++ * get_link_status flag is set upon receiving a Link Status ++ * Change or Rx Sequence Error interrupt. ++ */ ++ if (!mac->get_link_status) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ ++ /* ++ * 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. ++ */ ++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); ++ if (ret_val) ++ goto out; ++ ++ if (!link) ++ goto out; /* No link detected */ ++ ++ mac->get_link_status = false; ++ ++ /* ++ * Check if there was DownShift, must be checked ++ * immediately after link-up ++ */ ++ e1000_check_downshift_generic(hw); ++ ++ /* ++ * If we are forcing speed/duplex, then we simply return since ++ * we have already determined whether we have link or not. ++ */ ++ if (!mac->autoneg) { ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ /* ++ * Auto-Neg is enabled. Auto Speed Detection takes care ++ * of MAC speed/duplex configuration. So we only need to ++ * configure Collision Distance in the MAC. ++ */ ++ e1000_config_collision_dist_generic(hw); ++ ++ /* ++ * Configure Flow Control now that Auto-Neg has completed. ++ * First, we need to restore the desired flow control ++ * settings because we may have had to re-autoneg with a ++ * different link partner. ++ */ ++ ret_val = e1000_config_fc_after_link_up_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error configuring flow control\n"); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_check_for_fiber_link_generic - Check for link (Fiber) ++ * @hw: pointer to the HW structure ++ * ++ * Checks for link up on the hardware. If link is not up and we have ++ * a signal, then we need to force link up. ++ **/ ++s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 rxcw; ++ u32 ctrl; ++ u32 status; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_check_for_fiber_link_generic"); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ rxcw = E1000_READ_REG(hw, E1000_RXCW); ++ ++ /* ++ * If we don't have link (auto-negotiation failed or link partner ++ * cannot auto-negotiate), the cable is plugged in (we have signal), ++ * and our link partner is not trying to auto-negotiate with us (we ++ * are receiving idles or data), we need to force link up. We also ++ * need to give auto-negotiation time to complete, in case the cable ++ * was just plugged in. The autoneg_failed flag does this. ++ */ ++ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ ++ if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && ++ (!(rxcw & E1000_RXCW_C))) { ++ if (mac->autoneg_failed == 0) { ++ mac->autoneg_failed = 1; ++ goto out; ++ } ++ DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n"); ++ ++ /* Disable auto-negotiation in the TXCW register */ ++ E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE)); ++ ++ /* Force link-up and also force full-duplex. */ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ ++ /* Configure Flow Control after forcing link up. */ ++ ret_val = e1000_config_fc_after_link_up_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error configuring flow control\n"); ++ goto out; ++ } ++ } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { ++ /* ++ * If we are forcing link and we are receiving /C/ ordered ++ * sets, re-enable auto-negotiation in the TXCW register ++ * and disable forced link in the Device Control register ++ * in an attempt to auto-negotiate with our link partner. ++ */ ++ DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n"); ++ E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw); ++ E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU)); ++ ++ mac->serdes_has_link = true; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_check_for_serdes_link_generic - Check for link (Serdes) ++ * @hw: pointer to the HW structure ++ * ++ * Checks for link up on the hardware. If link is not up and we have ++ * a signal, then we need to force link up. ++ **/ ++s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 rxcw; ++ u32 ctrl; ++ u32 status; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_check_for_serdes_link_generic"); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ rxcw = E1000_READ_REG(hw, E1000_RXCW); ++ ++ /* ++ * If we don't have link (auto-negotiation failed or link partner ++ * cannot auto-negotiate), and our link partner is not trying to ++ * auto-negotiate with us (we are receiving idles or data), ++ * we need to force link up. We also need to give auto-negotiation ++ * time to complete. ++ */ ++ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ ++ if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { ++ if (mac->autoneg_failed == 0) { ++ mac->autoneg_failed = 1; ++ goto out; ++ } ++ DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n"); ++ ++ /* Disable auto-negotiation in the TXCW register */ ++ E1000_WRITE_REG(hw, E1000_TXCW, (mac->txcw & ~E1000_TXCW_ANE)); ++ ++ /* Force link-up and also force full-duplex. */ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ ++ /* Configure Flow Control after forcing link up. */ ++ ret_val = e1000_config_fc_after_link_up_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error configuring flow control\n"); ++ goto out; ++ } ++ } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { ++ /* ++ * If we are forcing link and we are receiving /C/ ordered ++ * sets, re-enable auto-negotiation in the TXCW register ++ * and disable forced link in the Device Control register ++ * in an attempt to auto-negotiate with our link partner. ++ */ ++ DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n"); ++ E1000_WRITE_REG(hw, E1000_TXCW, mac->txcw); ++ E1000_WRITE_REG(hw, E1000_CTRL, (ctrl & ~E1000_CTRL_SLU)); ++ ++ mac->serdes_has_link = true; ++ } else if (!(E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW))) { ++ /* ++ * If we force link for non-auto-negotiation switch, check ++ * link status based on MAC synchronization for internal ++ * serdes media type. ++ */ ++ /* SYNCH bit and IV bit are sticky. */ ++ usec_delay(10); ++ rxcw = E1000_READ_REG(hw, E1000_RXCW); ++ if (rxcw & E1000_RXCW_SYNCH) { ++ if (!(rxcw & E1000_RXCW_IV)) { ++ mac->serdes_has_link = true; ++ DEBUGOUT("SERDES: Link up - forced.\n"); ++ } ++ } else { ++ mac->serdes_has_link = false; ++ DEBUGOUT("SERDES: Link down - force failed.\n"); ++ } ++ } ++ ++ if (E1000_TXCW_ANE & E1000_READ_REG(hw, E1000_TXCW)) { ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ if (status & E1000_STATUS_LU) { ++ /* SYNCH bit and IV bit are sticky, so reread rxcw. */ ++ usec_delay(10); ++ rxcw = E1000_READ_REG(hw, E1000_RXCW); ++ if (rxcw & E1000_RXCW_SYNCH) { ++ if (!(rxcw & E1000_RXCW_IV)) { ++ mac->serdes_has_link = TRUE; ++ DEBUGOUT("SERDES: Link up - autoneg " ++ "completed sucessfully.\n"); ++ } else { ++ mac->serdes_has_link = FALSE; ++ DEBUGOUT("SERDES: Link down - invalid" ++ "codewords detected in autoneg.\n"); ++ } ++ } else { ++ mac->serdes_has_link = FALSE; ++ DEBUGOUT("SERDES: Link down - no sync.\n"); ++ } ++ } else { ++ mac->serdes_has_link = FALSE; ++ DEBUGOUT("SERDES: Link down - autoneg failed\n"); ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_setup_link_generic - Setup flow control and link settings ++ * @hw: pointer to the HW structure ++ * ++ * Determines which flow control settings to use, then configures flow ++ * control. Calls the appropriate media-specific link configuration ++ * function. Assuming the adapter has a valid link partner, a valid link ++ * should be established. Assumes the hardware has previously been reset ++ * and the transmitter and receiver are not enabled. ++ **/ ++s32 e1000_setup_link_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_setup_link_generic"); ++ ++ /* ++ * In the case of the phy reset being blocked, we already have a link. ++ * We do not need to set it up again. ++ */ ++ if (hw->phy.ops.check_reset_block) ++ if (hw->phy.ops.check_reset_block(hw)) ++ goto out; ++ ++ /* ++ * If flow control is set to default, set flow control based on ++ * the EEPROM flow control settings. ++ */ ++ if (hw->fc.type == e1000_fc_default) { ++ ret_val = e1000_set_default_fc_generic(hw); ++ if (ret_val) ++ goto out; ++ } ++ ++ /* ++ * 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. ++ */ ++ hw->fc.original_type = hw->fc.type; ++ ++ DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); ++ ++ /* Call the necessary media_type subroutine to configure the link. */ ++ ret_val = hw->mac.ops.setup_physical_interface(hw); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Initialize the flow control address, type, and PAUSE timer ++ * registers to their default values. This is done even if flow ++ * control is disabled, because it does not hurt anything to ++ * initialize these registers. ++ */ ++ DEBUGOUT("Initializing the Flow Control address, type and timer regs\n"); ++ E1000_WRITE_REG(hw, E1000_FCT, FLOW_CONTROL_TYPE); ++ E1000_WRITE_REG(hw, E1000_FCAH, FLOW_CONTROL_ADDRESS_HIGH); ++ E1000_WRITE_REG(hw, E1000_FCAL, FLOW_CONTROL_ADDRESS_LOW); ++ ++ E1000_WRITE_REG(hw, E1000_FCTTV, hw->fc.pause_time); ++ ++ ret_val = e1000_set_fc_watermarks_generic(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_setup_fiber_serdes_link_generic - Setup link for fiber/serdes ++ * @hw: pointer to the HW structure ++ * ++ * Configures collision distance and flow control for fiber and serdes ++ * links. Upon successful setup, poll for link. ++ **/ ++s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_setup_fiber_serdes_link_generic"); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ++ /* Take the link out of reset */ ++ ctrl &= ~E1000_CTRL_LRST; ++ ++ e1000_config_collision_dist_generic(hw); ++ ++ ret_val = e1000_commit_fc_settings_generic(hw); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Since auto-negotiation is enabled, take the link out of reset (the ++ * link will be in reset, because we previously reset the chip). This ++ * will restart auto-negotiation. If auto-negotiation is successful ++ * then the link-up status bit will be set and the flow control enable ++ * bits (RFCE and TFCE) will be set according to their negotiated value. ++ */ ++ DEBUGOUT("Auto-negotiation enabled\n"); ++ ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ E1000_WRITE_FLUSH(hw); ++ msec_delay(1); ++ ++ /* ++ * For these adapters, the SW definable pin 1 is set when the optics ++ * detect a signal. If we have a signal, then poll for a "Link-Up" ++ * indication. ++ */ ++ if (hw->phy.media_type == e1000_media_type_internal_serdes || ++ (E1000_READ_REG(hw, E1000_CTRL) & E1000_CTRL_SWDPIN1)) { ++ ret_val = e1000_poll_fiber_serdes_link_generic(hw); ++ } else { ++ DEBUGOUT("No signal detected\n"); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_config_collision_dist_generic - Configure collision distance ++ * @hw: pointer to the HW structure ++ * ++ * Configures the collision distance to the default value and is used ++ * during link setup. Currently no func pointer exists and all ++ * implementations are handled in the generic version of this function. ++ **/ ++void e1000_config_collision_dist_generic(struct e1000_hw *hw) ++{ ++ u32 tctl; ++ ++ DEBUGFUNC("e1000_config_collision_dist_generic"); ++ ++ tctl = E1000_READ_REG(hw, E1000_TCTL); ++ ++ tctl &= ~E1000_TCTL_COLD; ++ tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; ++ ++ E1000_WRITE_REG(hw, E1000_TCTL, tctl); ++ E1000_WRITE_FLUSH(hw); ++} ++ ++/** ++ * e1000_poll_fiber_serdes_link_generic - Poll for link up ++ * @hw: pointer to the HW structure ++ * ++ * Polls for link up by reading the status register, if link fails to come ++ * up with auto-negotiation, then the link is forced if a signal is detected. ++ **/ ++s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 i, status; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); ++ ++ /* ++ * If we have a signal (the cable is plugged in, or assumed true for ++ * serdes media) then poll for a "Link-Up" indication in the Device ++ * Status Register. Time-out if a link isn't seen in 500 milliseconds ++ * seconds (Auto-negotiation should complete in less than 500 ++ * milliseconds even if the other end is doing it in SW). ++ */ ++ for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { ++ msec_delay(10); ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ if (status & E1000_STATUS_LU) ++ break; ++ } ++ if (i == FIBER_LINK_UP_LIMIT) { ++ DEBUGOUT("Never got a valid link from auto-neg!!!\n"); ++ mac->autoneg_failed = 1; ++ /* ++ * AutoNeg failed to achieve a link, so we'll call ++ * mac->check_for_link. This routine will force the ++ * link up if we detect a signal. This will allow us to ++ * communicate with non-autonegotiating link partners. ++ */ ++ ret_val = hw->mac.ops.check_for_link(hw); ++ if (ret_val) { ++ DEBUGOUT("Error while checking for link\n"); ++ goto out; ++ } ++ mac->autoneg_failed = 0; ++ } else { ++ mac->autoneg_failed = 0; ++ DEBUGOUT("Valid Link Found\n"); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_commit_fc_settings_generic - Configure flow control ++ * @hw: pointer to the HW structure ++ * ++ * Write the flow control settings to the Transmit Config Word Register (TXCW) ++ * base on the flow control settings in e1000_mac_info. ++ **/ ++s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 txcw; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_commit_fc_settings_generic"); ++ ++ /* ++ * Check for a software override of the flow control settings, and ++ * setup the device accordingly. If auto-negotiation is enabled, then ++ * software will have to set the "PAUSE" bits to the correct value in ++ * the Transmit Config Word Register (TXCW) and re-start auto- ++ * negotiation. However, if auto-negotiation is disabled, then ++ * software will have to manually configure the two flow control enable ++ * bits in the CTRL register. ++ * ++ * The possible values of the "fc" parameter are: ++ * 0: Flow control is completely disabled ++ * 1: Rx flow control is enabled (we can receive pause frames, ++ * but not send pause frames). ++ * 2: Tx flow control is enabled (we can send pause frames but we ++ * do not support receiving pause frames). ++ * 3: Both Rx and Tx flow control (symmetric) are enabled. ++ */ ++ switch (hw->fc.type) { ++ case e1000_fc_none: ++ /* Flow control completely disabled by a software over-ride. */ ++ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); ++ break; ++ case e1000_fc_rx_pause: ++ /* ++ * Rx Flow control is enabled and Tx Flow control is disabled ++ * by a software over-ride. Since there really isn't a way to ++ * advertise that we are capable of Rx Pause ONLY, we will ++ * advertise that we support both symmetric and asymmetric RX ++ * PAUSE. Later, we will disable the adapter's ability to send ++ * PAUSE frames. ++ */ ++ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); ++ break; ++ case e1000_fc_tx_pause: ++ /* ++ * Tx Flow control is enabled, and Rx Flow control is disabled, ++ * by a software over-ride. ++ */ ++ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); ++ break; ++ case e1000_fc_full: ++ /* ++ * Flow control (both Rx and Tx) is enabled by a software ++ * over-ride. ++ */ ++ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); ++ break; ++ default: ++ DEBUGOUT("Flow control param set incorrectly\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ break; ++ } ++ ++ E1000_WRITE_REG(hw, E1000_TXCW, txcw); ++ mac->txcw = txcw; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_set_fc_watermarks_generic - Set flow control high/low watermarks ++ * @hw: pointer to the HW structure ++ * ++ * Sets the flow control high/low threshold (watermark) registers. If ++ * flow control XON frame transmission is enabled, then set XON frame ++ * transmission as well. ++ **/ ++s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u32 fcrtl = 0, fcrth = 0; ++ ++ DEBUGFUNC("e1000_set_fc_watermarks_generic"); ++ ++ /* ++ * Set the flow control receive threshold registers. Normally, ++ * these registers will be set to a default threshold that may be ++ * adjusted later by the driver's runtime code. However, if the ++ * ability to transmit pause frames is not enabled, then these ++ * registers will be set to 0. ++ */ ++ if (hw->fc.type & e1000_fc_tx_pause) { ++ /* ++ * We need to set up the Receive Threshold high and low water ++ * marks as well as (optionally) enabling the transmission of ++ * XON frames. ++ */ ++ fcrtl = hw->fc.low_water; ++ if (hw->fc.send_xon) ++ fcrtl |= E1000_FCRTL_XONE; ++ ++ fcrth = hw->fc.high_water; ++ } ++ E1000_WRITE_REG(hw, E1000_FCRTL, fcrtl); ++ E1000_WRITE_REG(hw, E1000_FCRTH, fcrth); ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_set_default_fc_generic - Set flow control default values ++ * @hw: pointer to the HW structure ++ * ++ * Read the EEPROM for the default values for flow control and store the ++ * values. ++ **/ ++s32 e1000_set_default_fc_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 nvm_data; ++ ++ DEBUGFUNC("e1000_set_default_fc_generic"); ++ ++ /* ++ * 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 ++ * disabling auto-negotiation, and the direction of the ++ * SW defined pins. If there is no SW over-ride of the flow ++ * control setting, then the variable hw->fc will ++ * be initialized based on a value in the EEPROM. ++ */ ++ ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); ++ ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ ++ if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) ++ hw->fc.type = e1000_fc_none; ++ else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == ++ NVM_WORD0F_ASM_DIR) ++ hw->fc.type = e1000_fc_tx_pause; ++ else ++ hw->fc.type = e1000_fc_full; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_force_mac_fc_generic - Force the MAC's flow control settings ++ * @hw: pointer to the HW structure ++ * ++ * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the ++ * device control register to reflect the adapter settings. TFCE and RFCE ++ * need to be explicitly set by software when a copper PHY is used because ++ * autonegotiation is managed by the PHY rather than the MAC. Software must ++ * also configure these bits when link is forced on a fiber connection. ++ **/ ++s32 e1000_force_mac_fc_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_force_mac_fc_generic"); ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ++ /* ++ * Because we didn't get link via the internal auto-negotiation ++ * mechanism (we either forced link or we got link via PHY ++ * auto-neg), we have to manually enable/disable transmit an ++ * receive flow control. ++ * ++ * The "Case" statement below enables/disable flow control ++ * according to the "hw->fc.type" parameter. ++ * ++ * The possible values of the "fc" parameter are: ++ * 0: Flow control is completely disabled ++ * 1: Rx flow control is enabled (we can receive pause ++ * frames but not send pause frames). ++ * 2: Tx flow control is enabled (we can send pause frames ++ * frames but we do not receive pause frames). ++ * 3: Both Rx and Tx flow control (symmetric) is enabled. ++ * other: No other values should be possible at this point. ++ */ ++ DEBUGOUT1("hw->fc.type = %u\n", hw->fc.type); ++ ++ switch (hw->fc.type) { ++ case e1000_fc_none: ++ ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); ++ break; ++ case e1000_fc_rx_pause: ++ ctrl &= (~E1000_CTRL_TFCE); ++ ctrl |= E1000_CTRL_RFCE; ++ break; ++ case e1000_fc_tx_pause: ++ ctrl &= (~E1000_CTRL_RFCE); ++ ctrl |= E1000_CTRL_TFCE; ++ break; ++ case e1000_fc_full: ++ ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); ++ break; ++ default: ++ DEBUGOUT("Flow control param set incorrectly\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_config_fc_after_link_up_generic - Configures flow control after link ++ * @hw: pointer to the HW structure ++ * ++ * Checks the status of auto-negotiation after link up to ensure that the ++ * speed and duplex were not forced. If the link needed to be forced, then ++ * flow control needs to be forced also. If auto-negotiation is enabled ++ * and did not fail, then we configure flow control based on our link ++ * partner. ++ **/ ++s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; ++ u16 speed, duplex; ++ ++ DEBUGFUNC("e1000_config_fc_after_link_up_generic"); ++ ++ /* ++ * Check for the case where we have fiber media and auto-neg failed ++ * so we had to force link. In this case, we need to force the ++ * configuration of the MAC to match the "fc" parameter. ++ */ ++ if (mac->autoneg_failed) { ++ if (hw->phy.media_type == e1000_media_type_fiber || ++ hw->phy.media_type == e1000_media_type_internal_serdes) ++ ret_val = e1000_force_mac_fc_generic(hw); ++ } else { ++ if (hw->phy.media_type == e1000_media_type_copper) ++ ret_val = e1000_force_mac_fc_generic(hw); ++ } ++ ++ if (ret_val) { ++ DEBUGOUT("Error forcing flow control settings\n"); ++ goto out; ++ } ++ ++ /* ++ * Check for the case where we have copper media and auto-neg is ++ * enabled. In this case, we need to check and see if Auto-Neg ++ * has completed, and if so, how the PHY and link partner has ++ * flow control configured. ++ */ ++ if ((hw->phy.media_type == e1000_media_type_copper) && mac->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 = phy->ops.read_reg(hw, PHY_STATUS, &mii_status_reg); ++ if (ret_val) ++ goto out; ++ ret_val = phy->ops.read_reg(hw, PHY_STATUS, &mii_status_reg); ++ if (ret_val) ++ goto out; ++ ++ if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { ++ DEBUGOUT("Copper PHY and Auto Neg " ++ "has not completed.\n"); ++ goto out; ++ } ++ ++ /* ++ * 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 Register (Address 5) to determine how ++ * flow control was negotiated. ++ */ ++ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, ++ &mii_nway_adv_reg); ++ if (ret_val) ++ goto out; ++ ret_val = phy->ops.read_reg(hw, PHY_LP_ABILITY, ++ &mii_nway_lp_ability_reg); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Two bits in the Auto Negotiation Advertisement Register ++ * (Address 4) and two bits in the Auto Negotiation Base ++ * Page Ability Register (Address 5) determine flow control ++ * for both the PHY and the link partner. The following ++ * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, ++ * 1999, describes these PAUSE resolution bits and how flow ++ * control is determined based upon these settings. ++ * NOTE: DC = Don't Care ++ * ++ * LOCAL DEVICE | LINK PARTNER ++ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution ++ *-------|---------|-------|---------|-------------------- ++ * 0 | 0 | DC | DC | e1000_fc_none ++ * 0 | 1 | 0 | DC | e1000_fc_none ++ * 0 | 1 | 1 | 0 | e1000_fc_none ++ * 0 | 1 | 1 | 1 | e1000_fc_tx_pause ++ * 1 | 0 | 0 | DC | e1000_fc_none ++ * 1 | DC | 1 | DC | e1000_fc_full ++ * 1 | 1 | 0 | 0 | e1000_fc_none ++ * 1 | 1 | 0 | 1 | e1000_fc_rx_pause ++ * ++ * Are both PAUSE bits set to 1? If so, this implies ++ * Symmetric Flow Control is enabled at both ends. The ++ * ASM_DIR bits are irrelevant per the spec. ++ * ++ * For Symmetric Flow Control: ++ * ++ * LOCAL DEVICE | LINK PARTNER ++ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result ++ *-------|---------|-------|---------|-------------------- ++ * 1 | DC | 1 | DC | E1000_fc_full ++ * ++ */ ++ 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->fc.original_type == e1000_fc_full) { ++ hw->fc.type = e1000_fc_full; ++ DEBUGOUT("Flow Control = FULL.\r\n"); ++ } else { ++ hw->fc.type = e1000_fc_rx_pause; ++ DEBUGOUT("Flow Control = " ++ "RX PAUSE frames only.\r\n"); ++ } ++ } ++ /* ++ * For receiving PAUSE frames ONLY. ++ * ++ * LOCAL DEVICE | LINK PARTNER ++ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result ++ *-------|---------|-------|---------|-------------------- ++ * 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)) { ++ hw->fc.type = e1000_fc_tx_pause; ++ DEBUGOUT("Flow Control = TX PAUSE frames only.\r\n"); ++ } ++ /* ++ * For transmitting PAUSE frames ONLY. ++ * ++ * LOCAL DEVICE | LINK PARTNER ++ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result ++ *-------|---------|-------|---------|-------------------- ++ * 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)) { ++ hw->fc.type = e1000_fc_rx_pause; ++ DEBUGOUT("Flow Control = RX PAUSE frames only.\r\n"); ++ } else { ++ /* ++ * Per the IEEE spec, at this point flow control ++ * should be disabled. ++ */ ++ hw->fc.type = e1000_fc_none; ++ DEBUGOUT("Flow Control = NONE.\r\n"); ++ } ++ ++ /* ++ * Now we need to do one last check... If we auto- ++ * negotiated to HALF DUPLEX, flow control should not be ++ * enabled per IEEE 802.3 spec. ++ */ ++ ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); ++ if (ret_val) { ++ DEBUGOUT("Error getting link speed and duplex\n"); ++ goto out; ++ } ++ ++ if (duplex == HALF_DUPLEX) ++ hw->fc.type = 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_generic(hw); ++ if (ret_val) { ++ DEBUGOUT("Error forcing flow control settings\n"); ++ goto out; ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_get_speed_and_duplex_copper_generic - Retrieve current speed/duplex ++ * @hw: pointer to the HW structure ++ * @speed: stores the current speed ++ * @duplex: stores the current duplex ++ * ++ * Read the status register for the current speed/duplex and store the current ++ * speed and duplex for copper connections. ++ **/ ++s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, ++ u16 *duplex) ++{ ++ u32 status; ++ ++ DEBUGFUNC("e1000_get_speed_and_duplex_copper_generic"); ++ ++ status = E1000_READ_REG(hw, E1000_STATUS); ++ if (status & E1000_STATUS_SPEED_1000) { ++ *speed = SPEED_1000; ++ DEBUGOUT("1000 Mbs, "); ++ } else if (status & E1000_STATUS_SPEED_100) { ++ *speed = SPEED_100; ++ DEBUGOUT("100 Mbs, "); ++ } else { ++ *speed = SPEED_10; ++ DEBUGOUT("10 Mbs, "); ++ } ++ ++ if (status & E1000_STATUS_FD) { ++ *duplex = FULL_DUPLEX; ++ DEBUGOUT("Full Duplex\n"); ++ } else { ++ *duplex = HALF_DUPLEX; ++ DEBUGOUT("Half Duplex\n"); ++ } ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_get_speed_and_duplex_fiber_generic - Retrieve current speed/duplex ++ * @hw: pointer to the HW structure ++ * @speed: stores the current speed ++ * @duplex: stores the current duplex ++ * ++ * Sets the speed and duplex to gigabit full duplex (the only possible option) ++ * for fiber/serdes links. ++ **/ ++s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, ++ u16 *speed, u16 *duplex) ++{ ++ DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); ++ ++ *speed = SPEED_1000; ++ *duplex = FULL_DUPLEX; ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_get_hw_semaphore_generic - Acquire hardware semaphore ++ * @hw: pointer to the HW structure ++ * ++ * Acquire the HW semaphore to access the PHY or NVM ++ **/ ++s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw) ++{ ++ u32 swsm; ++ s32 ret_val = E1000_SUCCESS; ++ s32 timeout = hw->nvm.word_size + 1; ++ s32 i = 0; ++ ++ DEBUGFUNC("e1000_get_hw_semaphore_generic"); ++ ++ /* Get the SW semaphore */ ++ while (i < timeout) { ++ swsm = E1000_READ_REG(hw, E1000_SWSM); ++ if (!(swsm & E1000_SWSM_SMBI)) ++ break; ++ ++ usec_delay(50); ++ i++; ++ } ++ ++ if (i == timeout) { ++ DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ /* Get the FW semaphore. */ ++ for (i = 0; i < timeout; i++) { ++ swsm = E1000_READ_REG(hw, E1000_SWSM); ++ E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); ++ ++ /* Semaphore acquired if bit latched */ ++ if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) ++ break; ++ ++ usec_delay(50); ++ } ++ ++ if (i == timeout) { ++ /* Release semaphores */ ++ e1000_put_hw_semaphore_generic(hw); ++ DEBUGOUT("Driver can't access the NVM\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_put_hw_semaphore_generic - Release hardware semaphore ++ * @hw: pointer to the HW structure ++ * ++ * Release hardware semaphore used to access the PHY or NVM ++ **/ ++void e1000_put_hw_semaphore_generic(struct e1000_hw *hw) ++{ ++ u32 swsm; ++ ++ DEBUGFUNC("e1000_put_hw_semaphore_generic"); ++ ++ swsm = E1000_READ_REG(hw, E1000_SWSM); ++ ++ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); ++ ++ E1000_WRITE_REG(hw, E1000_SWSM, swsm); ++} ++ ++/** ++ * e1000_get_auto_rd_done_generic - Check for auto read completion ++ * @hw: pointer to the HW structure ++ * ++ * Check EEPROM for Auto Read done bit. ++ **/ ++s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw) ++{ ++ s32 i = 0; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_get_auto_rd_done_generic"); ++ ++ while (i < AUTO_READ_DONE_TIMEOUT) { ++ if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_AUTO_RD) ++ break; ++ msec_delay(1); ++ i++; ++ } ++ ++ if (i == AUTO_READ_DONE_TIMEOUT) { ++ DEBUGOUT("Auto read by HW from NVM has not completed.\n"); ++ ret_val = -E1000_ERR_RESET; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_valid_led_default_generic - Verify a valid default LED config ++ * @hw: pointer to the HW structure ++ * @data: pointer to the NVM (EEPROM) ++ * ++ * Read the EEPROM for the current default LED configuration. If the ++ * LED configuration is not valid, set to a valid LED configuration. ++ **/ ++s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data) ++{ ++ s32 ret_val; ++ ++ DEBUGFUNC("e1000_valid_led_default_generic"); ++ ++ ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ ++ if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) ++ *data = ID_LED_DEFAULT; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_id_led_init_generic - ++ * @hw: pointer to the HW structure ++ * ++ **/ ++s32 e1000_id_led_init_generic(struct e1000_hw * hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ s32 ret_val; ++ const u32 ledctl_mask = 0x000000FF; ++ const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; ++ const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; ++ u16 data, i, temp; ++ const u16 led_mask = 0x0F; ++ ++ DEBUGFUNC("e1000_id_led_init_generic"); ++ ++ ret_val = hw->nvm.ops.valid_led_default(hw, &data); ++ if (ret_val) ++ goto out; ++ ++ mac->ledctl_default = E1000_READ_REG(hw, E1000_LEDCTL); ++ mac->ledctl_mode1 = mac->ledctl_default; ++ mac->ledctl_mode2 = mac->ledctl_default; ++ ++ for (i = 0; i < 4; i++) { ++ temp = (data >> (i << 2)) & led_mask; ++ switch (temp) { ++ case ID_LED_ON1_DEF2: ++ case ID_LED_ON1_ON2: ++ case ID_LED_ON1_OFF2: ++ mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); ++ mac->ledctl_mode1 |= ledctl_on << (i << 3); ++ break; ++ case ID_LED_OFF1_DEF2: ++ case ID_LED_OFF1_ON2: ++ case ID_LED_OFF1_OFF2: ++ mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); ++ mac->ledctl_mode1 |= ledctl_off << (i << 3); ++ break; ++ default: ++ /* Do nothing */ ++ break; ++ } ++ switch (temp) { ++ case ID_LED_DEF1_ON2: ++ case ID_LED_ON1_ON2: ++ case ID_LED_OFF1_ON2: ++ mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); ++ mac->ledctl_mode2 |= ledctl_on << (i << 3); ++ break; ++ case ID_LED_DEF1_OFF2: ++ case ID_LED_ON1_OFF2: ++ case ID_LED_OFF1_OFF2: ++ mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); ++ mac->ledctl_mode2 |= ledctl_off << (i << 3); ++ break; ++ default: ++ /* Do nothing */ ++ break; ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_setup_led_generic - Configures SW controllable LED ++ * @hw: pointer to the HW structure ++ * ++ * This prepares the SW controllable LED for use and saves the current state ++ * of the LED so it can be later restored. ++ **/ ++s32 e1000_setup_led_generic(struct e1000_hw *hw) ++{ ++ u32 ledctl; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_setup_led_generic"); ++ ++ if (hw->mac.ops.setup_led != e1000_setup_led_generic) { ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ if (hw->phy.media_type == e1000_media_type_fiber) { ++ ledctl = E1000_READ_REG(hw, E1000_LEDCTL); ++ hw->mac.ledctl_default = ledctl; ++ /* Turn off LED0 */ ++ ledctl &= ~(E1000_LEDCTL_LED0_IVRT | ++ E1000_LEDCTL_LED0_BLINK | ++ E1000_LEDCTL_LED0_MODE_MASK); ++ ledctl |= (E1000_LEDCTL_MODE_LED_OFF << ++ E1000_LEDCTL_LED0_MODE_SHIFT); ++ E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl); ++ } else if (hw->phy.media_type == e1000_media_type_copper) { ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_cleanup_led_generic - Set LED config to default operation ++ * @hw: pointer to the HW structure ++ * ++ * Remove the current LED configuration and set the LED configuration ++ * to the default value, saved from the EEPROM. ++ **/ ++s32 e1000_cleanup_led_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_cleanup_led_generic"); ++ ++ if (hw->mac.ops.cleanup_led != e1000_cleanup_led_generic) { ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_default); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_blink_led_generic - Blink LED ++ * @hw: pointer to the HW structure ++ * ++ * Blink the LEDs which are set to be on. ++ **/ ++s32 e1000_blink_led_generic(struct e1000_hw *hw) ++{ ++ u32 ledctl_blink = 0; ++ u32 i; ++ ++ DEBUGFUNC("e1000_blink_led_generic"); ++ ++ if (hw->phy.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->mac.ledctl_mode2; ++ for (i = 0; i < 4; i++) ++ if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == ++ E1000_LEDCTL_MODE_LED_ON) ++ ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << ++ (i * 8)); ++ } ++ ++ E1000_WRITE_REG(hw, E1000_LEDCTL, ledctl_blink); ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_led_on_generic - Turn LED on ++ * @hw: pointer to the HW structure ++ * ++ * Turn LED on. ++ **/ ++s32 e1000_led_on_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ ++ DEBUGFUNC("e1000_led_on_generic"); ++ ++ switch (hw->phy.media_type) { ++ case e1000_media_type_fiber: ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl &= ~E1000_CTRL_SWDPIN0; ++ ctrl |= E1000_CTRL_SWDPIO0; ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ break; ++ case e1000_media_type_copper: ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode2); ++ break; ++ default: ++ break; ++ } ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_led_off_generic - Turn LED off ++ * @hw: pointer to the HW structure ++ * ++ * Turn LED off. ++ **/ ++s32 e1000_led_off_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ ++ DEBUGFUNC("e1000_led_off_generic"); ++ ++ switch (hw->phy.media_type) { ++ case e1000_media_type_fiber: ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= E1000_CTRL_SWDPIN0; ++ ctrl |= E1000_CTRL_SWDPIO0; ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ break; ++ case e1000_media_type_copper: ++ E1000_WRITE_REG(hw, E1000_LEDCTL, hw->mac.ledctl_mode1); ++ break; ++ default: ++ break; ++ } ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_set_pcie_no_snoop_generic - Set PCI-express capabilities ++ * @hw: pointer to the HW structure ++ * @no_snoop: bitmap of snoop events ++ * ++ * Set the PCI-express register to snoop for events enabled in 'no_snoop'. ++ **/ ++void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop) ++{ ++ u32 gcr; ++ ++ DEBUGFUNC("e1000_set_pcie_no_snoop_generic"); ++ ++ if (hw->bus.type != e1000_bus_type_pci_express) ++ goto out; ++ ++ if (no_snoop) { ++ gcr = E1000_READ_REG(hw, E1000_GCR); ++ gcr &= ~(PCIE_NO_SNOOP_ALL); ++ gcr |= no_snoop; ++ E1000_WRITE_REG(hw, E1000_GCR, gcr); ++ } ++out: ++ return; ++} ++ ++/** ++ * e1000_disable_pcie_master_generic - Disables PCI-express master access ++ * @hw: pointer to the HW structure ++ * ++ * Returns 0 (E1000_SUCCESS) if successful, else returns -10 ++ * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused ++ * the master requests to be disabled. ++ * ++ * Disables PCI-Express master access and verifies there are no pending ++ * requests. ++ **/ ++s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl; ++ s32 timeout = MASTER_DISABLE_TIMEOUT; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_disable_pcie_master_generic"); ++ ++ if (hw->bus.type != e1000_bus_type_pci_express) ++ goto out; ++ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ ++ while (timeout) { ++ if (!(E1000_READ_REG(hw, E1000_STATUS) & ++ E1000_STATUS_GIO_MASTER_ENABLE)) ++ break; ++ usec_delay(100); ++ timeout--; ++ } ++ ++ if (!timeout) { ++ DEBUGOUT("Master requests are pending.\n"); ++ ret_val = -E1000_ERR_MASTER_REQUESTS_PENDING; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_reset_adaptive_generic - Reset Adaptive Interframe Spacing ++ * @hw: pointer to the HW structure ++ * ++ * Reset the Adaptive Interframe Spacing throttle to default values. ++ **/ ++void e1000_reset_adaptive_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ ++ DEBUGFUNC("e1000_reset_adaptive_generic"); ++ ++ if (!mac->adaptive_ifs) { ++ DEBUGOUT("Not in Adaptive IFS mode!\n"); ++ goto out; ++ } ++ ++ if (!mac->ifs_params_forced) { ++ mac->current_ifs_val = 0; ++ mac->ifs_min_val = IFS_MIN; ++ mac->ifs_max_val = IFS_MAX; ++ mac->ifs_step_size = IFS_STEP; ++ mac->ifs_ratio = IFS_RATIO; ++ } ++ ++ mac->in_ifs_mode = false; ++ E1000_WRITE_REG(hw, E1000_AIT, 0); ++out: ++ return; ++} ++ ++/** ++ * e1000_update_adaptive_generic - Update Adaptive Interframe Spacing ++ * @hw: pointer to the HW structure ++ * ++ * Update the Adaptive Interframe Spacing Throttle value based on the ++ * time between transmitted packets and time between collisions. ++ **/ ++void e1000_update_adaptive_generic(struct e1000_hw *hw) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ ++ DEBUGFUNC("e1000_update_adaptive_generic"); ++ ++ if (!mac->adaptive_ifs) { ++ DEBUGOUT("Not in Adaptive IFS mode!\n"); ++ goto out; ++ } ++ ++ if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { ++ if (mac->tx_packet_delta > MIN_NUM_XMITS) { ++ mac->in_ifs_mode = true; ++ if (mac->current_ifs_val < mac->ifs_max_val) { ++ if (!mac->current_ifs_val) ++ mac->current_ifs_val = mac->ifs_min_val; ++ else ++ mac->current_ifs_val += ++ mac->ifs_step_size; ++ E1000_WRITE_REG(hw, E1000_AIT, mac->current_ifs_val); ++ } ++ } ++ } else { ++ if (mac->in_ifs_mode && ++ (mac->tx_packet_delta <= MIN_NUM_XMITS)) { ++ mac->current_ifs_val = 0; ++ mac->in_ifs_mode = false; ++ E1000_WRITE_REG(hw, E1000_AIT, 0); ++ } ++ } ++out: ++ return; ++} ++ ++/** ++ * e1000_validate_mdi_setting_generic - Verify MDI/MDIx settings ++ * @hw: pointer to the HW structure ++ * ++ * Verify that when not using auto-negotiation that MDI/MDIx is correctly ++ * set, which is forced to MDI mode only. ++ **/ ++s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_validate_mdi_setting_generic"); ++ ++ if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) { ++ DEBUGOUT("Invalid MDI setting detected\n"); ++ hw->phy.mdix = 1; ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_8bit_ctrl_reg_generic - Write a 8bit CTRL register ++ * @hw: pointer to the HW structure ++ * @reg: 32bit register offset such as E1000_SCTL ++ * @offset: register offset to write to ++ * @data: data to write at register offset ++ * ++ * Writes an address/data control type register. There are several of these ++ * and they all have the format address << 8 | data and bit 31 is polled for ++ * completion. ++ **/ ++s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, ++ u32 offset, u8 data) ++{ ++ u32 i, regvalue = 0; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_write_8bit_ctrl_reg_generic"); ++ ++ /* Set up the address and data */ ++ regvalue = ((u32)data) | (offset << E1000_GEN_CTL_ADDRESS_SHIFT); ++ E1000_WRITE_REG(hw, reg, regvalue); ++ ++ /* Poll the ready bit to see if the MDI read completed */ ++ for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) { ++ usec_delay(5); ++ regvalue = E1000_READ_REG(hw, reg); ++ if (regvalue & E1000_GEN_CTL_READY) ++ break; ++ } ++ if (!(regvalue & E1000_GEN_CTL_READY)) { ++ DEBUGOUT1("Reg %08x did not indicate ready\n", reg); ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_mac.h linux-2.6.22-10/drivers/net/e1000e/e1000_mac.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_mac.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_mac.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,86 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _E1000_MAC_H_ ++#define _E1000_MAC_H_ ++ ++/* ++ * Functions that should not be called directly from drivers but can be used ++ * by other files in this 'shared code' ++ */ ++void e1000_init_mac_ops_generic(struct e1000_hw *hw); ++s32 e1000_blink_led_generic(struct e1000_hw *hw); ++s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw); ++s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw); ++s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw); ++s32 e1000_cleanup_led_generic(struct e1000_hw *hw); ++s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw); ++s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw); ++s32 e1000_disable_pcie_master_generic(struct e1000_hw *hw); ++s32 e1000_force_mac_fc_generic(struct e1000_hw *hw); ++s32 e1000_get_auto_rd_done_generic(struct e1000_hw *hw); ++s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw); ++s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw); ++s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, ++ u16 *duplex); ++s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, ++ u16 *speed, u16 *duplex); ++s32 e1000_id_led_init_generic(struct e1000_hw *hw); ++s32 e1000_led_on_generic(struct e1000_hw *hw); ++s32 e1000_led_off_generic(struct e1000_hw *hw); ++void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, ++ u8 *mc_addr_list, u32 mc_addr_count, ++ u32 rar_used_count, u32 rar_count); ++s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw); ++s32 e1000_set_default_fc_generic(struct e1000_hw *hw); ++s32 e1000_set_fc_watermarks_generic(struct e1000_hw *hw); ++s32 e1000_setup_fiber_serdes_link_generic(struct e1000_hw *hw); ++s32 e1000_setup_led_generic(struct e1000_hw *hw); ++s32 e1000_setup_link_generic(struct e1000_hw *hw); ++s32 e1000_validate_mdi_setting_generic(struct e1000_hw *hw); ++s32 e1000_write_8bit_ctrl_reg_generic(struct e1000_hw *hw, u32 reg, ++ u32 offset, u8 data); ++ ++u32 e1000_hash_mc_addr_generic(struct e1000_hw *hw, u8 *mc_addr); ++ ++void e1000_clear_hw_cntrs_base_generic(struct e1000_hw *hw); ++void e1000_clear_vfta_generic(struct e1000_hw *hw); ++void e1000_config_collision_dist_generic(struct e1000_hw *hw); ++void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count); ++void e1000_mta_set_generic(struct e1000_hw *hw, u32 hash_value); ++void e1000_pcix_mmrbc_workaround_generic(struct e1000_hw *hw); ++void e1000_put_hw_semaphore_generic(struct e1000_hw *hw); ++void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); ++s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw); ++void e1000_remove_device_generic(struct e1000_hw *hw); ++void e1000_reset_adaptive_generic(struct e1000_hw *hw); ++void e1000_set_pcie_no_snoop_generic(struct e1000_hw *hw, u32 no_snoop); ++void e1000_update_adaptive_generic(struct e1000_hw *hw); ++void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_manage.c linux-2.6.22-10/drivers/net/e1000e/e1000_manage.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_manage.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_manage.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,383 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#include "e1000_hw.h" ++ ++static u8 e1000_calculate_checksum(u8 *buffer, u32 length); ++ ++/** ++ * e1000_calculate_checksum - Calculate checksum for buffer ++ * @buffer: pointer to EEPROM ++ * @length: size of EEPROM to calculate a checksum for ++ * ++ * Calculates the checksum for some buffer on a specified length. The ++ * checksum calculated is returned. ++ **/ ++static u8 e1000_calculate_checksum(u8 *buffer, u32 length) ++{ ++ u32 i; ++ u8 sum = 0; ++ ++ DEBUGFUNC("e1000_calculate_checksum"); ++ ++ if (!buffer) ++ return 0; ++ ++ for (i = 0; i < length; i++) ++ sum += buffer[i]; ++ ++ return (u8) (0 - sum); ++} ++ ++/** ++ * e1000_mng_enable_host_if_generic - Checks host interface is enabled ++ * @hw: pointer to the HW structure ++ * ++ * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND ++ * ++ * This function checks whether the HOST IF is enabled for command operation ++ * and also checks whether the previous command is completed. It busy waits ++ * in case of previous command is not completed. ++ **/ ++s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw) ++{ ++ u32 hicr; ++ s32 ret_val = E1000_SUCCESS; ++ u8 i; ++ ++ DEBUGFUNC("e1000_mng_enable_host_if_generic"); ++ ++ /* Check that the host interface is enabled. */ ++ hicr = E1000_READ_REG(hw, E1000_HICR); ++ if ((hicr & E1000_HICR_EN) == 0) { ++ DEBUGOUT("E1000_HOST_EN bit disabled.\n"); ++ ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; ++ goto out; ++ } ++ /* check the previous command is completed */ ++ for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { ++ hicr = E1000_READ_REG(hw, E1000_HICR); ++ if (!(hicr & E1000_HICR_C)) ++ break; ++ msec_delay_irq(1); ++ } ++ ++ if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { ++ DEBUGOUT("Previous command timeout failed .\n"); ++ ret_val = -E1000_ERR_HOST_INTERFACE_COMMAND; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_check_mng_mode_generic - Generic check management mode ++ * @hw: pointer to the HW structure ++ * ++ * Reads the firmware semaphore register and returns true (>0) if ++ * manageability is enabled, else false (0). ++ **/ ++bool e1000_check_mng_mode_generic(struct e1000_hw *hw) ++{ ++ u32 fwsm; ++ ++ DEBUGFUNC("e1000_check_mng_mode_generic"); ++ ++ fwsm = E1000_READ_REG(hw, E1000_FWSM); ++ ++ return ((fwsm & E1000_FWSM_MODE_MASK) == ++ (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)); ++} ++ ++/** ++ * e1000_enable_tx_pkt_filtering_generic - Enable packet filtering on TX ++ * @hw: pointer to the HW structure ++ * ++ * Enables packet filtering on transmit packets if manageability is enabled ++ * and host interface is enabled. ++ **/ ++bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) ++{ ++ struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; ++ u32 *buffer = (u32 *)&hw->mng_cookie; ++ u32 offset; ++ s32 ret_val, hdr_csum, csum; ++ u8 i, len; ++ bool tx_filter = true; ++ ++ DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); ++ ++ /* No manageability, no filtering */ ++ if (!hw->mac.ops.check_mng_mode(hw)) { ++ tx_filter = false; ++ goto out; ++ } ++ ++ /* ++ * If we can't read from the host interface for whatever ++ * reason, disable filtering. ++ */ ++ ret_val = hw->mac.ops.mng_enable_host_if(hw); ++ if (ret_val != E1000_SUCCESS) { ++ tx_filter = false; ++ goto out; ++ } ++ ++ /* Read in the header. Length and offset are in dwords. */ ++ len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; ++ offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; ++ for (i = 0; i < len; i++) { ++ *(buffer + i) = E1000_READ_REG_ARRAY_DWORD(hw, ++ E1000_HOST_IF, ++ offset + i); ++ } ++ hdr_csum = hdr->checksum; ++ hdr->checksum = 0; ++ csum = e1000_calculate_checksum((u8 *)hdr, ++ E1000_MNG_DHCP_COOKIE_LENGTH); ++ /* ++ * If either the checksums or signature don't match, then ++ * the cookie area isn't considered valid, in which case we ++ * take the safe route of assuming Tx filtering is enabled. ++ */ ++ if (hdr_csum != csum) ++ goto out; ++ if (hdr->signature != E1000_IAMT_SIGNATURE) ++ goto out; ++ ++ /* Cookie area is valid, make the final check for filtering. */ ++ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) ++ tx_filter = false; ++ ++out: ++ hw->mac.tx_pkt_filtering = tx_filter; ++ return tx_filter; ++} ++ ++/** ++ * e1000_mng_write_dhcp_info_generic - Writes DHCP info to host interface ++ * @hw: pointer to the HW structure ++ * @buffer: pointer to the host interface ++ * @length: size of the buffer ++ * ++ * Writes the DHCP information to the host interface. ++ **/ ++s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, ++ u16 length) ++{ ++ struct e1000_host_mng_command_header hdr; ++ s32 ret_val; ++ u32 hicr; ++ ++ DEBUGFUNC("e1000_mng_write_dhcp_info_generic"); ++ ++ hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; ++ hdr.command_length = length; ++ hdr.reserved1 = 0; ++ hdr.reserved2 = 0; ++ hdr.checksum = 0; ++ ++ /* Enable the host interface */ ++ ret_val = hw->mac.ops.mng_enable_host_if(hw); ++ if (ret_val) ++ goto out; ++ ++ /* Populate the host interface with the contents of "buffer". */ ++ ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, ++ sizeof(hdr), &(hdr.checksum)); ++ if (ret_val) ++ goto out; ++ ++ /* Write the manageability command header */ ++ ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); ++ if (ret_val) ++ goto out; ++ ++ /* Tell the ARC a new command is pending. */ ++ hicr = E1000_READ_REG(hw, E1000_HICR); ++ E1000_WRITE_REG(hw, E1000_HICR, hicr | E1000_HICR_C); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_mng_write_cmd_header_generic - Writes manageability command header ++ * @hw: pointer to the HW structure ++ * @hdr: pointer to the host interface command header ++ * ++ * Writes the command header after does the checksum calculation. ++ **/ ++s32 e1000_mng_write_cmd_header_generic(struct e1000_hw * hw, ++ struct e1000_host_mng_command_header * hdr) ++{ ++ u16 i, length = sizeof(struct e1000_host_mng_command_header); ++ ++ DEBUGFUNC("e1000_mng_write_cmd_header_generic"); ++ ++ /* Write the whole command header structure with new checksum. */ ++ ++ hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); ++ ++ length >>= 2; ++ /* Write the relevant command block into the ram area. */ ++ for (i = 0; i < length; i++) { ++ E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, i, ++ *((u32 *) hdr + i)); ++ E1000_WRITE_FLUSH(hw); ++ } ++ ++ return E1000_SUCCESS; ++} ++ ++/** ++ * e1000_mng_host_if_write_generic - Write to the manageability host interface ++ * @hw: pointer to the HW structure ++ * @buffer: pointer to the host interface buffer ++ * @length: size of the buffer ++ * @offset: location in the buffer to write to ++ * @sum: sum of the data (not checksum) ++ * ++ * 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. ++ **/ ++s32 e1000_mng_host_if_write_generic(struct e1000_hw * hw, u8 *buffer, ++ u16 length, u16 offset, u8 *sum) ++{ ++ u8 *tmp; ++ u8 *bufptr = buffer; ++ u32 data = 0; ++ s32 ret_val = E1000_SUCCESS; ++ u16 remaining, i, j, prev_bytes; ++ ++ DEBUGFUNC("e1000_mng_host_if_write_generic"); ++ ++ /* sum = only sum of the data and it is not checksum */ ++ ++ if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { ++ ret_val = -E1000_ERR_PARAM; ++ goto out; ++ } ++ ++ tmp = (u8 *)&data; ++ prev_bytes = offset & 0x3; ++ offset >>= 2; ++ ++ if (prev_bytes) { ++ data = E1000_READ_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset); ++ for (j = prev_bytes; j < sizeof(u32); j++) { ++ *(tmp + j) = *bufptr++; ++ *sum += *(tmp + j); ++ } ++ E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_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(u32); j++) { ++ *(tmp + j) = *bufptr++; ++ *sum += *(tmp + j); ++ } ++ ++ E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); ++ } ++ if (remaining) { ++ for (j = 0; j < sizeof(u32); j++) { ++ if (j < remaining) ++ *(tmp + j) = *bufptr++; ++ else ++ *(tmp + j) = 0; ++ ++ *sum += *(tmp + j); ++ } ++ E1000_WRITE_REG_ARRAY_DWORD(hw, E1000_HOST_IF, offset + i, data); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_enable_mng_pass_thru - Enable processing of ARP's ++ * @hw: pointer to the HW structure ++ * ++ * Verifies the hardware needs to allow ARPs to be processed by the host. ++ **/ ++bool e1000_enable_mng_pass_thru(struct e1000_hw *hw) ++{ ++ u32 manc; ++ u32 fwsm, factps; ++ bool ret_val = false; ++ ++ DEBUGFUNC("e1000_enable_mng_pass_thru"); ++ ++ if (!hw->mac.asf_firmware_present) ++ goto out; ++ ++ manc = E1000_READ_REG(hw, E1000_MANC); ++ ++ if (!(manc & E1000_MANC_RCV_TCO_EN) || ++ !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) ++ goto out; ++ ++ if (hw->mac.arc_subsystem_valid) { ++ fwsm = E1000_READ_REG(hw, E1000_FWSM); ++ factps = E1000_READ_REG(hw, E1000_FACTPS); ++ ++ if (!(factps & E1000_FACTPS_MNGCG) && ++ ((fwsm & E1000_FWSM_MODE_MASK) == ++ (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { ++ ret_val = true; ++ goto out; ++ } ++ } else { ++ if ((manc & E1000_MANC_SMBUS_EN) && ++ !(manc & E1000_MANC_ASF_EN)) { ++ ret_val = true; ++ goto out; ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_manage.h linux-2.6.22-10/drivers/net/e1000e/e1000_manage.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_manage.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_manage.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,82 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _E1000_MANAGE_H_ ++#define _E1000_MANAGE_H_ ++ ++bool e1000_check_mng_mode_generic(struct e1000_hw *hw); ++bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw); ++s32 e1000_mng_enable_host_if_generic(struct e1000_hw *hw); ++s32 e1000_mng_host_if_write_generic(struct e1000_hw *hw, u8 *buffer, ++ u16 length, u16 offset, u8 *sum); ++s32 e1000_mng_write_cmd_header_generic(struct e1000_hw *hw, ++ struct e1000_host_mng_command_header *hdr); ++s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw *hw, ++ u8 *buffer, u16 length); ++bool e1000_enable_mng_pass_thru(struct e1000_hw *hw); ++ ++typedef enum { ++ e1000_mng_mode_none = 0, ++ e1000_mng_mode_asf, ++ e1000_mng_mode_pt, ++ e1000_mng_mode_ipmi, ++ e1000_mng_mode_host_if_only ++} e1000_mng_mode; ++ ++#define E1000_FACTPS_MNGCG 0x20000000 ++ ++#define E1000_FWSM_MODE_MASK 0xE ++#define E1000_FWSM_MODE_SHIFT 1 ++ ++#define E1000_MNG_IAMT_MODE 0x3 ++#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 ++#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 ++#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 ++#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 ++#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING 0x1 ++#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2 ++ ++#define E1000_VFTA_ENTRY_SHIFT 5 ++#define E1000_VFTA_ENTRY_MASK 0x7F ++#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F ++ ++#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */ ++#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */ ++#define E1000_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */ ++ ++#define E1000_HICR_EN 0x01 /* Enable bit - RO */ ++/* Driver sets this bit when done to put command in RAM */ ++#define E1000_HICR_C 0x02 ++#define E1000_HICR_SV 0x04 /* Status Validity */ ++#define E1000_HICR_FW_RESET_ENABLE 0x40 ++#define E1000_HICR_FW_RESET 0x80 ++ ++/* Intel(R) Active Management Technology signature */ ++#define E1000_IAMT_SIGNATURE 0x544D4149 ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_nvm.c linux-2.6.22-10/drivers/net/e1000e/e1000_nvm.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_nvm.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_nvm.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,875 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#include "e1000_hw.h" ++ ++/** ++ * e1000_init_nvm_ops_generic - Initialize NVM function pointers ++ * @hw: pointer to the HW structure ++ * ++ * Setups up the function pointers to no-op functions ++ **/ ++void e1000_init_nvm_ops_generic(struct e1000_hw *hw) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ DEBUGFUNC("e1000_init_nvm_ops_generic"); ++ ++ /* Initialize function pointers */ ++ nvm->ops.reload = e1000_reload_nvm_generic; ++} ++ ++/** ++ * e1000_raise_eec_clk - Raise EEPROM clock ++ * @hw: pointer to the HW structure ++ * @eecd: pointer to the EEPROM ++ * ++ * Enable/Raise the EEPROM clock bit. ++ **/ ++static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) ++{ ++ *eecd = *eecd | E1000_EECD_SK; ++ E1000_WRITE_REG(hw, E1000_EECD, *eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(hw->nvm.delay_usec); ++} ++ ++/** ++ * e1000_lower_eec_clk - Lower EEPROM clock ++ * @hw: pointer to the HW structure ++ * @eecd: pointer to the EEPROM ++ * ++ * Clear/Lower the EEPROM clock bit. ++ **/ ++static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) ++{ ++ *eecd = *eecd & ~E1000_EECD_SK; ++ E1000_WRITE_REG(hw, E1000_EECD, *eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(hw->nvm.delay_usec); ++} ++ ++/** ++ * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM ++ * @hw: pointer to the HW structure ++ * @data: data to send to the EEPROM ++ * @count: number of bits to shift out ++ * ++ * We need to shift 'count' bits out to the EEPROM. So, the value in the ++ * "data" parameter will be shifted out to the EEPROM one bit at a time. ++ * In order to do this, "data" must be broken down into bits. ++ **/ ++static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); ++ u32 mask; ++ ++ DEBUGFUNC("e1000_shift_out_eec_bits"); ++ ++ mask = 0x01 << (count - 1); ++ if (nvm->type == e1000_nvm_eeprom_microwire) ++ eecd &= ~E1000_EECD_DO; ++ else if (nvm->type == e1000_nvm_eeprom_spi) ++ eecd |= E1000_EECD_DO; ++ ++ do { ++ eecd &= ~E1000_EECD_DI; ++ ++ if (data & mask) ++ eecd |= E1000_EECD_DI; ++ ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ E1000_WRITE_FLUSH(hw); ++ ++ usec_delay(nvm->delay_usec); ++ ++ e1000_raise_eec_clk(hw, &eecd); ++ e1000_lower_eec_clk(hw, &eecd); ++ ++ mask >>= 1; ++ } while (mask); ++ ++ eecd &= ~E1000_EECD_DI; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++} ++ ++/** ++ * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM ++ * @hw: pointer to the HW structure ++ * @count: number of bits to shift in ++ * ++ * In order to read a register from the EEPROM, we need to shift 'count' bits ++ * in from the EEPROM. Bits are "shifted in" by raising the clock input to ++ * the EEPROM (setting the SK bit), and then reading the value of the data out ++ * "DO" bit. During this "shifting in" process the data in "DI" bit should ++ * always be clear. ++ **/ ++static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) ++{ ++ u32 eecd; ++ u32 i; ++ u16 data; ++ ++ DEBUGFUNC("e1000_shift_in_eec_bits"); ++ ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ ++ eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); ++ data = 0; ++ ++ for (i = 0; i < count; i++) { ++ data <<= 1; ++ e1000_raise_eec_clk(hw, &eecd); ++ ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ ++ eecd &= ~E1000_EECD_DI; ++ if (eecd & E1000_EECD_DO) ++ data |= 1; ++ ++ e1000_lower_eec_clk(hw, &eecd); ++ } ++ ++ return data; ++} ++ ++/** ++ * e1000_poll_eerd_eewr_done - Poll for EEPROM read/write completion ++ * @hw: pointer to the HW structure ++ * @ee_reg: EEPROM flag for polling ++ * ++ * Polls the EEPROM status bit for either read or write completion based ++ * upon the value of 'ee_reg'. ++ **/ ++s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) ++{ ++ u32 attempts = 100000; ++ u32 i, reg = 0; ++ s32 ret_val = -E1000_ERR_NVM; ++ ++ DEBUGFUNC("e1000_poll_eerd_eewr_done"); ++ ++ for (i = 0; i < attempts; i++) { ++ if (ee_reg == E1000_NVM_POLL_READ) ++ reg = E1000_READ_REG(hw, E1000_EERD); ++ else ++ reg = E1000_READ_REG(hw, E1000_EEWR); ++ ++ if (reg & E1000_NVM_RW_REG_DONE) { ++ ret_val = E1000_SUCCESS; ++ break; ++ } ++ ++ usec_delay(5); ++ } ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_acquire_nvm_generic - Generic request for access to EEPROM ++ * @hw: pointer to the HW structure ++ * ++ * Set the EEPROM access request bit and wait for EEPROM access grant bit. ++ * Return successful if access grant bit set, else clear the request for ++ * EEPROM access and return -E1000_ERR_NVM (-1). ++ **/ ++s32 e1000_acquire_nvm_generic(struct e1000_hw *hw) ++{ ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); ++ s32 timeout = E1000_NVM_GRANT_ATTEMPTS; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_acquire_nvm_generic"); ++ ++ E1000_WRITE_REG(hw, E1000_EECD, eecd | E1000_EECD_REQ); ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ ++ while (timeout) { ++ if (eecd & E1000_EECD_GNT) ++ break; ++ usec_delay(5); ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ timeout--; ++ } ++ ++ if (!timeout) { ++ eecd &= ~E1000_EECD_REQ; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ DEBUGOUT("Could not acquire NVM grant\n"); ++ ret_val = -E1000_ERR_NVM; ++ } ++ ++ return ret_val; ++} ++ ++/** ++ * e1000_standby_nvm - Return EEPROM to standby state ++ * @hw: pointer to the HW structure ++ * ++ * Return the EEPROM to a standby state. ++ **/ ++static void e1000_standby_nvm(struct e1000_hw *hw) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); ++ ++ DEBUGFUNC("e1000_standby_nvm"); ++ ++ if (nvm->type == e1000_nvm_eeprom_microwire) { ++ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(nvm->delay_usec); ++ ++ e1000_raise_eec_clk(hw, &eecd); ++ ++ /* Select EEPROM */ ++ eecd |= E1000_EECD_CS; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(nvm->delay_usec); ++ ++ e1000_lower_eec_clk(hw, &eecd); ++ } else if (nvm->type == e1000_nvm_eeprom_spi) { ++ /* Toggle CS to flush commands */ ++ eecd |= E1000_EECD_CS; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(nvm->delay_usec); ++ eecd &= ~E1000_EECD_CS; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ E1000_WRITE_FLUSH(hw); ++ usec_delay(nvm->delay_usec); ++ } ++} ++ ++/** ++ * e1000_stop_nvm - Terminate EEPROM command ++ * @hw: pointer to the HW structure ++ * ++ * Terminates the current command by inverting the EEPROM's chip select pin. ++ **/ ++void e1000_stop_nvm(struct e1000_hw *hw) ++{ ++ u32 eecd; ++ ++ DEBUGFUNC("e1000_stop_nvm"); ++ ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ if (hw->nvm.type == e1000_nvm_eeprom_spi) { ++ /* Pull CS high */ ++ eecd |= E1000_EECD_CS; ++ e1000_lower_eec_clk(hw, &eecd); ++ } else if (hw->nvm.type == e1000_nvm_eeprom_microwire) { ++ /* CS on Microwire is active-high */ ++ eecd &= ~(E1000_EECD_CS | E1000_EECD_DI); ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ e1000_raise_eec_clk(hw, &eecd); ++ e1000_lower_eec_clk(hw, &eecd); ++ } ++} ++ ++/** ++ * e1000_release_nvm_generic - Release exclusive access to EEPROM ++ * @hw: pointer to the HW structure ++ * ++ * Stop any current commands to the EEPROM and clear the EEPROM request bit. ++ **/ ++void e1000_release_nvm_generic(struct e1000_hw *hw) ++{ ++ u32 eecd; ++ ++ DEBUGFUNC("e1000_release_nvm_generic"); ++ ++ e1000_stop_nvm(hw); ++ ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ eecd &= ~E1000_EECD_REQ; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++} ++ ++/** ++ * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write ++ * @hw: pointer to the HW structure ++ * ++ * Setups the EEPROM for reading and writing. ++ **/ ++static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 eecd = E1000_READ_REG(hw, E1000_EECD); ++ s32 ret_val = E1000_SUCCESS; ++ u16 timeout = 0; ++ u8 spi_stat_reg; ++ ++ DEBUGFUNC("e1000_ready_nvm_eeprom"); ++ ++ if (nvm->type == e1000_nvm_eeprom_microwire) { ++ /* Clear SK and DI */ ++ eecd &= ~(E1000_EECD_DI | E1000_EECD_SK); ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ /* Set CS */ ++ eecd |= E1000_EECD_CS; ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ } else if (nvm->type == e1000_nvm_eeprom_spi) { ++ /* Clear SK and CS */ ++ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); ++ E1000_WRITE_REG(hw, E1000_EECD, eecd); ++ usec_delay(1); ++ timeout = NVM_MAX_RETRY_SPI; ++ ++ /* ++ * Read "Status Register" repeatedly until the LSB is cleared. ++ * The EEPROM will signal that the command has been completed ++ * by clearing bit 0 of the internal status register. If it's ++ * not cleared within 'timeout', then error out. ++ */ ++ while (timeout) { ++ e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, ++ hw->nvm.opcode_bits); ++ spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); ++ if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) ++ break; ++ ++ usec_delay(5); ++ e1000_standby_nvm(hw); ++ timeout--; ++ } ++ ++ if (!timeout) { ++ DEBUGOUT("SPI NVM Status error\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_nvm_spi - Read EEPROM's using SPI ++ * @hw: pointer to the HW structure ++ * @offset: offset of word in the EEPROM to read ++ * @words: number of words to read ++ * @data: word read from the EEPROM ++ * ++ * Reads a 16 bit word from the EEPROM. ++ **/ ++s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 i = 0; ++ s32 ret_val; ++ u16 word_in; ++ u8 read_opcode = NVM_READ_OPCODE_SPI; ++ ++ DEBUGFUNC("e1000_read_nvm_spi"); ++ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_ready_nvm_eeprom(hw); ++ if (ret_val) ++ goto release; ++ ++ e1000_standby_nvm(hw); ++ ++ if ((nvm->address_bits == 8) && (offset >= 128)) ++ read_opcode |= NVM_A8_OPCODE_SPI; ++ ++ /* Send the READ command (opcode + addr) */ ++ e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); ++ e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); ++ ++ /* ++ * Read the data. SPI NVMs increment the address with each byte ++ * read and will roll over if reading beyond the end. This allows ++ * us to read the whole NVM from any offset ++ */ ++ for (i = 0; i < words; i++) { ++ word_in = e1000_shift_in_eec_bits(hw, 16); ++ data[i] = (word_in >> 8) | (word_in << 8); ++ } ++ ++release: ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_nvm_microwire - Reads EEPROM's using microwire ++ * @hw: pointer to the HW structure ++ * @offset: offset of word in the EEPROM to read ++ * @words: number of words to read ++ * @data: word read from the EEPROM ++ * ++ * Reads a 16 bit word from the EEPROM. ++ **/ ++s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 i = 0; ++ s32 ret_val; ++ u8 read_opcode = NVM_READ_OPCODE_MICROWIRE; ++ ++ DEBUGFUNC("e1000_read_nvm_microwire"); ++ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_ready_nvm_eeprom(hw); ++ if (ret_val) ++ goto release; ++ ++ for (i = 0; i < words; i++) { ++ /* Send the READ command (opcode + addr) */ ++ e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); ++ e1000_shift_out_eec_bits(hw, (u16)(offset + i), ++ nvm->address_bits); ++ ++ /* ++ * Read the data. For microwire, each word requires the ++ * overhead of setup and tear-down. ++ */ ++ data[i] = e1000_shift_in_eec_bits(hw, 16); ++ e1000_standby_nvm(hw); ++ } ++ ++release: ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_nvm_eerd - Reads EEPROM using EERD register ++ * @hw: pointer to the HW structure ++ * @offset: offset of word in the EEPROM to read ++ * @words: number of words to read ++ * @data: word read from the EEPROM ++ * ++ * Reads a 16 bit word from the EEPROM using the EERD register. ++ **/ ++s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ u32 i, eerd = 0; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_read_nvm_eerd"); ++ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * too many words for the offset, and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ for (i = 0; i < words; i++) { ++ eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + ++ E1000_NVM_RW_REG_START; ++ ++ E1000_WRITE_REG(hw, E1000_EERD, eerd); ++ ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); ++ if (ret_val) ++ break; ++ ++ data[i] = (E1000_READ_REG(hw, E1000_EERD) >> ++ E1000_NVM_RW_REG_DATA); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_nvm_spi - Write to EEPROM using SPI ++ * @hw: pointer to the HW structure ++ * @offset: offset within the EEPROM to be written to ++ * @words: number of words to write ++ * @data: 16 bit word(s) to be written to the EEPROM ++ * ++ * Writes data to EEPROM at offset using SPI interface. ++ * ++ * If e1000_update_nvm_checksum is not called after this function , the ++ * EEPROM will most likely contain an invalid checksum. ++ **/ ++s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ s32 ret_val; ++ u16 widx = 0; ++ ++ DEBUGFUNC("e1000_write_nvm_spi"); ++ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ while (widx < words) { ++ u8 write_opcode = NVM_WRITE_OPCODE_SPI; ++ ++ ret_val = e1000_ready_nvm_eeprom(hw); ++ if (ret_val) ++ goto release; ++ ++ e1000_standby_nvm(hw); ++ ++ /* Send the WRITE ENABLE command (8 bit opcode) */ ++ e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, ++ nvm->opcode_bits); ++ ++ e1000_standby_nvm(hw); ++ ++ /* ++ * Some SPI eeproms use the 8th address bit embedded in the ++ * opcode ++ */ ++ if ((nvm->address_bits == 8) && (offset >= 128)) ++ write_opcode |= NVM_A8_OPCODE_SPI; ++ ++ /* Send the Write command (8-bit opcode + addr) */ ++ e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); ++ e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), ++ nvm->address_bits); ++ ++ /* Loop to allow for up to whole page write of eeprom */ ++ while (widx < words) { ++ u16 word_out = data[widx]; ++ word_out = (word_out >> 8) | (word_out << 8); ++ e1000_shift_out_eec_bits(hw, word_out, 16); ++ widx++; ++ ++ if ((((offset + widx) * 2) % nvm->page_size) == 0) { ++ e1000_standby_nvm(hw); ++ break; ++ } ++ } ++ } ++ ++ msec_delay(nvm->semaphore_delay); ++release: ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_nvm_microwire - Writes EEPROM using microwire ++ * @hw: pointer to the HW structure ++ * @offset: offset within the EEPROM to be written to ++ * @words: number of words to write ++ * @data: 16 bit word(s) to be written to the EEPROM ++ * ++ * Writes data to EEPROM at offset using microwire interface. ++ * ++ * If e1000_update_nvm_checksum is not called after this function , the ++ * EEPROM will most likely contain an invalid checksum. ++ **/ ++s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data) ++{ ++ struct e1000_nvm_info *nvm = &hw->nvm; ++ s32 ret_val; ++ u32 eecd; ++ u16 words_written = 0; ++ u16 widx = 0; ++ ++ DEBUGFUNC("e1000_write_nvm_microwire"); ++ ++ /* ++ * A check for invalid values: offset too large, too many words, ++ * and not enough words. ++ */ ++ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || ++ (words == 0)) { ++ DEBUGOUT("nvm parameter(s) out of bounds\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++ ret_val = nvm->ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_ready_nvm_eeprom(hw); ++ if (ret_val) ++ goto release; ++ ++ e1000_shift_out_eec_bits(hw, NVM_EWEN_OPCODE_MICROWIRE, ++ (u16)(nvm->opcode_bits + 2)); ++ ++ e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); ++ ++ e1000_standby_nvm(hw); ++ ++ while (words_written < words) { ++ e1000_shift_out_eec_bits(hw, NVM_WRITE_OPCODE_MICROWIRE, ++ nvm->opcode_bits); ++ ++ e1000_shift_out_eec_bits(hw, (u16)(offset + words_written), ++ nvm->address_bits); ++ ++ e1000_shift_out_eec_bits(hw, data[words_written], 16); ++ ++ e1000_standby_nvm(hw); ++ ++ for (widx = 0; widx < 200; widx++) { ++ eecd = E1000_READ_REG(hw, E1000_EECD); ++ if (eecd & E1000_EECD_DO) ++ break; ++ usec_delay(50); ++ } ++ ++ if (widx == 200) { ++ DEBUGOUT("NVM Write did not complete\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto release; ++ } ++ ++ e1000_standby_nvm(hw); ++ ++ words_written++; ++ } ++ ++ e1000_shift_out_eec_bits(hw, NVM_EWDS_OPCODE_MICROWIRE, ++ (u16)(nvm->opcode_bits + 2)); ++ ++ e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); ++ ++release: ++ nvm->ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_pba_num_generic - Read device part number ++ * @hw: pointer to the HW structure ++ * @pba_num: pointer to device part number ++ * ++ * Reads the product board assembly (PBA) number from the EEPROM and stores ++ * the value in pba_num. ++ **/ ++s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num) ++{ ++ s32 ret_val; ++ u16 nvm_data; ++ ++ DEBUGFUNC("e1000_read_pba_num_generic"); ++ ++ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ *pba_num = (u32)(nvm_data << 16); ++ ++ ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ *pba_num |= nvm_data; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_mac_addr_generic - Read device MAC address ++ * @hw: pointer to the HW structure ++ * ++ * Reads the device MAC address from the EEPROM and stores the value. ++ * Since devices with two ports use the same EEPROM, we increment the ++ * last bit in the MAC address for the second port. ++ **/ ++s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 offset, nvm_data, i; ++ ++ DEBUGFUNC("e1000_read_mac_addr"); ++ ++ for (i = 0; i < ETH_ADDR_LEN; i += 2) { ++ offset = i >> 1; ++ ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); ++ hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); ++ } ++ ++ /* Flip last bit of mac address if we're on second port */ ++ if (hw->bus.func == E1000_FUNC_1) ++ hw->mac.perm_addr[5] ^= 1; ++ ++ for (i = 0; i < ETH_ADDR_LEN; i++) ++ hw->mac.addr[i] = hw->mac.perm_addr[i]; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_validate_nvm_checksum_generic - Validate EEPROM checksum ++ * @hw: pointer to the HW structure ++ * ++ * Calculates the EEPROM checksum by reading/adding each word of the EEPROM ++ * and then verifies that the sum of the EEPROM is equal to 0xBABA. ++ **/ ++s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ u16 checksum = 0; ++ u16 i, nvm_data; ++ ++ DEBUGFUNC("e1000_validate_nvm_checksum_generic"); ++ ++ for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { ++ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error\n"); ++ goto out; ++ } ++ checksum += nvm_data; ++ } ++ ++ if (checksum != (u16) NVM_SUM) { ++ DEBUGOUT("NVM Checksum Invalid\n"); ++ ret_val = -E1000_ERR_NVM; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_update_nvm_checksum_generic - Update EEPROM checksum ++ * @hw: pointer to the HW structure ++ * ++ * Updates the EEPROM checksum by reading/adding each word of the EEPROM ++ * up to the checksum. Then calculates the EEPROM checksum and writes the ++ * value to the EEPROM. ++ **/ ++s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val; ++ u16 checksum = 0; ++ u16 i, nvm_data; ++ ++ DEBUGFUNC("e1000_update_nvm_checksum"); ++ ++ for (i = 0; i < NVM_CHECKSUM_REG; i++) { ++ ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); ++ if (ret_val) { ++ DEBUGOUT("NVM Read Error while updating checksum.\n"); ++ goto out; ++ } ++ checksum += nvm_data; ++ } ++ checksum = (u16) NVM_SUM - checksum; ++ ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum); ++ if (ret_val) { ++ DEBUGOUT("NVM Write Error while updating checksum.\n"); ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_reload_nvm_generic - Reloads EEPROM ++ * @hw: pointer to the HW structure ++ * ++ * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the ++ * extended control register. ++ **/ ++void e1000_reload_nvm_generic(struct e1000_hw *hw) ++{ ++ u32 ctrl_ext; ++ ++ DEBUGFUNC("e1000_reload_nvm_generic"); ++ ++ usec_delay(10); ++ ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); ++ ctrl_ext |= E1000_CTRL_EXT_EE_RST; ++ E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); ++ E1000_WRITE_FLUSH(hw); ++} ++ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_nvm.h linux-2.6.22-10/drivers/net/e1000e/e1000_nvm.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_nvm.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_nvm.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,58 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _E1000_NVM_H_ ++#define _E1000_NVM_H_ ++ ++void e1000_init_nvm_ops_generic(struct e1000_hw *hw); ++s32 e1000_acquire_nvm_generic(struct e1000_hw *hw); ++ ++s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg); ++s32 e1000_read_mac_addr_generic(struct e1000_hw *hw); ++s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num); ++s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); ++s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++s32 e1000_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data); ++s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data); ++s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw); ++s32 e1000_write_nvm_eewr(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, ++ u16 words, u16 *data); ++s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, ++ u16 *data); ++s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw); ++void e1000_stop_nvm(struct e1000_hw *hw); ++void e1000_release_nvm_generic(struct e1000_hw *hw); ++void e1000_reload_nvm_generic(struct e1000_hw *hw); ++ ++#define E1000_STM_OPCODE 0xDB00 ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_osdep.h linux-2.6.22-10/drivers/net/e1000e/e1000_osdep.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_osdep.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_osdep.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,116 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++ ++/* glue for the OS-dependent part of e1000 ++ * includes register access macros ++ */ ++ ++#ifndef _E1000_OSDEP_H_ ++#define _E1000_OSDEP_H_ ++ ++#include ++#include ++#include ++#include ++ ++#include "kcompat.h" ++ ++#define usec_delay(x) udelay(x) ++#ifndef msec_delay ++#define msec_delay(x) do { if(in_interrupt()) { \ ++ /* Don't sleep in interrupt context! */ \ ++ BUG(); \ ++ } else { \ ++ 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 ++#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE ++#define ETH_ADDR_LEN ETH_ALEN ++ ++ ++#define DEBUGOUT(S) ++#define DEBUGOUT1(S, A...) ++ ++#define DEBUGFUNC(F) DEBUGOUT(F "\n") ++#define DEBUGOUT2 DEBUGOUT1 ++#define DEBUGOUT3 DEBUGOUT2 ++#define DEBUGOUT7 DEBUGOUT3 ++ ++#define E1000_WRITE_REG(a, reg, value) ( \ ++ writel((value), ((a)->hw_addr + reg))) ++ ++#define E1000_READ_REG(a, reg) (readl((a)->hw_addr + reg)) ++ ++#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \ ++ writel((value), ((a)->hw_addr + reg + ((offset) << 2)))) ++ ++#define E1000_READ_REG_ARRAY(a, reg, offset) ( \ ++ readl((a)->hw_addr + 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 + reg + ((offset) << 1)))) ++ ++#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \ ++ readw((a)->hw_addr + reg + ((offset) << 1))) ++ ++#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \ ++ writeb((value), ((a)->hw_addr + reg + (offset)))) ++ ++#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \ ++ readb((a)->hw_addr + reg + (offset))) ++ ++#define E1000_WRITE_REG_IO(a, reg, offset) do { \ ++ outl(reg, ((a)->io_base)); \ ++ outl(offset, ((a)->io_base + 4)); } while(0) ++ ++#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS) ++ ++#define E1000_WRITE_FLASH_REG(a, reg, value) ( \ ++ writel((value), ((a)->flash_address + reg))) ++ ++#define E1000_WRITE_FLASH_REG16(a, reg, value) ( \ ++ writew((value), ((a)->flash_address + reg))) ++ ++#define E1000_READ_FLASH_REG(a, reg) (readl((a)->flash_address + reg)) ++ ++#define E1000_READ_FLASH_REG16(a, reg) (readw((a)->flash_address + reg)) ++ ++#endif /* _E1000_OSDEP_H_ */ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_phy.c linux-2.6.22-10/drivers/net/e1000e/e1000_phy.c +--- linux-2.6.22-0/drivers/net/e1000e/e1000_phy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_phy.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,2489 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#include "e1000_hw.h" ++ ++static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); ++/* Cable length tables */ ++static const u16 e1000_m88_cable_length_table[] = ++ { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; ++#define M88E1000_CABLE_LENGTH_TABLE_SIZE \ ++ (sizeof(e1000_m88_cable_length_table) / \ ++ sizeof(e1000_m88_cable_length_table[0])) ++ ++static const u16 e1000_igp_2_cable_length_table[] = ++ { 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}; ++#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ ++ (sizeof(e1000_igp_2_cable_length_table) / \ ++ sizeof(e1000_igp_2_cable_length_table[0])) ++ ++/** ++ * e1000_check_reset_block_generic - Check if PHY reset is blocked ++ * @hw: pointer to the HW structure ++ * ++ * Read the PHY management control register and check whether a PHY reset ++ * is blocked. If a reset is not blocked return E1000_SUCCESS, otherwise ++ * return E1000_BLK_PHY_RESET (12). ++ **/ ++s32 e1000_check_reset_block_generic(struct e1000_hw *hw) ++{ ++ u32 manc; ++ ++ DEBUGFUNC("e1000_check_reset_block"); ++ ++ manc = E1000_READ_REG(hw, E1000_MANC); ++ ++ return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? ++ E1000_BLK_PHY_RESET : E1000_SUCCESS; ++} ++ ++/** ++ * e1000_get_phy_id - Retrieve the PHY ID and revision ++ * @hw: pointer to the HW structure ++ * ++ * Reads the PHY registers and stores the PHY ID and possibly the PHY ++ * revision in the hardware structure. ++ **/ ++s32 e1000_get_phy_id(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_id; ++ ++ DEBUGFUNC("e1000_get_phy_id"); ++ ++ if (!(phy->ops.read_reg)) ++ goto out; ++ ++ ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); ++ if (ret_val) ++ goto out; ++ ++ phy->id = (u32)(phy_id << 16); ++ usec_delay(20); ++ ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); ++ if (ret_val) ++ goto out; ++ ++ phy->id |= (u32)(phy_id & PHY_REVISION_MASK); ++ phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_phy_reset_dsp_generic - Reset PHY DSP ++ * @hw: pointer to the HW structure ++ * ++ * Reset the digital signal processor. ++ **/ ++s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_phy_reset_dsp_generic"); ++ ++ if (!(hw->phy.ops.write_reg)) ++ goto out; ++ ++ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); ++ if (ret_val) ++ goto out; ++ ++ ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_phy_reg_mdic - Read MDI control register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to be read ++ * @data: pointer to the read data ++ * ++ * Reads the MDI control register in the PHY at offset and stores the ++ * information read to data. ++ **/ ++s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ u32 i, mdic = 0; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_read_phy_reg_mdic"); ++ ++ /* ++ * Set up Op-code, Phy Address, and register offset in the MDI ++ * Control register. The MAC will take care of interfacing with the ++ * PHY to retrieve the desired data. ++ */ ++ mdic = ((offset << E1000_MDIC_REG_SHIFT) | ++ (phy->addr << E1000_MDIC_PHY_SHIFT) | ++ (E1000_MDIC_OP_READ)); ++ ++ E1000_WRITE_REG(hw, E1000_MDIC, mdic); ++ ++ /* ++ * Poll the ready bit to see if the MDI read completed ++ * Increasing the time out as testing showed failures with ++ * the lower time out ++ */ ++ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { ++ usec_delay(50); ++ mdic = E1000_READ_REG(hw, E1000_MDIC); ++ if (mdic & E1000_MDIC_READY) ++ break; ++ } ++ if (!(mdic & E1000_MDIC_READY)) { ++ DEBUGOUT("MDI Read did not complete\n"); ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ if (mdic & E1000_MDIC_ERROR) { ++ DEBUGOUT("MDI Error\n"); ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ *data = (u16) mdic; ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_phy_reg_mdic - Write MDI control register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write to register at offset ++ * ++ * Writes data to MDI control register in the PHY at offset. ++ **/ ++s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ u32 i, mdic = 0; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_write_phy_reg_mdic"); ++ ++ /* ++ * Set up Op-code, Phy Address, and register offset in the MDI ++ * Control register. The MAC will take care of interfacing with the ++ * PHY to retrieve the desired data. ++ */ ++ mdic = (((u32)data) | ++ (offset << E1000_MDIC_REG_SHIFT) | ++ (phy->addr << E1000_MDIC_PHY_SHIFT) | ++ (E1000_MDIC_OP_WRITE)); ++ ++ E1000_WRITE_REG(hw, E1000_MDIC, mdic); ++ ++ /* ++ * Poll the ready bit to see if the MDI read completed ++ * Increasing the time out as testing showed failures with ++ * the lower time out ++ */ ++ for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) { ++ usec_delay(50); ++ mdic = E1000_READ_REG(hw, E1000_MDIC); ++ if (mdic & E1000_MDIC_READY) ++ break; ++ } ++ if (!(mdic & E1000_MDIC_READY)) { ++ DEBUGOUT("MDI Write did not complete\n"); ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ if (mdic & E1000_MDIC_ERROR) { ++ DEBUGOUT("MDI Error\n"); ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_phy_reg_m88 - Read m88 PHY register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to be read ++ * @data: pointer to the read data ++ * ++ * Acquires semaphore, if necessary, then reads the PHY register at offset ++ * and storing the retrieved information in data. Release any acquired ++ * semaphores before exiting. ++ **/ ++s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_read_phy_reg_m88"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_read_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_phy_reg_m88 - Write m88 PHY register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write at register offset ++ * ++ * Acquires semaphore, if necessary, then writes the data to PHY register ++ * at the offset. Release any acquired semaphores before exiting. ++ **/ ++s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_write_phy_reg_m88"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_phy_reg_igp - Read igp PHY register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to be read ++ * @data: pointer to the read data ++ * ++ * Acquires semaphore, if necessary, then reads the PHY register at offset ++ * and storing the retrieved information in data. Release any acquired ++ * semaphores before exiting. ++ **/ ++s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_read_phy_reg_igp"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ IGP01E1000_PHY_PAGE_SELECT, ++ (u16)offset); ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; ++ } ++ } ++ ++ ret_val = e1000_read_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_phy_reg_igp - Write igp PHY register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write at register offset ++ * ++ * Acquires semaphore, if necessary, then writes the data to PHY register ++ * at the offset. Release any acquired semaphores before exiting. ++ **/ ++s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) ++{ ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_write_phy_reg_igp"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ IGP01E1000_PHY_PAGE_SELECT, ++ (u16)offset); ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; ++ } ++ } ++ ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_read_kmrn_reg_generic - Read kumeran register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to be read ++ * @data: pointer to the read data ++ * ++ * Acquires semaphore, if necessary. Then reads the PHY register at offset ++ * using the kumeran interface. The information retrieved is stored in data. ++ * Release any acquired semaphores before exiting. ++ **/ ++s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) ++{ ++ u32 kmrnctrlsta; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_read_kmrn_reg_generic"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & ++ E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; ++ E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); ++ ++ usec_delay(2); ++ ++ kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); ++ *data = (u16)kmrnctrlsta; ++ ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_write_kmrn_reg_generic - Write kumeran register ++ * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write at register offset ++ * ++ * Acquires semaphore, if necessary. Then write the data to PHY register ++ * at the offset using the kumeran interface. Release any acquired semaphores ++ * before exiting. ++ **/ ++s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) ++{ ++ u32 kmrnctrlsta; ++ s32 ret_val = E1000_SUCCESS; ++ ++ DEBUGFUNC("e1000_write_kmrn_reg_generic"); ++ ++ if (!(hw->phy.ops.acquire)) ++ goto out; ++ ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; ++ ++ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & ++ E1000_KMRNCTRLSTA_OFFSET) | data; ++ E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); ++ ++ usec_delay(2); ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_copper_link_setup_m88 - Setup m88 PHY's for copper link ++ * @hw: pointer to the HW structure ++ * ++ * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock ++ * and downshift values are set also. ++ **/ ++s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_data; ++ ++ DEBUGFUNC("e1000_copper_link_setup_m88"); ++ ++ if (phy->reset_disable) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ ++ /* Enable CRS on TX. This must be set for half-duplex operation. */ ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; ++ ++ /* For newer PHYs this bit is downshift enable */ ++ if (phy->type == e1000_phy_m88) ++ 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 (phy->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 (phy->disable_polarity_correction == 1) ++ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; ++ ++ /* Enable downshift on BM (disabled by default) */ ++ if (phy->type == e1000_phy_bm) ++ phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT; ++ ++ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ++ if (ret_val) ++ goto out; ++ ++ if ((phy->type == e1000_phy_m88) && ++ (phy->revision < E1000_REVISION_4) && ++ (phy->id != BME1000_E_PHY_ID_R2)) { ++ /* ++ * Force TX_CLK in the Extended PHY Specific Control Register ++ * to 25MHz clock. ++ */ ++ ret_val = phy->ops.read_reg(hw, ++ M88E1000_EXT_PHY_SPEC_CTRL, ++ &phy_data); ++ if (ret_val) ++ goto out; ++ ++ phy_data |= M88E1000_EPSCR_TX_CLK_25; ++ ++ if ((phy->revision == E1000_REVISION_2) && ++ (phy->id == M88E1111_I_PHY_ID)) { ++ /* 82573L PHY - set the downshift counter to 5x. */ ++ phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK; ++ phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X; ++ } 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 = phy->ops.write_reg(hw, ++ M88E1000_EXT_PHY_SPEC_CTRL, ++ phy_data); ++ if (ret_val) ++ goto out; ++ } ++ ++ if ((phy->type == e1000_phy_bm) && (phy->id == BME1000_E_PHY_ID_R2)) { ++ /* Set PHY page 0, register 29 to 0x0003 */ ++ ret_val = phy->ops.write_reg(hw, 29, 0x0003); ++ if (ret_val) ++ goto out; ++ ++ /* Set PHY page 0, register 30 to 0x0000 */ ++ ret_val = phy->ops.write_reg(hw, 30, 0x0000); ++ if (ret_val) ++ goto out; ++ } ++ ++ /* Commit the changes. */ ++ ret_val = phy->ops.commit(hw); ++ if (ret_val) { ++ DEBUGOUT("Error committing the PHY changes\n"); ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_copper_link_setup_igp - Setup igp PHY's for copper link ++ * @hw: pointer to the HW structure ++ * ++ * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for ++ * igp PHY's. ++ **/ ++s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 data; + -+/* Offload data descriptor */ -+struct e1000_data_desc { -+ u64 buffer_addr; /* Address of the descriptor's buffer address */ -+ union { -+ u32 data; -+ struct { -+ u16 length; /* Data buffer length */ -+ u8 typ_len_ext; -+ u8 cmd; -+ } flags; -+ } lower; -+ union { -+ u32 data; -+ struct { -+ u8 status; /* Descriptor status */ -+ u8 popts; /* Packet Options */ -+ u16 special; /* */ -+ } fields; -+ } upper; -+}; ++ DEBUGFUNC("e1000_copper_link_setup_igp"); + -+/* Statistics counters collected by the MAC */ -+struct e1000_hw_stats { -+ u64 crcerrs; -+ u64 algnerrc; -+ u64 symerrs; -+ u64 rxerrc; -+ u64 mpc; -+ u64 scc; -+ u64 ecol; -+ u64 mcc; -+ u64 latecol; -+ u64 colc; -+ u64 dc; -+ u64 tncrs; -+ u64 sec; -+ u64 cexterr; -+ u64 rlec; -+ u64 xonrxc; -+ u64 xontxc; -+ u64 xoffrxc; -+ u64 xofftxc; -+ u64 fcruc; -+ u64 prc64; -+ u64 prc127; -+ u64 prc255; -+ u64 prc511; -+ u64 prc1023; -+ u64 prc1522; -+ u64 gprc; -+ u64 bprc; -+ u64 mprc; -+ u64 gptc; -+ u64 gorcl; -+ u64 gorch; -+ u64 gotcl; -+ u64 gotch; -+ u64 rnbc; -+ u64 ruc; -+ u64 rfc; -+ u64 roc; -+ u64 rjc; -+ u64 mgprc; -+ u64 mgpdc; -+ u64 mgptc; -+ u64 torl; -+ u64 torh; -+ u64 totl; -+ u64 toth; -+ u64 tpr; -+ u64 tpt; -+ u64 ptc64; -+ u64 ptc127; -+ u64 ptc255; -+ u64 ptc511; -+ u64 ptc1023; -+ u64 ptc1522; -+ u64 mptc; -+ u64 bptc; -+ u64 tsctc; -+ u64 tsctfc; -+ u64 iac; -+ u64 icrxptc; -+ u64 icrxatc; -+ u64 ictxptc; -+ u64 ictxatc; -+ u64 ictxqec; -+ u64 ictxqmtc; -+ u64 icrxdmtc; -+ u64 icrxoc; -+}; ++ if (phy->reset_disable) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ ++ ret_val = hw->phy.ops.reset(hw); ++ if (ret_val) { ++ DEBUGOUT("Error resetting the PHY.\n"); ++ goto out; ++ } ++ ++ /* ++ * Wait 100ms for MAC to configure PHY from NVM settings, to avoid ++ * timeout issues when LFS is enabled. ++ */ ++ msec_delay(100); ++ ++ /* ++ * The NVM settings will configure LPLU in D3 for ++ * non-IGP1 PHYs. ++ */ ++ if (phy->type == e1000_phy_igp) { ++ /* disable lplu d3 during driver init */ ++ ret_val = hw->phy.ops.set_d3_lplu_state(hw, false); ++ if (ret_val) { ++ DEBUGOUT("Error Disabling LPLU D3\n"); ++ goto out; ++ } ++ } ++ ++ /* disable lplu d0 during driver init */ ++ if (hw->phy.ops.set_d0_lplu_state) { ++ ret_val = hw->phy.ops.set_d0_lplu_state(hw, false); ++ if (ret_val) { ++ DEBUGOUT("Error Disabling LPLU D0\n"); ++ goto out; ++ } ++ } ++ /* Configure mdi-mdix settings */ ++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~IGP01E1000_PSCR_AUTO_MDIX; ++ ++ switch (phy->mdix) { ++ case 1: ++ data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; ++ break; ++ case 2: ++ data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; ++ break; ++ case 0: ++ default: ++ data |= IGP01E1000_PSCR_AUTO_MDIX; ++ break; ++ } ++ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data); ++ if (ret_val) ++ goto out; ++ ++ /* set auto-master slave resolution settings */ ++ if (hw->mac.autoneg) { ++ /* ++ * when autonegotiation advertisement is only 1000Mbps then we ++ * should disable SmartSpeed and enable Auto MasterSlave ++ * resolution as hardware default. ++ */ ++ if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { ++ /* Disable SmartSpeed */ ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ ++ /* Set auto Master/Slave resolution process */ ++ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); ++ if (ret_val) ++ goto out; ++ ++ data &= ~CR_1000T_MS_ENABLE; ++ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); ++ if (ret_val) ++ goto out; ++ } ++ ++ ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); ++ if (ret_val) ++ goto out; ++ ++ /* load defaults for future use */ ++ phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ? ++ ((data & CR_1000T_MS_VALUE) ? ++ e1000_ms_force_master : ++ e1000_ms_force_slave) : ++ e1000_ms_auto; ++ ++ switch (phy->ms_type) { ++ case e1000_ms_force_master: ++ data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); ++ break; ++ case e1000_ms_force_slave: ++ data |= CR_1000T_MS_ENABLE; ++ data &= ~(CR_1000T_MS_VALUE); ++ break; ++ case e1000_ms_auto: ++ data &= ~CR_1000T_MS_ENABLE; ++ default: ++ break; ++ } ++ ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); ++ if (ret_val) ++ goto out; ++ } ++ ++out: ++ return ret_val; ++} ++ ++/** ++ * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link ++ * @hw: pointer to the HW structure ++ * ++ * Performs initial bounds checking on autoneg advertisement parameter, then ++ * configure to advertise the full capability. Setup the PHY to autoneg ++ * and restart the negotiation process between the link partner. If ++ * autoneg_wait_to_complete, then wait for autoneg to complete before exiting. ++ **/ ++s32 e1000_copper_link_autoneg(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_ctrl; ++ ++ DEBUGFUNC("e1000_copper_link_autoneg"); ++ ++ /* ++ * Perform some bounds checking on the autoneg advertisement ++ * parameter. ++ */ ++ phy->autoneg_advertised &= phy->autoneg_mask; ++ ++ /* ++ * If autoneg_advertised is zero, we assume it was not defaulted ++ * by the calling code so we set to advertise full capability. ++ */ ++ if (phy->autoneg_advertised == 0) ++ phy->autoneg_advertised = phy->autoneg_mask; ++ ++ DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); ++ ret_val = e1000_phy_setup_autoneg(hw); ++ if (ret_val) { ++ DEBUGOUT("Error Setting up Auto-Negotiation\n"); ++ goto out; ++ } ++ 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 = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); ++ if (ret_val) ++ goto out; ++ ++ phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); ++ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl); ++ if (ret_val) ++ goto out; ++ ++ /* ++ * Does the user want to wait for Auto-Neg to complete here, or ++ * check at a later time (for example, callback routine). ++ */ ++ if (phy->autoneg_wait_to_complete) { ++ ret_val = hw->mac.ops.wait_autoneg(hw); ++ if (ret_val) { ++ DEBUGOUT("Error while waiting for " ++ "autoneg to complete\n"); ++ goto out; ++ } ++ } + -+struct e1000_phy_stats { -+ u32 idle_errors; -+ u32 receive_errors; -+}; ++ hw->mac.get_link_status = true; + -+struct e1000_host_mng_dhcp_cookie { -+ u32 signature; -+ u8 status; -+ u8 reserved0; -+ u16 vlan_id; -+ u32 reserved1; -+ u16 reserved2; -+ u8 reserved3; -+ u8 checksum; -+}; ++out: ++ return ret_val; ++} + -+/* Host Interface "Rev 1" */ -+struct e1000_host_command_header { -+ u8 command_id; -+ u8 command_length; -+ u8 command_options; -+ u8 checksum; -+}; ++/** ++ * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation ++ * @hw: pointer to the HW structure ++ * ++ * Reads the MII auto-neg advertisement register and/or the 1000T control ++ * register and if the PHY is already setup for auto-negotiation, then ++ * return successful. Otherwise, setup advertisement and flow control to ++ * the appropriate values for the wanted auto-negotiation. ++ **/ ++s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 mii_autoneg_adv_reg; ++ u16 mii_1000t_ctrl_reg = 0; + -+#define E1000_HI_MAX_DATA_LENGTH 252 -+struct e1000_host_command_info { -+ struct e1000_host_command_header command_header; -+ u8 command_data[E1000_HI_MAX_DATA_LENGTH]; -+}; ++ DEBUGFUNC("e1000_phy_setup_autoneg"); + -+/* Host Interface "Rev 2" */ -+struct e1000_host_mng_command_header { -+ u8 command_id; -+ u8 checksum; -+ u16 reserved1; -+ u16 reserved2; -+ u16 command_length; -+}; ++ phy->autoneg_advertised &= phy->autoneg_mask; + -+#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 -+struct e1000_host_mng_command_info { -+ struct e1000_host_mng_command_header command_header; -+ u8 command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; -+}; ++ /* Read the MII Auto-Neg Advertisement Register (Address 4). */ ++ ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); ++ if (ret_val) ++ goto out; + -+/* Function pointers and static data for the MAC. */ -+struct e1000_mac_operations { -+ u32 mng_mode_enab; ++ if (phy->autoneg_mask & ADVERTISE_1000_FULL) { ++ /* Read the MII 1000Base-T Control Register (Address 9). */ ++ ret_val = phy->ops.read_reg(hw, ++ PHY_1000T_CTRL, ++ &mii_1000t_ctrl_reg); ++ if (ret_val) ++ goto out; ++ } + -+ s32 (*check_for_link)(struct e1000_hw *); -+ s32 (*cleanup_led)(struct e1000_hw *); -+ void (*clear_hw_cntrs)(struct e1000_hw *); -+ s32 (*get_bus_info)(struct e1000_hw *); -+ s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); -+ s32 (*led_on)(struct e1000_hw *); -+ s32 (*led_off)(struct e1000_hw *); -+ void (*mc_addr_list_update)(struct e1000_hw *, u8 *, u32, u32, -+ u32); -+ s32 (*reset_hw)(struct e1000_hw *); -+ s32 (*init_hw)(struct e1000_hw *); -+ s32 (*setup_link)(struct e1000_hw *); -+ s32 (*setup_physical_interface)(struct e1000_hw *); -+}; ++ /* ++ * Need to parse both autoneg_advertised and fc and set up ++ * the appropriate PHY registers. First we will parse for ++ * autoneg_advertised software override. Since we can advertise ++ * a plethora of combinations, we need to check each bit ++ * individually. ++ */ + -+/* Function pointers for the PHY. */ -+struct e1000_phy_operations { -+ s32 (*acquire_phy)(struct e1000_hw *); -+ s32 (*check_reset_block)(struct e1000_hw *); -+ s32 (*commit_phy)(struct e1000_hw *); -+ s32 (*force_speed_duplex)(struct e1000_hw *); -+ s32 (*get_cfg_done)(struct e1000_hw *hw); -+ s32 (*get_cable_length)(struct e1000_hw *); -+ s32 (*get_phy_info)(struct e1000_hw *); -+ s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); -+ void (*release_phy)(struct e1000_hw *); -+ s32 (*reset_phy)(struct e1000_hw *); -+ s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); -+ s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); -+ s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); -+}; ++ /* ++ * First we clear all the 10/100 mb speed bits in the Auto-Neg ++ * Advertisement Register (Address 4) and the 1000 mb speed bits in ++ * the 1000Base-T Control Register (Address 9). ++ */ ++ mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | ++ NWAY_AR_100TX_HD_CAPS | ++ NWAY_AR_10T_FD_CAPS | ++ NWAY_AR_10T_HD_CAPS); ++ mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS); + -+/* Function pointers for the NVM. */ -+struct e1000_nvm_operations { -+ s32 (*acquire_nvm)(struct e1000_hw *); -+ s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *); -+ void (*release_nvm)(struct e1000_hw *); -+ s32 (*update_nvm)(struct e1000_hw *); -+ s32 (*valid_led_default)(struct e1000_hw *, u16 *); -+ s32 (*validate_nvm)(struct e1000_hw *); -+ s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *); -+}; ++ DEBUGOUT1("autoneg_advertised %x\n", phy->autoneg_advertised); + -+struct e1000_mac_info { -+ struct e1000_mac_operations ops; ++ /* Do we want to advertise 10 Mb Half Duplex? */ ++ if (phy->autoneg_advertised & ADVERTISE_10_HALF) { ++ DEBUGOUT("Advertise 10mb Half duplex\n"); ++ mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS; ++ } + -+ u8 addr[6]; -+ u8 perm_addr[6]; ++ /* Do we want to advertise 10 Mb Full Duplex? */ ++ if (phy->autoneg_advertised & ADVERTISE_10_FULL) { ++ DEBUGOUT("Advertise 10mb Full duplex\n"); ++ mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS; ++ } + -+ enum e1000_mac_type type; -+ enum e1000_fc_mode fc; -+ enum e1000_fc_mode original_fc; ++ /* Do we want to advertise 100 Mb Half Duplex? */ ++ if (phy->autoneg_advertised & ADVERTISE_100_HALF) { ++ DEBUGOUT("Advertise 100mb Half duplex\n"); ++ mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS; ++ } + -+ u32 collision_delta; -+ u32 ledctl_default; -+ u32 ledctl_mode1; -+ u32 ledctl_mode2; -+ u32 max_frame_size; -+ u32 mc_filter_type; -+ u32 min_frame_size; -+ u32 tx_packet_delta; -+ u32 txcw; ++ /* Do we want to advertise 100 Mb Full Duplex? */ ++ if (phy->autoneg_advertised & ADVERTISE_100_FULL) { ++ DEBUGOUT("Advertise 100mb Full duplex\n"); ++ mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS; ++ } + -+ u16 current_ifs_val; -+ u16 ifs_max_val; -+ u16 ifs_min_val; -+ u16 ifs_ratio; -+ u16 ifs_step_size; -+ u16 mta_reg_count; -+ u16 rar_entry_count; -+ u16 fc_high_water; -+ u16 fc_low_water; -+ u16 fc_pause_time; ++ /* We do not allow the Phy to advertise 1000 Mb Half Duplex */ ++ if (phy->autoneg_advertised & ADVERTISE_1000_HALF) { ++ DEBUGOUT("Advertise 1000mb Half duplex request denied!\n"); ++ } + -+ u8 forced_speed_duplex; ++ /* Do we want to advertise 1000 Mb Full Duplex? */ ++ if (phy->autoneg_advertised & ADVERTISE_1000_FULL) { ++ DEBUGOUT("Advertise 1000mb Full duplex\n"); ++ mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; ++ } + -+ bool arc_subsystem_valid; -+ bool autoneg; -+ bool autoneg_failed; -+ bool get_link_status; -+ bool in_ifs_mode; -+ bool serdes_has_link; -+ bool tx_pkt_filtering; -+}; ++ /* ++ * Check for a software override of the flow control settings, and ++ * setup the PHY advertisement registers accordingly. If ++ * auto-negotiation is enabled, then software will have to set the ++ * "PAUSE" bits to the correct value in the Auto-Negotiation ++ * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto- ++ * negotiation. ++ * ++ * The possible values of the "fc" parameter are: ++ * 0: Flow control is completely disabled ++ * 1: Rx flow control is enabled (we can receive pause frames ++ * but not send pause frames). ++ * 2: Tx flow control is enabled (we can send pause frames ++ * but we do not support receiving pause frames). ++ * 3: Both Rx and Tx flow control (symmetric) are enabled. ++ * other: No software override. The flow control configuration ++ * in the EEPROM is used. ++ */ ++ switch (hw->fc.type) { ++ case e1000_fc_none: ++ /* ++ * Flow control (Rx & Tx) is completely disabled by a ++ * software over-ride. ++ */ ++ mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); ++ break; ++ case e1000_fc_rx_pause: ++ /* ++ * Rx Flow control is enabled, and Tx Flow control is ++ * disabled, by a software over-ride. ++ * ++ * Since there really isn't a way to advertise that we are ++ * capable of Rx Pause ONLY, we will advertise that we ++ * support both symmetric and asymmetric Rx PAUSE. Later ++ * (in e1000_config_fc_after_link_up) we will disable the ++ * hw's ability to send PAUSE frames. ++ */ ++ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); ++ break; ++ case e1000_fc_tx_pause: ++ /* ++ * Tx Flow control is enabled, and Rx Flow control is ++ * disabled, by a software over-ride. ++ */ ++ mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; ++ mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; ++ break; ++ case e1000_fc_full: ++ /* ++ * Flow control (both Rx and Tx) is enabled by a software ++ * over-ride. ++ */ ++ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); ++ break; ++ default: ++ DEBUGOUT("Flow control param set incorrectly\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } + -+struct e1000_phy_info { -+ struct e1000_phy_operations ops; ++ ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); ++ if (ret_val) ++ goto out; + -+ enum e1000_phy_type type; ++ DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); + -+ enum e1000_1000t_rx_status local_rx; -+ enum e1000_1000t_rx_status remote_rx; -+ enum e1000_ms_type ms_type; -+ enum e1000_ms_type original_ms_type; -+ enum e1000_rev_polarity cable_polarity; -+ enum e1000_smart_speed smart_speed; ++ if (phy->autoneg_mask & ADVERTISE_1000_FULL) { ++ ret_val = phy->ops.write_reg(hw, ++ PHY_1000T_CTRL, ++ mii_1000t_ctrl_reg); ++ if (ret_val) ++ goto out; ++ } + -+ u32 addr; -+ u32 id; -+ u32 reset_delay_us; /* in usec */ -+ u32 revision; ++out: ++ return ret_val; ++} + -+ u16 autoneg_advertised; -+ u16 autoneg_mask; -+ u16 cable_length; -+ u16 max_cable_length; -+ u16 min_cable_length; ++/** ++ * e1000_setup_copper_link_generic - Configure copper link settings ++ * @hw: pointer to the HW structure ++ * ++ * Calls the appropriate function to configure the link for auto-neg or forced ++ * speed and duplex. Then we check for link, once link is established calls ++ * to configure collision distance and flow control are called. If link is ++ * not established, we return -E1000_ERR_PHY (-2). ++ **/ ++s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) ++{ ++ s32 ret_val; ++ bool link; + -+ u8 mdix; ++ DEBUGFUNC("e1000_setup_copper_link_generic"); + -+ bool disable_polarity_correction; -+ bool is_mdix; -+ bool polarity_correction; -+ bool speed_downgraded; -+ bool wait_for_link; -+}; ++ if (hw->mac.autoneg) { ++ /* ++ * Setup autoneg and flow control advertisement and perform ++ * autonegotiation. ++ */ ++ ret_val = e1000_copper_link_autoneg(hw); ++ if (ret_val) ++ goto out; ++ } else { ++ /* ++ * PHY will be set to 10H, 10F, 100H or 100F ++ * depending on user settings. ++ */ ++ DEBUGOUT("Forcing Speed and Duplex\n"); ++ ret_val = hw->phy.ops.force_speed_duplex(hw); ++ if (ret_val) { ++ DEBUGOUT("Error Forcing Speed and Duplex\n"); ++ goto out; ++ } ++ } ++ ++ /* ++ * Check link status. Wait up to 100 microseconds for link to become ++ * valid. ++ */ ++ ret_val = e1000_phy_has_link_generic(hw, ++ COPPER_LINK_UP_LIMIT, ++ 10, ++ &link); ++ if (ret_val) ++ goto out; ++ ++ if (link) { ++ DEBUGOUT("Valid link established!!!\n"); ++ e1000_config_collision_dist_generic(hw); ++ ret_val = e1000_config_fc_after_link_up_generic(hw); ++ } else { ++ DEBUGOUT("Unable to establish link!!!\n"); ++ } ++ ++out: ++ return ret_val; ++} + -+struct e1000_nvm_info { -+ struct e1000_nvm_operations ops; ++/** ++ * e1000_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY ++ * @hw: pointer to the HW structure ++ * ++ * Calls the PHY setup function to force speed and duplex. Clears the ++ * auto-crossover to force MDI manually. Waits for link and returns ++ * successful if link up is successful, else -E1000_ERR_PHY (-2). ++ **/ ++s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_data; ++ bool link; + -+ enum e1000_nvm_type type; -+ enum e1000_nvm_override override; ++ DEBUGFUNC("e1000_phy_force_speed_duplex_igp"); + -+ u32 flash_bank_size; -+ u32 flash_base_addr; ++ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); ++ if (ret_val) ++ goto out; + -+ u16 word_size; -+ u16 delay_usec; -+ u16 address_bits; -+ u16 opcode_bits; -+ u16 page_size; -+}; ++ e1000_phy_force_speed_duplex_setup(hw, &phy_data); + -+struct e1000_bus_info { -+ enum e1000_bus_width width; ++ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); ++ if (ret_val) ++ goto out; + -+ u16 func; -+}; ++ /* ++ * Clear Auto-Crossover to force MDI manually. IGP requires MDI ++ * forced whenever speed and duplex are forced. ++ */ ++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); ++ if (ret_val) ++ goto out; + -+struct e1000_dev_spec_82571 { -+ bool laa_is_present; -+}; ++ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; ++ phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; + -+struct e1000_shadow_ram { -+ u16 value; -+ bool modified; -+}; ++ ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); ++ if (ret_val) ++ goto out; + -+#define E1000_ICH8_SHADOW_RAM_WORDS 2048 ++ DEBUGOUT1("IGP PSCR: %X\n", phy_data); + -+struct e1000_dev_spec_ich8lan { -+ bool kmrn_lock_loss_workaround_enabled; -+ struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS]; -+}; ++ usec_delay(1); + -+struct e1000_hw { -+ struct e1000_adapter *adapter; ++ if (phy->autoneg_wait_to_complete) { ++ DEBUGOUT("Waiting for forced speed/duplex link on IGP phy.\n"); + -+ u8 __iomem *hw_addr; -+ u8 __iomem *flash_address; ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; + -+ struct e1000_mac_info mac; -+ struct e1000_phy_info phy; -+ struct e1000_nvm_info nvm; -+ struct e1000_bus_info bus; -+ struct e1000_host_mng_dhcp_cookie mng_cookie; ++ if (!link) { ++ DEBUGOUT("Link taking longer than expected.\n"); ++ } + -+ union { -+ struct e1000_dev_spec_82571 e82571; -+ struct e1000_dev_spec_ich8lan ich8lan; -+ } dev_spec; ++ /* Try once more */ ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; ++ } + -+ enum e1000_media_type media_type; -+}; ++out: ++ return ret_val; ++} + -+#ifdef DEBUG -+#define hw_dbg(hw, format, arg...) \ -+ printk(KERN_DEBUG, "%s: " format, e1000_get_hw_dev_name(hw), ##arg); -+#else -+static inline int __attribute__ ((format (printf, 2, 3))) -+hw_dbg(struct e1000_hw *hw, const char *format, ...) ++/** ++ * e1000_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY ++ * @hw: pointer to the HW structure ++ * ++ * Calls the PHY setup function to force speed and duplex. Clears the ++ * auto-crossover to force MDI manually. Resets the PHY to commit the ++ * changes. If time expires while waiting for link up, we reset the DSP. ++ * After reset, TX_CLK and CRS on Tx must be set. Return successful upon ++ * successful completion, else return corresponding error code. ++ **/ ++s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) +{ -+ return 0; -+} -+#endif ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_data; ++ bool link; + -+#endif -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/ich8lan.c linux-2.6.22-10/drivers/net/e1000e/ich8lan.c ---- linux-2.6.22-0/drivers/net/e1000e/ich8lan.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/ich8lan.c 2007-11-21 13:55:28.000000000 -0500 -@@ -0,0 +1,2225 @@ -+/******************************************************************************* ++ DEBUGFUNC("e1000_phy_force_speed_duplex_m88"); + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++ /* ++ * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI ++ * forced whenever speed and duplex are forced. ++ */ ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; ++ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ++ if (ret_val) ++ goto out; + -+ This program is distributed in the hope 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. ++ DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data); + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); ++ if (ret_val) ++ goto out; + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++ e1000_phy_force_speed_duplex_setup(hw, &phy_data); + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ /* Reset the phy to commit changes. */ ++ phy_data |= MII_CR_RESET; + -+*******************************************************************************/ ++ ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); ++ if (ret_val) ++ goto out; + -+/* -+ * 82562G-2 10/100 Network Connection -+ * 82562GT 10/100 Network Connection -+ * 82562GT-2 10/100 Network Connection -+ * 82562V 10/100 Network Connection -+ * 82562V-2 10/100 Network Connection -+ * 82566DC-2 Gigabit Network Connection -+ * 82566DC Gigabit Network Connection -+ * 82566DM-2 Gigabit Network Connection -+ * 82566DM Gigabit Network Connection -+ * 82566MC Gigabit Network Connection -+ * 82566MM Gigabit Network Connection -+ */ ++ usec_delay(1); + -+#include -+#include -+#include -+#include ++ if (phy->autoneg_wait_to_complete) { ++ DEBUGOUT("Waiting for forced speed/duplex link on M88 phy.\n"); + -+#include "e1000.h" ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; ++ ++ if (!link) { ++ /* ++ * We didn't get link. ++ * Reset the DSP and cross our fingers. ++ */ ++ ret_val = phy->ops.write_reg(hw, ++ M88E1000_PHY_PAGE_SELECT, ++ 0x001d); ++ if (ret_val) ++ goto out; ++ ret_val = e1000_phy_reset_dsp_generic(hw); ++ if (ret_val) ++ goto out; ++ } + -+#define ICH_FLASH_GFPREG 0x0000 -+#define ICH_FLASH_HSFSTS 0x0004 -+#define ICH_FLASH_HSFCTL 0x0006 -+#define ICH_FLASH_FADDR 0x0008 -+#define ICH_FLASH_FDATA0 0x0010 ++ /* Try once more */ ++ ret_val = e1000_phy_has_link_generic(hw, ++ PHY_FORCE_LIMIT, ++ 100000, ++ &link); ++ if (ret_val) ++ goto out; ++ } + -+#define ICH_FLASH_READ_COMMAND_TIMEOUT 500 -+#define ICH_FLASH_WRITE_COMMAND_TIMEOUT 500 -+#define ICH_FLASH_ERASE_COMMAND_TIMEOUT 3000000 -+#define ICH_FLASH_LINEAR_ADDR_MASK 0x00FFFFFF -+#define ICH_FLASH_CYCLE_REPEAT_COUNT 10 ++ ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; + -+#define ICH_CYCLE_READ 0 -+#define ICH_CYCLE_WRITE 2 -+#define ICH_CYCLE_ERASE 3 ++ /* ++ * Resetting the phy means we need to re-force TX_CLK in the ++ * Extended PHY Specific Control Register to 25MHz clock from ++ * the reset value of 2.5MHz. ++ */ ++ phy_data |= M88E1000_EPSCR_TX_CLK_25; ++ ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); ++ if (ret_val) ++ goto out; + -+#define FLASH_GFPREG_BASE_MASK 0x1FFF -+#define FLASH_SECTOR_ADDR_SHIFT 12 ++ /* ++ * In addition, we must re-enable CRS on Tx for both half and full ++ * duplex. ++ */ ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; + -+#define ICH_FLASH_SEG_SIZE_256 256 -+#define ICH_FLASH_SEG_SIZE_4K 4096 -+#define ICH_FLASH_SEG_SIZE_8K 8192 -+#define ICH_FLASH_SEG_SIZE_64K 65536 ++ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; ++ ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + ++out: ++ return ret_val; ++} + -+#define E1000_ICH_FWSM_RSPCIPHY 0x00000040 /* Reset PHY on PCI Reset */ ++/** ++ * e1000_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex ++ * @hw: pointer to the HW structure ++ * @phy_ctrl: pointer to current value of PHY_CONTROL ++ * ++ * Forces speed and duplex on the PHY by doing the following: disable flow ++ * control, force speed/duplex on the MAC, disable auto speed detection, ++ * disable auto-negotiation, configure duplex, configure speed, configure ++ * the collision distance, write configuration to CTRL register. The ++ * caller must write to the PHY_CONTROL register for these settings to ++ * take affect. ++ **/ ++void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) ++{ ++ struct e1000_mac_info *mac = &hw->mac; ++ u32 ctrl; + -+#define E1000_ICH_MNG_IAMT_MODE 0x2 ++ DEBUGFUNC("e1000_phy_force_speed_duplex_setup"); + -+#define ID_LED_DEFAULT_ICH8LAN ((ID_LED_DEF1_DEF2 << 12) | \ -+ (ID_LED_DEF1_OFF2 << 8) | \ -+ (ID_LED_DEF1_ON2 << 4) | \ -+ (ID_LED_DEF1_DEF2)) ++ /* Turn off flow control when forcing speed/duplex */ ++ hw->fc.type = e1000_fc_none; + -+#define E1000_ICH_NVM_SIG_WORD 0x13 -+#define E1000_ICH_NVM_SIG_MASK 0xC000 ++ /* Force speed/duplex on the mac */ ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); ++ ctrl &= ~E1000_CTRL_SPD_SEL; + -+#define E1000_ICH8_LAN_INIT_TIMEOUT 1500 ++ /* Disable Auto Speed Detection */ ++ ctrl &= ~E1000_CTRL_ASDE; + -+#define E1000_FEXTNVM_SW_CONFIG 1 -+#define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */ ++ /* Disable autoneg on the phy */ ++ *phy_ctrl &= ~MII_CR_AUTO_NEG_EN; + -+#define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL ++ /* Forcing Full or Half Duplex? */ ++ if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) { ++ ctrl &= ~E1000_CTRL_FD; ++ *phy_ctrl &= ~MII_CR_FULL_DUPLEX; ++ DEBUGOUT("Half Duplex\n"); ++ } else { ++ ctrl |= E1000_CTRL_FD; ++ *phy_ctrl |= MII_CR_FULL_DUPLEX; ++ DEBUGOUT("Full Duplex\n"); ++ } + -+#define E1000_ICH_RAR_ENTRIES 7 ++ /* Forcing 10mb or 100mb? */ ++ if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) { ++ ctrl |= E1000_CTRL_SPD_100; ++ *phy_ctrl |= MII_CR_SPEED_100; ++ *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10); ++ DEBUGOUT("Forcing 100mb\n"); ++ } else { ++ ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); ++ *phy_ctrl |= MII_CR_SPEED_10; ++ *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100); ++ DEBUGOUT("Forcing 10mb\n"); ++ } + -+#define PHY_PAGE_SHIFT 5 -+#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \ -+ ((reg) & MAX_PHY_REG_ADDRESS)) -+#define IGP3_KMRN_DIAG PHY_REG(770, 19) /* KMRN Diagnostic */ -+#define IGP3_VR_CTRL PHY_REG(776, 18) /* Voltage Regulator Control */ ++ e1000_config_collision_dist_generic(hw); + -+#define IGP3_KMRN_DIAG_PCS_LOCK_LOSS 0x0002 -+#define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300 -+#define IGP3_VR_CTRL_MODE_SHUTDOWN 0x0200 ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++} + -+/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ -+/* Offset 04h HSFSTS */ -+union ich8_hws_flash_status { -+ struct ich8_hsfsts { -+ u16 flcdone :1; /* bit 0 Flash Cycle Done */ -+ u16 flcerr :1; /* bit 1 Flash Cycle Error */ -+ u16 dael :1; /* bit 2 Direct Access error Log */ -+ u16 berasesz :2; /* bit 4:3 Sector Erase Size */ -+ u16 flcinprog :1; /* bit 5 flash cycle in Progress */ -+ u16 reserved1 :2; /* bit 13:6 Reserved */ -+ u16 reserved2 :6; /* bit 13:6 Reserved */ -+ u16 fldesvalid :1; /* bit 14 Flash Descriptor Valid */ -+ u16 flockdn :1; /* bit 15 Flash Config Lock-Down */ -+ } hsf_status; -+ u16 regval; -+}; ++/** ++ * e1000_set_d3_lplu_state_generic - Sets low power link up state for D3 ++ * @hw: pointer to the HW structure ++ * @active: boolean used to enable/disable lplu ++ * ++ * Success returns 0, Failure returns 1 ++ * ++ * The low power link up (lplu) state is set to the power management level D3 ++ * and SmartSpeed is disabled when active is true, else clear lplu for D3 ++ * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU ++ * is used during Dx states where the power conservation is most important. ++ * During driver activity, SmartSpeed should be enabled so performance is ++ * maintained. ++ **/ ++s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) ++{ ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val = E1000_SUCCESS; ++ u16 data; + -+/* ICH GbE Flash Hardware Sequencing Flash control Register bit breakdown */ -+/* Offset 06h FLCTL */ -+union ich8_hws_flash_ctrl { -+ struct ich8_hsflctl { -+ u16 flcgo :1; /* 0 Flash Cycle Go */ -+ u16 flcycle :2; /* 2:1 Flash Cycle */ -+ u16 reserved :5; /* 7:3 Reserved */ -+ u16 fldbcount :2; /* 9:8 Flash Data Byte Count */ -+ u16 flockdn :6; /* 15:10 Reserved */ -+ } hsf_ctrl; -+ u16 regval; -+}; ++ DEBUGFUNC("e1000_set_d3_lplu_state_generic"); + -+/* ICH Flash Region Access Permissions */ -+union ich8_hws_flash_regacc { -+ struct ich8_flracc { -+ u32 grra :8; /* 0:7 GbE region Read Access */ -+ u32 grwa :8; /* 8:15 GbE region Write Access */ -+ u32 gmrag :8; /* 23:16 GbE Master Read Access Grant */ -+ u32 gmwag :8; /* 31:24 GbE Master Write Access Grant */ -+ } hsf_flregacc; -+ u16 regval; -+}; ++ if (!(hw->phy.ops.read_reg)) ++ goto out; + -+static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); -+static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); -+static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); -+static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); -+static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); -+static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, -+ u32 offset, u8 byte); -+static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, -+ u16 *data); -+static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, -+ u8 size, u16 *data); -+static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); -+static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); ++ ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); ++ if (ret_val) ++ goto out; + -+static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) -+{ -+ return readw(hw->flash_address + reg); -+} ++ if (!active) { ++ data &= ~IGP02E1000_PM_D3_LPLU; ++ ret_val = phy->ops.write_reg(hw, ++ IGP02E1000_PHY_POWER_MGMT, ++ data); ++ if (ret_val) ++ goto out; ++ /* ++ * 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 (phy->smart_speed == e1000_smart_speed_on) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+static inline u32 __er32flash(struct e1000_hw *hw, unsigned long reg) -+{ -+ return readl(hw->flash_address + reg); -+} ++ data |= IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } else if (phy->smart_speed == e1000_smart_speed_off) { ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+static inline void __ew16flash(struct e1000_hw *hw, unsigned long reg, u16 val) -+{ -+ writew(val, hw->flash_address + reg); -+} ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ if (ret_val) ++ goto out; ++ } ++ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || ++ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || ++ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { ++ data |= IGP02E1000_PM_D3_LPLU; ++ ret_val = phy->ops.write_reg(hw, ++ IGP02E1000_PHY_POWER_MGMT, ++ data); ++ if (ret_val) ++ goto out; + -+static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val) -+{ -+ writel(val, hw->flash_address + reg); -+} ++ /* When LPLU is enabled, we should disable SmartSpeed */ ++ ret_val = phy->ops.read_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ &data); ++ if (ret_val) ++ goto out; + -+#define er16flash(reg) __er16flash(hw, (reg)) -+#define er32flash(reg) __er32flash(hw, (reg)) -+#define ew16flash(reg,val) __ew16flash(hw, (reg), (val)) -+#define ew32flash(reg,val) __ew32flash(hw, (reg), (val)) ++ data &= ~IGP01E1000_PSCFR_SMART_SPEED; ++ ret_val = phy->ops.write_reg(hw, ++ IGP01E1000_PHY_PORT_CONFIG, ++ data); ++ } ++ ++out: ++ return ret_val; ++} + +/** -+ * e1000_init_phy_params_ich8lan - Initialize PHY function pointers ++ * e1000_check_downshift_generic - Checks whether a downshift in speed occurred + * @hw: pointer to the HW structure + * -+ * Initialize family-specific PHY parameters and function pointers. ++ * Success returns 0, Failure returns 1 ++ * ++ * A downshift is detected by querying the PHY link health. + **/ -+static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) ++s32 e1000_check_downshift_generic(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; -+ u16 i = 0; -+ -+ phy->addr = 1; -+ phy->reset_delay_us = 100; ++ u16 phy_data, offset, mask; + -+ phy->id = 0; -+ while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) && -+ (i++ < 100)) { -+ msleep(1); -+ ret_val = e1000e_get_phy_id(hw); -+ if (ret_val) -+ return ret_val; -+ } ++ DEBUGFUNC("e1000_check_downshift_generic"); + -+ /* Verify phy id */ -+ switch (phy->id) { -+ case IGP03E1000_E_PHY_ID: -+ phy->type = e1000_phy_igp_3; -+ phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; ++ switch (phy->type) { ++ case e1000_phy_m88: ++ case e1000_phy_gg82563: ++ case e1000_phy_bm: ++ offset = M88E1000_PHY_SPEC_STATUS; ++ mask = M88E1000_PSSR_DOWNSHIFT; + break; -+ case IFE_E_PHY_ID: -+ case IFE_PLUS_E_PHY_ID: -+ case IFE_C_E_PHY_ID: -+ phy->type = e1000_phy_ife; -+ phy->autoneg_mask = E1000_ALL_NOT_GIG; ++ case e1000_phy_igp_2: ++ case e1000_phy_igp: ++ case e1000_phy_igp_3: ++ offset = IGP01E1000_PHY_LINK_HEALTH; ++ mask = IGP01E1000_PLHR_SS_DOWNGRADE; + break; + default: -+ return -E1000_ERR_PHY; -+ break; ++ /* speed downshift not supported */ ++ phy->speed_downgraded = false; ++ ret_val = E1000_SUCCESS; ++ goto out; + } + -+ return 0; ++ ret_val = phy->ops.read_reg(hw, offset, &phy_data); ++ ++ if (!ret_val) ++ phy->speed_downgraded = (phy_data & mask) ? true : false; ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_init_nvm_params_ich8lan - Initialize NVM function pointers ++ * e1000_check_polarity_m88 - Checks the polarity. + * @hw: pointer to the HW structure + * -+ * Initialize family-specific NVM parameters and function -+ * pointers. ++ * Success returns 0, Failure returns -E1000_ERR_PHY (-2) ++ * ++ * Polarity is determined based on the PHY specific status register. + **/ -+static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) ++s32 e1000_check_polarity_m88(struct e1000_hw *hw) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -+ u32 gfpreg; -+ u32 sector_base_addr; -+ u32 sector_end_addr; -+ u16 i; -+ -+ /* Can't read flash registers if the register set isn't mapped. -+ */ -+ if (!hw->flash_address) { -+ hw_dbg(hw, "ERROR: Flash registers not mapped\n"); -+ return -E1000_ERR_CONFIG; -+ } -+ -+ nvm->type = e1000_nvm_flash_sw; -+ -+ gfpreg = er32flash(ICH_FLASH_GFPREG); -+ -+ /* sector_X_addr is a "sector"-aligned address (4096 bytes) -+ * Add 1 to sector_end_addr since this sector is included in -+ * the overall size. */ -+ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; -+ sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1; -+ -+ /* flash_base_addr is byte-aligned */ -+ nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT; ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 data; + -+ /* find total size of the NVM, then cut in half since the total -+ * size represents two separate NVM banks. */ -+ nvm->flash_bank_size = (sector_end_addr - sector_base_addr) -+ << FLASH_SECTOR_ADDR_SHIFT; -+ nvm->flash_bank_size /= 2; -+ /* Adjust to word count */ -+ nvm->flash_bank_size /= sizeof(u16); ++ DEBUGFUNC("e1000_check_polarity_m88"); + -+ nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS; ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data); + -+ /* Clear shadow ram */ -+ for (i = 0; i < nvm->word_size; i++) { -+ dev_spec->shadow_ram[i].modified = 0; -+ dev_spec->shadow_ram[i].value = 0xFFFF; -+ } ++ if (!ret_val) ++ phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) ++ ? e1000_rev_polarity_reversed ++ : e1000_rev_polarity_normal; + -+ return 0; ++ return ret_val; +} + +/** -+ * e1000_init_mac_params_ich8lan - Initialize MAC function pointers ++ * e1000_check_polarity_igp - Checks the polarity. + * @hw: pointer to the HW structure + * -+ * Initialize family-specific MAC parameters and function -+ * pointers. ++ * Success returns 0, Failure returns -E1000_ERR_PHY (-2) ++ * ++ * Polarity is determined based on the PHY port status register, and the ++ * current speed (since there is no polarity at 100Mbps). + **/ -+static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) ++s32 e1000_check_polarity_igp(struct e1000_hw *hw) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_mac_info *mac = &hw->mac; -+ -+ /* Set media type function pointer */ -+ hw->media_type = e1000_media_type_copper; -+ -+ /* Set mta register count */ -+ mac->mta_reg_count = 32; -+ /* Set rar entry count */ -+ mac->rar_entry_count = E1000_ICH_RAR_ENTRIES; -+ if (mac->type == e1000_ich8lan) -+ mac->rar_entry_count--; -+ /* Set if manageability features are enabled. */ -+ mac->arc_subsystem_valid = 1; -+ -+ /* Enable PCS Lock-loss workaround for ICH8 */ -+ if (mac->type == e1000_ich8lan) -+ e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1); -+ -+ return 0; -+} ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 data, offset, mask; + -+static s32 e1000_get_invariants_ich8lan(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ s32 rc; ++ DEBUGFUNC("e1000_check_polarity_igp"); + -+ rc = e1000_init_mac_params_ich8lan(adapter); -+ if (rc) -+ return rc; ++ /* ++ * Polarity is determined based on the speed of ++ * our connection. ++ */ ++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); ++ if (ret_val) ++ goto out; + -+ rc = e1000_init_nvm_params_ich8lan(hw); -+ if (rc) -+ return rc; ++ if ((data & IGP01E1000_PSSR_SPEED_MASK) == ++ IGP01E1000_PSSR_SPEED_1000MBPS) { ++ offset = IGP01E1000_PHY_PCS_INIT_REG; ++ mask = IGP01E1000_PHY_POLARITY_MASK; ++ } else { ++ /* ++ * This really only applies to 10Mbps since ++ * there is no polarity for 100Mbps (always 0). ++ */ ++ offset = IGP01E1000_PHY_PORT_STATUS; ++ mask = IGP01E1000_PSSR_POLARITY_REVERSED; ++ } + -+ rc = e1000_init_phy_params_ich8lan(hw); -+ if (rc) -+ return rc; ++ ret_val = phy->ops.read_reg(hw, offset, &data); + -+ if ((adapter->hw.mac.type == e1000_ich8lan) && -+ (adapter->hw.phy.type == e1000_phy_igp_3)) -+ adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; ++ if (!ret_val) ++ phy->cable_polarity = (data & mask) ++ ? e1000_rev_polarity_reversed ++ : e1000_rev_polarity_normal; + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_acquire_swflag_ich8lan - Acquire software control flag ++ * e1000_wait_autoneg_generic - Wait for auto-neg completion + * @hw: pointer to the HW structure + * -+ * Acquires the software control flag for performing NVM and PHY -+ * operations. This is a function pointer entry point only called by -+ * read/write routines for the PHY and NVM parts. ++ * Waits for auto-negotiation to complete or for the auto-negotiation time ++ * limit to expire, which ever happens first. + **/ -+static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) ++s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) +{ -+ u32 extcnf_ctrl; -+ u32 timeout = PHY_CFG_TIMEOUT; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i, phy_status; + -+ while (timeout) { -+ extcnf_ctrl = er32(EXTCNF_CTRL); -+ extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; -+ ew32(EXTCNF_CTRL, extcnf_ctrl); ++ DEBUGFUNC("e1000_wait_autoneg_generic"); + -+ extcnf_ctrl = er32(EXTCNF_CTRL); -+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) -+ break; -+ mdelay(1); -+ timeout--; -+ } ++ if (!(hw->phy.ops.read_reg)) ++ return E1000_SUCCESS; + -+ if (!timeout) { -+ hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); -+ return -E1000_ERR_CONFIG; ++ /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */ ++ for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) { ++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); ++ if (ret_val) ++ break; ++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); ++ if (ret_val) ++ break; ++ if (phy_status & MII_SR_AUTONEG_COMPLETE) ++ break; ++ msec_delay(100); + } + -+ return 0; ++ /* ++ * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation ++ * has completed. ++ */ ++ return ret_val; +} + +/** -+ * e1000_release_swflag_ich8lan - Release software control flag ++ * e1000_phy_has_link_generic - Polls PHY for link + * @hw: pointer to the HW structure ++ * @iterations: number of times to poll for link ++ * @usec_interval: delay between polling attempts ++ * @success: pointer to whether polling was successful or not + * -+ * Releases the software control flag for performing NVM and PHY operations. -+ * This is a function pointer entry point only called by read/write -+ * routines for the PHY and NVM parts. ++ * Polls the PHY status register for link, 'iterations' number of times. + **/ -+static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) ++s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, ++ u32 usec_interval, bool *success) +{ -+ u32 extcnf_ctrl; ++ s32 ret_val = E1000_SUCCESS; ++ u16 i, phy_status; + -+ extcnf_ctrl = er32(EXTCNF_CTRL); -+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; -+ ew32(EXTCNF_CTRL, extcnf_ctrl); ++ DEBUGFUNC("e1000_phy_has_link_generic"); ++ ++ if (!(hw->phy.ops.read_reg)) ++ return E1000_SUCCESS; ++ ++ for (i = 0; i < iterations; i++) { ++ /* ++ * Some PHYs require the PHY_STATUS register to be read ++ * twice due to the link bit being sticky. No harm doing ++ * it across the board. ++ */ ++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); ++ if (ret_val) ++ break; ++ ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); ++ if (ret_val) ++ break; ++ if (phy_status & MII_SR_LINK_STATUS) ++ break; ++ if (usec_interval >= 1000) ++ msec_delay_irq(usec_interval/1000); ++ else ++ usec_delay(usec_interval); ++ } ++ ++ *success = (i < iterations) ? true : false; ++ ++ return ret_val; +} + +/** -+ * e1000_check_reset_block_ich8lan - Check if PHY reset is blocked ++ * e1000_get_cable_length_m88 - Determine cable length for m88 PHY + * @hw: pointer to the HW structure + * -+ * Checks if firmware is blocking the reset of the PHY. -+ * This is a function pointer entry point only called by -+ * reset routines. ++ * Reads the PHY specific status register to retrieve the cable length ++ * information. The cable length is determined by averaging the minimum and ++ * maximum values to get the "average" cable length. The m88 PHY has four ++ * possible cable length values, which are: ++ * Register Value Cable Length ++ * 0 < 50 meters ++ * 1 50 - 80 meters ++ * 2 80 - 110 meters ++ * 3 110 - 140 meters ++ * 4 > 140 meters + **/ -+static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) ++s32 e1000_get_cable_length_m88(struct e1000_hw *hw) +{ -+ u32 fwsm; ++ struct e1000_phy_info *phy = &hw->phy; ++ s32 ret_val; ++ u16 phy_data, index; ++ ++ DEBUGFUNC("e1000_get_cable_length_m88"); ++ ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); ++ if (ret_val) ++ goto out; ++ ++ index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> ++ M88E1000_PSSR_CABLE_LENGTH_SHIFT; ++ phy->min_cable_length = e1000_m88_cable_length_table[index]; ++ phy->max_cable_length = e1000_m88_cable_length_table[index+1]; + -+ fwsm = er32(FWSM); ++ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; + -+ return (fwsm & E1000_ICH_FWSM_RSPCIPHY) ? 0 : E1000_BLK_PHY_RESET; ++out: ++ return ret_val; +} + +/** -+ * e1000_phy_force_speed_duplex_ich8lan - Force PHY speed & duplex ++ * e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY + * @hw: pointer to the HW structure + * -+ * Forces the speed and duplex settings of the PHY. -+ * This is a function pointer entry point only called by -+ * PHY setup routines. ++ * The automatic gain control (agc) normalizes the amplitude of the ++ * received signal, adjusting for the attenuation produced by the ++ * cable. By reading the AGC registers, which represent the ++ * combination of coarse and fine gain value, the value can be put ++ * into a lookup table to obtain the approximate cable length ++ * for each channel. + **/ -+static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) ++s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; -+ bool link; -+ -+ if (phy->type != e1000_phy_ife) { -+ ret_val = e1000e_phy_force_speed_duplex_igp(hw); -+ return ret_val; -+ } -+ -+ ret_val = e1e_rphy(hw, PHY_CONTROL, &data); -+ if (ret_val) -+ return ret_val; -+ -+ e1000e_phy_force_speed_duplex_setup(hw, &data); -+ -+ ret_val = e1e_wphy(hw, PHY_CONTROL, data); -+ if (ret_val) -+ return ret_val; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_data, i, agc_value = 0; ++ u16 cur_agc_index, max_agc_index = 0; ++ u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; ++ u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = ++ {IGP02E1000_PHY_AGC_A, ++ IGP02E1000_PHY_AGC_B, ++ IGP02E1000_PHY_AGC_C, ++ IGP02E1000_PHY_AGC_D}; + -+ /* Disable MDI-X support for 10/100 */ -+ ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data); -+ if (ret_val) -+ return ret_val; ++ DEBUGFUNC("e1000_get_cable_length_igp_2"); + -+ data &= ~IFE_PMC_AUTO_MDIX; -+ data &= ~IFE_PMC_FORCE_MDIX; ++ /* Read the AGC registers for all channels */ ++ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { ++ ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data); ++ if (ret_val) ++ goto out; + -+ ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, data); -+ if (ret_val) -+ return ret_val; ++ /* ++ * Getting bits 15:9, which represent the combination of ++ * coarse 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; + -+ hw_dbg(hw, "IFE PMC: %X\n", data); ++ /* Array index bound check. */ ++ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) || ++ (cur_agc_index == 0)) { ++ ret_val = -E1000_ERR_PHY; ++ goto out; ++ } + -+ udelay(1); ++ /* 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; + -+ if (phy->wait_for_link) { -+ hw_dbg(hw, "Waiting for forced speed/duplex link on IFE phy.\n"); ++ agc_value += e1000_igp_2_cable_length_table[cur_agc_index]; ++ } + -+ ret_val = e1000e_phy_has_link_generic(hw, -+ PHY_FORCE_LIMIT, -+ 100000, -+ &link); -+ if (ret_val) -+ return ret_val; ++ 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); + -+ if (!link) -+ hw_dbg(hw, "Link taking longer than expected.\n"); ++ /* Calculate cable length with the error range of +/- 10 meters. */ ++ phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? ++ (agc_value - IGP02E1000_AGC_RANGE) : 0; ++ phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE; + -+ /* Try once more */ -+ ret_val = e1000e_phy_has_link_generic(hw, -+ PHY_FORCE_LIMIT, -+ 100000, -+ &link); -+ if (ret_val) -+ return ret_val; -+ } ++ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_phy_hw_reset_ich8lan - Performs a PHY reset ++ * e1000_get_phy_info_m88 - Retrieve PHY information + * @hw: pointer to the HW structure + * -+ * Resets the PHY -+ * This is a function pointer entry point called by drivers -+ * or other shared routines. ++ * Valid for only copper links. Read the PHY status register (sticky read) ++ * to verify that link is up. Read the PHY special control register to ++ * determine the polarity and 10base-T extended distance. Read the PHY ++ * special status register to determine MDI/MDIx and current speed. If ++ * speed is 1000, then determine cable length, local and remote receiver. + **/ -+static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) ++s32 e1000_get_phy_info_m88(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; -+ u32 i; -+ u32 data, cnf_size, cnf_base_addr, sw_cfg_mask; -+ s32 ret_val; -+ u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT; -+ u16 word_addr, reg_data, reg_addr, phy_page = 0; -+ -+ ret_val = e1000e_phy_hw_reset_generic(hw); -+ if (ret_val) -+ return ret_val; -+ -+ /* Initialize the PHY from the NVM on ICH 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. -+ */ -+ if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) { -+ struct e1000_adapter *adapter = hw->adapter; -+ -+ /* Check if SW needs configure the PHY */ -+ if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) || -+ (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M)) -+ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M; -+ else -+ sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG; -+ -+ data = er32(FEXTNVM); -+ if (!(data & sw_cfg_mask)) -+ return 0; ++ s32 ret_val; ++ u16 phy_data; ++ bool link; + -+ /* Wait for basic configuration completes before proceeding*/ -+ do { -+ data = er32(STATUS); -+ data &= E1000_STATUS_LAN_INIT_DONE; -+ udelay(100); -+ } while ((!data) && --loop); ++ DEBUGFUNC("e1000_get_phy_info_m88"); + -+ /* If basic configuration is incomplete before the above loop -+ * count reaches 0, loading the configuration from NVM will -+ * leave the PHY in a bad state possibly resulting in no link. -+ */ -+ if (loop == 0) { -+ hw_dbg(hw, "LAN_INIT_DONE not set, increase timeout\n"); -+ } ++ if (hw->phy.media_type != e1000_media_type_copper) { ++ DEBUGOUT("Phy info is only valid for copper media\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } + -+ /* Clear the Init Done bit for the next init event */ -+ data = er32(STATUS); -+ data &= ~E1000_STATUS_LAN_INIT_DONE; -+ ew32(STATUS, data); ++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); ++ if (ret_val) ++ goto out; + -+ /* Make sure HW does not configure LCD from PHY -+ * extended configuration before SW configuration */ -+ data = er32(EXTCNF_CTRL); -+ if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE) -+ return 0; ++ if (!link) { ++ DEBUGOUT("Phy info is only valid if link is up\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; ++ } + -+ cnf_size = er32(EXTCNF_SIZE); -+ cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK; -+ cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT; -+ if (!cnf_size) -+ return 0; ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ++ if (ret_val) ++ goto out; + -+ cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK; -+ cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT; ++ phy->polarity_correction = (phy_data & M88E1000_PSCR_POLARITY_REVERSAL) ++ ? true ++ : false; + -+ /* Configure LCD from extended configuration -+ * region. */ ++ ret_val = e1000_check_polarity_m88(hw); ++ if (ret_val) ++ goto out; + -+ /* cnf_base_addr is in DWORD */ -+ word_addr = (u16)(cnf_base_addr << 1); ++ ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); ++ if (ret_val) ++ goto out; + -+ for (i = 0; i < cnf_size; i++) { -+ ret_val = e1000_read_nvm(hw, -+ (word_addr + i * 2), -+ 1, -+ ®_data); -+ if (ret_val) -+ return ret_val; ++ phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX) ? true : false; + -+ ret_val = e1000_read_nvm(hw, -+ (word_addr + i * 2 + 1), -+ 1, -+ ®_addr); -+ if (ret_val) -+ return ret_val; ++ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) { ++ ret_val = hw->phy.ops.get_cable_length(hw); ++ if (ret_val) ++ goto out; + -+ /* Save off the PHY page for future writes. */ -+ if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) { -+ phy_page = reg_data; -+ continue; -+ } ++ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); ++ if (ret_val) ++ goto out; + -+ reg_addr |= phy_page; ++ phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) ++ ? e1000_1000t_rx_status_ok ++ : e1000_1000t_rx_status_not_ok; + -+ ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data); -+ if (ret_val) -+ return ret_val; -+ } ++ phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) ++ ? e1000_1000t_rx_status_ok ++ : e1000_1000t_rx_status_not_ok; ++ } else { ++ /* Set values to "undefined" */ ++ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; ++ phy->local_rx = e1000_1000t_rx_status_undefined; ++ phy->remote_rx = e1000_1000t_rx_status_undefined; + } + -+ return 0; ++out: ++ return ret_val; +} + +/** -+ * e1000_get_phy_info_ife_ich8lan - Retrieves various IFE PHY states ++ * e1000_get_phy_info_igp - Retrieve igp PHY information + * @hw: pointer to the HW structure + * -+ * Populates "phy" structure with various feature states. -+ * This function is only called by other family-specific -+ * routines. ++ * Read PHY status to determine if link is up. If link is up, then ++ * set/determine 10base-T extended distance and polarity correction. Read ++ * PHY port status to determine MDI/MDIx and speed. Based on the speed, ++ * determine on the cable length, local and remote receiver. + **/ -+static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) ++s32 e1000_get_phy_info_igp(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + s32 ret_val; + u16 data; + bool link; + -+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); ++ DEBUGFUNC("e1000_get_phy_info_igp"); ++ ++ ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) -+ return ret_val; ++ goto out; + + if (!link) { -+ hw_dbg(hw, "Phy info is only valid if link is up\n"); -+ return -E1000_ERR_CONFIG; ++ DEBUGOUT("Phy info is only valid if link is up\n"); ++ ret_val = -E1000_ERR_CONFIG; ++ goto out; + } + -+ ret_val = e1e_rphy(hw, IFE_PHY_SPECIAL_CONTROL, &data); -+ if (ret_val) -+ return ret_val; -+ phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE)); ++ phy->polarity_correction = true; + -+ if (phy->polarity_correction) { -+ ret_val = e1000_check_polarity_ife_ich8lan(hw); -+ if (ret_val) -+ return ret_val; -+ } else { -+ /* Polarity is forced */ -+ phy->cable_polarity = (data & IFE_PSC_FORCE_POLARITY) -+ ? e1000_rev_polarity_reversed -+ : e1000_rev_polarity_normal; -+ } ++ ret_val = e1000_check_polarity_igp(hw); ++ if (ret_val) ++ goto out; + -+ ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &data); ++ ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); + if (ret_val) -+ return ret_val; ++ goto out; + -+ phy->is_mdix = (data & IFE_PMC_MDIX_STATUS); ++ phy->is_mdix = (data & IGP01E1000_PSSR_MDIX) ? true : false; + -+ /* The following parameters are undefined for 10/100 operation. */ -+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; -+ phy->local_rx = e1000_1000t_rx_status_undefined; -+ phy->remote_rx = e1000_1000t_rx_status_undefined; ++ if ((data & IGP01E1000_PSSR_SPEED_MASK) == ++ IGP01E1000_PSSR_SPEED_1000MBPS) { ++ ret_val = hw->phy.ops.get_cable_length(hw); ++ if (ret_val) ++ goto out; + -+ return 0; -+} ++ ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); ++ if (ret_val) ++ goto out; + -+/** -+ * e1000_get_phy_info_ich8lan - Calls appropriate PHY type get_phy_info -+ * @hw: pointer to the HW structure -+ * -+ * Wrapper for calling the get_phy_info routines for the appropriate phy type. -+ * This is a function pointer entry point called by drivers -+ * or other shared routines. -+ **/ -+static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) -+{ -+ switch (hw->phy.type) { -+ case e1000_phy_ife: -+ return e1000_get_phy_info_ife_ich8lan(hw); -+ break; -+ case e1000_phy_igp_3: -+ return e1000e_get_phy_info_igp(hw); -+ break; -+ default: -+ break; ++ phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) ++ ? e1000_1000t_rx_status_ok ++ : e1000_1000t_rx_status_not_ok; ++ ++ phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) ++ ? e1000_1000t_rx_status_ok ++ : e1000_1000t_rx_status_not_ok; ++ } else { ++ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; ++ phy->local_rx = e1000_1000t_rx_status_undefined; ++ phy->remote_rx = e1000_1000t_rx_status_undefined; + } + -+ return -E1000_ERR_PHY_TYPE; ++out: ++ return ret_val; +} + +/** -+ * e1000_check_polarity_ife_ich8lan - Check cable polarity for IFE PHY ++ * e1000_phy_sw_reset_generic - PHY software reset + * @hw: pointer to the HW structure + * -+ * Polarity is determined on the polarity reveral feature being enabled. -+ * This function is only called by other family-specific -+ * routines. ++ * Does a software reset of the PHY by reading the PHY control register and ++ * setting/write the control register reset bit to the PHY. + **/ -+static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) ++s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data, offset, mask; ++ s32 ret_val = E1000_SUCCESS; ++ u16 phy_ctrl; + -+ /* Polarity is determined based on the reversal feature -+ * being enabled. -+ */ -+ if (phy->polarity_correction) { -+ offset = IFE_PHY_EXTENDED_STATUS_CONTROL; -+ mask = IFE_PESC_POLARITY_REVERSED; -+ } else { -+ offset = IFE_PHY_SPECIAL_CONTROL; -+ mask = IFE_PSC_FORCE_POLARITY; -+ } ++ DEBUGFUNC("e1000_phy_sw_reset_generic"); ++ ++ if (!(hw->phy.ops.read_reg)) ++ goto out; + -+ ret_val = e1e_rphy(hw, offset, &phy_data); ++ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); ++ if (ret_val) ++ goto out; + -+ if (!ret_val) -+ phy->cable_polarity = (phy_data & mask) -+ ? e1000_rev_polarity_reversed -+ : e1000_rev_polarity_normal; ++ phy_ctrl |= MII_CR_RESET; ++ ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl); ++ if (ret_val) ++ goto out; ++ ++ usec_delay(1); + ++out: + return ret_val; +} + +/** -+ * e1000_set_d0_lplu_state_ich8lan - Set Low Power Linkup D0 state ++ * e1000_phy_hw_reset_generic - PHY hardware reset + * @hw: pointer to the HW structure -+ * @active: TRUE to enable LPLU, FALSE to disable + * -+ * Sets the LPLU D0 state according to the active flag. When -+ * activating LPLU this function also disables smart speed -+ * and vice versa. LPLU will not be activated unless the -+ * device autonegotiation advertisement meets standards of -+ * either 10 or 10/100 or 10/100/1000 at all duplexes. -+ * This is a function pointer entry point only called by -+ * PHY setup routines. ++ * Verify the reset block is not blocking us from resetting. Acquire ++ * semaphore (if necessary) and read/set/write the device control reset ++ * bit in the PHY. Wait the appropriate delay time for the device to ++ * reset and release the semaphore (if necessary). + **/ -+static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) ++s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; -+ u32 phy_ctrl; -+ s32 ret_val = 0; -+ u16 data; ++ s32 ret_val = E1000_SUCCESS; ++ u32 ctrl; + -+ if (phy->type != e1000_phy_igp_3) -+ return ret_val; ++ DEBUGFUNC("e1000_phy_hw_reset_generic"); + -+ phy_ctrl = er32(PHY_CTRL); ++ ret_val = phy->ops.check_reset_block(hw); ++ if (ret_val) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } + -+ if (active) { -+ phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU; -+ ew32(PHY_CTRL, phy_ctrl); ++ ret_val = phy->ops.acquire(hw); ++ if (ret_val) ++ goto out; + -+ /* Call gig speed drop workaround on LPLU before accessing -+ * any PHY registers */ -+ if ((hw->mac.type == e1000_ich8lan) && -+ (hw->phy.type == e1000_phy_igp_3)) -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++ ctrl = E1000_READ_REG(hw, E1000_CTRL); ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_PHY_RST); ++ E1000_WRITE_FLUSH(hw); + -+ /* When LPLU is enabled, we should disable SmartSpeed */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); -+ if (ret_val) -+ return ret_val; -+ } else { -+ phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU; -+ ew32(PHY_CTRL, phy_ctrl); ++ usec_delay(phy->reset_delay_us); + -+ /* 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 (phy->smart_speed == e1000_smart_speed_on) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ E1000_WRITE_REG(hw, E1000_CTRL, ctrl); ++ E1000_WRITE_FLUSH(hw); + -+ data |= IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } else if (phy->smart_speed == e1000_smart_speed_off) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ usec_delay(150); + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } -+ } ++ phy->ops.release(hw); + -+ return 0; ++ ret_val = phy->ops.get_cfg_done(hw); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_set_d3_lplu_state_ich8lan - Set Low Power Linkup D3 state ++ * e1000_get_cfg_done_generic - Generic configuration done + * @hw: pointer to the HW structure -+ * @active: TRUE to enable LPLU, FALSE to disable + * -+ * Sets the LPLU D3 state according to the active flag. When -+ * activating LPLU this function also disables smart speed -+ * and vice versa. LPLU will not be activated unless the -+ * device autonegotiation advertisement meets standards of -+ * either 10 or 10/100 or 10/100/1000 at all duplexes. -+ * This is a function pointer entry point only called by -+ * PHY setup routines. ++ * Generic function to wait 10 milli-seconds for configuration to complete ++ * and return success. + **/ -+static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) ++s32 e1000_get_cfg_done_generic(struct e1000_hw *hw) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ u32 phy_ctrl; -+ s32 ret_val; -+ u16 data; ++ DEBUGFUNC("e1000_get_cfg_done_generic"); + -+ phy_ctrl = er32(PHY_CTRL); -+ -+ if (!active) { -+ phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU; -+ ew32(PHY_CTRL, phy_ctrl); -+ /* 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 (phy->smart_speed == e1000_smart_speed_on) { -+ ret_val = e1e_rphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ msec_delay_irq(10); + -+ data |= IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } else if (phy->smart_speed == e1000_smart_speed_off) { -+ ret_val = e1e_rphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ return E1000_SUCCESS; ++} + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } -+ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || -+ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || -+ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { -+ phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU; -+ ew32(PHY_CTRL, phy_ctrl); ++/** ++ * e1000_phy_init_script_igp3 - Inits the IGP3 PHY ++ * @hw: pointer to the HW structure ++ * ++ * Initializes a Intel Gigabit PHY3 when an EEPROM is not present. ++ **/ ++s32 e1000_phy_init_script_igp3(struct e1000_hw *hw) ++{ ++ DEBUGOUT("Running IGP 3 PHY init script\n"); ++ ++ /* PHY init IGP 3 */ ++ /* Enable rise/fall, 10-mode work in class-A */ ++ hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018); ++ /* Remove all caps from Replica path filter */ ++ hw->phy.ops.write_reg(hw, 0x2F52, 0x0000); ++ /* Bias trimming for ADC, AFE and Driver (Default) */ ++ hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24); ++ /* Increase Hybrid poly bias */ ++ hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0); ++ /* Add 4% to Tx amplitude in Gig mode */ ++ hw->phy.ops.write_reg(hw, 0x2010, 0x10B0); ++ /* Disable trimming (TTT) */ ++ hw->phy.ops.write_reg(hw, 0x2011, 0x0000); ++ /* Poly DC correction to 94.6% + 2% for all channels */ ++ hw->phy.ops.write_reg(hw, 0x20DD, 0x249A); ++ /* ABS DC correction to 95.9% */ ++ hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3); ++ /* BG temp curve trim */ ++ hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE); ++ /* Increasing ADC OPAMP stage 1 currents to max */ ++ hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4); ++ /* Force 1000 ( required for enabling PHY regs configuration) */ ++ hw->phy.ops.write_reg(hw, 0x0000, 0x0140); ++ /* Set upd_freq to 6 */ ++ hw->phy.ops.write_reg(hw, 0x1F30, 0x1606); ++ /* Disable NPDFE */ ++ hw->phy.ops.write_reg(hw, 0x1F31, 0xB814); ++ /* Disable adaptive fixed FFE (Default) */ ++ hw->phy.ops.write_reg(hw, 0x1F35, 0x002A); ++ /* Enable FFE hysteresis */ ++ hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067); ++ /* Fixed FFE for short cable lengths */ ++ hw->phy.ops.write_reg(hw, 0x1F54, 0x0065); ++ /* Fixed FFE for medium cable lengths */ ++ hw->phy.ops.write_reg(hw, 0x1F55, 0x002A); ++ /* Fixed FFE for long cable lengths */ ++ hw->phy.ops.write_reg(hw, 0x1F56, 0x002A); ++ /* Enable Adaptive Clip Threshold */ ++ hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0); ++ /* AHT reset limit to 1 */ ++ hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF); ++ /* Set AHT master delay to 127 msec */ ++ hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC); ++ /* Set scan bits for AHT */ ++ hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF); ++ /* Set AHT Preset bits */ ++ hw->phy.ops.write_reg(hw, 0x1F79, 0x0210); ++ /* Change integ_factor of channel A to 3 */ ++ hw->phy.ops.write_reg(hw, 0x1895, 0x0003); ++ /* Change prop_factor of channels BCD to 8 */ ++ hw->phy.ops.write_reg(hw, 0x1796, 0x0008); ++ /* Change cg_icount + enable integbp for channels BCD */ ++ hw->phy.ops.write_reg(hw, 0x1798, 0xD008); ++ /* ++ * Change cg_icount + enable integbp + change prop_factor_master ++ * to 8 for channel A ++ */ ++ hw->phy.ops.write_reg(hw, 0x1898, 0xD918); ++ /* Disable AHT in Slave mode on channel A */ ++ hw->phy.ops.write_reg(hw, 0x187A, 0x0800); ++ /* ++ * Enable LPLU and disable AN to 1000 in non-D0a states, ++ * Enable SPD+B2B ++ */ ++ hw->phy.ops.write_reg(hw, 0x0019, 0x008D); ++ /* Enable restart AN on an1000_dis change */ ++ hw->phy.ops.write_reg(hw, 0x001B, 0x2080); ++ /* Enable wh_fifo read clock in 10/100 modes */ ++ hw->phy.ops.write_reg(hw, 0x0014, 0x0045); ++ /* Restart AN, Speed selection is 1000 */ ++ hw->phy.ops.write_reg(hw, 0x0000, 0x1340); + -+ /* Call gig speed drop workaround on LPLU before accessing -+ * any PHY registers */ -+ if ((hw->mac.type == e1000_ich8lan) && -+ (hw->phy.type == e1000_phy_igp_3)) -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++ return E1000_SUCCESS; ++} + -+ /* When LPLU is enabled, we should disable SmartSpeed */ -+ ret_val = e1e_rphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++/** ++ * e1000_get_phy_type_from_id - Get PHY type from id ++ * @phy_id: phy_id read from the phy ++ * ++ * Returns the phy type from the id. ++ **/ ++e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id) ++{ ++ e1000_phy_type phy_type = e1000_phy_unknown; + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, -+ IGP01E1000_PHY_PORT_CONFIG, -+ data); ++ switch (phy_id) { ++ case M88E1000_I_PHY_ID: ++ case M88E1000_E_PHY_ID: ++ case M88E1111_I_PHY_ID: ++ case M88E1011_I_PHY_ID: ++ phy_type = e1000_phy_m88; ++ break; ++ case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */ ++ phy_type = e1000_phy_igp_2; ++ break; ++ case GG82563_E_PHY_ID: ++ phy_type = e1000_phy_gg82563; ++ break; ++ case IGP03E1000_E_PHY_ID: ++ phy_type = e1000_phy_igp_3; ++ break; ++ case IFE_E_PHY_ID: ++ case IFE_PLUS_E_PHY_ID: ++ case IFE_C_E_PHY_ID: ++ phy_type = e1000_phy_ife; ++ break; ++ case BME1000_E_PHY_ID: ++ case BME1000_E_PHY_ID_R2: ++ phy_type = e1000_phy_bm; ++ break; ++ default: ++ phy_type = e1000_phy_unknown; ++ break; + } -+ -+ return 0; ++ return phy_type; +} + +/** -+ * e1000_read_nvm_ich8lan - Read word(s) from the NVM ++ * e1000_determine_phy_address - Determines PHY address. + * @hw: pointer to the HW structure -+ * @offset: The offset (in bytes) of the word(s) to read. -+ * @words: Size of data to read in words -+ * @data: Pointer to the word(s) to read at offset. + * -+ * Reads a word(s) from the NVM using the flash access registers. ++ * This uses a trial and error method to loop through possible PHY ++ * addresses. It tests each by reading the PHY ID registers and ++ * checking for a match. + **/ -+static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, -+ u16 *data) ++s32 e1000_determine_phy_address(struct e1000_hw* hw) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -+ u32 act_offset; -+ s32 ret_val; -+ u16 i, word; ++ s32 ret_val = -E1000_ERR_PHY_TYPE; ++ u32 phy_addr= 0; ++ u32 i; ++ e1000_phy_type phy_type = e1000_phy_unknown; + -+ if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; -+ } ++ for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) { ++ hw->phy.addr = phy_addr; ++ i = 0; + -+ ret_val = e1000_acquire_swflag_ich8lan(hw); -+ if (ret_val) -+ return ret_val; ++ do { ++ e1000_get_phy_id(hw); ++ phy_type = e1000_get_phy_type_from_id(hw->phy.id); ++ ++ /* ++ * If phy_type is valid, break - we found our ++ * PHY address ++ */ ++ if (phy_type != e1000_phy_unknown) { ++ ret_val = E1000_SUCCESS; ++ goto out; ++ } ++ msec_delay(1); ++ i++; ++ } while (i < 10); ++ } + -+ /* Start with the bank offset, then add the relative offset. */ -+ act_offset = (er32(EECD) & E1000_EECD_SEC1VAL) -+ ? nvm->flash_bank_size -+ : 0; -+ act_offset += offset; ++out: ++ return ret_val; ++} + -+ for (i = 0; i < words; i++) { -+ if ((dev_spec->shadow_ram) && -+ (dev_spec->shadow_ram[offset+i].modified)) { -+ data[i] = dev_spec->shadow_ram[offset+i].value; -+ } else { -+ ret_val = e1000_read_flash_word_ich8lan(hw, -+ act_offset + i, -+ &word); -+ if (ret_val) -+ break; -+ data[i] = word; -+ } -+ } ++/** ++ * e1000_get_phy_addr_for_bm_page - Retrieve PHY page address ++ * @page: page to access ++ * ++ * Returns the phy address for the page requested. ++ **/ ++static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg) ++{ ++ u32 phy_addr = 2; + -+ e1000_release_swflag_ich8lan(hw); ++ if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31)) ++ phy_addr = 1; + -+ return ret_val; ++ return phy_addr; +} + +/** -+ * e1000_flash_cycle_init_ich8lan - Initialize flash ++ * e1000_write_phy_reg_bm - Write BM PHY register + * @hw: pointer to the HW structure ++ * @offset: register offset to write to ++ * @data: data to write at register offset + * -+ * This function does initial flash setup so that a new read/write/erase cycle -+ * can be started. ++ * Acquires semaphore, if necessary, then writes the data to PHY register ++ * at the offset. Release any acquired semaphores before exiting. + **/ -+static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) ++s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) +{ -+ union ich8_hws_flash_status hsfsts; -+ s32 ret_val = -E1000_ERR_NVM; -+ s32 i = 0; ++ s32 ret_val; ++ u32 page_select = 0; ++ u32 page = offset >> IGP_PAGE_SHIFT; ++ u32 page_shift = 0; + -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); ++ DEBUGFUNC("e1000_write_phy_reg_bm"); + -+ /* Check if the flash descriptor is valid */ -+ if (hsfsts.hsf_status.fldesvalid == 0) { -+ hw_dbg(hw, "Flash descriptor invalid. " -+ "SW Sequencing must be used."); -+ return -E1000_ERR_NVM; ++ /* Page 800 works differently than the rest so it has its own func */ ++ if (page == BM_WUC_PAGE) { ++ ret_val = e1000_access_phy_wakeup_reg_bm(hw, ++ offset, &data, false); ++ goto out; + } + -+ /* Clear FCERR and DAEL in hw status by writing 1 */ -+ hsfsts.hsf_status.flcerr = 1; -+ hsfsts.hsf_status.dael = 1; -+ -+ ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval); ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; + -+ /* 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. -+ */ ++ hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); + -+ 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; -+ ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval); -+ ret_val = 0; -+ } else { -+ /* otherwise poll for sometime so the current -+ * cycle has a chance to end before giving up. */ -+ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { -+ hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS); -+ if (hsfsts.hsf_status.flcinprog == 0) { -+ ret_val = 0; -+ break; -+ } -+ udelay(1); -+ } -+ if (ret_val == 0) { -+ /* Successful in waiting for previous cycle to timeout, -+ * now set the Flash Cycle Done. */ -+ hsfsts.hsf_status.flcdone = 1; -+ ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval); ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { ++ /* ++ * Page select is register 31 for phy address 1 and 22 for ++ * phy address 2 and 3. Page select is shifted only for ++ * phy address 1. ++ */ ++ if (hw->phy.addr == 1) { ++ page_shift = IGP_PAGE_SHIFT; ++ page_select = IGP01E1000_PHY_PAGE_SELECT; + } else { -+ hw_dbg(hw, "Flash controller busy, cannot get access"); ++ page_shift = 0; ++ page_select = BM_PHY_PAGE_SELECT; ++ } ++ ++ /* Page is shifted left, PHY expects (page x 32) */ ++ ret_val = e1000_write_phy_reg_mdic(hw, page_select, ++ (page << page_shift)); ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; + } + } + ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ ++ hw->phy.ops.release(hw); ++ ++out: + return ret_val; +} + +/** -+ * e1000_flash_cycle_ich8lan - Starts flash cycle (read/write/erase) ++ * e1000_read_phy_reg_bm - Read BM PHY register + * @hw: pointer to the HW structure -+ * @timeout: maximum time to wait for completion ++ * @offset: register offset to be read ++ * @data: pointer to the read data + * -+ * This function starts a flash cycle and waits for its completion. ++ * Acquires semaphore, if necessary, then reads the PHY register at offset ++ * and storing the retrieved information in data. Release any acquired ++ * semaphores before exiting. + **/ -+static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) ++s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) +{ -+ union ich8_hws_flash_ctrl hsflctl; -+ union ich8_hws_flash_status hsfsts; -+ s32 ret_val = -E1000_ERR_NVM; -+ u32 i = 0; ++ s32 ret_val; ++ u32 page_select = 0; ++ u32 page = offset >> IGP_PAGE_SHIFT; ++ u32 page_shift = 0; + -+ /* Start a cycle by writing 1 in Flash Cycle Go in Hw Flash Control */ -+ hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); -+ hsflctl.hsf_ctrl.flcgo = 1; -+ ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval); ++ DEBUGFUNC("e1000_read_phy_reg_bm"); + -+ /* wait till FDONE bit is set to 1 */ -+ do { -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); -+ if (hsfsts.hsf_status.flcdone == 1) -+ break; -+ udelay(1); -+ } while (i++ < timeout); ++ /* Page 800 works differently than the rest so it has its own func */ ++ if (page == BM_WUC_PAGE) { ++ ret_val = e1000_access_phy_wakeup_reg_bm(hw, ++ offset, data, true); ++ goto out; ++ } + -+ if (hsfsts.hsf_status.flcdone == 1 && hsfsts.hsf_status.flcerr == 0) -+ return 0; ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; + -+ return ret_val; -+} ++ hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset); ++ ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { ++ /* ++ * Page select is register 31 for phy address 1 and 22 for ++ * phy address 2 and 3. Page select is shifted only for ++ * phy address 1. ++ */ ++ if (hw->phy.addr == 1) { ++ page_shift = IGP_PAGE_SHIFT; ++ page_select = IGP01E1000_PHY_PAGE_SELECT; ++ } else { ++ page_shift = 0; ++ page_select = BM_PHY_PAGE_SELECT; ++ } ++ ++ /* Page is shifted left, PHY expects (page x 32) */ ++ ret_val = e1000_write_phy_reg_mdic(hw, page_select, ++ (page << page_shift)); ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; ++ } ++ } + -+/** -+ * e1000_read_flash_word_ich8lan - Read word from flash -+ * @hw: pointer to the HW structure -+ * @offset: offset to data location -+ * @data: pointer to the location for storing the data -+ * -+ * Reads the flash word at offset into data. Offset is converted -+ * to bytes before read. -+ **/ -+static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, -+ u16 *data) -+{ -+ /* Must convert offset into bytes. */ -+ offset <<= 1; ++ ret_val = e1000_read_phy_reg_mdic(hw, ++ MAX_PHY_REG_ADDRESS & offset, ++ data); ++ hw->phy.ops.release(hw); + -+ return e1000_read_flash_data_ich8lan(hw, offset, 2, data); ++out: ++ return ret_val; +} + +/** -+ * e1000_read_flash_data_ich8lan - Read byte or word from NVM ++ * e1000_read_phy_reg_bm2 - Read BM PHY register + * @hw: pointer to the HW structure -+ * @offset: The offset (in bytes) 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. ++ * @offset: register offset to be read ++ * @data: pointer to the read data + * -+ * Reads a byte or word from the NVM using the flash access registers. ++ * Acquires semaphore, if necessary, then reads the PHY register at offset ++ * and storing the retrieved information in data. Release any acquired ++ * semaphores before exiting. + **/ -+static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, -+ u8 size, u16 *data) ++s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) +{ -+ union ich8_hws_flash_status hsfsts; -+ union ich8_hws_flash_ctrl hsflctl; -+ u32 flash_linear_addr; -+ u32 flash_data = 0; -+ s32 ret_val = -E1000_ERR_NVM; -+ u8 count = 0; ++ s32 ret_val; ++ u16 page = (u16)(offset >> IGP_PAGE_SHIFT); + -+ if (size < 1 || size > 2 || offset > ICH_FLASH_LINEAR_ADDR_MASK) -+ return -E1000_ERR_NVM; ++ DEBUGFUNC("e1000_write_phy_reg_bm2"); + -+ flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + -+ hw->nvm.flash_base_addr; ++ /* Page 800 works differently than the rest so it has its own func */ ++ if (page == BM_WUC_PAGE) { ++ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, ++ true); ++ goto out; ++ } + -+ do { -+ udelay(1); -+ /* Steps */ -+ ret_val = e1000_flash_cycle_init_ich8lan(hw); -+ if (ret_val != 0) -+ break; ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) ++ goto out; + -+ hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); -+ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ -+ hsflctl.hsf_ctrl.fldbcount = size - 1; -+ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_READ; -+ ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval); ++ hw->phy.addr = 1; + -+ ew32flash(ICH_FLASH_FADDR, flash_linear_addr); ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { + -+ ret_val = e1000_flash_cycle_ich8lan(hw, -+ ICH_FLASH_READ_COMMAND_TIMEOUT); ++ /* Page is shifted left, PHY expects (page x 32) */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, ++ page); + -+ /* 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 (ret_val == 0) { -+ flash_data = er32flash(ICH_FLASH_FDATA0); -+ if (size == 1) { -+ *data = (u8)(flash_data & 0x000000FF); -+ } else if (size == 2) { -+ *data = (u16)(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... -+ * ICH_FLASH_CYCLE_REPEAT_COUNT times. -+ */ -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); -+ if (hsfsts.hsf_status.flcerr == 1) { -+ /* Repeat for some time before giving up. */ -+ continue; -+ } else if (hsfsts.hsf_status.flcdone == 0) { -+ hw_dbg(hw, "Timeout error - flash cycle " -+ "did not complete."); -+ break; -+ } ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; + } -+ } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); ++ } ++ ++ ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, ++ data); ++ hw->phy.ops.release(hw); + ++out: + return ret_val; +} + +/** -+ * e1000_write_nvm_ich8lan - Write word(s) to the NVM ++ * e1000_write_phy_reg_bm2 - Write BM PHY register + * @hw: pointer to the HW structure -+ * @offset: The offset (in bytes) of the word(s) to write. -+ * @words: Size of data to write in words -+ * @data: Pointer to the word(s) to write at offset. ++ * @offset: register offset to write to ++ * @data: data to write at register offset + * -+ * Writes a byte or word to the NVM using the flash access registers. ++ * Acquires semaphore, if necessary, then writes the data to PHY register ++ * at the offset. Release any acquired semaphores before exiting. + **/ -+static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, -+ u16 *data) ++s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; + s32 ret_val; -+ u16 i; ++ u16 page = (u16)(offset >> IGP_PAGE_SHIFT); + -+ if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; ++ DEBUGFUNC("e1000_write_phy_reg_bm2"); ++ ++ /* Page 800 works differently than the rest so it has its own func */ ++ if (page == BM_WUC_PAGE) { ++ ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, ++ false); ++ goto out; + } + -+ ret_val = e1000_acquire_swflag_ich8lan(hw); ++ ret_val = hw->phy.ops.acquire(hw); + if (ret_val) -+ return ret_val; ++ goto out; + -+ for (i = 0; i < words; i++) { -+ dev_spec->shadow_ram[offset+i].modified = 1; -+ dev_spec->shadow_ram[offset+i].value = data[i]; ++ hw->phy.addr = 1; ++ ++ if (offset > MAX_PHY_MULTI_PAGE_REG) { ++ /* Page is shifted left, PHY expects (page x 32) */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, ++ page); ++ ++ if (ret_val) { ++ hw->phy.ops.release(hw); ++ goto out; ++ } + } + -+ e1000_release_swflag_ich8lan(hw); ++ ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, ++ data); + -+ return 0; ++ hw->phy.ops.release(hw); ++ ++out: ++ return ret_val; +} + +/** -+ * e1000_update_nvm_checksum_ich8lan - Update the checksum for NVM ++ * e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register + * @hw: pointer to the HW structure ++ * @offset: register offset to be read or written ++ * @data: pointer to the data to read or write ++ * @read: determines if operation is read or write + * -+ * The NVM checksum is updated by calling the generic update_nvm_checksum, -+ * which writes the checksum to the shadow ram. The changes in the shadow -+ * ram are then committed to the EEPROM by processing each bank at a time -+ * checking for the modified bit and writing only the pending changes. -+ * After a succesful commit, the shadow ram is cleared and is ready for -+ * future writes. ++ * Acquires semaphore, if necessary, then reads the PHY register at offset ++ * and storing the retrieved information in data. Release any acquired ++ * semaphores before exiting. Note that procedure to read the wakeup ++ * registers are different. It works as such: ++ * 1) Set page 769, register 17, bit 2 = 1 ++ * 2) Set page to 800 for host (801 if we were manageability) ++ * 3) Write the address using the address opcode (0x11) ++ * 4) Read or write the data using the data opcode (0x12) ++ * 5) Restore 769_17.2 to its original value + **/ -+static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) ++s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, ++ u32 offset, u16 *data, bool read) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -+ u32 i, act_offset, new_bank_offset, old_bank_offset; + s32 ret_val; -+ u16 data; -+ -+ ret_val = e1000e_update_nvm_checksum_generic(hw); -+ if (ret_val) -+ return ret_val;; ++ u16 reg = ((u16)offset); ++ u16 phy_reg = 0; ++ u8 phy_acquired = 1; + -+ if (nvm->type != e1000_nvm_flash_sw) -+ return ret_val;; -+ -+ ret_val = e1000_acquire_swflag_ich8lan(hw); -+ if (ret_val) -+ return ret_val;; ++ DEBUGFUNC("e1000_read_phy_wakeup_reg_bm"); + -+ /* 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 (!(er32(EECD) & E1000_EECD_SEC1VAL)) { -+ new_bank_offset = nvm->flash_bank_size; -+ old_bank_offset = 0; -+ e1000_erase_flash_bank_ich8lan(hw, 1); -+ } else { -+ old_bank_offset = nvm->flash_bank_size; -+ new_bank_offset = 0; -+ e1000_erase_flash_bank_ich8lan(hw, 0); ++ ret_val = hw->phy.ops.acquire(hw); ++ if (ret_val) { ++ DEBUGOUT("Could not acquire PHY\n"); ++ phy_acquired = 0; ++ goto out; + } + -+ for (i = 0; i < E1000_ICH8_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 (dev_spec->shadow_ram[i].modified) { -+ data = dev_spec->shadow_ram[i].value; -+ } else { -+ e1000_read_flash_word_ich8lan(hw, -+ i + old_bank_offset, -+ &data); -+ } -+ -+ /* 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_ICH_NVM_SIG_WORD) -+ data |= E1000_ICH_NVM_SIG_MASK; -+ -+ /* Convert offset to bytes. */ -+ act_offset = (i + new_bank_offset) << 1; ++ /* All operations in this function are phy address 1 */ ++ hw->phy.addr = 1; + -+ udelay(100); -+ /* Write the bytes to the new bank. */ -+ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, -+ act_offset, -+ (u8)data); -+ if (ret_val) -+ break; ++ /* Set page 769 */ ++ e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, ++ (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); + -+ udelay(100); -+ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, -+ act_offset + 1, -+ (u8)(data >> 8)); -+ if (ret_val) -+ break; ++ ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg); ++ if (ret_val) { ++ DEBUGOUT("Could not read PHY page 769\n"); ++ goto out; + } + -+ /* Don't bother writing the segment valid bits if sector -+ * programming failed. */ ++ /* First clear bit 4 to avoid a power state change */ ++ phy_reg &= ~(BM_WUC_HOST_WU_BIT); ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); + if (ret_val) { -+ hw_dbg(hw, "Flash commit failed.\n"); -+ e1000_release_swflag_ich8lan(hw); -+ return ret_val; ++ DEBUGOUT("Could not clear PHY page 769 bit 4\n"); ++ goto out; + } + -+ /* 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 */ -+ act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD; -+ e1000_read_flash_word_ich8lan(hw, act_offset, &data); -+ data &= 0xBFFF; -+ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, -+ act_offset * 2 + 1, -+ (u8)(data >> 8)); ++ /* Write bit 2 = 1, and clear bit 4 to 769_17 */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, ++ phy_reg | BM_WUC_ENABLE_BIT); + if (ret_val) { -+ e1000_release_swflag_ich8lan(hw); -+ return ret_val; ++ DEBUGOUT("Could not write PHY page 769 bit 2\n"); ++ goto out; + } + -+ /* 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 */ -+ act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; -+ ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); ++ /* Select page 800 */ ++ ret_val = e1000_write_phy_reg_mdic(hw, ++ IGP01E1000_PHY_PAGE_SELECT, ++ (BM_WUC_PAGE << IGP_PAGE_SHIFT)); ++ ++ /* Write the page 800 offset value using opcode 0x11 */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg); + if (ret_val) { -+ e1000_release_swflag_ich8lan(hw); -+ return ret_val; ++ DEBUGOUT("Could not write address opcode to page 800\n"); ++ goto out; + } + -+ /* Great! Everything worked, we can now clear the cached entries. */ -+ for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) { -+ dev_spec->shadow_ram[i].modified = 0; -+ dev_spec->shadow_ram[i].value = 0xFFFF; ++ if (read) { ++ /* Read the page 800 value using opcode 0x12 */ ++ ret_val = e1000_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, ++ data); ++ } else { ++ /* Read the page 800 value using opcode 0x12 */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE, ++ *data); + } + -+ e1000_release_swflag_ich8lan(hw); ++ if (ret_val) { ++ DEBUGOUT("Could not read data value from page 800\n"); ++ goto out; ++ } + -+ /* Reload the EEPROM, or else modifications will not appear -+ * until after the next adapter reset. ++ /* ++ * Restore 769_17.2 to its original value ++ * Set page 769 + */ -+ e1000e_reload_nvm(hw); -+ msleep(10); ++ e1000_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, ++ (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT)); ++ ++ /* Clear 769_17.2 */ ++ ret_val = e1000_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg); ++ if (ret_val) { ++ DEBUGOUT("Could not clear PHY page 769 bit 2\n"); ++ goto out; ++ } + ++out: ++ if (phy_acquired == 1) ++ hw->phy.ops.release(hw); + return ret_val; +} + +/** -+ * e1000_validate_nvm_checksum_ich8lan - Validate EEPROM checksum -+ * @hw: pointer to the HW structure ++ * e1000_power_up_phy_copper - Restore copper link in case of PHY power down ++ * @hw: pointer to the HW structure + * -+ * Check to see if checksum needs to be fixed by reading bit 6 in word 0x19. -+ * If the bit is 0, that the EEPROM had been modified, but the checksum was not -+ * calculated, in which case we need to calculate the checksum and set bit 6. ++ * In the case of a PHY power down to save power, or to turn off link during a ++ * driver unload, or wake on lan is not enabled, restore the link to previous ++ * settings. + **/ -+static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) ++void e1000_power_up_phy_copper(struct e1000_hw *hw) +{ -+ s32 ret_val; -+ u16 data; ++ u16 mii_reg = 0; + -+ /* Read 0x19 and check bit 6. If this bit is 0, the checksum -+ * needs to be fixed. This bit is an indication that the NVM -+ * was prepared by OEM software and did not calculate the -+ * checksum...a likely scenario. -+ */ -+ ret_val = e1000_read_nvm(hw, 0x19, 1, &data); -+ if (ret_val) -+ return ret_val; ++ /* The PHY will retain its settings across a power down/up cycle */ ++ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); ++ mii_reg &= ~MII_CR_POWER_DOWN; ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); ++} ++ ++/** ++ * e1000_power_down_phy_copper - Restore copper link in case of PHY power down ++ * @hw: pointer to the HW structure ++ * ++ * In the case of a PHY power down to save power, or to turn off link during a ++ * driver unload, or wake on lan is not enabled, restore the link to previous ++ * settings. ++ **/ ++void e1000_power_down_phy_copper(struct e1000_hw *hw) ++{ ++ u16 mii_reg = 0; ++ ++ /* The PHY will retain its settings across a power down/up cycle */ ++ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); ++ mii_reg |= MII_CR_POWER_DOWN; ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); ++ msec_delay(1); ++} +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_phy.h linux-2.6.22-10/drivers/net/e1000e/e1000_phy.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_phy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_phy.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,190 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _E1000_PHY_H_ ++#define _E1000_PHY_H_ ++ ++typedef enum { ++ e1000_ms_hw_default = 0, ++ e1000_ms_force_master, ++ e1000_ms_force_slave, ++ e1000_ms_auto ++} e1000_ms_type; ++ ++typedef enum { ++ e1000_smart_speed_default = 0, ++ e1000_smart_speed_on, ++ e1000_smart_speed_off ++} e1000_smart_speed; ++ ++void e1000_init_phy_ops_generic(struct e1000_hw *hw); ++s32 e1000_check_downshift_generic(struct e1000_hw *hw); ++s32 e1000_check_polarity_m88(struct e1000_hw *hw); ++s32 e1000_check_polarity_igp(struct e1000_hw *hw); ++s32 e1000_check_reset_block_generic(struct e1000_hw *hw); ++s32 e1000_copper_link_autoneg(struct e1000_hw *hw); ++s32 e1000_copper_link_setup_igp(struct e1000_hw *hw); ++s32 e1000_copper_link_setup_m88(struct e1000_hw *hw); ++s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw); ++s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw); ++s32 e1000_get_cable_length_m88(struct e1000_hw *hw); ++s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw); ++s32 e1000_get_cfg_done_generic(struct e1000_hw *hw); ++s32 e1000_get_phy_id(struct e1000_hw *hw); ++s32 e1000_get_phy_info_igp(struct e1000_hw *hw); ++s32 e1000_get_phy_info_m88(struct e1000_hw *hw); ++s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw); ++void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl); ++s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw); ++s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw); ++s32 e1000_phy_setup_autoneg(struct e1000_hw *hw); ++s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active); ++s32 e1000_setup_copper_link_generic(struct e1000_hw *hw); ++s32 e1000_wait_autoneg_generic(struct e1000_hw *hw); ++s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data); ++s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data); ++s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data); ++s32 e1000_phy_reset_dsp(struct e1000_hw *hw); ++s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, ++ u32 usec_interval, bool *success); ++s32 e1000_phy_init_script_igp3(struct e1000_hw *hw); ++e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id); ++s32 e1000_determine_phy_address(struct e1000_hw* hw); ++s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); ++s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, ++ bool read); ++s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); ++void e1000_power_up_phy_copper(struct e1000_hw *hw); ++void e1000_power_down_phy_copper(struct e1000_hw *hw); ++s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); ++s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); ++ ++#define E1000_MAX_PHY_ADDR 4 ++ ++/* IGP01E1000 Specific Registers */ ++#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* Port Config */ ++#define IGP01E1000_PHY_PORT_STATUS 0x11 /* Status */ ++#define IGP01E1000_PHY_PORT_CTRL 0x12 /* Control */ ++#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health */ ++#define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO */ ++#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality */ ++#define IGP02E1000_PHY_POWER_MGMT 0x19 /* Power Management */ ++#define IGP01E1000_PHY_PAGE_SELECT 0x1F /* Page Select */ ++#define BM_PHY_PAGE_SELECT 22 /* Page Select for BM */ ++#define IGP_PAGE_SHIFT 5 ++#define PHY_REG_MASK 0x1F ++ ++#define BM_WUC_PAGE 800 ++#define BM_WUC_ADDRESS_OPCODE 0x11 ++#define BM_WUC_DATA_OPCODE 0x12 ++#define BM_WUC_ENABLE_PAGE 769 ++#define BM_WUC_ENABLE_REG 17 ++#define BM_WUC_ENABLE_BIT (1 << 2) ++#define BM_WUC_HOST_WU_BIT (1 << 4) ++ ++/* BM PHY Copper Specific Control 1 */ ++#define BM_CS_CTRL1 16 ++#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */ ++ ++/* BM PHY Copper Specific States */ ++#define BM_CS_STATUS 17 ++#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */ ++ ++#define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 ++#define IGP01E1000_PHY_POLARITY_MASK 0x0078 ++ ++#define IGP01E1000_PSCR_AUTO_MDIX 0x1000 ++#define IGP01E1000_PSCR_FORCE_MDI_MDIX 0x2000 /* 0=MDI, 1=MDIX */ ++ ++#define IGP01E1000_PSCFR_SMART_SPEED 0x0080 ++ ++/* Enable flexible speed on link-up */ ++#define IGP01E1000_GMII_FLEX_SPD 0x0010 ++#define IGP01E1000_GMII_SPD 0x0020 /* Enable SPD */ ++ ++#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ ++#define IGP02E1000_PM_D0_LPLU 0x0002 /* For D0a states */ ++#define IGP02E1000_PM_D3_LPLU 0x0004 /* For all other states */ ++ ++#define IGP01E1000_PLHR_SS_DOWNGRADE 0x8000 ++ ++#define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002 ++#define IGP01E1000_PSSR_MDIX 0x0008 ++#define IGP01E1000_PSSR_SPEED_MASK 0xC000 ++#define IGP01E1000_PSSR_SPEED_1000MBPS 0xC000 ++ ++#define IGP02E1000_PHY_CHANNEL_NUM 4 ++#define IGP02E1000_PHY_AGC_A 0x11B1 ++#define IGP02E1000_PHY_AGC_B 0x12B1 ++#define IGP02E1000_PHY_AGC_C 0x14B1 ++#define IGP02E1000_PHY_AGC_D 0x18B1 ++ ++#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Course - 15:13, Fine - 12:9 */ ++#define IGP02E1000_AGC_LENGTH_MASK 0x7F ++#define IGP02E1000_AGC_RANGE 15 ++ ++#define IGP03E1000_PHY_MISC_CTRL 0x1B ++#define IGP03E1000_PHY_MISC_DUPLEX_MANUAL_SET 0x1000 /* Manually Set Duplex */ ++ ++#define E1000_CABLE_LENGTH_UNDEFINED 0xFF ++ ++#define E1000_KMRNCTRLSTA_OFFSET 0x001F0000 ++#define E1000_KMRNCTRLSTA_OFFSET_SHIFT 16 ++#define E1000_KMRNCTRLSTA_REN 0x00200000 ++#define E1000_KMRNCTRLSTA_DIAG_OFFSET 0x3 /* Kumeran Diagnostic */ ++#define E1000_KMRNCTRLSTA_DIAG_NELPBK 0x1000 /* Nearend Loopback mode */ ++ ++#define IFE_PHY_EXTENDED_STATUS_CONTROL 0x10 ++#define IFE_PHY_SPECIAL_CONTROL 0x11 /* 100BaseTx PHY Special Control */ ++#define IFE_PHY_SPECIAL_CONTROL_LED 0x1B /* PHY Special and LED Control */ ++#define IFE_PHY_MDIX_CONTROL 0x1C /* MDI/MDI-X Control */ ++ ++/* IFE PHY Extended Status Control */ ++#define IFE_PESC_POLARITY_REVERSED 0x0100 ++ ++/* IFE PHY Special Control */ ++#define IFE_PSC_AUTO_POLARITY_DISABLE 0x0010 ++#define IFE_PSC_FORCE_POLARITY 0x0020 ++#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN 0x0100 ++ ++/* IFE PHY Special Control and LED Control */ ++#define IFE_PSCL_PROBE_MODE 0x0020 ++#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 */ ++ ++/* IFE PHY MDIX Control */ ++#define IFE_PMC_MDIX_STATUS 0x0020 /* 1=MDI-X, 0=MDI */ ++#define IFE_PMC_FORCE_MDIX 0x0040 /* 1=force MDI-X, 0=force MDI */ ++#define IFE_PMC_AUTO_MDIX 0x0080 /* 1=enable auto MDI/MDI-X, 0=disable */ ++ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/e1000_regs.h linux-2.6.22-10/drivers/net/e1000e/e1000_regs.h +--- linux-2.6.22-0/drivers/net/e1000e/e1000_regs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/e1000_regs.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,310 @@ ++/******************************************************************************* + -+ if ((data & 0x40) == 0) { -+ data |= 0x40; -+ ret_val = e1000_write_nvm(hw, 0x19, 1, &data); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_update_nvm_checksum(hw); -+ if (ret_val) -+ return ret_val; -+ } ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ return e1000e_validate_nvm_checksum_generic(hw); -+} ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+/** -+ * e1000_write_flash_data_ich8lan - Writes bytes to the NVM -+ * @hw: pointer to the HW structure -+ * @offset: The offset (in bytes) 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. -+ * -+ * Writes one/two bytes to the NVM using the flash access registers. -+ **/ -+static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, -+ u8 size, u16 data) -+{ -+ union ich8_hws_flash_status hsfsts; -+ union ich8_hws_flash_ctrl hsflctl; -+ u32 flash_linear_addr; -+ u32 flash_data = 0; -+ s32 ret_val; -+ u8 count = 0; ++ This program is distributed in the hope 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. + -+ if (size < 1 || size > 2 || data > size * 0xff || -+ offset > ICH_FLASH_LINEAR_ADDR_MASK) -+ return -E1000_ERR_NVM; ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ flash_linear_addr = (ICH_FLASH_LINEAR_ADDR_MASK & offset) + -+ hw->nvm.flash_base_addr; ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ do { -+ udelay(1); -+ /* Steps */ -+ ret_val = e1000_flash_cycle_init_ich8lan(hw); -+ if (ret_val) -+ break; ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); -+ /* 0b/1b corresponds to 1 or 2 byte size, respectively. */ -+ hsflctl.hsf_ctrl.fldbcount = size -1; -+ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_WRITE; -+ ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval); ++*******************************************************************************/ + -+ ew32flash(ICH_FLASH_FADDR, flash_linear_addr); ++#ifndef _E1000_REGS_H_ ++#define _E1000_REGS_H_ ++ ++#define E1000_CTRL 0x00000 /* Device Control - RW */ ++#define E1000_CTRL_DUP 0x00004 /* Device Control Duplicate (Shadow) - RW */ ++#define E1000_STATUS 0x00008 /* Device Status - RO */ ++#define E1000_EECD 0x00010 /* EEPROM/Flash Control - RW */ ++#define E1000_EERD 0x00014 /* EEPROM Read - RW */ ++#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_FCAL 0x00028 /* Flow Control Address Low - RW */ ++#define E1000_FCAH 0x0002C /* Flow Control Address High -RW */ ++#define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ ++#define E1000_FCT 0x00030 /* Flow Control Type - RW */ ++#define E1000_CONNSW 0x00034 /* Copper/Fiber switch control - RW */ ++#define E1000_VET 0x00038 /* VLAN Ether Type - RW */ ++#define E1000_ICR 0x000C0 /* Interrupt Cause Read - R/clr */ ++#define E1000_ITR 0x000C4 /* Interrupt Throttling Rate - RW */ ++#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_IVAR 0x000E4 /* Interrupt Vector Allocation Register - RW */ ++#define E1000_RCTL 0x00100 /* Rx Control - 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_EICR 0x01580 /* Ext. Interrupt Cause Read - R/clr */ ++#define E1000_EITR(_n) (0x01680 + (0x4 * (_n))) ++#define E1000_EICS 0x01520 /* Ext. Interrupt Cause Set - W0 */ ++#define E1000_EIMS 0x01524 /* Ext. Interrupt Mask Set/Read - RW */ ++#define E1000_EIMC 0x01528 /* Ext. Interrupt Mask Clear - WO */ ++#define E1000_EIAC 0x0152C /* Ext. Interrupt Auto Clear - RW */ ++#define E1000_EIAM 0x01530 /* Ext. Interrupt Ack Auto Clear Mask - RW */ ++#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 E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ ++#define E1000_PBS 0x01008 /* Packet Buffer Size */ ++#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ ++#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_I2CCMD 0x01028 /* SFPI2C Command Register - RW */ ++#define E1000_I2CPARAMS 0x0102C /* SFPI2C Parameters Register - RW */ ++#define E1000_WDSTP 0x01040 /* Watchdog Setup - RW */ ++#define E1000_SWDSTS 0x01044 /* SW Device Status - RW */ ++#define E1000_FRTIMER 0x01048 /* Free Running Timer - RW */ ++#define E1000_TCPTIMER 0x0104C /* TCP Timer - RW */ ++#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_RDFPCQ(_n) (0x02430 + (0x4 * (_n))) ++#define E1000_PBRTH 0x02458 /* PB Rx Arbitration Threshold - RW */ ++#define E1000_FCRTV 0x02460 /* Flow Control Refresh Timer Value - RW */ ++/* Split and Replication Rx Control - RW */ ++#define E1000_RDPUMB 0x025CC /* DMA Rx Descriptor uC Mailbox - RW */ ++#define E1000_RDPUAD 0x025D0 /* DMA Rx Descriptor uC Addr Command - RW */ ++#define E1000_RDPUWD 0x025D4 /* DMA Rx Descriptor uC Data Write - RW */ ++#define E1000_RDPURD 0x025D8 /* DMA Rx Descriptor uC Data Read - RW */ ++#define E1000_RDPUCTL 0x025DC /* DMA Rx Descriptor uC Control - RW */ ++#define E1000_RDTR 0x02820 /* Rx Delay Timer - RW */ ++#define E1000_RADV 0x0282C /* Rx Interrupt Absolute Delay Timer - RW */ ++/* ++ * Convenience macros ++ * ++ * Note: "_n" is the queue number of the register to be written to. ++ * ++ * Example usage: ++ * E1000_RDBAL_REG(current_rx_queue) ++ */ ++#define E1000_RDBAL(_n) ((_n) < 4 ? (0x02800 + ((_n) * 0x100)) : (0x0C000 + ((_n) * 0x40))) ++#define E1000_RDBAH(_n) ((_n) < 4 ? (0x02804 + ((_n) * 0x100)) : (0x0C004 + ((_n) * 0x40))) ++#define E1000_RDLEN(_n) ((_n) < 4 ? (0x02808 + ((_n) * 0x100)) : (0x0C008 + ((_n) * 0x40))) ++#define E1000_SRRCTL(_n) ((_n) < 4 ? (0x0280C + ((_n) * 0x100)) : (0x0C00C + ((_n) * 0x40))) ++#define E1000_RDH(_n) ((_n) < 4 ? (0x02810 + ((_n) * 0x100)) : (0x0C010 + ((_n) * 0x40))) ++#define E1000_RDT(_n) ((_n) < 4 ? (0x02818 + ((_n) * 0x100)) : (0x0C018 + ((_n) * 0x40))) ++#define E1000_RXDCTL(_n) ((_n) < 4 ? (0x02828 + ((_n) * 0x100)) : (0x0C028 + ((_n) * 0x40))) ++#define E1000_TDBAL(_n) ((_n) < 4 ? (0x03800 + ((_n) * 0x100)) : (0x0E000 + ((_n) * 0x40))) ++#define E1000_TDBAH(_n) ((_n) < 4 ? (0x03804 + ((_n) * 0x100)) : (0x0E004 + ((_n) * 0x40))) ++#define E1000_TDLEN(_n) ((_n) < 4 ? (0x03808 + ((_n) * 0x100)) : (0x0E008 + ((_n) * 0x40))) ++#define E1000_TDH(_n) ((_n) < 4 ? (0x03810 + ((_n) * 0x100)) : (0x0E010 + ((_n) * 0x40))) ++#define E1000_TDT(_n) ((_n) < 4 ? (0x03818 + ((_n) * 0x100)) : (0x0E018 + ((_n) * 0x40))) ++#define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) : (0x0E028 + ((_n) * 0x40))) ++#define E1000_TARC(_n) (0x03840 + (_n << 8)) ++#define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) ++#define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) ++#define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) : (0x0E038 + ((_n) * 0x40))) ++#define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) : (0x0E03C + ((_n) * 0x40))) ++#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_PSRTYPE(_i) (0x05480 + ((_i) * 4)) ++#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x054E0 + ((_i - 16) * 8))) ++#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x054E4 + ((_i - 16) * 8))) ++#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8)) ++#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4)) ++#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4)) ++#define E1000_FFMT_REG(_i) (0x09000 + ((_i) * 8)) ++#define E1000_FFVT_REG(_i) (0x09800 + ((_i) * 8)) ++#define E1000_FFLT_REG(_i) (0x05F00 + ((_i) * 8)) ++#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 */ ++#define E1000_TDFTS 0x03428 /* Tx Data FIFO Tail Saved - RW */ ++#define E1000_TDFPC 0x03430 /* Tx Data FIFO Packet Count - RW */ ++#define E1000_TDPUMB 0x0357C /* DMA Tx Descriptor uC Mail Box - RW */ ++#define E1000_TDPUAD 0x03580 /* DMA Tx Descriptor uC Addr Command - RW */ ++#define E1000_TDPUWD 0x03584 /* DMA Tx Descriptor uC Data Write - RW */ ++#define E1000_TDPURD 0x03588 /* DMA Tx Descriptor uC Data Read - RW */ ++#define E1000_TDPUCTL 0x0358C /* DMA Tx Descriptor uC Control - RW */ ++#define E1000_DTXCTL 0x03590 /* DMA Tx Control - RW */ ++#define E1000_TIDV 0x03820 /* Tx Interrupt Delay Value - RW */ ++#define E1000_TADV 0x0382C /* Tx Interrupt Absolute Delay Val - RW */ ++#define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ ++#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 */ ++#define E1000_RXERRC 0x0400C /* Receive Error Count - R/clr */ ++#define E1000_MPC 0x04010 /* Missed Packet Count - R/clr */ ++#define E1000_SCC 0x04014 /* Single Collision Count - R/clr */ ++#define E1000_ECOL 0x04018 /* Excessive Collision Count - R/clr */ ++#define E1000_MCC 0x0401C /* Multiple Collision Count - R/clr */ ++#define E1000_LATECOL 0x04020 /* Late Collision Count - R/clr */ ++#define E1000_COLC 0x04028 /* Collision Count - R/clr */ ++#define E1000_DC 0x04030 /* Defer Count - R/clr */ ++#define E1000_TNCRS 0x04034 /* Tx-No CRS - R/clr */ ++#define E1000_SEC 0x04038 /* Sequence Error Count - R/clr */ ++#define E1000_CEXTERR 0x0403C /* Carrier Extension Error Count - R/clr */ ++#define E1000_RLEC 0x04040 /* Receive Length Error Count - R/clr */ ++#define E1000_XONRXC 0x04048 /* XON Rx Count - R/clr */ ++#define E1000_XONTXC 0x0404C /* XON Tx Count - R/clr */ ++#define E1000_XOFFRXC 0x04050 /* XOFF Rx Count - R/clr */ ++#define E1000_XOFFTXC 0x04054 /* XOFF Tx Count - R/clr */ ++#define E1000_FCRUC 0x04058 /* Flow Control Rx Unsupported Count- R/clr */ ++#define E1000_PRC64 0x0405C /* Packets Rx (64 bytes) - R/clr */ ++#define E1000_PRC127 0x04060 /* Packets Rx (65-127 bytes) - R/clr */ ++#define E1000_PRC255 0x04064 /* Packets Rx (128-255 bytes) - R/clr */ ++#define E1000_PRC511 0x04068 /* Packets Rx (255-511 bytes) - R/clr */ ++#define E1000_PRC1023 0x0406C /* Packets Rx (512-1023 bytes) - R/clr */ ++#define E1000_PRC1522 0x04070 /* Packets Rx (1024-1522 bytes) - R/clr */ ++#define E1000_GPRC 0x04074 /* Good Packets Rx Count - R/clr */ ++#define E1000_BPRC 0x04078 /* Broadcast Packets Rx Count - R/clr */ ++#define E1000_MPRC 0x0407C /* Multicast Packets Rx Count - R/clr */ ++#define E1000_GPTC 0x04080 /* Good Packets Tx Count - R/clr */ ++#define E1000_GORCL 0x04088 /* Good Octets Rx Count Low - R/clr */ ++#define E1000_GORCH 0x0408C /* Good Octets Rx Count High - R/clr */ ++#define E1000_GOTCL 0x04090 /* Good Octets Tx Count Low - R/clr */ ++#define E1000_GOTCH 0x04094 /* Good Octets Tx Count High - R/clr */ ++#define E1000_RNBC 0x040A0 /* Rx No Buffers Count - R/clr */ ++#define E1000_RUC 0x040A4 /* Rx Undersize Count - R/clr */ ++#define E1000_RFC 0x040A8 /* Rx Fragment Count - R/clr */ ++#define E1000_ROC 0x040AC /* Rx Oversize Count - R/clr */ ++#define E1000_RJC 0x040B0 /* Rx Jabber Count - R/clr */ ++#define E1000_MGTPRC 0x040B4 /* Management Packets Rx Count - R/clr */ ++#define E1000_MGTPDC 0x040B8 /* Management Packets Dropped Count - R/clr */ ++#define E1000_MGTPTC 0x040BC /* Management Packets Tx Count - R/clr */ ++#define E1000_TORL 0x040C0 /* Total Octets Rx Low - R/clr */ ++#define E1000_TORH 0x040C4 /* Total Octets Rx High - R/clr */ ++#define E1000_TOTL 0x040C8 /* Total Octets Tx Low - R/clr */ ++#define E1000_TOTH 0x040CC /* Total Octets Tx High - R/clr */ ++#define E1000_TPR 0x040D0 /* Total Packets Rx - R/clr */ ++#define E1000_TPT 0x040D4 /* Total Packets Tx - R/clr */ ++#define E1000_PTC64 0x040D8 /* Packets Tx (64 bytes) - R/clr */ ++#define E1000_PTC127 0x040DC /* Packets Tx (65-127 bytes) - R/clr */ ++#define E1000_PTC255 0x040E0 /* Packets Tx (128-255 bytes) - R/clr */ ++#define E1000_PTC511 0x040E4 /* Packets Tx (256-511 bytes) - R/clr */ ++#define E1000_PTC1023 0x040E8 /* Packets Tx (512-1023 bytes) - R/clr */ ++#define E1000_PTC1522 0x040EC /* Packets Tx (1024-1522 Bytes) - R/clr */ ++#define E1000_MPTC 0x040F0 /* Multicast Packets Tx Count - R/clr */ ++#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_PCS_CFG0 0x04200 /* PCS Configuration 0 - RW */ ++#define E1000_PCS_LCTL 0x04208 /* PCS Link Control - RW */ ++#define E1000_PCS_LSTAT 0x0420C /* PCS Link Status - RO */ ++#define E1000_CBTMPC 0x0402C /* Circuit Breaker Tx Packet Count */ ++#define E1000_HTDPMC 0x0403C /* Host Transmit Discarded Packets */ ++#define E1000_CBRDPC 0x04044 /* Circuit Breaker Rx Dropped Count */ ++#define E1000_CBRMPC 0x040FC /* Circuit Breaker Rx Packet Count */ ++#define E1000_RPTHC 0x04104 /* Rx Packets To Host */ ++#define E1000_HGPTC 0x04118 /* Host Good Packets Tx Count */ ++#define E1000_HTCBDPC 0x04124 /* Host Tx Circuit Breaker Dropped Count */ ++#define E1000_HGORCL 0x04128 /* Host Good Octets Received Count Low */ ++#define E1000_HGORCH 0x0412C /* Host Good Octets Received Count High */ ++#define E1000_HGOTCL 0x04130 /* Host Good Octets Transmit Count Low */ ++#define E1000_HGOTCH 0x04134 /* Host Good Octets Transmit Count High */ ++#define E1000_LENERRS 0x04138 /* Length Errors Count */ ++#define E1000_SCVPC 0x04228 /* SerDes/SGMII Code Violation Pkt Count */ ++#define E1000_HRMPC 0x0A018 /* Header Redirection Missed Packet Count */ ++#define E1000_PCS_ANADV 0x04218 /* AN advertisement - RW */ ++#define E1000_PCS_LPAB 0x0421C /* Link Partner Ability - RW */ ++#define E1000_PCS_NPTX 0x04220 /* AN Next Page Transmit - RW */ ++#define E1000_PCS_LPABNP 0x04224 /* Link Partner Ability Next Page - RW */ ++#define E1000_1GSTAT_RCV 0x04228 /* 1GSTAT Code Violation Packet Count - RW */ ++#define E1000_RXCSUM 0x05000 /* Rx Checksum Control - RW */ ++#define E1000_RLPML 0x05004 /* Rx Long Packet Max Length */ ++#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 */ ++#define E1000_VMD_CTL 0x0581C /* VMDq Control - RW */ ++#define E1000_VFQA0 0x0B000 /* VLAN Filter Queue Array 0 - RW Array */ ++#define E1000_VFQA1 0x0B200 /* VLAN Filter Queue Array 1 - RW Array */ ++#define E1000_WUC 0x05800 /* Wakeup Control - RW */ ++#define E1000_WUFC 0x05808 /* Wakeup Filter Control - RW */ ++#define E1000_WUS 0x05810 /* Wakeup Status - RO */ ++#define E1000_MANC 0x05820 /* Management Control - RW */ ++#define E1000_IPAV 0x05838 /* IP Address Valid - RW */ ++#define E1000_IP4AT 0x05840 /* IPv4 Address Table - RW Array */ ++#define E1000_IP6AT 0x05880 /* IPv6 Address Table - RW Array */ ++#define E1000_WUPL 0x05900 /* Wakeup Packet Length - RW */ ++#define E1000_WUPM 0x05A00 /* Wakeup Packet Memory - RO A */ ++#define E1000_PBACL 0x05B68 /* MSIx PBA Clear - Read/Write 1's to clear */ ++#define E1000_FFLT 0x05F00 /* Flexible Filter Length Table - RW Array */ ++#define E1000_HOST_IF 0x08800 /* Host Interface */ ++#define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ ++#define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ ++ ++#define E1000_KMRNCTRLSTA 0x00034 /* MAC-PHY interface - RW */ ++#define E1000_MDPHYA 0x0003C /* PHY address - RW */ ++#define E1000_MANC2H 0x05860 /* Management Control To Host - RW */ ++#define E1000_SW_FW_SYNC 0x05B5C /* Software-Firmware Synchronization - RW */ ++#define E1000_CCMCTL 0x05B48 /* CCM Control Register */ ++#define E1000_GIOCTL 0x05B44 /* GIO Analog Control Register */ ++#define E1000_SCCTL 0x05B4C /* PCIc PLL Configuration Register */ ++#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_DCA_ID 0x05B70 /* DCA Requester ID Information - RO */ ++#define E1000_DCA_CTRL 0x05B74 /* DCA Control - RW */ ++#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ ++#define E1000_HICR 0x08F00 /* Host Interface Control */ + -+ if (size == 1) -+ flash_data = (u32)data & 0x00FF; -+ else -+ flash_data = (u32)data; ++/* RSS registers */ ++#define E1000_CPUVEC 0x02C10 /* CPU Vector Register - RW */ ++#define E1000_MRQC 0x05818 /* Multiple Receive Control - RW */ ++#define E1000_IMIR(_i) (0x05A80 + ((_i) * 4)) /* Immediate Interrupt */ ++#define E1000_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* Immediate Interrupt Ext*/ ++#define E1000_IMIRVP 0x05AC0 /* Immediate Interrupt Rx VLAN Priority - RW */ ++#define E1000_MSIXBM(_i) (0x01600 + ((_i) * 4)) /* MSI-X Allocation Register (_i) - RW */ ++#define E1000_MSIXTADD(_i) (0x0C000 + ((_i) * 0x10)) /* MSI-X Table entry addr low reg 0 - RW */ ++#define E1000_MSIXTUADD(_i) (0x0C004 + ((_i) * 0x10)) /* MSI-X Table entry addr upper reg 0 - RW */ ++#define E1000_MSIXTMSG(_i) (0x0C008 + ((_i) * 0x10)) /* MSI-X Table entry message reg 0 - RW */ ++#define E1000_MSIXVCTRL(_i) (0x0C00C + ((_i) * 0x10)) /* MSI-X Table entry vector ctrl reg 0 - RW */ ++#define E1000_MSIXPBA 0x0E000 /* MSI-X Pending bit array */ ++#define E1000_RETA(_i) (0x05C00 + ((_i) * 4)) /* Redirection Table - RW Array */ ++#define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */ ++#define E1000_RSSIM 0x05864 /* RSS Interrupt Mask */ ++#define E1000_RSSIR 0x05868 /* RSS Interrupt Request */ ++#define E1000_RXMTRL 0x0B634 /* Time sync Rx EtherType and Message Type - RW */ ++#define E1000_RXUDP 0x0B638 /* Time Sync Rx UDP Port - RW */ ++#endif +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/ethtool.c linux-2.6.22-10/drivers/net/e1000e/ethtool.c +--- linux-2.6.22-0/drivers/net/e1000e/ethtool.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/ethtool.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,2005 @@ ++/******************************************************************************* + -+ ew32flash(ICH_FLASH_FDATA0, flash_data); ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ /* check if FCERR is set to 1 , if set to 1, clear it -+ * and try the whole sequence a few more times else done */ -+ ret_val = e1000_flash_cycle_ich8lan(hw, -+ ICH_FLASH_WRITE_COMMAND_TIMEOUT); -+ if (!ret_val) -+ break; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ /* 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...ICH_FLASH_CYCLE_REPEAT_COUNT times. -+ */ -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); -+ if (hsfsts.hsf_status.flcerr == 1) -+ /* Repeat for some time before giving up. */ -+ continue; -+ if (hsfsts.hsf_status.flcdone == 0) { -+ hw_dbg(hw, "Timeout error - flash cycle " -+ "did not complete."); -+ break; -+ } -+ } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); ++ This program is distributed in the hope 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. + -+ return ret_val; -+} ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+/** -+ * e1000_write_flash_byte_ich8lan - Write a single byte to NVM -+ * @hw: pointer to the HW structure -+ * @offset: The index of the byte to read. -+ * @data: The byte to write to the NVM. -+ * -+ * Writes a single byte to the NVM using the flash access registers. -+ **/ -+static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, -+ u8 data) -+{ -+ u16 word = (u16)data; ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ return e1000_write_flash_data_ich8lan(hw, offset, 1, word); -+} ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+/** -+ * e1000_retry_write_flash_byte_ich8lan - Writes a single byte to NVM -+ * @hw: pointer to the HW structure -+ * @offset: The offset of the byte to write. -+ * @byte: The byte to write to the NVM. -+ * -+ * Writes a single byte to the NVM using the flash access registers. -+ * Goes through a retry algorithm before giving up. -+ **/ -+static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, -+ u32 offset, u8 byte) -+{ -+ s32 ret_val; -+ u16 program_retries; ++*******************************************************************************/ + -+ ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); -+ if (!ret_val) -+ return ret_val; ++/* ethtool support for e1000 */ + -+ for (program_retries = 0; program_retries < 100; program_retries++) { -+ hw_dbg(hw, "Retrying Byte %2.2X at offset %u\n", byte, offset); -+ udelay(100); -+ ret_val = e1000_write_flash_byte_ich8lan(hw, offset, byte); -+ if (!ret_val) -+ break; -+ } -+ if (program_retries == 100) -+ return -E1000_ERR_NVM; ++#include ++#ifdef SIOCETHTOOL ++#include ++#include ++#include + -+ return 0; -+} ++#include "e1000.h" ++#ifdef NETIF_F_HW_VLAN_TX ++#include ++#endif + -+/** -+ * e1000_erase_flash_bank_ich8lan - Erase a bank (4k) from NVM -+ * @hw: pointer to the HW structure -+ * @bank: 0 for first bank, 1 for second bank, etc. -+ * -+ * Erases the bank specified. Each bank is a 4k block. Banks are 0 based. -+ * bank N is 4096 * N + flash_reg_addr. -+ **/ -+static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) -+{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ union ich8_hws_flash_status hsfsts; -+ union ich8_hws_flash_ctrl hsflctl; -+ u32 flash_linear_addr; -+ /* bank size is in 16bit words - adjust to bytes */ -+ u32 flash_bank_size = nvm->flash_bank_size * 2; -+ s32 ret_val; -+ s32 count = 0; -+ s32 iteration; -+ s32 sector_size; -+ s32 j; ++#ifdef ETHTOOL_OPS_COMPAT ++#include "kcompat_ethtool.c" ++#endif + -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); ++struct e1000_stats { ++ char stat_string[ETH_GSTRING_LEN]; ++ int sizeof_stat; ++ int stat_offset; ++}; + -+ /* 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 = bank * 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 = bank * 4096 -+ * 10: The Hw sector is 8K bytes, nth sector = bank * 8192 -+ * (ich9 only, otherwise error condition) -+ * 11: The Hw sector is 64K bytes, nth sector = bank * 65536 -+ */ -+ switch (hsfsts.hsf_status.berasesz) { -+ case 0: -+ /* Hw sector size 256 */ -+ sector_size = ICH_FLASH_SEG_SIZE_256; -+ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_256; -+ break; -+ case 1: -+ sector_size = ICH_FLASH_SEG_SIZE_4K; -+ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_4K; -+ break; -+ case 2: -+ if (hw->mac.type == e1000_ich9lan) { -+ sector_size = ICH_FLASH_SEG_SIZE_8K; -+ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K; -+ } else { -+ return -E1000_ERR_NVM; -+ } -+ break; -+ case 3: -+ sector_size = ICH_FLASH_SEG_SIZE_64K; -+ iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_64K; -+ break; -+ default: -+ return -E1000_ERR_NVM; -+ } ++#define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ ++ offsetof(struct e1000_adapter, m) ++static const struct e1000_stats e1000_gstrings_stats[] = { ++ { "rx_packets", E1000_STAT(stats.gprc) }, ++ { "tx_packets", E1000_STAT(stats.gptc) }, ++ { "rx_bytes", E1000_STAT(stats.gorc) }, ++ { "tx_bytes", E1000_STAT(stats.gotc) }, ++ { "rx_broadcast", E1000_STAT(stats.bprc) }, ++ { "tx_broadcast", E1000_STAT(stats.bptc) }, ++ { "rx_multicast", E1000_STAT(stats.mprc) }, ++ { "tx_multicast", E1000_STAT(stats.mptc) }, ++ { "rx_errors", E1000_STAT(net_stats.rx_errors) }, ++ { "tx_errors", E1000_STAT(net_stats.tx_errors) }, ++ { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, ++ { "multicast", E1000_STAT(stats.mprc) }, ++ { "collisions", E1000_STAT(stats.colc) }, ++ { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, ++ { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, ++ { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, ++ { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, ++ { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, ++ { "rx_missed_errors", E1000_STAT(stats.mpc) }, ++ { "tx_aborted_errors", E1000_STAT(stats.ecol) }, ++ { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, ++ { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, ++ { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, ++ { "tx_window_errors", E1000_STAT(stats.latecol) }, ++ { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, ++ { "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) }, ++ { "tx_restart_queue", E1000_STAT(restart_queue) }, ++ { "rx_long_length_errors", E1000_STAT(stats.roc) }, ++ { "rx_short_length_errors", E1000_STAT(stats.ruc) }, ++ { "rx_align_errors", E1000_STAT(stats.algnerrc) }, ++ { "tx_tcp_seg_good", E1000_STAT(stats.tsctc) }, ++ { "tx_tcp_seg_failed", E1000_STAT(stats.tsctfc) }, ++ { "rx_flow_control_xon", E1000_STAT(stats.xonrxc) }, ++ { "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.gorc) }, ++ { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, ++ { "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) }, ++ { "tx_smbus", E1000_STAT(stats.mgptc) }, ++ { "rx_smbus", E1000_STAT(stats.mgprc) }, ++ { "dropped_smbus", E1000_STAT(stats.mgpdc) }, ++ { "rx_dma_failed", E1000_STAT(rx_dma_failed) }, ++ { "tx_dma_failed", E1000_STAT(tx_dma_failed) }, ++}; ++ ++#define E1000_GLOBAL_STATS_LEN \ ++ sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) ++#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN) ++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 ARRAY_SIZE(e1000_gstrings_test) ++ ++static int e1000_get_settings(struct net_device *netdev, ++ struct ethtool_cmd *ecmd) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 status; + -+ /* Start with the base address, then add the sector offset. */ -+ flash_linear_addr = hw->nvm.flash_base_addr; -+ flash_linear_addr += (bank) ? (sector_size * iteration) : 0; ++ if (hw->phy.media_type == e1000_media_type_copper) { + -+ for (j = 0; j < iteration ; j++) { -+ do { -+ /* Steps */ -+ ret_val = e1000_flash_cycle_init_ich8lan(hw); -+ if (ret_val) -+ return ret_val; ++ ecmd->supported = (SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_1000baseT_Full | ++ SUPPORTED_Autoneg | ++ SUPPORTED_TP); ++ if (hw->phy.type == e1000_phy_ife) ++ ecmd->supported &= ~SUPPORTED_1000baseT_Full; ++ ecmd->advertising = ADVERTISED_TP; + -+ /* Write a value 11 (block Erase) in Flash -+ * Cycle field in hw flash control */ -+ hsflctl.regval = er16flash(ICH_FLASH_HSFCTL); -+ hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE; -+ ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval); ++ if (hw->mac.autoneg == 1) { ++ ecmd->advertising |= ADVERTISED_Autoneg; ++ /* the e1000 autoneg seems to match ethtool nicely */ ++ ecmd->advertising |= hw->phy.autoneg_advertised; ++ } + -+ /* Write the last 24 bits of an index within the -+ * block into Flash Linear address field in Flash -+ * Address. -+ */ -+ flash_linear_addr += (j * sector_size); -+ ew32flash(ICH_FLASH_FADDR, flash_linear_addr); ++ ecmd->port = PORT_TP; ++ ecmd->phy_address = hw->phy.addr; ++ ecmd->transceiver = XCVR_INTERNAL; + -+ ret_val = e1000_flash_cycle_ich8lan(hw, -+ ICH_FLASH_ERASE_COMMAND_TIMEOUT); -+ if (ret_val == 0) -+ break; ++ } else { ++ ecmd->supported = (SUPPORTED_1000baseT_Full | ++ SUPPORTED_FIBRE | ++ SUPPORTED_Autoneg); + -+ /* Check if FCERR is set to 1. If 1, -+ * clear it and try the whole sequence -+ * a few more times else Done */ -+ hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); -+ if (hsfsts.hsf_status.flcerr == 1) -+ /* repeat for some time before -+ * giving up */ -+ continue; -+ else if (hsfsts.hsf_status.flcdone == 0) -+ return ret_val; -+ } while (++count < ICH_FLASH_CYCLE_REPEAT_COUNT); -+ } ++ ecmd->advertising = (ADVERTISED_1000baseT_Full | ++ ADVERTISED_FIBRE | ++ ADVERTISED_Autoneg); + -+ return 0; -+} ++ ecmd->port = PORT_FIBRE; ++ ecmd->transceiver = XCVR_EXTERNAL; ++ } + -+/** -+ * e1000_valid_led_default_ich8lan - Set the default LED settings -+ * @hw: pointer to the HW structure -+ * @data: Pointer to the LED settings -+ * -+ * Reads the LED default settings from the NVM to data. If the NVM LED -+ * settings is all 0's or F's, set the LED default to a valid LED default -+ * setting. -+ **/ -+static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) -+{ -+ s32 ret_val; ++ status = er32(STATUS); ++ if (status & E1000_STATUS_LU) { ++ if (status & E1000_STATUS_SPEED_1000) ++ ecmd->speed = 1000; ++ else if (status & E1000_STATUS_SPEED_100) ++ ecmd->speed = 100; ++ else ++ ecmd->speed = 10; + -+ ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; ++ if (status & E1000_STATUS_FD) ++ ecmd->duplex = DUPLEX_FULL; ++ else ++ ecmd->duplex = DUPLEX_HALF; ++ } else { ++ ecmd->speed = -1; ++ ecmd->duplex = -1; + } + -+ if (*data == ID_LED_RESERVED_0000 || -+ *data == ID_LED_RESERVED_FFFF) -+ *data = ID_LED_DEFAULT_ICH8LAN; -+ ++ ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) || ++ hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE; + return 0; +} + -+/** -+ * e1000_get_bus_info_ich8lan - Get/Set the bus type and width -+ * @hw: pointer to the HW structure -+ * -+ * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability -+ * register, so the the bus width is hard coded. -+ **/ -+static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) ++static u32 e1000_get_link(struct net_device *netdev) +{ -+ struct e1000_bus_info *bus = &hw->bus; -+ s32 ret_val; -+ -+ ret_val = e1000e_get_bus_info_pcie(hw); -+ -+ /* ICH devices are "PCI Express"-ish. They have -+ * a configuration space, but do not contain -+ * PCI Express Capability registers, so bus width -+ * must be hardcoded. -+ */ -+ if (bus->width == e1000_bus_width_unknown) -+ bus->width = e1000_bus_width_pcie_x1; -+ -+ return ret_val; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 status; ++ ++ status = er32(STATUS); ++ return (status & E1000_STATUS_LU); +} + -+/** -+ * e1000_reset_hw_ich8lan - Reset the hardware -+ * @hw: pointer to the HW structure -+ * -+ * Does a full reset of the hardware which includes a reset of the PHY and -+ * MAC. -+ **/ -+static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ++static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) +{ -+ u32 ctrl, icr, kab; -+ s32 ret_val; -+ -+ /* Prevent the PCI-E bus from sticking if there is no TLP connection -+ * on the last TLP read/write transaction when MAC is reset. -+ */ -+ ret_val = e1000e_disable_pcie_master(hw); -+ if (ret_val) { -+ hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); -+ } -+ -+ hw_dbg(hw, "Masking off all interrupts\n"); -+ ew32(IMC, 0xffffffff); -+ -+ /* Disable the Transmit and Receive units. Then delay to allow -+ * any pending transactions to complete before we hit the MAC -+ * with the global reset. -+ */ -+ ew32(RCTL, 0); -+ ew32(TCTL, E1000_TCTL_PSP); -+ e1e_flush(); -+ -+ msleep(10); -+ -+ /* Workaround for ICH8 bit corruption issue in FIFO memory */ -+ if (hw->mac.type == e1000_ich8lan) { -+ /* Set Tx and Rx buffer allocation to 8k apiece. */ -+ ew32(PBA, E1000_PBA_8K); -+ /* Set Packet Buffer Size to 16k. */ -+ ew32(PBS, E1000_PBS_16K); -+ } ++ struct e1000_mac_info *mac = &adapter->hw.mac; + -+ ctrl = er32(CTRL); ++ mac->autoneg = 0; + -+ if (!e1000_check_reset_block(hw)) { -+ /* 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; ++ /* Fiber NICs only allow 1000 gbps Full duplex */ ++ if ((adapter->hw.phy.media_type == e1000_media_type_fiber) && ++ spddplx != (SPEED_1000 + DUPLEX_FULL)) { ++ e_err("Unsupported Speed/Duplex configuration\n"); ++ return -EINVAL; + } -+ ret_val = e1000_acquire_swflag_ich8lan(hw); -+ hw_dbg(hw, "Issuing a global reset to ich8lan"); -+ ew32(CTRL, (ctrl | E1000_CTRL_RST)); -+ msleep(20); + -+ ret_val = e1000e_get_auto_rd_done(hw); -+ if (ret_val) { -+ /* -+ * When auto config read does not complete, do not -+ * return with an error. This can happen in situations -+ * where there is no eeprom and prevents getting link. -+ */ -+ hw_dbg(hw, "Auto Read Done did not complete\n"); ++ switch (spddplx) { ++ case SPEED_10 + DUPLEX_HALF: ++ mac->forced_speed_duplex = ADVERTISE_10_HALF; ++ break; ++ case SPEED_10 + DUPLEX_FULL: ++ mac->forced_speed_duplex = ADVERTISE_10_FULL; ++ break; ++ case SPEED_100 + DUPLEX_HALF: ++ mac->forced_speed_duplex = ADVERTISE_100_HALF; ++ break; ++ case SPEED_100 + DUPLEX_FULL: ++ mac->forced_speed_duplex = ADVERTISE_100_FULL; ++ break; ++ case SPEED_1000 + DUPLEX_FULL: ++ mac->autoneg = 1; ++ adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL; ++ break; ++ case SPEED_1000 + DUPLEX_HALF: /* not supported */ ++ default: ++ e_err("Unsupported Speed/Duplex configuration\n"); ++ return -EINVAL; + } -+ -+ ew32(IMC, 0xffffffff); -+ icr = er32(ICR); -+ -+ kab = er32(KABGTXD); -+ kab |= E1000_KABGTXD_BGSQLBIAS; -+ ew32(KABGTXD, kab); -+ -+ return ret_val; ++ return 0; +} + -+/** -+ * e1000_init_hw_ich8lan - Initialize the hardware -+ * @hw: pointer to the HW structure -+ * -+ * Prepares the hardware for transmit and receive by doing the following: -+ * - initialize hardware bits -+ * - initialize LED identification -+ * - setup receive address registers -+ * - setup flow control -+ * - setup transmit discriptors -+ * - clear statistics -+ **/ -+static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) ++static int e1000_set_settings(struct net_device *netdev, ++ struct ethtool_cmd *ecmd) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 ctrl_ext, txdctl, snoop; -+ s32 ret_val; -+ u16 i; -+ -+ e1000_initialize_hw_bits_ich8lan(hw); ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ /* Initialize identification LED */ -+ ret_val = e1000e_id_led_init(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error initializing identification LED\n"); -+ return ret_val; ++ /* ++ * When SoL/IDER sessions are active, autoneg/speed/duplex ++ * cannot be changed ++ */ ++ if (hw->phy.ops.check_reset_block && ++ hw->phy.ops.check_reset_block(&adapter->hw)) { ++ e_err("Cannot change link characteristics when SoL/IDER" ++ " is active.\n"); ++ return -EINVAL; + } + -+ /* Setup the receive address. */ -+ e1000e_init_rx_addrs(hw, mac->rar_entry_count); -+ -+ /* Zero out the Multicast HASH table */ -+ hw_dbg(hw, "Zeroing the MTA\n"); -+ for (i = 0; i < mac->mta_reg_count; i++) -+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); -+ -+ /* Setup link and flow control */ -+ ret_val = e1000_setup_link_ich8lan(hw); -+ -+ /* Set the transmit descriptor write-back policy for both queues */ -+ txdctl = er32(TXDCTL); -+ txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB; -+ txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | -+ E1000_TXDCTL_MAX_TX_DESC_PREFETCH; -+ ew32(TXDCTL, txdctl); -+ txdctl = er32(TXDCTL1); -+ txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | -+ E1000_TXDCTL_FULL_TX_DESC_WB; -+ txdctl = (txdctl & ~E1000_TXDCTL_PTHRESH) | -+ E1000_TXDCTL_MAX_TX_DESC_PREFETCH; -+ ew32(TXDCTL1, txdctl); -+ -+ /* ICH8 has opposite polarity of no_snoop bits. -+ * By default, we should use snoop behavior. */ -+ if (mac->type == e1000_ich8lan) -+ snoop = PCIE_ICH8_SNOOP_ALL; -+ else -+ snoop = (u32) ~(PCIE_NO_SNOOP_ALL); -+ e1000e_set_pcie_no_snoop(hw, snoop); -+ -+ ctrl_ext = er32(CTRL_EXT); -+ ctrl_ext |= E1000_CTRL_EXT_RO_DIS; -+ ew32(CTRL_EXT, ctrl_ext); -+ -+ /* 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 -+ * is no link. -+ */ -+ e1000_clear_hw_cntrs_ich8lan(hw); ++ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) ++ msleep(1); + -+ return 0; -+} -+/** -+ * e1000_initialize_hw_bits_ich8lan - Initialize required hardware bits -+ * @hw: pointer to the HW structure -+ * -+ * Sets/Clears required hardware bits necessary for correctly setting up the -+ * hardware for transmit and receive. -+ **/ -+static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw) -+{ -+ u32 reg; ++ if (ecmd->autoneg == AUTONEG_ENABLE) { ++ hw->mac.autoneg = 1; ++ if (hw->phy.media_type == e1000_media_type_fiber) ++ hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full | ++ ADVERTISED_FIBRE | ++ ADVERTISED_Autoneg; ++ else ++ hw->phy.autoneg_advertised = ecmd->advertising | ++ ADVERTISED_TP | ++ ADVERTISED_Autoneg; ++ ecmd->advertising = hw->phy.autoneg_advertised; ++ if (adapter->fc_autoneg) ++ hw->fc.original_type = e1000_fc_default; ++ } else { ++ if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { ++ clear_bit(__E1000_RESETTING, &adapter->state); ++ return -EINVAL; ++ } ++ } + -+ /* Extended Device Control */ -+ reg = er32(CTRL_EXT); -+ reg |= (1 << 22); -+ ew32(CTRL_EXT, reg); ++ /* reset the link */ + -+ /* Transmit Descriptor Control 0 */ -+ reg = er32(TXDCTL); -+ reg |= (1 << 22); -+ ew32(TXDCTL, reg); ++ if (netif_running(adapter->netdev)) { ++ e1000_down(adapter); ++ e1000_up(adapter); ++ } else { ++ e1000_reset(adapter); ++ } + -+ /* Transmit Descriptor Control 1 */ -+ reg = er32(TXDCTL1); -+ reg |= (1 << 22); -+ ew32(TXDCTL1, reg); ++ clear_bit(__E1000_RESETTING, &adapter->state); ++ return 0; ++} + -+ /* Transmit Arbitration Control 0 */ -+ reg = er32(TARC0); -+ if (hw->mac.type == e1000_ich8lan) -+ reg |= (1 << 28) | (1 << 29); -+ reg |= (1 << 23) | (1 << 24) | (1 << 26) | (1 << 27); -+ ew32(TARC0, reg); ++static void e1000_get_pauseparam(struct net_device *netdev, ++ struct ethtool_pauseparam *pause) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ /* Transmit Arbitration Control 1 */ -+ reg = er32(TARC1); -+ if (er32(TCTL) & E1000_TCTL_MULR) -+ reg &= ~(1 << 28); -+ else -+ reg |= (1 << 28); -+ reg |= (1 << 24) | (1 << 26) | (1 << 30); -+ ew32(TARC1, reg); ++ pause->autoneg = ++ (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); + -+ /* Device Status */ -+ if (hw->mac.type == e1000_ich8lan) { -+ reg = er32(STATUS); -+ reg &= ~(1 << 31); -+ ew32(STATUS, reg); ++ if (hw->fc.type == e1000_fc_rx_pause) { ++ pause->rx_pause = 1; ++ } else if (hw->fc.type == e1000_fc_tx_pause) { ++ pause->tx_pause = 1; ++ } else if (hw->fc.type == e1000_fc_full) { ++ pause->rx_pause = 1; ++ pause->tx_pause = 1; + } +} + -+/** -+ * e1000_setup_link_ich8lan - Setup flow control and link settings -+ * @hw: pointer to the HW structure -+ * -+ * Determines which flow control settings to use, then configures flow -+ * control. Calls the appropriate media-specific link configuration -+ * function. Assuming the adapter has a valid link partner, a valid link -+ * should be established. Assumes the hardware has previously been reset -+ * and the transmitter and receiver are not enabled. -+ **/ -+static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) ++static int e1000_set_pauseparam(struct net_device *netdev, ++ struct ethtool_pauseparam *pause) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ int retval = 0; + -+ if (e1000_check_reset_block(hw)) -+ return 0; ++ adapter->fc_autoneg = pause->autoneg; + -+ /* ICH parts do not have a word in the NVM to determine -+ * the default flow control setting, so we explicitly -+ * set it to full. -+ */ -+ if (mac->fc == e1000_fc_default) -+ mac->fc = e1000_fc_full; ++ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) ++ msleep(1); + -+ mac->original_fc = mac->fc; ++ if (pause->rx_pause && pause->tx_pause) ++ hw->fc.type = e1000_fc_full; ++ else if (pause->rx_pause && !pause->tx_pause) ++ hw->fc.type = e1000_fc_rx_pause; ++ else if (!pause->rx_pause && pause->tx_pause) ++ hw->fc.type = e1000_fc_tx_pause; ++ else if (!pause->rx_pause && !pause->tx_pause) ++ hw->fc.type = e1000_fc_none; + -+ hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", mac->fc); ++ hw->fc.original_type = hw->fc.type; + -+ /* Continue to configure the copper link. */ -+ ret_val = e1000_setup_copper_link_ich8lan(hw); -+ if (ret_val) -+ return ret_val; ++ if (adapter->fc_autoneg == AUTONEG_ENABLE) { ++ hw->fc.type = e1000_fc_default; ++ if (netif_running(adapter->netdev)) { ++ e1000_down(adapter); ++ e1000_up(adapter); ++ } else { ++ e1000_reset(adapter); ++ } ++ } else { ++ retval = ((hw->phy.media_type == e1000_media_type_fiber) ? ++ hw->mac.ops.setup_link(hw) : ++ e1000_force_mac_fc_generic(hw)); ++ } + -+ ew32(FCTTV, mac->fc_pause_time); ++ clear_bit(__E1000_RESETTING, &adapter->state); ++ return retval; ++} + -+ return e1000e_set_fc_watermarks(hw); ++static u32 e1000_get_rx_csum(struct net_device *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ return (adapter->flags & FLAG_RX_CSUM_ENABLED); +} + -+/** -+ * e1000_setup_copper_link_ich8lan - Configure MAC/PHY interface -+ * @hw: pointer to the HW structure -+ * -+ * Configures the kumeran interface to the PHY to wait the appropriate time -+ * when polling the PHY, then call the generic setup_copper_link to finish -+ * configuring the copper link. -+ **/ -+static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) ++static int e1000_set_rx_csum(struct net_device *netdev, u32 data) +{ -+ u32 ctrl; -+ s32 ret_val; -+ u16 reg_data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_SLU; -+ ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); -+ ew32(CTRL, ctrl); ++ if (data) ++ adapter->flags |= FLAG_RX_CSUM_ENABLED; ++ else ++ adapter->flags &= ~FLAG_RX_CSUM_ENABLED; + -+ /* 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 = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), ®_data); -+ if (ret_val) -+ return ret_val; -+ reg_data |= 0x3F; -+ ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data); -+ if (ret_val) -+ return ret_val; ++ if (netif_running(netdev)) ++ e1000_reinit_locked(adapter); ++ else ++ e1000_reset(adapter); ++ return 0; ++} + -+ if (hw->phy.type == e1000_phy_igp_3) { -+ ret_val = e1000e_copper_link_setup_igp(hw); -+ if (ret_val) -+ return ret_val; -+ } ++static u32 e1000_get_tx_csum(struct net_device *netdev) ++{ ++ return ((netdev->features & NETIF_F_HW_CSUM) != 0); ++} ++ ++static int e1000_set_tx_csum(struct net_device *netdev, u32 data) ++{ ++ if (data) ++ netdev->features |= NETIF_F_HW_CSUM; ++ else ++ netdev->features &= ~NETIF_F_HW_CSUM; + -+ return e1000e_setup_copper_link(hw); ++ return 0; +} + -+/** -+ * e1000_get_link_up_info_ich8lan - Get current link speed and duplex -+ * @hw: pointer to the HW structure -+ * @speed: pointer to store current link speed -+ * @duplex: pointer to store the current link duplex -+ * -+ * Calls the generic get_speed_and_duplex to retreive the current link -+ * information and then calls the Kumeran lock loss workaround for links at -+ * gigabit speeds. -+ **/ -+static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, -+ u16 *duplex) ++#ifdef NETIF_F_TSO ++static int e1000_set_tso(struct net_device *netdev, u32 data) +{ -+ s32 ret_val; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ int i; ++ struct net_device *v_netdev; + -+ ret_val = e1000e_get_speed_and_duplex_copper(hw, speed, duplex); -+ if (ret_val) -+ return ret_val; ++ if (data) { ++ netdev->features |= NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ netdev->features |= NETIF_F_TSO6; ++#endif ++ } else { ++ netdev->features &= ~NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ netdev->features &= ~NETIF_F_TSO6; ++#endif ++#ifdef NETIF_F_HW_VLAN_TX ++ /* disable TSO on all VLANs if they're present */ ++ if (!adapter->vlgrp) ++ goto tso_out; ++ for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) { ++ v_netdev = vlan_group_get_device(adapter->vlgrp, i); ++ if (!v_netdev) ++ continue; + -+ if ((hw->mac.type == e1000_ich8lan) && -+ (hw->phy.type == e1000_phy_igp_3) && -+ (*speed == SPEED_1000)) { -+ ret_val = e1000_kmrn_lock_loss_workaround_ich8lan(hw); ++ v_netdev->features &= ~NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ v_netdev->features &= ~NETIF_F_TSO6; ++#endif ++ vlan_group_set_device(adapter->vlgrp, i, v_netdev); ++ } ++#endif + } ++ ++tso_out: ++ e_info("TSO is %s\n", data ? "Enabled" : "Disabled"); ++ adapter->flags |= FLAG_TSO_FORCE; ++ return 0; ++} ++#endif + -+ return ret_val; ++static u32 e1000_get_msglevel(struct net_device *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ return adapter->msg_enable; +} + -+/** -+ * e1000_kmrn_lock_loss_workaround_ich8lan - Kumeran workaround -+ * @hw: pointer to the HW structure -+ * -+ * 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. -+ **/ -+static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) ++static void e1000_set_msglevel(struct net_device *netdev, u32 data) +{ -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -+ u32 phy_ctrl; -+ s32 ret_val; -+ u16 i, data; -+ bool link; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ adapter->msg_enable = data; ++} + -+ if (!dev_spec->kmrn_lock_loss_workaround_enabled) -+ return 0; ++static int e1000_get_regs_len(struct net_device *netdev) ++{ ++#define E1000_REGS_LEN 32 /* overestimate */ ++ return E1000_REGS_LEN * sizeof(u32); ++} + -+ /* Make sure link is up before proceeding. If not just return. -+ * Attempting this while link is negotiating fouled up link -+ * stability */ -+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); -+ if (!link) -+ return 0; ++static void e1000_get_regs(struct net_device *netdev, ++ struct ethtool_regs *regs, void *p) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 *regs_buff = p; ++ u16 phy_data; ++ u8 revision_id; + -+ for (i = 0; i < 10; i++) { -+ /* read once to clear */ -+ ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data); -+ if (ret_val) -+ return ret_val; -+ /* and again to get new status */ -+ ret_val = e1e_rphy(hw, IGP3_KMRN_DIAG, &data); -+ if (ret_val) -+ return ret_val; ++ memset(p, 0, E1000_REGS_LEN * sizeof(u32)); + -+ /* check for PCS lock */ -+ if (!(data & IGP3_KMRN_DIAG_PCS_LOCK_LOSS)) -+ return 0; ++ pci_read_config_byte(adapter->pdev, PCI_REVISION_ID, &revision_id); + -+ /* Issue PHY reset */ -+ e1000_phy_hw_reset(hw); -+ mdelay(5); -+ } -+ /* Disable GigE link negotiation */ -+ phy_ctrl = er32(PHY_CTRL); -+ phy_ctrl |= (E1000_PHY_CTRL_GBE_DISABLE | -+ E1000_PHY_CTRL_NOND0A_GBE_DISABLE); -+ ew32(PHY_CTRL, phy_ctrl); ++ regs->version = (1 << 24) | (revision_id << 16) | adapter->pdev->device; + -+ /* Call gig speed drop workaround on Giga disable before accessing -+ * any PHY registers */ -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++ regs_buff[0] = er32(CTRL); ++ regs_buff[1] = er32(STATUS); + -+ /* unable to acquire PCS lock */ -+ return -E1000_ERR_PHY; -+} ++ regs_buff[2] = er32(RCTL); ++ regs_buff[3] = er32(RDLEN(0)); ++ regs_buff[4] = er32(RDH(0)); ++ regs_buff[5] = er32(RDT(0)); ++ regs_buff[6] = er32(RDTR); + -+/** -+ * e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state -+ * @hw: pointer to the HW structure -+ * @state: boolean value used to set the current Kumaran workaround state -+ * -+ * If ICH8, set the current Kumeran workaround state (enabled - TRUE -+ * /disabled - FALSE). -+ **/ -+void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw, -+ bool state) -+{ -+ struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; ++ regs_buff[7] = er32(TCTL); ++ regs_buff[8] = er32(TDLEN(0)); ++ regs_buff[9] = er32(TDH(0)); ++ regs_buff[10] = er32(TDT(0)); ++ regs_buff[11] = er32(TIDV); + -+ if (hw->mac.type != e1000_ich8lan) { -+ hw_dbg(hw, "Workaround applies to ICH8 only.\n"); -+ return; ++ regs_buff[12] = adapter->hw.phy.type; /* PHY type (IGP=1, M88=0) */ ++ if (hw->phy.type == e1000_phy_m88) { ++ hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); ++ regs_buff[13] = (u32)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) */ ++ hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); ++ regs_buff[17] = (u32)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) */ ++ regs_buff[20] = regs_buff[17]; /* polarity correction */ ++ /* phy receive errors */ ++ regs_buff[22] = adapter->phy_stats.receive_errors; ++ regs_buff[23] = regs_buff[13]; /* mdix mode */ + } ++ regs_buff[21] = adapter->phy_stats.idle_errors; /* phy idle errors */ ++ hw->phy.ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); ++ regs_buff[24] = (u32)phy_data; /* phy local receiver status */ ++ regs_buff[25] = regs_buff[24]; /* phy remote receiver status */ ++} + -+ dev_spec->kmrn_lock_loss_workaround_enabled = state; ++static int e1000_get_eeprom_len(struct net_device *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ return adapter->hw.nvm.word_size * 2; +} + -+/** -+ * e1000_ipg3_phy_powerdown_workaround_ich8lan - Power down workaround on D3 -+ * @hw: pointer to the HW structure -+ * -+ * Workaround for 82566 power-down on D3 entry: -+ * 1) disable gigabit link -+ * 2) write VR power-down enable -+ * 3) read it back -+ * Continue if successful, else issue LCD reset and repeat -+ **/ -+void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) ++static int e1000_get_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *eeprom, u8 *bytes) +{ -+ u32 reg; -+ u16 data; -+ u8 retry = 0; -+ -+ if (hw->phy.type != e1000_phy_igp_3) -+ return; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u16 *eeprom_buff; ++ int first_word; ++ int last_word; ++ int ret_val = 0; ++ u16 i; + -+ /* Try the workaround twice (if needed) */ -+ do { -+ /* Disable link */ -+ reg = er32(PHY_CTRL); -+ reg |= (E1000_PHY_CTRL_GBE_DISABLE | -+ E1000_PHY_CTRL_NOND0A_GBE_DISABLE); -+ ew32(PHY_CTRL, reg); ++ if (eeprom->len == 0) ++ return -EINVAL; + -+ /* Call gig speed drop workaround on Giga disable before -+ * accessing any PHY registers */ -+ if (hw->mac.type == e1000_ich8lan) -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++ eeprom->magic = adapter->pdev->vendor | (adapter->pdev->device << 16); + -+ /* Write VR power-down enable */ -+ e1e_rphy(hw, IGP3_VR_CTRL, &data); -+ data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; -+ e1e_wphy(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN); ++ first_word = eeprom->offset >> 1; ++ last_word = (eeprom->offset + eeprom->len - 1) >> 1; + -+ /* Read it back and test */ -+ e1e_rphy(hw, IGP3_VR_CTRL, &data); -+ data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; -+ if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry) -+ break; ++ eeprom_buff = kmalloc(sizeof(u16) * ++ (last_word - first_word + 1), GFP_KERNEL); ++ if (!eeprom_buff) ++ return -ENOMEM; + -+ /* Issue PHY reset and repeat at most one more time */ -+ reg = er32(CTRL); -+ ew32(CTRL, reg | E1000_CTRL_PHY_RST); -+ retry++; -+ } while (retry); -+} ++ if (hw->nvm.type == e1000_nvm_eeprom_spi) { ++ ret_val = hw->nvm.ops.read(hw, first_word, ++ last_word - first_word + 1, ++ eeprom_buff); ++ } else { ++ for (i = 0; i < last_word - first_word + 1; i++) { ++ ret_val = hw->nvm.ops.read(hw, first_word + i, 1, ++ &eeprom_buff[i]); ++ if (ret_val) ++ break; ++ } ++ } + -+/** -+ * e1000e_gig_downshift_workaround_ich8lan - WoL from S5 stops working -+ * @hw: pointer to the HW structure -+ * -+ * Steps to take when dropping from 1Gb/s (eg. link cable removal (LSC), -+ * LPLU, Giga disable, MDIC PHY reset): -+ * 1) Set Kumeran Near-end loopback -+ * 2) Clear Kumeran Near-end loopback -+ * Should only be called for ICH8[m] devices with IGP_3 Phy. -+ **/ -+void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) -+{ -+ s32 ret_val; -+ u16 reg_data; ++ /* Device's eeprom is always little-endian, word addressable */ ++ for (i = 0; i < last_word - first_word + 1; i++) ++ le16_to_cpus(&eeprom_buff[i]); + -+ if ((hw->mac.type != e1000_ich8lan) || -+ (hw->phy.type != e1000_phy_igp_3)) -+ return; ++ memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); ++ kfree(eeprom_buff); + -+ ret_val = e1000e_read_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, -+ ®_data); -+ if (ret_val) -+ return; -+ reg_data |= E1000_KMRNCTRLSTA_DIAG_NELPBK; -+ ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, -+ reg_data); -+ if (ret_val) -+ return; -+ reg_data &= ~E1000_KMRNCTRLSTA_DIAG_NELPBK; -+ ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_DIAG_OFFSET, -+ reg_data); ++ return ret_val; +} + -+/** -+ * e1000_cleanup_led_ich8lan - Restore the default LED operation -+ * @hw: pointer to the HW structure -+ * -+ * Return the LED back to the default configuration. -+ **/ -+static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) ++static int e1000_set_eeprom(struct net_device *netdev, ++ struct ethtool_eeprom *eeprom, u8 *bytes) +{ -+ if (hw->phy.type == e1000_phy_ife) -+ return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0); ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u16 *eeprom_buff; ++ void *ptr; ++ int max_len; ++ int first_word; ++ int last_word; ++ int ret_val = 0; ++ u16 i; + -+ ew32(LEDCTL, hw->mac.ledctl_default); -+ return 0; -+} ++ if (eeprom->len == 0) ++ return -EOPNOTSUPP; + -+/** -+ * e1000_led_on_ich8lan - Turn LED's on -+ * @hw: pointer to the HW structure -+ * -+ * Turn on the LED's. -+ **/ -+static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) -+{ -+ if (hw->phy.type == e1000_phy_ife) -+ return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, -+ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); ++ if (eeprom->magic != (adapter->pdev->vendor | (adapter->pdev->device << 16))) ++ return -EFAULT; + -+ ew32(LEDCTL, hw->mac.ledctl_mode2); -+ return 0; -+} ++ if (adapter->flags2 & FLAG2_READ_ONLY_NVM) ++ return -EINVAL; + -+/** -+ * e1000_led_off_ich8lan - Turn LED's off -+ * @hw: pointer to the HW structure -+ * -+ * Turn off the LED's. -+ **/ -+static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) -+{ -+ if (hw->phy.type == e1000_phy_ife) -+ return e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, -+ (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); ++ max_len = hw->nvm.word_size * 2; + -+ ew32(LEDCTL, hw->mac.ledctl_mode1); -+ return 0; -+} ++ first_word = eeprom->offset >> 1; ++ last_word = (eeprom->offset + eeprom->len - 1) >> 1; ++ eeprom_buff = kmalloc(max_len, GFP_KERNEL); ++ if (!eeprom_buff) ++ return -ENOMEM; + -+/** -+ * e1000_clear_hw_cntrs_ich8lan - Clear statistical counters -+ * @hw: pointer to the HW structure -+ * -+ * Clears hardware counters specific to the silicon family and calls -+ * clear_hw_cntrs_generic to clear all general purpose counters. -+ **/ -+static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) -+{ -+ u32 temp; ++ ptr = (void *)eeprom_buff; + -+ e1000e_clear_hw_cntrs_base(hw); ++ 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 = hw->nvm.ops.read(hw, first_word, 1, &eeprom_buff[0]); ++ ptr++; ++ } ++ 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 = hw->nvm.ops.read(hw, last_word, 1, ++ &eeprom_buff[last_word - first_word]); + -+ temp = er32(ALGNERRC); -+ temp = er32(RXERRC); -+ temp = er32(TNCRS); -+ temp = er32(CEXTERR); -+ temp = er32(TSCTC); -+ temp = er32(TSCTFC); ++ /* Device's eeprom is always little-endian, word addressable */ ++ for (i = 0; i < last_word - first_word + 1; i++) ++ le16_to_cpus(&eeprom_buff[i]); + -+ temp = er32(MGTPRC); -+ temp = er32(MGTPDC); -+ temp = er32(MGTPTC); ++ memcpy(ptr, bytes, eeprom->len); + -+ temp = er32(IAC); -+ temp = er32(ICRXOC); ++ for (i = 0; i < last_word - first_word + 1; i++) ++ eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); + -+} ++ ret_val = hw->nvm.ops.write(hw, first_word, last_word - first_word + 1, ++ eeprom_buff); + -+static struct e1000_mac_operations ich8_mac_ops = { -+ .mng_mode_enab = E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, -+ .check_for_link = e1000e_check_for_copper_link, -+ .cleanup_led = e1000_cleanup_led_ich8lan, -+ .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, -+ .get_bus_info = e1000_get_bus_info_ich8lan, -+ .get_link_up_info = e1000_get_link_up_info_ich8lan, -+ .led_on = e1000_led_on_ich8lan, -+ .led_off = e1000_led_off_ich8lan, -+ .mc_addr_list_update = e1000e_mc_addr_list_update_generic, -+ .reset_hw = e1000_reset_hw_ich8lan, -+ .init_hw = e1000_init_hw_ich8lan, -+ .setup_link = e1000_setup_link_ich8lan, -+ .setup_physical_interface= e1000_setup_copper_link_ich8lan, -+}; ++ /* ++ * Update the checksum over the first part of the EEPROM if needed ++ * and flush shadow RAM for 82573 controllers ++ */ ++ if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) || ++ (hw->mac.type == e1000_82574) || ++ (hw->mac.type == e1000_82573))) ++ hw->nvm.ops.update(hw); + -+static struct e1000_phy_operations ich8_phy_ops = { -+ .acquire_phy = e1000_acquire_swflag_ich8lan, -+ .check_reset_block = e1000_check_reset_block_ich8lan, -+ .commit_phy = NULL, -+ .force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan, -+ .get_cfg_done = e1000e_get_cfg_done, -+ .get_cable_length = e1000e_get_cable_length_igp_2, -+ .get_phy_info = e1000_get_phy_info_ich8lan, -+ .read_phy_reg = e1000e_read_phy_reg_igp, -+ .release_phy = e1000_release_swflag_ich8lan, -+ .reset_phy = e1000_phy_hw_reset_ich8lan, -+ .set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan, -+ .set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan, -+ .write_phy_reg = e1000e_write_phy_reg_igp, -+}; ++ kfree(eeprom_buff); ++ return ret_val; ++} + -+static struct e1000_nvm_operations ich8_nvm_ops = { -+ .acquire_nvm = e1000_acquire_swflag_ich8lan, -+ .read_nvm = e1000_read_nvm_ich8lan, -+ .release_nvm = e1000_release_swflag_ich8lan, -+ .update_nvm = e1000_update_nvm_checksum_ich8lan, -+ .valid_led_default = e1000_valid_led_default_ich8lan, -+ .validate_nvm = e1000_validate_nvm_checksum_ich8lan, -+ .write_nvm = e1000_write_nvm_ich8lan, -+}; ++static void e1000_get_drvinfo(struct net_device *netdev, ++ struct ethtool_drvinfo *drvinfo) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ char firmware_version[32]; ++ u16 eeprom_data; + -+struct e1000_info e1000_ich8_info = { -+ .mac = e1000_ich8lan, -+ .flags = FLAG_HAS_WOL -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_CTRLEXT_ON_LOAD -+ | FLAG_HAS_AMT -+ | FLAG_HAS_FLASH -+ | FLAG_APME_IN_WUC, -+ .pba = 8, -+ .get_invariants = e1000_get_invariants_ich8lan, -+ .mac_ops = &ich8_mac_ops, -+ .phy_ops = &ich8_phy_ops, -+ .nvm_ops = &ich8_nvm_ops, -+}; ++ strncpy(drvinfo->driver, e1000e_driver_name, 32); ++ strncpy(drvinfo->version, e1000e_driver_version, 32); + -+struct e1000_info e1000_ich9_info = { -+ .mac = e1000_ich9lan, -+ .flags = FLAG_HAS_JUMBO_FRAMES -+ | FLAG_HAS_WOL -+ | FLAG_RX_CSUM_ENABLED -+ | FLAG_HAS_CTRLEXT_ON_LOAD -+ | FLAG_HAS_AMT -+ | FLAG_HAS_ERT -+ | FLAG_HAS_FLASH -+ | FLAG_APME_IN_WUC, -+ .pba = 10, -+ .get_invariants = e1000_get_invariants_ich8lan, -+ .mac_ops = &ich8_mac_ops, -+ .phy_ops = &ich8_phy_ops, -+ .nvm_ops = &ich8_nvm_ops, -+}; ++ /* ++ * EEPROM image version # is reported as firmware version # for ++ * PCI-E controllers ++ */ ++ hw->nvm.ops.read(&adapter->hw, 5, 1, &eeprom_data); ++ sprintf(firmware_version, "%d.%d-%d", ++ (eeprom_data & 0xF000) >> 12, ++ (eeprom_data & 0x0FF0) >> 4, ++ eeprom_data & 0x000F); + -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/lib.c linux-2.6.22-10/drivers/net/e1000e/lib.c ---- linux-2.6.22-0/drivers/net/e1000e/lib.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/lib.c 2007-11-21 13:55:36.000000000 -0500 -@@ -0,0 +1,2466 @@ -+/******************************************************************************* ++ strncpy(drvinfo->fw_version, firmware_version, 32); ++ strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); ++ drvinfo->regdump_len = e1000_get_regs_len(netdev); ++ drvinfo->eedump_len = e1000_get_eeprom_len(netdev); ++} + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++static void e1000_get_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *ring) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_ring *rx_ring = adapter->rx_ring; + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ ring->rx_max_pending = E1000_MAX_RXD; ++ ring->tx_max_pending = E1000_MAX_TXD; ++ ring->rx_mini_max_pending = 0; ++ ring->rx_jumbo_max_pending = 0; ++ ring->rx_pending = rx_ring->count; ++ ring->tx_pending = tx_ring->count; ++ ring->rx_mini_pending = 0; ++ ring->rx_jumbo_pending = 0; ++} + -+ This program is distributed in the hope 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. ++static int e1000_set_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *ring) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_ring *tx_ring, *tx_old; ++ struct e1000_ring *rx_ring, *rx_old; ++ int err; + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) ++ return -EINVAL; + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) ++ msleep(1); + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ if (netif_running(adapter->netdev)) ++ e1000_down(adapter); + -+*******************************************************************************/ ++ tx_old = adapter->tx_ring; ++ rx_old = adapter->rx_ring; + -+#include -+#include -+#include -+#include ++ err = -ENOMEM; ++ tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); ++ if (!tx_ring) ++ goto err_alloc_tx; ++ /* ++ * use a memcpy to save any previously configured ++ * items like napi structs from having to be ++ * reinitialized ++ */ ++ memcpy(tx_ring, tx_old, sizeof(struct e1000_ring)); + -+#include "e1000.h" ++ rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); ++ if (!rx_ring) ++ goto err_alloc_rx; ++ memcpy(rx_ring, rx_old, sizeof(struct e1000_ring)); + -+enum e1000_mng_mode { -+ e1000_mng_mode_none = 0, -+ e1000_mng_mode_asf, -+ e1000_mng_mode_pt, -+ e1000_mng_mode_ipmi, -+ e1000_mng_mode_host_if_only -+}; ++ adapter->tx_ring = tx_ring; ++ adapter->rx_ring = rx_ring; + -+#define E1000_FACTPS_MNGCG 0x20000000 ++ rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD); ++ rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD)); ++ rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); + -+#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management -+ * Technology signature */ ++ tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD); ++ tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD)); ++ tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); + -+/** -+ * e1000e_get_bus_info_pcie - Get PCIe bus information -+ * @hw: pointer to the HW structure -+ * -+ * Determines and stores the system bus information for a particular -+ * network interface. The following bus information is determined and stored: -+ * bus speed, bus width, type (PCIe), and PCIe function. -+ **/ -+s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) -+{ -+ struct e1000_bus_info *bus = &hw->bus; -+ struct e1000_adapter *adapter = hw->adapter; -+ u32 status; -+ u16 pcie_link_status, pci_header_type, cap_offset; ++ if (netif_running(adapter->netdev)) { ++ /* Try to get new resources before deleting old */ ++ err = e1000_setup_rx_resources(adapter); ++ if (err) ++ goto err_setup_rx; ++ err = e1000_setup_tx_resources(adapter); ++ if (err) ++ goto err_setup_tx; + -+ cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); -+ if (!cap_offset) { -+ bus->width = e1000_bus_width_unknown; -+ } else { -+ pci_read_config_word(adapter->pdev, -+ cap_offset + PCIE_LINK_STATUS, -+ &pcie_link_status); -+ bus->width = (enum e1000_bus_width)((pcie_link_status & -+ PCIE_LINK_WIDTH_MASK) >> -+ PCIE_LINK_WIDTH_SHIFT); ++ /* ++ * restore the old in order to free it, ++ * then add in the new ++ */ ++ adapter->rx_ring = rx_old; ++ adapter->tx_ring = tx_old; ++ e1000_free_rx_resources(adapter); ++ e1000_free_tx_resources(adapter); ++ kfree(tx_old); ++ kfree(rx_old); ++ adapter->rx_ring = rx_ring; ++ adapter->tx_ring = tx_ring; ++ err = e1000_up(adapter); ++ if (err) ++ goto err_setup; + } + -+ pci_read_config_word(adapter->pdev, PCI_HEADER_TYPE_REGISTER, -+ &pci_header_type); -+ if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) { -+ status = er32(STATUS); -+ bus->func = (status & E1000_STATUS_FUNC_MASK) -+ >> E1000_STATUS_FUNC_SHIFT; -+ } else { -+ bus->func = 0; -+ } ++ clear_bit(__E1000_RESETTING, &adapter->state); ++ return 0; ++err_setup_tx: ++ e1000_free_rx_resources(adapter); ++err_setup_rx: ++ adapter->rx_ring = rx_old; ++ adapter->tx_ring = tx_old; ++ kfree(rx_ring); ++err_alloc_rx: ++ kfree(tx_ring); ++err_alloc_tx: ++ e1000_up(adapter); ++err_setup: ++ clear_bit(__E1000_RESETTING, &adapter->state); ++ return err; ++} + ++static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data, ++ int reg, int offset, u32 mask, u32 write) ++{ ++ u32 pat, val; ++ static const u32 test[] = ++ {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; ++ for (pat = 0; pat < ARRAY_SIZE(test); pat++) { ++ E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset, ++ (test[pat] & write)); ++ val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset); ++ if (val != (test[pat] & write & mask)) { ++ e_err("pattern test reg %04X failed: got " ++ "0x%08X expected 0x%08X\n", ++ reg + offset, ++ val, (test[pat] & write & mask)); ++ *data = reg; ++ return 1; ++ } ++ } + return 0; +} + -+/** -+ * e1000e_write_vfta - Write value to VLAN filter table -+ * @hw: pointer to the HW structure -+ * @offset: register offset in VLAN filter table -+ * @value: register value written to VLAN filter table -+ * -+ * Writes value at the given offset in the register array which stores -+ * the VLAN filter table. -+ **/ -+void e1000e_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) ++static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data, ++ int reg, u32 mask, u32 write) +{ -+ E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); -+ e1e_flush(); ++ u32 val; ++ __ew32(&adapter->hw, reg, write & mask); ++ val = __er32(&adapter->hw, reg); ++ if ((write & mask) != (val & mask)) { ++ e_err("set/check reg %04X test failed: got 0x%08X" ++ "expected 0x%08X\n", reg, (val & mask), (write & mask)); ++ *data = reg; ++ return 1; ++ } ++ return 0; +} ++#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write) \ ++ do { \ ++ if (reg_pattern_test(adapter, data, reg, offset, mask, write)) \ ++ return 1; \ ++ } while (0) ++#define REG_PATTERN_TEST(reg, mask, write) \ ++ REG_PATTERN_TEST_ARRAY(reg, 0, mask, write) + -+/** -+ * e1000e_init_rx_addrs - Initialize receive address's -+ * @hw: pointer to the HW structure -+ * @rar_count: receive address registers -+ * -+ * Setups the receive address registers by setting the base receive address -+ * register to the devices MAC address and clearing all the other receive -+ * address registers to 0. -+ **/ -+void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) ++#define REG_SET_AND_CHECK(reg, mask, write) \ ++ do { \ ++ if (reg_set_and_check(adapter, data, reg, mask, write)) \ ++ return 1; \ ++ } while (0) ++ ++static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data) +{ ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_mac_info *mac = &adapter->hw.mac; ++ u32 value; ++ u32 before; ++ u32 after; + u32 i; ++ u32 toggle; + -+ /* Setup the receive address */ -+ hw_dbg(hw, "Programming MAC Address into RAR[0]\n"); ++ /* ++ * The status register is Read Only, so a write should fail. ++ * Some bits that get toggled are ignored. ++ */ ++ switch (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_82574: ++ case e1000_ich8lan: ++ case e1000_ich9lan: ++ case e1000_ich10lan: ++ toggle = 0x7FFFF033; ++ break; ++ default: ++ toggle = 0xFFFFF833; ++ break; ++ } + -+ e1000e_rar_set(hw, hw->mac.addr, 0); ++ before = er32(STATUS); ++ value = (er32(STATUS) & toggle); ++ ew32(STATUS, toggle); ++ after = er32(STATUS) & toggle; ++ if (value != after) { ++ e_err("failed STATUS register test got: " ++ "0x%08X expected: 0x%08X\n", after, value); ++ *data = 1; ++ return 1; ++ } ++ /* restore previous status */ ++ ew32(STATUS, before); + -+ /* Zero out the other (rar_entry_count - 1) receive addresses */ -+ hw_dbg(hw, "Clearing RAR[1-%u]\n", rar_count-1); -+ for (i = 1; i < rar_count; i++) { -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0); -+ e1e_flush(); -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0); -+ e1e_flush(); ++ if (!(adapter->flags & FLAG_IS_ICH)) { ++ REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_VET, 0x0000FFFF, 0xFFFFFFFF); + } ++ ++ REG_PATTERN_TEST(E1000_RDTR, 0x0000FFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_RDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_RDLEN(0), 0x000FFF80, 0x000FFFFF); ++ REG_PATTERN_TEST(E1000_RDH(0), 0x0000FFFF, 0x0000FFFF); ++ REG_PATTERN_TEST(E1000_RDT(0), 0x0000FFFF, 0x0000FFFF); ++ REG_PATTERN_TEST(E1000_FCRTH, 0x0000FFF8, 0x0000FFF8); ++ REG_PATTERN_TEST(E1000_FCTTV, 0x0000FFFF, 0x0000FFFF); ++ REG_PATTERN_TEST(E1000_TIPG, 0x3FFFFFFF, 0x3FFFFFFF); ++ REG_PATTERN_TEST(E1000_TDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_TDLEN(0), 0x000FFF80, 0x000FFFFF); ++ ++ REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000); ++ ++ before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE); ++ REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB); ++ REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000); ++ ++ REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_RDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF); ++ if (!(adapter->flags & FLAG_IS_ICH)) ++ REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF); ++ REG_PATTERN_TEST(E1000_TDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF); ++ REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF); ++ for (i = 0; i < mac->rar_entry_count; i++) ++ REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1), ++ ((mac->type == e1000_ich10lan) ? ++ 0x8007FFFF : 0x8003FFFF), ++ 0xFFFFFFFF); ++ ++ for (i = 0; i < mac->mta_reg_count; i++) ++ REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF); ++ ++ *data = 0; ++ return 0; +} + -+/** -+ * e1000e_rar_set - Set receive address register -+ * @hw: pointer to the HW structure -+ * @addr: pointer to the receive address -+ * @index: receive address array register -+ * -+ * Sets the receive address array register at index to the address passed -+ * in by addr. -+ **/ -+void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) ++static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data) +{ -+ u32 rar_low, rar_high; ++ struct e1000_hw *hw = &adapter->hw; ++ u16 temp; ++ u16 checksum = 0; ++ u16 i; + -+ /* HW expects these in little endian so we reverse the byte order -+ * from network order (big endian) to little endian -+ */ -+ rar_low = ((u32) addr[0] | -+ ((u32) addr[1] << 8) | -+ ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); ++ *data = 0; ++ /* Read and add up the contents of the EEPROM */ ++ for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { ++ if ((hw->nvm.ops.read(&adapter->hw, i, 1, &temp)) < 0) { ++ *data = 1; ++ break; ++ } ++ checksum += temp; ++ } + -+ rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); ++ /* If Checksum is not Correct return error else test passed */ ++ if ((checksum != (u16) NVM_SUM) && !(*data)) ++ *data = 2; ++ ++ return *data; ++} ++ ++static irqreturn_t e1000_test_intr(int irq, void *data) ++{ ++ struct net_device *netdev = (struct net_device *) data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ rar_high |= E1000_RAH_AV; ++ adapter->test_icr |= er32(ICR); + -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); ++ return IRQ_HANDLED; +} + -+/** -+ * e1000_mta_set - Set multicast filter table address -+ * @hw: pointer to the HW structure -+ * @hash_value: determines the MTA register and bit to set -+ * -+ * The multicast table address is a register array of 32-bit registers. -+ * The hash_value is used to determine what register the bit is in, the -+ * current value is read, the new bit is OR'd in and the new value is -+ * written back into the register. -+ **/ -+static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value) ++static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) +{ -+ u32 hash_bit, hash_reg, mta; ++ struct net_device *netdev = adapter->netdev; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 mask; ++ u32 shared_int = 1; ++ u32 irq = adapter->pdev->irq; ++ int i; ++#ifdef CONFIG_E1000E_MSIX ++ int ret_val = 0; ++ int int_mode = E1000E_INT_MODE_LEGACY; ++#endif + -+ /* The MTA is a register array of 32-bit registers. It is -+ * treated like an array of (32*mta_reg_count) bits. We want to -+ * set bit BitArray[hash_value]. So we figure out what register -+ * the bit is in, read it, OR in the new bit, then write -+ * back the new value. The (hw->mac.mta_reg_count - 1) serves as a -+ * mask to bits 31:5 of the hash value which gives us the -+ * register we're modifying. The hash bit within that register -+ * is determined by the lower 5 bits of the hash value. -+ */ -+ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); -+ hash_bit = hash_value & 0x1F; ++ *data = 0; ++ ++ /* NOTE: we don't test MSI/MSI-X interrupts here, yet */ ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->int_mode == E1000E_INT_MODE_MSIX) { ++ int_mode = adapter->int_mode; ++ e1000_reset_interrupt_capability(adapter); ++ adapter->int_mode = E1000E_INT_MODE_LEGACY; ++ e1000_set_interrupt_capability(adapter); ++ } ++#endif ++ /* Hook up test interrupt handler just for this test */ ++ if (!request_irq(irq, &e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, ++ netdev)) { ++ shared_int = 0; ++ } else if (request_irq(irq, &e1000_test_intr, IRQF_SHARED, ++ netdev->name, netdev)) { ++ *data = 1; ++#ifdef CONFIG_E1000E_MSIX ++ ret_val = -1; ++ goto out; ++#else ++ return -1; ++#endif ++ } ++ e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared")); ++ ++ /* Disable all the interrupts */ ++ ew32(IMC, 0xFFFFFFFF); ++ msleep(10); ++ ++ /* Test each interrupt */ ++ for (i = 0; i < 10; i++) { ++ /* Interrupt to test */ ++ mask = 1 << i; + -+ mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); ++ if (adapter->flags & FLAG_IS_ICH) { ++ switch (mask) { ++ case E1000_ICR_RXSEQ: ++ continue; ++ case 0x00000100: ++ if (adapter->hw.mac.type == e1000_ich8lan || ++ adapter->hw.mac.type == e1000_ich9lan) ++ continue; ++ break; ++ default: ++ break; ++ } ++ } + -+ mta |= (1 << hash_bit); ++ 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; ++ ew32(IMC, mask); ++ ew32(ICS, mask); ++ msleep(10); + -+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); -+ e1e_flush(); -+} ++ if (adapter->test_icr & mask) { ++ *data = 3; ++ break; ++ } ++ } + -+/** -+ * e1000_hash_mc_addr - Generate a multicast hash value -+ * @hw: pointer to the HW structure -+ * @mc_addr: pointer to a multicast address -+ * -+ * Generates a multicast address hash value which is used to determine -+ * the multicast filter table array address and new table value. See -+ * e1000_mta_set_generic() -+ **/ -+static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) -+{ -+ u32 hash_value, hash_mask; -+ u8 bit_shift = 0; ++ /* ++ * Enable 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 not posted to the bus, the ++ * test failed. ++ */ ++ adapter->test_icr = 0; ++ ew32(IMS, mask); ++ ew32(ICS, mask); ++ msleep(10); + -+ /* Register count multiplied by bits per register */ -+ hash_mask = (hw->mac.mta_reg_count * 32) - 1; ++ if (!(adapter->test_icr & mask)) { ++ *data = 4; ++ break; ++ } + -+ /* For a mc_filter_type of 0, bit_shift is the number of left-shifts -+ * where 0xFF would still fall within the hash mask. */ -+ while (hash_mask >> bit_shift != 0xFF) -+ bit_shift++; ++ 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; ++ ew32(IMC, ~mask & 0x00007FFF); ++ ew32(ICS, ~mask & 0x00007FFF); ++ msleep(10); + -+ /* The portion of the address that is used for the hash table -+ * is determined by the mc_filter_type setting. -+ * The algorithm is such that there is a total of 8 bits of shifting. -+ * The bit_shift for a mc_filter_type of 0 represents the number of -+ * left-shifts where the MSB of mc_addr[5] would still fall within -+ * the hash_mask. Case 0 does this exactly. Since there are a total -+ * of 8 bits of shifting, then mc_addr[4] will shift right the -+ * remaining number of bits. Thus 8 - bit_shift. The rest of the -+ * cases are a variation of this algorithm...essentially raising the -+ * number of bits to shift mc_addr[5] left, while still keeping the -+ * 8-bit shifting total. -+ */ -+ /* For example, given the following Destination MAC Address and an -+ * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), -+ * we can see that the bit_shift for case 0 is 4. These are the hash -+ * values resulting from each mc_filter_type... -+ * [0] [1] [2] [3] [4] [5] -+ * 01 AA 00 12 34 56 -+ * LSB MSB -+ * -+ * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 -+ * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 -+ * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 -+ * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 -+ */ -+ switch (hw->mac.mc_filter_type) { -+ default: -+ case 0: -+ break; -+ case 1: -+ bit_shift += 1; -+ break; -+ case 2: -+ bit_shift += 2; -+ break; -+ case 3: -+ bit_shift += 4; -+ break; ++ if (adapter->test_icr) { ++ *data = 5; ++ break; ++ } ++ } + } + -+ hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | -+ (((u16) mc_addr[5]) << bit_shift))); ++ /* Disable all the interrupts */ ++ ew32(IMC, 0xFFFFFFFF); ++ msleep(10); + -+ return hash_value; ++ /* Unhook test interrupt handler */ ++ free_irq(irq, netdev); ++ ++#ifdef CONFIG_E1000E_MSIX ++out: ++ if (int_mode == E1000E_INT_MODE_MSIX) { ++ e1000_reset_interrupt_capability(adapter); ++ adapter->int_mode = int_mode; ++ e1000_set_interrupt_capability(adapter); ++ } ++ ++ return ret_val; ++#else ++ return *data; ++#endif +} + -+/** -+ * e1000e_mc_addr_list_update_generic - Update Multicast addresses -+ * @hw: pointer to the HW structure -+ * @mc_addr_list: array of multicast addresses to program -+ * @mc_addr_count: number of multicast addresses to program -+ * @rar_used_count: the first RAR register free to program -+ * @rar_count: total number of supported Receive Address Registers -+ * -+ * Updates the Receive Address Registers and Multicast Table Array. -+ * The caller must have a packed mc_addr_list of multicast addresses. -+ * The parameter rar_count will usually be hw->mac.rar_entry_count -+ * unless there are workarounds that change this. -+ **/ -+void e1000e_mc_addr_list_update_generic(struct e1000_hw *hw, -+ u8 *mc_addr_list, u32 mc_addr_count, -+ u32 rar_used_count, u32 rar_count) ++static void e1000_free_desc_rings(struct e1000_adapter *adapter) +{ -+ u32 hash_value; -+ u32 i; ++ struct e1000_ring *tx_ring = &adapter->test_tx_ring; ++ struct e1000_ring *rx_ring = &adapter->test_rx_ring; ++ struct pci_dev *pdev = adapter->pdev; ++ int i; + -+ /* Load the first set of multicast addresses into the exact -+ * filters (RAR). If there are not enough to fill the RAR -+ * array, clear the filters. -+ */ -+ for (i = rar_used_count; i < rar_count; i++) { -+ if (mc_addr_count) { -+ e1000e_rar_set(hw, mc_addr_list, i); -+ mc_addr_count--; -+ mc_addr_list += ETH_ALEN; -+ } else { -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0); -+ e1e_flush(); -+ E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0); -+ e1e_flush(); ++ if (tx_ring->desc && tx_ring->buffer_info) { ++ for (i = 0; i < tx_ring->count; i++) { ++ if (tx_ring->buffer_info[i].dma) ++ pci_unmap_single(pdev, ++ tx_ring->buffer_info[i].dma, ++ tx_ring->buffer_info[i].length, ++ PCI_DMA_TODEVICE); ++ if (tx_ring->buffer_info[i].skb) ++ dev_kfree_skb(tx_ring->buffer_info[i].skb); + } + } + -+ /* Clear the old settings from the MTA */ -+ hw_dbg(hw, "Clearing MTA\n"); -+ for (i = 0; i < hw->mac.mta_reg_count; i++) { -+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); -+ e1e_flush(); ++ if (rx_ring->desc && rx_ring->buffer_info) { ++ for (i = 0; i < rx_ring->count; i++) { ++ if (rx_ring->buffer_info[i].dma) ++ pci_unmap_single(pdev, ++ rx_ring->buffer_info[i].dma, ++ 2048, PCI_DMA_FROMDEVICE); ++ if (rx_ring->buffer_info[i].skb) ++ dev_kfree_skb(rx_ring->buffer_info[i].skb); ++ } + } + -+ /* Load any remaining multicast addresses into the hash table. */ -+ for (; mc_addr_count > 0; mc_addr_count--) { -+ hash_value = e1000_hash_mc_addr(hw, mc_addr_list); -+ hw_dbg(hw, "Hash value = 0x%03X\n", hash_value); -+ e1000_mta_set(hw, hash_value); -+ mc_addr_list += ETH_ALEN; ++ if (tx_ring->desc) { ++ dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, ++ tx_ring->dma); ++ tx_ring->desc = NULL; ++ } ++ if (rx_ring->desc) { ++ dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, ++ rx_ring->dma); ++ rx_ring->desc = NULL; + } ++ ++ kfree(tx_ring->buffer_info); ++ tx_ring->buffer_info = NULL; ++ kfree(rx_ring->buffer_info); ++ rx_ring->buffer_info = NULL; +} + -+/** -+ * e1000e_clear_hw_cntrs_base - Clear base hardware counters -+ * @hw: pointer to the HW structure -+ * -+ * Clears the base hardware counters by reading the counter registers. -+ **/ -+void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) -+{ -+ u32 temp; -+ -+ temp = er32(CRCERRS); -+ temp = er32(SYMERRS); -+ temp = er32(MPC); -+ temp = er32(SCC); -+ temp = er32(ECOL); -+ temp = er32(MCC); -+ temp = er32(LATECOL); -+ temp = er32(COLC); -+ temp = er32(DC); -+ temp = er32(SEC); -+ temp = er32(RLEC); -+ temp = er32(XONRXC); -+ temp = er32(XONTXC); -+ temp = er32(XOFFRXC); -+ temp = er32(XOFFTXC); -+ temp = er32(FCRUC); -+ temp = er32(GPRC); -+ temp = er32(BPRC); -+ temp = er32(MPRC); -+ temp = er32(GPTC); -+ temp = er32(GORCL); -+ temp = er32(GORCH); -+ temp = er32(GOTCL); -+ temp = er32(GOTCH); -+ temp = er32(RNBC); -+ temp = er32(RUC); -+ temp = er32(RFC); -+ temp = er32(ROC); -+ temp = er32(RJC); -+ temp = er32(TORL); -+ temp = er32(TORH); -+ temp = er32(TOTL); -+ temp = er32(TOTH); -+ temp = er32(TPR); -+ temp = er32(TPT); -+ temp = er32(MPTC); -+ temp = er32(BPTC); -+} -+ -+/** -+ * e1000e_check_for_copper_link - Check for link (Copper) -+ * @hw: pointer to the HW structure -+ * -+ * Checks to see of the link status of the hardware has changed. If a -+ * change in link status has been detected, then we read the PHY registers -+ * to get the current speed/duplex if link exists. -+ **/ -+s32 e1000e_check_for_copper_link(struct e1000_hw *hw) ++static int e1000_setup_desc_rings(struct e1000_adapter *adapter) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val; -+ bool link; ++ struct e1000_ring *tx_ring = &adapter->test_tx_ring; ++ struct e1000_ring *rx_ring = &adapter->test_rx_ring; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 rctl; ++ int i; ++ int ret_val; + -+ /* We only want to go out to the PHY registers to see if Auto-Neg -+ * has completed and/or if our link status has changed. The -+ * get_link_status flag is set upon receiving a Link Status -+ * Change or Rx Sequence Error interrupt. -+ */ -+ if (!mac->get_link_status) -+ return 0; ++ /* Setup Tx descriptor ring and Tx buffers */ + -+ /* 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. -+ */ -+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); -+ if (ret_val) -+ return ret_val; ++ if (!tx_ring->count) ++ tx_ring->count = E1000_DEFAULT_TXD; + -+ if (!link) -+ return ret_val; /* No link detected */ ++ if (!(tx_ring->buffer_info = kcalloc(tx_ring->count, ++ sizeof(struct e1000_buffer), ++ GFP_KERNEL))) { ++ ret_val = 1; ++ goto err_nomem; ++ } ++ ++ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); ++ tx_ring->size = ALIGN(tx_ring->size, 4096); ++ tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size, ++ &tx_ring->dma, GFP_KERNEL); ++ if (!tx_ring->desc) { ++ ret_val = 2; ++ goto err_nomem; ++ } ++ tx_ring->next_to_use = 0; ++ tx_ring->next_to_clean = 0; + -+ mac->get_link_status = 0; ++ ew32(TDBAL(0), ((u64) tx_ring->dma & 0x00000000FFFFFFFF)); ++ ew32(TDBAH(0), ((u64) tx_ring->dma >> 32)); ++ ew32(TDLEN(0), tx_ring->count * sizeof(struct e1000_tx_desc)); ++ ew32(TDH(0), 0); ++ ew32(TDT(0), 0); ++ ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN | E1000_TCTL_MULR | ++ E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT | ++ E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT); + -+ /* Check if there was DownShift, must be checked -+ * immediately after link-up */ -+ e1000e_check_downshift(hw); ++ for (i = 0; i < tx_ring->count; i++) { ++ struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i); ++ struct sk_buff *skb; ++ unsigned int skb_size = 1024; + -+ /* If we are forcing speed/duplex, then we simply return since -+ * we have already determined whether we have link or not. -+ */ -+ if (!mac->autoneg) { -+ ret_val = -E1000_ERR_CONFIG; -+ return ret_val; ++ skb = alloc_skb(skb_size, GFP_KERNEL); ++ if (!skb) { ++ ret_val = 3; ++ goto err_nomem; ++ } ++ skb_put(skb, skb_size); ++ tx_ring->buffer_info[i].skb = skb; ++ tx_ring->buffer_info[i].length = skb->len; ++ tx_ring->buffer_info[i].dma = ++ pci_map_single(pdev, skb->data, skb->len, ++ PCI_DMA_TODEVICE); ++ if (pci_dma_mapping_error(pdev, tx_ring->buffer_info[i].dma)) { ++ ret_val = 4; ++ goto err_nomem; ++ } ++ tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); ++ tx_desc->lower.data = cpu_to_le32(skb->len); ++ tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP | ++ E1000_TXD_CMD_IFCS | ++ E1000_TXD_CMD_RS); ++ tx_desc->upper.data = 0; + } + -+ /* Auto-Neg is enabled. Auto Speed Detection takes care -+ * of MAC speed/duplex configuration. So we only need to -+ * configure Collision Distance in the MAC. -+ */ -+ e1000e_config_collision_dist(hw); ++ /* Setup Rx descriptor ring and Rx buffers */ + -+ /* Configure Flow Control now that Auto-Neg has completed. -+ * First, we need to restore the desired flow control -+ * settings because we may have had to re-autoneg with a -+ * different link partner. -+ */ -+ ret_val = e1000e_config_fc_after_link_up(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error configuring flow control\n"); ++ if (!rx_ring->count) ++ rx_ring->count = E1000_DEFAULT_RXD; ++ ++ if (!(rx_ring->buffer_info = kcalloc(rx_ring->count, ++ sizeof(struct e1000_buffer), ++ GFP_KERNEL))) { ++ ret_val = 5; ++ goto err_nomem; + } + -+ return ret_val; -+} ++ rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc); ++ rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, ++ &rx_ring->dma, GFP_KERNEL); ++ if (!rx_ring->desc) { ++ ret_val = 6; ++ goto err_nomem; ++ } ++ rx_ring->next_to_use = 0; ++ rx_ring->next_to_clean = 0; + -+/** -+ * e1000e_check_for_fiber_link - Check for link (Fiber) -+ * @hw: pointer to the HW structure -+ * -+ * Checks for link up on the hardware. If link is not up and we have -+ * a signal, then we need to force link up. -+ **/ -+s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 rxcw; -+ u32 ctrl; -+ u32 status; -+ s32 ret_val; ++ rctl = er32(RCTL); ++ ew32(RCTL, rctl & ~E1000_RCTL_EN); ++ ew32(RDBAL(0), ((u64) rx_ring->dma & 0xFFFFFFFF)); ++ ew32(RDBAH(0), ((u64) rx_ring->dma >> 32)); ++ ew32(RDLEN(0), rx_ring->size); ++ ew32(RDH(0), 0); ++ ew32(RDT(0), 0); ++ rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | ++ E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE | ++ E1000_RCTL_SBP | E1000_RCTL_SECRC | ++ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | ++ (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); ++ ew32(RCTL, rctl); + -+ ctrl = er32(CTRL); -+ status = er32(STATUS); -+ rxcw = er32(RXCW); ++ for (i = 0; i < rx_ring->count; i++) { ++ struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rx_ring, i); ++ struct sk_buff *skb; + -+ /* If we don't have link (auto-negotiation failed or link partner -+ * cannot auto-negotiate), the cable is plugged in (we have signal), -+ * and our link partner is not trying to auto-negotiate with us (we -+ * are receiving idles or data), we need to force link up. We also -+ * need to give auto-negotiation time to complete, in case the cable -+ * was just plugged in. The autoneg_failed flag does this. -+ */ -+ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ -+ if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && -+ (!(rxcw & E1000_RXCW_C))) { -+ if (mac->autoneg_failed == 0) { -+ mac->autoneg_failed = 1; -+ return 0; ++ skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL); ++ if (!skb) { ++ ret_val = 7; ++ goto err_nomem; + } -+ hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n"); -+ -+ /* Disable auto-negotiation in the TXCW register */ -+ ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); -+ -+ /* Force link-up and also force full-duplex. */ -+ ctrl = er32(CTRL); -+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); -+ ew32(CTRL, ctrl); -+ -+ /* Configure Flow Control after forcing link up. */ -+ ret_val = e1000e_config_fc_after_link_up(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error configuring flow control\n"); -+ return ret_val; ++ skb_reserve(skb, NET_IP_ALIGN); ++ rx_ring->buffer_info[i].skb = skb; ++ rx_ring->buffer_info[i].dma = ++ pci_map_single(pdev, skb->data, 2048, ++ PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(pdev, rx_ring->buffer_info[i].dma)) { ++ ret_val = 8; ++ goto err_nomem; + } -+ } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { -+ /* If we are forcing link and we are receiving /C/ ordered -+ * sets, re-enable auto-negotiation in the TXCW register -+ * and disable forced link in the Device Control register -+ * in an attempt to auto-negotiate with our link partner. -+ */ -+ hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n"); -+ ew32(TXCW, mac->txcw); -+ ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); -+ -+ mac->serdes_has_link = 1; ++ rx_desc->buffer_addr = ++ cpu_to_le64(rx_ring->buffer_info[i].dma); ++ memset(skb->data, 0x00, skb->len); + } + + return 0; ++ ++err_nomem: ++ e1000_free_desc_rings(adapter); ++ return ret_val; +} + -+/** -+ * e1000e_check_for_serdes_link - Check for link (Serdes) -+ * @hw: pointer to the HW structure -+ * -+ * Checks for link up on the hardware. If link is not up and we have -+ * a signal, then we need to force link up. -+ **/ -+s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) ++static void e1000_phy_disable_receiver(struct e1000_adapter *adapter) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 rxcw; -+ u32 ctrl; -+ u32 status; -+ s32 ret_val; ++ /* Write out to PHY registers 29 and 30 to disable the Receiver. */ ++ adapter->hw.phy.ops.write_reg(&adapter->hw, 29, 0x001F); ++ adapter->hw.phy.ops.write_reg(&adapter->hw, 30, 0x8FFC); ++ adapter->hw.phy.ops.write_reg(&adapter->hw, 29, 0x001A); ++ adapter->hw.phy.ops.write_reg(&adapter->hw, 30, 0x8FF0); ++} + -+ ctrl = er32(CTRL); -+ status = er32(STATUS); -+ rxcw = er32(RXCW); ++static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl_reg = 0; ++ u32 stat_reg = 0; ++ u16 phy_reg = 0; + -+ /* If we don't have link (auto-negotiation failed or link partner -+ * cannot auto-negotiate), and our link partner is not trying to -+ * auto-negotiate with us (we are receiving idles or data), -+ * we need to force link up. We also need to give auto-negotiation -+ * time to complete. -+ */ -+ /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ -+ if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { -+ if (mac->autoneg_failed == 0) { -+ mac->autoneg_failed = 1; -+ return 0; -+ } -+ hw_dbg(hw, "NOT RXing /C/, disable AutoNeg and force link.\n"); ++ hw->mac.autoneg = 0; + -+ /* Disable auto-negotiation in the TXCW register */ -+ ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); ++ if (hw->phy.type == e1000_phy_m88) { ++ /* Auto-MDI/MDIX Off */ ++ hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, 0x0808); ++ /* reset to update Auto-MDI/MDIX */ ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, 0x9140); ++ /* autoneg off */ ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, 0x8140); ++ } else if (hw->phy.type == e1000_phy_gg82563) ++ hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC); + -+ /* Force link-up and also force full-duplex. */ -+ ctrl = er32(CTRL); -+ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); -+ ew32(CTRL, ctrl); ++ ctrl_reg = er32(CTRL); + -+ /* Configure Flow Control after forcing link up. */ -+ ret_val = e1000e_config_fc_after_link_up(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error configuring flow control\n"); -+ return ret_val; -+ } -+ } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { -+ /* If we are forcing link and we are receiving /C/ ordered -+ * sets, re-enable auto-negotiation in the TXCW register -+ * and disable forced link in the Device Control register -+ * in an attempt to auto-negotiate with our link partner. -+ */ -+ hw_dbg(hw, "RXing /C/, enable AutoNeg and stop forcing link.\n"); -+ ew32(TXCW, mac->txcw); -+ ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); ++ switch (hw->phy.type) { ++ case e1000_phy_ife: ++ /* force 100, set loopback */ ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, 0x6100); + -+ mac->serdes_has_link = 1; -+ } else if (!(E1000_TXCW_ANE & er32(TXCW))) { -+ /* If we force link for non-auto-negotiation switch, check -+ * link status based on MAC synchronization for internal -+ * serdes media type. -+ */ -+ /* SYNCH bit and IV bit are sticky. */ -+ udelay(10); -+ if (E1000_RXCW_SYNCH & er32(RXCW)) { -+ if (!(rxcw & E1000_RXCW_IV)) { -+ mac->serdes_has_link = 1; -+ hw_dbg(hw, "SERDES: Link is up.\n"); -+ } -+ } else { -+ mac->serdes_has_link = 0; -+ hw_dbg(hw, "SERDES: Link is down.\n"); -+ } -+ } ++ /* 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 */ ++ break; ++ case e1000_phy_bm: ++ /* Set Default MAC Interface speed to 1GB */ ++ hw->phy.ops.read_reg(hw, PHY_REG(2, 21), &phy_reg); ++ phy_reg &= ~0x0007; ++ phy_reg |= 0x006; ++ hw->phy.ops.write_reg(hw, PHY_REG(2, 21), phy_reg); ++ /* Assert SW reset for above settings to take effect */ ++ hw->phy.ops.commit(hw); ++ mdelay(1); ++ /* Force Full Duplex */ ++ hw->phy.ops.read_reg(hw, PHY_REG(769, 16), &phy_reg); ++ hw->phy.ops.write_reg(hw, PHY_REG(769, 16), phy_reg | 0x000C); ++ /* Set Link Up (in force link) */ ++ hw->phy.ops.read_reg(hw, PHY_REG(776, 16), &phy_reg); ++ hw->phy.ops.write_reg(hw, PHY_REG(776, 16), phy_reg | 0x0040); ++ /* Force Link */ ++ hw->phy.ops.read_reg(hw, PHY_REG(769, 16), &phy_reg); ++ hw->phy.ops.write_reg(hw, PHY_REG(769, 16), phy_reg | 0x0040); ++ /* Set Early Link Enable */ ++ hw->phy.ops.read_reg(hw, PHY_REG(769, 20), &phy_reg); ++ hw->phy.ops.write_reg(hw, PHY_REG(769, 20), phy_reg | 0x0400); ++ /* fall through */ ++ default: ++ /* force 1000, set loopback */ ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, 0x4140); ++ mdelay(250); + -+ if (E1000_TXCW_ANE & er32(TXCW)) { -+ status = er32(STATUS); -+ mac->serdes_has_link = (status & E1000_STATUS_LU); -+ } ++ /* Now set up the MAC to the same speed/duplex as the PHY. */ ++ ctrl_reg = er32(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 */ + -+ return 0; -+} ++ if (adapter->flags & FLAG_IS_ICH) ++ ctrl_reg |= E1000_CTRL_SLU; /* Set Link Up */ ++ } + -+/** -+ * e1000_set_default_fc_generic - Set flow control default values -+ * @hw: pointer to the HW structure -+ * -+ * Read the EEPROM for the default values for flow control and store the -+ * values. -+ **/ -+static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val; -+ u16 nvm_data; ++ if (hw->phy.media_type == e1000_media_type_copper && ++ hw->phy.type == e1000_phy_m88) { ++ ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */ ++ } else { ++ /* ++ * Set the ILOS bit on the fiber Nic if half duplex link is ++ * detected. ++ */ ++ stat_reg = er32(STATUS); ++ if ((stat_reg & E1000_STATUS_FD) == 0) ++ ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU); ++ } + -+ if (mac->fc != e1000_fc_default) -+ return 0; ++ ew32(CTRL, ctrl_reg); + -+ /* 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 -+ * disabling auto-negotiation, and the direction of the -+ * SW defined pins. If there is no SW over-ride of the flow -+ * control setting, then the variable hw->fc will -+ * be initialized based on a value in the EEPROM. ++ /* ++ * 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. + */ -+ ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); -+ -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; -+ } ++ if (hw->phy.type == e1000_phy_m88) ++ e1000_phy_disable_receiver(adapter); + -+ if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) -+ mac->fc = e1000_fc_none; -+ else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == -+ NVM_WORD0F_ASM_DIR) -+ mac->fc = e1000_fc_tx_pause; -+ else -+ mac->fc = e1000_fc_full; ++ udelay(500); + + return 0; +} + -+/** -+ * e1000e_setup_link - Setup flow control and link settings -+ * @hw: pointer to the HW structure -+ * -+ * Determines which flow control settings to use, then configures flow -+ * control. Calls the appropriate media-specific link configuration -+ * function. Assuming the adapter has a valid link partner, a valid link -+ * should be established. Assumes the hardware has previously been reset -+ * and the transmitter and receiver are not enabled. -+ **/ -+s32 e1000e_setup_link(struct e1000_hw *hw) ++static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val; -+ -+ /* In the case of the phy reset being blocked, we already have a link. -+ * We do not need to set it up again. -+ */ -+ if (e1000_check_reset_block(hw)) -+ return 0; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl = er32(CTRL); ++ int link = 0; + -+ ret_val = e1000_set_default_fc_generic(hw); -+ if (ret_val) -+ return ret_val; ++ /* special requirements for 82571/82572 fiber adapters */ + -+ /* 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. ++ /* ++ * jump through hoops to make sure link is up because serdes ++ * link is hardwired up + */ -+ mac->original_fc = mac->fc; ++ ctrl |= E1000_CTRL_SLU; ++ ew32(CTRL, ctrl); + -+ hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", mac->fc); ++ /* disable autoneg */ ++ ctrl = er32(TXCW); ++ ctrl &= ~(1 << 31); ++ ew32(TXCW, ctrl); + -+ /* Call the necessary media_type subroutine to configure the link. */ -+ ret_val = mac->ops.setup_physical_interface(hw); -+ if (ret_val) -+ return ret_val; ++ link = (er32(STATUS) & E1000_STATUS_LU); ++ ++ if (!link) { ++ /* set invert loss of signal */ ++ ctrl = er32(CTRL); ++ ctrl |= E1000_CTRL_ILOS; ++ ew32(CTRL, ctrl); ++ } + -+ /* Initialize the flow control address, type, and PAUSE timer -+ * registers to their default values. This is done even if flow -+ * control is disabled, because it does not hurt anything to -+ * initialize these registers. ++ /* ++ * special write to serdes control register to enable SerDes analog ++ * loopback + */ -+ hw_dbg(hw, "Initializing the Flow Control address, type and timer regs\n"); -+ ew32(FCT, FLOW_CONTROL_TYPE); -+ ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH); -+ ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW); -+ -+ ew32(FCTTV, mac->fc_pause_time); ++#define E1000_SERDES_LB_ON 0x410 ++ ew32(SCTL, E1000_SERDES_LB_ON); ++ msleep(10); + -+ return e1000e_set_fc_watermarks(hw); ++ return 0; +} + -+/** -+ * e1000_commit_fc_settings_generic - Configure flow control -+ * @hw: pointer to the HW structure -+ * -+ * Write the flow control settings to the Transmit Config Word Register (TXCW) -+ * base on the flow control settings in e1000_mac_info. -+ **/ -+static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) ++/* only call this for fiber/serdes connections to es2lan */ ++static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 txcw; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrlext = er32(CTRL_EXT); ++ u32 ctrl = er32(CTRL); + -+ /* Check for a software override of the flow control settings, and -+ * setup the device accordingly. If auto-negotiation is enabled, then -+ * software will have to set the "PAUSE" bits to the correct value in -+ * the Transmit Config Word Register (TXCW) and re-start auto- -+ * negotiation. However, if auto-negotiation is disabled, then -+ * software will have to manually configure the two flow control enable -+ * bits in the CTRL register. -+ * -+ * The possible values of the "fc" parameter are: -+ * 0: Flow control is completely disabled -+ * 1: Rx flow control is enabled (we can receive pause frames, -+ * but not send pause frames). -+ * 2: Tx flow control is enabled (we can send pause frames but we -+ * do not support receiving pause frames). -+ * 3: Both Rx and TX flow control (symmetric) are enabled. ++ /* ++ * save CTRL_EXT to restore later, reuse an empty variable (unused ++ * on mac_type 80003es2lan) + */ -+ switch (mac->fc) { -+ case e1000_fc_none: -+ /* Flow control completely disabled by a software over-ride. */ -+ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); -+ break; -+ case e1000_fc_rx_pause: -+ /* RX Flow control is enabled and TX Flow control is disabled -+ * by a software over-ride. Since there really isn't a way to -+ * advertise that we are capable of RX Pause ONLY, we will -+ * advertise that we support both symmetric and asymmetric RX -+ * PAUSE. Later, we will disable the adapter's ability to send -+ * PAUSE frames. -+ */ -+ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); -+ break; -+ case e1000_fc_tx_pause: -+ /* TX Flow control is enabled, and RX Flow control is disabled, -+ * by a software over-ride. -+ */ -+ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); -+ break; -+ case e1000_fc_full: -+ /* Flow control (both RX and TX) is enabled by a software -+ * over-ride. -+ */ -+ txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); -+ break; -+ default: -+ hw_dbg(hw, "Flow control param set incorrectly\n"); -+ return -E1000_ERR_CONFIG; -+ break; -+ } ++ adapter->tx_fifo_head = ctrlext; + -+ ew32(TXCW, txcw); -+ mac->txcw = txcw; ++ /* clear the serdes mode bits, putting the device into mac loopback */ ++ ctrlext &= ~E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES; ++ ew32(CTRL_EXT, ctrlext); ++ ++ /* force speed to 1000/FD, link up */ ++ ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); ++ ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | ++ E1000_CTRL_SPD_1000 | E1000_CTRL_FD); ++ ew32(CTRL, ctrl); ++ ++ /* set mac loopback */ ++ ctrl = er32(RCTL); ++ ctrl |= E1000_RCTL_LBM_MAC; ++ ew32(RCTL, ctrl); ++ ++ /* set testing mode parameters (no need to reset later) */ ++#define KMRNCTRLSTA_OPMODE (0x1F << 16) ++#define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582 ++ ew32(KMRNCTRLSTA, ++ (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII)); + + return 0; +} + -+/** -+ * e1000_poll_fiber_serdes_link_generic - Poll for link up -+ * @hw: pointer to the HW structure -+ * -+ * Polls for link up by reading the status register, if link fails to come -+ * up with auto-negotiation, then the link is forced if a signal is detected. -+ **/ -+static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) ++static int e1000_setup_loopback_test(struct e1000_adapter *adapter) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 i, status; -+ s32 ret_val; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 rctl; + -+ /* If we have a signal (the cable is plugged in, or assumed true for -+ * serdes media) then poll for a "Link-Up" indication in the Device -+ * Status Register. Time-out if a link isn't seen in 500 milliseconds -+ * seconds (Auto-negotiation should complete in less than 500 -+ * milliseconds even if the other end is doing it in SW). -+ */ -+ for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { -+ msleep(10); -+ status = er32(STATUS); -+ if (status & E1000_STATUS_LU) ++ if (hw->phy.media_type == e1000_media_type_fiber || ++ hw->phy.media_type == e1000_media_type_internal_serdes) { ++ switch (hw->mac.type) { ++ case e1000_80003es2lan: ++ return e1000_set_es2lan_mac_loopback(adapter); + break; -+ } -+ if (i == FIBER_LINK_UP_LIMIT) { -+ hw_dbg(hw, "Never got a valid link from auto-neg!!!\n"); -+ mac->autoneg_failed = 1; -+ /* AutoNeg failed to achieve a link, so we'll call -+ * mac->check_for_link. This routine will force the -+ * link up if we detect a signal. This will allow us to -+ * communicate with non-autonegotiating link partners. -+ */ -+ ret_val = mac->ops.check_for_link(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error while checking for link\n"); -+ return ret_val; ++ case e1000_82571: ++ case e1000_82572: ++ return e1000_set_82571_fiber_loopback(adapter); ++ break; ++ default: ++ rctl = er32(RCTL); ++ rctl |= E1000_RCTL_LBM_TCVR; ++ ew32(RCTL, rctl); ++ return 0; + } -+ mac->autoneg_failed = 0; -+ } else { -+ mac->autoneg_failed = 0; -+ hw_dbg(hw, "Valid Link Found\n"); ++ } else if (hw->phy.media_type == e1000_media_type_copper) { ++ return e1000_integrated_phy_loopback(adapter); + } + -+ return 0; ++ return 7; +} + -+/** -+ * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes -+ * @hw: pointer to the HW structure -+ * -+ * Configures collision distance and flow control for fiber and serdes -+ * links. Upon successful setup, poll for link. -+ **/ -+s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) ++static void e1000_loopback_cleanup(struct e1000_adapter *adapter) +{ -+ u32 ctrl; -+ s32 ret_val; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 rctl; ++ u16 phy_reg; + -+ ctrl = er32(CTRL); ++ rctl = er32(RCTL); ++ rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); ++ ew32(RCTL, rctl); + -+ /* Take the link out of reset */ -+ ctrl &= ~E1000_CTRL_LRST; ++ switch (hw->mac.type) { ++ case e1000_80003es2lan: ++ if (hw->phy.media_type == e1000_media_type_fiber || ++ hw->phy.media_type == e1000_media_type_internal_serdes) { ++ /* restore CTRL_EXT, stealing space from tx_fifo_head */ ++ ew32(CTRL_EXT, adapter->tx_fifo_head); ++ adapter->tx_fifo_head = 0; ++ } ++ /* fall through */ ++ case e1000_82571: ++ case e1000_82572: ++ if (hw->phy.media_type == e1000_media_type_fiber || ++ hw->phy.media_type == e1000_media_type_internal_serdes) { ++#define E1000_SERDES_LB_OFF 0x400 ++ ew32(SCTL, E1000_SERDES_LB_OFF); ++ msleep(10); ++ break; ++ } ++ /* Fall Through */ ++ default: ++ hw->mac.autoneg = 1; ++ if (hw->phy.type == e1000_phy_gg82563) ++ hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ++ 0x180); ++ if(hw->phy.ops.read_reg) ++ hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_reg); ++ if (phy_reg & MII_CR_LOOPBACK) { ++ phy_reg &= ~MII_CR_LOOPBACK; ++ hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_reg); ++ if (hw->phy.ops.commit) ++ hw->phy.ops.commit(hw); ++ } ++ break; ++ } ++} + -+ e1000e_config_collision_dist(hw); ++static void e1000_create_lbtest_frame(struct sk_buff *skb, ++ unsigned int frame_size) ++{ ++ memset(skb->data, 0xFF, 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); ++} + -+ ret_val = e1000_commit_fc_settings_generic(hw); -+ if (ret_val) -+ return ret_val; ++static int e1000_check_lbtest_frame(struct sk_buff *skb, ++ unsigned int frame_size) ++{ ++ 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; ++ return 13; ++} + -+ /* Since auto-negotiation is enabled, take the link out of reset (the -+ * link will be in reset, because we previously reset the chip). This -+ * will restart auto-negotiation. If auto-negotiation is successful -+ * then the link-up status bit will be set and the flow control enable -+ * bits (RFCE and TFCE) will be set according to their negotiated value. -+ */ -+ hw_dbg(hw, "Auto-negotiation enabled\n"); ++static int e1000_run_loopback_test(struct e1000_adapter *adapter) ++{ ++ struct e1000_ring *tx_ring = &adapter->test_tx_ring; ++ struct e1000_ring *rx_ring = &adapter->test_rx_ring; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_hw *hw = &adapter->hw; ++ int i, j, k, l; ++ int lc; ++ int good_cnt; ++ int ret_val = 0; ++ unsigned long time; + -+ ew32(CTRL, ctrl); -+ e1e_flush(); -+ msleep(1); ++ ew32(RDT(0), rx_ring->count - 1); + -+ /* For these adapters, the SW defineable pin 1 is set when the optics -+ * detect a signal. If we have a signal, then poll for a "Link-Up" -+ * indication. ++ /* ++ * 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 + */ -+ if (hw->media_type == e1000_media_type_internal_serdes || -+ (er32(CTRL) & E1000_CTRL_SWDPIN1)) { -+ ret_val = e1000_poll_fiber_serdes_link_generic(hw); -+ } else { -+ hw_dbg(hw, "No signal detected\n"); -+ } -+ -+ return 0; -+} -+ -+/** -+ * e1000e_config_collision_dist - Configure collision distance -+ * @hw: pointer to the HW structure -+ * -+ * Configures the collision distance to the default value and is used -+ * during link setup. Currently no func pointer exists and all -+ * implementations are handled in the generic version of this function. -+ **/ -+void e1000e_config_collision_dist(struct e1000_hw *hw) -+{ -+ u32 tctl; + -+ tctl = er32(TCTL); ++ if (rx_ring->count <= tx_ring->count) ++ lc = ((tx_ring->count / 64) * 2) + 1; ++ else ++ lc = ((rx_ring->count / 64) * 2) + 1; + -+ tctl &= ~E1000_TCTL_COLD; -+ tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; ++ k = 0; ++ l = 0; ++ for (j = 0; j <= lc; j++) { /* loop count loop */ ++ for (i = 0; i < 64; i++) { /* send the packets */ ++ e1000_create_lbtest_frame(tx_ring->buffer_info[k].skb, ++ 1024); ++ pci_dma_sync_single_for_device(pdev, ++ tx_ring->buffer_info[k].dma, ++ tx_ring->buffer_info[k].length, ++ PCI_DMA_TODEVICE); ++ k++; ++ if (k == tx_ring->count) ++ k = 0; ++ } ++ ew32(TDT(0), k); ++ msleep(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, ++ rx_ring->buffer_info[l].dma, 2048, ++ PCI_DMA_FROMDEVICE); + -+ ew32(TCTL, tctl); -+ e1e_flush(); ++ ret_val = e1000_check_lbtest_frame( ++ rx_ring->buffer_info[l].skb, 1024); ++ if (!ret_val) ++ good_cnt++; ++ l++; ++ if (l == rx_ring->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) && !time_after(jiffies, time + 20)); ++ if (good_cnt != 64) { ++ ret_val = 13; /* ret_val is the same as mis-compare */ ++ break; ++ } ++ if (jiffies >= (time + 20)) { ++ ret_val = 14; /* error code for time out error */ ++ break; ++ } ++ } /* end loop count loop */ ++ return ret_val; +} + -+/** -+ * e1000e_set_fc_watermarks - Set flow control high/low watermarks -+ * @hw: pointer to the HW structure -+ * -+ * Sets the flow control high/low threshold (watermark) registers. If -+ * flow control XON frame transmission is enabled, then set XON frame -+ * tansmission as well. -+ **/ -+s32 e1000e_set_fc_watermarks(struct e1000_hw *hw) ++static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 fcrtl = 0, fcrth = 0; -+ -+ /* Set the flow control receive threshold registers. Normally, -+ * these registers will be set to a default threshold that may be -+ * adjusted later by the driver's runtime code. However, if the -+ * ability to transmit pause frames is not enabled, then these -+ * registers will be set to 0. ++ struct e1000_hw *hw = &adapter->hw; ++ /* ++ * PHY loopback cannot be performed if SoL/IDER ++ * sessions are active + */ -+ if (mac->fc & e1000_fc_tx_pause) { -+ /* We need to set up the Receive Threshold high and low water -+ * marks as well as (optionally) enabling the transmission of -+ * XON frames. -+ */ -+ fcrtl = mac->fc_low_water; -+ fcrtl |= E1000_FCRTL_XONE; -+ fcrth = mac->fc_high_water; ++ if (hw->phy.ops.check_reset_block && ++ hw->phy.ops.check_reset_block(&adapter->hw)) { ++ e_err("Cannot do PHY loopback test when SoL/IDER is active.\n"); ++ *data = 0; ++ goto out; + } -+ ew32(FCRTL, fcrtl); -+ ew32(FCRTH, fcrth); -+ -+ return 0; -+} -+ -+/** -+ * e1000e_force_mac_fc - Force the MAC's flow control settings -+ * @hw: pointer to the HW structure -+ * -+ * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the -+ * device control register to reflect the adapter settings. TFCE and RFCE -+ * need to be explicitly set by software when a copper PHY is used because -+ * autonegotiation is managed by the PHY rather than the MAC. Software must -+ * also configure these bits when link is forced on a fiber connection. -+ **/ -+s32 e1000e_force_mac_fc(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 ctrl; -+ -+ ctrl = er32(CTRL); + -+ /* Because we didn't get link via the internal auto-negotiation -+ * mechanism (we either forced link or we got link via PHY -+ * auto-neg), we have to manually enable/disable transmit an -+ * receive flow control. -+ * -+ * The "Case" statement below enables/disable flow control -+ * according to the "mac->fc" parameter. -+ * -+ * The possible values of the "fc" parameter are: -+ * 0: Flow control is completely disabled -+ * 1: Rx flow control is enabled (we can receive pause -+ * frames but not send pause frames). -+ * 2: Tx flow control is enabled (we can send pause frames -+ * frames but we do not receive pause frames). -+ * 3: Both Rx and TX flow control (symmetric) is enabled. -+ * other: No other values should be possible at this point. -+ */ -+ hw_dbg(hw, "mac->fc = %u\n", mac->fc); ++ *data = e1000_setup_desc_rings(adapter); ++ if (*data) ++ goto out; + -+ switch (mac->fc) { -+ case e1000_fc_none: -+ ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); -+ break; -+ case e1000_fc_rx_pause: -+ ctrl &= (~E1000_CTRL_TFCE); -+ ctrl |= E1000_CTRL_RFCE; -+ break; -+ case e1000_fc_tx_pause: -+ ctrl &= (~E1000_CTRL_RFCE); -+ ctrl |= E1000_CTRL_TFCE; -+ break; -+ case e1000_fc_full: -+ ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); -+ break; -+ default: -+ hw_dbg(hw, "Flow control param set incorrectly\n"); -+ return -E1000_ERR_CONFIG; -+ } ++ *data = e1000_setup_loopback_test(adapter); ++ if (*data) ++ goto err_loopback; + -+ ew32(CTRL, ctrl); ++ *data = e1000_run_loopback_test(adapter); ++ e1000_loopback_cleanup(adapter); + -+ return 0; ++err_loopback: ++ e1000_free_desc_rings(adapter); ++out: ++ return *data; +} + -+/** -+ * e1000e_config_fc_after_link_up - Configures flow control after link -+ * @hw: pointer to the HW structure -+ * -+ * Checks the status of auto-negotiation after link up to ensure that the -+ * speed and duplex were not forced. If the link needed to be forced, then -+ * flow control needs to be forced also. If auto-negotiation is enabled -+ * and did not fail, then we configure flow control based on our link -+ * partner. -+ **/ -+s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) ++static int e1000_link_test(struct e1000_adapter *adapter, u64 *data) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val = 0; -+ u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; -+ u16 speed, duplex; ++ struct e1000_hw *hw = &adapter->hw; + -+ /* Check for the case where we have fiber media and auto-neg failed -+ * so we had to force link. In this case, we need to force the -+ * configuration of the MAC to match the "fc" parameter. -+ */ -+ if (mac->autoneg_failed) { -+ if (hw->media_type == e1000_media_type_fiber || -+ hw->media_type == e1000_media_type_internal_serdes) -+ ret_val = e1000e_force_mac_fc(hw); ++ *data = 0; ++ if (hw->phy.media_type == e1000_media_type_internal_serdes) { ++ int i = 0; ++ hw->mac.serdes_has_link = 0; ++ ++ /* ++ * On some blade server designs, link establishment ++ * could take as long as 2-3 minutes ++ */ ++ do { ++ hw->mac.ops.check_for_link(hw); ++ if (hw->mac.serdes_has_link) ++ return *data; ++ msleep(20); ++ } while (i++ < 3750); ++ ++ *data = 1; + } else { -+ if (hw->media_type == e1000_media_type_copper) -+ ret_val = e1000e_force_mac_fc(hw); -+ } ++ hw->mac.ops.check_for_link(hw); ++ if (hw->mac.autoneg) ++ msleep(4000); + -+ if (ret_val) { -+ hw_dbg(hw, "Error forcing flow control settings\n"); -+ return ret_val; ++ if (!(er32(STATUS) & ++ E1000_STATUS_LU)) ++ *data = 1; + } ++ return *data; ++} + -+ /* Check for the case where we have copper media and auto-neg is -+ * enabled. In this case, we need to check and see if Auto-Neg -+ * has completed, and if so, how the PHY and link partner has -+ * flow control configured. -+ */ -+ if ((hw->media_type == e1000_media_type_copper) && mac->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 = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); -+ if (ret_val) -+ return ret_val; ++static int e1000_get_self_test_count(struct net_device *netdev) ++{ ++ return E1000_TEST_LEN; ++} + -+ if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { -+ hw_dbg(hw, "Copper PHY and Auto Neg " -+ "has not completed.\n"); -+ return ret_val; -+ } ++static int e1000_get_stats_count(struct net_device *netdev) ++{ ++ return E1000_STATS_LEN; ++} + -+ /* 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 Register (Address 5) to determine how -+ * flow control was negotiated. -+ */ -+ ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); -+ if (ret_val) -+ return ret_val; ++static void e1000_diag_test(struct net_device *netdev, ++ struct ethtool_test *eth_test, u64 *data) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ u16 autoneg_advertised; ++ u8 forced_speed_duplex; ++ u8 autoneg; ++ bool if_running = netif_running(netdev); + -+ /* Two bits in the Auto Negotiation Advertisement Register -+ * (Address 4) and two bits in the Auto Negotiation Base -+ * Page Ability Register (Address 5) determine flow control -+ * for both the PHY and the link partner. The following -+ * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, -+ * 1999, describes these PAUSE resolution bits and how flow -+ * control is determined based upon these settings. -+ * NOTE: DC = Don't Care -+ * -+ * LOCAL DEVICE | LINK PARTNER -+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution -+ *-------|---------|-------|---------|-------------------- -+ * 0 | 0 | DC | DC | e1000_fc_none -+ * 0 | 1 | 0 | DC | e1000_fc_none -+ * 0 | 1 | 1 | 0 | e1000_fc_none -+ * 0 | 1 | 1 | 1 | e1000_fc_tx_pause -+ * 1 | 0 | 0 | DC | e1000_fc_none -+ * 1 | DC | 1 | DC | e1000_fc_full -+ * 1 | 1 | 0 | 0 | e1000_fc_none -+ * 1 | 1 | 0 | 1 | e1000_fc_rx_pause -+ * -+ */ -+ /* Are both PAUSE bits set to 1? If so, this implies -+ * Symmetric Flow Control is enabled at both ends. The -+ * ASM_DIR bits are irrelevant per the spec. -+ * -+ * For Symmetric Flow Control: -+ * -+ * LOCAL DEVICE | LINK PARTNER -+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result -+ *-------|---------|-------|---------|-------------------- -+ * 1 | DC | 1 | DC | E1000_fc_full -+ * -+ */ -+ 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 (mac->original_fc == e1000_fc_full) { -+ mac->fc = e1000_fc_full; -+ hw_dbg(hw, "Flow Control = FULL.\r\n"); -+ } else { -+ mac->fc = e1000_fc_rx_pause; -+ hw_dbg(hw, "Flow Control = " -+ "RX PAUSE frames only.\r\n"); -+ } -+ } -+ /* For receiving PAUSE frames ONLY. -+ * -+ * LOCAL DEVICE | LINK PARTNER -+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result -+ *-------|---------|-------|---------|-------------------- -+ * 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)) { -+ mac->fc = e1000_fc_tx_pause; -+ hw_dbg(hw, "Flow Control = TX PAUSE frames only.\r\n"); -+ } -+ /* For transmitting PAUSE frames ONLY. -+ * -+ * LOCAL DEVICE | LINK PARTNER -+ * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result -+ *-------|---------|-------|---------|-------------------- -+ * 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)) { -+ mac->fc = e1000_fc_rx_pause; -+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); -+ } -+ /* Per the IEEE spec, at this point flow control should be -+ * disabled. However, we want to consider that we could -+ * be connected to a legacy switch that doesn't advertise -+ * desired flow control, but can be forced on the link -+ * partner. So if we advertised no flow control, that is -+ * what we will resolve to. If we advertised some kind of -+ * receive capability (Rx Pause Only or Full Flow Control) -+ * and the link partner advertised none, we will configure -+ * ourselves to enable Rx Flow Control only. We can do -+ * this safely for two reasons: If the link partner really -+ * didn't want flow control enabled, and we enable Rx, no -+ * harm done since we won't be receiving any PAUSE frames -+ * anyway. If the intent on the link partner was to have -+ * flow control enabled, then by us enabling RX only, we -+ * can at least receive pause frames and process them. -+ * This is a good idea because in most cases, since we are -+ * predominantly a server NIC, more times than not we will -+ * be asked to delay transmission of packets than asking -+ * our link partner to pause transmission of frames. -+ */ -+ else if ((mac->original_fc == e1000_fc_none) || -+ (mac->original_fc == e1000_fc_tx_pause)) { -+ mac->fc = e1000_fc_none; -+ hw_dbg(hw, "Flow Control = NONE.\r\n"); -+ } else { -+ mac->fc = e1000_fc_rx_pause; -+ hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n"); -+ } ++ set_bit(__E1000_TESTING, &adapter->state); ++ if (eth_test->flags == ETH_TEST_FL_OFFLINE) { ++ /* Offline tests */ + -+ /* Now we need to do one last check... If we auto- -+ * negotiated to HALF DUPLEX, flow control should not be -+ * enabled per IEEE 802.3 spec. -+ */ -+ ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); -+ if (ret_val) { -+ hw_dbg(hw, "Error getting link speed and duplex\n"); -+ return ret_val; -+ } ++ /* save speed, duplex, autoneg settings */ ++ autoneg_advertised = adapter->hw.phy.autoneg_advertised; ++ forced_speed_duplex = adapter->hw.mac.forced_speed_duplex; ++ autoneg = adapter->hw.mac.autoneg; + -+ if (duplex == HALF_DUPLEX) -+ mac->fc = e1000_fc_none; ++ e_info("offline testing starting\n"); + -+ /* Now we call a subroutine to actually force the MAC -+ * controller to use the correct flow control settings. ++ /* ++ * Link test performed before hardware reset so autoneg doesn't ++ * interfere with test result + */ -+ ret_val = e1000e_force_mac_fc(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error forcing flow control settings\n"); -+ return ret_val; -+ } -+ } ++ if (e1000_link_test(adapter, &data[4])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+ return 0; -+} ++ if (if_running) ++ /* indicate we're in test mode */ ++ dev_close(netdev); ++ else ++ e1000_reset(adapter); + -+/** -+ * e1000e_get_speed_and_duplex_copper - Retreive current speed/duplex -+ * @hw: pointer to the HW structure -+ * @speed: stores the current speed -+ * @duplex: stores the current duplex -+ * -+ * Read the status register for the current speed/duplex and store the current -+ * speed and duplex for copper connections. -+ **/ -+s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex) -+{ -+ u32 status; ++ if (e1000_reg_test(adapter, &data[0])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+ status = er32(STATUS); -+ if (status & E1000_STATUS_SPEED_1000) { -+ *speed = SPEED_1000; -+ hw_dbg(hw, "1000 Mbs, "); -+ } else if (status & E1000_STATUS_SPEED_100) { -+ *speed = SPEED_100; -+ hw_dbg(hw, "100 Mbs, "); -+ } else { -+ *speed = SPEED_10; -+ hw_dbg(hw, "10 Mbs, "); -+ } ++ e1000_reset(adapter); ++ if (e1000_eeprom_test(adapter, &data[1])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+ if (status & E1000_STATUS_FD) { -+ *duplex = FULL_DUPLEX; -+ hw_dbg(hw, "Full Duplex\n"); -+ } else { -+ *duplex = HALF_DUPLEX; -+ hw_dbg(hw, "Half Duplex\n"); -+ } ++ e1000_reset(adapter); ++ if (e1000_intr_test(adapter, &data[2])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+ return 0; -+} ++ e1000_reset(adapter); ++ /* make sure the phy is powered up */ ++ e1000_power_up_phy(&adapter->hw); ++ if (e1000_loopback_test(adapter, &data[3])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+/** -+ * e1000e_get_speed_and_duplex_fiber_serdes - Retreive current speed/duplex -+ * @hw: pointer to the HW structure -+ * @speed: stores the current speed -+ * @duplex: stores the current duplex -+ * -+ * Sets the speed and duplex to gigabit full duplex (the only possible option) -+ * for fiber/serdes links. -+ **/ -+s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex) -+{ -+ *speed = SPEED_1000; -+ *duplex = FULL_DUPLEX; ++ /* restore speed, duplex, autoneg settings */ ++ adapter->hw.phy.autoneg_advertised = autoneg_advertised; ++ adapter->hw.mac.forced_speed_duplex = forced_speed_duplex; ++ adapter->hw.mac.autoneg = autoneg; + -+ return 0; -+} ++ /* force this routine to wait until autoneg complete/timeout */ ++ adapter->hw.phy.autoneg_wait_to_complete = 1; ++ e1000_reset(adapter); ++ adapter->hw.phy.autoneg_wait_to_complete = 0; + -+/** -+ * e1000e_get_hw_semaphore - Acquire hardware semaphore -+ * @hw: pointer to the HW structure -+ * -+ * Acquire the HW semaphore to access the PHY or NVM -+ **/ -+s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) -+{ -+ u32 swsm; -+ s32 timeout = hw->nvm.word_size + 1; -+ s32 i = 0; ++ clear_bit(__E1000_TESTING, &adapter->state); ++ if (if_running) ++ dev_open(netdev); ++ } else { ++ e_info("online testing starting\n"); ++ /* Online tests */ ++ if (e1000_link_test(adapter, &data[4])) ++ eth_test->flags |= ETH_TEST_FL_FAILED; + -+ /* Get the SW semaphore */ -+ while (i < timeout) { -+ swsm = er32(SWSM); -+ if (!(swsm & E1000_SWSM_SMBI)) -+ break; ++ /* Online tests aren't run; pass by default */ ++ data[0] = 0; ++ data[1] = 0; ++ data[2] = 0; ++ data[3] = 0; + -+ udelay(50); -+ i++; ++ clear_bit(__E1000_TESTING, &adapter->state); + } ++ msleep_interruptible(4 * 1000); ++} + -+ if (i == timeout) { -+ hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n"); -+ return -E1000_ERR_NVM; -+ } ++static void e1000_get_wol(struct net_device *netdev, ++ struct ethtool_wolinfo *wol) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ /* Get the FW semaphore. */ -+ for (i = 0; i < timeout; i++) { -+ swsm = er32(SWSM); -+ ew32(SWSM, swsm | E1000_SWSM_SWESMBI); ++ wol->supported = 0; ++ wol->wolopts = 0; + -+ /* Semaphore acquired if bit latched */ -+ if (er32(SWSM) & E1000_SWSM_SWESMBI) -+ break; ++ if (!(adapter->flags & FLAG_HAS_WOL)) ++ return; + -+ udelay(50); -+ } ++ wol->supported = WAKE_UCAST | WAKE_MCAST | ++ WAKE_BCAST | WAKE_MAGIC | ++ WAKE_PHY | WAKE_ARP; + -+ if (i == timeout) { -+ /* Release semaphores */ -+ e1000e_put_hw_semaphore(hw); -+ hw_dbg(hw, "Driver can't access the NVM\n"); -+ return -E1000_ERR_NVM; ++ /* apply any specific unsupported masks here */ ++ if (adapter->flags & FLAG_NO_WAKE_UCAST) { ++ wol->supported &= ~WAKE_UCAST; ++ ++ if (adapter->wol & E1000_WUFC_EX) ++ e_err("Interface does not support directed (unicast)" ++ " frame wake-up packets\n"); + } + -+ return 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; ++ if (adapter->wol & E1000_WUFC_LNKC) ++ wol->wolopts |= WAKE_PHY; ++ if (adapter->wol & E1000_WUFC_ARP) ++ wol->wolopts |= WAKE_ARP; +} + -+/** -+ * e1000e_put_hw_semaphore - Release hardware semaphore -+ * @hw: pointer to the HW structure -+ * -+ * Release hardware semaphore used to access the PHY or NVM -+ **/ -+void e1000e_put_hw_semaphore(struct e1000_hw *hw) ++static int e1000_set_wol(struct net_device *netdev, ++ struct ethtool_wolinfo *wol) +{ -+ u32 swsm; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ swsm = er32(SWSM); -+ swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); -+ ew32(SWSM, swsm); -+} ++ if (wol->wolopts & WAKE_MAGICSECURE) ++ return -EOPNOTSUPP; + -+/** -+ * e1000e_get_auto_rd_done - Check for auto read completion -+ * @hw: pointer to the HW structure -+ * -+ * Check EEPROM for Auto Read done bit. -+ **/ -+s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) -+{ -+ s32 i = 0; ++ if (!(adapter->flags & FLAG_HAS_WOL)) ++ return wol->wolopts ? -EOPNOTSUPP : 0; + -+ while (i < AUTO_READ_DONE_TIMEOUT) { -+ if (er32(EECD) & E1000_EECD_AUTO_RD) -+ break; -+ msleep(1); -+ i++; -+ } ++ /* these settings will always override what we currently have */ ++ adapter->wol = 0; + -+ if (i == AUTO_READ_DONE_TIMEOUT) { -+ hw_dbg(hw, "Auto read by HW from NVM has not completed.\n"); -+ return -E1000_ERR_RESET; -+ } ++ 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_PHY) ++ adapter->wol |= E1000_WUFC_LNKC; ++ if (wol->wolopts & WAKE_ARP) ++ adapter->wol |= E1000_WUFC_ARP; + + return 0; +} + -+/** -+ * e1000e_valid_led_default - Verify a valid default LED config -+ * @hw: pointer to the HW structure -+ * @data: pointer to the NVM (EEPROM) -+ * -+ * Read the EEPROM for the current default LED configuration. If the -+ * LED configuration is not valid, set to a valid LED configuration. -+ **/ -+s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data) -+{ -+ s32 ret_val; ++/* toggle LED 4 times per second = 2 "blinks" per second */ ++#define E1000_ID_INTERVAL (HZ/4) + -+ ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; -+ } ++/* bit defines for adapter->led_status */ ++#define E1000_LED_ON 0 + -+ if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) -+ *data = ID_LED_DEFAULT; ++static void e1000_led_blink_callback(unsigned long data) ++{ ++ struct e1000_adapter *adapter = (struct e1000_adapter *) data; + -+ return 0; ++ if (test_and_change_bit(E1000_LED_ON, &adapter->led_status)) ++ adapter->hw.mac.ops.led_off(&adapter->hw); ++ else ++ adapter->hw.mac.ops.led_on(&adapter->hw); ++ ++ mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL); +} + -+/** -+ * e1000e_id_led_init - -+ * @hw: pointer to the HW structure -+ * -+ **/ -+s32 e1000e_id_led_init(struct e1000_hw *hw) ++static int e1000_phys_id(struct net_device *netdev, u32 data) +{ -+ struct e1000_mac_info *mac = &hw->mac; -+ s32 ret_val; -+ const u32 ledctl_mask = 0x000000FF; -+ const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; -+ const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; -+ u16 data, i, temp; -+ const u16 led_mask = 0x0F; -+ -+ ret_val = hw->nvm.ops.valid_led_default(hw, &data); -+ if (ret_val) -+ return ret_val; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ mac->ledctl_default = er32(LEDCTL); -+ mac->ledctl_mode1 = mac->ledctl_default; -+ mac->ledctl_mode2 = mac->ledctl_default; ++ if (!data) ++ data = INT_MAX; + -+ for (i = 0; i < 4; i++) { -+ temp = (data >> (i << 2)) & led_mask; -+ switch (temp) { -+ case ID_LED_ON1_DEF2: -+ case ID_LED_ON1_ON2: -+ case ID_LED_ON1_OFF2: -+ mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); -+ mac->ledctl_mode1 |= ledctl_on << (i << 3); -+ break; -+ case ID_LED_OFF1_DEF2: -+ case ID_LED_OFF1_ON2: -+ case ID_LED_OFF1_OFF2: -+ mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); -+ mac->ledctl_mode1 |= ledctl_off << (i << 3); -+ break; -+ default: -+ /* Do nothing */ -+ break; -+ } -+ switch (temp) { -+ case ID_LED_DEF1_ON2: -+ case ID_LED_ON1_ON2: -+ case ID_LED_OFF1_ON2: -+ mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); -+ mac->ledctl_mode2 |= ledctl_on << (i << 3); -+ break; -+ case ID_LED_DEF1_OFF2: -+ case ID_LED_ON1_OFF2: -+ case ID_LED_OFF1_OFF2: -+ mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); -+ mac->ledctl_mode2 |= ledctl_off << (i << 3); -+ break; -+ default: -+ /* Do nothing */ -+ break; ++ if ((hw->phy.type == e1000_phy_ife) || ++ (hw->mac.type == e1000_82574)) { ++ 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); ++ if (hw->phy.type == e1000_phy_ife) ++ hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, ++ 0); ++ } else { ++ hw->mac.ops.blink_led(hw); ++ msleep_interruptible(data * 1000); + } + -+ return 0; -+} ++ hw->mac.ops.led_off(hw); ++ clear_bit(E1000_LED_ON, &adapter->led_status); ++ hw->mac.ops.cleanup_led(hw); + -+/** -+ * e1000e_cleanup_led_generic - Set LED config to default operation -+ * @hw: pointer to the HW structure -+ * -+ * Remove the current LED configuration and set the LED configuration -+ * to the default value, saved from the EEPROM. -+ **/ -+s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) -+{ -+ ew32(LEDCTL, hw->mac.ledctl_default); + return 0; +} + -+/** -+ * e1000e_blink_led - Blink LED -+ * @hw: pointer to the HW structure -+ * -+ * Blink the led's which are set to be on. -+ **/ -+s32 e1000e_blink_led(struct e1000_hw *hw) ++static int e1000_get_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *ec) +{ -+ u32 ledctl_blink = 0; -+ u32 i; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ 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->mac.ledctl_mode2; -+ for (i = 0; i < 4; i++) -+ if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == -+ E1000_LEDCTL_MODE_LED_ON) -+ ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << -+ (i * 8)); -+ } ++ if (adapter->itr_setting <= 3) ++ ec->rx_coalesce_usecs = adapter->itr_setting; ++ else ++ ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting; + -+ ew32(LEDCTL, ledctl_blink); ++ ec->stats_block_coalesce_usecs = adapter->stats_freq_us; + + return 0; +} + -+/** -+ * e1000e_led_on_generic - Turn LED on -+ * @hw: pointer to the HW structure -+ * -+ * Turn LED on. -+ **/ -+s32 e1000e_led_on_generic(struct e1000_hw *hw) ++static int e1000_set_coalesce(struct net_device *netdev, ++ struct ethtool_coalesce *ec) +{ -+ u32 ctrl; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ switch (hw->media_type) { -+ case e1000_media_type_fiber: -+ ctrl = er32(CTRL); -+ ctrl &= ~E1000_CTRL_SWDPIN0; -+ ctrl |= E1000_CTRL_SWDPIO0; -+ ew32(CTRL, ctrl); -+ break; -+ case e1000_media_type_copper: -+ ew32(LEDCTL, hw->mac.ledctl_mode2); -+ break; -+ default: -+ break; ++ if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) || ++ ((ec->rx_coalesce_usecs > 3) && ++ (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) || ++ (ec->rx_coalesce_usecs == 2) || ++ (ec->stats_block_coalesce_usecs > (10 * 1000000))) ++ return -EINVAL; ++ ++ adapter->stats_freq_us = ec->stats_block_coalesce_usecs; ++ ++ if (ec->rx_coalesce_usecs <= 3) { ++ adapter->itr = 20000; ++ adapter->itr_setting = ec->rx_coalesce_usecs; ++ } else { ++ adapter->itr = (1000000 / ec->rx_coalesce_usecs); ++ adapter->itr_setting = adapter->itr & ~3; + } + ++ if (adapter->itr_setting != 0) ++ ew32(ITR, 1000000000 / (adapter->itr * 256)); ++ else ++ ew32(ITR, 0); ++ + return 0; +} + -+/** -+ * e1000e_led_off_generic - Turn LED off -+ * @hw: pointer to the HW structure -+ * -+ * Turn LED off. -+ **/ -+s32 e1000e_led_off_generic(struct e1000_hw *hw) ++static int e1000_nway_reset(struct net_device *netdev) +{ -+ u32 ctrl; -+ -+ switch (hw->media_type) { -+ case e1000_media_type_fiber: -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_SWDPIN0; -+ ctrl |= E1000_CTRL_SWDPIO0; -+ ew32(CTRL, ctrl); -+ break; -+ case e1000_media_type_copper: -+ ew32(LEDCTL, hw->mac.ledctl_mode1); -+ break; -+ default: -+ break; -+ } -+ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ if (netif_running(netdev)) ++ e1000_reinit_locked(adapter); + return 0; +} + -+/** -+ * e1000e_set_pcie_no_snoop - Set PCI-express capabilities -+ * @hw: pointer to the HW structure -+ * @no_snoop: bitmap of snoop events -+ * -+ * Set the PCI-express register to snoop for events enabled in 'no_snoop'. -+ **/ -+void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) ++static void e1000_get_ethtool_stats(struct net_device *netdev, ++ struct ethtool_stats *stats, ++ u64 *data) +{ -+ u32 gcr; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ int i; + -+ if (no_snoop) { -+ gcr = er32(GCR); -+ gcr &= ~(PCIE_NO_SNOOP_ALL); -+ gcr |= no_snoop; -+ ew32(GCR, gcr); ++ e1000_update_stats(adapter); ++ 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(u64)) ? *(u64 *)p : *(u32 *)p; + } +} + -+/** -+ * e1000e_disable_pcie_master - Disables PCI-express master access -+ * @hw: pointer to the HW structure -+ * -+ * Returns 0 if successful, else returns -10 -+ * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not casued -+ * the master requests to be disabled. -+ * -+ * Disables PCI-Express master access and verifies there are no pending -+ * requests. -+ **/ -+s32 e1000e_disable_pcie_master(struct e1000_hw *hw) ++static void e1000_get_strings(struct net_device *netdev, u32 stringset, ++ u8 *data) +{ -+ u32 ctrl; -+ s32 timeout = MASTER_DISABLE_TIMEOUT; -+ -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; -+ ew32(CTRL, ctrl); ++ u8 *p = data; ++ int i; + -+ while (timeout) { -+ if (!(er32(STATUS) & -+ E1000_STATUS_GIO_MASTER_ENABLE)) -+ break; -+ udelay(100); -+ timeout--; ++ switch (stringset) { ++ case ETH_SS_TEST: ++ memcpy(data, *e1000_gstrings_test, sizeof(e1000_gstrings_test)); ++ break; ++ case ETH_SS_STATS: ++ for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { ++ memcpy(p, e1000_gstrings_stats[i].stat_string, ++ ETH_GSTRING_LEN); ++ p += ETH_GSTRING_LEN; ++ } ++ break; + } ++} + -+ if (!timeout) { -+ hw_dbg(hw, "Master requests are pending.\n"); -+ return -E1000_ERR_MASTER_REQUESTS_PENDING; -+ } ++static const struct ethtool_ops e1000_ethtool_ops = { ++ .get_settings = e1000_get_settings, ++ .set_settings = e1000_set_settings, ++ .get_drvinfo = e1000_get_drvinfo, ++ .get_regs_len = e1000_get_regs_len, ++ .get_regs = e1000_get_regs, ++ .get_wol = e1000_get_wol, ++ .set_wol = e1000_set_wol, ++ .get_msglevel = e1000_get_msglevel, ++ .set_msglevel = e1000_set_msglevel, ++ .nway_reset = e1000_nway_reset, ++ .get_link = e1000_get_link, ++ .get_eeprom_len = e1000_get_eeprom_len, ++ .get_eeprom = e1000_get_eeprom, ++ .set_eeprom = e1000_set_eeprom, ++ .get_ringparam = e1000_get_ringparam, ++ .set_ringparam = e1000_set_ringparam, ++ .get_pauseparam = e1000_get_pauseparam, ++ .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, ++ .set_tx_csum = e1000_set_tx_csum, ++ .get_sg = ethtool_op_get_sg, ++ .set_sg = ethtool_op_set_sg, ++#ifdef NETIF_F_TSO ++ .get_tso = ethtool_op_get_tso, ++ .set_tso = e1000_set_tso, ++#endif ++ .self_test = e1000_diag_test, ++ .get_strings = e1000_get_strings, ++ .phys_id = e1000_phys_id, ++ .get_ethtool_stats = e1000_get_ethtool_stats, ++ .self_test_count = e1000_get_self_test_count, ++ .get_stats_count = e1000_get_stats_count, ++ .get_coalesce = e1000_get_coalesce, ++ .set_coalesce = e1000_set_coalesce, ++}; + -+ return 0; ++void e1000_set_ethtool_ops(struct net_device *netdev) ++{ ++ /* have to "undeclare" const on this struct to remove warnings */ ++ SET_ETHTOOL_OPS(netdev, (struct ethtool_ops *)&e1000_ethtool_ops); +} ++#endif /* SIOCETHTOOL */ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/kcompat.c linux-2.6.22-10/drivers/net/e1000e/kcompat.c +--- linux-2.6.22-0/drivers/net/e1000e/kcompat.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/kcompat.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,318 @@ ++/******************************************************************************* + -+/** -+ * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing -+ * @hw: pointer to the HW structure -+ * -+ * Reset the Adaptive Interframe Spacing throttle to default values. -+ **/ -+void e1000e_reset_adaptive(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ mac->current_ifs_val = 0; -+ mac->ifs_min_val = IFS_MIN; -+ mac->ifs_max_val = IFS_MAX; -+ mac->ifs_step_size = IFS_STEP; -+ mac->ifs_ratio = IFS_RATIO; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ mac->in_ifs_mode = 0; -+ ew32(AIT, 0); -+} ++ This program is distributed in the hope 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. + -+/** -+ * e1000e_update_adaptive - Update Adaptive Interframe Spacing -+ * @hw: pointer to the HW structure -+ * -+ * Update the Adaptive Interframe Spacing Throttle value based on the -+ * time between transmitted packets and time between collisions. -+ **/ -+void e1000e_update_adaptive(struct e1000_hw *hw) -+{ -+ struct e1000_mac_info *mac = &hw->mac; ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { -+ if (mac->tx_packet_delta > MIN_NUM_XMITS) { -+ mac->in_ifs_mode = 1; -+ if (mac->current_ifs_val < mac->ifs_max_val) { -+ if (!mac->current_ifs_val) -+ mac->current_ifs_val = mac->ifs_min_val; -+ else -+ mac->current_ifs_val += -+ mac->ifs_step_size; -+ ew32(AIT, -+ mac->current_ifs_val); -+ } -+ } -+ } else { -+ if (mac->in_ifs_mode && -+ (mac->tx_packet_delta <= MIN_NUM_XMITS)) { -+ mac->current_ifs_val = 0; -+ mac->in_ifs_mode = 0; -+ ew32(AIT, 0); -+ } -+ } -+} ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+/** -+ * e1000_raise_eec_clk - Raise EEPROM clock -+ * @hw: pointer to the HW structure -+ * @eecd: pointer to the EEPROM -+ * -+ * Enable/Raise the EEPROM clock bit. -+ **/ -+static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) -+{ -+ *eecd = *eecd | E1000_EECD_SK; -+ ew32(EECD, *eecd); -+ e1e_flush(); -+ udelay(hw->nvm.delay_usec); -+} ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+/** -+ * e1000_lower_eec_clk - Lower EEPROM clock -+ * @hw: pointer to the HW structure -+ * @eecd: pointer to the EEPROM -+ * -+ * Clear/Lower the EEPROM clock bit. -+ **/ -+static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) -+{ -+ *eecd = *eecd & ~E1000_EECD_SK; -+ ew32(EECD, *eecd); -+ e1e_flush(); -+ udelay(hw->nvm.delay_usec); -+} ++*******************************************************************************/ + -+/** -+ * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM -+ * @hw: pointer to the HW structure -+ * @data: data to send to the EEPROM -+ * @count: number of bits to shift out -+ * -+ * We need to shift 'count' bits out to the EEPROM. So, the value in the -+ * "data" parameter will be shifted out to the EEPROM one bit at a time. -+ * In order to do this, "data" must be broken down into bits. -+ **/ -+static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) -+{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 eecd = er32(EECD); -+ u32 mask; + -+ mask = 0x01 << (count - 1); -+ if (nvm->type == e1000_nvm_eeprom_spi) -+ eecd |= E1000_EECD_DO; + -+ do { -+ eecd &= ~E1000_EECD_DI; ++#ifdef DRIVER_E1000E ++#include "e1000.h" ++#endif ++ ++ + -+ if (data & mask) -+ eecd |= E1000_EECD_DI; + -+ ew32(EECD, eecd); -+ e1e_flush(); ++#include "kcompat.h" + -+ udelay(nvm->delay_usec); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) ) + -+ e1000_raise_eec_clk(hw, &eecd); -+ e1000_lower_eec_clk(hw, &eecd); ++/**************************************/ ++/* PCI DMA MAPPING */ + -+ mask >>= 1; -+ } while (mask); ++#if defined(CONFIG_HIGHMEM) + -+ eecd &= ~E1000_EECD_DI; -+ ew32(EECD, eecd); ++#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); +} + -+/** -+ * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM -+ * @hw: pointer to the HW structure -+ * @count: number of bits to shift in -+ * -+ * In order to read a register from the EEPROM, we need to shift 'count' bits -+ * in from the EEPROM. Bits are "shifted in" by raising the clock input to -+ * the EEPROM (setting the SK bit), and then reading the value of the data out -+ * "DO" bit. During this "shifting in" process the data in "DI" bit should -+ * always be clear. -+ **/ -+static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) ++#else /* CONFIG_HIGHMEM */ ++ ++u64 ++_kc_pci_map_page(struct pci_dev *dev, struct page *page, unsigned long offset, ++ size_t size, int direction) +{ -+ u32 eecd; -+ u32 i; -+ u16 data; ++ return pci_map_single(dev, (void *)page_address(page) + offset, size, ++ direction); ++} + -+ eecd = er32(EECD); ++#endif /* CONFIG_HIGHMEM */ + -+ eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); -+ data = 0; ++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); ++} + -+ for (i = 0; i < count; i++) { -+ data <<= 1; -+ e1000_raise_eec_clk(hw, &eecd); ++#endif /* 2.4.13 => 2.4.3 */ + -+ eecd = er32(EECD); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) ) + -+ eecd &= ~E1000_EECD_DI; -+ if (eecd & E1000_EECD_DO) -+ data |= 1; ++/**************************************/ ++/* PCI DRIVER API */ + -+ e1000_lower_eec_clk(hw, &eecd); -+ } ++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; ++} + -+ return data; ++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; +} + -+/** -+ * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion -+ * @hw: pointer to the HW structure -+ * @ee_reg: EEPROM flag for polling -+ * -+ * Polls the EEPROM status bit for either read or write completion based -+ * upon the value of 'ee_reg'. -+ **/ -+s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) ++void ++_kc_pci_release_regions(struct pci_dev *dev) +{ -+ u32 attempts = 100000; -+ u32 i, reg = 0; ++ int i; + -+ for (i = 0; i < attempts; i++) { -+ if (ee_reg == E1000_NVM_POLL_READ) -+ reg = er32(EERD); -+ else -+ reg = er32(EEWR); ++ for (i = 0; i < 6; i++) { ++ if (pci_resource_len(dev, i) == 0) ++ continue; + -+ if (reg & E1000_NVM_RW_REG_DONE) -+ return 0; ++ if (pci_resource_flags(dev, i) & IORESOURCE_IO) ++ release_region(pci_resource_start(dev, i), pci_resource_len(dev, i)); + -+ udelay(5); ++ 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 -E1000_ERR_NVM; ++ return dev; +} + -+/** -+ * e1000e_acquire_nvm - Generic request for access to EEPROM -+ * @hw: pointer to the HW structure -+ * -+ * Set the EEPROM access request bit and wait for EEPROM access grant bit. -+ * Return successful if access grant bit set, else clear the request for -+ * EEPROM access and return -E1000_ERR_NVM (-1). -+ **/ -+s32 e1000e_acquire_nvm(struct e1000_hw *hw) ++int ++_kc_is_valid_ether_addr(u8 *addr) +{ -+ u32 eecd = er32(EECD); -+ s32 timeout = E1000_NVM_GRANT_ATTEMPTS; ++ const char zaddr[6] = { 0, }; + -+ ew32(EECD, eecd | E1000_EECD_REQ); -+ eecd = er32(EECD); ++ return !(addr[0] & 1) && memcmp(addr, zaddr, 6); ++} + -+ while (timeout) { -+ if (eecd & E1000_EECD_GNT) -+ break; -+ udelay(5); -+ eecd = er32(EECD); -+ timeout--; -+ } ++#endif /* 2.4.3 => 2.4.0 */ + -+ if (!timeout) { -+ eecd &= ~E1000_EECD_REQ; -+ ew32(EECD, eecd); -+ hw_dbg(hw, "Could not acquire NVM grant\n"); -+ return -E1000_ERR_NVM; -+ } ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) ) + ++int ++_kc_pci_set_power_state(struct pci_dev *dev, int state) ++{ + return 0; +} + -+/** -+ * e1000_standby_nvm - Return EEPROM to standby state -+ * @hw: pointer to the HW structure -+ * -+ * Return the EEPROM to a standby state. -+ **/ -+static void e1000_standby_nvm(struct e1000_hw *hw) ++int ++_kc_pci_save_state(struct pci_dev *dev, u32 *buffer) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 eecd = er32(EECD); ++ return 0; ++} + -+ if (nvm->type == e1000_nvm_eeprom_spi) { -+ /* Toggle CS to flush commands */ -+ eecd |= E1000_EECD_CS; -+ ew32(EECD, eecd); -+ e1e_flush(); -+ udelay(nvm->delay_usec); -+ eecd &= ~E1000_EECD_CS; -+ ew32(EECD, eecd); -+ e1e_flush(); -+ udelay(nvm->delay_usec); -+ } ++int ++_kc_pci_restore_state(struct pci_dev *pdev, u32 *buffer) ++{ ++ return 0; +} + -+/** -+ * e1000_stop_nvm - Terminate EEPROM command -+ * @hw: pointer to the HW structure -+ * -+ * Terminates the current command by inverting the EEPROM's chip select pin. -+ **/ -+static void e1000_stop_nvm(struct e1000_hw *hw) ++int ++_kc_pci_enable_wake(struct pci_dev *pdev, u32 state, int enable) +{ -+ u32 eecd; ++ return 0; ++} + -+ eecd = er32(EECD); -+ if (hw->nvm.type == e1000_nvm_eeprom_spi) { -+ /* Pull CS high */ -+ eecd |= E1000_EECD_CS; -+ e1000_lower_eec_clk(hw, &eecd); -+ } ++#endif /* 2.4.6 => 2.4.3 */ ++ ++/*****************************************************************************/ ++#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; +} + -+/** -+ * e1000e_release_nvm - Release exclusive access to EEPROM -+ * @hw: pointer to the HW structure ++/* ++ * Original Copyright: ++ * find_next_bit.c: fallback find next bit implementation + * -+ * Stop any current commands to the EEPROM and clear the EEPROM request bit. -+ **/ -+void e1000e_release_nvm(struct e1000_hw *hw) ++ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ */ ++ ++/** ++ * find_next_bit - find the next set bit in a memory region ++ * @addr: The address to base the search on ++ * @offset: The bitnumber to start searching at ++ * @size: The maximum size to search ++ */ ++unsigned long find_next_bit(const unsigned long *addr, unsigned long size, ++ unsigned long offset) ++{ ++ const unsigned long *p = addr + BITOP_WORD(offset); ++ unsigned long result = offset & ~(BITS_PER_LONG-1); ++ unsigned long tmp; ++ ++ if (offset >= size) ++ return size; ++ size -= result; ++ offset %= BITS_PER_LONG; ++ if (offset) { ++ tmp = *(p++); ++ tmp &= (~0UL << offset); ++ if (size < BITS_PER_LONG) ++ goto found_first; ++ if (tmp) ++ goto found_middle; ++ size -= BITS_PER_LONG; ++ result += BITS_PER_LONG; ++ } ++ while (size & ~(BITS_PER_LONG-1)) { ++ if ((tmp = *(p++))) ++ goto found_middle; ++ result += BITS_PER_LONG; ++ size -= BITS_PER_LONG; ++ } ++ if (!size) ++ return result; ++ tmp = *p; ++ ++found_first: ++ tmp &= (~0UL >> (BITS_PER_LONG - size)); ++ if (tmp == 0UL) /* Are any bits set? */ ++ return result + size; /* Nope. */ ++found_middle: ++ return result + ffs(tmp); ++} ++ ++#endif /* 2.6.0 => 2.4.6 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ) ++void *_kc_kzalloc(size_t size, int flags) ++{ ++ void *ret = kmalloc(size, flags); ++ if (ret) ++ memset(ret, 0, size); ++ return ret; ++} ++#endif /* <= 2.6.13 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ) ++struct sk_buff *_kc_netdev_alloc_skb(struct net_device *dev, ++ unsigned int length) +{ -+ u32 eecd; ++ /* 16 == NET_PAD_SKB */ ++ struct sk_buff *skb; ++ skb = alloc_skb(length + 16, GFP_ATOMIC); ++ if (likely(skb != NULL)) { ++ skb_reserve(skb, 16); ++ skb->dev = dev; ++ } ++ return skb; ++} ++#endif /* <= 2.6.17 */ + -+ e1000_stop_nvm(hw); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) ) ++#endif /* < 2.6.23 */ + -+ eecd = er32(EECD); -+ eecd &= ~E1000_EECD_REQ; -+ ew32(EECD, eecd); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) ++#ifdef NAPI ++int __kc_adapter_clean(struct net_device *netdev, int *budget) ++{ ++ int work_done; ++ int work_to_do = min(*budget, netdev->quota); ++ struct adapter_struct *adapter = netdev_priv(netdev); ++#ifdef DRIVER_E1000E ++ struct napi_struct *napi = &adapter->napi; ++#else ++ struct napi_struct *napi = &adapter->rx_ring[0].napi; ++#endif ++ ++ work_done = napi->poll(napi, work_to_do); ++ *budget -= work_done; ++ netdev->quota -= work_done; ++ return work_done ? 1 : 0; +} ++#endif /* NAPI */ ++#endif /* <= 2.6.24 */ + -+/** -+ * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write -+ * @hw: pointer to the HW structure +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/kcompat_ethtool.c linux-2.6.22-10/drivers/net/e1000e/kcompat_ethtool.c +--- linux-2.6.22-0/drivers/net/e1000e/kcompat_ethtool.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/kcompat_ethtool.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1169 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++/* ++ * net/core/ethtool.c - Ethtool ioctl handler ++ * Copyright (c) 2003 Matthew Wilcox + * -+ * Setups the EEPROM for reading and writing. -+ **/ -+static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) -+{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 eecd = er32(EECD); -+ u16 timeout = 0; -+ u8 spi_stat_reg; ++ * 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. ++ */ + -+ if (nvm->type == e1000_nvm_eeprom_spi) { -+ /* Clear SK and CS */ -+ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); -+ ew32(EECD, eecd); -+ udelay(1); -+ timeout = NVM_MAX_RETRY_SPI; ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "kcompat.h" ++ ++#undef SUPPORTED_10000baseT_Full ++#define SUPPORTED_10000baseT_Full (1 << 12) ++#undef ADVERTISED_10000baseT_Full ++#define ADVERTISED_10000baseT_Full (1 << 12) ++#undef SPEED_10000 ++#define SPEED_10000 10000 ++ ++#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)) + -+ /* Read "Status Register" repeatedly until the LSB is cleared. -+ * The EEPROM will signal that the command has been completed -+ * by clearing bit 0 of the internal status register. If it's -+ * not cleared within 'timeout', then error out. */ -+ while (timeout) { -+ e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, -+ hw->nvm.opcode_bits); -+ spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); -+ if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) -+ break; ++/* ++ * Some useful ethtool_ops methods that are device independent. If we find that ++ * all drivers want to do the same thing here, we can turn these into dev_() ++ * function calls. ++ */ + -+ udelay(5); -+ e1000_standby_nvm(hw); -+ timeout--; -+ } ++#undef ethtool_op_get_link ++#define ethtool_op_get_link _kc_ethtool_op_get_link ++u32 _kc_ethtool_op_get_link(struct net_device *dev) ++{ ++ return netif_carrier_ok(dev) ? 1 : 0; ++} + -+ if (!timeout) { -+ hw_dbg(hw, "SPI NVM Status error\n"); -+ return -E1000_ERR_NVM; -+ } -+ } ++#undef ethtool_op_get_tx_csum ++#define ethtool_op_get_tx_csum _kc_ethtool_op_get_tx_csum ++u32 _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, u32 data) ++{ ++#ifdef NETIF_F_IP_CSUM ++ if (data) ++#ifdef NETIF_F_IPV6_CSUM ++ dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); ++ else ++ dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); ++#else ++ dev->features |= NETIF_F_IP_CSUM; ++ else ++ dev->features &= ~NETIF_F_IP_CSUM; ++#endif ++#endif + + return 0; +} + -+/** -+ * e1000e_read_nvm_spi - Read EEPROM's using SPI -+ * @hw: pointer to the HW structure -+ * @offset: offset of word in the EEPROM to read -+ * @words: number of words to read -+ * @data: word read from the EEPROM -+ * -+ * Reads a 16 bit word from the EEPROM. -+ **/ -+s32 e1000e_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++#undef ethtool_op_get_sg ++#define ethtool_op_get_sg _kc_ethtool_op_get_sg ++u32 _kc_ethtool_op_get_sg(struct net_device *dev) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 i = 0; -+ s32 ret_val; -+ u16 word_in; -+ u8 read_opcode = NVM_READ_OPCODE_SPI; ++#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, u32 data) ++{ ++#ifdef NETIF_F_SG ++ if (data) ++ dev->features |= NETIF_F_SG; ++ else ++ dev->features &= ~NETIF_F_SG; ++#endif ++ ++ return 0; ++} + -+ /* A check for invalid values: offset too large, too many words, -+ * and not enough words. */ -+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; -+ } ++#undef ethtool_op_get_tso ++#define ethtool_op_get_tso _kc_ethtool_op_get_tso ++u32 _kc_ethtool_op_get_tso(struct net_device *dev) ++{ ++#ifdef NETIF_F_TSO ++ return (dev->features & NETIF_F_TSO) != 0; ++#else ++ return 0; ++#endif ++} + -+ ret_val = nvm->ops.acquire_nvm(hw); -+ if (ret_val) -+ return ret_val; ++#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, u32 data) ++{ ++#ifdef NETIF_F_TSO ++ if (data) ++ dev->features |= NETIF_F_TSO; ++ else ++ dev->features &= ~NETIF_F_TSO; ++#endif + -+ ret_val = e1000_ready_nvm_eeprom(hw); -+ if (ret_val) { -+ nvm->ops.release_nvm(hw); -+ return ret_val; -+ } ++ return 0; ++} + -+ e1000_standby_nvm(hw); ++/* Handlers for each ethtool command */ + -+ if ((nvm->address_bits == 8) && (offset >= 128)) -+ read_opcode |= NVM_A8_OPCODE_SPI; ++static int ethtool_get_settings(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_cmd cmd = { ETHTOOL_GSET }; ++ int err; + -+ /* Send the READ command (opcode + addr) */ -+ e1000_shift_out_eec_bits(hw, read_opcode, nvm->opcode_bits); -+ e1000_shift_out_eec_bits(hw, (u16)(offset*2), nvm->address_bits); ++ if (!ethtool_ops->get_settings) ++ return -EOPNOTSUPP; + -+ /* Read the data. SPI NVMs increment the address with each byte -+ * read and will roll over if reading beyond the end. This allows -+ * us to read the whole NVM from any offset */ -+ for (i = 0; i < words; i++) { -+ word_in = e1000_shift_in_eec_bits(hw, 16); -+ data[i] = (word_in >> 8) | (word_in << 8); -+ } ++ err = ethtool_ops->get_settings(dev, &cmd); ++ if (err < 0) ++ return err; + -+ nvm->ops.release_nvm(hw); ++ if (copy_to_user(useraddr, &cmd, sizeof(cmd))) ++ return -EFAULT; + return 0; +} + -+/** -+ * e1000e_read_nvm_eerd - Reads EEPROM using EERD register -+ * @hw: pointer to the HW structure -+ * @offset: offset of word in the EEPROM to read -+ * @words: number of words to read -+ * @data: word read from the EEPROM -+ * -+ * Reads a 16 bit word from the EEPROM using the EERD register. -+ **/ -+s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++static int ethtool_set_settings(struct net_device *dev, void *useraddr) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ u32 i, eerd = 0; -+ s32 ret_val = 0; -+ -+ /* A check for invalid values: offset too large, too many words, -+ * and not enough words. */ -+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; -+ } -+ -+ for (i = 0; i < words; i++) { -+ eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + -+ E1000_NVM_RW_REG_START; ++ struct ethtool_cmd cmd; + -+ ew32(EERD, eerd); -+ ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); -+ if (ret_val) -+ break; ++ if (!ethtool_ops->set_settings) ++ return -EOPNOTSUPP; + -+ data[i] = (er32(EERD) >> -+ E1000_NVM_RW_REG_DATA); -+ } ++ if (copy_from_user(&cmd, useraddr, sizeof(cmd))) ++ return -EFAULT; + -+ return ret_val; ++ return ethtool_ops->set_settings(dev, &cmd); +} + -+/** -+ * e1000e_write_nvm_spi - Write to EEPROM using SPI -+ * @hw: pointer to the HW structure -+ * @offset: offset within the EEPROM to be written to -+ * @words: number of words to write -+ * @data: 16 bit word(s) to be written to the EEPROM -+ * -+ * Writes data to EEPROM at offset using SPI interface. -+ * -+ * If e1000e_update_nvm_checksum is not called after this function , the -+ * EEPROM will most likley contain an invalid checksum. -+ **/ -+s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) ++static int ethtool_get_drvinfo(struct net_device *dev, void *useraddr) +{ -+ struct e1000_nvm_info *nvm = &hw->nvm; -+ s32 ret_val; -+ u16 widx = 0; ++ struct ethtool_drvinfo info; ++ struct ethtool_ops *ops = ethtool_ops; + -+ /* A check for invalid values: offset too large, too many words, -+ * and not enough words. */ -+ if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || -+ (words == 0)) { -+ hw_dbg(hw, "nvm parameter(s) out of bounds\n"); -+ return -E1000_ERR_NVM; -+ } ++ if (!ops->get_drvinfo) ++ return -EOPNOTSUPP; + -+ ret_val = nvm->ops.acquire_nvm(hw); -+ if (ret_val) -+ return ret_val; ++ memset(&info, 0, sizeof(info)); ++ info.cmd = ETHTOOL_GDRVINFO; ++ ops->get_drvinfo(dev, &info); + -+ msleep(10); ++ 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); + -+ while (widx < words) { -+ u8 write_opcode = NVM_WRITE_OPCODE_SPI; ++ if (copy_to_user(useraddr, &info, sizeof(info))) ++ return -EFAULT; ++ return 0; ++} + -+ ret_val = e1000_ready_nvm_eeprom(hw); -+ if (ret_val) { -+ nvm->ops.release_nvm(hw); -+ return ret_val; -+ } ++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; + -+ e1000_standby_nvm(hw); ++ if (!ops->get_regs || !ops->get_regs_len) ++ return -EOPNOTSUPP; + -+ /* Send the WRITE ENABLE command (8 bit opcode) */ -+ e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, -+ nvm->opcode_bits); ++ if (copy_from_user(®s, useraddr, sizeof(regs))) ++ return -EFAULT; + -+ e1000_standby_nvm(hw); ++ reglen = ops->get_regs_len(dev); ++ if (regs.len > reglen) ++ regs.len = reglen; + -+ /* Some SPI eeproms use the 8th address bit embedded in the -+ * opcode */ -+ if ((nvm->address_bits == 8) && (offset >= 128)) -+ write_opcode |= NVM_A8_OPCODE_SPI; ++ regbuf = kmalloc(reglen, GFP_USER); ++ if (!regbuf) ++ return -ENOMEM; + -+ /* Send the Write command (8-bit opcode + addr) */ -+ e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); -+ e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), -+ nvm->address_bits); ++ ops->get_regs(dev, ®s, regbuf); + -+ /* Loop to allow for up to whole page write of eeprom */ -+ while (widx < words) { -+ u16 word_out = data[widx]; -+ word_out = (word_out >> 8) | (word_out << 8); -+ e1000_shift_out_eec_bits(hw, word_out, 16); -+ widx++; ++ 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; + -+ if ((((offset + widx) * 2) % nvm->page_size) == 0) { -+ e1000_standby_nvm(hw); -+ break; -+ } -+ } -+ } ++out: ++ kfree(regbuf); ++ return ret; ++} + -+ msleep(10); ++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; +} + -+/** -+ * e1000e_read_mac_addr - Read device MAC address -+ * @hw: pointer to the HW structure -+ * -+ * Reads the device MAC address from the EEPROM and stores the value. -+ * Since devices with two ports use the same EEPROM, we increment the -+ * last bit in the MAC address for the second port. -+ **/ -+s32 e1000e_read_mac_addr(struct e1000_hw *hw) ++static int ethtool_set_wol(struct net_device *dev, char *useraddr) +{ -+ s32 ret_val; -+ u16 offset, nvm_data, i; -+ -+ for (i = 0; i < ETH_ALEN; i += 2) { -+ offset = i >> 1; -+ ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; -+ } -+ hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF); -+ hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8); -+ } ++ struct ethtool_wolinfo wol; + -+ /* Flip last bit of mac address if we're on second port */ -+ if (hw->bus.func == E1000_FUNC_1) -+ hw->mac.perm_addr[5] ^= 1; ++ if (!ethtool_ops->set_wol) ++ return -EOPNOTSUPP; + -+ for (i = 0; i < ETH_ALEN; i++) -+ hw->mac.addr[i] = hw->mac.perm_addr[i]; ++ if (copy_from_user(&wol, useraddr, sizeof(wol))) ++ return -EFAULT; + -+ return 0; ++ return ethtool_ops->set_wol(dev, &wol); +} + -+/** -+ * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum -+ * @hw: pointer to the HW structure -+ * -+ * Calculates the EEPROM checksum by reading/adding each word of the EEPROM -+ * and then verifies that the sum of the EEPROM is equal to 0xBABA. -+ **/ -+s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) ++static int ethtool_get_msglevel(struct net_device *dev, char *useraddr) +{ -+ s32 ret_val; -+ u16 checksum = 0; -+ u16 i, nvm_data; ++ struct ethtool_value edata = { ETHTOOL_GMSGLVL }; + -+ for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { -+ ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error\n"); -+ return ret_val; -+ } -+ checksum += nvm_data; -+ } ++ if (!ethtool_ops->get_msglevel) ++ return -EOPNOTSUPP; + -+ if (checksum != (u16) NVM_SUM) { -+ hw_dbg(hw, "NVM Checksum Invalid\n"); -+ return -E1000_ERR_NVM; -+ } ++ edata.data = ethtool_ops->get_msglevel(dev); + ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; + return 0; +} + -+/** -+ * e1000e_update_nvm_checksum_generic - Update EEPROM checksum -+ * @hw: pointer to the HW structure -+ * -+ * Updates the EEPROM checksum by reading/adding each word of the EEPROM -+ * up to the checksum. Then calculates the EEPROM checksum and writes the -+ * value to the EEPROM. -+ **/ -+s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw) ++static int ethtool_set_msglevel(struct net_device *dev, char *useraddr) +{ -+ s32 ret_val; -+ u16 checksum = 0; -+ u16 i, nvm_data; ++ struct ethtool_value edata; + -+ for (i = 0; i < NVM_CHECKSUM_REG; i++) { -+ ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); -+ if (ret_val) { -+ hw_dbg(hw, "NVM Read Error while updating checksum.\n"); -+ return ret_val; -+ } -+ checksum += nvm_data; -+ } -+ checksum = (u16) NVM_SUM - checksum; -+ ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); -+ if (ret_val) -+ hw_dbg(hw, "NVM Write Error while updating checksum.\n"); ++ if (!ethtool_ops->set_msglevel) ++ return -EOPNOTSUPP; + -+ return ret_val; ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; ++ ++ ethtool_ops->set_msglevel(dev, edata.data); ++ return 0; +} + -+/** -+ * e1000e_reload_nvm - Reloads EEPROM -+ * @hw: pointer to the HW structure -+ * -+ * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the -+ * extended control register. -+ **/ -+void e1000e_reload_nvm(struct e1000_hw *hw) ++static int ethtool_nway_reset(struct net_device *dev) +{ -+ u32 ctrl_ext; ++ if (!ethtool_ops->nway_reset) ++ return -EOPNOTSUPP; + -+ udelay(10); -+ ctrl_ext = er32(CTRL_EXT); -+ ctrl_ext |= E1000_CTRL_EXT_EE_RST; -+ ew32(CTRL_EXT, ctrl_ext); -+ e1e_flush(); ++ return ethtool_ops->nway_reset(dev); +} + -+/** -+ * e1000_calculate_checksum - Calculate checksum for buffer -+ * @buffer: pointer to EEPROM -+ * @length: size of EEPROM to calculate a checksum for -+ * -+ * Calculates the checksum for some buffer on a specified length. The -+ * checksum calculated is returned. -+ **/ -+static u8 e1000_calculate_checksum(u8 *buffer, u32 length) ++static int ethtool_get_link(struct net_device *dev, void *useraddr) +{ -+ u32 i; -+ u8 sum = 0; ++ struct ethtool_value edata = { ETHTOOL_GLINK }; + -+ if (!buffer) -+ return 0; ++ if (!ethtool_ops->get_link) ++ return -EOPNOTSUPP; + -+ for (i = 0; i < length; i++) -+ sum += buffer[i]; ++ edata.data = ethtool_ops->get_link(dev); + -+ return (u8) (0 - sum); ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; +} + -+/** -+ * e1000_mng_enable_host_if - Checks host interface is enabled -+ * @hw: pointer to the HW structure -+ * -+ * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND -+ * -+ * 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. -+ **/ -+static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) ++static int ethtool_get_eeprom(struct net_device *dev, void *useraddr) +{ -+ u32 hicr; -+ u8 i; ++ struct ethtool_eeprom eeprom; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; + -+ /* Check that the host interface is enabled. */ -+ hicr = er32(HICR); -+ if ((hicr & E1000_HICR_EN) == 0) { -+ hw_dbg(hw, "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 = er32(HICR); -+ if (!(hicr & E1000_HICR_C)) -+ break; -+ mdelay(1); -+ } ++ if (!ops->get_eeprom || !ops->get_eeprom_len) ++ return -EOPNOTSUPP; + -+ if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { -+ hw_dbg(hw, "Previous command timeout failed .\n"); -+ return -E1000_ERR_HOST_INTERFACE_COMMAND; -+ } ++ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) ++ return -EFAULT; + -+ return 0; ++ /* 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; +} + -+/** -+ * e1000e_check_mng_mode - check managament mode -+ * @hw: pointer to the HW structure -+ * -+ * Reads the firmware semaphore register and returns true (>0) if -+ * manageability is enabled, else false (0). -+ **/ -+bool e1000e_check_mng_mode(struct e1000_hw *hw) ++static int ethtool_set_eeprom(struct net_device *dev, void *useraddr) +{ -+ u32 fwsm = er32(FWSM); ++ struct ethtool_eeprom eeprom; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; + -+ return (fwsm & E1000_FWSM_MODE_MASK) == hw->mac.ops.mng_mode_enab; -+} ++ if (!ops->set_eeprom || !ops->get_eeprom_len) ++ return -EOPNOTSUPP; + -+/** -+ * e1000e_enable_tx_pkt_filtering - Enable packet filtering on TX -+ * @hw: pointer to the HW structure -+ * -+ * Enables packet filtering on transmit packets if manageability is enabled -+ * and host interface is enabled. -+ **/ -+bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) -+{ -+ struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; -+ u32 *buffer = (u32 *)&hw->mng_cookie; -+ u32 offset; -+ s32 ret_val, hdr_csum, csum; -+ u8 i, len; ++ if (copy_from_user(&eeprom, useraddr, sizeof(eeprom))) ++ return -EFAULT; + -+ /* No manageability, no filtering */ -+ if (!e1000e_check_mng_mode(hw)) { -+ hw->mac.tx_pkt_filtering = 0; -+ return 0; -+ } ++ /* Check for wrap and zero */ ++ if (eeprom.offset + eeprom.len <= eeprom.offset) ++ return -EINVAL; + -+ /* If we can't read from the host interface for whatever -+ * reason, disable filtering. -+ */ -+ ret_val = e1000_mng_enable_host_if(hw); -+ if (ret_val != 0) { -+ hw->mac.tx_pkt_filtering = 0; -+ return ret_val; -+ } ++ /* Check for exceeding total eeprom len */ ++ if (eeprom.offset + eeprom.len > ops->get_eeprom_len(dev)) ++ return -EINVAL; + -+ /* Read in the header. Length and offset are in dwords. */ -+ len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; -+ offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; -+ for (i = 0; i < len; i++) -+ *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i); -+ hdr_csum = hdr->checksum; -+ hdr->checksum = 0; -+ csum = e1000_calculate_checksum((u8 *)hdr, -+ E1000_MNG_DHCP_COOKIE_LENGTH); -+ /* If either the checksums or signature don't match, then -+ * the cookie area isn't considered valid, in which case we -+ * take the safe route of assuming Tx filtering is enabled. -+ */ -+ if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { -+ hw->mac.tx_pkt_filtering = 1; -+ return 1; -+ } ++ data = kmalloc(eeprom.len, GFP_USER); ++ if (!data) ++ return -ENOMEM; + -+ /* Cookie area is valid, make the final check for filtering. */ -+ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { -+ hw->mac.tx_pkt_filtering = 0; -+ return 0; -+ } ++ ret = -EFAULT; ++ if (copy_from_user(data, useraddr + sizeof(eeprom), eeprom.len)) ++ goto out; + -+ hw->mac.tx_pkt_filtering = 1; -+ return 1; ++ 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; +} + -+/** -+ * e1000_mng_write_cmd_header - Writes manageability command header -+ * @hw: pointer to the HW structure -+ * @hdr: pointer to the host interface command header -+ * -+ * Writes the command header after does the checksum calculation. -+ **/ -+static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, -+ struct e1000_host_mng_command_header *hdr) ++static int ethtool_get_coalesce(struct net_device *dev, void *useraddr) +{ -+ u16 i, length = sizeof(struct e1000_host_mng_command_header); -+ -+ /* Write the whole command header structure with new checksum. */ ++ struct ethtool_coalesce coalesce = { ETHTOOL_GCOALESCE }; + -+ hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); ++ if (!ethtool_ops->get_coalesce) ++ return -EOPNOTSUPP; + -+ length >>= 2; -+ /* Write the relevant command block into the ram area. */ -+ for (i = 0; i < length; i++) { -+ E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, -+ *((u32 *) hdr + i)); -+ e1e_flush(); -+ } ++ ethtool_ops->get_coalesce(dev, &coalesce); + ++ if (copy_to_user(useraddr, &coalesce, sizeof(coalesce))) ++ return -EFAULT; + return 0; +} + -+/** -+ * e1000_mng_host_if_write - Writes to the manageability host interface -+ * @hw: pointer to the HW structure -+ * @buffer: pointer to the host interface buffer -+ * @length: size of the buffer -+ * @offset: location in the buffer to write to -+ * @sum: sum of the data (not checksum) -+ * -+ * 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. -+ **/ -+static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, -+ u16 length, u16 offset, u8 *sum) ++static int ethtool_set_coalesce(struct net_device *dev, void *useraddr) +{ -+ u8 *tmp; -+ u8 *bufptr = buffer; -+ u32 data = 0; -+ u16 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 = (u8 *)&data; -+ prev_bytes = offset & 0x3; -+ offset >>= 2; ++ struct ethtool_coalesce coalesce; + -+ if (prev_bytes) { -+ data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); -+ for (j = prev_bytes; j < sizeof(u32); j++) { -+ *(tmp + j) = *bufptr++; -+ *sum += *(tmp + j); -+ } -+ E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); -+ length -= j - prev_bytes; -+ offset++; -+ } ++ if (!ethtool_ops->get_coalesce) ++ return -EOPNOTSUPP; + -+ remaining = length & 0x3; -+ length -= remaining; ++ if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) ++ return -EFAULT; + -+ /* Calculate length in DWORDs */ -+ length >>= 2; ++ return ethtool_ops->set_coalesce(dev, &coalesce); ++} + -+ /* The device driver writes the relevant command block into the -+ * ram area. */ -+ for (i = 0; i < length; i++) { -+ for (j = 0; j < sizeof(u32); j++) { -+ *(tmp + j) = *bufptr++; -+ *sum += *(tmp + j); -+ } ++static int ethtool_get_ringparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_ringparam ringparam = { ETHTOOL_GRINGPARAM }; + -+ E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); -+ } -+ if (remaining) { -+ for (j = 0; j < sizeof(u32); j++) { -+ if (j < remaining) -+ *(tmp + j) = *bufptr++; -+ else -+ *(tmp + j) = 0; ++ if (!ethtool_ops->get_ringparam) ++ return -EOPNOTSUPP; + -+ *sum += *(tmp + j); -+ } -+ E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); -+ } ++ ethtool_ops->get_ringparam(dev, &ringparam); + ++ if (copy_to_user(useraddr, &ringparam, sizeof(ringparam))) ++ return -EFAULT; + return 0; +} + -+/** -+ * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface -+ * @hw: pointer to the HW structure -+ * @buffer: pointer to the host interface -+ * @length: size of the buffer -+ * -+ * Writes the DHCP information to the host interface. -+ **/ -+s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) ++static int ethtool_set_ringparam(struct net_device *dev, void *useraddr) +{ -+ struct e1000_host_mng_command_header hdr; -+ s32 ret_val; -+ u32 hicr; ++ struct ethtool_ringparam ringparam; + -+ hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; -+ hdr.command_length = length; -+ hdr.reserved1 = 0; -+ hdr.reserved2 = 0; -+ hdr.checksum = 0; ++ if (!ethtool_ops->get_ringparam) ++ return -EOPNOTSUPP; + -+ /* Enable the host interface */ -+ ret_val = e1000_mng_enable_host_if(hw); -+ if (ret_val) -+ return ret_val; ++ if (copy_from_user(&ringparam, useraddr, sizeof(ringparam))) ++ return -EFAULT; + -+ /* Populate the host interface with the contents of "buffer". */ -+ ret_val = e1000_mng_host_if_write(hw, buffer, length, -+ sizeof(hdr), &(hdr.checksum)); -+ if (ret_val) -+ return ret_val; ++ return ethtool_ops->set_ringparam(dev, &ringparam); ++} + -+ /* Write the manageability command header */ -+ ret_val = e1000_mng_write_cmd_header(hw, &hdr); -+ if (ret_val) -+ return ret_val; ++static int ethtool_get_pauseparam(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + -+ /* Tell the ARC a new command is pending. */ -+ hicr = er32(HICR); -+ ew32(HICR, hicr | E1000_HICR_C); ++ 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; +} + -+/** -+ * e1000e_enable_mng_pass_thru - Enable processing of ARP's -+ * @hw: pointer to the HW structure -+ * -+ * Verifies the hardware needs to allow ARPs to be processed by the host. -+ **/ -+bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) ++static int ethtool_set_pauseparam(struct net_device *dev, void *useraddr) +{ -+ u32 manc; -+ u32 fwsm, factps; -+ bool ret_val = 0; -+ -+ manc = er32(MANC); -+ -+ if (!(manc & E1000_MANC_RCV_TCO_EN) || -+ !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) -+ return ret_val; ++ struct ethtool_pauseparam pauseparam; + -+ if (hw->mac.arc_subsystem_valid) { -+ fwsm = er32(FWSM); -+ factps = er32(FACTPS); ++ if (!ethtool_ops->get_pauseparam) ++ return -EOPNOTSUPP; + -+ if (!(factps & E1000_FACTPS_MNGCG) && -+ ((fwsm & E1000_FWSM_MODE_MASK) == -+ (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { -+ ret_val = 1; -+ return ret_val; -+ } -+ } else { -+ if ((manc & E1000_MANC_SMBUS_EN) && -+ !(manc & E1000_MANC_ASF_EN)) { -+ ret_val = 1; -+ return ret_val; -+ } -+ } ++ if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) ++ return -EFAULT; + -+ return ret_val; ++ return ethtool_ops->set_pauseparam(dev, &pauseparam); +} + -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/Makefile linux-2.6.22-10/drivers/net/e1000e/Makefile ---- linux-2.6.22-0/drivers/net/e1000e/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/Makefile 2007-11-21 13:55:13.000000000 -0500 -@@ -0,0 +1,37 @@ -+################################################################################ -+# -+# Intel PRO/1000 Linux driver -+# Copyright(c) 1999 - 2007 Intel Corporation. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms and conditions of the GNU General Public License, -+# version 2, as published by the Free Software Foundation. -+# -+# This program is distributed in the hope 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., -+# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. -+# -+# The full GNU General Public License is included in this distribution in -+# the file called "COPYING". -+# -+# Contact Information: -+# Linux NICS -+# e1000-devel Mailing List -+# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 -+# -+################################################################################ -+ -+# -+# Makefile for the Intel(R) PRO/1000 ethernet driver -+# ++static int ethtool_get_rx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GRXCSUM }; + -+obj-$(CONFIG_E1000E) += e1000e.o ++ if (!ethtool_ops->get_rx_csum) ++ return -EOPNOTSUPP; + -+e1000e-objs := 82571.o ich8lan.o es2lan.o \ -+ lib.o phy.o param.o ethtool.o netdev.o ++ edata.data = ethtool_ops->get_rx_csum(dev); + -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/netdev.c linux-2.6.22-10/drivers/net/e1000e/netdev.c ---- linux-2.6.22-0/drivers/net/e1000e/netdev.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/netdev.c 2007-11-21 13:55:34.000000000 -0500 -@@ -0,0 +1,4460 @@ -+/******************************************************************************* ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++static int ethtool_set_rx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ if (!ethtool_ops->set_rx_csum) ++ return -EOPNOTSUPP; + -+ This program is distributed in the hope 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. ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ethtool_ops->set_rx_csum(dev, edata.data); ++ return 0; ++} + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++static int ethtool_get_tx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata = { ETHTOOL_GTXCSUM }; + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ if (!ethtool_ops->get_tx_csum) ++ return -EOPNOTSUPP; + -+*******************************************************************************/ ++ edata.data = ethtool_ops->get_tx_csum(dev); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; ++} + -+#include "e1000.h" ++static int ethtool_set_tx_csum(struct net_device *dev, char *useraddr) ++{ ++ struct ethtool_value edata; + -+#define DRV_VERSION "0.2.0" -+char e1000e_driver_name[] = "e1000e"; -+const char e1000e_driver_version[] = DRV_VERSION; ++ if (!ethtool_ops->set_tx_csum) ++ return -EOPNOTSUPP; + -+static const struct e1000_info *e1000_info_tbl[] = { -+ [board_82571] = &e1000_82571_info, -+ [board_82572] = &e1000_82572_info, -+ [board_82573] = &e1000_82573_info, -+ [board_80003es2lan] = &e1000_es2_info, -+ [board_ich8lan] = &e1000_ich8_info, -+ [board_ich9lan] = &e1000_ich9_info, -+}; ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; + -+#ifdef DEBUG -+/** -+ * e1000_get_hw_dev_name - return device name string -+ * used by hardware layer to print debugging information -+ **/ -+char *e1000e_get_hw_dev_name(struct e1000_hw *hw) ++ return ethtool_ops->set_tx_csum(dev, edata.data); ++} ++ ++static int ethtool_get_sg(struct net_device *dev, char *useraddr) +{ -+ struct e1000_adapter *adapter = hw->back; -+ struct net_device *netdev = adapter->netdev; -+ return netdev->name; ++ 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; +} -+#endif + -+/** -+ * e1000_desc_unused - calculate if we have unused descriptors -+ **/ -+static int e1000_desc_unused(struct e1000_ring *ring) ++static int ethtool_set_sg(struct net_device *dev, char *useraddr) +{ -+ if (ring->next_to_clean > ring->next_to_use) -+ return ring->next_to_clean - ring->next_to_use - 1; ++ struct ethtool_value edata; + -+ return ring->count + ring->next_to_clean - ring->next_to_use - 1; ++ 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); +} + -+/** -+ * e1000_receive_skb - helper function to handle rx indications -+ * @adapter: board private structure -+ * @status: descriptor status field as written by hardware -+ * @vlan: descriptor vlan field as written by hardware (no le/be conversion) -+ * @skb: pointer to sk_buff to be indicated to stack -+ **/ -+static void e1000_receive_skb(struct e1000_adapter *adapter, -+ struct net_device *netdev, -+ struct sk_buff *skb, -+ u8 status, u16 vlan) ++static int ethtool_get_tso(struct net_device *dev, char *useraddr) +{ -+ skb->protocol = eth_type_trans(skb, netdev); ++ struct ethtool_value edata = { ETHTOOL_GTSO }; + -+ if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) -+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, -+ le16_to_cpu(vlan) & -+ E1000_RXD_SPC_VLAN_MASK); -+ else -+ netif_receive_skb(skb); ++ if (!ethtool_ops->get_tso) ++ return -EOPNOTSUPP; + -+ netdev->last_rx = jiffies; ++ edata.data = ethtool_ops->get_tso(dev); ++ ++ if (copy_to_user(useraddr, &edata, sizeof(edata))) ++ return -EFAULT; ++ return 0; +} + -+/** -+ * 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 -+ **/ -+static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, -+ u32 csum, struct sk_buff *skb) ++static int ethtool_set_tso(struct net_device *dev, char *useraddr) +{ -+ u16 status = (u16)status_err; -+ u8 errors = (u8)(status_err >> 24); -+ skb->ip_summed = CHECKSUM_NONE; ++ struct ethtool_value edata; + -+ /* Ignore Checksum bit is set */ -+ if (status & E1000_RXD_STAT_IXSM) -+ return; -+ /* TCP/UDP checksum error bit is set */ -+ if (errors & E1000_RXD_ERR_TCPE) { -+ /* let the stack verify checksum errors */ -+ adapter->hw_csum_err++; -+ return; -+ } ++ if (!ethtool_ops->set_tso) ++ return -EOPNOTSUPP; + -+ /* TCP/UDP Checksum has not been calculated */ -+ if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))) -+ return; ++ if (copy_from_user(&edata, useraddr, sizeof(edata))) ++ return -EFAULT; + -+ /* It must be a TCP or UDP packet with a valid checksum */ -+ if (status & E1000_RXD_STAT_TCPCS) { -+ /* TCP checksum is good */ -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } else { -+ /* 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_COMPLETE; -+ } -+ adapter->hw_csum_good++; ++ return ethtool_ops->set_tso(dev, edata.data); +} + -+/** -+ * 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, -+ int cleaned_count) ++static int ethtool_self_test(struct net_device *dev, char *useraddr) +{ -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ 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; ++ struct ethtool_test test; ++ struct ethtool_ops *ops = ethtool_ops; ++ u64 *data; ++ int ret; + -+ i = rx_ring->next_to_use; -+ buffer_info = &rx_ring->buffer_info[i]; ++ if (!ops->self_test || !ops->self_test_count) ++ return -EOPNOTSUPP; + -+ while (cleaned_count--) { -+ skb = buffer_info->skb; -+ if (skb) { -+ skb_trim(skb, 0); -+ goto map_skb; -+ } ++ if (copy_from_user(&test, useraddr, sizeof(test))) ++ return -EFAULT; + -+ skb = netdev_alloc_skb(netdev, bufsz); -+ if (!skb) { -+ /* Better luck next round */ -+ adapter->alloc_rx_buff_failed++; -+ break; -+ } ++ test.len = ops->self_test_count(dev); ++ data = kmalloc(test.len * sizeof(u64), GFP_USER); ++ if (!data) ++ return -ENOMEM; + -+ /* 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); ++ ops->self_test(dev, &test, data); + -+ buffer_info->skb = skb; -+map_skb: -+ buffer_info->dma = pci_map_single(pdev, skb->data, -+ adapter->rx_buffer_len, -+ PCI_DMA_FROMDEVICE); -+ if (pci_dma_mapping_error(buffer_info->dma)) { -+ dev_err(&pdev->dev, "RX DMA map failed\n"); -+ adapter->rx_dma_failed++; -+ break; -+ } ++ 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; + -+ rx_desc = E1000_RX_DESC(*rx_ring, i); -+ rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); ++out: ++ kfree(data); ++ return ret; ++} + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ buffer_info = &rx_ring->buffer_info[i]; -+ } ++static int ethtool_get_strings(struct net_device *dev, void *useraddr) ++{ ++ struct ethtool_gstrings gstrings; ++ struct ethtool_ops *ops = ethtool_ops; ++ u8 *data; ++ int ret; + -+ if (rx_ring->next_to_use != i) { -+ rx_ring->next_to_use = i; -+ if (i-- == 0) -+ i = (rx_ring->count - 1); ++ if (!ops->get_strings) ++ return -EOPNOTSUPP; + -+ /* 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->tail); ++ 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; +} + -+/** -+ * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split -+ * @adapter: address of board private structure -+ **/ -+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, -+ int cleaned_count) ++static int ethtool_phys_id(struct net_device *dev, void *useraddr) +{ -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ union e1000_rx_desc_packet_split *rx_desc; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_buffer *buffer_info; -+ struct e1000_ps_page *ps_page; -+ struct sk_buff *skb; -+ unsigned int i, j; ++ struct ethtool_value id; + -+ i = rx_ring->next_to_use; -+ buffer_info = &rx_ring->buffer_info[i]; ++ if (!ethtool_ops->phys_id) ++ return -EOPNOTSUPP; + -+ while (cleaned_count--) { -+ rx_desc = E1000_RX_DESC_PS(*rx_ring, i); ++ if (copy_from_user(&id, useraddr, sizeof(id))) ++ return -EFAULT; + -+ for (j = 0; j < PS_PAGE_BUFFERS; j++) { -+ ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) -+ + j]; -+ if (j < adapter->rx_ps_pages) { -+ if (!ps_page->page) { -+ ps_page->page = alloc_page(GFP_ATOMIC); -+ if (!ps_page->page) { -+ adapter->alloc_rx_buff_failed++; -+ goto no_buffers; -+ } -+ ps_page->dma = pci_map_page(pdev, -+ ps_page->page, -+ 0, PAGE_SIZE, -+ PCI_DMA_FROMDEVICE); -+ if (pci_dma_mapping_error( -+ ps_page->dma)) { -+ dev_err(&adapter->pdev->dev, -+ "RX DMA page map failed\n"); -+ adapter->rx_dma_failed++; -+ goto no_buffers; -+ } -+ } -+ /* -+ * 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); -+ } else { -+ rx_desc->read.buffer_addr[j+1] = ~0; -+ } -+ } ++ return ethtool_ops->phys_id(dev, id.data); ++} + -+ skb = netdev_alloc_skb(netdev, -+ adapter->rx_ps_bsize0 + NET_IP_ALIGN); ++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 (!skb) { -+ adapter->alloc_rx_buff_failed++; -+ break; -+ } ++ if (!ops->get_ethtool_stats || !ops->get_stats_count) ++ return -EOPNOTSUPP; + -+ /* 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); ++ if (copy_from_user(&stats, useraddr, sizeof(stats))) ++ return -EFAULT; + -+ buffer_info->skb = skb; -+ buffer_info->dma = pci_map_single(pdev, skb->data, -+ adapter->rx_ps_bsize0, -+ PCI_DMA_FROMDEVICE); -+ if (pci_dma_mapping_error(buffer_info->dma)) { -+ dev_err(&pdev->dev, "RX DMA map failed\n"); -+ adapter->rx_dma_failed++; -+ /* cleanup skb */ -+ dev_kfree_skb_any(skb); -+ buffer_info->skb = NULL; -+ break; -+ } ++ 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; ++ u32 ethcmd; ++ ++ /* ++ * XXX: This can be pushed down into the ethtool_* handlers that ++ * need it. Keep existing behavior for the moment. ++ */ ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; + -+ rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); ++ if (!dev || !netif_device_present(dev)) ++ return -ENODEV; + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ buffer_info = &rx_ring->buffer_info[i]; ++ 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; + } + -+no_buffers: -+ if (rx_ring->next_to_use != i) { -+ rx_ring->next_to_use = i; ++ return -EOPNOTSUPP; ++} + -+ if (!(i--)) -+ i = (rx_ring->count - 1); ++#define mii_if_info _kc_mii_if_info ++struct _kc_mii_if_info { ++ int phy_id; ++ int advertising; ++ int phy_id_mask; ++ int reg_num_mask; + -+ /* 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->tail); ++ unsigned int full_duplex : 1; /* is full duplex? */ ++ unsigned int force_media : 1; /* is autoneg. disabled? */ ++ ++ struct net_device *dev; ++ int (*mdio_read) (struct net_device *dev, int phy_id, int location); ++ void (*mdio_write) (struct net_device *dev, int phy_id, int location, int val); ++}; ++ ++struct ethtool_cmd; ++struct mii_ioctl_data; ++ ++#undef mii_link_ok ++#define mii_link_ok _kc_mii_link_ok ++#undef mii_nway_restart ++#define mii_nway_restart _kc_mii_nway_restart ++#undef mii_ethtool_gset ++#define mii_ethtool_gset _kc_mii_ethtool_gset ++#undef mii_ethtool_sset ++#define mii_ethtool_sset _kc_mii_ethtool_sset ++#undef mii_check_link ++#define mii_check_link _kc_mii_check_link ++#undef generic_mii_ioctl ++#define generic_mii_ioctl _kc_generic_mii_ioctl ++extern int _kc_mii_link_ok (struct mii_if_info *mii); ++extern int _kc_mii_nway_restart (struct mii_if_info *mii); ++extern int _kc_mii_ethtool_gset(struct mii_if_info *mii, ++ struct ethtool_cmd *ecmd); ++extern int _kc_mii_ethtool_sset(struct mii_if_info *mii, ++ struct ethtool_cmd *ecmd); ++extern void _kc_mii_check_link (struct mii_if_info *mii); ++extern int _kc_generic_mii_ioctl(struct mii_if_info *mii_if, ++ struct mii_ioctl_data *mii_data, int cmd, ++ unsigned int *duplex_changed); ++ ++ ++struct _kc_pci_dev_ext { ++ struct pci_dev *dev; ++ void *pci_drvdata; ++ struct pci_driver *driver; ++}; ++ ++struct _kc_net_dev_ext { ++ struct net_device *dev; ++ unsigned int carrier; ++}; ++ ++ ++/**************************************/ ++/* mii support */ ++ ++int _kc_mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) ++{ ++ struct net_device *dev = mii->dev; ++ u32 advert, bmcr, lpa, nego; ++ ++ ecmd->supported = ++ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | ++ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII); ++ ++ /* only supports twisted-pair */ ++ ecmd->port = PORT_MII; ++ ++ /* only supports internal transceiver */ ++ ecmd->transceiver = XCVR_INTERNAL; ++ ++ /* this isn't fully supported at higher layers */ ++ ecmd->phy_address = mii->phy_id; ++ ++ ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII; ++ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); ++ if (advert & ADVERTISE_10HALF) ++ ecmd->advertising |= ADVERTISED_10baseT_Half; ++ if (advert & ADVERTISE_10FULL) ++ ecmd->advertising |= ADVERTISED_10baseT_Full; ++ if (advert & ADVERTISE_100HALF) ++ ecmd->advertising |= ADVERTISED_100baseT_Half; ++ if (advert & ADVERTISE_100FULL) ++ ecmd->advertising |= ADVERTISED_100baseT_Full; ++ ++ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); ++ lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA); ++ if (bmcr & BMCR_ANENABLE) { ++ ecmd->advertising |= ADVERTISED_Autoneg; ++ ecmd->autoneg = AUTONEG_ENABLE; ++ ++ nego = mii_nway_result(advert & lpa); ++ if (nego == LPA_100FULL || nego == LPA_100HALF) ++ ecmd->speed = SPEED_100; ++ else ++ ecmd->speed = SPEED_10; ++ if (nego == LPA_100FULL || nego == LPA_10FULL) { ++ ecmd->duplex = DUPLEX_FULL; ++ mii->full_duplex = 1; ++ } else { ++ ecmd->duplex = DUPLEX_HALF; ++ mii->full_duplex = 0; ++ } ++ } else { ++ ecmd->autoneg = AUTONEG_DISABLE; ++ ++ ecmd->speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10; ++ ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF; + } ++ ++ /* ignore maxtxpkt, maxrxpkt for now */ ++ ++ return 0; +} + -+/** -+ * e1000_alloc_rx_buffers_jumbo - Replace used jumbo receive buffers -+ * -+ * @adapter: address of board private structure -+ * @cleaned_count: number of buffers to allocate this pass -+ **/ -+static void e1000_alloc_rx_buffers_jumbo(struct e1000_adapter *adapter, -+ int cleaned_count) ++int _kc_mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd) +{ -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_rx_desc *rx_desc; -+ struct e1000_buffer *buffer_info; -+ struct sk_buff *skb; -+ unsigned int i; -+ unsigned int bufsz = 256 - -+ 16 /*for skb_reserve */ - -+ NET_IP_ALIGN; ++ struct net_device *dev = mii->dev; + -+ i = rx_ring->next_to_use; -+ buffer_info = &rx_ring->buffer_info[i]; ++ if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100) ++ return -EINVAL; ++ if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL) ++ return -EINVAL; ++ if (ecmd->port != PORT_MII) ++ return -EINVAL; ++ if (ecmd->transceiver != XCVR_INTERNAL) ++ return -EINVAL; ++ if (ecmd->phy_address != mii->phy_id) ++ return -EINVAL; ++ if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE) ++ return -EINVAL; ++ ++ /* ignore supported, maxtxpkt, maxrxpkt */ ++ ++ if (ecmd->autoneg == AUTONEG_ENABLE) { ++ u32 bmcr, advert, tmp; + -+ while (cleaned_count--) { -+ skb = buffer_info->skb; -+ if (skb) { -+ skb_trim(skb, 0); -+ goto check_page; -+ } ++ if ((ecmd->advertising & (ADVERTISED_10baseT_Half | ++ ADVERTISED_10baseT_Full | ++ ADVERTISED_100baseT_Half | ++ ADVERTISED_100baseT_Full)) == 0) ++ return -EINVAL; + -+ skb = netdev_alloc_skb(netdev, bufsz); -+ if (!skb) { -+ /* Better luck next round */ -+ adapter->alloc_rx_buff_failed++; -+ break; ++ /* advertise only what has been requested */ ++ advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE); ++ tmp = advert & ~(ADVERTISE_ALL | ADVERTISE_100BASE4); ++ if (ADVERTISED_10baseT_Half) ++ tmp |= ADVERTISE_10HALF; ++ if (ADVERTISED_10baseT_Full) ++ tmp |= ADVERTISE_10FULL; ++ if (ADVERTISED_100baseT_Half) ++ tmp |= ADVERTISE_100HALF; ++ if (ADVERTISED_100baseT_Full) ++ tmp |= ADVERTISE_100FULL; ++ if (advert != tmp) { ++ mii->mdio_write(dev, mii->phy_id, MII_ADVERTISE, tmp); ++ mii->advertising = tmp; + } ++ ++ /* turn on autonegotiation, and force a renegotiate */ ++ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); ++ bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); ++ mii->mdio_write(dev, mii->phy_id, MII_BMCR, bmcr); + -+ /* 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); ++ mii->force_media = 0; ++ } else { ++ u32 bmcr, tmp; ++ ++ /* turn off auto negotiation, set speed and duplexity */ ++ bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR); ++ tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX); ++ if (ecmd->speed == SPEED_100) ++ tmp |= BMCR_SPEED100; ++ if (ecmd->duplex == DUPLEX_FULL) { ++ tmp |= BMCR_FULLDPLX; ++ mii->full_duplex = 1; ++ } else ++ mii->full_duplex = 0; ++ if (bmcr != tmp) ++ mii->mdio_write(dev, mii->phy_id, MII_BMCR, tmp); ++ ++ mii->force_media = 1; ++ } ++ return 0; ++} + -+ buffer_info->skb = skb; -+check_page: -+ /* allocate a new page if necessary */ -+ if (!buffer_info->page) { -+ buffer_info->page = alloc_page(GFP_ATOMIC); -+ if (!buffer_info->page) { -+ adapter->alloc_rx_buff_failed++; -+ break; -+ } -+ } ++int _kc_mii_link_ok (struct mii_if_info *mii) ++{ ++ /* first, a dummy read, needed to latch some MII phys */ ++ mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR); ++ if (mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR) & BMSR_LSTATUS) ++ return 1; ++ return 0; ++} + -+ if (!buffer_info->dma) -+ buffer_info->dma = pci_map_page(pdev, -+ buffer_info->page, 0, -+ PAGE_SIZE, -+ PCI_DMA_FROMDEVICE); -+ if (pci_dma_mapping_error(buffer_info->dma)) { -+ dev_err(&adapter->pdev->dev, "RX DMA page map failed\n"); -+ adapter->rx_dma_failed++; -+ break; -+ } ++int _kc_mii_nway_restart (struct mii_if_info *mii) ++{ ++ int bmcr; ++ int r = -EINVAL; + -+ rx_desc = E1000_RX_DESC(*rx_ring, i); -+ rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); ++ /* if autoneg is off, it's an error */ ++ bmcr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMCR); + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ buffer_info = &rx_ring->buffer_info[i]; ++ if (bmcr & BMCR_ANENABLE) { ++ bmcr |= BMCR_ANRESTART; ++ mii->mdio_write(mii->dev, mii->phy_id, MII_BMCR, bmcr); ++ r = 0; + } + -+ if (rx_ring->next_to_use != i) { -+ rx_ring->next_to_use = i; -+ if (i-- == 0) -+ i = (rx_ring->count - 1); ++ return r; ++} + -+ /* 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->tail); -+ } ++void _kc_mii_check_link (struct mii_if_info *mii) ++{ ++ int cur_link = mii_link_ok(mii); ++ int prev_link = netif_carrier_ok(mii->dev); ++ ++ if (cur_link && !prev_link) ++ netif_carrier_on(mii->dev); ++ else if (prev_link && !cur_link) ++ netif_carrier_off(mii->dev); +} + -+/** -+ * e1000_clean_rx_irq - Send received data up the network stack; legacy -+ * @adapter: board private structure -+ * -+ * the return value indicates whether actual cleaning was done, there -+ * is no guarantee that everything was cleaned -+ **/ -+static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, -+ int *work_done, int work_to_do) ++int _kc_generic_mii_ioctl(struct mii_if_info *mii_if, ++ struct mii_ioctl_data *mii_data, int cmd, ++ unsigned int *duplex_chg_out) +{ -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_rx_desc *rx_desc, *next_rxd; -+ struct e1000_buffer *buffer_info, *next_buffer; -+ u32 length; -+ unsigned int i; -+ int cleaned_count = 0; -+ bool cleaned = 0; -+ unsigned int total_rx_bytes = 0, total_rx_packets = 0; ++ int rc = 0; ++ unsigned int duplex_changed = 0; + -+ i = rx_ring->next_to_clean; -+ rx_desc = E1000_RX_DESC(*rx_ring, i); -+ buffer_info = &rx_ring->buffer_info[i]; ++ if (duplex_chg_out) ++ *duplex_chg_out = 0; + -+ while (rx_desc->status & E1000_RXD_STAT_DD) { -+ struct sk_buff *skb; -+ u8 status; ++ mii_data->phy_id &= mii_if->phy_id_mask; ++ mii_data->reg_num &= mii_if->reg_num_mask; + -+ if (*work_done >= work_to_do) -+ break; -+ (*work_done)++; ++ switch(cmd) { ++ case SIOCDEVPRIVATE: /* binary compat, remove in 2.5 */ ++ case SIOCGMIIPHY: ++ mii_data->phy_id = mii_if->phy_id; ++ /* fall through */ + -+ status = rx_desc->status; -+ skb = buffer_info->skb; -+ buffer_info->skb = NULL; ++ case SIOCDEVPRIVATE + 1:/* binary compat, remove in 2.5 */ ++ case SIOCGMIIREG: ++ mii_data->val_out = ++ mii_if->mdio_read(mii_if->dev, mii_data->phy_id, ++ mii_data->reg_num); ++ break; + -+ prefetch(skb->data - NET_IP_ALIGN); ++ case SIOCDEVPRIVATE + 2:/* binary compat, remove in 2.5 */ ++ case SIOCSMIIREG: { ++ u16 val = mii_data->val_in; + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ next_rxd = E1000_RX_DESC(*rx_ring, i); -+ prefetch(next_rxd); ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; + -+ next_buffer = &rx_ring->buffer_info[i]; ++ if (mii_data->phy_id == mii_if->phy_id) { ++ switch(mii_data->reg_num) { ++ case MII_BMCR: { ++ unsigned int new_duplex = 0; ++ if (val & (BMCR_RESET|BMCR_ANENABLE)) ++ mii_if->force_media = 0; ++ else ++ mii_if->force_media = 1; ++ if (mii_if->force_media && ++ (val & BMCR_FULLDPLX)) ++ new_duplex = 1; ++ if (mii_if->full_duplex != new_duplex) { ++ duplex_changed = 1; ++ mii_if->full_duplex = new_duplex; ++ } ++ break; ++ } ++ case MII_ADVERTISE: ++ mii_if->advertising = val; ++ break; ++ default: ++ /* do nothing */ ++ break; ++ } ++ } + -+ cleaned = 1; -+ cleaned_count++; -+ pci_unmap_single(pdev, -+ buffer_info->dma, -+ adapter->rx_buffer_len, -+ PCI_DMA_FROMDEVICE); -+ buffer_info->dma = 0; ++ mii_if->mdio_write(mii_if->dev, mii_data->phy_id, ++ mii_data->reg_num, val); ++ break; ++ } + -+ length = le16_to_cpu(rx_desc->length); ++ default: ++ rc = -EOPNOTSUPP; ++ break; ++ } + -+ /* !EOP means multiple descriptors were used to store a single -+ * packet, also make sure the frame isn't just CRC only */ -+ if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) { -+ /* All receives must fit into a single buffer */ -+ ndev_dbg(netdev, "%s: Receive packet consumed " -+ "multiple buffers\n", netdev->name); -+ /* recycle */ -+ buffer_info->skb = skb; -+ goto next_desc; -+ } ++ if ((rc == 0) && (duplex_chg_out) && (duplex_changed)) ++ *duplex_chg_out = 1; + -+ if (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) { -+ /* recycle */ -+ buffer_info->skb = skb; -+ goto next_desc; -+ } ++ return rc; ++} + -+ /* adjust length to remove Ethernet CRC */ -+ length -= 4; +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/kcompat.h linux-2.6.22-10/drivers/net/e1000e/kcompat.h +--- linux-2.6.22-0/drivers/net/e1000e/kcompat.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/kcompat.h 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,1627 @@ ++/******************************************************************************* + -+ /* probably a little skewed due to removing CRC */ -+ total_rx_bytes += length; -+ total_rx_packets++; ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ /* code added for copybreak, this should improve -+ * performance for small packets with large amounts -+ * of reassembly being done in the stack */ -+ if (length < copybreak) { -+ struct sk_buff *new_skb = -+ netdev_alloc_skb(netdev, length + NET_IP_ALIGN); -+ if (new_skb) { -+ skb_reserve(new_skb, NET_IP_ALIGN); -+ 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; -+ } -+ /* else just continue with the old one */ -+ } -+ /* end copybreak code */ -+ skb_put(skb, length); ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#ifndef _KCOMPAT_H_ ++#define _KCOMPAT_H_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ /* Receive Checksum Offload */ -+ e1000_rx_checksum(adapter, -+ (u32)(status) | -+ ((u32)(rx_desc->errors) << 24), -+ le16_to_cpu(rx_desc->csum), skb); ++/* NAPI enable/disable flags here */ + -+ e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special); ++#ifdef DRIVER_E1000E ++#define NAPI ++#endif + -+next_desc: -+ rx_desc->status = 0; ++#ifdef _E1000_H_ ++#ifdef CONFIG_E1000_NAPI ++#define NAPI ++#endif ++#ifdef E1000_NAPI ++#undef NAPI ++#define NAPI ++#endif ++#ifdef E1000E_NAPI ++#undef NAPI ++#define NAPI ++#endif ++#ifdef E1000_NO_NAPI ++#undef NAPI ++#endif ++#ifdef E1000E_NO_NAPI ++#undef NAPI ++#endif ++#endif + -+ /* return some buffers to hardware, one at a time is too slow */ -+ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { -+ adapter->alloc_rx_buf(adapter, 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, cleaned_count); + -+ adapter->total_rx_packets += total_rx_packets; -+ adapter->total_rx_bytes += total_rx_bytes; -+ return cleaned; -+} + -+static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, -+ u16 length) -+{ -+ bi->page = NULL; -+ skb->len += length; -+ skb->data_len += length; -+ skb->truesize += length; -+} + -+static void e1000_put_txbuf(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); -+ buffer_info->dma = 0; -+ } -+ if (buffer_info->skb) { -+ dev_kfree_skb_any(buffer_info->skb); -+ buffer_info->skb = NULL; -+ } -+} ++#ifdef DRIVER_E1000E ++#define adapter_struct e1000_adapter ++#define CONFIG_E1000E_MSIX ++#endif + -+static void e1000_print_tx_hang(struct e1000_adapter *adapter) -+{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ unsigned int i = tx_ring->next_to_clean; -+ unsigned int eop = tx_ring->buffer_info[i].next_to_watch; -+ struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop); -+ struct net_device *netdev = adapter->netdev; + -+ /* detected Tx unit hang */ -+ ndev_err(netdev, -+ "Detected Tx Unit Hang:\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", -+ readl(adapter->hw.hw_addr + tx_ring->head), -+ readl(adapter->hw.hw_addr + tx_ring->tail), -+ tx_ring->next_to_use, -+ tx_ring->next_to_clean, -+ tx_ring->buffer_info[eop].time_stamp, -+ eop, -+ jiffies, -+ eop_desc->upper.fields.status); -+} + -+/** -+ * e1000_clean_tx_irq - Reclaim resources after transmit completes -+ * @adapter: board private structure -+ * -+ * the return value indicates whether actual cleaning was done, there -+ * is no guarantee that everything was cleaned -+ **/ -+static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) -+{ -+ struct net_device *netdev = adapter->netdev; -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_tx_desc *tx_desc, *eop_desc; -+ struct e1000_buffer *buffer_info; -+ unsigned int i, eop; -+ unsigned int count = 0; -+ bool cleaned = 0; -+ unsigned int total_tx_bytes = 0, total_tx_packets = 0; + -+ i = tx_ring->next_to_clean; -+ eop = tx_ring->buffer_info[i].next_to_watch; -+ eop_desc = E1000_TX_DESC(*tx_ring, eop); ++/* and finally set defines so that the code sees the changes */ ++#ifdef NAPI ++#ifndef CONFIG_E1000_NAPI ++#define CONFIG_E1000_NAPI ++#endif ++#ifndef CONFIG_E1000E_NAPI ++#define CONFIG_E1000E_NAPI ++#endif ++#else ++#undef CONFIG_E1000_NAPI ++#undef CONFIG_E1000E_NAPI ++#undef CONFIG_IXGB_NAPI ++#endif + -+ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { -+ for (cleaned = 0; !cleaned; ) { -+ tx_desc = E1000_TX_DESC(*tx_ring, i); -+ buffer_info = &tx_ring->buffer_info[i]; -+ cleaned = (i == eop); ++/* packet split disable/enable */ ++#ifdef DISABLE_PACKET_SPLIT ++#undef CONFIG_E1000_DISABLE_PACKET_SPLIT ++#define CONFIG_E1000_DISABLE_PACKET_SPLIT ++#undef CONFIG_IGB_DISABLE_PACKET_SPLIT ++#define CONFIG_IGB_DISABLE_PACKET_SPLIT ++#endif + -+ if (cleaned) { -+ struct sk_buff *skb = buffer_info->skb; -+ unsigned int segs, bytecount; -+ segs = skb_shinfo(skb)->gso_segs ?: 1; -+ /* multiply data chunks by size of headers */ -+ bytecount = ((segs - 1) * skb_headlen(skb)) + -+ skb->len; -+ total_tx_packets += segs; -+ total_tx_bytes += bytecount; -+ } ++/* MSI compatibility code for all kernels and drivers */ ++#ifdef DISABLE_PCI_MSI ++#undef CONFIG_PCI_MSI ++#endif ++#ifndef CONFIG_PCI_MSI ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) ) ++struct msix_entry { ++ u16 vector; /* kernel uses to write allocated vector */ ++ u16 entry; /* driver uses to specify entry, OS writes */ ++}; ++#endif ++#define pci_enable_msi(a) -ENOTSUPP ++#define pci_disable_msi(a) do {} while (0) ++#define pci_enable_msix(a, b, c) -ENOTSUPP ++#define pci_disable_msix(a) do {} while (0) ++#define msi_remove_pci_irq_vectors(a) do {} while (0) ++#endif /* CONFIG_PCI_MSI */ ++#ifdef DISABLE_PM ++#undef CONFIG_PM ++#endif + -+ e1000_put_txbuf(adapter, buffer_info); -+ tx_desc->upper.data = 0; ++#ifdef DISABLE_NET_POLL_CONTROLLER ++#undef CONFIG_NET_POLL_CONTROLLER ++#endif + -+ i++; -+ if (i == tx_ring->count) -+ i = 0; -+ } ++#ifndef PMSG_SUSPEND ++#define PMSG_SUSPEND 3 ++#endif + -+ eop = tx_ring->buffer_info[i].next_to_watch; -+ eop_desc = E1000_TX_DESC(*tx_ring, eop); -+#define E1000_TX_WEIGHT 64 -+ /* weight of a sort for tx, to avoid endless transmit cleanup */ -+ if (count++ == E1000_TX_WEIGHT) -+ break; -+ } ++/* generic boolean compatibility */ ++#undef TRUE ++#undef FALSE ++#define TRUE true ++#define FALSE false ++#ifdef GCC_VERSION ++#if ( GCC_VERSION < 3000 ) ++#define _Bool char ++#endif ++#endif ++#ifndef bool ++#define bool _Bool ++#define true 1 ++#define false 0 ++#endif + -+ tx_ring->next_to_clean = i; + -+#define TX_WAKE_THRESHOLD 32 -+ if (cleaned && netif_carrier_ok(netdev) && -+ e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { -+ /* Make sure that anybody stopping the queue after this -+ * sees the new next_to_clean. -+ */ -+ smp_mb(); ++#ifndef module_param ++#define module_param(v,t,p) MODULE_PARM(v, "i"); ++#endif + -+ if (netif_queue_stopped(netdev) && -+ !(test_bit(__E1000_DOWN, &adapter->state))) { -+ netif_wake_queue(netdev); -+ ++adapter->restart_queue; -+ } -+ } ++#ifndef DMA_64BIT_MASK ++#define DMA_64BIT_MASK 0xffffffffffffffffULL ++#endif + -+ 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 = 0; -+ if (tx_ring->buffer_info[eop].dma && -+ time_after(jiffies, tx_ring->buffer_info[eop].time_stamp -+ + (adapter->tx_timeout_factor * HZ)) -+ && !(er32(STATUS) & -+ E1000_STATUS_TXOFF)) { -+ e1000_print_tx_hang(adapter); -+ netif_stop_queue(netdev); -+ } -+ } -+ adapter->total_tx_bytes += total_tx_bytes; -+ adapter->total_tx_packets += total_tx_packets; -+ return cleaned; -+} ++#ifndef DMA_32BIT_MASK ++#define DMA_32BIT_MASK 0x00000000ffffffffULL ++#endif + -+/** -+ * e1000_clean_rx_irq_jumbo - Send received data up the network stack; legacy -+ * @adapter: board private structure -+ * -+ * the return value indicates whether actual cleaning was done, there -+ * is no guarantee that everything was cleaned -+ **/ -+static bool e1000_clean_rx_irq_jumbo(struct e1000_adapter *adapter, -+ int *work_done, int work_to_do) -+{ -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_rx_desc *rx_desc, *next_rxd; -+ struct e1000_buffer *buffer_info, *next_buffer; -+ u32 length; -+ unsigned int i; -+ int cleaned_count = 0; -+ bool cleaned = 0; -+ unsigned int total_rx_bytes = 0, total_rx_packets = 0; ++#ifndef PCI_CAP_ID_EXP ++#define PCI_CAP_ID_EXP 0x10 ++#endif + -+ i = rx_ring->next_to_clean; -+ rx_desc = E1000_RX_DESC(*rx_ring, i); -+ buffer_info = &rx_ring->buffer_info[i]; ++#ifndef mmiowb ++#ifdef CONFIG_IA64 ++#define mmiowb() asm volatile ("mf.a" ::: "memory") ++#else ++#define mmiowb() ++#endif ++#endif + -+ while (rx_desc->status & E1000_RXD_STAT_DD) { -+ struct sk_buff *skb; -+ u8 status; ++#ifndef IRQ_HANDLED ++#define irqreturn_t void ++#define IRQ_HANDLED ++#define IRQ_NONE ++#endif + -+ if (*work_done >= work_to_do) -+ break; -+ (*work_done)++; ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) ++#endif + -+ status = rx_desc->status; -+ skb = buffer_info->skb; -+ buffer_info->skb = NULL; ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(x) kfree(x) ++#endif + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ next_rxd = E1000_RX_DESC(*rx_ring, i); -+ prefetch(next_rxd); ++#ifdef HAVE_POLL_CONTROLLER ++#define CONFIG_NET_POLL_CONTROLLER ++#endif + -+ next_buffer = &rx_ring->buffer_info[i]; ++#ifndef NETDEV_TX_OK ++#define NETDEV_TX_OK 0 ++#endif + -+ cleaned = 1; -+ cleaned_count++; -+ pci_unmap_page(pdev, -+ buffer_info->dma, -+ PAGE_SIZE, -+ PCI_DMA_FROMDEVICE); -+ buffer_info->dma = 0; ++#ifndef NETDEV_TX_BUSY ++#define NETDEV_TX_BUSY 1 ++#endif + -+ length = le16_to_cpu(rx_desc->length); ++#ifndef NETDEV_TX_LOCKED ++#define NETDEV_TX_LOCKED -1 ++#endif + -+ /* errors is only valid for DD + EOP descriptors */ -+ if ((status & E1000_RXD_STAT_EOP) && -+ (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { -+ /* recycle both page and skb */ -+ buffer_info->skb = skb; -+ /* an error means any chain goes out the window too */ -+ if (rx_ring->rx_skb_top) -+ dev_kfree_skb(rx_ring->rx_skb_top); -+ rx_ring->rx_skb_top = NULL; -+ goto next_desc; -+ } ++#ifndef SKB_DATAREF_SHIFT ++/* if we do not have the infrastructure to detect if skb_header is cloned ++ just return false in all cases */ ++#define skb_header_cloned(x) 0 ++#endif + -+#define rxtop rx_ring->rx_skb_top -+ if (!(status & E1000_RXD_STAT_EOP)) { -+ /* this descriptor is only the beginning (or middle) */ -+ if (!rxtop) { -+ /* this is the beginning of a chain */ -+ rxtop = skb; -+ skb_fill_page_desc(rxtop, 0, buffer_info->page, -+ 0, length); -+ } else { -+ /* this is the middle of a chain */ -+ skb_fill_page_desc(rxtop, -+ skb_shinfo(rxtop)->nr_frags, -+ buffer_info->page, 0, -+ length); -+ /* re-use the skb, only consumed the page */ -+ buffer_info->skb = skb; -+ } -+ e1000_consume_page(buffer_info, rxtop, length); -+ goto next_desc; -+ } else { -+ if (rxtop) { -+ /* end of the chain */ -+ skb_fill_page_desc(rxtop, -+ skb_shinfo(rxtop)->nr_frags, -+ buffer_info->page, 0, length); -+ /* re-use the current skb, we only consumed the -+ * page */ -+ buffer_info->skb = skb; -+ skb = rxtop; -+ rxtop = NULL; -+ e1000_consume_page(buffer_info, skb, length); -+ } else { -+ /* no chain, got EOP, this buf is the packet -+ * copybreak to save the put_page/alloc_page */ -+ if (length <= copybreak && -+ skb_tailroom(skb) >= length) { -+ u8 *vaddr; -+ vaddr = kmap_atomic(buffer_info->page, -+ KM_SKB_DATA_SOFTIRQ); -+ memcpy(skb_tail_pointer(skb), -+ vaddr, length); -+ kunmap_atomic(vaddr, -+ KM_SKB_DATA_SOFTIRQ); -+ /* re-use the page, so don't erase -+ * buffer_info->page */ -+ skb_put(skb, length); -+ } else { -+ skb_fill_page_desc(skb, 0, -+ buffer_info->page, 0, -+ length); -+ e1000_consume_page(buffer_info, skb, -+ length); -+ } -+ } -+ } ++#ifndef NETIF_F_GSO ++#define gso_size tso_size ++#define gso_segs tso_segs ++#endif ++ ++#ifndef CHECKSUM_PARTIAL ++#define CHECKSUM_PARTIAL CHECKSUM_HW ++#define CHECKSUM_COMPLETE CHECKSUM_HW ++#endif ++ ++#ifndef __read_mostly ++#define __read_mostly ++#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, ++}; ++ ++#else ++#define NETIF_MSG_HW 0x2000 ++#define NETIF_MSG_WOL 0x4000 ++#endif /* HAVE_NETIF_MSG */ + -+ /* Receive Checksum Offload XXX recompute due to CRC strip? */ -+ e1000_rx_checksum(adapter, -+ (u32)(status) | -+ ((u32)(rx_desc->errors) << 24), -+ le16_to_cpu(rx_desc->csum), skb); ++#ifndef MII_RESV1 ++#define MII_RESV1 0x17 /* Reserved... */ ++#endif + -+ pskb_trim(skb, skb->len - 4); ++#ifndef unlikely ++#define unlikely(_x) _x ++#define likely(_x) _x ++#endif + -+ /* probably a little skewed due to removing CRC */ -+ total_rx_bytes += skb->len; -+ total_rx_packets++; ++#ifndef WARN_ON ++#define WARN_ON(x) ++#endif + -+ /* eth type trans needs skb->data to point to something */ -+ if (!pskb_may_pull(skb, ETH_HLEN)) { -+ ndev_err(netdev, "__pskb_pull_tail failed.\n"); -+ dev_kfree_skb(skb); -+ goto next_desc; -+ } ++#ifndef PCI_DEVICE ++#define PCI_DEVICE(vend,dev) \ ++ .vendor = (vend), .device = (dev), \ ++ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID ++#endif + -+ e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special); ++#ifndef num_online_cpus ++#define num_online_cpus() smp_num_cpus ++#endif + -+next_desc: -+ rx_desc->status = 0; ++#ifndef _LINUX_RANDOM_H ++#include ++#endif + -+ /* return some buffers to hardware, one at a time is too slow */ -+ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { -+ adapter->alloc_rx_buf(adapter, cleaned_count); -+ cleaned_count = 0; -+ } ++#ifndef DECLARE_BITMAP ++#ifndef BITS_TO_LONGS ++#define BITS_TO_LONGS(bits) (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) ++#endif ++#define DECLARE_BITMAP(name,bits) long name[BITS_TO_LONGS(bits)] ++#endif + -+ /* use prefetched values */ -+ rx_desc = next_rxd; -+ buffer_info = next_buffer; -+ } -+ rx_ring->next_to_clean = i; ++#ifndef VLAN_HLEN ++#define VLAN_HLEN 4 ++#endif + -+ cleaned_count = e1000_desc_unused(rx_ring); -+ if (cleaned_count) -+ adapter->alloc_rx_buf(adapter, cleaned_count); ++#ifndef VLAN_ETH_HLEN ++#define VLAN_ETH_HLEN 18 ++#endif + -+ adapter->total_rx_packets += total_rx_packets; -+ adapter->total_rx_bytes += total_rx_bytes; -+ return cleaned; -+} ++#ifndef VLAN_ETH_FRAME_LEN ++#define VLAN_ETH_FRAME_LEN 1518 ++#endif + -+/** -+ * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split -+ * @adapter: board private structure -+ * -+ * the return value indicates whether actual cleaning was done, there -+ * is no guarantee that everything was cleaned -+ **/ -+static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, -+ int *work_done, int work_to_do) -+{ -+ union e1000_rx_desc_packet_split *rx_desc, *next_rxd; -+ struct net_device *netdev = adapter->netdev; -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_buffer *buffer_info, *next_buffer; -+ struct e1000_ps_page *ps_page; -+ struct sk_buff *skb; -+ unsigned int i, j; -+ u32 length, staterr; -+ int cleaned_count = 0; -+ bool cleaned = 0; -+ unsigned int total_rx_bytes = 0, total_rx_packets = 0; ++#ifndef DCA_GET_TAG_TWO_ARGS ++#define dca3_get_tag(a,b) dca_get_tag(b) ++#endif + -+ 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) { -+ if (*work_done >= work_to_do) -+ break; -+ (*work_done)++; -+ skb = buffer_info->skb; ++/*****************************************************************************/ ++/* Installations with ethtool version without eeprom, adapter id, or statistics ++ * support */ + -+ /* in the packet split case this is header only */ -+ prefetch(skb->data - NET_IP_ALIGN); ++#ifndef ETH_GSTRING_LEN ++#define ETH_GSTRING_LEN 32 ++#endif + -+ i++; -+ if (i == rx_ring->count) -+ i = 0; -+ next_rxd = E1000_RX_DESC_PS(*rx_ring, i); -+ prefetch(next_rxd); ++#ifndef ETHTOOL_GSTATS ++#define ETHTOOL_GSTATS 0x1d ++#undef ethtool_drvinfo ++#define ethtool_drvinfo k_ethtool_drvinfo ++struct k_ethtool_drvinfo { ++ u32 cmd; ++ char driver[32]; ++ char version[32]; ++ char fw_version[32]; ++ char bus_info[32]; ++ char reserved1[32]; ++ char reserved2[16]; ++ u32 n_stats; ++ u32 testinfo_len; ++ u32 eedump_len; ++ u32 regdump_len; ++}; + -+ next_buffer = &rx_ring->buffer_info[i]; ++struct ethtool_stats { ++ u32 cmd; ++ u32 n_stats; ++ u64 data[0]; ++}; ++#endif /* ETHTOOL_GSTATS */ + -+ cleaned = 1; -+ cleaned_count++; -+ pci_unmap_single(pdev, buffer_info->dma, -+ adapter->rx_ps_bsize0, -+ PCI_DMA_FROMDEVICE); -+ buffer_info->dma = 0; ++#ifndef ETHTOOL_PHYS_ID ++#define ETHTOOL_PHYS_ID 0x1c ++#endif /* ETHTOOL_PHYS_ID */ + -+ if (!(staterr & E1000_RXD_STAT_EOP)) { -+ ndev_dbg(netdev, "%s: Packet Split buffers didn't pick " -+ "up the full packet\n", netdev->name); -+ dev_kfree_skb_irq(skb); -+ goto next_desc; -+ } ++#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]; ++}; ++#endif /* ETHTOOL_GSTRINGS */ + -+ if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { -+ dev_kfree_skb_irq(skb); -+ goto next_desc; -+ } ++#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 { ++ u32 cmd; ++ u32 flags; ++ u32 reserved; ++ u32 len; ++ u64 data[0]; ++}; ++#endif /* ETHTOOL_TEST */ ++ ++#ifndef ETHTOOL_GEEPROM ++#define ETHTOOL_GEEPROM 0xb ++#undef ETHTOOL_GREGS ++struct ethtool_eeprom { ++ u32 cmd; ++ u32 magic; ++ u32 offset; ++ u32 len; ++ u8 data[0]; ++}; + -+ length = le16_to_cpu(rx_desc->wb.middle.length0); ++struct ethtool_value { ++ u32 cmd; ++ u32 data; ++}; ++#endif /* ETHTOOL_GEEPROM */ ++ ++#ifndef ETHTOOL_GLINK ++#define ETHTOOL_GLINK 0xa ++#endif /* ETHTOOL_GLINK */ ++ ++#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 /* ETHTOOL_GREGS */ + -+ if (!length) { -+ ndev_dbg(netdev, "%s: Last part of the packet spanning" -+ " multiple descriptors\n", netdev->name); -+ dev_kfree_skb_irq(skb); -+ goto next_desc; -+ } ++#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; + -+ /* Good Receive */ -+ skb_put(skb, length); ++ /* 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; + -+ { -+ /* 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]); ++ /* 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; + -+ /* page alloc/put takes too long and effects small packet -+ * throughput, so unsplit small packets and save the alloc/put*/ -+ if (l1 && (l1 <= copybreak) && -+ ((length + l1) <= adapter->rx_ps_bsize0)) { -+ u8 *vaddr; ++ /* 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; + -+ ps_page = &rx_ring->ps_pages[i * PS_PAGE_BUFFERS]; ++ /* 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; + -+ /* 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, -+ PAGE_SIZE, PCI_DMA_FROMDEVICE); -+ vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ); -+ memcpy(skb_tail_pointer(skb), vaddr, l1); -+ kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); -+ pci_dma_sync_single_for_device(pdev, ps_page->dma, -+ PAGE_SIZE, PCI_DMA_FROMDEVICE); -+ /* remove the CRC */ -+ l1 -= 4; -+ skb_put(skb, l1); -+ goto copydone; -+ } /* if */ -+ } ++ /* 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; + -+ for (j = 0; j < PS_PAGE_BUFFERS; j++) { -+ length = le16_to_cpu(rx_desc->wb.upper.length[j]); -+ if (!length) -+ break; ++ /* 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; + -+ ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) + j]; -+ pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, -+ PCI_DMA_FROMDEVICE); -+ ps_page->dma = 0; -+ skb_fill_page_desc(skb, j, ps_page->page, 0, length); -+ ps_page->page = NULL; -+ skb->len += length; -+ skb->data_len += length; -+ skb->truesize += length; -+ } ++ /* 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. ++ */ + -+ /* 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); ++ /* 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 /* ETHTOOL_GCOALESCE */ + -+copydone: -+ total_rx_bytes += skb->len; -+ total_rx_packets++; ++#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; + -+ e1000_rx_checksum(adapter, staterr, le16_to_cpu( -+ rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); ++ /* 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 /* ETHTOOL_GRINGPARAM */ + -+ if (rx_desc->wb.upper.header_status & -+ cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) -+ adapter->rx_hdr_split++; ++#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 'autoneg' 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 /* ETHTOOL_GPAUSEPARAM */ + -+ e1000_receive_skb(adapter, netdev, skb, -+ staterr, rx_desc->wb.middle.vlan); ++#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 + -+next_desc: -+ rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); -+ buffer_info->skb = NULL; ++#ifndef ETHTOOL_BUSINFO_LEN ++#define ETHTOOL_BUSINFO_LEN 32 ++#endif + -+ /* return some buffers to hardware, one at a time is too slow */ -+ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { -+ adapter->alloc_rx_buf(adapter, cleaned_count); -+ cleaned_count = 0; -+ } ++/*****************************************************************************/ ++/* 2.4.3 => 2.4.0 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) ) + -+ /* use prefetched values */ -+ rx_desc = next_rxd; -+ buffer_info = next_buffer; ++/**************************************/ ++/* PCI DRIVER API */ + -+ staterr = le32_to_cpu(rx_desc->wb.middle.status_error); -+ } -+ rx_ring->next_to_clean = i; ++#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 + -+ cleaned_count = e1000_desc_unused(rx_ring); -+ if (cleaned_count) -+ adapter->alloc_rx_buf(adapter, cleaned_count); ++#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 + -+ adapter->total_rx_packets += total_rx_packets; -+ adapter->total_rx_bytes += total_rx_bytes; -+ return cleaned; -+} ++#ifndef pci_release_regions ++#define pci_release_regions _kc_pci_release_regions ++extern void _kc_pci_release_regions(struct pci_dev *pdev); ++#endif + -+/** -+ * e1000_clean_rx_ring - Free Rx Buffers per Queue -+ * @adapter: board private structure -+ **/ -+static void e1000_clean_rx_ring(struct e1000_adapter *adapter) -+{ -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ struct e1000_buffer *buffer_info; -+ struct e1000_ps_page *ps_page; -+ struct pci_dev *pdev = adapter->pdev; -+ unsigned long size; -+ unsigned int i, j; ++/**************************************/ ++/* NETWORK DRIVER API */ + -+ /* Free all the Rx ring sk_buffs */ -+ for (i = 0; i < rx_ring->count; i++) { -+ buffer_info = &rx_ring->buffer_info[i]; -+ if (buffer_info->dma) { -+ if (adapter->clean_rx == e1000_clean_rx_irq) -+ pci_unmap_single(pdev, buffer_info->dma, -+ adapter->rx_buffer_len, -+ PCI_DMA_FROMDEVICE); -+ else if (adapter->clean_rx == e1000_clean_rx_irq_jumbo) -+ pci_unmap_page(pdev, buffer_info->dma, -+ PAGE_SIZE, PCI_DMA_FROMDEVICE); -+ else if (adapter->clean_rx == e1000_clean_rx_irq_ps) -+ pci_unmap_single(pdev, buffer_info->dma, -+ adapter->rx_ps_bsize0, -+ PCI_DMA_FROMDEVICE); -+ buffer_info->dma = 0; -+ } ++#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 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) ) ++/* Generic MII registers. */ ++#define MII_BMCR 0x00 /* Basic mode control register */ ++#define MII_BMSR 0x01 /* Basic mode status register */ ++#define MII_PHYSID1 0x02 /* PHYS ID 1 */ ++#define MII_PHYSID2 0x03 /* PHYS ID 2 */ ++#define MII_ADVERTISE 0x04 /* Advertisement control reg */ ++#define MII_LPA 0x05 /* Link partner ability reg */ ++#define MII_EXPANSION 0x06 /* Expansion register */ ++/* Basic mode control register. */ ++#define BMCR_FULLDPLX 0x0100 /* Full duplex */ ++#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */ ++/* Basic mode status register. */ ++#define BMSR_ERCAP 0x0001 /* Ext-reg capability */ ++#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ ++#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ ++#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ ++#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ ++#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */ ++/* Advertisement control register. */ ++#define ADVERTISE_CSMA 0x0001 /* Only selector supported */ ++#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ ++#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ ++#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */ ++#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */ ++#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ ++ ADVERTISE_100HALF | ADVERTISE_100FULL) ++/* Expansion register for auto-negotiation. */ ++#define EXPANSION_ENABLENPAGE 0x0004 /* This enables npage words */ ++#endif + -+ if (buffer_info->page) { -+ put_page(buffer_info->page); -+ buffer_info->page = NULL; -+ } ++/*****************************************************************************/ ++/* 2.4.6 => 2.4.3 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6) ) + -+ if (buffer_info->skb) { -+ dev_kfree_skb(buffer_info->skb); -+ buffer_info->skb = NULL; -+ } ++#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 + -+ for (j = 0; j < PS_PAGE_BUFFERS; j++) { -+ ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) -+ + j]; -+ if (!ps_page->page) -+ break; -+ pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, -+ PCI_DMA_FROMDEVICE); -+ ps_page->dma = 0; -+ put_page(ps_page->page); -+ ps_page->page = NULL; -+ } -+ } ++#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 + -+ /* there also may be some cached data from a chained receive */ -+ if (rx_ring->rx_skb_top) { -+ dev_kfree_skb(rx_ring->rx_skb_top); -+ rx_ring->rx_skb_top = NULL; -+ } ++#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 + -+ size = sizeof(struct e1000_buffer) * rx_ring->count; -+ memset(rx_ring->buffer_info, 0, size); -+ size = sizeof(struct e1000_ps_page) -+ * (rx_ring->count * PS_PAGE_BUFFERS); -+ memset(rx_ring->ps_pages, 0, size); ++#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 + -+ /* Zero out the descriptor ring */ -+ memset(rx_ring->desc, 0, rx_ring->size); ++#ifndef pci_disable_device ++#define pci_disable_device _kc_pci_disable_device ++extern void _kc_pci_disable_device(struct pci_dev *pdev); ++#endif + -+ rx_ring->next_to_clean = 0; -+ rx_ring->next_to_use = 0; ++/* PCI PM entry point syntax changed, so don't support suspend/resume */ ++#undef CONFIG_PM + -+ writel(0, adapter->hw.hw_addr + rx_ring->head); -+ writel(0, adapter->hw.hw_addr + rx_ring->tail); -+} ++#endif /* 2.4.6 => 2.4.3 */ + -+/** -+ * e1000_intr_msi - Interrupt Handler -+ * @irq: interrupt number -+ * @data: pointer to a network interface device structure -+ **/ -+static irqreturn_t e1000_intr_msi(int irq, void *data) -+{ -+ struct net_device *netdev = data; -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u32 icr = er32(ICR); ++#ifndef HAVE_PCI_SET_MWI ++#define pci_set_mwi(X) pci_write_config_word(X, \ ++ PCI_COMMAND, adapter->hw.bus.pci_cmd_word | \ ++ PCI_COMMAND_INVALIDATE); ++#define pci_clear_mwi(X) pci_write_config_word(X, \ ++ PCI_COMMAND, adapter->hw.bus.pci_cmd_word & \ ++ ~PCI_COMMAND_INVALIDATE); ++#endif + -+ /* read ICR disables interrupts using IAM, so keep up with our -+ * enable/disable accounting */ -+ atomic_inc(&adapter->irq_sem); ++/*****************************************************************************/ ++/* 2.4.10 => 2.4.9 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) ) + -+ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { -+ hw->mac.get_link_status = 1; -+ /* ICH8 workaround-- Call gig speed drop workaround on cable -+ * disconnect (LSC) before accessing any PHY registers */ -+ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && -+ (!(er32(STATUS) & E1000_STATUS_LU))) -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++/**************************************/ ++/* MODULE API */ + -+ /* 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->flags & FLAG_RX_NEEDS_RESTART) { -+ /* disable receives */ -+ u32 rctl = er32(RCTL); -+ ew32(RCTL, rctl & ~E1000_RCTL_EN); -+ } -+ /* guard against interrupt when we're going down */ -+ if (!test_bit(__E1000_DOWN, &adapter->state)) -+ mod_timer(&adapter->watchdog_timer, jiffies + 1); -+ } ++#ifndef MODULE_LICENSE ++ #define MODULE_LICENSE(X) ++#endif + -+ if (netif_rx_schedule_prep(netdev)) { -+ adapter->total_tx_bytes = 0; -+ adapter->total_tx_packets = 0; -+ adapter->total_rx_bytes = 0; -+ adapter->total_rx_packets = 0; -+ __netif_rx_schedule(netdev); -+ } else { -+ atomic_dec(&adapter->irq_sem); -+ } ++/**************************************/ ++/* OTHER */ ++ ++#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; }) ++ ++#ifndef list_for_each_safe ++#define list_for_each_safe(pos, n, head) \ ++ for (pos = (head)->next, n = pos->next; pos != (head); \ ++ pos = n, n = pos->next) ++#endif + -+ return IRQ_HANDLED; -+} ++#endif /* 2.4.10 -> 2.4.6 */ + -+/** -+ * e1000_intr - Interrupt Handler -+ * @irq: interrupt number -+ * @data: pointer to a network interface device structure -+ **/ -+static irqreturn_t e1000_intr(int irq, void *data) -+{ -+ struct net_device *netdev = data; -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; + -+ u32 rctl, icr = er32(ICR); -+ if (!icr) -+ return IRQ_NONE; /* Not our interrupt */ ++/*****************************************************************************/ ++/* 2.4.13 => 2.4.10 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,13) ) + -+ /* IMS will not auto-mask if INT_ASSERTED is not set, and if it is -+ * not set, then the adapter didn't send an interrupt */ -+ if (!(icr & E1000_ICR_INT_ASSERTED)) -+ return IRQ_NONE; ++/**************************************/ ++/* PCI DMA MAPPING */ + -+ /* 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. */ -+ atomic_inc(&adapter->irq_sem); ++#ifndef virt_to_page ++ #define virt_to_page(v) (mem_map + (virt_to_phys(v) >> PAGE_SHIFT)) ++#endif + -+ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { -+ hw->mac.get_link_status = 1; -+ /* ICH8 workaround-- Call gig speed drop workaround on cable -+ * disconnect (LSC) before accessing any PHY registers */ -+ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && -+ (!(er32(STATUS) & E1000_STATUS_LU))) -+ e1000e_gig_downshift_workaround_ich8lan(hw); ++#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 + -+ /* 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->flags & FLAG_RX_NEEDS_RESTART)) { -+ /* disable receives */ -+ rctl = er32(RCTL); -+ ew32(RCTL, rctl & ~E1000_RCTL_EN); -+ } -+ /* guard against interrupt when we're going down */ -+ if (!test_bit(__E1000_DOWN, &adapter->state)) -+ mod_timer(&adapter->watchdog_timer, jiffies + 1); -+ } ++#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 + -+ if (netif_rx_schedule_prep(netdev)) { -+ adapter->total_tx_bytes = 0; -+ adapter->total_tx_packets = 0; -+ adapter->total_rx_bytes = 0; -+ adapter->total_rx_packets = 0; -+ __netif_rx_schedule(netdev); -+ } else { -+ atomic_dec(&adapter->irq_sem); -+ } ++/* pci_set_dma_mask takes dma_addr_t, which is only 32-bits prior to 2.4.13 */ + -+ return IRQ_HANDLED; -+} ++#undef DMA_32BIT_MASK ++#define DMA_32BIT_MASK 0xffffffff ++#undef DMA_64BIT_MASK ++#define DMA_64BIT_MASK 0xffffffff + -+static int e1000_request_irq(struct e1000_adapter *adapter) -+{ -+ struct net_device *netdev = adapter->netdev; -+ void (*handler) = &e1000_intr; -+ int irq_flags = IRQF_SHARED; -+ int err; ++/**************************************/ ++/* OTHER */ + -+ err = pci_enable_msi(adapter->pdev); -+ if (err) { -+ ndev_warn(netdev, -+ "Unable to allocate MSI interrupt Error: %d\n", err); -+ } else { -+ adapter->flags |= FLAG_MSI_ENABLED; -+ handler = &e1000_intr_msi; -+ irq_flags = 0; -+ } ++#ifndef cpu_relax ++#define cpu_relax() rep_nop() ++#endif + -+ err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name, -+ netdev); -+ if (err) { -+ if (adapter->flags & FLAG_MSI_ENABLED) -+ pci_disable_msi(adapter->pdev); -+ ndev_err(netdev, -+ "Unable to allocate interrupt Error: %d\n", err); -+ } ++#endif /* 2.4.13 => 2.4.10 */ + -+ return err; -+} ++/*****************************************************************************/ ++/* 2.4.17 => 2.4.12 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17) ) + -+static void e1000_free_irq(struct e1000_adapter *adapter) -+{ -+ struct net_device *netdev = adapter->netdev; ++#ifndef __devexit_p ++ #define __devexit_p(x) &(x) ++#endif + -+ free_irq(adapter->pdev->irq, netdev); -+ if (adapter->flags & FLAG_MSI_ENABLED) { -+ pci_disable_msi(adapter->pdev); -+ adapter->flags &= ~FLAG_MSI_ENABLED; ++#endif /* 2.4.17 => 2.4.13 */ ++ ++/*****************************************************************************/ ++/* 2.4.20 => 2.4.19 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20) ) ++ ++/* we won't support NAPI on less than 2.4.20 */ ++#ifdef NAPI ++#undef CONFIG_E1000_NAPI ++#undef CONFIG_E1000E_NAPI ++#undef CONFIG_IXGB_NAPI ++#endif ++ ++#endif /* 2.4.20 => 2.4.19 */ ++/*****************************************************************************/ ++/* 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.22 => 2.4.17 */ ++ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) ) ++#endif ++ ++/*****************************************************************************/ ++/*****************************************************************************/ ++/* 2.4.23 => 2.4.22 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) ) ++/*****************************************************************************/ ++#ifdef 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 + -+/** -+ * e1000_irq_disable - Mask off interrupt generation on the NIC -+ **/ -+static void e1000_irq_disable(struct e1000_adapter *adapter) ++#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) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ -+ atomic_inc(&adapter->irq_sem); -+ ew32(IMC, ~0); -+ e1e_flush(); -+ synchronize_irq(adapter->pdev->irq); ++ clear_bit(__LINK_STATE_RX_SCHED, &netdev->state); ++} ++#endif ++#endif /* NAPI */ ++#ifndef netif_tx_disable ++#define netif_tx_disable(x) _kc_netif_tx_disable(x) ++static inline void _kc_netif_tx_disable(struct net_device *dev) ++{ ++ spin_lock_bh(&dev->xmit_lock); ++ netif_stop_queue(dev); ++ spin_unlock_bh(&dev->xmit_lock); +} ++#endif ++#endif /* 2.4.23 => 2.4.22 */ ++ ++/*****************************************************************************/ ++/* 2.6.4 => 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 /* 2.6.4 => 2.6.0 */ ++ ++/*****************************************************************************/ ++/* 2.5.71 => 2.4.x */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,71) ) ++#include ++#define sk_protocol protocol ++ ++#define pci_get_device pci_find_device ++#endif /* 2.5.70 => 2.4.x */ ++ ++/*****************************************************************************/ ++/* < 2.4.27 or 2.6.0 <= 2.6.5 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,27) || \ ++ ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && \ ++ LINUX_VERSION_CODE < KERNEL_VERSION(2,6,5) ) ) ++ ++#ifndef netif_msg_init ++#define netif_msg_init _kc_netif_msg_init ++static inline u32 _kc_netif_msg_init(int debug_value, int default_msg_enable_bits) ++{ ++ /* use default */ ++ if (debug_value < 0 || debug_value >= (sizeof(u32) * 8)) ++ return default_msg_enable_bits; ++ if (debug_value == 0) /* no output */ ++ return 0; ++ /* set low N bits */ ++ return (1 << debug_value) -1; ++} ++#endif + -+/** -+ * e1000_irq_enable - Enable default interrupt generation settings -+ **/ -+static void e1000_irq_enable(struct e1000_adapter *adapter) ++#endif /* < 2.4.27 or 2.6.0 <= 2.6.5 */ ++/*****************************************************************************/ ++#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 ++ ++/*****************************************************************************/ ++/* <= 2.5.0 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ) ++#undef pci_register_driver ++#define pci_register_driver pci_module_init ++ ++#define dev_err(__unused_dev, format, arg...) \ ++ printk(KERN_ERR "%s: " format, pci_name(adapter->pdev) , ## arg) ++ ++/* hlist_* code - double linked lists */ ++struct hlist_head { ++ struct hlist_node *first; ++}; ++ ++struct hlist_node { ++ struct hlist_node *next, **pprev; ++}; ++ ++static inline void __hlist_del(struct hlist_node *n) +{ -+ struct e1000_hw *hw = &adapter->hw; ++ struct hlist_node *next = n->next; ++ struct hlist_node **pprev = n->pprev; ++ *pprev = next; ++ if (next) ++ next->pprev = pprev; ++} + -+ if (atomic_dec_and_test(&adapter->irq_sem)) { -+ ew32(IMS, IMS_ENABLE_MASK); -+ e1e_flush(); -+ } ++static inline void hlist_del(struct hlist_node *n) ++{ ++ __hlist_del(n); ++ n->next = NULL; ++ n->pprev = NULL; +} + -+/** -+ * 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 network i/f is open. -+ **/ -+static void e1000_get_hw_control(struct e1000_adapter *adapter) ++static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl_ext; -+ u32 swsm; ++ struct hlist_node *first = h->first; ++ n->next = first; ++ if (first) ++ first->pprev = &n->next; ++ h->first = n; ++ n->pprev = &h->first; ++} + -+ /* Let firmware know the driver has taken over */ -+ if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) { -+ swsm = er32(SWSM); -+ ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD); -+ } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) { -+ ctrl_ext = er32(CTRL_EXT); -+ ew32(CTRL_EXT, -+ ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); -+ } ++static inline int hlist_empty(const struct hlist_head *h) ++{ ++ return !h->first; ++} ++#define HLIST_HEAD_INIT { .first = NULL } ++#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } ++#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) ++static inline void INIT_HLIST_NODE(struct hlist_node *h) ++{ ++ h->next = NULL; ++ h->pprev = NULL; +} ++#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + -+/** -+ * 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 network i/f is closed. -+ * -+ **/ -+static void e1000_release_hw_control(struct e1000_adapter *adapter) ++#define hlist_for_each_entry(tpos, pos, head, member) \ ++ for (pos = (head)->first; \ ++ pos && ({ prefetch(pos->next); 1;}) && \ ++ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ ++ pos = pos->next) ++ ++#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ ++ for (pos = (head)->first; \ ++ pos && ({ n = pos->next; 1; }) && \ ++ ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ ++ pos = n) ++ ++/* we ignore GFP here */ ++#define dma_alloc_coherent(dv, sz, dma, gfp) \ ++ pci_alloc_consistent(pdev, (sz), (dma)) ++#define dma_free_coherent(dv, sz, addr, dma_addr) \ ++ pci_free_consistent(pdev, (sz), (addr), (dma_addr)) ++ ++#ifndef might_sleep ++#define might_sleep() ++#endif ++ ++#endif /* <= 2.5.0 */ ++ ++/*****************************************************************************/ ++/* 2.5.28 => 2.4.23 */ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,28) ) ++ ++static inline void _kc_synchronize_irq(void) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl_ext; -+ u32 swsm; ++ synchronize_irq(); ++} ++#undef synchronize_irq ++#define synchronize_irq(X) _kc_synchronize_irq() + -+ /* Let firmware taken over control of h/w */ -+ if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) { -+ swsm = er32(SWSM); -+ ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD); -+ } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) { -+ ctrl_ext = er32(CTRL_EXT); -+ ew32(CTRL_EXT, -+ ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); -+ } ++#include ++#define work_struct tq_struct ++#undef INIT_WORK ++#define INIT_WORK(a,b) INIT_TQUEUE(a,(void (*)(void *))b,a) ++#undef container_of ++#define container_of list_entry ++#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 ++#endif ++#ifndef CONFIG_IGB_DISABLE_PACKET_SPLIT ++#define CONFIG_IGB_DISABLE_PACKET_SPLIT 1 ++#endif ++ ++#define pci_set_consistent_dma_mask(dev,mask) 1 ++ ++#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 ++ ++#undef ALIGN ++#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1)) ++ ++/* find_first_bit and find_next bit are not defined for most ++ * 2.4 kernels (except for the redhat 2.4.21 kernels ++ */ ++#include ++#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) ++#undef find_next_bit ++#define find_next_bit _kc_find_next_bit ++extern unsigned long _kc_find_next_bit(const unsigned long *addr, ++ unsigned long size, ++ unsigned long offset); ++#define find_first_bit(addr, size) find_next_bit((addr), (size), 0) ++ ++#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,6,6) ) ++/* taken from 2.6 include/linux/bitmap.h */ ++#undef bitmap_zero ++#define bitmap_zero _kc_bitmap_zero ++static inline void _kc_bitmap_zero(unsigned long *dst, int nbits) ++{ ++ if (nbits <= BITS_PER_LONG) ++ *dst = 0UL; ++ else { ++ int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long); ++ memset(dst, 0, len); ++ } ++} ++#endif /* < 2.6.6 */ ++ ++/*****************************************************************************/ ++#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 /* < 2.6.8 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) ++#include ++#define __iomem ++ ++#ifndef kcalloc ++#define kcalloc(n, size, flags) _kc_kzalloc(((n) * (size)), flags) ++extern void *_kc_kzalloc(size_t size, int flags); ++#endif ++#define MSEC_PER_SEC 1000L ++static inline unsigned int _kc_jiffies_to_msecs(const unsigned long j) ++{ ++#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) ++ return (MSEC_PER_SEC / HZ) * j; ++#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) ++ return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); ++#else ++ return (j * MSEC_PER_SEC) / HZ; ++#endif ++} ++static inline unsigned long _kc_msecs_to_jiffies(const unsigned int m) ++{ ++ if (m > _kc_jiffies_to_msecs(MAX_JIFFY_OFFSET)) ++ return MAX_JIFFY_OFFSET; ++#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) ++ return (m + (MSEC_PER_SEC / HZ) - 1) / (MSEC_PER_SEC / HZ); ++#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) ++ return m * (HZ / MSEC_PER_SEC); ++#else ++ return (m * HZ + MSEC_PER_SEC - 1) / MSEC_PER_SEC; ++#endif +} + -+static void e1000_release_manageability(struct e1000_adapter *adapter) ++#define msleep_interruptible _kc_msleep_interruptible ++static inline unsigned long _kc_msleep_interruptible(unsigned int msecs) +{ -+ if (adapter->flags & FLAG_MNG_PT_ENABLED) { -+ struct e1000_hw *hw = &adapter->hw; -+ -+ u32 manc = er32(MANC); -+ -+ /* re-enable hardware interception of ARP */ -+ manc |= E1000_MANC_ARP_EN; -+ manc &= ~E1000_MANC_EN_MNG2HOST; ++ unsigned long timeout = _kc_msecs_to_jiffies(msecs) + 1; + -+ /* don't explicitly have to mess with MANC2H since -+ * MANC has an enable disable that gates MANC2H */ -+ ew32(MANC, manc); ++ while (timeout && !signal_pending(current)) { ++ __set_current_state(TASK_INTERRUPTIBLE); ++ timeout = schedule_timeout(timeout); + } ++ return _kc_jiffies_to_msecs(timeout); +} + -+/** -+ * @e1000_alloc_ring - allocate memory for a ring structure -+ **/ -+static int e1000_alloc_ring_dma(struct e1000_adapter *adapter, -+ struct e1000_ring *ring) ++/* Basic mode control register. */ ++#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ ++ ++#ifdef pci_dma_mapping_error ++#undef pci_dma_mapping_error ++#endif ++#define pci_dma_mapping_error _kc_pci_dma_mapping_error ++static inline int _kc_pci_dma_mapping_error(struct pci_dev *pdev, ++ dma_addr_t dma_addr) +{ -+ struct pci_dev *pdev = adapter->pdev; ++ return dma_addr == 0; ++} + -+ ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma, -+ GFP_KERNEL); -+ if (!ring->desc) -+ return -ENOMEM; ++#endif /* < 2.6.9 */ + -+ return 0; -+} ++/*****************************************************************************/ ++#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); \ ++ } \ ++ } \ ++} ++#endif /* 2.4.6 <= x < 2.6.10 */ ++ ++/*****************************************************************************/ ++#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 */ ++ ++/*****************************************************************************/ ++#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 ++ ++#undef NETIF_F_LLTX ++ ++#ifndef ARCH_HAS_PREFETCH ++#define prefetch(X) ++#endif + -+/** -+ * e1000e_setup_tx_resources - allocate Tx resources (Descriptors) -+ * @adapter: board private structure -+ * -+ * Return 0 on success, negative on failure -+ **/ -+int e1000e_setup_tx_resources(struct e1000_adapter *adapter) ++#ifndef NET_IP_ALIGN ++#define NET_IP_ALIGN 2 ++#endif ++ ++#define KC_USEC_PER_SEC 1000000L ++#define usecs_to_jiffies _kc_usecs_to_jiffies ++static inline unsigned int _kc_jiffies_to_usecs(const unsigned long j) +{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ int err = -ENOMEM, size; ++#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ) ++ return (KC_USEC_PER_SEC / HZ) * j; ++#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC) ++ return (j + (HZ / KC_USEC_PER_SEC) - 1)/(HZ / KC_USEC_PER_SEC); ++#else ++ return (j * KC_USEC_PER_SEC) / HZ; ++#endif ++} ++static inline unsigned long _kc_usecs_to_jiffies(const unsigned int m) ++{ ++ if (m > _kc_jiffies_to_usecs(MAX_JIFFY_OFFSET)) ++ return MAX_JIFFY_OFFSET; ++#if HZ <= KC_USEC_PER_SEC && !(KC_USEC_PER_SEC % HZ) ++ return (m + (KC_USEC_PER_SEC / HZ) - 1) / (KC_USEC_PER_SEC / HZ); ++#elif HZ > KC_USEC_PER_SEC && !(HZ % KC_USEC_PER_SEC) ++ return m * (HZ / KC_USEC_PER_SEC); ++#else ++ return (m * HZ + KC_USEC_PER_SEC - 1) / KC_USEC_PER_SEC; ++#endif ++} ++#endif /* < 2.6.11 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) ++#include ++#define USE_REBOOT_NOTIFIER ++ ++/* Generic MII registers. */ ++#define MII_CTRL1000 0x09 /* 1000BASE-T control */ ++#define MII_STAT1000 0x0a /* 1000BASE-T status */ ++/* Advertisement control register. */ ++#define ADVERTISE_PAUSE_CAP 0x0400 /* Try for pause */ ++#define ADVERTISE_PAUSE_ASYM 0x0800 /* Try for asymmetric pause */ ++/* 1000BASE-T Control register */ ++#define ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */ ++#endif + -+ size = sizeof(struct e1000_buffer) * tx_ring->count; -+ tx_ring->buffer_info = vmalloc(size); -+ if (!tx_ring->buffer_info) -+ goto err; -+ memset(tx_ring->buffer_info, 0, size); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) ) ++#define pm_message_t u32 ++#ifndef kzalloc ++#define kzalloc _kc_kzalloc ++extern void *_kc_kzalloc(size_t size, int flags); ++#endif + -+ /* round up to nearest 4K */ -+ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); -+ tx_ring->size = ALIGN(tx_ring->size, 4096); ++/* Generic MII registers. */ ++#define MII_ESTATUS 0x0f /* Extended Status */ ++/* Basic mode status register. */ ++#define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ ++/* Extended status register. */ ++#define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ ++#define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ ++#endif + -+ err = e1000_alloc_ring_dma(adapter, tx_ring); -+ if (err) -+ goto err; ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) ) ++#undef HAVE_PCI_ERS ++#else /* 2.6.16 and above */ ++#undef HAVE_PCI_ERS ++#define HAVE_PCI_ERS ++#endif + -+ tx_ring->next_to_use = 0; -+ tx_ring->next_to_clean = 0; -+ spin_lock_init(&adapter->tx_queue_lock); ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ) + -+ return 0; -+err: -+ vfree(tx_ring->buffer_info); -+ ndev_err(adapter->netdev, -+ "Unable to allocate memory for the transmit descriptor ring\n"); -+ return err; -+} ++#ifndef IRQF_PROBE_SHARED ++#ifdef SA_PROBEIRQ ++#define IRQF_PROBE_SHARED SA_PROBEIRQ ++#else ++#define IRQF_PROBE_SHARED 0 ++#endif ++#endif + -+/** -+ * e1000e_setup_rx_resources - allocate Rx resources (Descriptors) -+ * @adapter: board private structure -+ * -+ * Returns 0 on success, negative on failure -+ **/ -+int e1000e_setup_rx_resources(struct e1000_adapter *adapter) ++#ifndef IRQF_SHARED ++#define IRQF_SHARED SA_SHIRQ ++#endif ++ ++#ifndef ARRAY_SIZE ++#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) ++#endif ++ ++#ifndef netdev_alloc_skb ++#define netdev_alloc_skb _kc_netdev_alloc_skb ++extern struct sk_buff *_kc_netdev_alloc_skb(struct net_device *dev, ++ unsigned int length); ++#endif ++ ++#ifndef skb_is_gso ++#ifdef NETIF_F_TSO ++#define skb_is_gso _kc_skb_is_gso ++static inline int _kc_skb_is_gso(const struct sk_buff *skb) +{ -+ struct e1000_ring *rx_ring = adapter->rx_ring; -+ int size, desc_len, err = -ENOMEM; ++ return skb_shinfo(skb)->gso_size; ++} ++#else ++#define skb_is_gso(a) 0 ++#endif ++#endif + -+ size = sizeof(struct e1000_buffer) * rx_ring->count; -+ rx_ring->buffer_info = vmalloc(size); -+ if (!rx_ring->buffer_info) -+ goto err; -+ memset(rx_ring->buffer_info, 0, size); ++#endif /* < 2.6.18 */ + -+ rx_ring->ps_pages = kcalloc(rx_ring->count * PS_PAGE_BUFFERS, -+ sizeof(struct e1000_ps_page), -+ GFP_KERNEL); -+ if (!rx_ring->ps_pages) -+ goto err; ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) + -+ desc_len = sizeof(union e1000_rx_desc_packet_split); ++#ifndef DIV_ROUND_UP ++#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) ++#endif + -+ /* Round up to nearest 4K */ -+ rx_ring->size = rx_ring->count * desc_len; -+ rx_ring->size = ALIGN(rx_ring->size, 4096); ++#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ) ++#ifndef RHEL_RELEASE_CODE ++#define RHEL_RELEASE_CODE 0 ++#endif ++#ifndef RHEL_RELEASE_VERSION ++#define RHEL_RELEASE_VERSION(a,b) 0 ++#endif ++#ifndef AX_RELEASE_CODE ++#define AX_RELEASE_CODE 0 ++#endif ++#ifndef AX_RELEASE_VERSION ++#define AX_RELEASE_VERSION(a,b) 0 ++#endif ++#if (!(( RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(4,4) ) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(5,0) ) || ( RHEL_RELEASE_CODE > RHEL_RELEASE_VERSION(5,0) ) || (AX_RELEASE_CODE > AX_RELEASE_VERSION(3,0)))) ++typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *); ++#endif ++typedef irqreturn_t (*new_handler_t)(int, void*); ++static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) ++#else /* 2.4.x */ ++typedef void (*irq_handler_t)(int, void*, struct pt_regs *); ++typedef void (*new_handler_t)(int, void*); ++static inline int _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) ++#endif ++{ ++ irq_handler_t new_handler = (irq_handler_t) handler; ++ return request_irq(irq, new_handler, flags, devname, dev_id); ++} + -+ err = e1000_alloc_ring_dma(adapter, rx_ring); -+ if (err) -+ goto err; ++#undef request_irq ++#define request_irq(irq, handler, flags, devname, dev_id) _kc_request_irq((irq), (handler), (flags), (devname), (dev_id)) + -+ rx_ring->next_to_clean = 0; -+ rx_ring->next_to_use = 0; -+ rx_ring->rx_skb_top = NULL; ++#define irq_handler_t new_handler_t + -+ return 0; -+err: -+ vfree(rx_ring->buffer_info); -+ kfree(rx_ring->ps_pages); -+ ndev_err(adapter->netdev, -+ "Unable to allocate memory for the transmit descriptor ring\n"); -+ return err; ++/* pci_restore_state and pci_save_state handles MSI/PCIE from 2.6.19 */ ++#define PCIE_CONFIG_SPACE_LEN 256 ++#define PCI_CONFIG_SPACE_LEN 64 ++#define PCIE_LINK_STATUS 0x12 ++#ifdef DRIVER_E1000E ++#define pci_config_space_ich8lan() { \ ++ if (adapter->flags & FLAG_IS_ICH) \ ++ size = PCIE_CONFIG_SPACE_LEN; \ +} ++#else ++#define pci_config_space_ich8lan() ++#endif ++#undef pci_save_state ++#define pci_save_state(pdev) _kc_pci_save_state(adapter) ++#define _kc_pci_save_state(adapter) 0; { \ ++ int size = PCI_CONFIG_SPACE_LEN, i; \ ++ u16 pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP); \ ++ u16 pcie_link_status; \ ++ \ ++ if (pcie_cap_offset) { \ ++ if (!pci_read_config_word(pdev, pcie_cap_offset + PCIE_LINK_STATUS, \ ++ &pcie_link_status)) \ ++ size = PCIE_CONFIG_SPACE_LEN; \ ++ } \ ++ pci_config_space_ich8lan(); \ ++ WARN_ON(adapter->config_space != NULL); \ ++ adapter->config_space = kmalloc(size, GFP_KERNEL); \ ++ if (!adapter->config_space) { \ ++ printk(KERN_ERR "Out of memory in pci_save_state\n"); \ ++ return -ENOMEM; \ ++ } \ ++ for (i = 0; i < (size / 4); i++) \ ++ pci_read_config_dword(pdev, i * 4, &adapter->config_space[i]); \ ++} ++#undef pci_restore_state ++#define pci_restore_state(pdev) _kc_pci_restore_state(adapter) ++#define _kc_pci_restore_state(adapter) { \ ++ int size = PCI_CONFIG_SPACE_LEN, i; \ ++ u16 pcie_cap_offset; \ ++ u16 pcie_link_status; \ ++ \ ++ if (adapter->config_space != NULL) { \ ++ pcie_cap_offset = pci_find_capability(pdev, PCI_CAP_ID_EXP); \ ++ if (pcie_cap_offset) { \ ++ if (!pci_read_config_word(pdev, pcie_cap_offset + PCIE_LINK_STATUS, \ ++ &pcie_link_status)) \ ++ size = PCIE_CONFIG_SPACE_LEN; \ ++ } \ ++ pci_config_space_ich8lan(); \ ++ for (i = 0; i < (size / 4); i++) \ ++ pci_write_config_dword(pdev, i * 4, adapter->config_space[i]); \ ++ kfree(adapter->config_space); \ ++ adapter->config_space = NULL; \ ++ } \ ++} ++ ++#endif /* < 2.6.19 */ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ) ++#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) ) ++#undef INIT_WORK ++#define INIT_WORK(_work, _func) \ ++do { \ ++ INIT_LIST_HEAD(&(_work)->entry); \ ++ (_work)->pending = 0; \ ++ (_work)->func = (void (*)(void *))_func; \ ++ (_work)->data = _work; \ ++ init_timer(&(_work)->timer); \ ++} while (0) ++#endif + -+/** -+ * e1000_clean_tx_ring - Free Tx Buffers -+ * @adapter: board private structure -+ **/ -+static void e1000_clean_tx_ring(struct e1000_adapter *adapter) -+{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_buffer *buffer_info; -+ unsigned long size; -+ unsigned int i; ++#ifndef PCI_VDEVICE ++#define PCI_VDEVICE(ven, dev) \ ++ PCI_VENDOR_ID_##ven, (dev), \ ++ PCI_ANY_ID, PCI_ANY_ID, 0, 0 ++#endif + -+ for (i = 0; i < tx_ring->count; i++) { -+ buffer_info = &tx_ring->buffer_info[i]; -+ e1000_put_txbuf(adapter, buffer_info); -+ } ++#ifndef round_jiffies ++#define round_jiffies(x) x ++#endif + -+ size = sizeof(struct e1000_buffer) * tx_ring->count; -+ memset(tx_ring->buffer_info, 0, size); ++#define csum_offset csum ++ ++#endif /* < 2.6.20 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) ) ++#define vlan_group_get_device(vg, id) (vg->vlan_devices[id]) ++#define vlan_group_set_device(vg, id, dev) if (vg) vg->vlan_devices[id] = dev; ++#define pci_channel_offline(pdev) (pdev->error_state && \ ++ pdev->error_state != pci_channel_io_normal) ++#endif /* < 2.6.21 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) ) ++#define tcp_hdr(skb) (skb->h.th) ++#define tcp_hdrlen(skb) (skb->h.th->doff << 2) ++#define skb_transport_offset(skb) (skb->h.raw - skb->data) ++#define skb_transport_header(skb) (skb->h.raw) ++#define ipv6_hdr(skb) (skb->nh.ipv6h) ++#define ip_hdr(skb) (skb->nh.iph) ++#define skb_network_offset(skb) (skb->nh.raw - skb->data) ++#define skb_network_header(skb) (skb->nh.raw) ++#define skb_tail_pointer(skb) skb->tail ++#define skb_copy_to_linear_data_offset(skb, offset, from, len) \ ++ memcpy(skb->data + offset, from, len) ++#define skb_network_header_len(skb) (skb->h.raw - skb->nh.raw) ++#define pci_register_driver pci_module_init ++#define skb_mac_header(skb) skb->mac.raw ++ ++#ifdef NETIF_F_MULTI_QUEUE ++#ifndef alloc_etherdev_mq ++#define alloc_etherdev_mq(_a, _b) alloc_etherdev(_a) ++#endif ++#endif /* NETIF_F_MULTI_QUEUE */ + -+ memset(tx_ring->desc, 0, tx_ring->size); ++#ifndef ETH_FCS_LEN ++#define ETH_FCS_LEN 4 ++#endif ++#endif /* < 2.6.22 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22) ) ++#undef ETHTOOL_GPERMADDR ++#undef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do { } while (0) ++#endif /* > 2.6.22 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) ) ++/* NAPI API changes in 2.6.24 break everything */ ++struct napi_struct { ++ /* used to look up the real NAPI polling routine */ ++ int (*poll)(struct napi_struct *, int); ++ int weight; ++}; ++#ifdef NAPI ++extern int __kc_adapter_clean(struct net_device *, int *); ++#define netif_rx_complete(netdev, napi) netif_rx_complete(netdev) ++#define netif_rx_schedule_prep(netdev, napi) netif_rx_schedule_prep(netdev) ++#define netif_rx_schedule(netdev, napi) netif_rx_schedule(netdev) ++#define __netif_rx_schedule(netdev, napi) __netif_rx_schedule(netdev) ++#define napi_enable(napi) netif_poll_enable(adapter->netdev) ++#define napi_disable(napi) netif_poll_disable(adapter->netdev) ++#define netif_napi_add(_netdev, _napi, _poll, _weight) \ ++ do { \ ++ struct napi_struct *__napi = _napi; \ ++ _netdev->poll = &(__kc_adapter_clean); \ ++ _netdev->weight = (_weight); \ ++ __napi->poll = &(_poll); \ ++ __napi->weight = (_weight); \ ++ netif_poll_disable(_netdev); \ ++ } while (0) ++#else /* NAPI */ ++#define netif_napi_add(_netdev, _napi, _poll, _weight) \ ++ do { \ ++ struct napi_struct *__napi = _napi; \ ++ _netdev->poll = &(_poll); \ ++ _netdev->weight = (_weight); \ ++ __napi->poll = &(_poll); \ ++ __napi->weight = (_weight); \ ++ } while (0) ++#endif /* NAPI */ ++ ++#undef dev_get_by_name ++#define dev_get_by_name(_a, _b) dev_get_by_name(_b) ++#define __netif_subqueue_stopped(_a, _b) netif_subqueue_stopped(_a, _b) ++#endif /* < 2.6.24 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) ) ++#include ++#endif /* > 2.6.24 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) ) ++#define PM_QOS_CPU_DMA_LATENCY 1 ++ ++#if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) ) ++#include ++#define PM_QOS_DEFAULT_VALUE INFINITE_LATENCY ++#define pm_qos_add_requirement(pm_qos_class, name, value) \ ++ set_acceptable_latency(name, value) ++#define pm_qos_remove_requirement(pm_qos_class, name) \ ++ remove_acceptable_latency(name) ++#define pm_qos_update_requirement(pm_qos_class, name, value) \ ++ modify_acceptable_latency(name, value) ++#else ++#define PM_QOS_DEFAULT_VALUE -1 ++#define pm_qos_add_requirement(pm_qos_class, name, value) ++#define pm_qos_remove_requirement(pm_qos_class, name) ++#define pm_qos_update_requirement(pm_qos_class, name, value) { \ ++ if (value != PM_QOS_DEFAULT_VALUE) { \ ++ printk(KERN_WARNING "%s: unable to set PM QoS requirement\n", \ ++ pci_name(adapter->pdev)); \ ++ } \ ++} ++#endif /* > 2.6.18 */ ++ ++#endif /* < 2.6.25 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) ) ++#endif /* < 2.6.26 */ ++ ++/*****************************************************************************/ ++#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) ) ++#ifndef pci_dma_mapping_error ++#define pci_dma_mapping_error(pdev, dma_addr) pci_dma_mapping_error(dma_addr) ++#endif ++#endif /* < 2.6.27 */ + -+ tx_ring->next_to_use = 0; -+ tx_ring->next_to_clean = 0; -+ tx_ring->last_tx_tso = 0; ++#ifndef NETIF_F_MULTI_QUEUE ++#define NETIF_F_MULTI_QUEUE 0 ++#define netif_is_multiqueue(a) 0 ++#define netif_stop_subqueue(a, b) ++#define netif_wake_subqueue(a, b) ++#define netif_start_subqueue(a, b) ++#endif /* NETIF_F_MULTI_QUEUE */ + -+ writel(0, adapter->hw.hw_addr + tx_ring->head); -+ writel(0, adapter->hw.hw_addr + tx_ring->tail); -+} ++#endif /* _KCOMPAT_H_ */ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/Makefile linux-2.6.22-10/drivers/net/e1000e/Makefile +--- linux-2.6.22-0/drivers/net/e1000e/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/Makefile 2008-11-10 00:06:14.000000000 +0100 +@@ -0,0 +1,33 @@ ++################################################################################ ++# ++# Intel PRO/1000 Linux driver ++# Copyright(c) 1999 - 2008 Intel Corporation. ++# ++# This program is free software; you can redistribute it and/or modify it ++# under the terms and conditions of the GNU General Public License, ++# version 2, as published by the Free Software Foundation. ++# ++# This program is distributed in the hope 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., ++# 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++# ++# The full GNU General Public License is included in this distribution in ++# the file called "COPYING". ++# ++# Contact Information: ++# Linux NICS ++# e1000-devel Mailing List ++# Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++# ++################################################################################ + -+/** -+ * e1000e_free_tx_resources - Free Tx Resources per Queue -+ * @adapter: board private structure -+ * -+ * Free all transmit software resources -+ **/ -+void e1000e_free_tx_resources(struct e1000_adapter *adapter) ++obj-$(CONFIG_E1000E) := e1000e.o ++ ++e1000e-objs := e1000_82571.o e1000_ich8lan.o e1000_80003es2lan.o \ ++ netdev.o ethtool.o param.o e1000_mac.o e1000_nvm.o \ ++ e1000_phy.o e1000_manage.o kcompat.o +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/netdev.c linux-2.6.22-10/drivers/net/e1000e/netdev.c +--- linux-2.6.22-0/drivers/net/e1000e/netdev.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/netdev.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,5637 @@ ++/******************************************************************************* ++ ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. ++ ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. ++ ++ This program is distributed in the hope 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". ++ ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ ++*******************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef NETIF_F_TSO ++#include ++#ifdef NETIF_F_TSO6 ++#include ++#endif ++#endif ++#include ++#include ++#include ++ ++#include "e1000.h" ++ ++#ifdef CONFIG_E1000E_NAPI ++#define DRV_NAPI "-NAPI" ++#else ++#define DRV_NAPI ++#endif ++ ++#define DRV_DEBUG ++ ++#define DRV_VERSION "0.4.1.12" DRV_NAPI DRV_DEBUG ++char e1000e_driver_name[] = "e1000e"; ++const char e1000e_driver_version[] = DRV_VERSION; ++ ++static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) +{ ++ struct e1000_hw *hw = &adapter->hw; ++ static int global_quad_port_a; /* global port a indication */ + struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *tx_ring = adapter->tx_ring; ++ u16 eeprom_data = 0; ++ int is_port_b = er32(STATUS) & E1000_STATUS_FUNC_1; ++ ++ /* tag quad port adapters first, it's used below */ ++ switch (pdev->device) { ++ case E1000_DEV_ID_82571EB_QUAD_COPPER: ++ case E1000_DEV_ID_82571EB_QUAD_FIBER: ++ case E1000_DEV_ID_82571EB_QUAD_COPPER_LP: ++ case E1000_DEV_ID_82571PT_QUAD_COPPER: ++ adapter->flags |= FLAG_IS_QUAD_PORT; ++ /* mark the first port */ ++ if (global_quad_port_a == 0) ++ adapter->flags |= FLAG_IS_QUAD_PORT_A; ++ /* Reset for multiple quad port adapters */ ++ global_quad_port_a++; ++ if (global_quad_port_a == 4) ++ global_quad_port_a = 0; ++ break; ++ default: ++ break; ++ } ++ ++ switch (adapter->hw.mac.type) { ++ case e1000_82571: ++ /* these dual ports don't have WoL on port B at all */ ++ if (((pdev->device == E1000_DEV_ID_82571EB_FIBER) || ++ (pdev->device == E1000_DEV_ID_82571EB_SERDES) || ++ (pdev->device == E1000_DEV_ID_82571EB_COPPER)) && ++ (is_port_b)) ++ adapter->flags &= ~FLAG_HAS_WOL; ++ /* quad ports only support WoL on port A */ ++ if (adapter->flags & FLAG_IS_QUAD_PORT && ++ (!(adapter->flags & FLAG_IS_QUAD_PORT_A))) ++ adapter->flags &= ~FLAG_HAS_WOL; ++ /* Does not support WoL on any port */ ++ if (pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) ++ adapter->flags &= ~FLAG_HAS_WOL; ++ break; + -+ e1000_clean_tx_ring(adapter); ++ case e1000_82573: ++ if (pdev->device == E1000_DEV_ID_82573L) { ++ adapter->hw.nvm.ops.read(&adapter->hw, NVM_INIT_3GIO_3, ++ 1, &eeprom_data); ++ if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) ++ adapter->flags |= FLAG_HAS_JUMBO_FRAMES; ++ } ++ break; + -+ vfree(tx_ring->buffer_info); -+ tx_ring->buffer_info = NULL; ++ default: ++ break; ++ } + -+ dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, -+ tx_ring->dma); -+ tx_ring->desc = NULL; ++ return 0; +} + -+/** -+ * e1000e_free_rx_resources - Free Rx Resources -+ * @adapter: board private structure -+ * -+ * Free all receive software resources -+ **/ -+ -+void e1000e_free_rx_resources(struct e1000_adapter *adapter) -+{ -+ struct pci_dev *pdev = adapter->pdev; -+ struct e1000_ring *rx_ring = adapter->rx_ring; ++static struct e1000_info e1000_82571_info = { ++ .mac = e1000_82571, ++ .flags = FLAG_HAS_HW_VLAN_FILTER ++ | FLAG_HAS_JUMBO_FRAMES ++ | FLAG_HAS_WOL ++ | FLAG_APME_IN_CTRL3 ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_HAS_SMART_POWER_DOWN ++ | FLAG_RESET_OVERWRITES_LAA /* errata */ ++ | FLAG_TARC_SPEED_MODE_BIT /* errata */ ++ | FLAG_APME_CHECK_PORT_B, ++ .pba = 38, ++ .init_ops = e1000_init_function_pointers_82571, ++ .get_variants = e1000_get_variants_82571, ++}; + -+ e1000_clean_rx_ring(adapter); ++static struct e1000_info e1000_82572_info = { ++ .mac = e1000_82572, ++ .flags = FLAG_HAS_HW_VLAN_FILTER ++ | FLAG_HAS_JUMBO_FRAMES ++ | FLAG_HAS_WOL ++ | FLAG_APME_IN_CTRL3 ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_TARC_SPEED_MODE_BIT, /* errata */ ++ .pba = 38, ++ .init_ops = e1000_init_function_pointers_82571, ++ .get_variants = e1000_get_variants_82571, ++}; + -+ vfree(rx_ring->buffer_info); -+ rx_ring->buffer_info = NULL; ++static struct e1000_info e1000_82573_info = { ++ .mac = e1000_82573, ++ .flags = FLAG_HAS_HW_VLAN_FILTER ++ | FLAG_HAS_WOL ++ | FLAG_APME_IN_CTRL3 ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_SMART_POWER_DOWN ++ | FLAG_HAS_AMT ++ | FLAG_HAS_ASPM ++ | FLAG_HAS_ERT ++ | FLAG_HAS_SWSM_ON_LOAD, ++ .pba = 20, ++ .init_ops = e1000_init_function_pointers_82571, ++ .get_variants = e1000_get_variants_82571, ++}; + -+ kfree(rx_ring->ps_pages); -+ rx_ring->ps_pages = NULL; ++static struct e1000_info e1000_82574_info = { ++ .mac = e1000_82574, ++ .flags = FLAG_HAS_HW_VLAN_FILTER ++#ifdef CONFIG_E1000E_MSIX ++ | FLAG_HAS_MSIX ++#endif ++ | FLAG_HAS_JUMBO_FRAMES ++ | FLAG_HAS_WOL ++ | FLAG_APME_IN_CTRL3 ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_SMART_POWER_DOWN ++ | FLAG_HAS_AMT ++ | FLAG_HAS_ASPM ++ | FLAG_HAS_CTRLEXT_ON_LOAD, ++ .pba = 20, ++ .init_ops = e1000_init_function_pointers_82571, ++ .get_variants = e1000_get_variants_82571, ++}; + -+ dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, -+ rx_ring->dma); -+ rx_ring->desc = NULL; -+} ++static struct e1000_info e1000_es2_info = { ++ .mac = e1000_80003es2lan, ++ .flags = FLAG_HAS_HW_VLAN_FILTER ++ | FLAG_HAS_JUMBO_FRAMES ++ | FLAG_HAS_WOL ++ | FLAG_APME_IN_CTRL3 ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_RX_NEEDS_RESTART /* errata */ ++ | FLAG_TARC_SET_BIT_ZERO /* errata */ ++ | FLAG_APME_CHECK_PORT_B ++ | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ ++ | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, ++ .pba = 38, ++ .init_ops = e1000_init_function_pointers_80003es2lan, ++ .get_variants = NULL, ++}; + -+/** -+ * e1000_update_itr - update the dynamic ITR value based on statistics -+ * Stores a new ITR value based on packets and byte -+ * counts during the last interrupt. The advantage of per interrupt -+ * computation is faster updates and more accurate ITR for the current -+ * traffic pattern. Constants in this function were computed -+ * based on theoretical maximum wire speed and thresholds were set based -+ * on testing data as well as attempting to minimize response time -+ * while increasing bulk throughput. -+ * this functionality is controlled by the InterruptThrottleRate module -+ * parameter (see e1000_param.c) -+ * @adapter: pointer to adapter -+ * @itr_setting: current adapter->itr -+ * @packets: the number of packets during this measurement interval -+ * @bytes: the number of bytes during this measurement interval -+ **/ -+static unsigned int e1000_update_itr(struct e1000_adapter *adapter, -+ u16 itr_setting, int packets, -+ int bytes) ++static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter) +{ -+ unsigned int retval = itr_setting; -+ -+ if (packets == 0) -+ goto update_itr_done; ++ if (adapter->hw.phy.type == e1000_phy_ife) ++ adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES; + -+ switch (itr_setting) { -+ case lowest_latency: -+ /* handle TSO and jumbo frames */ -+ if (bytes/packets > 8000) -+ retval = bulk_latency; -+ else if ((packets < 5) && (bytes > 512)) { -+ retval = low_latency; -+ } -+ break; -+ case low_latency: /* 50 usec aka 20000 ints/s */ -+ if (bytes > 10000) { -+ /* this if handles the TSO accounting */ -+ if (bytes/packets > 8000) { -+ retval = bulk_latency; -+ } else if ((packets < 10) || ((bytes/packets) > 1200)) { -+ retval = bulk_latency; -+ } else if ((packets > 35)) { -+ retval = lowest_latency; -+ } -+ } else if (bytes/packets > 2000) { -+ retval = bulk_latency; -+ } else if (packets <= 2 && bytes < 512) { -+ retval = lowest_latency; -+ } -+ break; -+ case bulk_latency: /* 250 usec aka 4000 ints/s */ -+ if (bytes > 25000) { -+ if (packets > 35) { -+ retval = low_latency; -+ } -+ } else if (bytes < 6000) { -+ retval = low_latency; -+ } -+ break; -+ } ++ if ((adapter->hw.mac.type == e1000_ich8lan) && ++ (adapter->hw.phy.type == e1000_phy_igp_3)) ++ adapter->flags |= FLAG_LSC_GIG_SPEED_DROP; + -+update_itr_done: -+ return retval; ++ return 0; +} + -+static void e1000_set_itr(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ u16 current_itr; -+ u32 new_itr = adapter->itr; -+ -+ /* for non-gigabit speeds, just fix the interrupt rate at 4000 */ -+ if (adapter->link_speed != SPEED_1000) { -+ current_itr = 0; -+ new_itr = 4000; -+ goto set_itr_now; -+ } ++static struct e1000_info e1000_ich8_info = { ++ .mac = e1000_ich8lan, ++ .flags = FLAG_HAS_WOL ++ | FLAG_IS_ICH ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_HAS_AMT ++ | FLAG_HAS_FLASH ++ | FLAG_APME_IN_WUC, ++ .pba = 8, ++ .init_ops = e1000_init_function_pointers_ich8lan, ++ .get_variants = e1000_get_variants_ich8lan, ++}; + -+ adapter->tx_itr = e1000_update_itr(adapter, -+ adapter->tx_itr, -+ adapter->total_tx_packets, -+ adapter->total_tx_bytes); -+ /* conservative mode (itr 3) eliminates the lowest_latency setting */ -+ if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency) -+ adapter->tx_itr = low_latency; ++static struct e1000_info e1000_ich9_info = { ++ .mac = e1000_ich9lan, ++ .flags = FLAG_HAS_JUMBO_FRAMES ++ | FLAG_IS_ICH ++ | FLAG_HAS_WOL ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_HAS_AMT ++ | FLAG_HAS_ERT ++ | FLAG_HAS_FLASH ++ | FLAG_APME_IN_WUC, ++ .pba = 10, ++ .init_ops = e1000_init_function_pointers_ich8lan, ++ .get_variants = e1000_get_variants_ich8lan, ++}; + -+ adapter->rx_itr = e1000_update_itr(adapter, -+ adapter->rx_itr, -+ adapter->total_rx_packets, -+ adapter->total_rx_bytes); -+ /* conservative mode (itr 3) eliminates the lowest_latency setting */ -+ if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency) -+ adapter->rx_itr = low_latency; ++static struct e1000_info e1000_ich10_info = { ++ .mac = e1000_ich10lan, ++ .flags = FLAG_HAS_JUMBO_FRAMES ++ | FLAG_IS_ICH ++ | FLAG_HAS_WOL ++ | FLAG_RX_CSUM_ENABLED ++ | FLAG_HAS_CTRLEXT_ON_LOAD ++ | FLAG_HAS_AMT ++ | FLAG_HAS_ERT ++ | FLAG_HAS_FLASH ++ | FLAG_APME_IN_WUC, ++ .pba = 10, ++ .init_ops = e1000_init_function_pointers_ich8lan, ++ .get_variants = e1000_get_variants_ich8lan, ++}; + -+ current_itr = max(adapter->rx_itr, adapter->tx_itr); ++static const struct e1000_info *e1000_info_tbl[] = { ++ [board_82571] = &e1000_82571_info, ++ [board_82572] = &e1000_82572_info, ++ [board_82573] = &e1000_82573_info, ++ [board_82574] = &e1000_82574_info, ++ [board_80003es2lan] = &e1000_es2_info, ++ [board_ich8lan] = &e1000_ich8_info, ++ [board_ich9lan] = &e1000_ich9_info, ++ [board_ich10lan] = &e1000_ich10_info, ++}; + -+ switch (current_itr) { -+ /* counts and packets in update_itr are dependent on these numbers */ -+ case lowest_latency: -+ new_itr = 70000; -+ break; -+ case low_latency: -+ new_itr = 20000; /* aka hwitr = ~200 */ -+ break; -+ case bulk_latency: -+ new_itr = 4000; -+ break; -+ default: -+ break; -+ } + -+set_itr_now: -+ if (new_itr != adapter->itr) { -+ /* this attempts to bias the interrupt rate towards Bulk -+ * by adding intermediate steps when interrupt rate is -+ * increasing */ -+ new_itr = new_itr > adapter->itr ? -+ min(adapter->itr + (new_itr >> 2), new_itr) : -+ new_itr; -+ adapter->itr = new_itr; -+ ew32(ITR, 1000000000 / (new_itr * 256)); -+ } -+} ++void e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value) ++{ ++ struct e1000_adapter *adapter = hw->back; + -+/** -+ * e1000_clean - NAPI Rx polling callback -+ * @adapter: board private structure -+ **/ -+static int e1000_clean(struct net_device *poll_dev, int *budget) ++ pci_read_config_word(adapter->pdev, reg, value); ++} ++ ++s32 e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) +{ -+ struct e1000_adapter *adapter; -+ int work_to_do = min(*budget, poll_dev->quota); -+ int tx_cleaned = 0, work_done = 0; ++ struct e1000_adapter *adapter = hw->back; ++ u16 cap_offset; + -+ /* Must NOT use netdev_priv macro here. */ -+ adapter = poll_dev->priv; ++ cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); ++ if (!cap_offset) ++ return -E1000_ERR_CONFIG; + -+ /* Keep link state information with original netdev */ -+ if (!netif_carrier_ok(poll_dev)) -+ goto quit_polling; ++ pci_read_config_word(adapter->pdev, cap_offset + reg, value); + -+ /* e1000_clean is called per-cpu. This lock protects -+ * tx_ring from being cleaned by multiple cpus -+ * simultaneously. A failure obtaining the lock means -+ * tx_ring is currently being cleaned anyway. */ -+ if (spin_trylock(&adapter->tx_queue_lock)) { -+ tx_cleaned = e1000_clean_tx_irq(adapter); -+ spin_unlock(&adapter->tx_queue_lock); -+ } ++ return E1000_SUCCESS; ++} + -+ adapter->clean_rx(adapter, &work_done, work_to_do); -+ *budget -= work_done; -+ poll_dev->quota -= work_done; ++s32 e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size) ++{ ++ hw->dev_spec = kzalloc(size, GFP_KERNEL); + -+ /* 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: -+ if (adapter->itr_setting & 3) -+ e1000_set_itr(adapter); -+ netif_rx_complete(poll_dev); -+ if (test_bit(__E1000_DOWN, &adapter->state)) -+ atomic_dec(&adapter->irq_sem); -+ else -+ e1000_irq_enable(adapter); -+ return 0; -+ } ++ if (!hw->dev_spec) ++ return -ENOMEM; + -+ return 1; ++ return E1000_SUCCESS; +} + -+static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) ++void e1000_free_dev_spec_struct(struct e1000_hw *hw) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u32 vfta, index; -+ -+ /* don't update vlan cookie if already programmed */ -+ if ((adapter->hw.mng_cookie.status & -+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && -+ (vid == adapter->mng_vlan_id)) ++ if (!hw->dev_spec) + return; -+ /* add VID to filter table */ -+ index = (vid >> 5) & 0x7F; -+ vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index); -+ vfta |= (1 << (vid & 0x1F)); -+ e1000e_write_vfta(hw, index, vfta); ++ ++ kfree(hw->dev_spec); +} + -+static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) ++/** ++ * e1000_desc_unused - calculate if we have unused descriptors ++ **/ ++static int e1000_desc_unused(struct e1000_ring *ring) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u32 vfta, index; ++ if (ring->next_to_clean > ring->next_to_use) ++ return ring->next_to_clean - ring->next_to_use - 1; + -+ e1000_irq_disable(adapter); -+ vlan_group_set_device(adapter->vlgrp, vid, NULL); -+ e1000_irq_enable(adapter); ++ return ring->count + ring->next_to_clean - ring->next_to_use - 1; ++} + -+ if ((adapter->hw.mng_cookie.status & -+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && -+ (vid == adapter->mng_vlan_id)) { -+ /* release control to f/w */ -+ e1000_release_hw_control(adapter); -+ return; -+ } ++/** ++ * e1000_receive_skb - helper function to handle Rx indications ++ * @adapter: board private structure ++ * @status: descriptor status field as written by hardware ++ * @vlan: descriptor vlan field as written by hardware (no le/be conversion) ++ * @skb: pointer to sk_buff to be indicated to stack ++ **/ ++static void e1000_receive_skb(struct e1000_adapter *adapter, ++ struct net_device *netdev, ++ struct sk_buff *skb, ++ u8 status, u16 vlan) ++{ ++ skb->protocol = eth_type_trans(skb, netdev); + -+ /* remove VID from filter table */ -+ index = (vid >> 5) & 0x7F; -+ vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index); -+ vfta &= ~(1 << (vid & 0x1F)); -+ e1000e_write_vfta(hw, index, vfta); ++#ifdef CONFIG_E1000E_NAPI ++ if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) ++ vlan_hwaccel_receive_skb(skb, adapter->vlgrp, ++ le16_to_cpu(vlan) & ++ E1000_RXD_SPC_VLAN_MASK); ++ else ++ netif_receive_skb(skb); ++#else ++ if (adapter->vlgrp && (status & E1000_RXD_STAT_VP)) ++ vlan_hwaccel_rx(skb, adapter->vlgrp, ++ le16_to_cpu(vlan) & E1000_RXD_SPC_VLAN_MASK); ++ else ++ netif_rx(skb); ++#endif ++ ++ netdev->last_rx = jiffies; +} + -+static void e1000_update_mng_vlan(struct e1000_adapter *adapter) ++/** ++ * 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 ++ **/ ++static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, ++ u32 csum, struct sk_buff *skb) +{ -+ struct net_device *netdev = adapter->netdev; -+ u16 vid = adapter->hw.mng_cookie.vlan_id; -+ u16 old_vid = adapter->mng_vlan_id; ++ u16 status = (u16)status_err; ++ u8 errors = (u8)(status_err >> 24); ++ skb->ip_summed = CHECKSUM_NONE; + -+ if (!adapter->vlgrp) ++ /* Ignore Checksum bit is set */ ++ if (status & E1000_RXD_STAT_IXSM) + return; ++ /* TCP/UDP checksum error bit is set */ ++ if (errors & E1000_RXD_ERR_TCPE) { ++ /* let the stack verify checksum errors */ ++ adapter->hw_csum_err++; ++ return; ++ } + -+ if (!vlan_group_get_device(adapter->vlgrp, vid)) { -+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; -+ if (adapter->hw.mng_cookie.status & -+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { -+ e1000_vlan_rx_add_vid(netdev, vid); -+ adapter->mng_vlan_id = vid; -+ } ++ /* TCP/UDP Checksum has not been calculated */ ++ if (!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))) ++ return; + -+ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && -+ (vid != old_vid) && -+ !vlan_group_get_device(adapter->vlgrp, old_vid)) -+ e1000_vlan_rx_kill_vid(netdev, old_vid); ++ /* It must be a TCP or UDP packet with a valid checksum */ ++ if (status & E1000_RXD_STAT_TCPCS) { ++ /* TCP checksum is good */ ++ skb->ip_summed = CHECKSUM_UNNECESSARY; + } else { -+ adapter->mng_vlan_id = vid; ++ /* ++ * 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_COMPLETE; + } ++ adapter->hw_csum_good++; +} + -+ -+static void e1000_vlan_rx_register(struct net_device *netdev, -+ struct vlan_group *grp) ++/** ++ * 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, ++ int cleaned_count) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl, rctl; -+ -+ e1000_irq_disable(adapter); -+ adapter->vlgrp = grp; ++ struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ 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; + -+ if (grp) { -+ /* enable VLAN tag insert/strip */ -+ ctrl = er32(CTRL); -+ ctrl |= E1000_CTRL_VME; -+ ew32(CTRL, ctrl); ++ i = rx_ring->next_to_use; ++ buffer_info = &rx_ring->buffer_info[i]; + -+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { -+ /* enable VLAN receive filtering */ -+ rctl = er32(RCTL); -+ rctl |= E1000_RCTL_VFE; -+ rctl &= ~E1000_RCTL_CFIEN; -+ ew32(RCTL, rctl); -+ e1000_update_mng_vlan(adapter); ++ while (cleaned_count--) { ++ skb = buffer_info->skb; ++ if (skb) { ++ skb_trim(skb, 0); ++ goto map_skb; + } -+ } else { -+ /* disable VLAN tag insert/strip */ -+ ctrl = er32(CTRL); -+ ctrl &= ~E1000_CTRL_VME; -+ ew32(CTRL, ctrl); + -+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { -+ /* disable VLAN filtering */ -+ rctl = er32(RCTL); -+ rctl &= ~E1000_RCTL_VFE; -+ ew32(RCTL, rctl); -+ if (adapter->mng_vlan_id != -+ (u16)E1000_MNG_VLAN_NONE) { -+ e1000_vlan_rx_kill_vid(netdev, -+ adapter->mng_vlan_id); -+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; -+ } ++ skb = netdev_alloc_skb(netdev, bufsz); ++ if (!skb) { ++ /* Better luck next round */ ++ adapter->alloc_rx_buff_failed++; ++ break; + } -+ } + -+ e1000_irq_enable(adapter); -+} -+ -+static void e1000_restore_vlan(struct e1000_adapter *adapter) -+{ -+ u16 vid; ++ /* ++ * 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); + -+ e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); ++ buffer_info->skb = skb; ++map_skb: ++ buffer_info->dma = pci_map_single(pdev, skb->data, ++ adapter->rx_buffer_len, ++ PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(pdev, buffer_info->dma)) { ++ dev_err(&pdev->dev, "RX DMA map failed\n"); ++ adapter->rx_dma_failed++; ++ break; ++ } + -+ if (!adapter->vlgrp) -+ return; ++ rx_desc = E1000_RX_DESC(*rx_ring, i); ++ rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); + -+ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { -+ if (!vlan_group_get_device(adapter->vlgrp, vid)) -+ continue; -+ e1000_vlan_rx_add_vid(adapter->netdev, vid); ++ i++; ++ if (i == rx_ring->count) ++ i = 0; ++ buffer_info = &rx_ring->buffer_info[i]; + } -+} -+ -+static void e1000_init_manageability(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 manc, manc2h; -+ -+ if (!(adapter->flags & FLAG_MNG_PT_ENABLED)) -+ return; -+ -+ manc = er32(MANC); + -+ /* disable hardware interception of ARP */ -+ manc &= ~(E1000_MANC_ARP_EN); -+ -+ /* enable receiving management packets to the host. this will probably -+ * generate destination unreachable messages from the host OS, but -+ * the packets will be handled on SMBUS */ -+ manc |= E1000_MANC_EN_MNG2HOST; -+ manc2h = er32(MANC2H); -+#define E1000_MNG2HOST_PORT_623 (1 << 5) -+#define E1000_MNG2HOST_PORT_664 (1 << 6) -+ manc2h |= E1000_MNG2HOST_PORT_623; -+ manc2h |= E1000_MNG2HOST_PORT_664; -+ ew32(MANC2H, manc2h); -+ ew32(MANC, manc); ++ if (rx_ring->next_to_use != i) { ++ rx_ring->next_to_use = i; ++ if (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->tail); ++ } +} + +/** -+ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset -+ * @adapter: board private structure -+ * -+ * Configure the Tx unit of the MAC after a reset. ++ * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split ++ * @adapter: address of board private structure + **/ -+static void e1000_configure_tx(struct e1000_adapter *adapter) ++static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ++ int cleaned_count) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ u64 tdba; -+ u32 tdlen, tctl, tipg, tarc; -+ u32 ipgr1, ipgr2; -+ -+ /* Setup the HW Tx Head and Tail descriptor pointers */ -+ tdba = tx_ring->dma; -+ tdlen = tx_ring->count * sizeof(struct e1000_tx_desc); -+ ew32(TDBAL, (tdba & DMA_32BIT_MASK)); -+ ew32(TDBAH, (tdba >> 32)); -+ ew32(TDLEN, tdlen); -+ ew32(TDH, 0); -+ ew32(TDT, 0); -+ tx_ring->head = E1000_TDH; -+ tx_ring->tail = E1000_TDT; -+ -+ /* Set the default values for the Tx Inter Packet Gap timer */ -+ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ -+ ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ -+ ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ ++ struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; ++ union e1000_rx_desc_packet_split *rx_desc; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_buffer *buffer_info; ++ struct e1000_ps_page *ps_page; ++ struct sk_buff *skb; ++ unsigned int i, j; + -+ if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) -+ ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ ++ i = rx_ring->next_to_use; ++ buffer_info = &rx_ring->buffer_info[i]; + -+ tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; -+ tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; -+ ew32(TIPG, tipg); ++ while (cleaned_count--) { ++ rx_desc = E1000_RX_DESC_PS(*rx_ring, i); + -+ /* Set the Tx Interrupt Delay register */ -+ ew32(TIDV, adapter->tx_int_delay); -+ /* tx irq moderation */ -+ ew32(TADV, adapter->tx_abs_int_delay); ++ for (j = 0; j < PS_PAGE_BUFFERS; j++) { ++ ps_page = &buffer_info->ps_pages[j]; ++ if (j >= adapter->rx_ps_pages) { ++ /* all unused desc entries get hw null ptr */ ++ rx_desc->read.buffer_addr[j+1] = ~0; ++ continue; ++ } ++ if (!ps_page->page) { ++ ps_page->page = alloc_page(GFP_ATOMIC); ++ if (!ps_page->page) { ++ adapter->alloc_rx_buff_failed++; ++ goto no_buffers; ++ } ++ ps_page->dma = pci_map_page(pdev, ++ ps_page->page, ++ 0, PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(pdev, ps_page->dma)) { ++ dev_err(&adapter->pdev->dev, ++ "RX DMA page map failed\n"); ++ adapter->rx_dma_failed++; ++ goto no_buffers; ++ } ++ } ++ /* ++ * 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); ++ } + -+ /* Program the Transmit Control Register */ -+ tctl = er32(TCTL); -+ tctl &= ~E1000_TCTL_CT; -+ tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | -+ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); ++ skb = netdev_alloc_skb(netdev, ++ adapter->rx_ps_bsize0 + NET_IP_ALIGN); + -+ if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { -+ tarc = er32(TARC0); -+ /* set the speed mode bit, we'll clear it if we're not at -+ * gigabit link later */ -+#define SPEED_MODE_BIT (1 << 21) -+ tarc |= SPEED_MODE_BIT; -+ ew32(TARC0, tarc); -+ } ++ if (!skb) { ++ adapter->alloc_rx_buff_failed++; ++ break; ++ } + -+ /* errata: program both queues to unweighted RR */ -+ if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) { -+ tarc = er32(TARC0); -+ tarc |= 1; -+ ew32(TARC0, tarc); -+ tarc = er32(TARC1); -+ tarc |= 1; -+ ew32(TARC1, tarc); -+ } ++ /* ++ * 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); + -+ e1000e_config_collision_dist(hw); ++ buffer_info->skb = skb; ++ buffer_info->dma = pci_map_single(pdev, skb->data, ++ adapter->rx_ps_bsize0, ++ PCI_DMA_FROMDEVICE); ++ if (pci_dma_mapping_error(pdev, buffer_info->dma)) { ++ dev_err(&pdev->dev, "RX DMA map failed\n"); ++ adapter->rx_dma_failed++; ++ /* cleanup skb */ ++ dev_kfree_skb_any(skb); ++ buffer_info->skb = NULL; ++ break; ++ } + -+ /* Setup Transmit Descriptor Settings for eop descriptor */ -+ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; ++ rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); + -+ /* only set IDE if we are delaying interrupts using the timers */ -+ if (adapter->tx_int_delay) -+ adapter->txd_cmd |= E1000_TXD_CMD_IDE; ++ i++; ++ if (i == rx_ring->count) ++ i = 0; ++ buffer_info = &rx_ring->buffer_info[i]; ++ } + -+ /* enable Report Status bit */ -+ adapter->txd_cmd |= E1000_TXD_CMD_RS; ++no_buffers: ++ if (rx_ring->next_to_use != i) { ++ rx_ring->next_to_use = i; + -+ ew32(TCTL, tctl); ++ if (!(i--)) ++ i = (rx_ring->count - 1); + -+ adapter->tx_queue_len = adapter->netdev->tx_queue_len; ++ /* ++ * 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->tail); ++ } +} + ++#ifdef CONFIG_E1000E_NAPI +/** -+ * e1000_setup_rctl - configure the receive control registers -+ * @adapter: Board private structure ++ * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers ++ * @adapter: address of board private structure ++ * @rx_ring: pointer to receive ring structure ++ * @cleaned_count: number of buffers to allocate this pass + **/ -+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \ -+ (((S) & (PAGE_SIZE - 1)) ? 1 : 0)) -+static void e1000_setup_rctl(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; -+ u32 rctl, rfctl; -+ u32 psrctl = 0; -+ u32 pages = 0; -+ -+ /* Program MC offset vector base */ -+ rctl = er32(RCTL); -+ rctl &= ~(3 << E1000_RCTL_MO_SHIFT); -+ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | -+ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | -+ (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); -+ -+ /* Do not Store bad packets */ -+ rctl &= ~E1000_RCTL_SBP; -+ -+ /* Enable Long Packet receive */ -+ 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 256: -+ rctl |= E1000_RCTL_SZ_256; -+ rctl &= ~E1000_RCTL_BSEX; -+ break; -+ case 512: -+ rctl |= E1000_RCTL_SZ_512; -+ rctl &= ~E1000_RCTL_BSEX; -+ break; -+ case 1024: -+ rctl |= E1000_RCTL_SZ_1024; -+ rctl &= ~E1000_RCTL_BSEX; -+ break; -+ case 2048: -+ default: -+ rctl |= E1000_RCTL_SZ_2048; -+ rctl &= ~E1000_RCTL_BSEX; -+ break; -+ case 4096: -+ rctl |= E1000_RCTL_SZ_4096; -+ break; -+ case 8192: -+ rctl |= E1000_RCTL_SZ_8192; -+ break; -+ case 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. -+ * -+ * allocations using alloc_page take too long for regular MTU -+ * so only enable packet split for jumbo frames -+ * -+ * Using pages when the page size is greater than 16k wastes -+ * a lot of memory, since we allocate 3 pages at all times -+ * per packet. -+ */ -+ adapter->rx_ps_pages = 0; -+ pages = PAGE_USE_COUNT(adapter->netdev->mtu); -+ if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) -+ adapter->rx_ps_pages = pages; -+#endif -+ if (adapter->rx_ps_pages) { -+ /* Configure extra packet-split registers */ -+ rfctl = er32(RFCTL); -+ rfctl |= E1000_RFCTL_EXTEN; -+ /* disable packet split support for IPv6 extension headers, -+ * because some malformed IPv6 headers can hang the RX */ -+ rfctl |= (E1000_RFCTL_IPV6_EX_DIS | -+ E1000_RFCTL_NEW_IPV6_EXT_DIS); + -+ ew32(RFCTL, rfctl); ++static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, ++ int cleaned_count) ++{ ++ struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_rx_desc *rx_desc; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_buffer *buffer_info; ++ struct sk_buff *skb; ++ unsigned int i; ++ unsigned int bufsz = 256 - ++ 16 /* for skb_reserve */ - ++ NET_IP_ALIGN; + -+ /* disable the stripping of CRC because it breaks -+ * BMC firmware connected over SMBUS */ -+ rctl |= E1000_RCTL_DTYP_PS /* | E1000_RCTL_SECRC */; ++ i = rx_ring->next_to_use; ++ buffer_info = &rx_ring->buffer_info[i]; + -+ psrctl |= adapter->rx_ps_bsize0 >> -+ E1000_PSRCTL_BSIZE0_SHIFT; ++ while (cleaned_count--) { ++ skb = buffer_info->skb; ++ if (skb) { ++ skb_trim(skb, 0); ++ goto check_page; ++ } + -+ 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; ++ skb = netdev_alloc_skb(netdev, bufsz); ++ if (unlikely(!skb)) { ++ /* Better luck next round */ ++ adapter->alloc_rx_buff_failed++; + break; + } + -+ ew32(PSRCTL, psrctl); ++ /* 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); ++ ++ buffer_info->skb = skb; ++check_page: ++ /* allocate a new page if necessary */ ++ if (!buffer_info->page) { ++ buffer_info->page = alloc_page(GFP_ATOMIC); ++ if (unlikely(!buffer_info->page)) { ++ adapter->alloc_rx_buff_failed++; ++ break; ++ } ++ } ++ ++ if (!buffer_info->dma) ++ buffer_info->dma = pci_map_page(pdev, ++ buffer_info->page, 0, ++ PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ ++ rx_desc = E1000_RX_DESC(*rx_ring, i); ++ rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); ++ ++ if (unlikely(++i == rx_ring->count)) ++ i = 0; ++ buffer_info = &rx_ring->buffer_info[i]; + } + -+ ew32(RCTL, rctl); ++ 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->tail); ++ } +} ++#endif /* CONFIG_E1000E_NAPI */ + +/** -+ * e1000_configure_rx - Configure Receive Unit after Reset ++ * e1000_clean_rx_irq - Send received data up the network stack; legacy + * @adapter: board private structure + * -+ * Configure the Rx unit of the MAC after a reset. ++ * the return value indicates whether actual cleaning was done, there ++ * is no guarantee that everything was cleaned + **/ -+static void e1000_configure_rx(struct e1000_adapter *adapter) ++#ifdef CONFIG_E1000E_NAPI ++static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, ++ int *work_done, int work_to_do) ++#else ++static bool e1000_clean_rx_irq(struct e1000_adapter *adapter) ++#endif +{ -+ struct e1000_hw *hw = &adapter->hw; ++ struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; + struct e1000_ring *rx_ring = adapter->rx_ring; -+ u64 rdba; -+ u32 rdlen, rctl, rxcsum, ctrl_ext; ++ struct e1000_rx_desc *rx_desc, *next_rxd; ++ struct e1000_buffer *buffer_info, *next_buffer; ++ u32 length; ++ unsigned int i; ++ int cleaned_count = 0; ++ bool cleaned = 0; ++ unsigned int total_rx_bytes = 0, total_rx_packets = 0; + -+ if (adapter->rx_ps_pages) { -+ /* this is a 32 byte descriptor */ -+ rdlen = rx_ring->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 if (adapter->netdev->mtu > ETH_FRAME_LEN + VLAN_HLEN + 4) { -+ rdlen = rx_ring->count * -+ sizeof(struct e1000_rx_desc); -+ adapter->clean_rx = e1000_clean_rx_irq_jumbo; -+ adapter->alloc_rx_buf = e1000_alloc_rx_buffers_jumbo; -+ } else { -+ rdlen = rx_ring->count * -+ sizeof(struct e1000_rx_desc); -+ adapter->clean_rx = e1000_clean_rx_irq; -+ adapter->alloc_rx_buf = e1000_alloc_rx_buffers; -+ } ++ i = rx_ring->next_to_clean; ++ rx_desc = E1000_RX_DESC(*rx_ring, i); ++ buffer_info = &rx_ring->buffer_info[i]; + -+ /* disable receives while setting up the descriptors */ -+ rctl = er32(RCTL); -+ ew32(RCTL, rctl & ~E1000_RCTL_EN); -+ e1e_flush(); -+ msleep(10); ++ while (rx_desc->status & E1000_RXD_STAT_DD) { ++ struct sk_buff *skb; ++ u8 status; + -+ /* set the Receive Delay Timer Register */ -+ ew32(RDTR, adapter->rx_int_delay); ++#ifdef CONFIG_E1000E_NAPI ++ if (*work_done >= work_to_do) ++ break; ++ (*work_done)++; ++#endif + -+ /* irq moderation */ -+ ew32(RADV, adapter->rx_abs_int_delay); -+ if (adapter->itr_setting != 0) -+ ew32(ITR, -+ 1000000000 / (adapter->itr * 256)); ++ status = rx_desc->status; ++ skb = buffer_info->skb; ++ buffer_info->skb = NULL; + -+ ctrl_ext = er32(CTRL_EXT); -+ /* Reset delay timers after every interrupt */ -+ ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; -+ /* Auto-Mask interrupts upon ICR access */ -+ ctrl_ext |= E1000_CTRL_EXT_IAME; -+ ew32(IAM, 0xffffffff); -+ ew32(CTRL_EXT, ctrl_ext); -+ e1e_flush(); ++ prefetch(skb->data - NET_IP_ALIGN); + -+ /* Setup the HW Rx Head and Tail Descriptor Pointers and -+ * the Base and Length of the Rx Descriptor Ring */ -+ rdba = rx_ring->dma; -+ ew32(RDBAL, (rdba & DMA_32BIT_MASK)); -+ ew32(RDBAH, (rdba >> 32)); -+ ew32(RDLEN, rdlen); -+ ew32(RDH, 0); -+ ew32(RDT, 0); -+ rx_ring->head = E1000_RDH; -+ rx_ring->tail = E1000_RDT; ++ i++; ++ if (i == rx_ring->count) ++ i = 0; ++ next_rxd = E1000_RX_DESC(*rx_ring, i); ++ prefetch(next_rxd); + -+ /* Enable Receive Checksum Offload for TCP and UDP */ -+ rxcsum = er32(RXCSUM); -+ if (adapter->flags & FLAG_RX_CSUM_ENABLED) { -+ rxcsum |= E1000_RXCSUM_TUOFL; ++ next_buffer = &rx_ring->buffer_info[i]; + -+ /* IPv4 payload checksum for UDP fragments must be -+ * used in conjunction with packet-split. */ -+ if (adapter->rx_ps_pages) -+ rxcsum |= E1000_RXCSUM_IPPCSE; -+ } else { -+ rxcsum &= ~E1000_RXCSUM_TUOFL; -+ /* no need to clear IPPCSE as it defaults to 0 */ ++ cleaned = 1; ++ cleaned_count++; ++ pci_unmap_single(pdev, ++ buffer_info->dma, ++ adapter->rx_buffer_len, ++ PCI_DMA_FROMDEVICE); ++ buffer_info->dma = 0; ++ ++ length = le16_to_cpu(rx_desc->length); ++ ++ /* !EOP means multiple descriptors were used to store a single ++ * packet, also make sure the frame isn't just CRC only */ ++ if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) { ++ /* All receives must fit into a single buffer */ ++ e_dbg("Receive packet consumed multiple buffers\n"); ++ /* recycle */ ++ buffer_info->skb = skb; ++ goto next_desc; ++ } ++ ++ if (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) { ++ /* recycle */ ++ buffer_info->skb = skb; ++ goto next_desc; ++ } ++ ++ total_rx_bytes += length; ++ total_rx_packets++; ++ ++ /* ++ * code added for copybreak, this should improve ++ * performance for small packets with large amounts ++ * of reassembly being done in the stack ++ */ ++ if (length < copybreak) { ++ struct sk_buff *new_skb = ++ netdev_alloc_skb(netdev, length + NET_IP_ALIGN); ++ if (new_skb) { ++ skb_reserve(new_skb, NET_IP_ALIGN); ++ skb_copy_to_linear_data_offset(new_skb, ++ -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; ++ } ++ /* else just continue with the old one */ ++ } ++ /* end copybreak code */ ++ skb_put(skb, length); ++ ++ /* Receive Checksum Offload */ ++ e1000_rx_checksum(adapter, ++ (u32)(status) | ++ ((u32)(rx_desc->errors) << 24), ++ le16_to_cpu(rx_desc->csum), skb); ++ ++ e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special); ++ ++next_desc: ++ rx_desc->status = 0; ++ ++ /* return some buffers to hardware, one at a time is too slow */ ++ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { ++ adapter->alloc_rx_buf(adapter, cleaned_count); ++ cleaned_count = 0; ++ } ++ ++ /* use prefetched values */ ++ rx_desc = next_rxd; ++ buffer_info = next_buffer; + } -+ ew32(RXCSUM, rxcsum); ++ rx_ring->next_to_clean = i; + -+ /* Enable early receives on supported devices, only takes effect when -+ * packet size is equal or larger than the specified value (in 8 byte -+ * units), e.g. using jumbo frames when setting to E1000_ERT_2048 */ -+ if ((adapter->flags & FLAG_HAS_ERT) && -+ (adapter->netdev->mtu > ETH_DATA_LEN)) -+ ew32(ERT, E1000_ERT_2048); ++ cleaned_count = e1000_desc_unused(rx_ring); ++ if (cleaned_count) ++ adapter->alloc_rx_buf(adapter, cleaned_count); + -+ /* Enable Receives */ -+ ew32(RCTL, rctl); ++ adapter->total_rx_packets += total_rx_packets; ++ adapter->total_rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_packets += total_rx_packets; ++ return cleaned; ++} ++ ++static void e1000_put_txbuf(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); ++ buffer_info->dma = 0; ++ } ++ if (buffer_info->skb) { ++ dev_kfree_skb_any(buffer_info->skb); ++ buffer_info->skb = NULL; ++ } ++} ++ ++static void e1000_print_tx_hang(struct e1000_adapter *adapter) ++{ ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ unsigned int i = tx_ring->next_to_clean; ++ unsigned int eop = tx_ring->buffer_info[i].next_to_watch; ++ struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop); ++ ++ /* detected Tx unit hang */ ++ e_err("Detected Tx Unit Hang:\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", ++ readl(adapter->hw.hw_addr + tx_ring->head), ++ readl(adapter->hw.hw_addr + tx_ring->tail), ++ tx_ring->next_to_use, ++ tx_ring->next_to_clean, ++ tx_ring->buffer_info[eop].time_stamp, ++ eop, ++ jiffies, ++ eop_desc->upper.fields.status); +} + +/** -+ * e1000_mc_addr_list_update - Update Multicast addresses -+ * @hw: pointer to the HW structure -+ * @mc_addr_list: array of multicast addresses to program -+ * @mc_addr_count: number of multicast addresses to program -+ * @rar_used_count: the first RAR register free to program -+ * @rar_count: total number of supported Receive Address Registers ++ * @e1000_alloc_ring - allocate memory for a ring structure ++ **/ ++static int e1000_alloc_ring_dma(struct e1000_adapter *adapter, ++ struct e1000_ring *ring) ++{ ++ struct pci_dev *pdev = adapter->pdev; ++ ++ ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma, ++ GFP_KERNEL); ++ if (!ring->desc) ++ return -ENOMEM; ++ ++ return 0; ++} ++ ++/** ++ * e1000e_setup_tx_resources - allocate Tx resources (Descriptors) ++ * @adapter: board private structure + * -+ * Updates the Receive Address Registers and Multicast Table Array. -+ * The caller must have a packed mc_addr_list of multicast addresses. -+ * The parameter rar_count will usually be hw->mac.rar_entry_count -+ * unless there are workarounds that change this. Currently no func pointer -+ * exists and all implementations are handled in the generic version of this -+ * function. ++ * Return 0 on success, negative on failure + **/ -+static void e1000_mc_addr_list_update(struct e1000_hw *hw, u8 *mc_addr_list, -+ u32 mc_addr_count, u32 rar_used_count, -+ u32 rar_count) ++int e1000_setup_tx_resources(struct e1000_adapter *adapter) +{ -+ hw->mac.ops.mc_addr_list_update(hw, mc_addr_list, mc_addr_count, -+ rar_used_count, rar_count); ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ int err = -ENOMEM, size; ++ ++ size = sizeof(struct e1000_buffer) * tx_ring->count; ++ tx_ring->buffer_info = vmalloc(size); ++ if (!tx_ring->buffer_info) ++ goto err; ++ memset(tx_ring->buffer_info, 0, size); ++ ++ /* round up to nearest 4K */ ++ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc); ++ tx_ring->size = ALIGN(tx_ring->size, 4096); ++ ++ err = e1000_alloc_ring_dma(adapter, tx_ring); ++ if (err) ++ goto err; ++ ++ tx_ring->next_to_use = 0; ++ tx_ring->next_to_clean = 0; ++ spin_lock_init(&adapter->tx_queue_lock); ++ ++ return 0; ++err: ++ vfree(tx_ring->buffer_info); ++ e_err("Unable to allocate memory for the transmit descriptor ring\n"); ++ return err; +} + +/** -+ * e1000_set_multi - Multicast and Promiscuous mode set -+ * @netdev: network interface device structure ++ * e1000e_setup_rx_resources - allocate Rx resources (Descriptors) ++ * @adapter: board private structure + * -+ * The set_multi entry point is called whenever the multicast address -+ * list or the network interface flags are updated. This routine is -+ * responsible for configuring the hardware for proper multicast, -+ * promiscuous mode, and all-multi behavior. ++ * Returns 0 on success, negative on failure + **/ -+static void e1000_set_multi(struct net_device *netdev) ++int e1000_setup_rx_resources(struct e1000_adapter *adapter) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; -+ struct e1000_mac_info *mac = &hw->mac; -+ struct dev_mc_list *mc_ptr; -+ u8 *mta_list; -+ u32 rctl; -+ int i; -+ -+ /* Check for Promiscuous and All Multicast modes */ ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_buffer *buffer_info; ++ int i, size, desc_len, err = -ENOMEM; + -+ rctl = er32(RCTL); ++ size = sizeof(struct e1000_buffer) * rx_ring->count; ++ rx_ring->buffer_info = vmalloc(size); ++ if (!rx_ring->buffer_info) ++ goto err; ++ memset(rx_ring->buffer_info, 0, size); + -+ if (netdev->flags & IFF_PROMISC) { -+ rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); -+ } else if (netdev->flags & IFF_ALLMULTI) { -+ rctl |= E1000_RCTL_MPE; -+ rctl &= ~E1000_RCTL_UPE; -+ } else { -+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); ++ for (i = 0; i < rx_ring->count; i++) { ++ buffer_info = &rx_ring->buffer_info[i]; ++ buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS, ++ sizeof(struct e1000_ps_page), ++ GFP_KERNEL); ++ if (!buffer_info->ps_pages) ++ goto err_pages; + } + -+ ew32(RCTL, rctl); ++ desc_len = sizeof(union e1000_rx_desc_packet_split); + -+ if (netdev->mc_count) { -+ mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC); -+ if (!mta_list) -+ return; ++ /* Round up to nearest 4K */ ++ rx_ring->size = rx_ring->count * desc_len; ++ rx_ring->size = ALIGN(rx_ring->size, 4096); + -+ /* prepare a packed array of only addresses. */ -+ mc_ptr = netdev->mc_list; ++ err = e1000_alloc_ring_dma(adapter, rx_ring); ++ if (err) ++ goto err_pages; + -+ for (i = 0; i < netdev->mc_count; i++) { -+ if (!mc_ptr) -+ break; -+ memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, -+ ETH_ALEN); -+ mc_ptr = mc_ptr->next; -+ } ++ rx_ring->next_to_clean = 0; ++ rx_ring->next_to_use = 0; ++ rx_ring->rx_skb_top = NULL; + -+ e1000_mc_addr_list_update(hw, mta_list, i, 1, -+ mac->rar_entry_count); -+ kfree(mta_list); -+ } else { -+ /* -+ * if we're called from probe, we might not have -+ * anything to do here, so clear out the list -+ */ -+ e1000_mc_addr_list_update(hw, NULL, 0, 1, -+ mac->rar_entry_count); ++ return 0; ++ ++err_pages: ++ for (i = 0; i < rx_ring->count; i++) { ++ buffer_info = &rx_ring->buffer_info[i]; ++ kfree(buffer_info->ps_pages); + } ++err: ++ vfree(rx_ring->buffer_info); ++ e_err("Unable to allocate memory for the transmit descriptor ring\n"); ++ return err; +} + +/** -+ * e1000_configure - configure the hardware for RX and TX -+ * @adapter: private board structure ++ * e1000_clean_tx_ring - Free Tx Buffers ++ * @adapter: board private structure + **/ -+static void e1000_configure(struct e1000_adapter *adapter) ++static void e1000_clean_tx_ring(struct e1000_adapter *adapter) +{ -+ e1000_set_multi(adapter->netdev); ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_buffer *buffer_info; ++ unsigned long size; ++ unsigned int i; + -+ e1000_restore_vlan(adapter); -+ e1000_init_manageability(adapter); ++ for (i = 0; i < tx_ring->count; i++) { ++ buffer_info = &tx_ring->buffer_info[i]; ++ e1000_put_txbuf(adapter, buffer_info); ++ } + -+ e1000_configure_tx(adapter); -+ e1000_setup_rctl(adapter); -+ e1000_configure_rx(adapter); -+ adapter->alloc_rx_buf(adapter, -+ e1000_desc_unused(adapter->rx_ring)); -+} ++ size = sizeof(struct e1000_buffer) * tx_ring->count; ++ memset(tx_ring->buffer_info, 0, size); + -+/** -+ * e1000e_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 e1000e_reset *** -+ **/ -+void e1000e_power_up_phy(struct e1000_adapter *adapter) -+{ -+ u16 mii_reg = 0; ++ memset(tx_ring->desc, 0, tx_ring->size); + -+ /* 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 */ -+ e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg); -+ mii_reg &= ~MII_CR_POWER_DOWN; -+ e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg); -+ } ++ tx_ring->next_to_use = 0; ++ tx_ring->next_to_clean = 0; + -+ adapter->hw.mac.ops.setup_link(&adapter->hw); ++ writel(0, adapter->hw.hw_addr + tx_ring->head); ++ writel(0, adapter->hw.hw_addr + tx_ring->tail); +} + +/** -+ * e1000_power_down_phy - Power down the PHY ++ * e1000_free_tx_resources - Free Tx Resources per Queue ++ * @adapter: board private structure + * -+ * Power down the PHY so no link is implied when interface is down -+ * The PHY cannot be powered down is management or WoL is active -+ */ -+static void e1000_power_down_phy(struct e1000_adapter *adapter) ++ * Free all transmit software resources ++ **/ ++void e1000_free_tx_resources(struct e1000_adapter *adapter) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u16 mii_reg; -+ -+ /* WoL is enabled */ -+ if (!adapter->wol) -+ return; -+ -+ /* non-copper PHY? */ -+ if (adapter->hw.media_type != e1000_media_type_copper) -+ return; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_ring *tx_ring = adapter->tx_ring; + -+ /* reset is blocked because of a SoL/IDER session */ -+ if (e1000e_check_mng_mode(hw) || -+ e1000_check_reset_block(hw)) -+ return; ++ e1000_clean_tx_ring(adapter); + -+ /* managebility (AMT) is enabled */ -+ if (er32(MANC) & E1000_MANC_SMBUS_EN) -+ return; ++ vfree(tx_ring->buffer_info); ++ tx_ring->buffer_info = NULL; + -+ /* power down the PHY */ -+ e1e_rphy(hw, PHY_CONTROL, &mii_reg); -+ mii_reg |= MII_CR_POWER_DOWN; -+ e1e_wphy(hw, PHY_CONTROL, mii_reg); -+ mdelay(1); ++ dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc, ++ tx_ring->dma); ++ tx_ring->desc = NULL; +} + +/** -+ * e1000e_reset - bring the hardware into a known good state ++ * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split ++ * @adapter: board private structure + * -+ * This function boots the hardware and enables some settings that -+ * require a configuration cycle of the hardware - those cannot be -+ * set/changed during runtime. After reset the device needs to be -+ * properly configured for rx, tx etc. -+ */ -+void e1000e_reset(struct e1000_adapter *adapter) ++ * the return value indicates whether actual cleaning was done, there ++ * is no guarantee that everything was cleaned ++ **/ ++#ifdef CONFIG_E1000E_NAPI ++static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, ++ int *work_done, int work_to_do) ++#else ++static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter) ++#endif +{ -+ struct e1000_mac_info *mac = &adapter->hw.mac; -+ struct e1000_hw *hw = &adapter->hw; -+ u32 tx_space, min_tx_space, min_rx_space; -+ u16 hwm; ++ union e1000_rx_desc_packet_split *rx_desc, *next_rxd; ++ struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_buffer *buffer_info, *next_buffer; ++ struct e1000_ps_page *ps_page; ++ struct sk_buff *skb; ++ unsigned int i, j; ++ u32 length, staterr; ++ int cleaned_count = 0; ++ bool cleaned = 0; ++ unsigned int total_rx_bytes = 0, total_rx_packets = 0; + -+ if (mac->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) { -+ /* To maintain wire speed transmits, the Tx FIFO should be -+ * large enough to accommodate two full transmit packets, -+ * rounded up to the next 1KB and expressed in KB. Likewise, -+ * the Rx FIFO should be large enough to accommodate at least -+ * one full receive packet and is similarly rounded up and -+ * expressed in KB. */ -+ adapter->pba = er32(PBA); -+ /* upper 16 bits has Tx packet buffer allocation size in KB */ -+ tx_space = adapter->pba >> 16; -+ /* lower 16 bits has Rx packet buffer allocation size in KB */ -+ adapter->pba &= 0xffff; -+ /* the tx fifo also stores 16 bytes of information about the tx -+ * but don't include ethernet FCS because hardware appends it */ -+ min_tx_space = (mac->max_frame_size + -+ sizeof(struct e1000_tx_desc) - -+ ETH_FCS_LEN) * 2; -+ min_tx_space = ALIGN(min_tx_space, 1024); -+ min_tx_space >>= 10; -+ /* software strips receive CRC, so leave room for it */ -+ min_rx_space = mac->max_frame_size; -+ min_rx_space = ALIGN(min_rx_space, 1024); -+ min_rx_space >>= 10; ++ 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]; + -+ /* If current Tx allocation is less than the min Tx FIFO size, -+ * and the min Tx FIFO size is less than the current Rx FIFO -+ * allocation, take space away from current Rx allocation */ -+ if (tx_space < min_tx_space && -+ ((min_tx_space - tx_space) < adapter->pba)) { -+ adapter->pba -= - (min_tx_space - tx_space); -+ -+ /* if short on rx space, rx wins and must trump tx -+ * adjustment or use Early Receive if available */ -+ if ((adapter->pba < min_rx_space) && -+ (!(adapter->flags & FLAG_HAS_ERT))) -+ /* ERT enabled in e1000_configure_rx */ -+ adapter->pba = min_rx_space; -+ } -+ } ++ while (staterr & E1000_RXD_STAT_DD) { ++#ifdef CONFIG_E1000E_NAPI ++ if (*work_done >= work_to_do) ++ break; ++ (*work_done)++; ++#endif ++ skb = buffer_info->skb; + -+ ew32(PBA, adapter->pba); ++ /* in the packet split case this is header only */ ++ prefetch(skb->data - NET_IP_ALIGN); + -+ /* flow control settings */ -+ /* The high water mark must be low enough to fit one full frame -+ * (or the size used for early receive) above it in the Rx FIFO. -+ * Set it to the lower of: -+ * - 90% of the Rx FIFO size, and -+ * - the full Rx FIFO size minus the early receive size (for parts -+ * with ERT support assuming ERT set to E1000_ERT_2048), or -+ * - the full Rx FIFO size minus one full frame */ -+ if (adapter->flags & FLAG_HAS_ERT) -+ hwm = min(((adapter->pba << 10) * 9 / 10), -+ ((adapter->pba << 10) - (E1000_ERT_2048 << 3))); -+ else -+ hwm = min(((adapter->pba << 10) * 9 / 10), -+ ((adapter->pba << 10) - mac->max_frame_size)); ++ i++; ++ if (i == rx_ring->count) ++ i = 0; ++ next_rxd = E1000_RX_DESC_PS(*rx_ring, i); ++ prefetch(next_rxd); + -+ mac->fc_high_water = hwm & 0xFFF8; /* 8-byte granularity */ -+ mac->fc_low_water = mac->fc_high_water - 8; ++ next_buffer = &rx_ring->buffer_info[i]; + -+ if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) -+ mac->fc_pause_time = 0xFFFF; -+ else -+ mac->fc_pause_time = E1000_FC_PAUSE_TIME; -+ mac->fc = mac->original_fc; ++ cleaned = 1; ++ cleaned_count++; ++ pci_unmap_single(pdev, buffer_info->dma, ++ adapter->rx_ps_bsize0, ++ PCI_DMA_FROMDEVICE); ++ buffer_info->dma = 0; + -+ /* Allow time for pending master requests to run */ -+ mac->ops.reset_hw(hw); -+ ew32(WUC, 0); ++ if (!(staterr & E1000_RXD_STAT_EOP)) { ++ e_dbg("Packet Split buffers didn't pick up the full" ++ " packet\n"); ++ dev_kfree_skb_irq(skb); ++ goto next_desc; ++ } + -+ if (mac->ops.init_hw(hw)) -+ ndev_err(adapter->netdev, "Hardware Error\n"); ++ if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) { ++ dev_kfree_skb_irq(skb); ++ goto next_desc; ++ } + -+ e1000_update_mng_vlan(adapter); ++ length = le16_to_cpu(rx_desc->wb.middle.length0); + -+ /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ -+ ew32(VET, ETH_P_8021Q); ++ if (!length) { ++ e_dbg("Last part of the packet spanning multiple" ++ " descriptors\n"); ++ dev_kfree_skb_irq(skb); ++ goto next_desc; ++ } + -+ e1000e_reset_adaptive(hw); -+ e1000_get_phy_info(hw); ++ /* Good Receive */ ++ skb_put(skb, length); + -+ if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) { -+ u16 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 */ -+ e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); -+ phy_data &= ~IGP02E1000_PM_SPD; -+ e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); -+ } ++#ifdef CONFIG_E1000E_NAPI ++ { ++ /* ++ * 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]); + -+ e1000_release_manageability(adapter); -+} ++ /* ++ * page alloc/put takes too long and effects small packet ++ * throughput, so unsplit small packets and save the alloc/put ++ * only valid in softirq (napi) context to call kmap_* ++ */ ++ if (l1 && (l1 <= copybreak) && ++ ((length + l1) <= adapter->rx_ps_bsize0)) { ++ u8 *vaddr; + -+int e1000e_up(struct e1000_adapter *adapter) -+{ -+ struct e1000_hw *hw = &adapter->hw; ++ ps_page = &buffer_info->ps_pages[0]; + -+ /* hardware has been reset, we need to reload some things */ -+ e1000_configure(adapter); ++ /* ++ * 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, ++ PAGE_SIZE, PCI_DMA_FROMDEVICE); ++ vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ); ++ memcpy(skb_tail_pointer(skb), vaddr, l1); ++ kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); ++ pci_dma_sync_single_for_device(pdev, ps_page->dma, ++ PAGE_SIZE, PCI_DMA_FROMDEVICE); + -+ clear_bit(__E1000_DOWN, &adapter->state); ++ skb_put(skb, l1); ++ goto copydone; ++ } /* if */ ++ } ++#endif + -+ netif_poll_enable(adapter->netdev); -+ e1000_irq_enable(adapter); ++ for (j = 0; j < PS_PAGE_BUFFERS; j++) { ++ length = le16_to_cpu(rx_desc->wb.upper.length[j]); ++ if (!length) ++ break; + -+ /* fire a link change interrupt to start the watchdog */ -+ ew32(ICS, E1000_ICS_LSC); -+ return 0; -+} ++ ps_page = &buffer_info->ps_pages[j]; ++ pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ ps_page->dma = 0; ++ skb_fill_page_desc(skb, j, ps_page->page, 0, length); ++ ps_page->page = NULL; ++ skb->len += length; ++ skb->data_len += length; ++ skb->truesize += length; ++ } + -+void e1000e_down(struct e1000_adapter *adapter) -+{ -+ struct net_device *netdev = adapter->netdev; -+ struct e1000_hw *hw = &adapter->hw; -+ u32 tctl, rctl; ++#ifdef CONFIG_E1000E_NAPI ++copydone: ++#endif ++ total_rx_bytes += skb->len; ++ total_rx_packets++; + -+ /* signal that we're down so the interrupt handler does not -+ * reschedule our watchdog timer */ -+ set_bit(__E1000_DOWN, &adapter->state); ++ e1000_rx_checksum(adapter, staterr, le16_to_cpu( ++ rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); + -+ /* disable receives in the hardware */ -+ rctl = er32(RCTL); -+ ew32(RCTL, rctl & ~E1000_RCTL_EN); -+ /* flush and sleep below */ ++ if (rx_desc->wb.upper.header_status & ++ cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) ++ adapter->rx_hdr_split++; + -+ netif_stop_queue(netdev); ++ e1000_receive_skb(adapter, netdev, skb, ++ staterr, rx_desc->wb.middle.vlan); + -+ /* disable transmits in the hardware */ -+ tctl = er32(TCTL); -+ tctl &= ~E1000_TCTL_EN; -+ ew32(TCTL, tctl); -+ /* flush both disables and wait for them to finish */ -+ e1e_flush(); -+ msleep(10); ++next_desc: ++ rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); ++ buffer_info->skb = NULL; + -+ netif_poll_disable(netdev); -+ e1000_irq_disable(adapter); ++ /* return some buffers to hardware, one at a time is too slow */ ++ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { ++ adapter->alloc_rx_buf(adapter, cleaned_count); ++ cleaned_count = 0; ++ } + -+ del_timer_sync(&adapter->watchdog_timer); -+ del_timer_sync(&adapter->phy_info_timer); ++ /* use prefetched values */ ++ rx_desc = next_rxd; ++ buffer_info = next_buffer; + -+ netdev->tx_queue_len = adapter->tx_queue_len; -+ netif_carrier_off(netdev); -+ adapter->link_speed = 0; -+ adapter->link_duplex = 0; ++ staterr = le32_to_cpu(rx_desc->wb.middle.status_error); ++ } ++ rx_ring->next_to_clean = i; + -+ e1000e_reset(adapter); -+ e1000_clean_tx_ring(adapter); -+ e1000_clean_rx_ring(adapter); ++ cleaned_count = e1000_desc_unused(rx_ring); ++ if (cleaned_count) ++ adapter->alloc_rx_buf(adapter, cleaned_count); + -+ /* -+ * TODO: for power management, we could drop the link and -+ * pci_disable_device here. -+ */ ++ adapter->total_rx_packets += total_rx_packets; ++ adapter->total_rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_packets += total_rx_packets; ++ return cleaned; +} + -+void e1000e_reinit_locked(struct e1000_adapter *adapter) ++#ifdef CONFIG_E1000E_NAPI ++/* NOTE: these new jumbo frame routines rely on NAPI because of the ++ * pskb_may_pull call, which eventually must call kmap_atomic which you cannot ++ * call from hard irq context */ ++ ++/** ++ * e1000_consume_page - helper function ++ **/ ++static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, ++ u16 length) +{ -+ might_sleep(); -+ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) -+ msleep(1); -+ e1000e_down(adapter); -+ e1000e_up(adapter); -+ clear_bit(__E1000_RESETTING, &adapter->state); ++ bi->page = NULL; ++ skb->len += length; ++ skb->data_len += length; ++ skb->truesize += length; +} + +/** -+ * e1000_sw_init - Initialize general software structures (struct e1000_adapter) -+ * @adapter: board private structure to initialize ++ * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy ++ * @adapter: board private structure + * -+ * e1000_sw_init initializes the Adapter private data structure. -+ * Fields are initialized based on PCI device information and -+ * OS network device settings (MTU size). ++ * the return value indicates whether actual cleaning was done, there ++ * is no guarantee that everything was cleaned + **/ -+static int __devinit e1000_sw_init(struct e1000_adapter *adapter) ++ ++static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, ++ int *work_done, int work_to_do) +{ -+ struct e1000_hw *hw = &adapter->hw; + struct net_device *netdev = adapter->netdev; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_rx_desc *rx_desc, *next_rxd; ++ struct e1000_buffer *buffer_info, *next_buffer; ++ u32 length; ++ unsigned int i; ++ int cleaned_count = 0; ++ bool cleaned = FALSE; ++ unsigned int total_rx_bytes=0, total_rx_packets=0; + -+ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN; -+ adapter->rx_ps_bsize0 = 128; -+ hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; -+ hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN; ++ i = rx_ring->next_to_clean; ++ rx_desc = E1000_RX_DESC(*rx_ring, i); ++ buffer_info = &rx_ring->buffer_info[i]; + -+ adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); -+ if (!adapter->tx_ring) -+ goto err; ++ while (rx_desc->status & E1000_RXD_STAT_DD) { ++ struct sk_buff *skb; ++ u8 status; + -+ adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); -+ if (!adapter->rx_ring) -+ goto err; ++ if (*work_done >= work_to_do) ++ break; ++ (*work_done)++; + -+ spin_lock_init(&adapter->tx_queue_lock); ++ status = rx_desc->status; ++ skb = buffer_info->skb; ++ buffer_info->skb = NULL; + -+ /* Explicitly disable IRQ since the NIC can be in any state. */ -+ atomic_set(&adapter->irq_sem, 0); -+ e1000_irq_disable(adapter); ++ ++i; ++ if (i == rx_ring->count) ++ i = 0; ++ next_rxd = E1000_RX_DESC(*rx_ring, i); ++ prefetch(next_rxd); + -+ spin_lock_init(&adapter->stats_lock); ++ next_buffer = &rx_ring->buffer_info[i]; + -+ set_bit(__E1000_DOWN, &adapter->state); -+ return 0; ++ cleaned = TRUE; ++ cleaned_count++; ++ pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ buffer_info->dma = 0; + -+err: -+ ndev_err(netdev, "Unable to allocate memory for queues\n"); -+ kfree(adapter->rx_ring); -+ kfree(adapter->tx_ring); -+ return -ENOMEM; -+} ++ length = le16_to_cpu(rx_desc->length); + -+/** -+ * 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); -+ struct e1000_hw *hw = &adapter->hw; -+ int err; ++ /* errors is only valid for DD + EOP descriptors */ ++ if (unlikely((status & E1000_RXD_STAT_EOP) && ++ (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) { ++ /* recycle both page and skb */ ++ buffer_info->skb = skb; ++ /* an error means any chain goes out the window ++ * too */ ++ if (rx_ring->rx_skb_top) ++ dev_kfree_skb(rx_ring->rx_skb_top); ++ rx_ring->rx_skb_top = NULL; ++ goto next_desc; ++ } + -+ /* disallow open during test */ -+ if (test_bit(__E1000_TESTING, &adapter->state)) -+ return -EBUSY; ++#define rxtop rx_ring->rx_skb_top ++ if (!(status & E1000_RXD_STAT_EOP)) { ++ /* this descriptor is only the beginning (or middle) */ ++ if (!rxtop) { ++ /* this is the beginning of a chain */ ++ rxtop = skb; ++ skb_fill_page_desc(rxtop, 0, buffer_info->page, ++ 0, length); ++ } else { ++ /* this is the middle of a chain */ ++ skb_fill_page_desc(rxtop, ++ skb_shinfo(rxtop)->nr_frags, ++ buffer_info->page, 0, length); ++ /* re-use the skb, only consumed the page */ ++ buffer_info->skb = skb; ++ } ++ e1000_consume_page(buffer_info, rxtop, length); ++ goto next_desc; ++ } else { ++ if (rxtop) { ++ /* end of the chain */ ++ skb_fill_page_desc(rxtop, ++ skb_shinfo(rxtop)->nr_frags, ++ buffer_info->page, 0, length); ++ /* re-use the current skb, we only consumed the ++ * page */ ++ buffer_info->skb = skb; ++ skb = rxtop; ++ rxtop = NULL; ++ e1000_consume_page(buffer_info, skb, length); ++ } else { ++ /* no chain, got EOP, this buf is the packet ++ * copybreak to save the put_page/alloc_page */ ++ if (length <= copybreak && ++ skb_tailroom(skb) >= length) { ++ u8 *vaddr; ++ vaddr = kmap_atomic(buffer_info->page, ++ KM_SKB_DATA_SOFTIRQ); ++ memcpy(skb_tail_pointer(skb), vaddr, ++ length); ++ kunmap_atomic(vaddr, ++ KM_SKB_DATA_SOFTIRQ); ++ /* re-use the page, so don't erase ++ * buffer_info->page */ ++ skb_put(skb, length); ++ } else { ++ skb_fill_page_desc(skb, 0, ++ buffer_info->page, 0, ++ length); ++ e1000_consume_page(buffer_info, skb, ++ length); ++ } ++ } ++ } + -+ /* allocate transmit descriptors */ -+ err = e1000e_setup_tx_resources(adapter); -+ if (err) -+ goto err_setup_tx; ++ /* Receive Checksum Offload XXX recompute due to CRC strip? */ ++ e1000_rx_checksum(adapter, ++ (u32)(status) | ++ ((u32)(rx_desc->errors) << 24), ++ le16_to_cpu(rx_desc->csum), skb); + -+ /* allocate receive descriptors */ -+ err = e1000e_setup_rx_resources(adapter); -+ if (err) -+ goto err_setup_rx; ++ /* probably a little skewed due to removing CRC */ ++ total_rx_bytes += skb->len; ++ total_rx_packets++; ++ ++ /* eth type trans needs skb->data to point to something */ ++ if (!pskb_may_pull(skb, ETH_HLEN)) { ++ e_err("pskb_may_pull failed.\n"); ++ dev_kfree_skb(skb); ++ goto next_desc; ++ } ++ ++ e1000_receive_skb(adapter, netdev, skb, status, ++ rx_desc->special); ++ ++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, cleaned_count); ++ cleaned_count = 0; ++ } + -+ e1000e_power_up_phy(adapter); ++ /* use prefetched values */ ++ rx_desc = next_rxd; ++ buffer_info = next_buffer; ++ } ++ rx_ring->next_to_clean = i; + -+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; -+ if ((adapter->hw.mng_cookie.status & -+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) -+ e1000_update_mng_vlan(adapter); ++ cleaned_count = e1000_desc_unused(rx_ring); ++ if (cleaned_count) ++ adapter->alloc_rx_buf(adapter, cleaned_count); + -+ /* If AMT is enabled, let the firmware know that the network -+ * interface is now open */ -+ if ((adapter->flags & FLAG_HAS_AMT) && -+ e1000e_check_mng_mode(&adapter->hw)) -+ e1000_get_hw_control(adapter); ++ adapter->total_rx_packets += total_rx_packets; ++ adapter->total_rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_bytes += total_rx_bytes; ++ adapter->net_stats.rx_packets += total_rx_packets; ++ return cleaned; ++} ++#endif /* CONFIG_E1000E_NAPI */ + -+ /* before we allocate an interrupt, we must be ready to handle it. -+ * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt -+ * as soon as we call pci_request_irq, so we have to setup our -+ * clean_rx handler before we do so. */ -+ e1000_configure(adapter); ++/** ++ * e1000_clean_rx_ring - Free Rx Buffers per Queue ++ * @adapter: board private structure ++ **/ ++static void e1000_clean_rx_ring(struct e1000_adapter *adapter) ++{ ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_buffer *buffer_info; ++ struct e1000_ps_page *ps_page; ++ struct pci_dev *pdev = adapter->pdev; ++ unsigned int i, j; + -+ err = e1000_request_irq(adapter); -+ if (err) -+ goto err_req_irq; ++ /* Free all the Rx ring sk_buffs */ ++ for (i = 0; i < rx_ring->count; i++) { ++ buffer_info = &rx_ring->buffer_info[i]; ++ if (buffer_info->dma) { ++ if (adapter->clean_rx == e1000_clean_rx_irq) ++ pci_unmap_single(pdev, buffer_info->dma, ++ adapter->rx_buffer_len, ++ PCI_DMA_FROMDEVICE); ++#ifdef CONFIG_E1000E_NAPI ++ else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq) ++ pci_unmap_page(pdev, buffer_info->dma, ++ PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++#endif ++ else if (adapter->clean_rx == e1000_clean_rx_irq_ps) ++ pci_unmap_single(pdev, buffer_info->dma, ++ adapter->rx_ps_bsize0, ++ PCI_DMA_FROMDEVICE); ++ buffer_info->dma = 0; ++ } + -+ /* From here on the code is the same as e1000e_up() */ -+ clear_bit(__E1000_DOWN, &adapter->state); ++ if (buffer_info->page) { ++ put_page(buffer_info->page); ++ buffer_info->page = NULL; ++ } + -+ netif_poll_enable(netdev); ++ if (buffer_info->skb) { ++ dev_kfree_skb(buffer_info->skb); ++ buffer_info->skb = NULL; ++ } + -+ e1000_irq_enable(adapter); ++ for (j = 0; j < PS_PAGE_BUFFERS; j++) { ++ ps_page = &buffer_info->ps_pages[j]; ++ if (!ps_page->page) ++ break; ++ pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE, ++ PCI_DMA_FROMDEVICE); ++ ps_page->dma = 0; ++ put_page(ps_page->page); ++ ps_page->page = NULL; ++ } ++ } + -+ /* fire a link status change interrupt to start the watchdog */ -+ ew32(ICS, E1000_ICS_LSC); ++#ifdef CONFIG_E1000E_NAPI ++ /* there also may be some cached data from a chained receive */ ++ if (rx_ring->rx_skb_top) { ++ dev_kfree_skb(rx_ring->rx_skb_top); ++ rx_ring->rx_skb_top = NULL; ++ } ++#endif + -+ return 0; ++ /* Zero out the descriptor ring */ ++ memset(rx_ring->desc, 0, rx_ring->size); + -+err_req_irq: -+ e1000_release_hw_control(adapter); -+ e1000_power_down_phy(adapter); -+ e1000e_free_rx_resources(adapter); -+err_setup_rx: -+ e1000e_free_tx_resources(adapter); -+err_setup_tx: -+ e1000e_reset(adapter); ++ rx_ring->next_to_clean = 0; ++ rx_ring->next_to_use = 0; + -+ return err; ++ writel(0, adapter->hw.hw_addr + rx_ring->head); ++ writel(0, adapter->hw.hw_addr + rx_ring->tail); +} + +/** -+ * e1000_close - Disables a network interface -+ * @netdev: network interface device structure -+ * -+ * Returns 0, this is not allowed to fail ++ * e1000_free_rx_resources - Free Rx Resources ++ * @adapter: board private structure + * -+ * The close entry point is called when an interface is de-activated -+ * by the OS. The hardware is still under the drivers control, but -+ * needs to be disabled. A global MAC reset is issued to stop the -+ * hardware, and all transmit and receive resources are freed. ++ * Free all receive software resources + **/ -+static int e1000_close(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); -+ e1000e_down(adapter); -+ e1000_power_down_phy(adapter); -+ e1000_free_irq(adapter); ++void e1000_free_rx_resources(struct e1000_adapter *adapter) ++{ ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ int i; + -+ e1000e_free_tx_resources(adapter); -+ e1000e_free_rx_resources(adapter); ++ e1000_clean_rx_ring(adapter); + -+ /* kill manageability vlan ID if supported, but not if a vlan with -+ * the same ID is registered on the host OS (let 8021q kill it) */ -+ if ((adapter->hw.mng_cookie.status & -+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && -+ !(adapter->vlgrp && -+ vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) -+ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); ++ for (i = 0; i < rx_ring->count; i++) { ++ kfree(rx_ring->buffer_info[i].ps_pages); ++ } + -+ /* If AMT is enabled, let the firmware know that the network -+ * interface is now closed */ -+ if ((adapter->flags & FLAG_HAS_AMT) && -+ e1000e_check_mng_mode(&adapter->hw)) -+ e1000_release_hw_control(adapter); ++ vfree(rx_ring->buffer_info); ++ rx_ring->buffer_info = NULL; + -+ return 0; ++ dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc, ++ rx_ring->dma); ++ rx_ring->desc = NULL; +} ++ +/** -+ * e1000_set_mac - Change the Ethernet Address of the NIC -+ * @netdev: network interface device structure -+ * @p: pointer to an address structure ++ * e1000_update_itr - update the dynamic ITR value based on statistics ++ * @adapter: pointer to adapter ++ * @itr_setting: current adapter->itr ++ * @packets: the number of packets during this measurement interval ++ * @bytes: the number of bytes during this measurement interval + * -+ * Returns 0 on success, negative on failure ++ * Stores a new ITR value based on packets and byte ++ * counts during the last interrupt. The advantage of per interrupt ++ * computation is faster updates and more accurate ITR for the current ++ * traffic pattern. Constants in this function were computed ++ * based on theoretical maximum wire speed and thresholds were set based ++ * on testing data as well as attempting to minimize response time ++ * while increasing bulk throughput. This functionality is controlled ++ * by the InterruptThrottleRate module parameter. + **/ -+static int e1000_set_mac(struct net_device *netdev, void *p) ++static unsigned int e1000_update_itr(struct e1000_adapter *adapter, ++ u16 itr_setting, int packets, ++ int bytes) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct sockaddr *addr = p; ++ unsigned int retval = itr_setting; + -+ if (!is_valid_ether_addr(addr->sa_data)) -+ return -EADDRNOTAVAIL; ++ if (packets == 0) ++ goto update_itr_done; + -+ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); -+ memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len); ++ switch (itr_setting) { ++ case lowest_latency: ++ /* handle TSO and jumbo frames */ ++ if (bytes/packets > 8000) ++ retval = bulk_latency; ++ else if ((packets < 5) && (bytes > 512)) { ++ retval = low_latency; ++ } ++ break; ++ case low_latency: /* 50 usec aka 20000 ints/s */ ++ if (bytes > 10000) { ++ /* this if handles the TSO accounting */ ++ if (bytes/packets > 8000) { ++ retval = bulk_latency; ++ } else if ((packets < 10) || ((bytes/packets) > 1200)) { ++ retval = bulk_latency; ++ } else if ((packets > 35)) { ++ retval = lowest_latency; ++ } ++ } else if (bytes/packets > 2000) { ++ retval = bulk_latency; ++ } else if (packets <= 2 && bytes < 512) { ++ retval = lowest_latency; ++ } ++ break; ++ case bulk_latency: /* 250 usec aka 4000 ints/s */ ++ if (bytes > 25000) { ++ if (packets > 35) { ++ retval = low_latency; ++ } ++ } else if (bytes < 6000) { ++ retval = low_latency; ++ } ++ break; ++ } + -+ e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); ++update_itr_done: ++ return retval; ++} + -+ if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) { -+ /* activate the work around */ -+ e1000e_set_laa_state_82571(&adapter->hw, 1); ++static void e1000_set_itr(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u16 current_itr; ++ u32 new_itr = adapter->itr; + -+ /* 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. Eventually the LAA will be in RAR[0] and -+ * RAR[14] */ -+ e1000e_rar_set(&adapter->hw, -+ adapter->hw.mac.addr, -+ adapter->hw.mac.rar_entry_count - 1); ++ /* for non-gigabit speeds, just fix the interrupt rate at 4000 */ ++ if (adapter->link_speed != SPEED_1000) { ++ current_itr = 0; ++ new_itr = 4000; ++ goto set_itr_now; + } + -+ return 0; -+} ++ adapter->tx_itr = e1000_update_itr(adapter, ++ adapter->tx_itr, ++ adapter->total_tx_packets, ++ adapter->total_tx_bytes); ++ /* conservative mode (itr 3) eliminates the lowest_latency setting */ ++ if (adapter->itr_setting == 3 && adapter->tx_itr == lowest_latency) ++ adapter->tx_itr = low_latency; + -+/* 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) -+{ -+ struct e1000_adapter *adapter = (struct e1000_adapter *) data; -+ e1000_get_phy_info(&adapter->hw); ++ adapter->rx_itr = e1000_update_itr(adapter, ++ adapter->rx_itr, ++ adapter->total_rx_packets, ++ adapter->total_rx_bytes); ++ /* conservative mode (itr 3) eliminates the lowest_latency setting */ ++ if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency) ++ adapter->rx_itr = low_latency; ++ ++ current_itr = max(adapter->rx_itr, adapter->tx_itr); ++ ++ switch (current_itr) { ++ /* counts and packets in update_itr are dependent on these numbers */ ++ case lowest_latency: ++ new_itr = 70000; ++ break; ++ case low_latency: ++ new_itr = 20000; /* aka hwitr = ~200 */ ++ break; ++ case bulk_latency: ++ new_itr = 4000; ++ break; ++ default: ++ break; ++ } ++ ++set_itr_now: ++ if (new_itr != adapter->itr) { ++ /* ++ * this attempts to bias the interrupt rate towards Bulk ++ * by adding intermediate steps when interrupt rate is ++ * increasing ++ */ ++ new_itr = new_itr > adapter->itr ? ++ min(adapter->itr + (new_itr >> 2), new_itr) : ++ new_itr; ++ adapter->itr = new_itr; ++#ifdef CONFIG_E1000E_MSIX ++ adapter->rx_ring->itr_val = new_itr; ++ if (adapter->msix_entries) ++ adapter->rx_ring->set_itr = 1; ++ else ++#endif ++ ew32(ITR, 1000000000 / (new_itr * 256)); ++ } +} + +/** -+ * e1000e_update_stats - Update the board statistics counters ++ * e1000_clean_tx_irq - Reclaim resources after transmit completes + * @adapter: board private structure ++ * ++ * the return value indicates if there is more work to do (later) + **/ -+void e1000e_update_stats(struct e1000_adapter *adapter) ++static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) +{ ++ struct net_device *netdev = adapter->netdev; + struct e1000_hw *hw = &adapter->hw; -+ struct pci_dev *pdev = adapter->pdev; -+ unsigned long irq_flags; -+ u16 phy_tmp; -+ -+#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_tx_desc *tx_desc, *eop_desc; ++ struct e1000_buffer *buffer_info; ++ unsigned int i, eop; ++ bool cleaned = 0, retval = 1; ++ unsigned int total_tx_bytes = 0, total_tx_packets = 0; + -+ /* -+ * Prevent stats update while adapter is being reset, or if the pci -+ * connection is down. -+ */ -+ if (adapter->link_speed == 0) -+ return; -+ if (pci_channel_offline(pdev)) -+ return; ++ i = tx_ring->next_to_clean; ++ eop = tx_ring->buffer_info[i].next_to_watch; ++ eop_desc = E1000_TX_DESC(*tx_ring, eop); + -+ spin_lock_irqsave(&adapter->stats_lock, irq_flags); ++ while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { ++ for (cleaned = 0; !cleaned; ) { ++ tx_desc = E1000_TX_DESC(*tx_ring, i); ++ buffer_info = &tx_ring->buffer_info[i]; ++ cleaned = (i == eop); + -+ /* these counters are modified from e1000_adjust_tbi_stats, -+ * called from the interrupt context, so they must only -+ * be written while holding adapter->stats_lock -+ */ ++ if (cleaned) { ++ struct sk_buff *skb = buffer_info->skb; ++#ifdef NETIF_F_TSO ++ unsigned int segs, bytecount; ++ segs = skb_shinfo(skb)->gso_segs ?: 1; ++ /* multiply data chunks by size of headers */ ++ bytecount = ((segs - 1) * skb_headlen(skb)) + ++ skb->len; ++ total_tx_packets += segs; ++ total_tx_bytes += bytecount; ++#else ++ total_tx_packets++; ++ total_tx_bytes += skb->len; ++#endif ++ } + -+ adapter->stats.crcerrs += er32(CRCERRS); -+ adapter->stats.gprc += er32(GPRC); -+ adapter->stats.gorcl += er32(GORCL); -+ adapter->stats.gorch += er32(GORCH); -+ adapter->stats.bprc += er32(BPRC); -+ adapter->stats.mprc += er32(MPRC); -+ adapter->stats.roc += er32(ROC); ++ e1000_put_txbuf(adapter, buffer_info); ++ tx_desc->upper.data = 0; + -+ if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) { -+ adapter->stats.prc64 += er32(PRC64); -+ adapter->stats.prc127 += er32(PRC127); -+ adapter->stats.prc255 += er32(PRC255); -+ adapter->stats.prc511 += er32(PRC511); -+ adapter->stats.prc1023 += er32(PRC1023); -+ adapter->stats.prc1522 += er32(PRC1522); -+ adapter->stats.symerrs += er32(SYMERRS); -+ adapter->stats.sec += er32(SEC); -+ } ++ i++; ++ if (i == tx_ring->count) ++ i = 0; ++#ifdef CONFIG_E1000E_NAPI ++ if (total_tx_packets >= tx_ring->count) { ++ retval = 0; ++ goto done_cleaning; ++ } ++#endif ++ } + -+ adapter->stats.mpc += er32(MPC); -+ adapter->stats.scc += er32(SCC); -+ adapter->stats.ecol += er32(ECOL); -+ adapter->stats.mcc += er32(MCC); -+ adapter->stats.latecol += er32(LATECOL); -+ adapter->stats.dc += er32(DC); -+ adapter->stats.rlec += er32(RLEC); -+ adapter->stats.xonrxc += er32(XONRXC); -+ adapter->stats.xontxc += er32(XONTXC); -+ adapter->stats.xoffrxc += er32(XOFFRXC); -+ adapter->stats.xofftxc += er32(XOFFTXC); -+ adapter->stats.fcruc += er32(FCRUC); -+ adapter->stats.gptc += er32(GPTC); -+ adapter->stats.gotcl += er32(GOTCL); -+ adapter->stats.gotch += er32(GOTCH); -+ adapter->stats.rnbc += er32(RNBC); -+ adapter->stats.ruc += er32(RUC); -+ adapter->stats.rfc += er32(RFC); -+ adapter->stats.rjc += er32(RJC); -+ adapter->stats.torl += er32(TORL); -+ adapter->stats.torh += er32(TORH); -+ adapter->stats.totl += er32(TOTL); -+ adapter->stats.toth += er32(TOTH); -+ adapter->stats.tpr += er32(TPR); -+ -+ if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) { -+ adapter->stats.ptc64 += er32(PTC64); -+ adapter->stats.ptc127 += er32(PTC127); -+ adapter->stats.ptc255 += er32(PTC255); -+ adapter->stats.ptc511 += er32(PTC511); -+ adapter->stats.ptc1023 += er32(PTC1023); -+ adapter->stats.ptc1522 += er32(PTC1522); ++ eop = tx_ring->buffer_info[i].next_to_watch; ++ eop_desc = E1000_TX_DESC(*tx_ring, eop); + } + -+ adapter->stats.mptc += er32(MPTC); -+ adapter->stats.bptc += er32(BPTC); -+ -+ /* used for adaptive IFS */ -+ -+ hw->mac.tx_packet_delta = er32(TPT); -+ adapter->stats.tpt += hw->mac.tx_packet_delta; -+ hw->mac.collision_delta = er32(COLC); -+ adapter->stats.colc += hw->mac.collision_delta; -+ -+ adapter->stats.algnerrc += er32(ALGNERRC); -+ adapter->stats.rxerrc += er32(RXERRC); -+ adapter->stats.tncrs += er32(TNCRS); -+ adapter->stats.cexterr += er32(CEXTERR); -+ adapter->stats.tsctc += er32(TSCTC); -+ adapter->stats.tsctfc += er32(TSCTFC); ++#ifdef CONFIG_E1000E_NAPI ++done_cleaning: ++#endif ++ tx_ring->next_to_clean = i; + -+ adapter->stats.iac += er32(IAC); ++#define TX_WAKE_THRESHOLD 32 ++ if (cleaned && netif_carrier_ok(netdev) && ++ e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) { ++ /* ++ * Make sure that anybody stopping the queue after this ++ * sees the new next_to_clean. ++ */ ++ smp_mb(); + -+ if (adapter->flags & FLAG_HAS_STATS_ICR_ICT) { -+ adapter->stats.icrxoc += er32(ICRXOC); -+ adapter->stats.icrxptc += er32(ICRXPTC); -+ adapter->stats.icrxatc += er32(ICRXATC); -+ adapter->stats.ictxptc += er32(ICTXPTC); -+ adapter->stats.ictxatc += er32(ICTXATC); -+ adapter->stats.ictxqec += er32(ICTXQEC); -+ adapter->stats.ictxqmtc += er32(ICTXQMTC); -+ adapter->stats.icrxdmtc += er32(ICRXDMTC); ++ if (netif_queue_stopped(netdev) && ++ !(test_bit(__E1000_DOWN, &adapter->state))) { ++ netif_wake_queue(netdev); ++ ++adapter->restart_queue; ++ } + } + -+ /* Fill out the OS statistics structure */ -+ adapter->net_stats.rx_packets = adapter->stats.gprc; -+ adapter->net_stats.tx_packets = adapter->stats.gptc; -+ adapter->net_stats.rx_bytes = adapter->stats.gorcl; -+ adapter->net_stats.tx_bytes = adapter->stats.gotcl; -+ adapter->net_stats.multicast = adapter->stats.mprc; -+ adapter->net_stats.collisions = adapter->stats.colc; -+ -+ /* 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.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_missed_errors = adapter->stats.mpc; ++ 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 = 0; ++ if (tx_ring->buffer_info[eop].dma && ++ time_after(jiffies, tx_ring->buffer_info[eop].time_stamp ++ + (adapter->tx_timeout_factor * HZ)) ++ && !(er32(STATUS) & E1000_STATUS_TXOFF)) { ++ e1000_print_tx_hang(adapter); ++ netif_stop_queue(netdev); ++ } ++ } ++ adapter->total_tx_bytes += total_tx_bytes; ++ adapter->total_tx_packets += total_tx_packets; ++ adapter->net_stats.tx_bytes += total_tx_bytes; ++ adapter->net_stats.tx_packets += total_tx_packets; ++ return retval; ++} + -+ /* Tx Errors */ -+ adapter->net_stats.tx_errors = adapter->stats.ecol + -+ adapter->stats.latecol; -+ adapter->net_stats.tx_aborted_errors = adapter->stats.ecol; -+ adapter->net_stats.tx_window_errors = adapter->stats.latecol; -+ adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs; ++/** ++ * e1000_intr_msi - Interrupt Handler ++ * @irq: interrupt number ++ * @data: pointer to a network interface device structure ++ **/ ++static irqreturn_t e1000_intr_msi(int irq, void *data) ++{ ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++#ifndef CONFIG_E1000E_NAPI ++ int i; ++#endif ++ /* read ICR disables interrupts using IAM */ ++ u32 icr = er32(ICR); + -+ /* Tx Dropped needs to be maintained elsewhere */ ++ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { ++ hw->mac.get_link_status = 1; ++ /* ++ * ICH8 workaround-- Call gig speed drop workaround on cable ++ * disconnect (LSC) before accessing any PHY registers ++ */ ++ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && ++ (!(er32(STATUS) & E1000_STATUS_LU))) ++ e1000_gig_downshift_workaround_ich8lan(hw); + -+ /* Phy Stats */ -+ if (hw->media_type == e1000_media_type_copper) { -+ if ((adapter->link_speed == SPEED_1000) && -+ (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) { -+ phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; -+ adapter->phy_stats.idle_errors += phy_tmp; ++ /* ++ * 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->flags & FLAG_RX_NEEDS_RESTART) { ++ /* disable receives */ ++ u32 rctl = er32(RCTL); ++ ew32(RCTL, rctl & ~E1000_RCTL_EN); ++ adapter->flags |= FLAG_RX_RESTART_NOW; + } ++ /* guard against interrupt when we're going down */ ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ mod_timer(&adapter->watchdog_timer, jiffies + 1); + } + -+ /* Management Stats */ -+ adapter->stats.mgptc += er32(MGTPTC); -+ adapter->stats.mgprc += er32(MGTPRC); -+ adapter->stats.mgpdc += er32(MGTPDC); -+ -+ spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); -+} ++#ifdef CONFIG_E1000E_NAPI ++ if (netif_rx_schedule_prep(netdev, &adapter->napi)) { ++ adapter->total_tx_bytes = 0; ++ adapter->total_tx_packets = 0; ++ adapter->total_rx_bytes = 0; ++ adapter->total_rx_packets = 0; ++ __netif_rx_schedule(netdev, &adapter->napi); ++ } ++#else ++ adapter->total_tx_bytes = 0; ++ adapter->total_rx_bytes = 0; ++ adapter->total_tx_packets = 0; ++ adapter->total_rx_packets = 0; ++ ++ for (i = 0; i < E1000_MAX_INTR; i++) { ++ int rx_cleaned = adapter->clean_rx(adapter); ++ int tx_cleaned_complete = e1000_clean_tx_irq(adapter); ++ if (!rx_cleaned && tx_cleaned_complete) ++ break; ++ } + -+static void e1000_print_link_info(struct e1000_adapter *adapter) -+{ -+ struct net_device *netdev = adapter->netdev; -+ struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl = er32(CTRL); ++ if (likely(adapter->itr_setting & 3)) ++ e1000_set_itr(adapter); ++#endif /* CONFIG_E1000E_NAPI */ + -+ ndev_info(netdev, -+ "Link is Up %d Mbps %s, Flow Control: %s\n", -+ adapter->link_speed, -+ (adapter->link_duplex == FULL_DUPLEX) ? -+ "Full Duplex" : "Half Duplex", -+ ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? -+ "RX/TX" : -+ ((ctrl & E1000_CTRL_RFCE) ? "RX" : -+ ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); ++ return IRQ_HANDLED; +} + +/** -+ * e1000_watchdog - Timer Call-back -+ * @data: pointer to adapter cast into an unsigned long ++ * e1000_intr - Interrupt Handler ++ * @irq: interrupt number ++ * @data: pointer to a network interface device structure + **/ -+static void e1000_watchdog(unsigned long data) ++static irqreturn_t e1000_intr(int irq, void *data) +{ -+ struct e1000_adapter *adapter = (struct e1000_adapter *) data; ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++#ifndef CONFIG_E1000E_NAPI ++ int i; ++ int rx_cleaned, tx_cleaned_complete; ++#endif ++ u32 rctl, icr = er32(ICR); + -+ /* Do the rest outside of interrupt context */ -+ schedule_work(&adapter->watchdog_task); ++ if (!icr) ++ return IRQ_NONE; /* Not our interrupt */ + -+ /* TODO: make this use queue_delayed_work() */ ++#ifdef CONFIG_E1000E_NAPI ++ /* ++ * IMS will not auto-mask if INT_ASSERTED is not set, and if it is ++ * not set, then the adapter didn't send an interrupt ++ */ ++ if (!(icr & E1000_ICR_INT_ASSERTED)) ++ return IRQ_NONE; ++ ++#endif /* CONFIG_E1000E_NAPI */ ++ if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { ++ hw->mac.get_link_status = 1; ++ /* ++ * ICH8 workaround-- Call gig speed drop workaround on cable ++ * disconnect (LSC) before accessing any PHY registers ++ */ ++ if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) && ++ (!(er32(STATUS) & E1000_STATUS_LU))) ++ e1000_gig_downshift_workaround_ich8lan(hw); ++ ++ /* ++ * 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->flags & FLAG_RX_NEEDS_RESTART)) { ++ /* disable receives */ ++ rctl = er32(RCTL); ++ ew32(RCTL, rctl & ~E1000_RCTL_EN); ++ adapter->flags |= FLAG_RX_RESTART_NOW; ++ } ++ /* guard against interrupt when we're going down */ ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ mod_timer(&adapter->watchdog_timer, jiffies + 1); ++ } ++ ++#ifdef CONFIG_E1000E_NAPI ++ if (netif_rx_schedule_prep(netdev, &adapter->napi)) { ++ adapter->total_tx_bytes = 0; ++ adapter->total_tx_packets = 0; ++ adapter->total_rx_bytes = 0; ++ adapter->total_rx_packets = 0; ++ __netif_rx_schedule(netdev, &adapter->napi); ++ } ++#else ++ adapter->total_tx_bytes = 0; ++ adapter->total_rx_bytes = 0; ++ adapter->total_tx_packets = 0; ++ adapter->total_rx_packets = 0; ++ ++ for (i = 0; i < E1000_MAX_INTR; i++) { ++ rx_cleaned = adapter->clean_rx(adapter); ++ tx_cleaned_complete = e1000_clean_tx_irq(adapter); ++ if (!rx_cleaned && tx_cleaned_complete) ++ break; ++ } ++ ++ if (likely(adapter->itr_setting & 3)) ++ e1000_set_itr(adapter); ++#endif /* CONFIG_E1000E_NAPI */ ++ ++ return IRQ_HANDLED; +} + -+static void e1000_watchdog_task(struct work_struct *work) ++#ifdef CONFIG_E1000E_MSIX ++static irqreturn_t e1000_msix_other(int irq, void *data) +{ -+ struct e1000_adapter *adapter = container_of(work, -+ struct e1000_adapter, watchdog_task); -+ -+ struct net_device *netdev = adapter->netdev; -+ struct e1000_mac_info *mac = &adapter->hw.mac; -+ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; -+ u32 link, tctl; -+ s32 ret_val; -+ int tx_pending = 0; ++ u32 icr = er32(ICR); + -+ if ((netif_carrier_ok(netdev)) && -+ (er32(STATUS) & E1000_STATUS_LU)) -+ goto link_up; ++ if (!(icr & E1000_ICR_INT_ASSERTED)) ++ { ++ ew32(IMS, E1000_IMS_OTHER); ++ return IRQ_NONE; ++ } + -+ ret_val = mac->ops.check_for_link(hw); -+ if ((ret_val == E1000_ERR_PHY) && -+ (adapter->hw.phy.type == e1000_phy_igp_3) && -+ (er32(CTRL) & -+ E1000_PHY_CTRL_GBE_DISABLE)) { -+ /* See e1000_kmrn_lock_loss_workaround_ich8lan() */ -+ ndev_info(netdev, -+ "Gigabit has been disabled, downgrading speed\n"); ++ if (icr & adapter->eiac_mask) ++ ew32(ICS, (icr & adapter->eiac_mask)); ++ ++ if (icr & E1000_ICR_OTHER) { ++ if (!(icr & E1000_ICR_LSC)) ++ goto no_link_interrupt; ++ hw->mac.get_link_status = 1; ++ /* guard against interrupt when we're going down */ ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ mod_timer(&adapter->watchdog_timer, jiffies + 1); + } + -+ if ((e1000e_enable_tx_pkt_filtering(hw)) && -+ (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)) -+ e1000_update_mng_vlan(adapter); ++no_link_interrupt: ++ ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER); + -+ if ((adapter->hw.media_type == e1000_media_type_internal_serdes) && -+ !(er32(TXCW) & E1000_TXCW_ANE)) -+ link = adapter->hw.mac.serdes_has_link; -+ else -+ link = er32(STATUS) & E1000_STATUS_LU; ++ return IRQ_HANDLED; ++} + -+ if (link) { -+ if (!netif_carrier_ok(netdev)) { -+ bool txb2b = 1; -+ mac->ops.get_link_up_info(&adapter->hw, -+ &adapter->link_speed, -+ &adapter->link_duplex); -+ e1000_print_link_info(adapter); -+ /* 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 = 14; -+ break; -+ case SPEED_100: -+ txb2b = 0; -+ netdev->tx_queue_len = 100; -+ /* maybe add some timeout factor ? */ -+ break; -+ } + -+ /* workaround: re-program speed mode bit after -+ * link-up event */ -+ if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) && -+ !txb2b) { -+ u32 tarc0; -+ tarc0 = er32(TARC0); -+ tarc0 &= ~SPEED_MODE_BIT; -+ ew32(TARC0, tarc0); -+ } ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++static irqreturn_t e1000_intr_msix_tx(int irq, void *data) ++{ ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_ring *tx_ring = adapter->tx_ring; + -+ /* disable TSO for pcie and 10/100 speeds, to avoid -+ * some hardware issues */ -+ if (!(adapter->flags & FLAG_TSO_FORCE)) { -+ switch (adapter->link_speed) { -+ case SPEED_10: -+ case SPEED_100: -+ ndev_info(netdev, -+ "10/100 speed: disabling TSO\n"); -+ netdev->features &= ~NETIF_F_TSO; -+ netdev->features &= ~NETIF_F_TSO6; -+ break; -+ case SPEED_1000: -+ netdev->features |= NETIF_F_TSO; -+ netdev->features |= NETIF_F_TSO6; -+ break; -+ default: -+ /* oops */ -+ break; -+ } -+ } + -+ /* enable transmits in the hardware, need to do this -+ * after setting TARC0 */ -+ tctl = er32(TCTL); -+ tctl |= E1000_TCTL_EN; -+ ew32(TCTL, tctl); ++ adapter->total_tx_bytes = 0; ++ adapter->total_tx_packets = 0; + -+ netif_carrier_on(netdev); -+ netif_wake_queue(netdev); ++ if (!e1000_clean_tx_irq(adapter)) ++ /* Ring was not completely cleaned, so fire another interrupt */ ++ ew32(ICS, tx_ring->ims_val); + -+ if (!test_bit(__E1000_DOWN, &adapter->state)) -+ mod_timer(&adapter->phy_info_timer, -+ round_jiffies(jiffies + 2 * HZ)); -+ } else { -+ /* make sure the receive unit is started */ -+ if (adapter->flags & FLAG_RX_NEEDS_RESTART) { -+ u32 rctl = er32(RCTL); -+ ew32(RCTL, rctl | -+ E1000_RCTL_EN); -+ } -+ } -+ } else { -+ if (netif_carrier_ok(netdev)) { -+ adapter->link_speed = 0; -+ adapter->link_duplex = 0; -+ ndev_info(netdev, "Link is Down\n"); -+ netif_carrier_off(netdev); -+ netif_stop_queue(netdev); -+ if (!test_bit(__E1000_DOWN, &adapter->state)) -+ mod_timer(&adapter->phy_info_timer, -+ round_jiffies(jiffies + 2 * HZ)); ++ return IRQ_HANDLED; ++} + -+ if (adapter->flags & FLAG_RX_NEEDS_RESTART) -+ schedule_work(&adapter->reset_task); -+ } ++#endif /* CONFIG_E1000E_SEPARATE_TX_HANDLER */ ++static irqreturn_t e1000_intr_msix_rx(int irq, void *data) ++{ ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++#ifndef CONFIG_E1000E_NAPI ++ int i; ++ struct e1000_hw *hw = &adapter->hw; ++#endif ++ ++ /* Write the ITR value calculated at the end of the ++ * previous interrupt. ++ */ ++ if (adapter->rx_ring->set_itr) { ++ writel(1000000000 / (adapter->rx_ring->itr_val * 256), ++ adapter->hw.hw_addr + adapter->rx_ring->itr_register); ++ adapter->rx_ring->set_itr = 0; ++ } ++ ++#ifdef CONFIG_E1000E_NAPI ++ if (netif_rx_schedule_prep(netdev, &adapter->napi)) { ++ adapter->total_rx_bytes = 0; ++ adapter->total_rx_packets = 0; ++#ifndef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ adapter->total_tx_bytes = 0; ++ adapter->total_tx_packets = 0; ++#endif /* CONFIG_E1000E_SEPARATE_TX_HANDLER */ ++ __netif_rx_schedule(netdev, &adapter->napi); + } ++#else ++ adapter->total_rx_bytes = 0; ++ adapter->total_rx_packets = 0; ++#ifndef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ adapter->total_tx_bytes = 0; ++ adapter->total_tx_packets = 0; ++#endif + -+link_up: -+ e1000e_update_stats(adapter); ++ for (i = 0; i < E1000_MAX_INTR; i++) { ++ int rx_cleaned = adapter->clean_rx(adapter); ++#ifndef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ int tx_cleaned_complete = e1000_clean_tx_irq(adapter); ++ if (!rx_cleaned && tx_cleaned_complete) ++#else ++ if (!rx_cleaned) ++#endif ++ goto out; ++ } ++ /* If we got here, the ring was not completely cleaned, ++ * so fire another interrupt. ++ */ ++ ew32(ICS, adapter->rx_ring->ims_val); + -+ mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; -+ adapter->tpt_old = adapter->stats.tpt; -+ mac->collision_delta = adapter->stats.colc - adapter->colc_old; -+ adapter->colc_old = adapter->stats.colc; ++out: ++#endif /* CONFIG_E1000E_NAPI */ ++ return IRQ_HANDLED; ++} + -+ adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old; -+ adapter->gorcl_old = adapter->stats.gorcl; -+ adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old; -+ adapter->gotcl_old = adapter->stats.gotcl; ++/** ++ * e1000_configure_msix - Configure MSI-X hardware ++ * ++ * e1000_configure_msix sets up the hardware to properly ++ * generate MSI-X interrupts. ++ **/ ++static void e1000_configure_msix(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ int vector = 0; ++ u32 ctrl_ext, ivar = 0; + -+ e1000e_update_adaptive(&adapter->hw); ++ adapter->eiac_mask = 0; + -+ if (!netif_carrier_ok(netdev)) { -+ tx_pending = (e1000_desc_unused(tx_ring) + 1 < -+ tx_ring->count); -+ if (tx_pending) { -+ /* 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). */ -+ adapter->tx_timeout_count++; -+ schedule_work(&adapter->reset_task); -+ } ++ /* Workaround issue with spurious interrupts on 82574 in MSI-X mode */ ++ if (hw->mac.type == e1000_82574) { ++ u32 rfctl = er32(RFCTL); ++ rfctl |= E1000_RFCTL_ACK_DIS; ++ ew32(RFCTL, rfctl); + } + -+ /* Cause software interrupt to ensure rx ring is cleaned */ -+ ew32(ICS, E1000_ICS_RXDMT0); ++#define E1000_IVAR_INT_ALLOC_VALID 0x8 ++ /* Configure Rx vector */ ++ rx_ring->ims_val = E1000_IMS_RXQ0; ++ adapter->eiac_mask |= rx_ring->ims_val; ++ if (rx_ring->itr_val) ++ writel(1000000000 / (rx_ring->itr_val * 256), ++ hw->hw_addr + rx_ring->itr_register); ++ else ++ writel(1, hw->hw_addr + rx_ring->itr_register); ++ ivar = E1000_IVAR_INT_ALLOC_VALID | vector; ++ ++ /* Configure Tx vector */ ++ tx_ring->ims_val = E1000_IMS_TXQ0; ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ vector++; ++ if (tx_ring->itr_val) ++ writel(1000000000 / (tx_ring->itr_val * 256), ++ hw->hw_addr + tx_ring->itr_register); ++ else ++ writel(1, hw->hw_addr + tx_ring->itr_register); ++#else ++ rx_ring->ims_val |= tx_ring->ims_val; ++#endif ++ adapter->eiac_mask |= tx_ring->ims_val; ++ ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8); ++ ++ /* set vector for Other Causes, e.g. link changes */ ++ vector++; ++ ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 16); ++ if (rx_ring->itr_val) ++ writel(1000000000 / (rx_ring->itr_val * 256), ++ hw->hw_addr + E1000_EITR_82574(vector)); ++ else ++ writel(1, hw->hw_addr + E1000_EITR_82574(vector)); + -+ /* Force detection of hung controller every watchdog period */ -+ adapter->detect_tx_hung = 1; ++ /* Cause Tx interrupts on every write back */ ++ ivar |= (1 << 31); + -+ /* With 82571 controllers, LAA may be overwritten due to controller -+ * reset from the other port. Set the appropriate LAA in RAR[0] */ -+ if (e1000e_get_laa_state_82571(hw)) -+ e1000e_rar_set(hw, adapter->hw.mac.addr, 0); ++ ew32(IVAR, ivar); + -+ /* Reset the timer */ -+ if (!test_bit(__E1000_DOWN, &adapter->state)) -+ mod_timer(&adapter->watchdog_timer, -+ round_jiffies(jiffies + 2 * HZ)); ++ /* enable MSI-X PBA support */ ++ ctrl_ext = er32(CTRL_EXT); ++ ctrl_ext |= E1000_CTRL_EXT_PBA_CLR; ++ ++ /* Auto-Mask Other interrupts upon ICR read */ ++ ew32(IAM, ~E1000_EIAC_MASK_82574 | E1000_IMS_OTHER); ++ ctrl_ext |= E1000_CTRL_EXT_EIAME; ++ ew32(CTRL_EXT, ctrl_ext); ++ e1e_flush(); +} + -+#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 ++void e1000_reset_interrupt_capability(struct e1000_adapter *adapter) ++{ ++ if (adapter->msix_entries) { ++ pci_disable_msix(adapter->pdev); ++ kfree(adapter->msix_entries); ++ adapter->msix_entries = NULL; ++ } else if (adapter->flags & FLAG_MSI_ENABLED) { ++ pci_disable_msi(adapter->pdev); ++ adapter->flags &= ~FLAG_MSI_ENABLED; ++ } + -+static int e1000_tso(struct e1000_adapter *adapter, -+ struct sk_buff *skb) ++ return; ++} ++ ++/** ++ * e1000_set_interrupt_capability - set MSI or MSI-X if supported ++ * ++ * Attempt to configure interrupts using the best available ++ * capabilities of the hardware and kernel. ++ **/ ++void e1000_set_interrupt_capability(struct e1000_adapter *adapter) +{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_context_desc *context_desc; -+ struct e1000_buffer *buffer_info; -+ unsigned int i; -+ u32 cmd_length = 0; -+ u16 ipcse = 0, tucse, mss; -+ u8 ipcss, ipcso, tucss, tucso, hdr_len; + int err; ++ int numvecs, i; + -+ if (skb_is_gso(skb)) { -+ if (skb_header_cloned(skb)) { -+ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); -+ if (err) -+ return err; -+ } + -+ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); -+ mss = skb_shinfo(skb)->gso_size; -+ if (skb->protocol == htons(ETH_P_IP)) { -+ struct iphdr *iph = ip_hdr(skb); -+ iph->tot_len = 0; -+ iph->check = 0; -+ tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, -+ iph->daddr, 0, -+ IPPROTO_TCP, -+ 0); -+ cmd_length = E1000_TXD_CMD_IP; -+ ipcse = skb_transport_offset(skb) - 1; -+ } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { -+ ipv6_hdr(skb)->payload_len = 0; -+ tcp_hdr(skb)->check = -+ ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, -+ &ipv6_hdr(skb)->daddr, -+ 0, IPPROTO_TCP, 0); -+ ipcse = 0; ++ switch (adapter->int_mode) { ++ case E1000E_INT_MODE_MSIX: ++ if (adapter->flags & FLAG_HAS_MSIX) { ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ numvecs = 3; /* RxQ0, TxQ0 and other */ ++#else ++ numvecs = 2; /* RxQ0/TxQ0 and other */ ++#endif ++ adapter->msix_entries = kcalloc(numvecs, ++ sizeof(struct msix_entry), ++ GFP_KERNEL); ++ if (adapter->msix_entries) { ++ for (i=0; i < numvecs; i++) ++ adapter->msix_entries[i].entry = i; ++ ++ err = pci_enable_msix(adapter->pdev, ++ adapter->msix_entries, ++ numvecs); ++ if (err == 0) ++ return; ++ } ++ /* MSI-X failed, so fall through and try MSI */ ++ e_err("Failed to initialize MSI-X interrupts. " ++ "Falling back to MSI interrupts.\n"); ++ e1000_reset_interrupt_capability(adapter); + } -+ ipcss = skb_network_offset(skb); -+ ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data; -+ tucss = skb_transport_offset(skb); -+ tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; -+ tucse = 0; -+ -+ cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | -+ E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); ++ adapter->int_mode = E1000E_INT_MODE_MSI; ++ /* Fall through */ ++ case E1000E_INT_MODE_MSI: ++ if (!pci_enable_msi(adapter->pdev)) { ++ adapter->flags |= FLAG_MSI_ENABLED; ++ } else { ++ adapter->int_mode = E1000E_INT_MODE_LEGACY; ++ e_err("Failed to initialize MSI interrupts. Falling " ++ "back to legacy interrupts.\n"); ++ } ++ /* Fall through */ ++ case E1000E_INT_MODE_LEGACY: ++ /* Don't do anything; this is the system default */ ++ break; ++ } + -+ i = tx_ring->next_to_use; -+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i); -+ buffer_info = &tx_ring->buffer_info[i]; ++ return; ++} + -+ context_desc->lower_setup.ip_fields.ipcss = ipcss; -+ context_desc->lower_setup.ip_fields.ipcso = ipcso; -+ context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); -+ context_desc->upper_setup.tcp_fields.tucss = tucss; -+ context_desc->upper_setup.tcp_fields.tucso = tucso; -+ 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(cmd_length); ++/** ++ * e1000_request_msix - Initialize MSI-X interrupts ++ * ++ * e1000_request_msix allocates MSI-X vectors and requests interrupts from the ++ * kernel. ++ **/ ++static int e1000_request_msix(struct e1000_adapter *adapter) ++{ ++ struct net_device *netdev = adapter->netdev; ++ int err = 0, vector = 0; + -+ buffer_info->time_stamp = jiffies; -+ buffer_info->next_to_watch = i; ++ if (strlen(netdev->name) < (IFNAMSIZ - 5)) ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ sprintf(adapter->rx_ring->name, "%s-rx0", netdev->name); ++#else ++ sprintf(adapter->rx_ring->name, "%s-Q0", netdev->name); ++#endif ++ else ++ memcpy(adapter->rx_ring->name, netdev->name, IFNAMSIZ); ++ err = request_irq(adapter->msix_entries[vector].vector, ++ &e1000_intr_msix_rx, 0, adapter->rx_ring->name, ++ netdev); ++ if (err) ++ goto out; ++ adapter->rx_ring->itr_register = E1000_EITR_82574(vector); ++ adapter->rx_ring->itr_val = adapter->itr; ++ vector++; + -+ i++; -+ if (i == tx_ring->count) -+ i = 0; -+ tx_ring->next_to_use = i; ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ if (strlen(netdev->name) < (IFNAMSIZ - 5)) ++ sprintf(adapter->tx_ring->name, "%s-tx0", netdev->name); ++ else ++ memcpy(adapter->tx_ring->name, netdev->name, IFNAMSIZ); ++ err = request_irq(adapter->msix_entries[vector].vector, ++ &e1000_intr_msix_tx, 0, adapter->tx_ring->name, ++ netdev); ++ if (err) ++ goto out; ++ adapter->tx_ring->itr_register = E1000_EITR_82574(vector); ++ adapter->tx_ring->itr_val = adapter->itr; ++ vector++; + -+ return 1; -+ } ++#endif /* CONFIG_E1000E_SEPARATE_TX_HANDLER */ ++ err = request_irq(adapter->msix_entries[vector].vector, ++ &e1000_msix_other, 0, netdev->name, netdev); ++ if (err) ++ goto out; + ++ e1000_configure_msix(adapter); + return 0; ++out: ++ return err; +} + -+static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) ++#endif /* CONFIG_E1000E_MSIX */ ++/** ++ * e1000_alloc_queues - Allocate memory for all rings ++ * @adapter: board private structure to initialize ++ **/ ++static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter) +{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_context_desc *context_desc; -+ struct e1000_buffer *buffer_info; -+ unsigned int i; -+ u8 css; ++ adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); ++ if (!adapter->tx_ring) ++ goto err; ++ ++ adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); ++ if (!adapter->rx_ring) ++ goto err; + -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ css = skb_transport_offset(skb); ++ return 0; ++err: ++ e_err("Unable to allocate memory for queues\n"); ++ kfree(adapter->rx_ring); ++ kfree(adapter->tx_ring); ++ return -ENOMEM; ++} + -+ i = tx_ring->next_to_use; -+ buffer_info = &tx_ring->buffer_info[i]; -+ context_desc = E1000_CONTEXT_DESC(*tx_ring, i); ++/** ++ * e1000_request_irq - initialize interrupts ++ * ++ * Attempts to configure interrupts using the best available ++ * capabilities of the hardware and kernel. ++ **/ ++static int e1000_request_irq(struct e1000_adapter *adapter) ++{ ++ struct net_device *netdev = adapter->netdev; ++ int err; ++#ifdef CONFIG_E1000E_MSIX + -+ context_desc->lower_setup.ip_config = 0; -+ context_desc->upper_setup.tcp_fields.tucss = css; -+ context_desc->upper_setup.tcp_fields.tucso = -+ css + skb->csum_offset; -+ 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 (adapter->msix_entries) { ++ err = e1000_request_msix(adapter); ++ if (!err) ++ return err; ++ /* fall back to MSI */ ++ e1000_reset_interrupt_capability(adapter); ++ adapter->int_mode = E1000E_INT_MODE_MSI; ++ e1000_set_interrupt_capability(adapter); ++ } ++ if (adapter->flags & FLAG_MSI_ENABLED) { ++ err = request_irq(adapter->pdev->irq, &e1000_intr_msi, 0, ++ netdev->name, netdev); ++ if (!err) ++ return err; + -+ buffer_info->time_stamp = jiffies; -+ buffer_info->next_to_watch = i; ++ /* fall back to legacy interrupt */ ++ e1000_reset_interrupt_capability(adapter); ++ adapter->int_mode = E1000E_INT_MODE_LEGACY; ++ } + -+ i++; -+ if (i == tx_ring->count) -+ i = 0; -+ tx_ring->next_to_use = i; ++ err = request_irq(adapter->pdev->irq, &e1000_intr, IRQF_SHARED, ++ netdev->name, netdev); ++ if (err) ++ e_err("Unable to allocate interrupt, Error: %d\n", err); ++#else ++ int irq_flags = IRQF_SHARED; + -+ return 1; ++ if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) { ++ err = pci_enable_msi(adapter->pdev); ++ if (!err) { ++ adapter->flags |= FLAG_MSI_ENABLED; ++ irq_flags = 0; ++ } + } + -+ return 0; -+} ++ err = request_irq(adapter->pdev->irq, ++ ((adapter->flags & FLAG_MSI_ENABLED) ? ++ &e1000_intr_msi : &e1000_intr), ++ irq_flags, netdev->name, netdev); ++ if (err) { ++ if (adapter->flags & FLAG_MSI_ENABLED) { ++ pci_disable_msi(adapter->pdev); ++ adapter->flags &= ~FLAG_MSI_ENABLED; ++ } ++ e_err("Unable to allocate interrupt, Error: %d\n", err); ++ } ++#endif /* CONFIG_E1000E_MSIX */ + -+#define E1000_MAX_PER_TXD 8192 -+#define E1000_MAX_TXD_PWR 12 ++ return err; ++} + -+static 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 void e1000_free_irq(struct e1000_adapter *adapter) +{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_buffer *buffer_info; -+ unsigned int len = skb->len - skb->data_len; -+ unsigned int offset = 0, size, count = 0, i; -+ unsigned int f; -+ -+ i = tx_ring->next_to_use; ++ struct net_device *netdev = adapter->netdev; + -+ while (len) { -+ buffer_info = &tx_ring->buffer_info[i]; -+ size = min(len, max_per_txd); -+ /* 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 (tx_ring->last_tx_tso && !skb_is_gso(skb)) { -+ tx_ring->last_tx_tso = 0; -+ if (!skb->data_len) -+ size -= 4; -+ } ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->msix_entries) { ++ int vector = 0; + -+ /* Workaround for premature desc write-backs -+ * in TSO mode. Append 4-byte sentinel desc */ -+ if (mss && !nr_frags && size == len && size > 8) -+ size -= 4; ++ free_irq(adapter->msix_entries[vector].vector, netdev); ++ vector++; + -+ buffer_info->length = size; -+ /* set time_stamp *before* dma to help avoid a possible race */ -+ buffer_info->time_stamp = jiffies; -+ buffer_info->dma = -+ pci_map_single(adapter->pdev, -+ skb->data + offset, -+ size, -+ PCI_DMA_TODEVICE); -+ if (pci_dma_mapping_error(buffer_info->dma)) { -+ dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); -+ adapter->tx_dma_failed++; -+ return -1; -+ } -+ buffer_info->next_to_watch = i; ++#ifdef CONFIG_E1000E_SEPARATE_TX_HANDLER ++ free_irq(adapter->msix_entries[vector].vector, netdev); ++ vector++; + -+ len -= size; -+ offset += size; -+ count++; -+ i++; -+ if (i == tx_ring->count) -+ i = 0; ++#endif ++ /* Other Causes interrupt vector */ ++ free_irq(adapter->msix_entries[vector].vector, netdev); ++ return; + } + -+ for (f = 0; f < nr_frags; f++) { -+ struct skb_frag_struct *frag; ++#endif /* CONFIG_E1000E_MSIX */ ++ free_irq(adapter->pdev->irq, netdev); ++#ifndef CONFIG_E1000E_MSIX ++ if (adapter->flags & FLAG_MSI_ENABLED) { ++ pci_disable_msi(adapter->pdev); ++ adapter->flags &= ~FLAG_MSI_ENABLED; ++ } ++#endif ++} + -+ frag = &skb_shinfo(skb)->frags[f]; -+ len = frag->size; -+ offset = frag->page_offset; ++/** ++ * e1000_irq_disable - Mask off interrupt generation on the NIC ++ **/ ++static void e1000_irq_disable(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; + -+ while (len) { -+ buffer_info = &tx_ring->buffer_info[i]; -+ size = min(len, max_per_txd); -+ /* Workaround for premature desc write-backs -+ * in TSO mode. Append 4-byte sentinel desc */ -+ if (mss && f == (nr_frags-1) && size == len && size > 8) -+ size -= 4; ++ ew32(IMC, ~0); ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->msix_entries) { ++ ew32(EIAC_82574, 0); ++ } ++#endif /* CONFIG_E1000E_MSIX */ ++ e1e_flush(); ++ synchronize_irq(adapter->pdev->irq); ++} + -+ buffer_info->length = size; -+ buffer_info->time_stamp = jiffies; -+ buffer_info->dma = -+ pci_map_page(adapter->pdev, -+ frag->page, -+ offset, -+ size, -+ PCI_DMA_TODEVICE); -+ if (pci_dma_mapping_error(buffer_info->dma)) { -+ dev_err(&adapter->pdev->dev, -+ "TX DMA page map failed\n"); -+ adapter->tx_dma_failed++; -+ return -1; -+ } ++/** ++ * e1000_irq_enable - Enable default interrupt generation settings ++ **/ ++static void e1000_irq_enable(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++#ifdef CONFIG_E1000E_MSIX + -+ buffer_info->next_to_watch = i; ++ if (adapter->msix_entries) { ++ ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); ++ ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); ++ } else { ++ ew32(IMS, IMS_ENABLE_MASK); ++ } ++#else ++ ew32(IMS, IMS_ENABLE_MASK); ++#endif /* CONFIG_E1000E_MSIX */ ++} + -+ len -= size; -+ offset += size; -+ count++; ++/** ++ * 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|SWSM}: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 network i/f is open. ++ **/ ++static void e1000_get_hw_control(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl_ext; ++ u32 swsm; + -+ i++; -+ if (i == tx_ring->count) -+ i = 0; -+ } ++ /* Let firmware know the driver has taken over */ ++ if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) { ++ swsm = er32(SWSM); ++ ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD); ++ } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) { ++ ctrl_ext = er32(CTRL_EXT); ++ ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD); + } ++} + -+ if (i == 0) -+ i = tx_ring->count - 1; -+ else -+ i--; -+ -+ tx_ring->buffer_info[i].skb = skb; -+ tx_ring->buffer_info[first].next_to_watch = i; ++/** ++ * 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|SWSM}: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 network i/f is closed. ++ * ++ **/ ++static void e1000_release_hw_control(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl_ext; ++ u32 swsm; + -+ return count; ++ /* Let firmware taken over control of h/w */ ++ if (adapter->flags & FLAG_HAS_SWSM_ON_LOAD) { ++ swsm = er32(SWSM); ++ ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD); ++ } else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) { ++ ctrl_ext = er32(CTRL_EXT); ++ ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD); ++ } +} + -+static void e1000_tx_queue(struct e1000_adapter *adapter, -+ int tx_flags, int count) ++#ifdef CONFIG_E1000E_NAPI ++/** ++ * e1000_poll - NAPI Rx polling callback ++ * @napi: struct associated with this polling callback ++ * @budget: amount of packets driver is allowed to process this poll ++ **/ ++static int e1000_poll(struct napi_struct *napi, int budget) +{ -+ struct e1000_ring *tx_ring = adapter->tx_ring; -+ struct e1000_tx_desc *tx_desc = NULL; -+ struct e1000_buffer *buffer_info; -+ u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; -+ unsigned int i; ++ struct e1000_adapter *adapter = container_of(napi, struct e1000_adapter, ++ napi); ++ struct net_device *netdev = adapter->netdev; ++ int tx_clean_complete = 1, work_done = 0; ++#ifdef CONFIG_E1000E_MSIX ++ struct e1000_hw *hw = &adapter->hw; + -+ if (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_TXSM << 8; ++ if (adapter->msix_entries && ++ !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val)) ++ goto clean_rx; + -+ if (tx_flags & E1000_TX_FLAGS_IPV4) -+ txd_upper |= E1000_TXD_POPTS_IXSM << 8; ++#endif ++ /* ++ * e1000_poll is called per-cpu. This lock protects ++ * tx_ring from being cleaned by multiple cpus ++ * simultaneously. A failure obtaining the lock means ++ * tx_ring is currently being cleaned anyway. ++ */ ++ if (spin_trylock(&adapter->tx_queue_lock)) { ++ tx_clean_complete &= e1000_clean_tx_irq(adapter); ++ spin_unlock(&adapter->tx_queue_lock); + } + -+ if (tx_flags & E1000_TX_FLAGS_CSUM) { -+ txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; -+ txd_upper |= E1000_TXD_POPTS_TXSM << 8; -+ } ++#ifdef CONFIG_E1000E_MSIX ++clean_rx: ++#endif ++ adapter->clean_rx(adapter, &work_done, budget); + -+ if (tx_flags & E1000_TX_FLAGS_VLAN) { -+ txd_lower |= E1000_TXD_CMD_VLE; -+ txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK); ++ /* If Tx completed and all Rx work done, exit the polling mode */ ++ if ((tx_clean_complete && (work_done == 0)) || !netif_running(netdev)) { ++ netif_rx_complete(netdev, napi); ++ if (adapter->itr_setting & 3) ++ e1000_set_itr(adapter); ++ if (!test_bit(__E1000_DOWN, &adapter->state)) { ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->msix_entries) ++ ew32(IMS, adapter->rx_ring->ims_val); ++ else ++#endif ++ e1000_irq_enable(adapter); ++ } ++ return 0; + } + -+ i = tx_ring->next_to_use; ++ if (!tx_clean_complete) ++ work_done = budget; + -+ 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); ++ return work_done; ++} + -+ i++; -+ if (i == tx_ring->count) -+ i = 0; -+ } ++#endif /* CONFIG_E1000E_NAPI */ ++static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 vfta, index; ++ struct net_device *v_netdev; + -+ tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd); ++ /* don't update vlan cookie if already programmed */ ++ if ((adapter->hw.mng_cookie.status & ++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && ++ (vid == adapter->mng_vlan_id)) ++ return; ++ /* add VID to filter table */ ++ index = (vid >> 5) & 0x7F; ++ vfta = E1000_READ_REG_ARRAY(hw, E1000_VFTA, index); ++ vfta |= (1 << (vid & 0x1F)); ++ if (hw->mac.ops.write_vfta) ++ hw->mac.ops.write_vfta(hw, index, vfta); ++ /* ++ * Copy feature flags from netdev to the vlan netdev for this vid. ++ * This allows things like TSO to bubble down to our vlan device. ++ */ ++ v_netdev = vlan_group_get_device(adapter->vlgrp, vid); ++ v_netdev->features |= adapter->netdev->features; ++ vlan_group_set_device(adapter->vlgrp, vid, v_netdev); ++} + -+ /* 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(); ++static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 vfta, index; + -+ tx_ring->next_to_use = i; -+ writel(i, adapter->hw.hw_addr + tx_ring->tail); -+ /* we need this if more than one processor can write to our tail -+ * at a time, it synchronizes IO on IA64/Altix systems */ -+ mmiowb(); ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ e1000_irq_disable(adapter); ++ vlan_group_set_device(adapter->vlgrp, vid, NULL); ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ e1000_irq_enable(adapter); ++ ++ if ((adapter->hw.mng_cookie.status & ++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && ++ (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(hw, E1000_VFTA, index); ++ vfta &= ~(1 << (vid & 0x1F)); ++ if (hw->mac.ops.write_vfta) ++ hw->mac.ops.write_vfta(hw, index, vfta); +} + -+#define MINIMUM_DHCP_PACKET_SIZE 282 -+static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, -+ struct sk_buff *skb) ++static void e1000_update_mng_vlan(struct e1000_adapter *adapter) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ u16 length, offset; ++ struct net_device *netdev = adapter->netdev; ++ u16 vid = adapter->hw.mng_cookie.vlan_id; ++ u16 old_vid = adapter->mng_vlan_id; + -+ 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))) -+ return 0; ++ if (!adapter->vlgrp) ++ return; ++ ++ if (!vlan_group_get_device(adapter->vlgrp, vid)) { ++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; ++ if (adapter->hw.mng_cookie.status & ++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) { ++ e1000_vlan_rx_add_vid(netdev, vid); ++ adapter->mng_vlan_id = vid; ++ } ++ ++ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && ++ (vid != old_vid) && ++ !vlan_group_get_device(adapter->vlgrp, old_vid)) ++ e1000_vlan_rx_kill_vid(netdev, old_vid); ++ } else { ++ adapter->mng_vlan_id = vid; + } ++} + -+ if (skb->len <= MINIMUM_DHCP_PACKET_SIZE) -+ return 0; + -+ if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP)) -+ return 0; ++static void e1000_vlan_rx_register(struct net_device *netdev, ++ struct vlan_group *grp) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl, rctl; + -+ { -+ const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); -+ struct udphdr *udp; ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ e1000_irq_disable(adapter); ++ adapter->vlgrp = grp; + -+ if (ip->protocol != IPPROTO_UDP) -+ return 0; ++ if (grp) { ++ /* enable VLAN tag insert/strip */ ++ ctrl = er32(CTRL); ++ ctrl |= E1000_CTRL_VME; ++ ew32(CTRL, ctrl); + -+ udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); -+ if (ntohs(udp->dest) != 67) -+ return 0; ++ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { ++ /* enable VLAN receive filtering */ ++ rctl = er32(RCTL); ++ rctl |= E1000_RCTL_VFE; ++ rctl &= ~E1000_RCTL_CFIEN; ++ ew32(RCTL, rctl); ++ e1000_update_mng_vlan(adapter); ++ } ++ } else { ++ /* disable VLAN tag insert/strip */ ++ ctrl = er32(CTRL); ++ ctrl &= ~E1000_CTRL_VME; ++ ew32(CTRL, ctrl); + -+ offset = (u8 *)udp + 8 - skb->data; -+ length = skb->len - offset; -+ return e1000e_mng_write_dhcp_info(hw, (u8 *)udp + 8, length); ++ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) { ++ /* disable VLAN filtering */ ++ rctl = er32(RCTL); ++ rctl &= ~E1000_RCTL_VFE; ++ ew32(RCTL, rctl); ++ if (adapter->mng_vlan_id != ++ (u16)E1000_MNG_VLAN_NONE) { ++ e1000_vlan_rx_kill_vid(netdev, ++ adapter->mng_vlan_id); ++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; ++ } ++ } + } + -+ return 0; ++ if (!test_bit(__E1000_DOWN, &adapter->state)) ++ e1000_irq_enable(adapter); +} + -+static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) ++static void e1000_restore_vlan(struct e1000_adapter *adapter) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ u16 vid; + -+ netif_stop_queue(netdev); -+ /* Herbert's original patch had: -+ * smp_mb__after_netif_stop_queue(); -+ * but since that doesn't exist yet, just open code it. */ -+ smp_mb(); ++ e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp); + -+ /* We need to check again in a case another CPU has just -+ * made room available. */ -+ if (e1000_desc_unused(adapter->tx_ring) < size) -+ return -EBUSY; ++ if (!adapter->vlgrp) ++ return; + -+ /* A reprieve! */ -+ netif_start_queue(netdev); -+ ++adapter->restart_queue; -+ return 0; ++ for (vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) { ++ if (!vlan_group_get_device(adapter->vlgrp, vid)) ++ continue; ++ e1000_vlan_rx_add_vid(adapter->netdev, vid); ++ } +} + -+static int e1000_maybe_stop_tx(struct net_device *netdev, int size) ++static void e1000_init_manageability(struct e1000_adapter *adapter) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 manc, manc2h; + -+ if (e1000_desc_unused(adapter->tx_ring) >= size) -+ return 0; -+ return __e1000_maybe_stop_tx(netdev, size); ++ if (!(adapter->flags & FLAG_MNG_PT_ENABLED)) ++ return; ++ ++ manc = er32(MANC); ++ ++ /* ++ * enable receiving management packets to the host. this will probably ++ * generate destination unreachable messages from the host OS, but ++ * the packets will be handled on SMBUS ++ */ ++ manc |= E1000_MANC_EN_MNG2HOST; ++ manc2h = er32(MANC2H); ++#define E1000_MNG2HOST_PORT_623 (1 << 5) ++#define E1000_MNG2HOST_PORT_664 (1 << 6) ++ manc2h |= E1000_MNG2HOST_PORT_623; ++ manc2h |= E1000_MNG2HOST_PORT_664; ++ ew32(MANC2H, manc2h); ++ ew32(MANC, manc); +} + -+#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) -+static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ++/** ++ * e1000_configure_tx - Configure 8254x Transmit Unit after Reset ++ * @adapter: board private structure ++ * ++ * Configure the Tx unit of the MAC after a reset. ++ **/ ++static void e1000_configure_tx(struct e1000_adapter *adapter) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + struct e1000_ring *tx_ring = adapter->tx_ring; -+ unsigned int first; -+ unsigned int max_per_txd = E1000_MAX_PER_TXD; -+ unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; -+ unsigned int tx_flags = 0; -+ unsigned int len = skb->len; -+ unsigned long irq_flags; -+ unsigned int nr_frags = 0; -+ unsigned int mss = 0; -+ int count = 0; -+ int tso; -+ unsigned int f; -+ len -= skb->data_len; ++ u64 tdba; ++ u32 tdlen, tctl, tipg, tarc; ++ u32 ipgr1, ipgr2; + -+ if (test_bit(__E1000_DOWN, &adapter->state)) { -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+ } ++ /* Setup the HW Tx Head and Tail descriptor pointers */ ++ tdba = tx_ring->dma; ++ tdlen = tx_ring->count * sizeof(struct e1000_tx_desc); ++ ew32(TDBAL(0), (tdba & DMA_32BIT_MASK)); ++ ew32(TDBAH(0), (tdba >> 32)); ++ ew32(TDLEN(0), tdlen); ++ ew32(TDH(0), 0); ++ ew32(TDT(0), 0); ++ tx_ring->head = E1000_TDH(0); ++ tx_ring->tail = E1000_TDT(0); + -+ if (skb->len <= 0) { -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+ } ++ /* Set the default values for the Tx Inter Packet Gap timer */ ++ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ ++ ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ ++ ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ + -+ mss = skb_shinfo(skb)->gso_size; -+ /* 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) { -+ u8 hdr_len; -+ max_per_txd = min(mss << 2, max_per_txd); -+ max_txd_pwr = fls(max_per_txd) - 1; ++ if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) ++ ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ + -+ /* 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_transport_offset(skb) + tcp_hdrlen(skb); -+ if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) { -+ unsigned int pull_size; ++ tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; ++ tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; ++ ew32(TIPG, tipg); + -+ pull_size = min((unsigned int)4, skb->data_len); -+ if (!__pskb_pull_tail(skb, pull_size)) { -+ ndev_err(netdev, -+ "__pskb_pull_tail failed.\n"); -+ dev_kfree_skb_any(skb); -+ return NETDEV_TX_OK; -+ } -+ len = skb->len - skb->data_len; -+ } ++ /* Set the Tx Interrupt Delay register */ ++ ew32(TIDV, adapter->tx_int_delay); ++ /* Tx irq moderation */ ++ ew32(TADV, adapter->tx_abs_int_delay); ++ ++ /* Program the Transmit Control Register */ ++ tctl = er32(TCTL); ++ tctl &= ~E1000_TCTL_CT; ++ tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | ++ (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); ++ ++ if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { ++ tarc = er32(TARC(0)); ++ /* ++ * set the speed mode bit, we'll clear it if we're not at ++ * gigabit link later ++ */ ++#define SPEED_MODE_BIT (1 << 21) ++ tarc |= SPEED_MODE_BIT; ++ ew32(TARC(0), tarc); + } + -+ /* reserve a descriptor for the offload context */ -+ if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL)) -+ count++; -+ count++; ++ /* errata: program both queues to unweighted RR */ ++ if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) { ++ tarc = er32(TARC(0)); ++ tarc |= 1; ++ ew32(TARC(0), tarc); ++ tarc = er32(TARC(1)); ++ tarc |= 1; ++ ew32(TARC(1), tarc); ++ } + -+ /* Controller Erratum workaround */ -+ if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb)) -+ count++; ++ hw->mac.ops.config_collision_dist(hw); + -+ count += TXD_USE_COUNT(len, max_txd_pwr); ++ /* Setup Transmit Descriptor Settings for eop descriptor */ ++ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; + -+ nr_frags = skb_shinfo(skb)->nr_frags; -+ for (f = 0; f < nr_frags; f++) -+ count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, -+ max_txd_pwr); ++ /* only set IDE if we are delaying interrupts using the timers */ ++ if (adapter->tx_int_delay) ++ adapter->txd_cmd |= E1000_TXD_CMD_IDE; + -+ if (adapter->hw.mac.tx_pkt_filtering) -+ e1000_transfer_dhcp_info(adapter, skb); ++ /* enable Report Status bit */ ++ adapter->txd_cmd |= E1000_TXD_CMD_RS; + -+ if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags)) -+ /* Collision - tell upper layer to requeue */ -+ return NETDEV_TX_LOCKED; ++ ew32(TCTL, tctl); + -+ /* need: count + 2 desc gap to keep tail from touching -+ * head, otherwise try next time */ -+ if (e1000_maybe_stop_tx(netdev, count + 2)) { -+ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); -+ return NETDEV_TX_BUSY; -+ } ++ adapter->tx_queue_len = adapter->netdev->tx_queue_len; ++} ++ ++/** ++ * 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) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 rctl, rfctl; ++ u32 psrctl = 0; ++ u32 pages = 0; ++ ++ /* Program MC offset vector base */ ++ rctl = er32(RCTL); ++ rctl &= ~(3 << E1000_RCTL_MO_SHIFT); ++ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | ++ E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | ++ (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT); + -+ if (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); -+ } ++ /* Do not Store bad packets */ ++ rctl &= ~E1000_RCTL_SBP; + -+ first = tx_ring->next_to_use; ++ /* Enable Long Packet receive */ ++ if (adapter->netdev->mtu <= ETH_DATA_LEN) ++ rctl &= ~E1000_RCTL_LPE; ++ else ++ rctl |= E1000_RCTL_LPE; + -+ tso = e1000_tso(adapter, skb); -+ if (tso < 0) { -+ dev_kfree_skb_any(skb); -+ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); -+ return NETDEV_TX_OK; -+ } ++ /* Enable hardware CRC frame stripping */ ++ rctl |= E1000_RCTL_SECRC; + -+ if (tso) { -+ tx_ring->last_tx_tso = 1; -+ tx_flags |= E1000_TX_FLAGS_TSO; -+ } else if (e1000_tx_csum(adapter, skb)) { -+ tx_flags |= E1000_TX_FLAGS_CSUM; ++ /* Setup buffer sizes */ ++ rctl &= ~E1000_RCTL_SZ_4096; ++ rctl |= E1000_RCTL_BSEX; ++ switch (adapter->rx_buffer_len) { ++ case 256: ++ rctl |= E1000_RCTL_SZ_256; ++ rctl &= ~E1000_RCTL_BSEX; ++ break; ++ case 512: ++ rctl |= E1000_RCTL_SZ_512; ++ rctl &= ~E1000_RCTL_BSEX; ++ break; ++ case 1024: ++ rctl |= E1000_RCTL_SZ_1024; ++ rctl &= ~E1000_RCTL_BSEX; ++ break; ++ case 2048: ++ default: ++ rctl |= E1000_RCTL_SZ_2048; ++ rctl &= ~E1000_RCTL_BSEX; ++ break; ++ case 4096: ++ rctl |= E1000_RCTL_SZ_4096; ++ break; ++ case 8192: ++ rctl |= E1000_RCTL_SZ_8192; ++ break; ++ case 16384: ++ rctl |= E1000_RCTL_SZ_16384; ++ break; + } + -+ /* 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 (skb->protocol == htons(ETH_P_IP)) -+ tx_flags |= E1000_TX_FLAGS_IPV4; ++ /* ++ * 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. ++ * ++ * allocations using alloc_page take too long for regular MTU ++ * so only enable packet split for jumbo frames ++ * ++ * Using pages when the page size is greater than 16k wastes ++ * a lot of memory, since we allocate 3 pages at all times ++ * per packet. ++ */ ++ pages = PAGE_USE_COUNT(adapter->netdev->mtu); ++ if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) && ++ (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) ++ adapter->rx_ps_pages = pages; ++ else ++ adapter->rx_ps_pages = 0; + -+ count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); -+ if (count < 0) { -+ /* handle pci_map_single() error in e1000_tx_map */ -+ dev_kfree_skb_any(skb); -+ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); -+ return NETDEV_TX_BUSY; -+ } ++ if (adapter->rx_ps_pages) { ++ /* Configure extra packet-split registers */ ++ rfctl = er32(RFCTL); ++ rfctl |= E1000_RFCTL_EXTEN; ++ /* ++ * disable packet split support for IPv6 extension headers, ++ * because some malformed IPv6 headers can hang the Rx ++ */ ++ rfctl |= (E1000_RFCTL_IPV6_EX_DIS | ++ E1000_RFCTL_NEW_IPV6_EXT_DIS); + -+ e1000_tx_queue(adapter, tx_flags, count); ++ ew32(RFCTL, rfctl); + -+ netdev->trans_start = jiffies; ++ /* Enable Packet split descriptors */ ++ rctl |= E1000_RCTL_DTYP_PS; + -+ /* Make sure there is space in the ring for the next send. */ -+ e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); ++ psrctl |= adapter->rx_ps_bsize0 >> ++ E1000_PSRCTL_BSIZE0_SHIFT; + -+ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); -+ return NETDEV_TX_OK; ++ 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; ++ } ++ ++ ew32(PSRCTL, psrctl); ++ } ++ ++ ew32(RCTL, rctl); ++ /* just started the receive unit, no need to restart */ ++ adapter->flags &= ~FLAG_RX_RESTART_NOW; +} + +/** -+ * e1000_tx_timeout - Respond to a Tx Hang -+ * @netdev: network interface device structure ++ * e1000_configure_rx - Configure Receive Unit after Reset ++ * @adapter: board private structure ++ * ++ * Configure the Rx unit of the MAC after a reset. + **/ -+static void e1000_tx_timeout(struct net_device *netdev) ++static void e1000_configure_rx(struct e1000_adapter *adapter) +{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_ring *rx_ring = adapter->rx_ring; ++ u64 rdba; ++ u32 rdlen, rctl, rxcsum, ctrl_ext; + -+ /* Do the reset outside of interrupt context */ -+ adapter->tx_timeout_count++; -+ schedule_work(&adapter->reset_task); -+} ++ if (adapter->rx_ps_pages) { ++ /* this is a 32 byte descriptor */ ++ rdlen = rx_ring->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; ++#ifdef CONFIG_E1000E_NAPI ++ } else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) { ++ rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); ++ adapter->clean_rx = e1000_clean_jumbo_rx_irq; ++ adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers; ++#endif ++ } else { ++ rdlen = rx_ring->count * sizeof(struct e1000_rx_desc); ++ adapter->clean_rx = e1000_clean_rx_irq; ++ adapter->alloc_rx_buf = e1000_alloc_rx_buffers; ++ } + -+static void e1000_reset_task(struct work_struct *work) -+{ -+ struct e1000_adapter *adapter; -+ adapter = container_of(work, struct e1000_adapter, reset_task); ++ /* disable receives while setting up the descriptors */ ++ rctl = er32(RCTL); ++ ew32(RCTL, rctl & ~E1000_RCTL_EN); ++ e1e_flush(); ++ msleep(10); + -+ e1000e_reinit_locked(adapter); -+} ++ /* set the Receive Delay Timer Register */ ++ ew32(RDTR, adapter->rx_int_delay); + -+/** -+ * e1000_get_stats - Get System Network Statistics -+ * @netdev: network interface device structure -+ * -+ * Returns the address of the device statistics structure. -+ * The statistics are actually updated from the timer callback. -+ **/ -+static struct net_device_stats *e1000_get_stats(struct net_device *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ /* irq moderation */ ++ ew32(RADV, adapter->rx_abs_int_delay); ++ if (adapter->itr_setting != 0) ++ ew32(ITR, 1000000000 / (adapter->itr * 256)); + -+ /* only return the current stats */ -+ return &adapter->net_stats; -+} ++ ctrl_ext = er32(CTRL_EXT); ++ /* Reset delay timers after every interrupt */ ++ ctrl_ext |= E1000_CTRL_EXT_INT_TIMER_CLR; ++#ifdef CONFIG_E1000E_NAPI ++ /* Auto-Mask interrupts upon ICR access */ ++ ctrl_ext |= E1000_CTRL_EXT_IAME; ++ ew32(IAM, 0xffffffff); ++#endif ++ ew32(CTRL_EXT, ctrl_ext); ++ e1e_flush(); + -+/** -+ * e1000_change_mtu - Change the Maximum Transfer Unit -+ * @netdev: network interface device structure -+ * @new_mtu: new value for maximum frame size -+ * -+ * Returns 0 on success, negative on failure -+ **/ -+static int e1000_change_mtu(struct net_device *netdev, int new_mtu) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; ++ /* ++ * Setup the HW Rx Head and Tail Descriptor Pointers and ++ * the Base and Length of the Rx Descriptor Ring ++ */ ++ rdba = rx_ring->dma; ++ ew32(RDBAL(0), (rdba & DMA_32BIT_MASK)); ++ ew32(RDBAH(0), (rdba >> 32)); ++ ew32(RDLEN(0), rdlen); ++ ew32(RDH(0), 0); ++ ew32(RDT(0), 0); ++ rx_ring->head = E1000_RDH(0); ++ rx_ring->tail = E1000_RDT(0); + -+ if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) || -+ (max_frame > MAX_JUMBO_FRAME_SIZE)) { -+ ndev_err(netdev, "Invalid MTU setting\n"); -+ return -EINVAL; -+ } ++ /* Enable Receive Checksum Offload for TCP and UDP */ ++ rxcsum = er32(RXCSUM); ++ if (adapter->flags & FLAG_RX_CSUM_ENABLED) { ++ rxcsum |= E1000_RXCSUM_TUOFL; + -+ /* Jumbo frame size limits */ -+ if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { -+ if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { -+ ndev_err(netdev, "Jumbo Frames not supported.\n"); -+ return -EINVAL; -+ } -+ if (adapter->hw.phy.type == e1000_phy_ife) { -+ ndev_err(netdev, "Jumbo Frames not supported.\n"); -+ return -EINVAL; -+ } ++ /* ++ * IPv4 payload checksum for UDP fragments must be ++ * used in conjunction with packet-split. ++ */ ++ if (adapter->rx_ps_pages) ++ rxcsum |= E1000_RXCSUM_IPPCSE; ++ } else { ++ rxcsum &= ~E1000_RXCSUM_TUOFL; ++ /* no need to clear IPPCSE as it defaults to 0 */ + } ++ ew32(RXCSUM, rxcsum); + -+#define MAX_STD_JUMBO_FRAME_SIZE 9234 -+ if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { -+ ndev_err(netdev, "MTU > 9216 not supported.\n"); -+ return -EINVAL; ++ /* ++ * Enable early receives on supported devices, only takes effect when ++ * packet size is equal or larger than the specified value (in 8 byte ++ * units), e.g. using jumbo frames when setting to E1000_ERT_2048 ++ */ ++ if ((adapter->flags & FLAG_HAS_ERT) && ++ (adapter->netdev->mtu > ETH_DATA_LEN)) { ++ u32 rxdctl = er32(RXDCTL(0)); ++ ew32(RXDCTL(0), rxdctl | 0x3); ++ ew32(ERT, E1000_ERT_2048 | (1 << 13)); ++ /* ++ * With jumbo frames and early-receive enabled, excessive ++ * C4->C2 latencies result in dropped transactions. ++ */ ++ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, ++ e1000e_driver_name, 55); ++ } else { ++ pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY, ++ e1000e_driver_name, ++ PM_QOS_DEFAULT_VALUE); + } + -+ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) -+ msleep(1); -+ /* e1000e_down has a dependency on max_frame_size */ -+ adapter->hw.mac.max_frame_size = max_frame; -+ if (netif_running(netdev)) -+ e1000e_down(adapter); -+ -+ /* NOTE: netdev_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 -+ * however with the new *_jumbo* routines, jumbo receives will use -+ * fragmented skbs */ -+ -+ if (max_frame <= 256) -+ adapter->rx_buffer_len = 256; -+ else if (max_frame <= 512) -+ adapter->rx_buffer_len = 512; -+ else if (max_frame <= 1024) -+ adapter->rx_buffer_len = 1024; -+ else if (max_frame <= 2048) -+ adapter->rx_buffer_len = 2048; -+ else -+ adapter->rx_buffer_len = 4096; ++ /* Enable Receives */ ++ ew32(RCTL, rctl); ++} + -+ /* adjust allocation if LPE protects us, and we aren't using SBP */ -+ if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) || -+ (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)) -+ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN -+ + ETH_FCS_LEN ; ++/** ++ * e1000_set_multi - Multicast and Promiscuous mode set ++ * @netdev: network interface device structure ++ * ++ * The set_multi entry point is called whenever the multicast address ++ * list or the network interface flags are updated. This routine is ++ * responsible for configuring the hardware for proper multicast, ++ * promiscuous mode, and all-multi behavior. ++ **/ ++static void e1000_set_multi(struct net_device *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_mac_info *mac = &hw->mac; ++ struct dev_mc_list *mc_ptr; ++ u8 *mta_list; ++ u32 rctl; ++ int i; + -+ ndev_info(netdev, "changing MTU from %d to %d\n", -+ netdev->mtu, new_mtu); -+ netdev->mtu = new_mtu; ++ /* Check for Promiscuous and All Multicast modes */ + -+ if (netif_running(netdev)) -+ e1000e_up(adapter); -+ else -+ e1000e_reset(adapter); ++ rctl = er32(RCTL); + -+ clear_bit(__E1000_RESETTING, &adapter->state); ++ if (netdev->flags & IFF_PROMISC) { ++ rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); ++ } else if (netdev->flags & IFF_ALLMULTI) { ++ rctl |= E1000_RCTL_MPE; ++ rctl &= ~E1000_RCTL_UPE; ++ } else { ++ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); ++ } + -+ return 0; -+} ++ ew32(RCTL, rctl); + -+static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, -+ int cmd) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct mii_ioctl_data *data = if_mii(ifr); -+ unsigned long irq_flags; ++ if (netdev->mc_count) { ++ mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC); ++ if (!mta_list) ++ return; + -+ if (adapter->hw.media_type != e1000_media_type_copper) -+ return -EOPNOTSUPP; ++ /* prepare a packed array of only addresses. */ ++ mc_ptr = netdev->mc_list; + -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ data->phy_id = adapter->hw.phy.addr; -+ break; -+ case SIOCGMIIREG: -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ spin_lock_irqsave(&adapter->stats_lock, irq_flags); -+ if (e1e_rphy(&adapter->hw, data->reg_num & 0x1F, -+ &data->val_out)) { -+ spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); -+ return -EIO; ++ for (i = 0; i < netdev->mc_count; i++) { ++ if (!mc_ptr) ++ break; ++ memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ++ ETH_ALEN); ++ mc_ptr = mc_ptr->next; + } -+ spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); -+ break; -+ case SIOCSMIIREG: -+ default: -+ return -EOPNOTSUPP; ++ ++ hw->mac.ops.update_mc_addr_list(hw, mta_list, i, 1, ++ mac->rar_entry_count); ++ kfree(mta_list); ++ } else { ++ /* ++ * if we're called from probe, we might not have ++ * anything to do here, so clear out the list ++ */ ++ hw->mac.ops.update_mc_addr_list(hw, NULL, 0, 1, ++ mac->rar_entry_count); + } -+ return 0; +} + -+static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) ++/** ++ * e1000_configure - configure the hardware for Rx and Tx ++ * @adapter: private board structure ++ **/ ++static void e1000_configure(struct e1000_adapter *adapter) +{ -+ switch (cmd) { -+ case SIOCGMIIPHY: -+ case SIOCGMIIREG: -+ case SIOCSMIIREG: -+ return e1000_mii_ioctl(netdev, ifr, cmd); -+ default: -+ return -EOPNOTSUPP; -+ } ++ e1000_set_multi(adapter->netdev); ++ ++ e1000_restore_vlan(adapter); ++ e1000_init_manageability(adapter); ++ ++ e1000_configure_tx(adapter); ++ e1000_setup_rctl(adapter); ++ e1000_configure_rx(adapter); ++ adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring)); +} + -+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) ++/** ++ * e1000e_reset - bring the hardware into a known good state ++ * ++ * This function boots the hardware and enables some settings that ++ * require a configuration cycle of the hardware - those cannot be ++ * set/changed during runtime. After reset the device needs to be ++ * properly configured for Rx, Tx etc. ++ */ ++void e1000_reset(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_mac_info *mac = &adapter->hw.mac; ++ struct e1000_fc_info *fc = &adapter->hw.fc; + struct e1000_hw *hw = &adapter->hw; -+ u32 ctrl, ctrl_ext, rctl, status; -+ u32 wufc = adapter->wol; -+ int retval = 0; ++ u32 tx_space, min_tx_space, min_rx_space; ++ u32 pba = adapter->pba; ++ u16 hwm; + -+ netif_device_detach(netdev); ++ /* reset Packet Buffer Allocation to default */ ++ ew32(PBA, pba); + -+ if (netif_running(netdev)) { -+ WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); -+ e1000e_down(adapter); -+ e1000_free_irq(adapter); -+ } ++ if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) { ++ /* ++ * To maintain wire speed transmits, the Tx FIFO should be ++ * large enough to accommodate two full transmit packets, ++ * rounded up to the next 1KB and expressed in KB. Likewise, ++ * the Rx FIFO should be large enough to accommodate at least ++ * one full receive packet and is similarly rounded up and ++ * expressed in KB. ++ */ ++ pba = er32(PBA); ++ /* upper 16 bits has Tx packet buffer allocation size in KB */ ++ tx_space = pba >> 16; ++ /* lower 16 bits has Rx packet buffer allocation size in KB */ ++ pba &= 0xffff; ++ /* ++ * the Tx fifo also stores 16 bytes of information about the tx ++ * but don't include ethernet FCS because hardware appends it ++ */ ++ min_tx_space = (adapter->max_frame_size + ++ sizeof(struct e1000_tx_desc) - ++ ETH_FCS_LEN) * 2; ++ min_tx_space = ALIGN(min_tx_space, 1024); ++ min_tx_space >>= 10; ++ /* software strips receive CRC, so leave room for it */ ++ min_rx_space = adapter->max_frame_size; ++ min_rx_space = ALIGN(min_rx_space, 1024); ++ min_rx_space >>= 10; + -+ retval = pci_save_state(pdev); -+ if (retval) -+ return retval; ++ /* ++ * If current Tx allocation is less than the min Tx FIFO size, ++ * and the min Tx FIFO size is less than the current Rx FIFO ++ * allocation, take space away from current Rx allocation ++ */ ++ if ((tx_space < min_tx_space) && ++ ((min_tx_space - tx_space) < pba)) { ++ pba -= min_tx_space - tx_space; + -+ status = er32(STATUS); -+ if (status & E1000_STATUS_LU) -+ wufc &= ~E1000_WUFC_LNKC; ++ /* ++ * if short on Rx space, Rx wins and must trump tx ++ * adjustment or use Early Receive if available ++ */ ++ if ((pba < min_rx_space) && ++ (!(adapter->flags & FLAG_HAS_ERT))) ++ /* ERT enabled in e1000_configure_rx */ ++ pba = min_rx_space; ++ } + -+ if (wufc) { -+ e1000_setup_rctl(adapter); -+ e1000_set_multi(netdev); ++ ew32(PBA, pba); ++ } + -+ /* turn on all-multi mode if wake on multicast is enabled */ -+ if (wufc & E1000_WUFC_MC) { -+ rctl = er32(RCTL); -+ rctl |= E1000_RCTL_MPE; -+ ew32(RCTL, rctl); -+ } + -+ ctrl = er32(CTRL); -+ /* advertise wake from D3Cold */ -+ #define E1000_CTRL_ADVD3WUC 0x00100000 -+ /* phy power management enable */ -+ #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 -+ ctrl |= E1000_CTRL_ADVD3WUC | -+ E1000_CTRL_EN_PHY_PWR_MGMT; -+ ew32(CTRL, ctrl); ++ /* ++ * flow control settings ++ * ++ * The high water mark must be low enough to fit one full frame ++ * (or the size used for early receive) above it in the Rx FIFO. ++ * Set it to the lower of: ++ * - 90% of the Rx FIFO size, and ++ * - the full Rx FIFO size minus the early receive size (for parts ++ * with ERT support assuming ERT set to E1000_ERT_2048), or ++ * - the full Rx FIFO size minus one full frame ++ */ ++ if (adapter->flags & FLAG_HAS_ERT) ++ hwm = min(((pba << 10) * 9 / 10), ++ ((pba << 10) - (E1000_ERT_2048 << 3))); ++ else ++ hwm = min(((pba << 10) * 9 / 10), ++ ((pba << 10) - adapter->max_frame_size)); + -+ 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 = er32(CTRL_EXT); -+ ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA; -+ ew32(CTRL_EXT, ctrl_ext); -+ } ++ fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */ ++ fc->low_water = fc->high_water - 8; + -+ /* Allow time for pending master requests to run */ -+ e1000e_disable_pcie_master(&adapter->hw); ++ if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) ++ fc->pause_time = 0xFFFF; ++ else ++ fc->pause_time = E1000_FC_PAUSE_TIME; ++ fc->send_xon = 1; ++ fc->type = fc->original_type; + -+ ew32(WUC, E1000_WUC_PME_EN); -+ ew32(WUFC, wufc); -+ pci_enable_wake(pdev, PCI_D3hot, 1); -+ pci_enable_wake(pdev, PCI_D3cold, 1); -+ } else { -+ ew32(WUC, 0); -+ ew32(WUFC, 0); -+ pci_enable_wake(pdev, PCI_D3hot, 0); -+ pci_enable_wake(pdev, PCI_D3cold, 0); -+ } ++ /* Allow time for pending master requests to run */ ++ mac->ops.reset_hw(hw); + -+ e1000_release_manageability(adapter); ++ /* ++ * For parts with AMT enabled, let the firmware know ++ * that the network interface is in control ++ */ ++ if (adapter->flags & FLAG_HAS_AMT) ++ e1000_get_hw_control(adapter); + -+ /* make sure adapter isn't asleep if manageability is enabled */ -+ if (adapter->flags & FLAG_MNG_PT_ENABLED) { -+ pci_enable_wake(pdev, PCI_D3hot, 1); -+ pci_enable_wake(pdev, PCI_D3cold, 1); -+ } ++ ew32(WUC, 0); + -+ if (adapter->hw.phy.type == e1000_phy_igp_3) -+ e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); ++ if (mac->ops.init_hw(hw)) ++ e_err("Hardware Error\n"); + -+ /* 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); ++ e1000_update_mng_vlan(adapter); + -+ pci_disable_device(pdev); ++ /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ ++ ew32(VET, ETH_P_8021Q); + -+ pci_set_power_state(pdev, pci_choose_state(pdev, state)); ++ e1000_reset_adaptive_generic(hw); ++ ++ if (!hw->phy.ops.get_info) ++ return; + -+ return 0; ++ hw->phy.ops.get_info(hw); ++ ++ if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) { ++ u16 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 ++ */ ++ hw->phy.ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); ++ phy_data &= ~IGP02E1000_PM_SPD; ++ hw->phy.ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); ++ } +} + -+#ifdef CONFIG_PM -+static int e1000_resume(struct pci_dev *pdev) ++int e1000_up(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; -+ u32 err; + -+ pci_set_power_state(pdev, PCI_D0); -+ pci_restore_state(pdev); -+ err = pci_enable_device(pdev); -+ if (err) { -+ dev_err(&pdev->dev, -+ "Cannot enable PCI device from suspend\n"); -+ return err; -+ } ++ /* hardware has been reset, we need to reload some things */ ++ e1000_configure(adapter); + -+ pci_set_master(pdev); ++ clear_bit(__E1000_DOWN, &adapter->state); + -+ pci_enable_wake(pdev, PCI_D3hot, 0); -+ pci_enable_wake(pdev, PCI_D3cold, 0); ++#ifdef CONFIG_E1000E_NAPI ++ napi_enable(&adapter->napi); ++#endif ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->msix_entries) ++ e1000_configure_msix(adapter); ++#endif /* CONFIG_E1000E_MSIX */ ++ e1000_irq_enable(adapter); + -+ if (netif_running(netdev)) { -+ err = e1000_request_irq(adapter); -+ if (err) -+ return err; -+ } ++ /* fire a link change interrupt to start the watchdog */ ++ ew32(ICS, E1000_ICS_LSC); ++ return 0; ++} + -+ e1000e_power_up_phy(adapter); -+ e1000e_reset(adapter); -+ ew32(WUS, ~0); ++void e1000_down(struct e1000_adapter *adapter) ++{ ++ struct net_device *netdev = adapter->netdev; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 tctl, rctl; + -+ e1000_init_manageability(adapter); ++ /* ++ * signal that we're down so the interrupt handler does not ++ * reschedule our watchdog timer ++ */ ++ set_bit(__E1000_DOWN, &adapter->state); + -+ if (netif_running(netdev)) -+ e1000e_up(adapter); ++ /* disable receives in the hardware */ ++ rctl = er32(RCTL); ++ ew32(RCTL, rctl & ~E1000_RCTL_EN); ++ /* flush and sleep below */ + -+ netif_device_attach(netdev); ++ netif_stop_queue(netdev); + -+ /* If the controller has 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->flags & FLAG_HAS_AMT) || !e1000e_check_mng_mode(&adapter->hw)) -+ e1000_get_hw_control(adapter); ++ /* disable transmits in the hardware */ ++ tctl = er32(TCTL); ++ tctl &= ~E1000_TCTL_EN; ++ ew32(TCTL, tctl); ++ /* flush both disables and wait for them to finish */ ++ e1e_flush(); ++ msleep(10); + -+ return 0; -+} ++#ifdef CONFIG_E1000E_NAPI ++ napi_disable(&adapter->napi); +#endif + -+static void e1000_shutdown(struct pci_dev *pdev) -+{ -+ e1000_suspend(pdev, PMSG_SUSPEND); -+} ++ e1000_irq_disable(adapter); + -+#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 *netdev) -+{ -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ del_timer_sync(&adapter->watchdog_timer); ++ del_timer_sync(&adapter->phy_info_timer); + -+ disable_irq(adapter->pdev->irq); -+ e1000_intr(adapter->pdev->irq, netdev); ++ netdev->tx_queue_len = adapter->tx_queue_len; ++ netif_carrier_off(netdev); ++ adapter->link_speed = 0; ++ adapter->link_duplex = 0; + -+ e1000_clean_tx_irq(adapter); ++ e1000_reset(adapter); ++ e1000_clean_tx_ring(adapter); ++ e1000_clean_rx_ring(adapter); + -+ enable_irq(adapter->pdev->irq); ++ /* ++ * TODO: for power management, we could drop the link and ++ * pci_disable_device here. ++ */ +} -+#endif + -+/** -+ * e1000_io_error_detected - called when PCI error is detected -+ * @pdev: Pointer to PCI device -+ * @state: The current pci connection state -+ * -+ * This function is called after a PCI bus error affecting -+ * this device has been detected. -+ */ -+static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, -+ pci_channel_state_t state) ++void e1000_reinit_locked(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ -+ netif_device_detach(netdev); -+ -+ if (netif_running(netdev)) -+ e1000e_down(adapter); -+ pci_disable_device(pdev); -+ -+ /* Request a slot slot reset. */ -+ return PCI_ERS_RESULT_NEED_RESET; ++ might_sleep(); ++ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) ++ msleep(1); ++ e1000_down(adapter); ++ e1000_up(adapter); ++ clear_bit(__E1000_RESETTING, &adapter->state); +} + +/** -+ * e1000_io_slot_reset - called after the pci bus has been reset. -+ * @pdev: Pointer to PCI device ++ * e1000_sw_init - Initialize general software structures (struct e1000_adapter) ++ * @adapter: board private structure to initialize + * -+ * Restart the card from scratch, as if from a cold-boot. Implementation -+ * resembles the first-half of the e1000_resume routine. -+ */ -+static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) ++ * e1000_sw_init initializes the Adapter private data structure. ++ * Fields are initialized based on PCI device information and ++ * OS network device settings (MTU size). ++ **/ ++static int __devinit e1000_sw_init(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ struct e1000_hw *hw = &adapter->hw; ++ struct net_device *netdev = adapter->netdev; ++ s32 rc; + -+ if (pci_enable_device(pdev)) { -+ dev_err(&pdev->dev, -+ "Cannot re-enable PCI device after reset.\n"); -+ return PCI_ERS_RESULT_DISCONNECT; -+ } -+ pci_set_master(pdev); ++ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN; ++ adapter->rx_ps_bsize0 = 128; ++ adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; ++ adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + -+ pci_enable_wake(pdev, PCI_D3hot, 0); -+ pci_enable_wake(pdev, PCI_D3cold, 0); ++ /* Set various function pointers */ ++ adapter->ei->init_ops(&adapter->hw); + -+ e1000e_reset(adapter); -+ ew32(WUS, ~0); ++ rc = adapter->hw.mac.ops.init_params(&adapter->hw); ++ if (rc) ++ return rc; + -+ return PCI_ERS_RESULT_RECOVERED; -+} ++ rc = adapter->hw.nvm.ops.init_params(&adapter->hw); ++ if (rc) ++ return rc; + -+/** -+ * e1000_io_resume - called when traffic can start flowing again. -+ * @pdev: Pointer to PCI device -+ * -+ * This callback is called when the error recovery driver tells us that -+ * its OK to resume normal operation. Implementation resembles the -+ * second-half of the e1000_resume routine. -+ */ -+static void e1000_io_resume(struct pci_dev *pdev) -+{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); ++ rc = adapter->hw.phy.ops.init_params(&adapter->hw); ++ if (rc) ++ return rc; + -+ e1000_init_manageability(adapter); ++#ifdef CONFIG_E1000E_MSIX ++ e1000_set_interrupt_capability(adapter); + -+ if (netif_running(netdev)) { -+ if (e1000e_up(adapter)) { -+ dev_err(&pdev->dev, -+ "can't bring device back up after reset\n"); -+ return; -+ } -+ } ++#endif /* CONFIG_E1000E_MSIX */ ++ if (e1000_alloc_queues(adapter)) ++ return -ENOMEM; + -+ netif_device_attach(netdev); ++ spin_lock_init(&adapter->tx_queue_lock); + -+ /* If the controller has 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->flags & FLAG_HAS_AMT) || -+ !e1000e_check_mng_mode(&adapter->hw)) -+ e1000_get_hw_control(adapter); ++ /* Explicitly disable IRQ since the NIC can be in any state. */ ++ e1000_irq_disable(adapter); ++ ++ spin_lock_init(&adapter->stats_lock); + ++ set_bit(__E1000_DOWN, &adapter->state); ++ return 0; +} + -+static void e1000_print_device_info(struct e1000_adapter *adapter) ++/** ++ * e1000_intr_msi_test - Interrupt Handler ++ * @irq: interrupt number ++ * @data: pointer to a network interface device structure ++ **/ ++static irqreturn_t e1000_intr_msi_test(int irq, void *data) +{ ++ struct net_device *netdev = data; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; -+ struct net_device *netdev = adapter->netdev; ++ u32 icr = er32(ICR); + -+ /* print bus type/speed/width info */ -+ ndev_info(netdev, "(PCI Express:2.5GB/s:%s) " -+ "%02x:%02x:%02x:%02x:%02x:%02x\n", -+ /* bus width */ -+ ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : -+ "Width x1"), -+ /* MAC address */ -+ netdev->dev_addr[0], netdev->dev_addr[1], -+ netdev->dev_addr[2], netdev->dev_addr[3], -+ netdev->dev_addr[4], netdev->dev_addr[5]); -+ ndev_info(netdev, "Intel(R) PRO/%s Network Connection\n", -+ (hw->phy.type == e1000_phy_ife) -+ ? "10/100" : "1000"); ++ e_dbg("icr is %08X\n", icr); ++ if (icr & E1000_ICR_RXSEQ) { ++ adapter->flags &= ~FLAG_MSI_TEST_FAILED; ++ wmb(); ++ } ++ ++ return IRQ_HANDLED; +} + +/** -+ * e1000_probe - Device Initialization Routine -+ * @pdev: PCI device information struct -+ * @ent: entry in e1000_pci_tbl -+ * -+ * Returns 0 on success, negative on failure ++ * e1000_test_msi_interrupt - Returns 0 for successful test ++ * @adapter: board private struct + * -+ * e1000_probe initializes an adapter identified by a pci_dev structure. -+ * The OS initialization, configuring of the adapter private structure, -+ * and a hardware reset occur. ++ * code flow taken from tg3.c + **/ -+static int __devinit e1000_probe(struct pci_dev *pdev, -+ const struct pci_device_id *ent) ++static int e1000_test_msi_interrupt(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev; -+ struct e1000_adapter *adapter; -+ struct e1000_hw *hw; -+ const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; -+ unsigned long mmio_start, mmio_len; -+ unsigned long flash_start, flash_len; ++ struct net_device *netdev = adapter->netdev; ++ struct e1000_hw *hw = &adapter->hw; ++ int err; + -+ static int cards_found; -+ int i, err, pci_using_dac; -+ u16 eeprom_data = 0; -+ u16 eeprom_apme_mask = E1000_EEPROM_APME; ++ /* poll_enable hasn't been called yet, so don't need disable */ ++ /* clear any pending events */ ++ er32(ICR); + -+ err = pci_enable_device(pdev); -+ if (err) -+ return err; ++ /* free the real vector and request a test handler */ ++ e1000_free_irq(adapter); ++#ifdef CONFIG_E1000E_MSIX ++ e1000_reset_interrupt_capability(adapter); ++#endif + -+ pci_using_dac = 0; -+ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); -+ if (!err) { -+ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); -+ if (!err) -+ pci_using_dac = 1; -+ } else { -+ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); -+ if (err) { -+ err = pci_set_consistent_dma_mask(pdev, -+ DMA_32BIT_MASK); -+ if (err) { -+ dev_err(&pdev->dev, "No usable DMA " -+ "configuration, aborting\n"); -+ goto err_dma; -+ } -+ } -+ } ++ /* Assume that the test fails, if it succeeds then the test ++ * MSI irq handler will unset this flag */ ++ adapter->flags |= FLAG_MSI_TEST_FAILED; + -+ err = pci_request_regions(pdev, e1000e_driver_name); ++ err = pci_enable_msi(adapter->pdev); + if (err) -+ goto err_pci_reg; ++ goto msi_test_failed; + -+ pci_set_master(pdev); ++ err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0, ++ netdev->name, netdev); ++ if (err) { ++ pci_disable_msi(adapter->pdev); ++ goto msi_test_failed; ++ } + -+ err = -ENOMEM; -+ netdev = alloc_etherdev(sizeof(struct e1000_adapter)); -+ if (!netdev) -+ goto err_alloc_etherdev; ++ wmb(); + -+ SET_MODULE_OWNER(netdev); -+ SET_NETDEV_DEV(netdev, &pdev->dev); ++ e1000_irq_enable(adapter); + -+ pci_set_drvdata(pdev, netdev); -+ adapter = netdev_priv(netdev); -+ hw = &adapter->hw; -+ adapter->netdev = netdev; -+ adapter->pdev = pdev; -+ adapter->ei = ei; -+ adapter->pba = ei->pba; -+ adapter->flags = ei->flags; -+ adapter->hw.adapter = adapter; -+ adapter->hw.mac.type = ei->mac; -+ adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; ++ /* fire an unusual interrupt on the test handler */ ++ ew32(ICS, E1000_ICS_RXSEQ); ++ e1e_flush(); ++ msleep(50); + -+ mmio_start = pci_resource_start(pdev, 0); -+ mmio_len = pci_resource_len(pdev, 0); ++ e1000_irq_disable(adapter); + -+ err = -EIO; -+ adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); -+ if (!adapter->hw.hw_addr) -+ goto err_ioremap; ++ rmb(); + -+ if ((adapter->flags & FLAG_HAS_FLASH) && -+ (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) -+ goto err_flashmap; ++ if (adapter->flags & FLAG_MSI_TEST_FAILED) { ++#ifdef CONFIG_E1000E_MSIX ++ adapter->int_mode = E1000E_INT_MODE_LEGACY; ++#endif ++ err = -EIO; ++ e_info("MSI interrupt test failed!\n"); + } + -+ /* construct the net_device struct */ -+ netdev->open = &e1000_open; -+ netdev->stop = &e1000_close; -+ netdev->hard_start_xmit = &e1000_xmit_frame; -+ netdev->get_stats = &e1000_get_stats; -+ netdev->set_multicast_list = &e1000_set_multi; -+ netdev->set_mac_address = &e1000_set_mac; -+ netdev->change_mtu = &e1000_change_mtu; -+ netdev->do_ioctl = &e1000_ioctl; -+ e1000e_set_ethtool_ops(netdev); -+ netdev->tx_timeout = &e1000_tx_timeout; -+ netdev->watchdog_timeo = 5 * HZ; -+ netdev->poll = &e1000_clean; -+ netdev->weight = 64; -+ 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; -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ netdev->poll_controller = e1000_netpoll; ++ free_irq(adapter->pdev->irq, netdev); ++ pci_disable_msi(adapter->pdev); ++ ++ if (err == -EIO) ++ goto msi_test_failed; ++ ++ /* okay so the test worked, restore settings */ ++ e_dbg("MSI interrupt test succeeded!\n"); ++msi_test_failed: ++#ifdef CONFIG_E1000E_MSIX ++ e1000_set_interrupt_capability(adapter); ++#else ++ /* restore the original vector, even if it failed */ +#endif -+ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); ++ e1000_request_irq(adapter); ++ return err; ++} ++ ++/** ++ * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored ++ * @adapter: board private struct ++ * ++ * code flow taken from tg3.c, called with e1000 interrupts disabled. ++ **/ ++static int e1000_test_msi(struct e1000_adapter *adapter) ++{ ++ int err; ++ u16 pci_cmd; ++ ++ if (!(adapter->flags & FLAG_MSI_ENABLED)) ++ return 0; ++ ++ /* disable SERR in case the MSI write causes a master abort */ ++ pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd); ++ pci_write_config_word(adapter->pdev, PCI_COMMAND, ++ pci_cmd & ~PCI_COMMAND_SERR); + -+ netdev->mem_start = mmio_start; -+ netdev->mem_end = mmio_start + mmio_len; ++ err = e1000_test_msi_interrupt(adapter); + -+ adapter->bd_number = cards_found++; ++ /* restore previous setting of command word */ ++ pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd); + -+ /* setup adapter struct */ -+ err = e1000_sw_init(adapter); -+ if (err) -+ goto err_sw_init; ++ /* success ! */ ++ if (!err) ++ return 0; + -+ err = -EIO; ++ /* EIO means MSI test failed */ ++ if (err != -EIO) ++ return err; + -+ memcpy(&hw->mac.ops, ei->mac_ops, sizeof(hw->mac.ops)); -+ memcpy(&hw->nvm.ops, ei->nvm_ops, sizeof(hw->nvm.ops)); -+ memcpy(&hw->phy.ops, ei->phy_ops, sizeof(hw->phy.ops)); ++ /* back to INTx mode */ ++ e_warn("MSI interrupt test failed, using legacy interrupt.\n"); + -+ err = ei->get_invariants(adapter); -+ if (err) -+ goto err_hw_init; ++ e1000_free_irq(adapter); + -+ hw->mac.ops.get_bus_info(&adapter->hw); ++ err = e1000_request_irq(adapter); + -+ adapter->hw.phy.wait_for_link = 0; ++ return err; ++} + -+ /* Copper options */ -+ if (adapter->hw.media_type == e1000_media_type_copper) { -+ adapter->hw.phy.mdix = AUTO_ALL_MODES; -+ adapter->hw.phy.disable_polarity_correction = 0; -+ adapter->hw.phy.ms_type = e1000_ms_hw_default; -+ } ++/** ++ * 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); ++ struct e1000_hw *hw = &adapter->hw; ++ int err; + -+ if (e1000_check_reset_block(&adapter->hw)) -+ ndev_info(netdev, -+ "PHY reset is blocked due to SOL/IDER session.\n"); ++ /* disallow open during test */ ++ if (test_bit(__E1000_TESTING, &adapter->state)) ++ return -EBUSY; + -+ netdev->features = NETIF_F_SG | -+ NETIF_F_HW_CSUM | -+ NETIF_F_HW_VLAN_TX | -+ NETIF_F_HW_VLAN_RX; ++ /* allocate transmit descriptors */ ++ err = e1000_setup_tx_resources(adapter); ++ if (err) ++ goto err_setup_tx; + -+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) -+ netdev->features |= NETIF_F_HW_VLAN_FILTER; ++ /* allocate receive descriptors */ ++ err = e1000_setup_rx_resources(adapter); ++ if (err) ++ goto err_setup_rx; + -+ netdev->features |= NETIF_F_TSO; -+ netdev->features |= NETIF_F_TSO6; ++ e1000_power_up_phy(hw); + -+ if (pci_using_dac) -+ netdev->features |= NETIF_F_HIGHDMA; ++ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; ++ if ((adapter->hw.mng_cookie.status & ++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) ++ e1000_update_mng_vlan(adapter); + -+ /* We should not be using LLTX anymore, but we are still TX faster with -+ * it. */ -+ netdev->features |= NETIF_F_LLTX; ++ /* ++ * If AMT is enabled, let the firmware know that the network ++ * interface is now open ++ */ ++ if (adapter->flags & FLAG_HAS_AMT) ++ e1000_get_hw_control(adapter); + -+ if (e1000e_enable_mng_pass_thru(&adapter->hw)) -+ adapter->flags |= FLAG_MNG_PT_ENABLED; ++ /* ++ * before we allocate an interrupt, we must be ready to handle it. ++ * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt ++ * as soon as we call pci_request_irq, so we have to setup our ++ * clean_rx handler before we do so. ++ */ ++ e1000_configure(adapter); + -+ /* before reading the NVM, reset the controller to -+ * put the device in a known good starting state */ -+ adapter->hw.mac.ops.reset_hw(&adapter->hw); ++ err = e1000_request_irq(adapter); ++ if (err) ++ goto err_req_irq; + + /* -+ * systems with ASPM and others may see the checksum fail on the first -+ * attempt. Let's give it a few tries ++ * Work around PCIe errata with MSI interrupts causing some chipsets to ++ * ignore e1000e MSI messages, which means we need to test our MSI ++ * interrupt now + */ -+ for (i = 0;; i++) { -+ if (e1000_validate_nvm_checksum(&adapter->hw) >= 0) -+ break; -+ if (i == 2) { -+ ndev_err(netdev, "The NVM Checksum Is Not Valid\n"); -+ err = -EIO; -+ goto err_eeprom; ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->int_mode != E1000E_INT_MODE_LEGACY) ++#endif ++ { ++ err = e1000_test_msi(adapter); ++ if (err) { ++ e_err("Interrupt allocation failed\n"); ++ goto err_req_irq; + } + } + -+ /* copy the MAC address out of the NVM */ -+ if (e1000e_read_mac_addr(&adapter->hw)) -+ ndev_err(netdev, "NVM Read Error while reading MAC address\n"); ++ /* From here on the code is the same as e1000_up() */ ++ clear_bit(__E1000_DOWN, &adapter->state); + -+ memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len); -+ memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len); ++#ifdef CONFIG_E1000E_NAPI ++ napi_enable(&adapter->napi); ++#endif + -+ if (!is_valid_ether_addr(netdev->perm_addr)) { -+ ndev_err(netdev, "Invalid MAC Address: " -+ "%02x:%02x:%02x:%02x:%02x:%02x\n", -+ netdev->perm_addr[0], netdev->perm_addr[1], -+ netdev->perm_addr[2], netdev->perm_addr[3], -+ netdev->perm_addr[4], netdev->perm_addr[5]); -+ err = -EIO; -+ goto err_eeprom; -+ } ++ e1000_irq_enable(adapter); + -+ init_timer(&adapter->watchdog_timer); -+ adapter->watchdog_timer.function = &e1000_watchdog; -+ adapter->watchdog_timer.data = (unsigned long) adapter; ++ /* fire a link status change interrupt to start the watchdog */ ++ ew32(ICS, E1000_ICS_LSC); + -+ init_timer(&adapter->phy_info_timer); -+ adapter->phy_info_timer.function = &e1000_update_phy_info; -+ adapter->phy_info_timer.data = (unsigned long) adapter; ++ return 0; + -+ INIT_WORK(&adapter->reset_task, e1000_reset_task); -+ INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); ++err_req_irq: ++ e1000_release_hw_control(adapter); ++ if (!adapter->wol && hw->phy.ops.power_down) ++ hw->phy.ops.power_down(hw); ++ e1000_free_rx_resources(adapter); ++err_setup_rx: ++ e1000_free_tx_resources(adapter); ++err_setup_tx: ++ e1000_reset(adapter); + -+ e1000e_check_options(adapter); ++ return err; ++} + -+ /* Initialize link parameters. User can change them with ethtool */ -+ adapter->hw.mac.autoneg = 1; -+ adapter->hw.mac.original_fc = e1000_fc_default; -+ adapter->hw.mac.fc = e1000_fc_default; -+ adapter->hw.phy.autoneg_advertised = 0x2f; ++/** ++ * e1000_close - Disables a network interface ++ * @netdev: network interface device structure ++ * ++ * Returns 0, this is not allowed to fail ++ * ++ * The close entry point is called when an interface is de-activated ++ * by the OS. The hardware is still under the drivers control, but ++ * needs to be disabled. A global MAC reset is issued to stop the ++ * hardware, and all transmit and receive resources are freed. ++ **/ ++static int e1000_close(struct net_device *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ /* ring size defaults */ -+ adapter->rx_ring->count = 256; -+ adapter->tx_ring->count = 256; ++ WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); ++ e1000_down(adapter); ++ if (!adapter->wol && hw->phy.ops.power_down) ++ hw->phy.ops.power_down(hw); ++ e1000_free_irq(adapter); ++ ++ e1000_free_tx_resources(adapter); ++ e1000_free_rx_resources(adapter); + + /* -+ * Initial Wake on LAN setting - If APM wake is enabled in -+ * the EEPROM, enable the ACPI Magic Packet filter ++ * kill manageability vlan ID if supported, but not if a vlan with ++ * the same ID is registered on the host OS (let 8021q kill it) + */ -+ if (adapter->flags & FLAG_APME_IN_WUC) { -+ /* APME bit in EEPROM is mapped to WUC.APME */ -+ eeprom_data = er32(WUC); -+ eeprom_apme_mask = E1000_WUC_APME; -+ } else if (adapter->flags & FLAG_APME_IN_CTRL3) { -+ if (adapter->flags & FLAG_APME_CHECK_PORT_B && -+ (adapter->hw.bus.func == 1)) -+ e1000_read_nvm(&adapter->hw, -+ NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); -+ else -+ e1000_read_nvm(&adapter->hw, -+ NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); ++ if ((adapter->hw.mng_cookie.status & ++ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && ++ !(adapter->vlgrp && ++ vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id))) ++ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); ++ ++ /* ++ * If AMT is enabled, let the firmware know that the network ++ * interface is now closed ++ */ ++ if (adapter->flags & FLAG_HAS_AMT) ++ e1000_release_hw_control(adapter); ++ ++ return 0; ++} ++/** ++ * e1000_set_mac - Change the Ethernet Address of the NIC ++ * @netdev: network interface device structure ++ * @p: pointer to an address structure ++ * ++ * Returns 0 on success, negative on failure ++ **/ ++static int e1000_set_mac(struct net_device *netdev, void *p) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct sockaddr *addr = p; ++ ++ if (!is_valid_ether_addr(addr->sa_data)) ++ return -EADDRNOTAVAIL; ++ ++ memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); ++ memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len); ++ ++ adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0); ++ ++ if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) { ++ /* activate the work around */ ++ e1000_set_laa_state_82571(&adapter->hw, 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. Eventually the LAA will be in RAR[0] and ++ * RAR[14] ++ */ ++ adapter->hw.mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, ++ adapter->hw.mac.rar_entry_count - 1); + } + -+ /* fetch WoL from EEPROM */ -+ if (eeprom_data & eeprom_apme_mask) -+ adapter->eeprom_wol |= E1000_WUFC_MAG; ++ return 0; ++} ++ ++/** ++ * 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) ++{ ++ struct e1000_adapter *adapter = (struct e1000_adapter *) data; ++ if (adapter->hw.phy.ops.get_info) ++ adapter->hw.phy.ops.get_info(&adapter->hw); ++} ++ ++/** ++ * e1000_update_stats - Update the board statistics counters ++ * @adapter: board private structure ++ **/ ++void e1000_update_stats(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++#ifdef HAVE_PCI_ERS ++ struct pci_dev *pdev = adapter->pdev; ++#endif ++ unsigned long irq_flags; ++ u16 phy_tmp; ++ ++#define PHY_IDLE_ERROR_COUNT_MASK 0x00FF + + /* -+ * 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 ++ * Prevent stats update while adapter is being reset, or if the pci ++ * connection is down. + */ -+ if (!(adapter->flags & FLAG_HAS_WOL)) -+ adapter->eeprom_wol = 0; ++ if (adapter->link_speed == 0) ++ return; ++#ifdef HAVE_PCI_ERS ++ if (pci_channel_offline(pdev)) ++ return; ++#endif + -+ /* initialize the wol settings based on the eeprom settings */ -+ adapter->wol = adapter->eeprom_wol; ++ spin_lock_irqsave(&adapter->stats_lock, irq_flags); ++ ++ /* ++ * these counters are modified from e1000_adjust_tbi_stats, ++ * called from the interrupt context, so they must only ++ * be written while holding adapter->stats_lock ++ */ ++ ++ adapter->stats.crcerrs += er32(CRCERRS); ++ adapter->stats.gprc += er32(GPRC); ++ adapter->stats.gorc += er32(GORCL); ++ er32(GORCH); /* Clear gorc */ ++ adapter->stats.bprc += er32(BPRC); ++ adapter->stats.mprc += er32(MPRC); ++ adapter->stats.roc += er32(ROC); ++ ++ adapter->stats.mpc += er32(MPC); ++ adapter->stats.scc += er32(SCC); ++ adapter->stats.ecol += er32(ECOL); ++ adapter->stats.mcc += er32(MCC); ++ adapter->stats.latecol += er32(LATECOL); ++ adapter->stats.dc += er32(DC); ++ adapter->stats.xonrxc += er32(XONRXC); ++ adapter->stats.xontxc += er32(XONTXC); ++ adapter->stats.xoffrxc += er32(XOFFRXC); ++ adapter->stats.xofftxc += er32(XOFFTXC); ++ adapter->stats.gptc += er32(GPTC); ++ adapter->stats.gotc += er32(GOTCL); ++ er32(GOTCH); /* Clear gotc */ ++ adapter->stats.rnbc += er32(RNBC); ++ adapter->stats.ruc += er32(RUC); ++ ++ adapter->stats.mptc += er32(MPTC); ++ adapter->stats.bptc += er32(BPTC); ++ ++ /* used for adaptive IFS */ ++ ++ hw->mac.tx_packet_delta = er32(TPT); ++ adapter->stats.tpt += hw->mac.tx_packet_delta; ++ hw->mac.collision_delta = er32(COLC); ++ adapter->stats.colc += hw->mac.collision_delta; + -+ /* reset the hardware with the new settings */ -+ e1000e_reset(adapter); ++ adapter->stats.algnerrc += er32(ALGNERRC); ++ adapter->stats.rxerrc += er32(RXERRC); ++ if (hw->mac.type != e1000_82574) ++ adapter->stats.tncrs += er32(TNCRS); ++ adapter->stats.cexterr += er32(CEXTERR); ++ adapter->stats.tsctc += er32(TSCTC); ++ adapter->stats.tsctfc += er32(TSCTFC); + -+ /* If the controller has 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->flags & FLAG_HAS_AMT) || -+ !e1000e_check_mng_mode(&adapter->hw)) -+ e1000_get_hw_control(adapter); ++ /* Fill out the OS statistics structure */ ++ adapter->net_stats.multicast = adapter->stats.mprc; ++ adapter->net_stats.collisions = adapter->stats.colc; + -+ /* tell the stack to leave us alone until e1000_open() is called */ -+ netif_carrier_off(netdev); -+ netif_stop_queue(netdev); -+ netif_poll_disable(netdev); ++ /* Rx Errors */ + -+ strcpy(netdev->name, "eth%d"); -+ err = register_netdev(netdev); -+ if (err) -+ goto err_register; ++ /* ++ * 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.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_missed_errors = adapter->stats.mpc; + -+ e1000_print_device_info(adapter); ++ /* Tx Errors */ ++ adapter->net_stats.tx_errors = adapter->stats.ecol + ++ adapter->stats.latecol; ++ adapter->net_stats.tx_aborted_errors = adapter->stats.ecol; ++ adapter->net_stats.tx_window_errors = adapter->stats.latecol; ++ adapter->net_stats.tx_carrier_errors = adapter->stats.tncrs; + -+ return 0; ++ /* Tx Dropped needs to be maintained elsewhere */ + -+err_register: -+err_hw_init: -+ e1000_release_hw_control(adapter); -+err_eeprom: -+ if (!e1000_check_reset_block(&adapter->hw)) -+ e1000_phy_hw_reset(&adapter->hw); ++ /* Phy Stats */ ++ if (hw->phy.media_type == e1000_media_type_copper) { ++ if ((adapter->link_speed == SPEED_1000) && ++ (!hw->phy.ops.read_reg(hw, PHY_1000T_STATUS, &phy_tmp))) { ++ phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK; ++ adapter->phy_stats.idle_errors += phy_tmp; ++ } ++ } + -+ if (adapter->hw.flash_address) -+ iounmap(adapter->hw.flash_address); ++ /* Management Stats */ ++ adapter->stats.mgptc += er32(MGTPTC); ++ adapter->stats.mgprc += er32(MGTPRC); ++ adapter->stats.mgpdc += er32(MGTPDC); + -+err_flashmap: -+ kfree(adapter->tx_ring); -+ kfree(adapter->rx_ring); -+err_sw_init: -+ iounmap(adapter->hw.hw_addr); -+err_ioremap: -+ free_netdev(netdev); -+err_alloc_etherdev: -+ pci_release_regions(pdev); -+err_pci_reg: -+err_dma: -+ pci_disable_device(pdev); -+ return err; ++ spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); +} + ++#ifdef SIOCGMIIPHY +/** -+ * e1000_remove - Device Removal Routine -+ * @pdev: PCI device information struct -+ * -+ * e1000_remove is called by the PCI subsystem to alert the driver -+ * that it should release a PCI device. The could be caused by a -+ * Hot-Plug event, or because the driver is going to be removed from -+ * memory. ++ * e1000_phy_read_status - Update the PHY register status snapshot ++ * @adapter: board private structure + **/ -+static void __devexit e1000_remove(struct pci_dev *pdev) ++static void e1000_phy_read_status(struct e1000_adapter *adapter) +{ -+ struct net_device *netdev = pci_get_drvdata(pdev); -+ struct e1000_adapter *adapter = netdev_priv(netdev); -+ -+ /* flush_scheduled work may reschedule our watchdog task, so -+ * explicitly disable watchdog tasks from being rescheduled */ -+ set_bit(__E1000_DOWN, &adapter->state); -+ del_timer_sync(&adapter->watchdog_timer); -+ del_timer_sync(&adapter->phy_info_timer); -+ -+ flush_scheduled_work(); -+ -+ e1000_release_manageability(adapter); -+ -+ /* 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); ++ struct e1000_hw *hw = &adapter->hw; ++ struct e1000_phy_regs *phy = &adapter->phy_regs; ++ int ret_val; ++ unsigned long irq_flags; + -+ unregister_netdev(netdev); + -+ if (!e1000_check_reset_block(&adapter->hw)) -+ e1000_phy_hw_reset(&adapter->hw); ++ spin_lock_irqsave(&adapter->stats_lock, irq_flags); + -+ kfree(adapter->tx_ring); -+ kfree(adapter->rx_ring); ++ if ((er32(STATUS) & E1000_STATUS_LU) && ++ (adapter->hw.phy.media_type == e1000_media_type_copper)) { ++ ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy->bmcr); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_STATUS, &phy->bmsr); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_AUTONEG_ADV, ++ &phy->advertise); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_LP_ABILITY, &phy->lpa); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_AUTONEG_EXP, ++ &phy->expansion); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_1000T_CTRL, ++ &phy->ctrl1000); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_1000T_STATUS, ++ &phy->stat1000); ++ ret_val |= hw->phy.ops.read_reg(hw, PHY_EXT_STATUS, ++ &phy->estatus); ++ if (ret_val) ++ e_warn("Error reading PHY register\n"); ++ } else { ++ /* ++ * Do not read PHY registers if link is not up ++ * Set values to typical power-on defaults ++ */ ++ phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX); ++ phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL | ++ BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE | ++ BMSR_ERCAP); ++ phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP | ++ ADVERTISE_ALL | ADVERTISE_CSMA); ++ phy->lpa = 0; ++ phy->expansion = EXPANSION_ENABLENPAGE; ++ phy->ctrl1000 = ADVERTISE_1000FULL; ++ phy->stat1000 = 0; ++ phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF); ++ } + -+ iounmap(adapter->hw.hw_addr); -+ if (adapter->hw.flash_address) -+ iounmap(adapter->hw.flash_address); -+ pci_release_regions(pdev); ++ spin_unlock_irqrestore(&adapter->stats_lock, irq_flags); ++} + -+ free_netdev(netdev); ++#endif /* SIOCGMIIPHY */ ++static void e1000_print_link_info(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl = er32(CTRL); + -+ pci_disable_device(pdev); ++ e_info("Link is Up %d Mbps %s, Flow Control: %s\n", ++ adapter->link_speed, ++ (adapter->link_duplex == FULL_DUPLEX) ? ++ "Full Duplex" : "Half Duplex", ++ ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ? ++ "RX/TX" : ++ ((ctrl & E1000_CTRL_RFCE) ? "RX" : ++ ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); +} + -+/* PCI Error Recovery (ERS) */ -+static struct pci_error_handlers e1000_err_handler = { -+ .error_detected = e1000_io_error_detected, -+ .slot_reset = e1000_io_slot_reset, -+ .resume = e1000_io_resume, -+}; ++static bool e1000_has_link(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ bool link_active = 0; ++ s32 ret_val = 0; + -+static struct pci_device_id e1000_pci_tbl[] = { + /* -+ * Support for 82571/2/3, es2lan and ich8 will be phased in -+ * stepwise. -+ -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT), -+ board_80003es2lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT), -+ board_80003es2lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT), -+ board_80003es2lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT), -+ board_80003es2lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan }, -+ */ ++ * get_link_status is set on LSC (link status) interrupt or ++ * Rx sequence error interrupt. get_link_status will stay ++ * false until the check_for_link establishes link ++ * for copper adapters ONLY ++ */ ++ switch (hw->phy.media_type) { ++ case e1000_media_type_copper: ++ if (hw->mac.get_link_status) { ++ ret_val = hw->mac.ops.check_for_link(hw); ++ link_active = !hw->mac.get_link_status; ++ } else { ++ link_active = 1; ++ } ++ break; ++ case e1000_media_type_fiber: ++ ret_val = hw->mac.ops.check_for_link(hw); ++ link_active = !!(er32(STATUS) & E1000_STATUS_LU); ++ break; ++ case e1000_media_type_internal_serdes: ++ ret_val = hw->mac.ops.check_for_link(hw); ++ link_active = adapter->hw.mac.serdes_has_link; ++ break; ++ default: ++ case e1000_media_type_unknown: ++ break; ++ } + -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan }, -+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan }, ++ if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) && ++ (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) { ++ /* See e1000_kmrn_lock_loss_workaround_ich8lan() */ ++ e_info("Gigabit has been disabled, downgrading speed\n"); ++ } + -+ { } /* terminate list */ -+}; -+MODULE_DEVICE_TABLE(pci, e1000_pci_tbl); ++ return link_active; ++} + -+/* PCI Device API Driver */ -+static struct pci_driver e1000_driver = { -+ .name = e1000e_driver_name, -+ .id_table = e1000_pci_tbl, -+ .probe = e1000_probe, -+ .remove = __devexit_p(e1000_remove), -+#ifdef CONFIG_PM -+ /* Power Managment Hooks */ -+ .suspend = e1000_suspend, -+ .resume = e1000_resume, -+#endif -+ .shutdown = e1000_shutdown, -+ .err_handler = &e1000_err_handler -+}; ++static void e1000e_enable_receives(struct e1000_adapter *adapter) ++{ ++ /* make sure the receive unit is started */ ++ if ((adapter->flags & FLAG_RX_NEEDS_RESTART) && ++ (adapter->flags & FLAG_RX_RESTART_NOW)) { ++ struct e1000_hw *hw = &adapter->hw; ++ u32 rctl = er32(RCTL); ++ ew32(RCTL, rctl | E1000_RCTL_EN); ++ adapter->flags &= ~FLAG_RX_RESTART_NOW; ++ } ++} + +/** -+ * e1000_init_module - Driver Registration Routine -+ * -+ * e1000_init_module is the first routine called when the driver is -+ * loaded. All it does is register with the PCI subsystem. ++ * e1000_watchdog - Timer Call-back ++ * @data: pointer to adapter cast into an unsigned long + **/ -+static int __init e1000_init_module(void) ++static void e1000_watchdog(unsigned long data) +{ -+ int ret; -+ printk(KERN_INFO "Intel(R) PRO/1000 Network Driver - %s\n", -+ e1000e_driver_version); -+ printk(KERN_INFO "Copyright (c) 1999-2007 Intel Corporation.\n"); -+ ret = pci_register_driver(&e1000_driver); ++ struct e1000_adapter *adapter = (struct e1000_adapter *) data; + -+ return ret; ++ /* Do the rest outside of interrupt context */ ++ schedule_work(&adapter->watchdog_task); ++ ++ /* TODO: make this use queue_delayed_work() */ +} -+module_init(e1000_init_module); + -+/** -+ * e1000_exit_module - Driver Exit Cleanup Routine -+ * -+ * e1000_exit_module is called just before the driver is removed -+ * from memory. -+ **/ -+static void __exit e1000_exit_module(void) ++static void e1000_watchdog_task(struct work_struct *work) +{ -+ pci_unregister_driver(&e1000_driver); -+} -+module_exit(e1000_exit_module); ++ struct e1000_adapter *adapter = container_of(work, ++ struct e1000_adapter, watchdog_task); ++ struct net_device *netdev = adapter->netdev; ++ struct e1000_mac_info *mac = &adapter->hw.mac; ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_hw *hw = &adapter->hw; ++ u32 link, tctl; ++ int tx_pending = 0; ++ unsigned long timer_val; + ++ link = e1000_has_link(adapter); ++ if ((netif_carrier_ok(netdev)) && link) { ++ e1000e_enable_receives(adapter); ++ goto link_up; ++ } + -+MODULE_AUTHOR("Intel Corporation, "); -+MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver"); -+MODULE_LICENSE("GPL"); -+MODULE_VERSION(DRV_VERSION); ++ if ((e1000_enable_tx_pkt_filtering_generic(hw)) && ++ (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id)) ++ e1000_update_mng_vlan(adapter); + -+/* e1000_main.c */ -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/param.c linux-2.6.22-10/drivers/net/e1000e/param.c ---- linux-2.6.22-0/drivers/net/e1000e/param.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/param.c 2007-11-21 13:55:28.000000000 -0500 -@@ -0,0 +1,382 @@ -+/******************************************************************************* ++ if (link) { ++ if (!netif_carrier_ok(netdev)) { ++ bool txb2b = 1; ++#ifdef SIOCGMIIPHY ++ /* update snapshot of PHY registers on LSC */ ++ e1000_phy_read_status(adapter); ++#endif ++ mac->ops.get_link_up_info(&adapter->hw, ++ &adapter->link_speed, ++ &adapter->link_duplex); ++ e1000_print_link_info(adapter); + -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. ++ /* ++ * On supported PHYs, check for duplex mismatch only ++ * if link has autonegotiated at 10/100 half ++ */ ++ if ((hw->phy.type == e1000_phy_igp_3 || ++ hw->phy.type == e1000_phy_bm) && ++ (hw->mac.autoneg == TRUE) && ++ (adapter->link_speed == SPEED_10 || ++ adapter->link_speed == SPEED_100) && ++ (adapter->link_duplex == HALF_DUPLEX)) { ++ u16 autoneg_exp; ++ ++ hw->phy.ops.read_reg(hw, PHY_AUTONEG_EXP, ++ &autoneg_exp); ++ ++ if (!(autoneg_exp & NWAY_ER_LP_NWAY_CAPS)) ++ e_info("Autonegotiated half duplex but" ++ " link partner cannot autoneg. " ++ " Try forcing full duplex if " ++ "link gets many collisions."); ++ } + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ /* ++ * 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 = 16; ++ break; ++ case SPEED_100: ++ txb2b = 0; ++ netdev->tx_queue_len = 100; ++ /* maybe add some timeout factor ? */ ++ break; ++ } + -+ This program is distributed in the hope 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. ++ /* ++ * workaround: re-program speed mode bit after ++ * link-up event ++ */ ++ if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) && ++ !txb2b) { ++ u32 tarc0; ++ tarc0 = er32(TARC(0)); ++ tarc0 &= ~SPEED_MODE_BIT; ++ ew32(TARC(0), tarc0); ++ } + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++#ifdef NETIF_F_TSO ++ /* ++ * disable TSO for pcie and 10/100 speeds, to avoid ++ * some hardware issues ++ */ ++ if (!(adapter->flags & FLAG_TSO_FORCE)) { ++ switch (adapter->link_speed) { ++ case SPEED_10: ++ case SPEED_100: ++ e_info("10/100 speed: disabling TSO\n"); ++ netdev->features &= ~NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ netdev->features &= ~NETIF_F_TSO6; ++#endif ++ break; ++ case SPEED_1000: ++ netdev->features |= NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ netdev->features |= NETIF_F_TSO6; ++#endif ++ break; ++ default: ++ /* oops */ ++ break; ++ } ++ } ++#endif + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++ /* ++ * enable transmits in the hardware, need to do this ++ * after setting TARC(0) ++ */ ++ tctl = er32(TCTL); ++ tctl |= E1000_TCTL_EN; ++ ew32(TCTL, tctl); + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ netif_carrier_on(netdev); ++ netif_wake_queue(netdev); ++ } ++ } else { ++ if (netif_carrier_ok(netdev)) { ++ adapter->link_speed = 0; ++ adapter->link_duplex = 0; ++ e_info("Link is Down\n"); ++ netif_carrier_off(netdev); ++ netif_stop_queue(netdev); + -+*******************************************************************************/ ++ if (adapter->flags & FLAG_RX_NEEDS_RESTART) ++ schedule_work(&adapter->reset_task); ++ } ++ } + -+#include ++link_up: ++ e1000_update_stats(adapter); + -+#include "e1000.h" ++ mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; ++ adapter->tpt_old = adapter->stats.tpt; ++ mac->collision_delta = adapter->stats.colc - adapter->colc_old; ++ adapter->colc_old = adapter->stats.colc; + -+/* This is the only thing that needs to be changed to adjust the -+ * maximum number of ports that the driver can manage. -+ */ ++ adapter->gorc = adapter->stats.gorc - adapter->gorc_old; ++ adapter->gorc_old = adapter->stats.gorc; ++ adapter->gotc = adapter->stats.gotc - adapter->gotc_old; ++ adapter->gotc_old = adapter->stats.gotc; + -+#define E1000_MAX_NIC 32 ++ e1000_update_adaptive_generic(&adapter->hw); + -+#define OPTION_UNSET -1 -+#define OPTION_DISABLED 0 -+#define OPTION_ENABLED 1 ++ if (!netif_carrier_ok(netdev)) { ++ tx_pending = (e1000_desc_unused(tx_ring) + 1 < ++ tx_ring->count); ++ if (tx_pending) { ++ /* ++ * 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). ++ */ ++ adapter->tx_timeout_count++; ++ schedule_work(&adapter->reset_task); ++ } ++ } + -+#define COPYBREAK_DEFAULT 256 -+unsigned int copybreak = COPYBREAK_DEFAULT; -+module_param(copybreak, uint, 0644); -+MODULE_PARM_DESC(copybreak, -+ "Maximum size of packet that is copied to a new buffer on receive"); ++ /* Cause software interrupt to ensure Rx ring is cleaned */ ++#ifdef CONFIG_E1000E_MSIX ++ if (adapter->msix_entries) ++ ew32(ICS, adapter->rx_ring->ims_val); ++ else ++#endif ++ ew32(ICS, E1000_ICS_RXDMT0); + -+/* 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). -+ */ ++ /* Force detection of hung controller every watchdog period */ ++ adapter->detect_tx_hung = 1; + -+#define E1000_PARAM_INIT { [0 ... E1000_MAX_NIC] = OPTION_UNSET } -+#define E1000_PARAM(X, desc) \ -+ static int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ -+ static int num_##X; \ -+ module_param_array_named(X, X, int, &num_##X, 0); \ -+ MODULE_PARM_DESC(X, desc); ++ /* ++ * With 82571 controllers, LAA may be overwritten due to controller ++ * reset from the other port. Set the appropriate LAA in RAR[0] ++ */ ++ if (e1000_get_laa_state_82571(hw)) ++ hw->mac.ops.rar_set(hw, adapter->hw.mac.addr, 0); + ++ /* Reset the timer */ ++ if (!test_bit(__E1000_DOWN, &adapter->state)) { ++ timer_val = jiffies + usecs_to_jiffies(adapter->stats_freq_us); ++ if (adapter->stats_freq_us > 1000000) ++ timer_val = round_jiffies(timer_val); ++ mod_timer(&adapter->watchdog_timer, timer_val); ++ } ++} + -+/* Transmit Interrupt Delay in units of 1.024 microseconds -+ * Tx interrupt delay needs to typically be set to something non zero -+ * -+ * Valid Range: 0-65535 -+ */ -+E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay"); -+#define DEFAULT_TIDV 8 -+#define MAX_TXDELAY 0xFFFF -+#define MIN_TXDELAY 0 ++#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 + -+/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds -+ * -+ * Valid Range: 0-65535 -+ */ -+E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); -+#define DEFAULT_TADV 32 -+#define MAX_TXABSDELAY 0xFFFF -+#define MIN_TXABSDELAY 0 ++static int e1000_tso(struct e1000_adapter *adapter, ++ struct sk_buff *skb) ++{ ++#ifdef NETIF_F_TSO ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_context_desc *context_desc; ++ struct e1000_buffer *buffer_info; ++ unsigned int i; ++ u32 cmd_length = 0; ++ u16 ipcse = 0, tucse, mss; ++ u8 ipcss, ipcso, tucss, tucso, hdr_len; ++ int err; + -+/* Receive Interrupt Delay in units of 1.024 microseconds -+ * hardware will likely hang if you set this to anything but zero. -+ * -+ * Valid Range: 0-65535 -+ */ -+E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); -+#define DEFAULT_RDTR 0 -+#define MAX_RXDELAY 0xFFFF -+#define MIN_RXDELAY 0 ++ if (!skb_is_gso(skb)) ++ return 0; + -+/* Receive Absolute Interrupt Delay in units of 1.024 microseconds -+ * -+ * Valid Range: 0-65535 -+ */ -+E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); -+#define DEFAULT_RADV 8 -+#define MAX_RXABSDELAY 0xFFFF -+#define MIN_RXABSDELAY 0 ++ if (skb_header_cloned(skb)) { ++ err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); ++ if (err) ++ return err; ++ } + -+/* Interrupt Throttle Rate (interrupts/sec) -+ * -+ * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) -+ */ -+E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); -+#define DEFAULT_ITR 3 -+#define MAX_ITR 100000 -+#define MIN_ITR 100 ++ hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb); ++ mss = skb_shinfo(skb)->gso_size; ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *iph = ip_hdr(skb); ++ iph->tot_len = 0; ++ iph->check = 0; ++ tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, ++ iph->daddr, 0, ++ IPPROTO_TCP, ++ 0); ++ cmd_length = E1000_TXD_CMD_IP; ++ ipcse = skb_transport_offset(skb) - 1; ++#ifdef NETIF_F_TSO6 ++ } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { ++ ipv6_hdr(skb)->payload_len = 0; ++ tcp_hdr(skb)->check = ++ ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, ++ &ipv6_hdr(skb)->daddr, ++ 0, IPPROTO_TCP, 0); ++ ipcse = 0; ++#endif ++ } ++ ipcss = skb_network_offset(skb); ++ ipcso = (void *)&(ip_hdr(skb)->check) - (void *)skb->data; ++ tucss = skb_transport_offset(skb); ++ tucso = (void *)&(tcp_hdr(skb)->check) - (void *)skb->data; ++ tucse = 0; + -+/* Enable Smart Power Down of the PHY -+ * -+ * Valid Range: 0, 1 -+ * -+ * Default Value: 0 (disabled) -+ */ -+E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); ++ cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | ++ E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); + -+/* Enable Kumeran Lock Loss workaround -+ * -+ * Valid Range: 0, 1 -+ * -+ * Default Value: 1 (enabled) -+ */ -+E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); ++ 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; ++ context_desc->lower_setup.ip_fields.ipcse = cpu_to_le16(ipcse); ++ context_desc->upper_setup.tcp_fields.tucss = tucss; ++ context_desc->upper_setup.tcp_fields.tucso = tucso; ++ 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(cmd_length); ++ ++ buffer_info->time_stamp = jiffies; ++ buffer_info->next_to_watch = i; ++ ++ i++; ++ if (i == tx_ring->count) ++ i = 0; ++ tx_ring->next_to_use = i; + -+struct e1000_option { -+ enum { enable_option, range_option, list_option } type; -+ char *name; -+ char *err; -+ int def; -+ union { -+ struct { /* range_option info */ -+ int min; -+ int max; -+ } r; -+ struct { /* list_option info */ -+ int nr; -+ struct e1000_opt_list { int i; char *str; } *p; -+ } l; -+ } arg; -+}; ++ return 1; ++#else ++ return 0; ++#endif ++} + -+static int __devinit e1000_validate_option(int *value, -+ struct e1000_option *opt, -+ struct e1000_adapter *adapter) ++static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) +{ -+ if (*value == OPTION_UNSET) { -+ *value = opt->def; ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_context_desc *context_desc; ++ struct e1000_buffer *buffer_info; ++ unsigned int i; ++ u8 css; ++ u32 cmd_len = E1000_TXD_CMD_DEXT; ++ ++ if (skb->ip_summed != CHECKSUM_PARTIAL) + return 0; -+ } + -+ switch (opt->type) { -+ case enable_option: -+ switch (*value) { -+ case OPTION_ENABLED: -+ ndev_info(adapter->netdev, "%s Enabled\n", opt->name); -+ return 0; -+ case OPTION_DISABLED: -+ ndev_info(adapter->netdev, "%s Disabled\n", opt->name); -+ return 0; -+ } -+ break; -+ case range_option: -+ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { -+ ndev_info(adapter->netdev, -+ "%s set to %i\n", opt->name, *value); -+ return 0; -+ } ++ switch (skb->protocol) { ++ case __constant_htons(ETH_P_IP): ++ if (ip_hdr(skb)->protocol == IPPROTO_TCP) ++ cmd_len |= E1000_TXD_CMD_TCP; + break; -+ case list_option: { -+ int i; -+ struct e1000_opt_list *ent; -+ -+ for (i = 0; i < opt->arg.l.nr; i++) { -+ ent = &opt->arg.l.p[i]; -+ if (*value == ent->i) { -+ if (ent->str[0] != '\0') -+ ndev_info(adapter->netdev, "%s\n", -+ ent->str); -+ return 0; -+ } -+ } -+ } ++ case __constant_htons(ETH_P_IPV6): ++ /* XXX not handling all IPV6 headers */ ++ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) ++ cmd_len |= E1000_TXD_CMD_TCP; + break; + default: -+ BUG(); ++ if (unlikely(net_ratelimit())) ++ e_warn("checksum_partial proto=%x!\n", skb->protocol); ++ break; + } + -+ ndev_info(adapter->netdev, "Invalid %s value specified (%i) %s\n", -+ opt->name, *value, opt->err); -+ *value = opt->def; -+ return -1; ++ css = skb_transport_offset(skb); ++ ++ i = tx_ring->next_to_use; ++ buffer_info = &tx_ring->buffer_info[i]; ++ context_desc = E1000_CONTEXT_DESC(*tx_ring, i); ++ ++ context_desc->lower_setup.ip_config = 0; ++ context_desc->upper_setup.tcp_fields.tucss = css; ++ context_desc->upper_setup.tcp_fields.tucso = css + skb->csum_offset; ++ context_desc->upper_setup.tcp_fields.tucse = 0; ++ context_desc->tcp_seg_setup.data = 0; ++ context_desc->cmd_and_length = cpu_to_le32(cmd_len); ++ ++ buffer_info->time_stamp = jiffies; ++ buffer_info->next_to_watch = i; ++ ++ i++; ++ if (i == tx_ring->count) ++ i = 0; ++ tx_ring->next_to_use = i; ++ ++ return 1; +} + -+/** -+ * e1000e_check_options - Range Checking for Command Line Parameters -+ * @adapter: board private structure -+ * -+ * This routine checks all command line parameters for valid user -+ * input. If an invalid value is given, or if no user specified -+ * value exists, a default value is used. The final value is stored -+ * in a variable in the adapter structure. -+ **/ -+void __devinit e1000e_check_options(struct e1000_adapter *adapter) ++#define E1000_MAX_PER_TXD 8192 ++#define E1000_MAX_TXD_PWR 12 ++ ++static 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) +{ -+ struct e1000_hw *hw = &adapter->hw; -+ struct net_device *netdev = adapter->netdev; -+ int bd = adapter->bd_number; ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct pci_dev *pdev = adapter->pdev; ++ struct e1000_buffer *buffer_info; ++ unsigned int len = skb->len - skb->data_len; ++ unsigned int offset = 0, size, count = 0, i; ++ unsigned int f; + -+ if (bd >= E1000_MAX_NIC) { -+ ndev_notice(netdev, -+ "Warning: no configuration for board #%i\n", bd); -+ ndev_notice(netdev, "Using defaults for all values\n"); -+ } ++ i = tx_ring->next_to_use; + -+ { /* Transmit Interrupt Delay */ -+ struct e1000_option opt = { -+ .type = range_option, -+ .name = "Transmit Interrupt Delay", -+ .err = "using default of " -+ __MODULE_STRING(DEFAULT_TIDV), -+ .def = DEFAULT_TIDV, -+ .arg = { .r = { .min = MIN_TXDELAY, -+ .max = MAX_TXDELAY } } -+ }; ++ while (len) { ++ buffer_info = &tx_ring->buffer_info[i]; ++ size = min(len, max_per_txd); + -+ if (num_TxIntDelay > bd) { -+ adapter->tx_int_delay = TxIntDelay[bd]; -+ e1000_validate_option(&adapter->tx_int_delay, &opt, -+ adapter); -+ } else { -+ adapter->tx_int_delay = opt.def; ++ buffer_info->length = size; ++ /* set time_stamp *before* dma to help avoid a possible race */ ++ buffer_info->time_stamp = jiffies; ++ buffer_info->dma = ++ pci_map_single(adapter->pdev, ++ skb->data + offset, ++ size, ++ PCI_DMA_TODEVICE); ++ if (pci_dma_mapping_error(pdev, buffer_info->dma)) { ++ dev_err(&pdev->dev, "TX DMA map failed\n"); ++ adapter->tx_dma_failed++; ++ return -1; + } -+ } -+ { /* Transmit Absolute Interrupt Delay */ -+ struct e1000_option opt = { -+ .type = range_option, -+ .name = "Transmit Absolute Interrupt Delay", -+ .err = "using default of " -+ __MODULE_STRING(DEFAULT_TADV), -+ .def = DEFAULT_TADV, -+ .arg = { .r = { .min = MIN_TXABSDELAY, -+ .max = MAX_TXABSDELAY } } -+ }; ++ buffer_info->next_to_watch = i; + -+ if (num_TxAbsIntDelay > bd) { -+ adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; -+ e1000_validate_option(&adapter->tx_abs_int_delay, &opt, -+ adapter); -+ } else { -+ adapter->tx_abs_int_delay = opt.def; -+ } ++ len -= size; ++ offset += size; ++ count++; ++ i++; ++ if (i == tx_ring->count) ++ i = 0; + } -+ { /* Receive Interrupt Delay */ -+ struct e1000_option opt = { -+ .type = range_option, -+ .name = "Receive Interrupt Delay", -+ .err = "using default of " -+ __MODULE_STRING(DEFAULT_RDTR), -+ .def = DEFAULT_RDTR, -+ .arg = { .r = { .min = MIN_RXDELAY, -+ .max = MAX_RXDELAY } } -+ }; + -+ /* modify min and default if 82573 for slow ping w/a, -+ * a value greater than 8 needs to be set for RDTR */ -+ if (adapter->flags & FLAG_HAS_ASPM) { -+ opt.def = 32; -+ opt.arg.r.min = 8; -+ } ++ for (f = 0; f < nr_frags; f++) { ++ struct skb_frag_struct *frag; + -+ if (num_RxIntDelay > bd) { -+ adapter->rx_int_delay = RxIntDelay[bd]; -+ e1000_validate_option(&adapter->rx_int_delay, &opt, -+ adapter); -+ } else { -+ adapter->rx_int_delay = opt.def; -+ } -+ } -+ { /* Receive Absolute Interrupt Delay */ -+ struct e1000_option opt = { -+ .type = range_option, -+ .name = "Receive Absolute Interrupt Delay", -+ .err = "using default of " -+ __MODULE_STRING(DEFAULT_RADV), -+ .def = DEFAULT_RADV, -+ .arg = { .r = { .min = MIN_RXABSDELAY, -+ .max = MAX_RXABSDELAY } } -+ }; ++ frag = &skb_shinfo(skb)->frags[f]; ++ len = frag->size; ++ offset = frag->page_offset; + -+ if (num_RxAbsIntDelay > bd) { -+ adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; -+ e1000_validate_option(&adapter->rx_abs_int_delay, &opt, -+ adapter); -+ } else { -+ adapter->rx_abs_int_delay = opt.def; -+ } -+ } -+ { /* Interrupt Throttling Rate */ -+ struct e1000_option opt = { -+ .type = range_option, -+ .name = "Interrupt Throttling Rate (ints/sec)", -+ .err = "using default of " -+ __MODULE_STRING(DEFAULT_ITR), -+ .def = DEFAULT_ITR, -+ .arg = { .r = { .min = MIN_ITR, -+ .max = MAX_ITR } } -+ }; ++ while (len) { ++ buffer_info = &tx_ring->buffer_info[i]; ++ size = min(len, max_per_txd); + -+ if (num_InterruptThrottleRate > bd) { -+ adapter->itr = InterruptThrottleRate[bd]; -+ switch (adapter->itr) { -+ case 0: -+ ndev_info(netdev, "%s turned off\n", -+ opt.name); -+ break; -+ case 1: -+ ndev_info(netdev, -+ "%s set to dynamic mode\n", -+ opt.name); -+ adapter->itr_setting = adapter->itr; -+ adapter->itr = 20000; -+ break; -+ case 3: -+ ndev_info(netdev, -+ "%s set to dynamic conservative mode\n", -+ opt.name); -+ adapter->itr_setting = adapter->itr; -+ adapter->itr = 20000; -+ break; -+ default: -+ e1000_validate_option(&adapter->itr, &opt, -+ adapter); -+ /* -+ * save the setting, because the dynamic bits -+ * change itr. clear the lower two bits -+ * because they are used as control -+ */ -+ adapter->itr_setting = adapter->itr & ~3; -+ break; ++ buffer_info->length = size; ++ buffer_info->time_stamp = jiffies; ++ buffer_info->dma = ++ pci_map_page(adapter->pdev, ++ frag->page, ++ offset, ++ size, ++ PCI_DMA_TODEVICE); ++ if (pci_dma_mapping_error(pdev, buffer_info->dma)) { ++ dev_err(&adapter->pdev->dev, ++ "TX DMA page map failed\n"); ++ adapter->tx_dma_failed++; ++ return -1; + } -+ } else { -+ adapter->itr_setting = opt.def; -+ adapter->itr = 20000; -+ } -+ } -+ { /* Smart Power Down */ -+ struct e1000_option opt = { -+ .type = enable_option, -+ .name = "PHY Smart Power Down", -+ .err = "defaulting to Disabled", -+ .def = OPTION_DISABLED -+ }; + -+ if (num_SmartPowerDownEnable > bd) { -+ int spd = SmartPowerDownEnable[bd]; -+ e1000_validate_option(&spd, &opt, adapter); -+ if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) -+ && spd) -+ adapter->flags |= FLAG_SMART_POWER_DOWN; -+ } -+ } -+ { /* Kumeran Lock Loss Workaround */ -+ struct e1000_option opt = { -+ .type = enable_option, -+ .name = "Kumeran Lock Loss Workaround", -+ .err = "defaulting to Enabled", -+ .def = OPTION_ENABLED -+ }; ++ buffer_info->next_to_watch = i; + -+ if (num_KumeranLockLoss > bd) { -+ int kmrn_lock_loss = KumeranLockLoss[bd]; -+ e1000_validate_option(&kmrn_lock_loss, &opt, adapter); -+ if (hw->mac.type == e1000_ich8lan) -+ e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, -+ kmrn_lock_loss); -+ } else { -+ if (hw->mac.type == e1000_ich8lan) -+ e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, -+ opt.def); ++ len -= size; ++ offset += size; ++ count++; ++ ++ i++; ++ if (i == tx_ring->count) ++ i = 0; + } + } -+} -diff -Nurp linux-2.6.22-0/drivers/net/e1000e/phy.c linux-2.6.22-10/drivers/net/e1000e/phy.c ---- linux-2.6.22-0/drivers/net/e1000e/phy.c 1969-12-31 19:00:00.000000000 -0500 -+++ linux-2.6.22-10/drivers/net/e1000e/phy.c 2007-11-21 13:55:36.000000000 -0500 -@@ -0,0 +1,1773 @@ -+/******************************************************************************* -+ -+ Intel PRO/1000 Linux driver -+ Copyright(c) 1999 - 2007 Intel Corporation. + -+ This program is free software; you can redistribute it and/or modify it -+ under the terms and conditions of the GNU General Public License, -+ version 2, as published by the Free Software Foundation. ++ if (i == 0) ++ i = tx_ring->count - 1; ++ else ++ i--; + -+ This program is distributed in the hope 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. ++ tx_ring->buffer_info[i].skb = skb; ++ tx_ring->buffer_info[first].next_to_watch = i; + -+ 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., -+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ return count; ++} + -+ The full GNU General Public License is included in this distribution in -+ the file called "COPYING". ++static void e1000_tx_queue(struct e1000_adapter *adapter, ++ int tx_flags, int count) ++{ ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ struct e1000_tx_desc *tx_desc = NULL; ++ struct e1000_buffer *buffer_info; ++ u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; ++ unsigned int i; + -+ Contact Information: -+ Linux NICS -+ e1000-devel Mailing List -+ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 ++ if (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_TXSM << 8; + -+*******************************************************************************/ ++ if (tx_flags & E1000_TX_FLAGS_IPV4) ++ txd_upper |= E1000_TXD_POPTS_IXSM << 8; ++ } + -+#include ++ if (tx_flags & E1000_TX_FLAGS_CSUM) { ++ txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D; ++ txd_upper |= E1000_TXD_POPTS_TXSM << 8; ++ } + -+#include "e1000.h" ++ if (tx_flags & E1000_TX_FLAGS_VLAN) { ++ txd_lower |= E1000_TXD_CMD_VLE; ++ txd_upper |= (tx_flags & E1000_TX_FLAGS_VLAN_MASK); ++ } + -+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw); -+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw); -+static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active); -+static s32 e1000_wait_autoneg(struct e1000_hw *hw); ++ i = tx_ring->next_to_use; + -+/* Cable length tables */ -+static const u16 e1000_m88_cable_length_table[] = -+ { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; ++ 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); + -+static const u16 e1000_igp_2_cable_length_table[] = -+ { 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}; -+#define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \ -+ (sizeof(e1000_igp_2_cable_length_table) / \ -+ sizeof(e1000_igp_2_cable_length_table[0])) ++ i++; ++ if (i == tx_ring->count) ++ i = 0; ++ } + -+/** -+ * e1000e_check_reset_block_generic - Check if PHY reset is blocked -+ * @hw: pointer to the HW structure -+ * -+ * Read the PHY management control register and check whether a PHY reset -+ * is blocked. If a reset is not blocked return 0, otherwise -+ * return E1000_BLK_PHY_RESET (12). -+ **/ -+s32 e1000e_check_reset_block_generic(struct e1000_hw *hw) -+{ -+ u32 manc; ++ tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd); + -+ manc = er32(MANC); ++ /* ++ * 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(); + -+ return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? -+ E1000_BLK_PHY_RESET : 0; ++ tx_ring->next_to_use = i; ++ writel(i, adapter->hw.hw_addr + tx_ring->tail); ++ /* ++ * we need this if more than one processor can write to our tail ++ * at a time, it synchronizes IO on IA64/Altix systems ++ */ ++ mmiowb(); +} + -+/** -+ * e1000e_get_phy_id - Retrieve the PHY ID and revision -+ * @hw: pointer to the HW structure -+ * -+ * Reads the PHY registers and stores the PHY ID and possibly the PHY -+ * revision in the hardware structure. -+ **/ -+s32 e1000e_get_phy_id(struct e1000_hw *hw) ++#define MINIMUM_DHCP_PACKET_SIZE 282 ++static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, ++ struct sk_buff *skb) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_id; ++ struct e1000_hw *hw = &adapter->hw; ++ u16 length, offset; + -+ ret_val = e1e_rphy(hw, PHY_ID1, &phy_id); -+ if (ret_val) -+ return ret_val; ++ 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))) ++ return 0; ++ } + -+ phy->id = (u32)(phy_id << 16); -+ udelay(20); -+ ret_val = e1e_rphy(hw, PHY_ID2, &phy_id); -+ if (ret_val) -+ return ret_val; ++ if (skb->len <= MINIMUM_DHCP_PACKET_SIZE) ++ return 0; + -+ phy->id |= (u32)(phy_id & PHY_REVISION_MASK); -+ phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); ++ if (((struct ethhdr *) skb->data)->h_proto != htons(ETH_P_IP)) ++ return 0; + -+ return 0; -+} ++ { ++ const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); ++ struct udphdr *udp; + -+/** -+ * e1000e_phy_reset_dsp - Reset PHY DSP -+ * @hw: pointer to the HW structure -+ * -+ * Reset the digital signal processor. -+ **/ -+s32 e1000e_phy_reset_dsp(struct e1000_hw *hw) -+{ -+ s32 ret_val; ++ if (ip->protocol != IPPROTO_UDP) ++ return 0; + -+ ret_val = e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); -+ if (ret_val) -+ return ret_val; ++ udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); ++ if (ntohs(udp->dest) != 67) ++ return 0; ++ ++ offset = (u8 *)udp + 8 - skb->data; ++ length = skb->len - offset; ++ return e1000_mng_write_dhcp_info_generic(hw, (u8 *)udp + 8, ++ length); ++ } + -+ return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0); ++ return 0; +} + -+/** -+ * e1000_read_phy_reg_mdic - Read MDI control register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to be read -+ * @data: pointer to the read data -+ * -+ * Reads the MDI control regsiter in the PHY at offset and stores the -+ * information read to data. -+ **/ -+static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) ++static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ u32 i, mdic = 0; ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ if (offset > MAX_PHY_REG_ADDRESS) { -+ hw_dbg(hw, "PHY Address %d is out of range\n", offset); -+ return -E1000_ERR_PARAM; -+ } ++ netif_stop_queue(netdev); ++ /* ++ * Herbert's original patch had: ++ * smp_mb__after_netif_stop_queue(); ++ * but since that doesn't exist yet, just open code it. ++ */ ++ smp_mb(); + -+ /* Set up Op-code, Phy Address, and register offset in the MDI -+ * Control register. The MAC will take care of interfacing with the -+ * PHY to retrieve the desired data. ++ /* ++ * We need to check again in a case another CPU has just ++ * made room available. + */ -+ mdic = ((offset << E1000_MDIC_REG_SHIFT) | -+ (phy->addr << E1000_MDIC_PHY_SHIFT) | -+ (E1000_MDIC_OP_READ)); ++ if (e1000_desc_unused(adapter->tx_ring) < size) ++ return -EBUSY; + -+ ew32(MDIC, mdic); ++ /* A reprieve! */ ++ netif_start_queue(netdev); ++ ++adapter->restart_queue; ++ return 0; ++} + -+ /* Poll the ready bit to see if the MDI read completed */ -+ for (i = 0; i < 64; i++) { -+ udelay(50); -+ mdic = er32(MDIC); -+ if (mdic & E1000_MDIC_READY) -+ break; -+ } -+ if (!(mdic & E1000_MDIC_READY)) { -+ hw_dbg(hw, "MDI Read did not complete\n"); -+ return -E1000_ERR_PHY; -+ } -+ if (mdic & E1000_MDIC_ERROR) { -+ hw_dbg(hw, "MDI Error\n"); -+ return -E1000_ERR_PHY; -+ } -+ *data = (u16) mdic; ++static int e1000_maybe_stop_tx(struct net_device *netdev, int size) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ return 0; ++ if (e1000_desc_unused(adapter->tx_ring) >= size) ++ return 0; ++ return __e1000_maybe_stop_tx(netdev, size); +} + -+/** -+ * e1000_write_phy_reg_mdic - Write MDI control register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to write to -+ * @data: data to write to register at offset -+ * -+ * Writes data to MDI control register in the PHY at offset. -+ **/ -+static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) ++#define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) ++static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ u32 i, mdic = 0; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_ring *tx_ring = adapter->tx_ring; ++ unsigned int first; ++ unsigned int max_per_txd = E1000_MAX_PER_TXD; ++ unsigned int max_txd_pwr = E1000_MAX_TXD_PWR; ++ unsigned int tx_flags = 0; ++ unsigned int len = skb->len - skb->data_len; ++#ifdef NETIF_F_LLTX ++ unsigned long irq_flags; ++#endif ++ unsigned int nr_frags; ++ unsigned int mss = 0; ++ int count = 0; ++ int tso; ++ unsigned int f; + -+ if (offset > MAX_PHY_REG_ADDRESS) { -+ hw_dbg(hw, "PHY Address %d is out of range\n", offset); -+ return -E1000_ERR_PARAM; ++ if (test_bit(__E1000_DOWN, &adapter->state)) { ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; + } + -+ /* Set up Op-code, Phy Address, and register offset in the MDI -+ * Control register. The MAC will take care of interfacing with the -+ * PHY to retrieve the desired data. ++ if (skb->len <= 0) { ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; ++ } ++ ++#ifdef NETIF_F_TSO ++ mss = skb_shinfo(skb)->gso_size; ++ /* ++ * 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. + */ -+ mdic = (((u32)data) | -+ (offset << E1000_MDIC_REG_SHIFT) | -+ (phy->addr << E1000_MDIC_PHY_SHIFT) | -+ (E1000_MDIC_OP_WRITE)); ++ if (mss) { ++ u8 hdr_len; ++ max_per_txd = min(mss << 2, max_per_txd); ++ max_txd_pwr = fls(max_per_txd) - 1; + -+ ew32(MDIC, mdic); ++ /* ++ * 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_transport_offset(skb) + tcp_hdrlen(skb); ++ /* ++ * we do this workaround for ES2LAN, but it is un-necessary, ++ * avoiding it could save a lot of cycles ++ */ ++ if (skb->data_len && (hdr_len == len)) { ++ unsigned int pull_size; + -+ /* Poll the ready bit to see if the MDI read completed */ -+ for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) { -+ udelay(5); -+ mdic = er32(MDIC); -+ if (mdic & E1000_MDIC_READY) -+ break; -+ } -+ if (!(mdic & E1000_MDIC_READY)) { -+ hw_dbg(hw, "MDI Write did not complete\n"); -+ return -E1000_ERR_PHY; ++ pull_size = min((unsigned int)4, skb->data_len); ++ if (!__pskb_pull_tail(skb, pull_size)) { ++ e_err("__pskb_pull_tail failed.\n"); ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; ++ } ++ len = skb->len - skb->data_len; ++ } + } + -+ return 0; -+} -+ -+/** -+ * e1000e_read_phy_reg_m88 - Read m88 PHY register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to be read -+ * @data: pointer to the read data -+ * -+ * Acquires semaphore, if necessary, then reads the PHY register at offset -+ * and storing the retrieved information in data. Release any acquired -+ * semaphores before exiting. -+ **/ -+s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) -+{ -+ s32 ret_val; -+ -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; ++ /* reserve a descriptor for the offload context */ ++ if ((mss) || (skb->ip_summed == CHECKSUM_PARTIAL)) ++ count++; ++ count++; ++#else ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ count++; ++#endif + -+ ret_val = e1000_read_phy_reg_mdic(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++ count += TXD_USE_COUNT(len, max_txd_pwr); + -+ hw->phy.ops.release_phy(hw); ++ nr_frags = skb_shinfo(skb)->nr_frags; ++ for (f = 0; f < nr_frags; f++) ++ count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, ++ max_txd_pwr); + -+ return ret_val; -+} ++ if (adapter->hw.mac.tx_pkt_filtering) ++ e1000_transfer_dhcp_info(adapter, skb); + -+/** -+ * e1000e_write_phy_reg_m88 - Write m88 PHY register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to write to -+ * @data: data to write at register offset -+ * -+ * Acquires semaphore, if necessary, then writes the data to PHY register -+ * at the offset. Release any acquired semaphores before exiting. -+ **/ -+s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) -+{ -+ s32 ret_val; ++#ifdef NETIF_F_LLTX ++ if (!spin_trylock_irqsave(&adapter->tx_queue_lock, irq_flags)) ++ /* Collision - tell upper layer to requeue */ ++ return NETDEV_TX_LOCKED; ++#endif + -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; ++ /* ++ * need: count + 2 desc gap to keep tail from touching ++ * head, otherwise try next time ++ */ ++ if (e1000_maybe_stop_tx(netdev, count + 2)) { ++#ifdef NETIF_F_LLTX ++ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); ++#endif ++ return NETDEV_TX_BUSY; ++ } + -+ ret_val = e1000_write_phy_reg_mdic(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++ if (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); ++ } + -+ hw->phy.ops.release_phy(hw); ++ first = tx_ring->next_to_use; + -+ return ret_val; -+} ++ tso = e1000_tso(adapter, skb); ++ if (unlikely(tso < 0)) { ++ dev_kfree_skb_any(skb); ++#ifdef NETIF_F_LLTX ++ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); ++#endif ++ return NETDEV_TX_OK; ++ } + -+/** -+ * e1000e_read_phy_reg_igp - Read igp PHY register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to be read -+ * @data: pointer to the read data -+ * -+ * Acquires semaphore, if necessary, then reads the PHY register at offset -+ * and storing the retrieved information in data. Release any acquired -+ * semaphores before exiting. -+ **/ -+s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) -+{ -+ s32 ret_val; ++ if (tso) ++ tx_flags |= E1000_TX_FLAGS_TSO; ++ else if (e1000_tx_csum(adapter, skb)) ++ tx_flags |= E1000_TX_FLAGS_CSUM; + -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; ++ /* ++ * 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 (skb->protocol == htons(ETH_P_IP)) ++ tx_flags |= E1000_TX_FLAGS_IPV4; + -+ if (offset > MAX_PHY_MULTI_PAGE_REG) { -+ ret_val = e1000_write_phy_reg_mdic(hw, -+ IGP01E1000_PHY_PAGE_SELECT, -+ (u16)offset); -+ if (ret_val) { -+ hw->phy.ops.release_phy(hw); -+ return ret_val; -+ } ++ count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); ++ if (unlikely(count < 0)) { ++ /* handle pci_map_single() error in e1000_tx_map */ ++ dev_kfree_skb_any(skb); ++#ifdef NETIF_F_LLTX ++ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); ++#endif ++ return NETDEV_TX_OK; + } + -+ ret_val = e1000_read_phy_reg_mdic(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++ e1000_tx_queue(adapter, tx_flags, count); + -+ hw->phy.ops.release_phy(hw); ++ netdev->trans_start = jiffies; + -+ return ret_val; ++ /* Make sure there is space in the ring for the next send. */ ++ e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); ++ ++#ifdef NETIF_F_LLTX ++ spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags); ++#endif ++ return NETDEV_TX_OK; +} + +/** -+ * e1000e_write_phy_reg_igp - Write igp PHY register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to write to -+ * @data: data to write at register offset -+ * -+ * Acquires semaphore, if necessary, then writes the data to PHY register -+ * at the offset. Release any acquired semaphores before exiting. ++ * e1000_tx_timeout - Respond to a Tx Hang ++ * @netdev: network interface device structure + **/ -+s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) ++static void e1000_tx_timeout(struct net_device *netdev) +{ -+ s32 ret_val; -+ -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; -+ -+ if (offset > MAX_PHY_MULTI_PAGE_REG) { -+ ret_val = e1000_write_phy_reg_mdic(hw, -+ IGP01E1000_PHY_PAGE_SELECT, -+ (u16)offset); -+ if (ret_val) { -+ hw->phy.ops.release_phy(hw); -+ return ret_val; -+ } -+ } ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ ret_val = e1000_write_phy_reg_mdic(hw, -+ MAX_PHY_REG_ADDRESS & offset, -+ data); ++ /* Do the reset outside of interrupt context */ ++ adapter->tx_timeout_count++; ++ schedule_work(&adapter->reset_task); ++} + -+ hw->phy.ops.release_phy(hw); ++static void e1000_reset_task(struct work_struct *work) ++{ ++ struct e1000_adapter *adapter; ++ adapter = container_of(work, struct e1000_adapter, reset_task); + -+ return ret_val; ++ e1000_reinit_locked(adapter); +} + +/** -+ * e1000e_read_kmrn_reg - Read kumeran register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to be read -+ * @data: pointer to the read data ++ * e1000_get_stats - Get System Network Statistics ++ * @netdev: network interface device structure + * -+ * Acquires semaphore, if necessary. Then reads the PHY register at offset -+ * using the kumeran interface. The information retrieved is stored in data. -+ * Release any acquired semaphores before exiting. ++ * Returns the address of the device statistics structure. ++ * The statistics are actually updated from the timer callback. + **/ -+s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data) ++static struct net_device_stats *e1000_get_stats(struct net_device *netdev) +{ -+ u32 kmrnctrlsta; -+ s32 ret_val; -+ -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; -+ -+ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & -+ E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; -+ ew32(KMRNCTRLSTA, kmrnctrlsta); -+ -+ udelay(2); -+ -+ kmrnctrlsta = er32(KMRNCTRLSTA); -+ *data = (u16)kmrnctrlsta; -+ -+ hw->phy.ops.release_phy(hw); ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ return ret_val; ++ /* only return the current stats */ ++ return &adapter->net_stats; +} + +/** -+ * e1000e_write_kmrn_reg - Write kumeran register -+ * @hw: pointer to the HW structure -+ * @offset: register offset to write to -+ * @data: data to write at register offset ++ * e1000_change_mtu - Change the Maximum Transfer Unit ++ * @netdev: network interface device structure ++ * @new_mtu: new value for maximum frame size + * -+ * Acquires semaphore, if necessary. Then write the data to PHY register -+ * at the offset using the kumeran interface. Release any acquired semaphores -+ * before exiting. ++ * Returns 0 on success, negative on failure + **/ -+s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) ++static int e1000_change_mtu(struct net_device *netdev, int new_mtu) +{ -+ u32 kmrnctrlsta; -+ s32 ret_val; ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; + -+ ret_val = hw->phy.ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; ++ if ((new_mtu < 68) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { ++ e_err("Invalid MTU setting\n"); ++ return -EINVAL; ++ } + -+ kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & -+ E1000_KMRNCTRLSTA_OFFSET) | data; -+ ew32(KMRNCTRLSTA, kmrnctrlsta); ++ /* Jumbo frame size limits */ ++ if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { ++ if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { ++ e_err("Jumbo Frames not supported.\n"); ++ return -EINVAL; ++ } ++ } + -+ udelay(2); -+ hw->phy.ops.release_phy(hw); ++#define MAX_STD_JUMBO_FRAME_SIZE 9234 ++ if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { ++ e_err("MTU > 9216 not supported.\n"); ++ return -EINVAL; ++ } + -+ return ret_val; -+} ++ while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) ++ msleep(1); ++ /* e1000_down has a dependency on max_frame_size */ ++ adapter->max_frame_size = max_frame; ++ if (netif_running(netdev)) ++ e1000_down(adapter); + -+/** -+ * e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link -+ * @hw: pointer to the HW structure -+ * -+ * Sets up MDI/MDI-X and polarity for m88 PHY's. If necessary, transmit clock -+ * and downshift values are set also. -+ **/ -+s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data; ++ /* ++ * NOTE: netdev_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 ++ * However with the new *_jumbo_rx* routines, jumbo receives will use ++ * fragmented skbs ++ */ + -+ /* Enable CRS on TX. This must be set for half-duplex operation. */ -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ if (max_frame <= 256) ++ adapter->rx_buffer_len = 256; ++ else if (max_frame <= 512) ++ adapter->rx_buffer_len = 512; ++ else if (max_frame <= 1024) ++ adapter->rx_buffer_len = 1024; ++ else if (max_frame <= 2048) ++ adapter->rx_buffer_len = 2048; ++#ifdef CONFIG_E1000E_NAPI ++ else ++ adapter->rx_buffer_len = 4096; ++#else ++ else if (max_frame <= 4096) ++ adapter->rx_buffer_len = 4096; ++ else if (max_frame <= 8192) ++ adapter->rx_buffer_len = 8192; ++ else if (max_frame <= 16384) ++ adapter->rx_buffer_len = 16384; ++#endif + -+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; ++ /* adjust allocation if LPE protects us, and we aren't using SBP */ ++ if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) || ++ (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN)) ++ adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN ++ + ETH_FCS_LEN; + -+ /* 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; ++ e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); ++ netdev->mtu = new_mtu; + -+ switch (phy->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; -+ } ++ if (netif_running(netdev)) ++ e1000_up(adapter); ++ else ++ e1000_reset(adapter); + -+ /* Options: -+ * disable_polarity_correction = 0 (default) -+ * Automatic Correction for Reversed Cable Polarity -+ * 0 - Disabled -+ * 1 - Enabled -+ */ -+ phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; -+ if (phy->disable_polarity_correction == 1) -+ phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; ++ clear_bit(__E1000_RESETTING, &adapter->state); + -+ ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; ++ return 0; ++} + -+ if (phy->revision < 4) { -+ /* Force TX_CLK in the Extended PHY Specific Control Register -+ * to 25MHz clock. -+ */ -+ ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, ++ int cmd) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct mii_ioctl_data *data = if_mii(ifr); + -+ phy_data |= M88E1000_EPSCR_TX_CLK_25; ++ if (adapter->hw.phy.media_type != e1000_media_type_copper) ++ return -EOPNOTSUPP; + -+ if ((phy->revision == 2) && -+ (phy->id == M88E1111_I_PHY_ID)) { -+ /* 82573L PHY - set the downshift counter to 5x. */ -+ phy_data &= ~M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK; -+ phy_data |= M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X; -+ } 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); ++ switch (cmd) { ++ case SIOCGMIIPHY: ++ data->phy_id = adapter->hw.phy.addr; ++ break; ++ case SIOCGMIIREG: ++ if (!capable(CAP_NET_ADMIN)) ++ return -EPERM; ++ switch (data->reg_num & 0x1F) { ++ case MII_BMCR: ++ data->val_out = adapter->phy_regs.bmcr; ++ break; ++ case MII_BMSR: ++ data->val_out = adapter->phy_regs.bmsr; ++ break; ++ case MII_PHYSID1: ++ data->val_out = (adapter->hw.phy.id >> 16); ++ break; ++ case MII_PHYSID2: ++ data->val_out = (adapter->hw.phy.id & 0xFFFF); ++ break; ++ case MII_ADVERTISE: ++ data->val_out = adapter->phy_regs.advertise; ++ break; ++ case MII_LPA: ++ data->val_out = adapter->phy_regs.lpa; ++ break; ++ case MII_EXPANSION: ++ data->val_out = adapter->phy_regs.expansion; ++ break; ++ case MII_CTRL1000: ++ data->val_out = adapter->phy_regs.ctrl1000; ++ break; ++ case MII_STAT1000: ++ data->val_out = adapter->phy_regs.stat1000; ++ break; ++ case MII_ESTATUS: ++ data->val_out = adapter->phy_regs.estatus; ++ break; ++ default: ++ return -EIO; + } -+ ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; ++ break; ++ case SIOCSMIIREG: ++ default: ++ return -EOPNOTSUPP; + } -+ -+ /* Commit the changes. */ -+ ret_val = e1000e_commit_phy(hw); -+ if (ret_val) -+ hw_dbg(hw, "Error committing the PHY changes\n"); -+ -+ return ret_val; ++ return 0; +} + -+/** -+ * e1000e_copper_link_setup_igp - Setup igp PHY's for copper link -+ * @hw: pointer to the HW structure -+ * -+ * Sets up LPLU, MDI/MDI-X, polarity, Smartspeed and Master/Slave config for -+ * igp PHY's. -+ **/ -+s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw) ++static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; -+ -+ ret_val = e1000_phy_hw_reset(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error resetting the PHY.\n"); -+ return ret_val; ++ switch (cmd) { ++ case SIOCGMIIPHY: ++ case SIOCGMIIREG: ++ case SIOCSMIIREG: ++ return e1000_mii_ioctl(netdev, ifr, cmd); ++#ifdef ETHTOOL_OPS_COMPAT ++ case SIOCETHTOOL: ++ return ethtool_ioctl(ifr); ++#endif ++ default: ++ return -EOPNOTSUPP; + } ++} + -+ /* Wait 15ms for MAC to configure PHY from NVM settings. */ -+ msleep(15); -+ -+ /* disable lplu d0 during driver init */ -+ ret_val = e1000_set_d0_lplu_state(hw, 0); -+ if (ret_val) { -+ hw_dbg(hw, "Error Disabling LPLU D0\n"); -+ return ret_val; -+ } -+ /* Configure mdi-mdix settings */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++static int e1000_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct net_device *netdev = pci_get_drvdata(pdev); ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 ctrl, ctrl_ext, rctl, status; ++ u32 wufc = adapter->wol; ++ int retval = 0; + -+ data &= ~IGP01E1000_PSCR_AUTO_MDIX; ++ netif_device_detach(netdev); + -+ switch (phy->mdix) { -+ case 1: -+ data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; -+ break; -+ case 2: -+ data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; -+ break; -+ case 0: -+ default: -+ data |= IGP01E1000_PSCR_AUTO_MDIX; -+ break; ++ if (netif_running(netdev)) { ++ WARN_ON(test_bit(__E1000_RESETTING, &adapter->state)); ++ e1000_down(adapter); ++ e1000_free_irq(adapter); + } -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, data); -+ if (ret_val) -+ return ret_val; + -+ /* set auto-master slave resolution settings */ -+ if (hw->mac.autoneg) { -+ /* when autonegotiation advertisement is only 1000Mbps then we -+ * should disable SmartSpeed and enable Auto MasterSlave -+ * resolution as hardware default. */ -+ if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { -+ /* Disable SmartSpeed */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++#ifdef CONFIG_PM ++ retval = pci_save_state(pdev); ++ if (retval) ++ return retval; ++#endif + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; ++ status = er32(STATUS); ++ if (status & E1000_STATUS_LU) ++ wufc &= ~E1000_WUFC_LNKC; + -+ /* Set auto Master/Slave resolution process */ -+ ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data); -+ if (ret_val) -+ return ret_val; ++ if (wufc) { ++ e1000_setup_rctl(adapter); ++ e1000_set_multi(netdev); + -+ data &= ~CR_1000T_MS_ENABLE; -+ ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data); -+ if (ret_val) -+ return ret_val; ++ /* turn on all-multi mode if wake on multicast is enabled */ ++ if (wufc & E1000_WUFC_MC) { ++ rctl = er32(RCTL); ++ rctl |= E1000_RCTL_MPE; ++ ew32(RCTL, rctl); + } + -+ ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &data); -+ if (ret_val) -+ return ret_val; -+ -+ /* load defaults for future use */ -+ phy->original_ms_type = (data & CR_1000T_MS_ENABLE) ? -+ ((data & CR_1000T_MS_VALUE) ? -+ e1000_ms_force_master : -+ e1000_ms_force_slave) : -+ e1000_ms_auto; ++ ctrl = er32(CTRL); ++ /* advertise wake from D3Cold */ ++ #define E1000_CTRL_ADVD3WUC 0x00100000 ++ /* phy power management enable */ ++ #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000 ++ ctrl |= E1000_CTRL_ADVD3WUC | ++ E1000_CTRL_EN_PHY_PWR_MGMT; ++ ew32(CTRL, ctrl); + -+ switch (phy->ms_type) { -+ case e1000_ms_force_master: -+ data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); -+ break; -+ case e1000_ms_force_slave: -+ data |= CR_1000T_MS_ENABLE; -+ data &= ~(CR_1000T_MS_VALUE); -+ break; -+ case e1000_ms_auto: -+ data &= ~CR_1000T_MS_ENABLE; -+ default: -+ break; ++ if (adapter->hw.phy.media_type == e1000_media_type_fiber || ++ adapter->hw.phy.media_type == e1000_media_type_internal_serdes) { ++ /* keep the laser running in D3 */ ++ ctrl_ext = er32(CTRL_EXT); ++ ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA; ++ ew32(CTRL_EXT, ctrl_ext); + } -+ ret_val = e1e_wphy(hw, PHY_1000T_CTRL, data); -+ } -+ -+ return ret_val; -+} + -+/** -+ * e1000_phy_setup_autoneg - Configure PHY for auto-negotiation -+ * @hw: pointer to the HW structure -+ * -+ * Reads the MII auto-neg advertisement register and/or the 1000T control -+ * register and if the PHY is already setup for auto-negotiation, then -+ * return successful. Otherwise, setup advertisement and flow control to -+ * the appropriate values for the wanted auto-negotiation. -+ **/ -+static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 mii_autoneg_adv_reg; -+ u16 mii_1000t_ctrl_reg = 0; ++ if (adapter->flags & FLAG_IS_ICH) ++ e1000_disable_gig_wol_ich8lan(&adapter->hw); + -+ phy->autoneg_advertised &= phy->autoneg_mask; ++ /* Allow time for pending master requests to run */ ++ e1000_disable_pcie_master_generic(&adapter->hw); + -+ /* Read the MII Auto-Neg Advertisement Register (Address 4). */ -+ ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); -+ if (ret_val) -+ return ret_val; ++ ew32(WUC, E1000_WUC_PME_EN); ++ ew32(WUFC, wufc); ++ pci_enable_wake(pdev, PCI_D3hot, 1); ++ pci_enable_wake(pdev, PCI_D3cold, 1); ++ } else { ++ ew32(WUC, 0); ++ ew32(WUFC, 0); ++ pci_enable_wake(pdev, PCI_D3hot, 0); ++ pci_enable_wake(pdev, PCI_D3cold, 0); ++ } + -+ if (phy->autoneg_mask & ADVERTISE_1000_FULL) { -+ /* Read the MII 1000Base-T Control Register (Address 9). */ -+ ret_val = e1e_rphy(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); -+ if (ret_val) -+ return ret_val; ++ /* make sure adapter isn't asleep if manageability is enabled */ ++ if (adapter->flags & FLAG_MNG_PT_ENABLED) { ++ pci_enable_wake(pdev, PCI_D3hot, 1); ++ pci_enable_wake(pdev, PCI_D3cold, 1); + } + -+ /* Need to parse both autoneg_advertised and fc and set up -+ * the appropriate PHY registers. First we will parse for -+ * autoneg_advertised software override. Since we can advertise -+ * a plethora of combinations, we need to check each bit -+ * individually. -+ */ ++ if (adapter->hw.phy.type == e1000_phy_igp_3) ++ e1000_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); + -+ /* First we clear all the 10/100 mb speed bits in the Auto-Neg -+ * Advertisement Register (Address 4) and the 1000 mb speed bits in -+ * the 1000Base-T Control Register (Address 9). ++ /* ++ * Release control of h/w to f/w. If f/w is AMT enabled, this ++ * would have already happened in close and is redundant. + */ -+ mii_autoneg_adv_reg &= ~(NWAY_AR_100TX_FD_CAPS | -+ NWAY_AR_100TX_HD_CAPS | -+ NWAY_AR_10T_FD_CAPS | -+ NWAY_AR_10T_HD_CAPS); -+ mii_1000t_ctrl_reg &= ~(CR_1000T_HD_CAPS | CR_1000T_FD_CAPS); ++ e1000_release_hw_control(adapter); + -+ hw_dbg(hw, "autoneg_advertised %x\n", phy->autoneg_advertised); ++ pci_disable_device(pdev); + -+ /* Do we want to advertise 10 Mb Half Duplex? */ -+ if (phy->autoneg_advertised & ADVERTISE_10_HALF) { -+ hw_dbg(hw, "Advertise 10mb Half duplex\n"); -+ mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS; -+ } ++ pci_set_power_state(pdev, pci_choose_state(pdev, state)); + -+ /* Do we want to advertise 10 Mb Full Duplex? */ -+ if (phy->autoneg_advertised & ADVERTISE_10_FULL) { -+ hw_dbg(hw, "Advertise 10mb Full duplex\n"); -+ mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS; -+ } ++ return 0; ++} + -+ /* Do we want to advertise 100 Mb Half Duplex? */ -+ if (phy->autoneg_advertised & ADVERTISE_100_HALF) { -+ hw_dbg(hw, "Advertise 100mb Half duplex\n"); -+ mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS; -+ } ++#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(netdev); ++ struct e1000_hw *hw = &adapter->hw; ++ u32 err; + -+ /* Do we want to advertise 100 Mb Full Duplex? */ -+ if (phy->autoneg_advertised & ADVERTISE_100_FULL) { -+ hw_dbg(hw, "Advertise 100mb Full duplex\n"); -+ mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS; ++ pci_set_power_state(pdev, PCI_D0); ++ pci_restore_state(pdev); ++ err = pci_enable_device(pdev); ++ if (err) { ++ dev_err(&pdev->dev, ++ "Cannot enable PCI device from suspend\n"); ++ return err; + } + -+ /* We do not allow the Phy to advertise 1000 Mb Half Duplex */ -+ if (phy->autoneg_advertised & ADVERTISE_1000_HALF) -+ hw_dbg(hw, "Advertise 1000mb Half duplex request denied!\n"); ++ pci_set_master(pdev); + -+ /* Do we want to advertise 1000 Mb Full Duplex? */ -+ if (phy->autoneg_advertised & ADVERTISE_1000_FULL) { -+ hw_dbg(hw, "Advertise 1000mb Full duplex\n"); -+ mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS; ++ pci_enable_wake(pdev, PCI_D3hot, 0); ++ pci_enable_wake(pdev, PCI_D3cold, 0); ++ ++ if (netif_running(netdev)) { ++ err = e1000_request_irq(adapter); ++ if (err) ++ return err; + } + -+ /* Check for a software override of the flow control settings, and -+ * setup the PHY advertisement registers accordingly. If -+ * auto-negotiation is enabled, then software will have to set the -+ * "PAUSE" bits to the correct value in the Auto-Negotiation -+ * Advertisement Register (PHY_AUTONEG_ADV) and re-start auto- -+ * negotiation. -+ * -+ * The possible values of the "fc" parameter are: -+ * 0: Flow control is completely disabled -+ * 1: Rx flow control is enabled (we can receive pause frames -+ * but not send pause frames). -+ * 2: Tx flow control is enabled (we can send pause frames -+ * but we do not support receiving pause frames). -+ * 3: Both Rx and TX flow control (symmetric) are enabled. -+ * other: No software override. The flow control configuration -+ * in the EEPROM is used. ++ e1000_power_up_phy(hw); ++ e1000_reset(adapter); ++ ew32(WUS, ~0); ++ ++ e1000_init_manageability(adapter); ++ ++ if (netif_running(netdev)) ++ e1000_up(adapter); ++ ++ netif_device_attach(netdev); ++ ++ /* ++ * If the controller has 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. + */ -+ switch (hw->mac.fc) { -+ case e1000_fc_none: -+ /* Flow control (RX & TX) is completely disabled by a -+ * software over-ride. -+ */ -+ mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); -+ break; -+ case e1000_fc_rx_pause: -+ /* RX Flow control is enabled, and TX Flow control is -+ * disabled, by a software over-ride. -+ */ -+ /* Since there really isn't a way to advertise that we are -+ * capable of RX Pause ONLY, we will advertise that we -+ * support both symmetric and asymmetric RX PAUSE. Later -+ * (in e1000e_config_fc_after_link_up) we will disable the -+ * hw's ability to send PAUSE frames. -+ */ -+ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); -+ break; -+ case e1000_fc_tx_pause: -+ /* TX Flow control is enabled, and RX Flow control is -+ * disabled, by a software over-ride. -+ */ -+ mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR; -+ mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE; -+ break; -+ case e1000_fc_full: -+ /* Flow control (both RX and TX) is enabled by a software -+ * over-ride. -+ */ -+ mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE); ++ if (!(adapter->flags & FLAG_HAS_AMT)) ++ e1000_get_hw_control(adapter); ++ ++ return 0; ++} ++#endif /* CONFIG_PM */ ++ ++#ifndef USE_REBOOT_NOTIFIER ++static void e1000_shutdown(struct pci_dev *pdev) ++{ ++ e1000_suspend(pdev, PMSG_SUSPEND); ++} ++#else ++static struct pci_driver e1000_driver; ++static int e1000_notify_reboot(struct notifier_block *nb, unsigned long event, ++ void *ptr) ++{ ++ struct pci_dev *pdev = NULL; ++ ++ 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, PMSG_SUSPEND); ++ } + break; -+ default: -+ hw_dbg(hw, "Flow control param set incorrectly\n"); -+ ret_val = -E1000_ERR_CONFIG; -+ return ret_val; + } ++ return NOTIFY_DONE; ++} + -+ ret_val = e1e_wphy(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); -+ if (ret_val) -+ return ret_val; ++static struct notifier_block e1000_notifier_reboot = { ++ .notifier_call = e1000_notify_reboot, ++ .next = NULL, ++ .priority = 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 *netdev) ++{ ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ hw_dbg(hw, "Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); ++ disable_irq(adapter->pdev->irq); ++ e1000_intr(adapter->pdev->irq, netdev); + -+ if (phy->autoneg_mask & ADVERTISE_1000_FULL) { -+ ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); -+ } ++ e1000_clean_tx_irq(adapter); ++#ifndef CONFIG_E1000E_NAPI ++ adapter->clean_rx(adapter); ++#endif + -+ return ret_val; ++ enable_irq(adapter->pdev->irq); +} ++#endif + ++#ifdef HAVE_PCI_ERS +/** -+ * e1000_copper_link_autoneg - Setup/Enable autoneg for copper link -+ * @hw: pointer to the HW structure ++ * e1000_io_error_detected - called when PCI error is detected ++ * @pdev: Pointer to PCI device ++ * @state: The current pci connection state + * -+ * Performs initial bounds checking on autoneg advertisement parameter, then -+ * configure to advertise the full capability. Setup the PHY to autoneg -+ * and restart the negotiation process between the link partner. If -+ * wait_for_link, then wait for autoneg to complete before exiting. -+ **/ -+static s32 e1000_copper_link_autoneg(struct e1000_hw *hw) ++ * This function is called after a PCI bus error affecting ++ * this device has been detected. ++ */ ++static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, ++ pci_channel_state_t state) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_ctrl; -+ -+ /* Perform some bounds checking on the autoneg advertisement -+ * parameter. -+ */ -+ phy->autoneg_advertised &= phy->autoneg_mask; -+ -+ /* If autoneg_advertised is zero, we assume it was not defaulted -+ * by the calling code so we set to advertise full capability. -+ */ -+ if (phy->autoneg_advertised == 0) -+ phy->autoneg_advertised = phy->autoneg_mask; -+ -+ hw_dbg(hw, "Reconfiguring auto-neg advertisement params\n"); -+ ret_val = e1000_phy_setup_autoneg(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error Setting up Auto-Negotiation\n"); -+ return ret_val; -+ } -+ hw_dbg(hw, "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 = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl); -+ if (ret_val) -+ return ret_val; -+ -+ phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); -+ ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl); -+ if (ret_val) -+ return ret_val; ++ struct net_device *netdev = pci_get_drvdata(pdev); ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ /* Does the user want to wait for Auto-Neg to complete here, or -+ * check at a later time (for example, callback routine). -+ */ -+ if (phy->wait_for_link) { -+ ret_val = e1000_wait_autoneg(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error while waiting for " -+ "autoneg to complete\n"); -+ return ret_val; -+ } -+ } ++ netif_device_detach(netdev); + -+ hw->mac.get_link_status = 1; ++ if (netif_running(netdev)) ++ e1000_down(adapter); ++ pci_disable_device(pdev); + -+ return ret_val; ++ /* Request a slot slot reset. */ ++ return PCI_ERS_RESULT_NEED_RESET; +} + +/** -+ * e1000e_setup_copper_link - Configure copper link settings -+ * @hw: pointer to the HW structure ++ * e1000_io_slot_reset - called after the pci bus has been reset. ++ * @pdev: Pointer to PCI device + * -+ * Calls the appropriate function to configure the link for auto-neg or forced -+ * speed and duplex. Then we check for link, once link is established calls -+ * to configure collision distance and flow control are called. If link is -+ * not established, we return -E1000_ERR_PHY (-2). -+ **/ -+s32 e1000e_setup_copper_link(struct e1000_hw *hw) ++ * Restart the card from scratch, as if from a cold-boot. Implementation ++ * resembles the first-half of the e1000_resume routine. ++ */ ++static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) +{ -+ s32 ret_val; -+ bool link; ++ struct net_device *netdev = pci_get_drvdata(pdev); ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ if (hw->mac.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 user settings. */ -+ hw_dbg(hw, "Forcing Speed and Duplex\n"); -+ ret_val = e1000_phy_force_speed_duplex(hw); -+ if (ret_val) { -+ hw_dbg(hw, "Error Forcing Speed and Duplex\n"); -+ return ret_val; -+ } ++ if (pci_enable_device(pdev)) { ++ dev_err(&pdev->dev, ++ "Cannot re-enable PCI device after reset.\n"); ++ return PCI_ERS_RESULT_DISCONNECT; + } ++ pci_set_master(pdev); + -+ /* Check link status. Wait up to 100 microseconds for link to become -+ * valid. -+ */ -+ ret_val = e1000e_phy_has_link_generic(hw, -+ COPPER_LINK_UP_LIMIT, -+ 10, -+ &link); -+ if (ret_val) -+ return ret_val; ++ pci_enable_wake(pdev, PCI_D3hot, 0); ++ pci_enable_wake(pdev, PCI_D3cold, 0); + -+ if (link) { -+ hw_dbg(hw, "Valid link established!!!\n"); -+ e1000e_config_collision_dist(hw); -+ ret_val = e1000e_config_fc_after_link_up(hw); -+ } else { -+ hw_dbg(hw, "Unable to establish link!!!\n"); -+ } ++ e1000_reset(adapter); ++ ew32(WUS, ~0); + -+ return ret_val; ++ return PCI_ERS_RESULT_RECOVERED; +} + +/** -+ * e1000e_phy_force_speed_duplex_igp - Force speed/duplex for igp PHY -+ * @hw: pointer to the HW structure ++ * e1000_io_resume - called when traffic can start flowing again. ++ * @pdev: Pointer to PCI device + * -+ * Calls the PHY setup function to force speed and duplex. Clears the -+ * auto-crossover to force MDI manually. Waits for link and returns -+ * successful if link up is successful, else -E1000_ERR_PHY (-2). -+ **/ -+s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw) ++ * This callback is called when the error recovery driver tells us that ++ * its OK to resume normal operation. Implementation resembles the ++ * second-half of the e1000_resume routine. ++ */ ++static void e1000_io_resume(struct pci_dev *pdev) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data; -+ bool link; ++ struct net_device *netdev = pci_get_drvdata(pdev); ++ struct e1000_adapter *adapter = netdev_priv(netdev); + -+ ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ e1000_init_manageability(adapter); + -+ e1000e_phy_force_speed_duplex_setup(hw, &phy_data); ++ if (netif_running(netdev)) { ++ if (e1000_up(adapter)) { ++ dev_err(&pdev->dev, ++ "can't bring device back up after reset\n"); ++ return; ++ } ++ } + -+ ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data); -+ if (ret_val) -+ return ret_val; ++ netif_device_attach(netdev); + -+ /* Clear Auto-Crossover to force MDI manually. IGP requires MDI -+ * forced whenever speed and duplex are forced. ++ /* ++ * If the controller has 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. + */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; -+ -+ phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; -+ phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; -+ -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; -+ -+ hw_dbg(hw, "IGP PSCR: %X\n", phy_data); -+ -+ udelay(1); -+ -+ if (phy->wait_for_link) { -+ hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n"); -+ -+ ret_val = e1000e_phy_has_link_generic(hw, -+ PHY_FORCE_LIMIT, -+ 100000, -+ &link); -+ if (ret_val) -+ return ret_val; ++ if (!(adapter->flags & FLAG_HAS_AMT)) ++ e1000_get_hw_control(adapter); + -+ if (!link) -+ hw_dbg(hw, "Link taking longer than expected.\n"); ++} ++#endif /* HAVE_PCI_ERS */ + -+ /* Try once more */ -+ ret_val = e1000e_phy_has_link_generic(hw, -+ PHY_FORCE_LIMIT, -+ 100000, -+ &link); -+ if (ret_val) -+ return ret_val; -+ } ++static void e1000_print_device_info(struct e1000_adapter *adapter) ++{ ++ struct e1000_hw *hw = &adapter->hw; ++ struct net_device *netdev = adapter->netdev; ++ u32 pba_num; + -+ return ret_val; ++ /* print bus type/speed/width info */ ++ e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n", ++ /* bus width */ ++ ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" : ++ "Width x1"), ++ /* MAC address */ ++ netdev->dev_addr[0], netdev->dev_addr[1], ++ netdev->dev_addr[2], netdev->dev_addr[3], ++ netdev->dev_addr[4], netdev->dev_addr[5]); ++ e_info("Intel(R) PRO/%s Network Connection\n", ++ (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000"); ++ e1000_read_pba_num_generic(hw, &pba_num); ++ e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n", ++ hw->mac.type, hw->phy.type, ++ (pba_num >> 8), (pba_num & 0xff)); +} + +/** -+ * e1000e_phy_force_speed_duplex_m88 - Force speed/duplex for m88 PHY -+ * @hw: pointer to the HW structure ++ * e1000_probe - Device Initialization Routine ++ * @pdev: PCI device information struct ++ * @ent: entry in e1000e_pci_tbl + * -+ * Calls the PHY setup function to force speed and duplex. Clears the -+ * auto-crossover to force MDI manually. Resets the PHY to commit the -+ * changes. If time expires while waiting for link up, we reset the DSP. -+ * After reset, TX_CLK and CRS on TX must be set. Return successful upon -+ * successful completion, else return corresponding error code. ++ * Returns 0 on success, negative on failure ++ * ++ * e1000_probe initializes an adapter identified by a pci_dev structure. ++ * The OS initialization, configuring of the adapter private structure, ++ * and a hardware reset occur. + **/ -+s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw) ++static int __devinit e1000_probe(struct pci_dev *pdev, ++ const struct pci_device_id *ent) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data; -+ bool link; -+ -+ /* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI -+ * forced whenever speed and duplex are forced. -+ */ -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; -+ -+ phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; -+ ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; -+ -+ hw_dbg(hw, "M88E1000 PSCR: %X\n", phy_data); ++ struct net_device *netdev; ++ struct e1000_adapter *adapter; ++ struct e1000_hw *hw; ++ const struct e1000_info *ei = e1000_info_tbl[ent->driver_data]; + -+ ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ static int cards_found; ++ int i, err, pci_using_dac; ++ u16 eeprom_data = 0; ++ u16 eeprom_apme_mask = E1000_EEPROM_APME; + -+ e1000e_phy_force_speed_duplex_setup(hw, &phy_data); ++ err = pci_enable_device(pdev); ++ if (err) ++ return err; + -+ /* Reset the phy to commit changes. */ -+ phy_data |= MII_CR_RESET; ++ pci_using_dac = 0; ++ err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); ++ if (!err) { ++ err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); ++ if (!err) ++ pci_using_dac = 1; ++ } else { ++ err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); ++ if (err) { ++ err = pci_set_consistent_dma_mask(pdev, ++ DMA_32BIT_MASK); ++ if (err) { ++ printk(KERN_ERR "%s: No usable DMA " ++ "configuration, aborting\n", ++ pci_name(pdev)); ++ goto err_dma; ++ } ++ } ++ } + -+ ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data); -+ if (ret_val) -+ return ret_val; ++ err = pci_request_regions(pdev, e1000e_driver_name); ++ if (err) ++ goto err_pci_reg; + -+ udelay(1); ++ pci_set_master(pdev); + -+ if (phy->wait_for_link) { -+ hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n"); ++ err = -ENOMEM; ++ netdev = alloc_etherdev(sizeof(struct e1000_adapter)); ++ if (!netdev) ++ goto err_alloc_etherdev; + -+ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, -+ 100000, &link); -+ if (ret_val) -+ return ret_val; ++ SET_MODULE_OWNER(netdev); ++ SET_NETDEV_DEV(netdev, &pdev->dev); + -+ if (!link) { -+ /* We didn't get link. -+ * Reset the DSP and cross our fingers. -+ */ -+ ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT, 0x001d); -+ if (ret_val) -+ return ret_val; -+ ret_val = e1000e_phy_reset_dsp(hw); -+ if (ret_val) -+ return ret_val; -+ } ++ pci_set_drvdata(pdev, netdev); ++ adapter = netdev_priv(netdev); ++ hw = &adapter->hw; ++ adapter->netdev = netdev; ++ adapter->pdev = pdev; ++ adapter->ei = ei; ++ adapter->pba = ei->pba; ++ adapter->flags = ei->flags; ++ adapter->flags2 = ei->flags2; ++ adapter->hw.back = adapter; ++ adapter->hw.mac.type = ei->mac; ++ adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1; ++ adapter->stats_freq_us = 2 * 1000000; /* default watchdog timer 2sec */ + -+ /* Try once more */ -+ ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, -+ 100000, &link); -+ if (ret_val) -+ return ret_val; -+ } ++ /* PCI config space info */ + -+ ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ hw->vendor_id = pdev->vendor; ++ hw->device_id = pdev->device; ++ hw->subsystem_vendor_id = pdev->subsystem_vendor; ++ hw->subsystem_device_id = pdev->subsystem_device; + -+ /* Resetting the phy means we need to re-force TX_CLK in the -+ * Extended PHY Specific Control Register to 25MHz clock from -+ * the reset value of 2.5MHz. -+ */ -+ phy_data |= M88E1000_EPSCR_TX_CLK_25; -+ ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); -+ if (ret_val) -+ return ret_val; ++ pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); ++ pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word); + -+ /* In addition, we must re-enable CRS on Tx for both half and full -+ * duplex. -+ */ -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++ err = -EIO; ++ adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, 0), ++ pci_resource_len(pdev, 0)); ++ if (!adapter->hw.hw_addr) ++ goto err_ioremap; + -+ phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; -+ ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ++ if ((adapter->flags & FLAG_HAS_FLASH) && ++ (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) { ++ adapter->hw.flash_address = ioremap(pci_resource_start(pdev, 1), ++ pci_resource_len(pdev, 1)); ++ if (!adapter->hw.flash_address) ++ goto err_flashmap; ++ } + -+ return ret_val; -+} ++ adapter->bd_number = cards_found++; + -+/** -+ * e1000e_phy_force_speed_duplex_setup - Configure forced PHY speed/duplex -+ * @hw: pointer to the HW structure -+ * @phy_ctrl: pointer to current value of PHY_CONTROL -+ * -+ * Forces speed and duplex on the PHY by doing the following: disable flow -+ * control, force speed/duplex on the MAC, disable auto speed detection, -+ * disable auto-negotiation, configure duplex, configure speed, configure -+ * the collision distance, write configuration to CTRL register. The -+ * caller must write to the PHY_CONTROL register for these settings to -+ * take affect. -+ **/ -+void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) -+{ -+ struct e1000_mac_info *mac = &hw->mac; -+ u32 ctrl; ++ e1000_check_options(adapter); + -+ /* Turn off flow control when forcing speed/duplex */ -+ mac->fc = e1000_fc_none; ++ /* setup adapter struct */ ++ err = e1000_sw_init(adapter); ++ if (err) ++ goto err_sw_init; + -+ /* Force speed/duplex on the mac */ -+ ctrl = er32(CTRL); -+ ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); -+ ctrl &= ~E1000_CTRL_SPD_SEL; ++ if (ei->get_variants) { ++ err = ei->get_variants(adapter); ++ if (err) ++ goto err_hw_init; ++ } + -+ /* Disable Auto Speed Detection */ -+ ctrl &= ~E1000_CTRL_ASDE; ++ /* construct the net_device struct */ ++ netdev->open = &e1000_open; ++ netdev->stop = &e1000_close; ++ netdev->hard_start_xmit = &e1000_xmit_frame; ++ netdev->get_stats = &e1000_get_stats; ++ netdev->set_multicast_list = &e1000_set_multi; ++ netdev->set_mac_address = &e1000_set_mac; ++ netdev->change_mtu = &e1000_change_mtu; ++ netdev->do_ioctl = &e1000_ioctl; ++ e1000_set_ethtool_ops(netdev); ++ netdev->tx_timeout = &e1000_tx_timeout; ++ netdev->watchdog_timeo = 5 * HZ; ++#ifdef CONFIG_E1000E_NAPI ++ netif_napi_add(netdev, &adapter->napi, e1000_poll, 64); ++#endif ++ 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; ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ netdev->poll_controller = e1000_netpoll; ++#endif ++ strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + -+ /* Disable autoneg on the phy */ -+ *phy_ctrl &= ~MII_CR_AUTO_NEG_EN; ++ if ((adapter->flags & FLAG_IS_ICH) && ++ (adapter->flags2 & FLAG2_READ_ONLY_NVM)) ++ e1000e_write_protect_nvm_ich8lan(&adapter->hw); + -+ /* Forcing Full or Half Duplex? */ -+ if (mac->forced_speed_duplex & E1000_ALL_HALF_DUPLEX) { -+ ctrl &= ~E1000_CTRL_FD; -+ *phy_ctrl &= ~MII_CR_FULL_DUPLEX; -+ hw_dbg(hw, "Half Duplex\n"); -+ } else { -+ ctrl |= E1000_CTRL_FD; -+ *phy_ctrl |= MII_CR_FULL_DUPLEX; -+ hw_dbg(hw, "Full Duplex\n"); -+ } ++ hw->mac.ops.get_bus_info(&adapter->hw); + -+ /* Forcing 10mb or 100mb? */ -+ if (mac->forced_speed_duplex & E1000_ALL_100_SPEED) { -+ ctrl |= E1000_CTRL_SPD_100; -+ *phy_ctrl |= MII_CR_SPEED_100; -+ *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_10); -+ hw_dbg(hw, "Forcing 100mb\n"); -+ } else { -+ ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100); -+ *phy_ctrl |= MII_CR_SPEED_10; -+ *phy_ctrl &= ~(MII_CR_SPEED_1000 | MII_CR_SPEED_100); -+ hw_dbg(hw, "Forcing 10mb\n"); ++ adapter->hw.phy.autoneg_wait_to_complete = 0; ++ ++ /* Copper options */ ++ if (adapter->hw.phy.media_type == e1000_media_type_copper) { ++ adapter->hw.phy.mdix = AUTO_ALL_MODES; ++ adapter->hw.phy.disable_polarity_correction = 0; ++ adapter->hw.phy.ms_type = e1000_ms_hw_default; + } + -+ e1000e_config_collision_dist(hw); ++ if (hw->phy.ops.check_reset_block && ++ hw->phy.ops.check_reset_block(hw)) ++ e_info("PHY reset is blocked due to SOL/IDER session.\n"); + -+ ew32(CTRL, ctrl); -+} ++ netdev->features = NETIF_F_SG | ++ NETIF_F_HW_CSUM | ++ NETIF_F_HW_VLAN_TX | ++ NETIF_F_HW_VLAN_RX; + -+/** -+ * e1000e_set_d3_lplu_state - Sets low power link up state for D3 -+ * @hw: pointer to the HW structure -+ * @active: boolean used to enable/disable lplu -+ * -+ * Success returns 0, Failure returns 1 -+ * -+ * The low power link up (lplu) state is set to the power management level D3 -+ * and SmartSpeed is disabled when active is true, else clear lplu for D3 -+ * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU -+ * is used during Dx states where the power conservation is most important. -+ * During driver activity, SmartSpeed should be enabled so performance is -+ * maintained. -+ **/ -+s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; ++ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) ++ netdev->features |= NETIF_F_HW_VLAN_FILTER; + -+ ret_val = e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &data); -+ if (ret_val) -+ return ret_val; ++#ifdef NETIF_F_TSO ++ netdev->features |= NETIF_F_TSO; ++#ifdef NETIF_F_TSO6 ++ netdev->features |= NETIF_F_TSO6; ++#endif ++#endif + -+ if (!active) { -+ data &= ~IGP02E1000_PM_D3_LPLU; -+ ret_val = e1e_wphy(hw, -+ IGP02E1000_PHY_POWER_MGMT, -+ 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 (phy->smart_speed == e1000_smart_speed_on) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++ if (pci_using_dac) ++ netdev->features |= NETIF_F_HIGHDMA; + -+ data |= IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } else if (phy->smart_speed == e1000_smart_speed_off) { -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ &data); -+ if (ret_val) -+ return ret_val; ++#ifdef NETIF_F_LLTX ++ /* ++ * We should not be using LLTX anymore, but we are still Tx faster with ++ * it. ++ */ ++ netdev->features |= NETIF_F_LLTX; ++#endif + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, -+ data); -+ if (ret_val) -+ return ret_val; -+ } -+ } else if ((phy->autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || -+ (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || -+ (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { -+ data |= IGP02E1000_PM_D3_LPLU; -+ ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data); -+ if (ret_val) -+ return ret_val; ++ if (e1000_enable_mng_pass_thru(&adapter->hw)) ++ adapter->flags |= FLAG_MNG_PT_ENABLED; + -+ /* When LPLU is enabled, we should disable SmartSpeed */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data); -+ if (ret_val) -+ return ret_val; ++ /* ++ * before reading the NVM, reset the controller to ++ * put the device in a known good starting state ++ */ ++ adapter->hw.mac.ops.reset_hw(&adapter->hw); + -+ data &= ~IGP01E1000_PSCFR_SMART_SPEED; -+ ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data); ++ /* ++ * systems with ASPM and others may see the checksum fail on the first ++ * attempt. Let's give it a few tries ++ */ ++ for (i = 0;; i++) { ++ if (hw->nvm.ops.validate(hw) >= 0) ++ break; ++ if (i == 2) { ++ e_err("The NVM Checksum Is Not Valid\n"); ++ err = -EIO; ++ goto err_eeprom; ++ } + } + -+ return ret_val; -+} ++ /* copy the MAC address out of the NVM */ ++ if (e1000_read_mac_addr(&adapter->hw)) ++ e_err("NVM Read Error while reading MAC address\n"); + -+/** -+ * e1000e_check_downshift - Checks whether a downshift in speed occured -+ * @hw: pointer to the HW structure -+ * -+ * Success returns 0, Failure returns 1 -+ * -+ * A downshift is detected by querying the PHY link health. -+ **/ -+s32 e1000e_check_downshift(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data, offset, mask; ++ 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); + -+ switch (phy->type) { -+ case e1000_phy_m88: -+ case e1000_phy_gg82563: -+ offset = M88E1000_PHY_SPEC_STATUS; -+ mask = M88E1000_PSSR_DOWNSHIFT; -+ break; -+ case e1000_phy_igp_2: -+ case e1000_phy_igp_3: -+ offset = IGP01E1000_PHY_LINK_HEALTH; -+ mask = IGP01E1000_PLHR_SS_DOWNGRADE; -+ break; -+ default: -+ /* speed downshift not supported */ -+ phy->speed_downgraded = 0; -+ return 0; ++ if (!is_valid_ether_addr(netdev->perm_addr)) { ++#else ++ if (!is_valid_ether_addr(netdev->dev_addr)) { ++#endif ++ e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ netdev->dev_addr[0], netdev->dev_addr[1], ++ netdev->dev_addr[2], netdev->dev_addr[3], ++ netdev->dev_addr[4], netdev->dev_addr[5]); ++ err = -EIO; ++ goto err_eeprom; + } + -+ ret_val = e1e_rphy(hw, offset, &phy_data); ++ init_timer(&adapter->watchdog_timer); ++ adapter->watchdog_timer.function = &e1000_watchdog; ++ adapter->watchdog_timer.data = (unsigned long) adapter; + -+ if (!ret_val) -+ phy->speed_downgraded = (phy_data & mask); ++ init_timer(&adapter->phy_info_timer); ++ adapter->phy_info_timer.function = &e1000_update_phy_info; ++ adapter->phy_info_timer.data = (unsigned long) adapter; + -+ return ret_val; -+} ++ INIT_WORK(&adapter->reset_task, e1000_reset_task); ++ INIT_WORK(&adapter->watchdog_task, e1000_watchdog_task); + -+/** -+ * e1000_check_polarity_m88 - Checks the polarity. -+ * @hw: pointer to the HW structure -+ * -+ * Success returns 0, Failure returns -E1000_ERR_PHY (-2) -+ * -+ * Polarity is determined based on the PHY specific status register. -+ **/ -+static s32 e1000_check_polarity_m88(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; ++ /* Initialize link parameters. User can change them with ethtool */ ++ adapter->hw.mac.autoneg = 1; ++ adapter->fc_autoneg = 1; ++ adapter->hw.fc.original_type = e1000_fc_default; ++ adapter->hw.fc.type = e1000_fc_default; ++ adapter->hw.phy.autoneg_advertised = 0x2f; ++ ++ /* ring size defaults */ ++ adapter->rx_ring->count = 256; ++ adapter->tx_ring->count = 256; ++ ++ /* ++ * Initial Wake on LAN setting - If APM wake is enabled in ++ * the EEPROM, enable the ACPI Magic Packet filter ++ */ ++ if (adapter->flags & FLAG_APME_IN_WUC) { ++ /* APME bit in EEPROM is mapped to WUC.APME */ ++ eeprom_data = er32(WUC); ++ eeprom_apme_mask = E1000_WUC_APME; ++ } else if (adapter->flags & FLAG_APME_IN_CTRL3) { ++ if (adapter->flags & FLAG_APME_CHECK_PORT_B && ++ (adapter->hw.bus.func == 1)) ++ hw->nvm.ops.read(&adapter->hw, NVM_INIT_CONTROL3_PORT_B, ++ 1, &eeprom_data); ++ else ++ hw->nvm.ops.read(&adapter->hw, NVM_INIT_CONTROL3_PORT_A, ++ 1, &eeprom_data); ++ } ++ ++ /* fetch WoL from EEPROM */ ++ if (eeprom_data & eeprom_apme_mask) ++ adapter->eeprom_wol |= E1000_WUFC_MAG; + -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &data); ++ /* ++ * 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 ++ */ ++ if (!(adapter->flags & FLAG_HAS_WOL)) ++ adapter->eeprom_wol = 0; + -+ if (!ret_val) -+ phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) -+ ? e1000_rev_polarity_reversed -+ : e1000_rev_polarity_normal; ++ /* initialize the wol settings based on the eeprom settings */ ++ adapter->wol = adapter->eeprom_wol; + -+ return ret_val; -+} ++ /* reset the hardware with the new settings */ ++ e1000_reset(adapter); + -+/** -+ * e1000_check_polarity_igp - Checks the polarity. -+ * @hw: pointer to the HW structure -+ * -+ * Success returns 0, Failure returns -E1000_ERR_PHY (-2) -+ * -+ * Polarity is determined based on the PHY port status register, and the -+ * current speed (since there is no polarity at 100Mbps). -+ **/ -+static s32 e1000_check_polarity_igp(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data, offset, mask; ++ /* ++ * If the controller has 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->flags & FLAG_HAS_AMT)) ++ e1000_get_hw_control(adapter); + -+ /* Polarity is determined based on the speed of -+ * our connection. */ -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data); -+ if (ret_val) -+ return ret_val; ++ /* tell the stack to leave us alone until e1000_open() is called */ ++ netif_carrier_off(netdev); ++ netif_stop_queue(netdev); + -+ if ((data & IGP01E1000_PSSR_SPEED_MASK) == -+ IGP01E1000_PSSR_SPEED_1000MBPS) { -+ offset = IGP01E1000_PHY_PCS_INIT_REG; -+ mask = IGP01E1000_PHY_POLARITY_MASK; -+ } else { -+ /* This really only applies to 10Mbps since -+ * there is no polarity for 100Mbps (always 0). -+ */ -+ offset = IGP01E1000_PHY_PORT_STATUS; -+ mask = IGP01E1000_PSSR_POLARITY_REVERSED; -+ } ++ strcpy(netdev->name, "eth%d"); ++ err = register_netdev(netdev); ++ if (err) ++ goto err_register; + -+ ret_val = e1e_rphy(hw, offset, &data); ++ e1000_print_device_info(adapter); + -+ if (!ret_val) -+ phy->cable_polarity = (data & mask) -+ ? e1000_rev_polarity_reversed -+ : e1000_rev_polarity_normal; ++ return 0; + -+ return ret_val; ++err_register: ++ if (!(adapter->flags & FLAG_HAS_AMT)) ++ e1000_release_hw_control(adapter); ++err_eeprom: ++ if (hw->phy.ops.check_reset_block && ++ !hw->phy.ops.check_reset_block(hw)) ++ hw->phy.ops.reset(hw); ++err_hw_init: ++ hw->mac.ops.remove_device(&adapter->hw); ++ kfree(adapter->tx_ring); ++ kfree(adapter->rx_ring); ++err_sw_init: ++ if (adapter->hw.flash_address) ++ iounmap(adapter->hw.flash_address); ++err_flashmap: ++ iounmap(adapter->hw.hw_addr); ++err_ioremap: ++ free_netdev(netdev); ++err_alloc_etherdev: ++ pci_release_regions(pdev); ++err_pci_reg: ++err_dma: ++ pci_disable_device(pdev); ++ return err; +} + +/** -+ * e1000_wait_autoneg - Wait for auto-neg compeletion -+ * @hw: pointer to the HW structure ++ * e1000_remove - Device Removal Routine ++ * @pdev: PCI device information struct + * -+ * Waits for auto-negotiation to complete or for the auto-negotiation time -+ * limit to expire, which ever happens first. ++ * e1000_remove is called by the PCI subsystem to alert the driver ++ * that it should release a PCI device. The could be caused by a ++ * Hot-Plug event, or because the driver is going to be removed from ++ * memory. + **/ -+static s32 e1000_wait_autoneg(struct e1000_hw *hw) ++static void __devexit e1000_remove(struct pci_dev *pdev) +{ -+ s32 ret_val = 0; -+ u16 i, phy_status; ++ struct net_device *netdev = pci_get_drvdata(pdev); ++ struct e1000_adapter *adapter = netdev_priv(netdev); ++ struct e1000_hw *hw = &adapter->hw; + -+ /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */ -+ for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) { -+ ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); -+ if (ret_val) -+ break; -+ ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); -+ if (ret_val) -+ break; -+ if (phy_status & MII_SR_AUTONEG_COMPLETE) -+ break; -+ msleep(100); -+ } ++ /* ++ * flush_scheduled work may reschedule our watchdog task, so ++ * explicitly disable watchdog tasks from being rescheduled ++ */ ++ set_bit(__E1000_DOWN, &adapter->state); ++ del_timer_sync(&adapter->watchdog_timer); ++ del_timer_sync(&adapter->phy_info_timer); + -+ /* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation -+ * has completed. ++ flush_scheduled_work(); ++ ++ /* ++ * Release control of h/w to f/w. If f/w is AMT enabled, this ++ * would have already happened in close and is redundant. + */ -+ return ret_val; -+} ++ e1000_release_hw_control(adapter); + -+/** -+ * e1000e_phy_has_link_generic - Polls PHY for link -+ * @hw: pointer to the HW structure -+ * @iterations: number of times to poll for link -+ * @usec_interval: delay between polling attempts -+ * @success: pointer to whether polling was successful or not -+ * -+ * Polls the PHY status register for link, 'iterations' number of times. -+ **/ -+s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, -+ u32 usec_interval, bool *success) -+{ -+ s32 ret_val = 0; -+ u16 i, phy_status; ++ unregister_netdev(netdev); + -+ for (i = 0; i < iterations; i++) { -+ /* Some PHYs require the PHY_STATUS register to be read -+ * twice due to the link bit being sticky. No harm doing -+ * it across the board. -+ */ -+ ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); -+ if (ret_val) -+ break; -+ ret_val = e1e_rphy(hw, PHY_STATUS, &phy_status); -+ if (ret_val) -+ break; -+ if (phy_status & MII_SR_LINK_STATUS) -+ break; -+ if (usec_interval >= 1000) -+ mdelay(usec_interval/1000); -+ else -+ udelay(usec_interval); -+ } ++ if (hw->phy.ops.check_reset_block && ++ !hw->phy.ops.check_reset_block(hw)) ++ hw->phy.ops.reset(hw); + -+ *success = (i < iterations); ++#ifdef CONFIG_E1000E_MSIX ++ e1000_reset_interrupt_capability(adapter); ++#endif /* CONFIG_E1000E_MSIX */ ++ hw->mac.ops.remove_device(&adapter->hw); ++ kfree(adapter->tx_ring); ++ kfree(adapter->rx_ring); + -+ return ret_val; -+} ++ iounmap(adapter->hw.hw_addr); ++ if (adapter->hw.flash_address) ++ iounmap(adapter->hw.flash_address); ++ pci_release_regions(pdev); + -+/** -+ * e1000e_get_cable_length_m88 - Determine cable length for m88 PHY -+ * @hw: pointer to the HW structure -+ * -+ * Reads the PHY specific status register to retrieve the cable length -+ * information. The cable length is determined by averaging the minimum and -+ * maximum values to get the "average" cable length. The m88 PHY has four -+ * possible cable length values, which are: -+ * Register Value Cable Length -+ * 0 < 50 meters -+ * 1 50 - 80 meters -+ * 2 80 - 110 meters -+ * 3 110 - 140 meters -+ * 4 > 140 meters -+ **/ -+s32 e1000e_get_cable_length_m88(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data, index; ++ free_netdev(netdev); + -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); -+ if (ret_val) -+ return ret_val; ++ pci_disable_device(pdev); ++} + -+ index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >> -+ M88E1000_PSSR_CABLE_LENGTH_SHIFT; -+ phy->min_cable_length = e1000_m88_cable_length_table[index]; -+ phy->max_cable_length = e1000_m88_cable_length_table[index+1]; ++#ifdef HAVE_PCI_ERS ++/* PCI Error Recovery (ERS) */ ++static struct pci_error_handlers e1000_err_handler = { ++ .error_detected = e1000_io_error_detected, ++ .slot_reset = e1000_io_slot_reset, ++ .resume = e1000_io_resume, ++}; ++#endif + -+ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; ++static struct pci_device_id e1000e_pci_tbl[] = { ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER_LP), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_FIBER), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 }, + -+ return ret_val; -+} ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 }, + -+/** -+ * e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY -+ * @hw: pointer to the HW structure -+ * -+ * The automatic gain control (agc) normalizes the amplitude of the -+ * received signal, adjusting for the attenuation produced by the -+ * cable. By reading the AGC registers, which reperesent the -+ * cobination of course and fine gain value, the value can be put -+ * into a lookup table to obtain the approximate cable length -+ * for each channel. -+ **/ -+s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data, i, agc_value = 0; -+ u16 cur_agc_index, max_agc_index = 0; -+ u16 min_agc_index = IGP02E1000_CABLE_LENGTH_TABLE_SIZE - 1; -+ u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = -+ {IGP02E1000_PHY_AGC_A, -+ IGP02E1000_PHY_AGC_B, -+ IGP02E1000_PHY_AGC_C, -+ IGP02E1000_PHY_AGC_D}; ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 }, + -+ /* Read the AGC registers for all channels */ -+ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { -+ ret_val = e1e_rphy(hw, agc_reg_array[i], &phy_data); -+ if (ret_val) -+ return ret_val; ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82574L), board_82574 }, + -+ /* 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; ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT), ++ board_80003es2lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT), ++ board_80003es2lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_DPT), ++ board_80003es2lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT), ++ board_80003es2lan }, + -+ /* Array index bound check. */ -+ if ((cur_agc_index >= IGP02E1000_CABLE_LENGTH_TABLE_SIZE) || -+ (cur_agc_index == 0)) -+ return -E1000_ERR_PHY; ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_AMT), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan }, + -+ /* 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; ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_BM), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan }, + -+ agc_value += e1000_igp_2_cable_length_table[cur_agc_index]; -+ } ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan }, + -+ 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); ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan }, + -+ /* Calculate cable length with the error range of +/- 10 meters. */ -+ phy->min_cable_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ? -+ (agc_value - IGP02E1000_AGC_RANGE) : 0; -+ phy->max_cable_length = agc_value + IGP02E1000_AGC_RANGE; ++ { } /* terminate list */ ++}; ++MODULE_DEVICE_TABLE(pci, e1000e_pci_tbl); + -+ phy->cable_length = (phy->min_cable_length + phy->max_cable_length) / 2; ++/* PCI Device API Driver */ ++static struct pci_driver e1000_driver = { ++ .name = e1000e_driver_name, ++ .id_table = e1000e_pci_tbl, ++ .probe = e1000_probe, ++ .remove = __devexit_p(e1000_remove), ++#ifdef CONFIG_PM ++ /* Power Management Hooks */ ++ .suspend = e1000_suspend, ++ .resume = e1000_resume, ++#endif ++#ifndef USE_REBOOT_NOTIFIER ++ .shutdown = e1000_shutdown, ++#endif ++#ifdef HAVE_PCI_ERS ++ .err_handler = &e1000_err_handler ++#endif ++}; + -+ return ret_val; ++/** ++ * e1000_init_module - Driver Registration Routine ++ * ++ * e1000_init_module is the first routine called when the driver is ++ * loaded. All it does is register with the PCI subsystem. ++ **/ ++static int __init e1000_init_module(void) ++{ ++ int ret; ++ printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Driver - %s\n", ++ e1000e_driver_name, e1000e_driver_version); ++ printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n", ++ e1000e_driver_name); ++ ret = pci_register_driver(&e1000_driver); ++ pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name, ++ PM_QOS_DEFAULT_VALUE); ++#ifdef USE_REBOOT_NOTIFIER ++ if (ret >= 0) ++ register_reboot_notifier(&e1000_notifier_reboot); ++#endif ++ ++ return ret; +} ++module_init(e1000_init_module); + +/** -+ * e1000e_get_phy_info_m88 - Retrieve PHY information -+ * @hw: pointer to the HW structure ++ * e1000_exit_module - Driver Exit Cleanup Routine + * -+ * Valid for only copper links. Read the PHY status register (sticky read) -+ * to verify that link is up. Read the PHY special control register to -+ * determine the polarity and 10base-T extended distance. Read the PHY -+ * special status register to determine MDI/MDIx and current speed. If -+ * speed is 1000, then determine cable length, local and remote receiver. ++ * e1000_exit_module is called just before the driver is removed ++ * from memory. + **/ -+s32 e1000e_get_phy_info_m88(struct e1000_hw *hw) ++static void __exit e1000_exit_module(void) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 phy_data; -+ bool link; -+ -+ if (hw->media_type != e1000_media_type_copper) { -+ hw_dbg(hw, "Phy info is only valid for copper media\n"); -+ return -E1000_ERR_CONFIG; -+ } ++#ifdef USE_REBOOT_NOTIFIER ++ unregister_reboot_notifier(&e1000_notifier_reboot); ++#endif ++ pci_unregister_driver(&e1000_driver); ++ pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name); ++} ++module_exit(e1000_exit_module); + -+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); -+ if (ret_val) -+ return ret_val; + -+ if (!link) { -+ hw_dbg(hw, "Phy info is only valid if link is up\n"); -+ return -E1000_ERR_CONFIG; -+ } ++MODULE_AUTHOR("Intel Corporation, "); ++MODULE_DESCRIPTION("Intel(R) PRO/1000 Network Driver"); ++MODULE_LICENSE("GPL"); ++MODULE_VERSION(DRV_VERSION); + -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); -+ if (ret_val) -+ return ret_val; ++/* netdev.c */ +diff -Nurp linux-2.6.22-0/drivers/net/e1000e/param.c linux-2.6.22-10/drivers/net/e1000e/param.c +--- linux-2.6.22-0/drivers/net/e1000e/param.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22-10/drivers/net/e1000e/param.c 2008-10-14 01:51:32.000000000 +0200 +@@ -0,0 +1,479 @@ ++/******************************************************************************* + -+ phy->polarity_correction = (phy_data & -+ M88E1000_PSCR_POLARITY_REVERSAL); ++ Intel PRO/1000 Linux driver ++ Copyright(c) 1999 - 2008 Intel Corporation. + -+ ret_val = e1000_check_polarity_m88(hw); -+ if (ret_val) -+ return ret_val; ++ This program is free software; you can redistribute it and/or modify it ++ under the terms and conditions of the GNU General Public License, ++ version 2, as published by the Free Software Foundation. + -+ ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); -+ if (ret_val) -+ return ret_val; ++ This program is distributed in the hope 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. + -+ phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX); ++ 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., ++ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + -+ if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) { -+ ret_val = e1000_get_cable_length(hw); -+ if (ret_val) -+ return ret_val; ++ The full GNU General Public License is included in this distribution in ++ the file called "COPYING". + -+ ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &phy_data); -+ if (ret_val) -+ return ret_val; ++ Contact Information: ++ Linux NICS ++ e1000-devel Mailing List ++ Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + -+ phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS) -+ ? e1000_1000t_rx_status_ok -+ : e1000_1000t_rx_status_not_ok; ++*******************************************************************************/ + -+ phy->remote_rx = (phy_data & SR_1000T_REMOTE_RX_STATUS) -+ ? e1000_1000t_rx_status_ok -+ : e1000_1000t_rx_status_not_ok; -+ } else { -+ /* Set values to "undefined" */ -+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; -+ phy->local_rx = e1000_1000t_rx_status_undefined; -+ phy->remote_rx = e1000_1000t_rx_status_undefined; -+ } ++#include + -+ return ret_val; -+} ++#include "e1000.h" + -+/** -+ * e1000e_get_phy_info_igp - Retrieve igp PHY information -+ * @hw: pointer to the HW structure -+ * -+ * Read PHY status to determine if link is up. If link is up, then -+ * set/determine 10base-T extended distance and polarity correction. Read -+ * PHY port status to determine MDI/MDIx and speed. Based on the speed, -+ * determine on the cable length, local and remote receiver. -+ **/ -+s32 e1000e_get_phy_info_igp(struct e1000_hw *hw) -+{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u16 data; -+ bool link; ++/* ++ * This is the only thing that needs to be changed to adjust the ++ * maximum number of ports that the driver can manage. ++ */ + -+ ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); -+ if (ret_val) -+ return ret_val; ++#define E1000_MAX_NIC 32 + -+ if (!link) { -+ hw_dbg(hw, "Phy info is only valid if link is up\n"); -+ return -E1000_ERR_CONFIG; -+ } ++#define OPTION_UNSET -1 ++#define OPTION_DISABLED 0 ++#define OPTION_ENABLED 1 + -+ phy->polarity_correction = 1; ++#define COPYBREAK_DEFAULT 256 ++unsigned int copybreak = COPYBREAK_DEFAULT; ++module_param(copybreak, uint, 0644); ++MODULE_PARM_DESC(copybreak, ++ "Maximum size of packet that is copied to a new buffer on receive"); + -+ ret_val = e1000_check_polarity_igp(hw); -+ if (ret_val) -+ return ret_val; ++/* ++ * 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). ++ */ + -+ ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data); -+ if (ret_val) -+ return ret_val; ++#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. ++ * The true default values are loaded in when e1000_check_options is called. ++ * ++ * This is a GCC extension to ANSI C. ++ * See the item "Labeled Elements in Initializers" in the section ++ * "Extensions to the C Language Family" of the GCC documentation. ++ */ ++#define E1000_PARAM(X, desc) \ ++ static const int __devinitdata X[E1000_MAX_NIC+1] = E1000_PARAM_INIT; \ ++ static unsigned int num_##X; \ ++ 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 unsigned int num_##X; \ ++ module_param_array_named(X, X, int, &num_##X, 0); \ ++ MODULE_PARM_DESC(X, desc); ++#endif + -+ phy->is_mdix = (data & IGP01E1000_PSSR_MDIX); ++/* ++ * Transmit Interrupt Delay in units of 1.024 microseconds ++ * Tx interrupt delay needs to typically be set to something non zero ++ * ++ * Valid Range: 0-65535 ++ */ ++E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay"); ++#define DEFAULT_TIDV 8 ++#define MAX_TXDELAY 0xFFFF ++#define MIN_TXDELAY 0 + -+ if ((data & IGP01E1000_PSSR_SPEED_MASK) == -+ IGP01E1000_PSSR_SPEED_1000MBPS) { -+ ret_val = e1000_get_cable_length(hw); -+ if (ret_val) -+ return ret_val; ++/* ++ * Transmit Absolute Interrupt Delay in units of 1.024 microseconds ++ * ++ * Valid Range: 0-65535 ++ */ ++E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay"); ++#define DEFAULT_TADV 32 ++#define MAX_TXABSDELAY 0xFFFF ++#define MIN_TXABSDELAY 0 + -+ ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data); -+ if (ret_val) -+ return ret_val; ++/* ++ * Receive Interrupt Delay in units of 1.024 microseconds ++ * hardware will likely hang if you set this to anything but zero. ++ * ++ * Valid Range: 0-65535 ++ */ ++E1000_PARAM(RxIntDelay, "Receive Interrupt Delay"); ++#define DEFAULT_RDTR 0 ++#define MAX_RXDELAY 0xFFFF ++#define MIN_RXDELAY 0 + -+ phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS) -+ ? e1000_1000t_rx_status_ok -+ : e1000_1000t_rx_status_not_ok; ++/* ++ * Receive Absolute Interrupt Delay in units of 1.024 microseconds ++ * ++ * Valid Range: 0-65535 ++ */ ++E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); ++#define DEFAULT_RADV 8 ++#define MAX_RXABSDELAY 0xFFFF ++#define MIN_RXABSDELAY 0 + -+ phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS) -+ ? e1000_1000t_rx_status_ok -+ : e1000_1000t_rx_status_not_ok; -+ } else { -+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED; -+ phy->local_rx = e1000_1000t_rx_status_undefined; -+ phy->remote_rx = e1000_1000t_rx_status_undefined; -+ } ++/* ++ * Interrupt Throttle Rate (interrupts/sec) ++ * ++ * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative) ++ */ ++E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); ++#define DEFAULT_ITR 3 ++#define MAX_ITR 100000 ++#define MIN_ITR 100 + -+ return ret_val; -+} ++#ifdef CONFIG_E1000E_MSIX ++/* IntMode (Interrupt Mode) ++ * ++ * Valid Range: 0 - 2 ++ * ++ * Default Value: 2 (MSI-X) ++ */ ++E1000_PARAM(IntMode, "Interrupt Mode"); ++#define MAX_INTMODE 2 ++#define MIN_INTMODE 0 + -+/** -+ * e1000e_phy_sw_reset - PHY software reset -+ * @hw: pointer to the HW structure ++#endif /* CONFIG_E1000E_MSIX */ ++/* ++ * Enable Smart Power Down of the PHY + * -+ * Does a software reset of the PHY by reading the PHY control register and -+ * setting/write the control register reset bit to the PHY. -+ **/ -+s32 e1000e_phy_sw_reset(struct e1000_hw *hw) -+{ -+ s32 ret_val; -+ u16 phy_ctrl; ++ * Valid Range: 0, 1 ++ * ++ * Default Value: 0 (disabled) ++ */ ++E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down"); + -+ ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl); -+ if (ret_val) -+ return ret_val; ++/* ++ * Enable Kumeran Lock Loss workaround ++ * ++ * Valid Range: 0, 1 ++ * ++ * Default Value: 1 (enabled) ++ */ ++E1000_PARAM(KumeranLockLoss, "Enable Kumeran lock loss workaround"); + -+ phy_ctrl |= MII_CR_RESET; -+ ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl); -+ if (ret_val) -+ return ret_val; ++/* ++ * Write Protect NVM ++ * ++ * Valid Range: 0, 1 ++ * ++ * Default Value: 1 (enabled) ++ */ ++E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can " ++ "lead to corrupted NVM]"); + -+ udelay(1); + -+ return ret_val; -+} ++struct e1000_option { ++ enum { enable_option, range_option, list_option } type; ++ const char *name; ++ const char *err; ++ int def; ++ union { ++ struct { /* range_option info */ ++ int min; ++ int max; ++ } r; ++ struct { /* list_option info */ ++ int nr; ++ struct e1000_opt_list { int i; char *str; } *p; ++ } l; ++ } arg; ++}; + -+/** -+ * e1000e_phy_hw_reset_generic - PHY hardware reset -+ * @hw: pointer to the HW structure -+ * -+ * Verify the reset block is not blocking us from resetting. Acquire -+ * semaphore (if necessary) and read/set/write the device control reset -+ * bit in the PHY. Wait the appropriate delay time for the device to -+ * reset and relase the semaphore (if necessary). -+ **/ -+s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw) ++static int __devinit e1000_validate_option(unsigned int *value, ++ const struct e1000_option *opt, ++ struct e1000_adapter *adapter) +{ -+ struct e1000_phy_info *phy = &hw->phy; -+ s32 ret_val; -+ u32 ctrl; -+ -+ ret_val = e1000_check_reset_block(hw); -+ if (ret_val) ++ if (*value == OPTION_UNSET) { ++ *value = opt->def; + return 0; ++ } + -+ ret_val = phy->ops.acquire_phy(hw); -+ if (ret_val) -+ return ret_val; -+ -+ ctrl = er32(CTRL); -+ ew32(CTRL, ctrl | E1000_CTRL_PHY_RST); -+ e1e_flush(); -+ -+ udelay(phy->reset_delay_us); -+ -+ ew32(CTRL, ctrl); -+ e1e_flush(); -+ -+ udelay(150); ++ switch (opt->type) { ++ case enable_option: ++ switch (*value) { ++ case OPTION_ENABLED: ++ e_info("%s Enabled\n", opt->name); ++ return 0; ++ case OPTION_DISABLED: ++ e_info("%s Disabled\n", opt->name); ++ return 0; ++ } ++ break; ++ case range_option: ++ if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { ++ e_info("%s set to %i\n", opt->name, *value); ++ return 0; ++ } ++ break; ++ case list_option: { ++ int i; ++ struct e1000_opt_list *ent; + -+ phy->ops.release_phy(hw); ++ for (i = 0; i < opt->arg.l.nr; i++) { ++ ent = &opt->arg.l.p[i]; ++ if (*value == ent->i) { ++ if (ent->str[0] != '\0') ++ e_info("%s\n", ent->str); ++ return 0; ++ } ++ } ++ } ++ break; ++ default: ++ BUG(); ++ } + -+ return e1000_get_phy_cfg_done(hw); ++ e_info("Invalid %s value specified (%i) %s\n", opt->name, *value, ++ opt->err); ++ *value = opt->def; ++ return -1; +} + +/** -+ * e1000e_get_cfg_done - Generic configuration done -+ * @hw: pointer to the HW structure ++ * e1000_check_options - Range Checking for Command Line Parameters ++ * @adapter: board private structure + * -+ * Generic function to wait 10 milli-seconds for configuration to complete -+ * and return success. ++ * This routine checks all command line parameters for valid user ++ * input. If an invalid value is given, or if no user specified ++ * value exists, a default value is used. The final value is stored ++ * in a variable in the adapter structure. + **/ -+s32 e1000e_get_cfg_done(struct e1000_hw *hw) ++void __devinit e1000_check_options(struct e1000_adapter *adapter) +{ -+ mdelay(10); -+ return 0; -+} ++ struct e1000_hw *hw = &adapter->hw; ++ int bd = adapter->bd_number; + -+/* Internal function pointers */ ++ if (bd >= E1000_MAX_NIC) { ++ e_notice("Warning: no configuration for board #%i\n", bd); ++ e_notice("Using defaults for all values\n"); ++ } + -+/** -+ * e1000_get_phy_cfg_done - Generic PHY configuration done -+ * @hw: pointer to the HW structure -+ * -+ * Return success if silicon family did not implement a family specific -+ * get_cfg_done function. -+ **/ -+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw) -+{ -+ if (hw->phy.ops.get_cfg_done) -+ return hw->phy.ops.get_cfg_done(hw); ++ { /* Transmit Interrupt Delay */ ++ const struct e1000_option opt = { ++ .type = range_option, ++ .name = "Transmit Interrupt Delay", ++ .err = "using default of " ++ __MODULE_STRING(DEFAULT_TIDV), ++ .def = DEFAULT_TIDV, ++ .arg = { .r = { .min = MIN_TXDELAY, ++ .max = MAX_TXDELAY } } ++ }; + -+ return 0; -+} ++ if (num_TxIntDelay > bd) { ++ adapter->tx_int_delay = TxIntDelay[bd]; ++ e1000_validate_option(&adapter->tx_int_delay, &opt, ++ adapter); ++ } else { ++ adapter->tx_int_delay = opt.def; ++ } ++ } ++ { /* Transmit Absolute Interrupt Delay */ ++ const struct e1000_option opt = { ++ .type = range_option, ++ .name = "Transmit Absolute Interrupt Delay", ++ .err = "using default of " ++ __MODULE_STRING(DEFAULT_TADV), ++ .def = DEFAULT_TADV, ++ .arg = { .r = { .min = MIN_TXABSDELAY, ++ .max = MAX_TXABSDELAY } } ++ }; + -+/** -+ * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex -+ * @hw: pointer to the HW structure -+ * -+ * When the silicon family has not implemented a forced speed/duplex -+ * function for the PHY, simply return 0. -+ **/ -+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw) -+{ -+ if (hw->phy.ops.force_speed_duplex) -+ return hw->phy.ops.force_speed_duplex(hw); ++ if (num_TxAbsIntDelay > bd) { ++ adapter->tx_abs_int_delay = TxAbsIntDelay[bd]; ++ e1000_validate_option(&adapter->tx_abs_int_delay, &opt, ++ adapter); ++ } else { ++ adapter->tx_abs_int_delay = opt.def; ++ } ++ } ++ { /* Receive Interrupt Delay */ ++ struct e1000_option opt = { ++ .type = range_option, ++ .name = "Receive Interrupt Delay", ++ .err = "using default of " ++ __MODULE_STRING(DEFAULT_RDTR), ++ .def = DEFAULT_RDTR, ++ .arg = { .r = { .min = MIN_RXDELAY, ++ .max = MAX_RXDELAY } } ++ }; + -+ return 0; -+} ++ /* ++ * modify min and default if 82573 for slow ping w/a, ++ * a value greater than 8 needs to be set for RDTR ++ */ ++ if (adapter->flags & FLAG_HAS_ASPM) { ++ opt.def = 32; ++ opt.arg.r.min = 8; ++ } + -+/** -+ * e1000e_get_phy_type_from_id - Get PHY type from id -+ * @phy_id: phy_id read from the phy -+ * -+ * Returns the phy type from the id. -+ **/ -+enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id) -+{ -+ enum e1000_phy_type phy_type = e1000_phy_unknown; ++ if (num_RxIntDelay > bd) { ++ adapter->rx_int_delay = RxIntDelay[bd]; ++ e1000_validate_option(&adapter->rx_int_delay, &opt, ++ adapter); ++ } else { ++ adapter->rx_int_delay = opt.def; ++ } ++ } ++ { /* Receive Absolute Interrupt Delay */ ++ const struct e1000_option opt = { ++ .type = range_option, ++ .name = "Receive Absolute Interrupt Delay", ++ .err = "using default of " ++ __MODULE_STRING(DEFAULT_RADV), ++ .def = DEFAULT_RADV, ++ .arg = { .r = { .min = MIN_RXABSDELAY, ++ .max = MAX_RXABSDELAY } } ++ }; + -+ switch (phy_id) { -+ case M88E1000_I_PHY_ID: -+ case M88E1000_E_PHY_ID: -+ case M88E1111_I_PHY_ID: -+ case M88E1011_I_PHY_ID: -+ phy_type = e1000_phy_m88; -+ break; -+ case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */ -+ phy_type = e1000_phy_igp_2; -+ break; -+ case GG82563_E_PHY_ID: -+ phy_type = e1000_phy_gg82563; -+ break; -+ case IGP03E1000_E_PHY_ID: -+ phy_type = e1000_phy_igp_3; -+ break; -+ case IFE_E_PHY_ID: -+ case IFE_PLUS_E_PHY_ID: -+ case IFE_C_E_PHY_ID: -+ phy_type = e1000_phy_ife; -+ break; -+ default: -+ phy_type = e1000_phy_unknown; -+ break; ++ if (num_RxAbsIntDelay > bd) { ++ adapter->rx_abs_int_delay = RxAbsIntDelay[bd]; ++ e1000_validate_option(&adapter->rx_abs_int_delay, &opt, ++ adapter); ++ } else { ++ adapter->rx_abs_int_delay = opt.def; ++ } + } -+ return phy_type; -+} ++ { /* Interrupt Throttling Rate */ ++ const struct e1000_option opt = { ++ .type = range_option, ++ .name = "Interrupt Throttling Rate (ints/sec)", ++ .err = "using default of " ++ __MODULE_STRING(DEFAULT_ITR), ++ .def = DEFAULT_ITR, ++ .arg = { .r = { .min = MIN_ITR, ++ .max = MAX_ITR } } ++ }; + -+/** -+ * e1000e_commit_phy - Soft PHY reset -+ * @hw: pointer to the HW structure -+ * -+ * Performs a soft PHY reset on those that apply. This is a function pointer -+ * entry point called by drivers. -+ **/ -+s32 e1000e_commit_phy(struct e1000_hw *hw) -+{ -+ if (hw->phy.ops.commit_phy) -+ return hw->phy.ops.commit_phy(hw); ++ if (num_InterruptThrottleRate > bd) { ++ adapter->itr = InterruptThrottleRate[bd]; ++ switch (adapter->itr) { ++ case 0: ++ e_info("%s turned off\n", opt.name); ++ break; ++ case 1: ++ e_info("%s set to dynamic mode\n", opt.name); ++ adapter->itr_setting = adapter->itr; ++ adapter->itr = 20000; ++ break; ++ case 3: ++ e_info("%s set to dynamic conservative mode\n", ++ opt.name); ++ adapter->itr_setting = adapter->itr; ++ adapter->itr = 20000; ++ break; ++ default: ++ /* ++ * Save the setting, because the dynamic bits ++ * change itr. ++ */ ++ if (e1000_validate_option(&adapter->itr, &opt, ++ adapter) && ++ (adapter->itr == 3)) { ++ /* ++ * In case of invalid user value, ++ * default to conservative mode. ++ */ ++ adapter->itr_setting = adapter->itr; ++ adapter->itr = 20000; ++ } else { ++ /* ++ * Clear the lower two bits because ++ * they are used as control. ++ */ ++ adapter->itr_setting = ++ adapter->itr & ~3; ++ } ++ break; ++ } ++ } else { ++ adapter->itr_setting = opt.def; ++ adapter->itr = 20000; ++ } ++ } ++#ifdef CONFIG_E1000E_MSIX ++ { /* Interrupt Mode */ ++ struct e1000_option opt = { ++ .type = range_option, ++ .name = "Interrupt Mode", ++ .err = "defaulting to 2 (MSI-X)", ++ .def = E1000E_INT_MODE_MSIX, ++ .arg = { .r = { .min = MIN_INTMODE, ++ .max = MAX_INTMODE }} ++ }; + -+ return 0; -+} ++ if (num_IntMode > bd) { ++ unsigned int int_mode = IntMode[bd]; ++ e1000_validate_option(&int_mode, &opt, adapter); ++ adapter->int_mode = int_mode; ++ } else { ++ adapter->int_mode = opt.def; ++ } ++ } ++#endif /* CONFIG_E1000E_MSIX */ ++ { /* Smart Power Down */ ++ const struct e1000_option opt = { ++ .type = enable_option, ++ .name = "PHY Smart Power Down", ++ .err = "defaulting to Disabled", ++ .def = OPTION_DISABLED ++ }; + -+/** -+ * e1000_set_d0_lplu_state - Sets low power link up state for D0 -+ * @hw: pointer to the HW structure -+ * @active: boolean used to enable/disable lplu -+ * -+ * Success returns 0, Failure returns 1 -+ * -+ * The low power link up (lplu) state is set to the power management level D0 -+ * and SmartSpeed is disabled when active is true, else clear lplu for D0 -+ * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU -+ * is used during Dx states where the power conservation is most important. -+ * During driver activity, SmartSpeed should be enabled so performance is -+ * maintained. This is a function pointer entry point called by drivers. -+ **/ -+static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) -+{ -+ if (hw->phy.ops.set_d0_lplu_state) -+ return hw->phy.ops.set_d0_lplu_state(hw, active); ++ if (num_SmartPowerDownEnable > bd) { ++ unsigned int spd = SmartPowerDownEnable[bd]; ++ e1000_validate_option(&spd, &opt, adapter); ++ if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) ++ && spd) ++ adapter->flags |= FLAG_SMART_POWER_DOWN; ++ } ++ } ++ { /* Kumeran Lock Loss Workaround */ ++ const struct e1000_option opt = { ++ .type = enable_option, ++ .name = "Kumeran Lock Loss Workaround", ++ .err = "defaulting to Enabled", ++ .def = OPTION_ENABLED ++ }; + -+ return 0; ++ if (num_KumeranLockLoss > bd) { ++ unsigned int kmrn_lock_loss = KumeranLockLoss[bd]; ++ e1000_validate_option(&kmrn_lock_loss, &opt, adapter); ++ if (hw->mac.type == e1000_ich8lan) ++ e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, ++ kmrn_lock_loss); ++ } else { ++ if (hw->mac.type == e1000_ich8lan) ++ e1000_set_kmrn_lock_loss_workaround_ich8lan(hw, ++ opt.def); ++ } ++ } ++ { /* Write-protect NVM */ ++ const struct e1000_option opt = { ++ .type = enable_option, ++ .name = "Write-protect NVM", ++ .err = "defaulting to Enabled", ++ .def = OPTION_ENABLED ++ }; ++ ++ if (adapter->flags & FLAG_IS_ICH) { ++ if (num_WriteProtectNVM > bd) { ++ unsigned int write_protect_nvm = WriteProtectNVM[bd]; ++ e1000_validate_option(&write_protect_nvm, &opt, ++ adapter); ++ if (write_protect_nvm) ++ adapter->flags2 |= FLAG2_READ_ONLY_NVM; ++ } else { ++ if (opt.def) ++ adapter->flags2 |= FLAG2_READ_ONLY_NVM; ++ } ++ } ++ } +} diff -Nurp linux-2.6.22-0/drivers/net/Kconfig linux-2.6.22-10/drivers/net/Kconfig ---- linux-2.6.22-0/drivers/net/Kconfig 2007-07-21 18:00:07.000000000 -0400 -+++ linux-2.6.22-10/drivers/net/Kconfig 2007-11-21 13:55:13.000000000 -0500 +--- linux-2.6.22-0/drivers/net/Kconfig 2007-07-09 01:32:17.000000000 +0200 ++++ linux-2.6.22-10/drivers/net/Kconfig 2008-11-10 00:06:46.000000000 +0100 @@ -1993,6 +1993,29 @@ config E1000_DISABLE_PACKET_SPLIT If in doubt, say N. @@ -17900,8 +26668,8 @@ diff -Nurp linux-2.6.22-0/drivers/net/Kconfig linux-2.6.22-10/drivers/net/Kconfi config MYRI_SBUS diff -Nurp linux-2.6.22-0/drivers/net/Makefile linux-2.6.22-10/drivers/net/Makefile ---- linux-2.6.22-0/drivers/net/Makefile 2007-07-21 18:00:07.000000000 -0400 -+++ linux-2.6.22-10/drivers/net/Makefile 2007-11-21 13:55:13.000000000 -0500 +--- linux-2.6.22-0/drivers/net/Makefile 2007-07-09 01:32:17.000000000 +0200 ++++ linux-2.6.22-10/drivers/net/Makefile 2008-11-10 00:02:57.000000000 +0100 @@ -3,6 +3,7 @@ # -- 2.43.0