diff options
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/82571.c | 70 | ||||
-rw-r--r-- | drivers/net/e1000e/defines.h | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 21 | ||||
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 34 | ||||
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 13 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 79 | ||||
-rw-r--r-- | drivers/net/e1000e/lib.c | 282 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 132 | ||||
-rw-r--r-- | drivers/net/e1000e/phy.c | 85 |
10 files changed, 397 insertions, 323 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index b979464091bb..3c95acb3a87d 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -237,6 +237,8 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* check for link */ switch (hw->phy.media_type) { @@ -265,8 +267,14 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) } switch (hw->mac.type) { + case e1000_82573: + func->set_lan_id = e1000_set_lan_id_single_port; + func->check_mng_mode = e1000e_check_mng_mode_generic; + func->led_on = e1000e_led_on_generic; + break; case e1000_82574: case e1000_82583: + func->set_lan_id = e1000_set_lan_id_single_port; func->check_mng_mode = e1000_check_mng_mode_82574; func->led_on = e1000_led_on_82574; break; @@ -920,9 +928,12 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) ew32(IMC, 0xffffffff); icr = er32(ICR); - if (hw->mac.type == e1000_82571 && - hw->dev_spec.e82571.alt_mac_addr_is_present) - e1000e_set_laa_state_82571(hw, true); + /* Install any alternate MAC address into RAR0 */ + ret_val = e1000_check_alt_mac_addr_generic(hw); + if (ret_val) + return ret_val; + + e1000e_set_laa_state_82571(hw, true); /* Reinitialize the 82571 serdes link state machine */ if (hw->phy.media_type == e1000_media_type_internal_serdes) @@ -1223,32 +1234,6 @@ static s32 e1000_led_on_82574(struct e1000_hw *hw) } /** - * 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) -{ - if (e1000e_get_laa_state_82571(hw)) - rar_count--; - - e1000e_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count, - rar_used_count, rar_count); -} - -/** * e1000_setup_link_82571 - Setup flow control and link settings * @hw: pointer to the HW structure * @@ -1619,6 +1604,29 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) } /** + * e1000_read_mac_addr_82571 - Read device MAC address + * @hw: pointer to the HW structure + **/ +static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) +{ + s32 ret_val = 0; + + /* + * If there's an alternate MAC address place it in RAR0 + * so that it will override the Si installed default perm + * address. + */ + ret_val = e1000_check_alt_mac_addr_generic(hw); + if (ret_val) + goto out; + + ret_val = e1000_read_mac_addr_generic(hw); + +out: + return ret_val; +} + +/** * e1000_power_down_phy_copper_82571 - Remove link during PHY power down * @hw: pointer to the HW structure * @@ -1693,10 +1701,11 @@ static struct e1000_mac_operations e82571_mac_ops = { .cleanup_led = e1000e_cleanup_led_generic, .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, .get_bus_info = e1000e_get_bus_info_pcie, + .set_lan_id = e1000_set_lan_id_multi_port_pcie, /* .get_link_up_info: media type dependent */ /* .led_on: mac type dependent */ .led_off = e1000e_led_off_generic, - .update_mc_addr_list = e1000_update_mc_addr_list_82571, + .update_mc_addr_list = e1000e_update_mc_addr_list_generic, .write_vfta = e1000_write_vfta_generic, .clear_vfta = e1000_clear_vfta_82571, .reset_hw = e1000_reset_hw_82571, @@ -1704,6 +1713,7 @@ static struct e1000_mac_operations e82571_mac_ops = { .setup_link = e1000_setup_link_82571, /* .setup_physical_interface: media type dependent */ .setup_led = e1000e_setup_led_generic, + .read_mac_addr = e1000_read_mac_addr_82571, }; static struct e1000_phy_operations e82_phy_ops_igp = { diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index e02e38221ed4..db05ec355749 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -460,6 +460,8 @@ */ #define E1000_RAR_ENTRIES 15 #define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */ +#define E1000_RAL_MAC_ADDR_LEN 4 +#define E1000_RAH_MAC_ADDR_LEN 2 /* Error Codes */ #define E1000_ERR_NVM 1 diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index cebbd9079d53..c2ec095d2163 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -421,6 +421,7 @@ struct e1000_info { /* CRC Stripping defines */ #define FLAG2_CRC_STRIPPING (1 << 0) #define FLAG2_HAS_PHY_WAKEUP (1 << 1) +#define FLAG2_IS_DISCARDING (1 << 2) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) @@ -458,7 +459,7 @@ 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); -extern bool e1000_has_link(struct e1000_adapter *adapter); +extern bool e1000e_has_link(struct e1000_adapter *adapter); extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); @@ -502,6 +503,8 @@ 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 void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw); +extern void e1000_set_lan_id_single_port(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); @@ -516,9 +519,7 @@ extern void e1000_clear_vfta_generic(struct e1000_hw *hw); extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count); extern void e1000e_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 mc_addr_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); @@ -529,6 +530,7 @@ 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 e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); +extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw); extern void e1000e_reset_adaptive(struct e1000_hw *hw); extern void e1000e_update_adaptive(struct e1000_hw *hw); @@ -582,7 +584,6 @@ extern s32 e1000_read_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data); extern s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data); -extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow); extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw); extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw); extern s32 e1000_check_polarity_82577(struct e1000_hw *hw); @@ -629,7 +630,15 @@ extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 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); +extern s32 e1000_read_mac_addr_generic(struct e1000_hw *hw); + +static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw) +{ + if (hw->mac.ops.read_mac_addr) + return hw->mac.ops.read_mac_addr(hw); + + return e1000_read_mac_addr_generic(hw); +} static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) { diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 3028f23da891..27d21589a69a 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -224,6 +224,8 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? true : false; + /* Adaptive IFS not supported */ + mac->adaptive_ifs = false; /* check for link */ switch (hw->phy.media_type) { @@ -244,6 +246,9 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter) break; } + /* set lan id for port to determine which phy lock to use */ + hw->mac.ops.set_lan_id(hw); + return 0; } @@ -812,7 +817,9 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) ew32(IMC, 0xffffffff); icr = er32(ICR); - return 0; + ret_val = e1000_check_alt_mac_addr_generic(hw); + + return ret_val; } /** @@ -1338,6 +1345,29 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, } /** + * e1000_read_mac_addr_80003es2lan - Read device MAC address + * @hw: pointer to the HW structure + **/ +static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) +{ + s32 ret_val = 0; + + /* + * If there's an alternate MAC address place it in RAR0 + * so that it will override the Si installed default perm + * address. + */ + ret_val = e1000_check_alt_mac_addr_generic(hw); + if (ret_val) + goto out; + + ret_val = e1000_read_mac_addr_generic(hw); + +out: + return ret_val; +} + +/** * e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down * @hw: pointer to the HW structure * @@ -1401,12 +1431,14 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) } static struct e1000_mac_operations es2_mac_ops = { + .read_mac_addr = e1000_read_mac_addr_80003es2lan, .id_led_init = e1000e_id_led_init, .check_mng_mode = e1000e_check_mng_mode_generic, /* 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, + .set_lan_id = e1000_set_lan_id_multi_port_pcie, .get_link_up_info = e1000_get_link_up_info_80003es2lan, .led_on = e1000e_led_on_generic, .led_off = e1000e_led_off_generic, diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 0aa50c229c79..b33e3cbe9ab0 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -202,7 +202,7 @@ static u32 e1000_get_link(struct net_device *netdev) if (!netif_carrier_ok(netdev)) mac->get_link_status = 1; - return e1000_has_link(adapter); + return e1000e_has_link(adapter); } static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index 2784cf44a6f3..8bdcd5f24eff 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -389,6 +389,9 @@ enum e1e_registers { #define E1000_FUNC_1 1 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0 +#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3 + enum e1000_mac_type { e1000_82571, e1000_82572, @@ -746,16 +749,18 @@ struct e1000_mac_operations { void (*clear_hw_cntrs)(struct e1000_hw *); void (*clear_vfta)(struct e1000_hw *); s32 (*get_bus_info)(struct e1000_hw *); + void (*set_lan_id)(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 (*update_mc_addr_list)(struct e1000_hw *, u8 *, 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 *); s32 (*setup_led)(struct e1000_hw *); void (*write_vfta)(struct e1000_hw *, u32, u32); + s32 (*read_mac_addr)(struct e1000_hw *); }; /* Function pointers for the PHY. */ @@ -814,10 +819,15 @@ struct e1000_mac_info { u16 ifs_ratio; u16 ifs_step_size; u16 mta_reg_count; + + /* Maximum size of the MTA register table in all supported adapters */ + #define MAX_MTA_REG 128 + u32 mta_shadow[MAX_MTA_REG]; u16 rar_entry_count; u8 forced_speed_duplex; + bool adaptive_ifs; bool arc_subsystem_valid; bool autoneg; bool autoneg_failed; @@ -896,7 +906,6 @@ struct e1000_fc_info { struct e1000_dev_spec_82571 { bool laa_is_present; - bool alt_mac_addr_is_present; u32 smb_counter; }; diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 9b09246af064..54d03a0ce3ce 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -138,6 +138,10 @@ #define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */ #define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */ +/* KMRN Mode Control */ +#define HV_KMRN_MODE_CTRL PHY_REG(769, 16) +#define HV_KMRN_MDIO_SLOW 0x0400 + /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ union ich8_hws_flash_status { @@ -219,6 +223,7 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active); static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw); static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link); +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg) { @@ -270,7 +275,21 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->id = e1000_phy_unknown; - e1000e_get_phy_id(hw); + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { + /* + * In case the PHY needs to be in mdio slow mode (eg. 82577), + * set slow mode and try to get the PHY id again. + */ + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + } phy->type = e1000e_get_phy_type_from_id(phy->id); switch (phy->type) { @@ -292,6 +311,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) break; } +out: return ret_val; } @@ -454,6 +474,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter) mac->rar_entry_count--; /* Set if manageability features are enabled. */ mac->arc_subsystem_valid = true; + /* Adaptive IFS supported */ + mac->adaptive_ifs = true; /* LED operations */ switch (mac->type) { @@ -1074,16 +1096,44 @@ out: /** + * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode + * @hw: pointer to the HW structure + **/ +static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw) +{ + s32 ret_val; + u16 data; + + ret_val = e1e_rphy(hw, HV_KMRN_MODE_CTRL, &data); + if (ret_val) + return ret_val; + + data |= HV_KMRN_MDIO_SLOW; + + ret_val = e1e_wphy(hw, HV_KMRN_MODE_CTRL, data); + + return ret_val; +} + +/** * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be * done after every PHY reset. **/ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) { s32 ret_val = 0; + u16 phy_data; if (hw->mac.type != e1000_pchlan) return ret_val; + /* Set MDIO slow mode before any other MDIO access */ + if (hw->phy.type == e1000_phy_82577) { + ret_val = e1000_set_mdio_slow_mode_hv(hw); + if (ret_val) + goto out; + } + if (((hw->phy.type == e1000_phy_82577) && ((hw->phy.revision == 1) || (hw->phy.revision == 2))) || ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) { @@ -1116,16 +1166,32 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw) hw->phy.addr = 1; ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0); + hw->phy.ops.release(hw); if (ret_val) goto out; - hw->phy.ops.release(hw); /* * Configure the K1 Si workaround during phy reset assuming there is * link so that it disables K1 if link is in 1Gbps. */ ret_val = e1000_k1_gig_workaround_hv(hw, true); + if (ret_val) + goto out; + /* Workaround for link disconnects on a busy hub in half duplex */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.read_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + &phy_data); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, + PHY_REG(BM_PORT_CTRL_PAGE, 17), + phy_data & 0x00FF); +release: + hw->phy.ops.release(hw); out: return ret_val; } @@ -1182,6 +1248,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) /* Allow time for h/w to get to a quiescent state after reset */ mdelay(10); + /* Perform any necessary post-reset workarounds */ if (hw->mac.type == e1000_pchlan) { ret_val = e1000_hv_phy_workarounds_ich8lan(hw); if (ret_val) @@ -2482,6 +2549,10 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) if (!ret_val) e1000_release_swflag_ich8lan(hw); + /* Perform any necessary post-reset workarounds */ + if (hw->mac.type == e1000_pchlan) + ret_val = e1000_hv_phy_workarounds_ich8lan(hw); + if (ctrl & E1000_CTRL_PHY_RST) ret_val = hw->phy.ops.get_cfg_done(hw); @@ -2526,9 +2597,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) kab |= E1000_KABGTXD_BGSQLBIAS; ew32(KABGTXD, kab); - if (hw->mac.type == e1000_pchlan) - ret_val = e1000_hv_phy_workarounds_ich8lan(hw); - out: return ret_val; } @@ -3300,6 +3368,7 @@ static struct e1000_mac_operations ich8_mac_ops = { /* cleanup_led dependent on mac type */ .clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan, .get_bus_info = e1000_get_bus_info_ich8lan, + .set_lan_id = e1000_set_lan_id_single_port, .get_link_up_info = e1000_get_link_up_info_ich8lan, /* led_on dependent on mac type */ /* led_off dependent on mac type */ diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index a86c17548c1e..2425ed11d5cc 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -51,10 +51,10 @@ enum e1000_mng_mode { **/ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) { + struct e1000_mac_info *mac = &hw->mac; struct e1000_bus_info *bus = &hw->bus; struct e1000_adapter *adapter = hw->adapter; - u32 status; - u16 pcie_link_status, pci_header_type, cap_offset; + u16 pcie_link_status, cap_offset; cap_offset = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP); if (!cap_offset) { @@ -68,20 +68,46 @@ s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) PCIE_LINK_WIDTH_SHIFT); } - 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; - } + mac->ops.set_lan_id(hw); return 0; } /** + * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices + * + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers + * and swaps the port value if requested. + **/ +void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + u32 reg; + + /* + * The status register reports the correct function number + * for the device regardless of function swap state. + */ + reg = er32(STATUS); + bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; +} + +/** + * e1000_set_lan_id_single_port - Set LAN id for a single port device + * @hw: pointer to the HW structure + * + * Sets the LAN function id to zero for a single port device. + **/ +void e1000_set_lan_id_single_port(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + + bus->func = 0; +} + +/** * e1000_clear_vfta_generic - Clear VLAN filter table * @hw: pointer to the HW structure * @@ -125,6 +151,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) { u32 i; + u8 mac_addr[ETH_ALEN] = {0}; /* Setup the receive address */ e_dbg("Programming MAC Address into RAR[0]\n"); @@ -133,12 +160,70 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) /* Zero out the other (rar_entry_count - 1) receive addresses */ e_dbg("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(); + for (i = 1; i < rar_count; i++) + e1000e_rar_set(hw, mac_addr, i); +} + +/** + * 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 programmed into RAR0, replacing + * the permanent address that was installed into RAR0 by the Si on reset. + * This function will return SUCCESS unless it encounters an error while + * reading the EEPROM. + **/ +s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) +{ + u32 i; + s32 ret_val = 0; + u16 offset, nvm_alt_mac_addr_offset, nvm_data; + u8 alt_mac_addr[ETH_ALEN]; + + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, + &nvm_alt_mac_addr_offset); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if (nvm_alt_mac_addr_offset == 0xFFFF) { + /* There is no Alternate MAC Address */ + goto out; + } + + if (hw->bus.func == E1000_FUNC_1) + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; + for (i = 0; i < ETH_ALEN; i += 2) { + offset = nvm_alt_mac_addr_offset + (i >> 1); + ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + if (ret_val) { + e_dbg("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) { + e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); + goto out; } + + /* + * We have a valid alternate MAC address, and we want to treat it the + * same as the normal permanent MAC address stored by the HW into the + * RAR. Do this by mapping this address into RAR0. + */ + e1000e_rar_set(hw, alt_mac_addr, 0); + +out: + return ret_val; } /** @@ -164,10 +249,19 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); - rar_high |= E1000_RAH_AV; + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) + rar_high |= E1000_RAH_AV; - E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); - E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); + /* + * Some bridges will combine consecutive 32-bit writes into + * a single burst write, which will malfunction on some parts. + * The flushes avoid this. + */ + ew32(RAL(index), rar_low); + e1e_flush(); + ew32(RAH(index), rar_high); + e1e_flush(); } /** @@ -246,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) * @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. + * Updates entire 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_update_mc_addr_list_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count, - u32 rar_used_count, u32 rar_count) + u8 *mc_addr_list, u32 mc_addr_count) { - u32 i; - u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC); + u32 hash_value, hash_bit, hash_reg; + int i; - if (!mcarray) { - printk(KERN_ERR "multicast array memory allocation failed\n"); - return; - } - - /* - * 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(); - } - } + /* clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); - /* Load any remaining multicast addresses into the hash table. */ - for (; mc_addr_count > 0; mc_addr_count--) { - u32 hash_value, hash_reg, hash_bit, mta; + /* update mta_shadow from mc_addr_list */ + for (i = 0; (u32) i < mc_addr_count; i++) { hash_value = e1000_hash_mc_addr(hw, mc_addr_list); - e_dbg("Hash value = 0x%03X\n", hash_value); + hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); hash_bit = hash_value & 0x1F; - mta = (1 << hash_bit); - mcarray[hash_reg] |= mta; - mc_addr_list += ETH_ALEN; - } - /* write the hash table completely */ - for (i = 0; i < hw->mac.mta_reg_count; i++) - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]); + hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); + mc_addr_list += (ETH_ALEN); + } + /* replace the entire MTA table */ + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); e1e_flush(); - kfree(mcarray); } /** @@ -1609,6 +1675,11 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + mac->current_ifs_val = 0; mac->ifs_min_val = IFS_MIN; mac->ifs_max_val = IFS_MAX; @@ -1617,6 +1688,8 @@ void e1000e_reset_adaptive(struct e1000_hw *hw) mac->in_ifs_mode = false; ew32(AIT, 0); +out: + return; } /** @@ -1630,6 +1703,11 @@ void e1000e_update_adaptive(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + if (!mac->adaptive_ifs) { + e_dbg("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; @@ -1650,6 +1728,8 @@ void e1000e_update_adaptive(struct e1000_hw *hw) ew32(AIT, 0); } } +out: + return; } /** @@ -2052,67 +2132,27 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) } /** - * e1000e_read_mac_addr - Read device MAC address + * 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 e1000e_read_mac_addr(struct e1000_hw *hw) +s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) { - s32 ret_val; - u16 offset, nvm_data, i; - u16 mac_addr_offset = 0; - - if (hw->mac.type == e1000_82571) { - /* Check 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.*/ - ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, - &mac_addr_offset); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - if (mac_addr_offset == 0xFFFF) - mac_addr_offset = 0; - - if (mac_addr_offset) { - if (hw->bus.func == E1000_FUNC_1) - mac_addr_offset += ETH_ALEN/sizeof(u16); - - /* make sure we have a valid mac address here - * before using it */ - ret_val = e1000_read_nvm(hw, mac_addr_offset, 1, - &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - if (nvm_data & 0x0001) - mac_addr_offset = 0; - } + u32 rar_high; + u32 rar_low; + u16 i; - if (mac_addr_offset) - hw->dev_spec.e82571.alt_mac_addr_is_present = 1; - } + rar_high = er32(RAH(0)); + rar_low = er32(RAL(0)); - for (i = 0; i < ETH_ALEN; i += 2) { - offset = mac_addr_offset + (i >> 1); - ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); - if (ret_val) { - e_dbg("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); - } + for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); - /* Flip last bit of mac address if we're on second port */ - if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1) - hw->mac.perm_addr[5] ^= 1; + for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); for (i = 0; i < ETH_ALEN; i++) hw->mac.addr[i] = hw->mac.perm_addr[i]; @@ -2287,10 +2327,12 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) s32 ret_val, hdr_csum, csum; u8 i, len; + hw->mac.tx_pkt_filtering = true; + /* No manageability, no filtering */ if (!e1000e_check_mng_mode(hw)) { hw->mac.tx_pkt_filtering = false; - return 0; + goto out; } /* @@ -2298,9 +2340,9 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) * reason, disable filtering. */ ret_val = e1000_mng_enable_host_if(hw); - if (ret_val != 0) { + if (ret_val) { hw->mac.tx_pkt_filtering = false; - return ret_val; + goto out; } /* Read in the header. Length and offset are in dwords. */ @@ -2319,17 +2361,17 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) */ if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { hw->mac.tx_pkt_filtering = true; - return 1; + goto out; } /* Cookie area is valid, make the final check for filtering. */ if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { hw->mac.tx_pkt_filtering = false; - return 0; + goto out; } - hw->mac.tx_pkt_filtering = true; - return 1; +out: + return hw->mac.tx_pkt_filtering; } /** diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 762b697ce731..88d54d3efcef 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -450,13 +450,23 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, 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)) { + /* + * !EOP means multiple descriptors were used to store a single + * packet, if that's the case we need to toss it. In fact, we + * need to toss every packet with the EOP bit clear and the + * next frame that _does_ have the EOP bit set, as it is by + * definition only a frame fragment + */ + if (unlikely(!(status & E1000_RXD_STAT_EOP))) + adapter->flags2 |= FLAG2_IS_DISCARDING; + + if (adapter->flags2 & FLAG2_IS_DISCARDING) { /* All receives must fit into a single buffer */ e_dbg("Receive packet consumed multiple buffers\n"); /* recycle */ buffer_info->skb = skb; + if (status & E1000_RXD_STAT_EOP) + adapter->flags2 &= ~FLAG2_IS_DISCARDING; goto next_desc; } @@ -745,10 +755,16 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, PCI_DMA_FROMDEVICE); buffer_info->dma = 0; - if (!(staterr & E1000_RXD_STAT_EOP)) { + /* see !EOP comment in other rx routine */ + if (!(staterr & E1000_RXD_STAT_EOP)) + adapter->flags2 |= FLAG2_IS_DISCARDING; + + if (adapter->flags2 & FLAG2_IS_DISCARDING) { e_dbg("Packet Split buffers didn't pick up the full " "packet\n"); dev_kfree_skb_irq(skb); + if (staterr & E1000_RXD_STAT_EOP) + adapter->flags2 &= ~FLAG2_IS_DISCARDING; goto next_desc; } @@ -1118,6 +1134,7 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) rx_ring->next_to_clean = 0; rx_ring->next_to_use = 0; + adapter->flags2 &= ~FLAG2_IS_DISCARDING; writel(0, adapter->hw.hw_addr + rx_ring->head); writel(0, adapter->hw.hw_addr + rx_ring->tail); @@ -2333,18 +2350,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) 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; @@ -2536,22 +2541,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) * @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. + * Updates the 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. **/ static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, - u32 mc_addr_count, u32 rar_used_count, - u32 rar_count) + u32 mc_addr_count) { - hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count, - rar_used_count, rar_count); + hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count); } /** @@ -2567,7 +2564,6 @@ 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; @@ -2593,31 +2589,25 @@ static void e1000_set_multi(struct net_device *netdev) ew32(RCTL, rctl); - if (netdev->mc_count) { - mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC); + if (!netdev_mc_empty(netdev)) { + mta_list = kmalloc(netdev_mc_count(netdev) * 6, GFP_ATOMIC); if (!mta_list) return; /* prepare a packed array of only addresses. */ - mc_ptr = netdev->mc_list; - - 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; - } + i = 0; + netdev_for_each_mc_addr(mc_ptr, netdev) + memcpy(mta_list + (i++ * ETH_ALEN), + mc_ptr->dmi_addr, ETH_ALEN); - e1000_update_mc_addr_list(hw, mta_list, i, 1, - mac->rar_entry_count); + e1000_update_mc_addr_list(hw, mta_list, i); kfree(mta_list); } else { /* * if we're called from probe, we might not have * anything to do here, so clear out the list */ - e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count); + e1000_update_mc_addr_list(hw, NULL, 0); } } @@ -3315,24 +3305,24 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_SCC_UPPER, &phy_data); - e1e_rphy(hw, HV_SCC_LOWER, &phy_data); - adapter->stats.scc += phy_data; + if (!e1e_rphy(hw, HV_SCC_LOWER, &phy_data)) + adapter->stats.scc += phy_data; e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); - adapter->stats.ecol += phy_data; + if (!e1e_rphy(hw, HV_ECOL_LOWER, &phy_data)) + adapter->stats.ecol += phy_data; e1e_rphy(hw, HV_MCC_UPPER, &phy_data); - e1e_rphy(hw, HV_MCC_LOWER, &phy_data); - adapter->stats.mcc += phy_data; + if (!e1e_rphy(hw, HV_MCC_LOWER, &phy_data)) + adapter->stats.mcc += phy_data; e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); - e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); - adapter->stats.latecol += phy_data; + if (!e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data)) + adapter->stats.latecol += phy_data; e1e_rphy(hw, HV_DC_UPPER, &phy_data); - e1e_rphy(hw, HV_DC_LOWER, &phy_data); - adapter->stats.dc += phy_data; + if (!e1e_rphy(hw, HV_DC_LOWER, &phy_data)) + adapter->stats.dc += phy_data; } else { adapter->stats.scc += er32(SCC); adapter->stats.ecol += er32(ECOL); @@ -3360,8 +3350,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_COLC_UPPER, &phy_data); - e1e_rphy(hw, HV_COLC_LOWER, &phy_data); - hw->mac.collision_delta = phy_data; + if (!e1e_rphy(hw, HV_COLC_LOWER, &phy_data)) + hw->mac.collision_delta = phy_data; } else { hw->mac.collision_delta = er32(COLC); } @@ -3372,8 +3362,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82577)) { e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); - e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); - adapter->stats.tncrs += phy_data; + if (!e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data)) + adapter->stats.tncrs += phy_data; } else { if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583)) @@ -3477,7 +3467,7 @@ static void e1000_print_link_info(struct e1000_adapter *adapter) ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" ))); } -bool e1000_has_link(struct e1000_adapter *adapter) +bool e1000e_has_link(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; bool link_active = 0; @@ -3558,7 +3548,7 @@ static void e1000_watchdog_task(struct work_struct *work) u32 link, tctl; int tx_pending = 0; - link = e1000_has_link(adapter); + link = e1000e_has_link(adapter); if ((netif_carrier_ok(netdev)) && link) { e1000e_enable_receives(adapter); goto link_up; @@ -3781,7 +3771,7 @@ static int e1000_tso(struct e1000_adapter *adapter, 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) { + } else if (skb_is_gso_v6(skb)) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, @@ -3962,13 +3952,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter, dma_error: dev_err(&pdev->dev, "TX DMA map failed\n"); buffer_info->dma = 0; - count--; - - while (count >= 0) { + if (count) count--; - i--; - if (i < 0) + + while (count--) { + if (i==0) i += tx_ring->count; + i--; buffer_info = &tx_ring->buffer_info[i]; e1000_put_txbuf(adapter, buffer_info);; } @@ -4317,13 +4307,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) * 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) + if (max_frame <= 2048) adapter->rx_buffer_len = 2048; else adapter->rx_buffer_len = 4096; @@ -4674,6 +4658,7 @@ static int e1000_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); + pci_save_state(pdev); e1000e_disable_l1aspm(pdev); err = pci_enable_device_mem(pdev); @@ -4825,6 +4810,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) } else { pci_set_master(pdev); pci_restore_state(pdev); + pci_save_state(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); @@ -5133,7 +5119,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, e1000_eeprom_checks(adapter); - /* copy the MAC address out of the NVM */ + /* copy the MAC address */ if (e1000e_read_mac_addr(&adapter->hw)) e_err("NVM Read Error while reading MAC address\n"); @@ -5325,7 +5311,7 @@ static struct pci_error_handlers e1000_err_handler = { .resume = e1000_io_resume, }; -static struct pci_device_id e1000_pci_tbl[] = { +static DEFINE_PCI_DEVICE_TABLE(e1000_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 }, diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 55a2c0acfee7..7f3ceb9dad6a 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -152,32 +152,9 @@ s32 e1000e_get_phy_id(struct e1000_hw *hw) if (phy->id != 0 && phy->id != PHY_REVISION_MASK) goto out; - /* - * If the PHY ID is still unknown, we may have an 82577 - * without link. We will try again after setting Slow MDIC - * mode. No harm in trying again in this case since the PHY - * ID is unknown at this point anyway. - */ - ret_val = phy->ops.acquire(hw); - if (ret_val) - goto out; - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - phy->ops.release(hw); - retry_count++; } out: - /* Revert to MDIO fast mode, if applicable */ - if (retry_count) { - ret_val = phy->ops.acquire(hw); - if (ret_val) - return ret_val; - ret_val = e1000_set_mdio_slow_mode_hv(hw, false); - phy->ops.release(hw); - } - return ret_val; } @@ -2791,38 +2768,6 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) } /** - * e1000_set_mdio_slow_mode_hv - Set slow MDIO access mode - * @hw: pointer to the HW structure - * @slow: true for slow mode, false for normal mode - * - * Assumes semaphore already acquired. - **/ -s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow) -{ - s32 ret_val = 0; - u16 data = 0; - - /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */ - hw->phy.addr = 1; - ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, - (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT)); - if (ret_val) - goto out; - - ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1, - (0x2180 | (slow << 10))); - if (ret_val) - goto out; - - /* dummy read when reverting to fast mode - throw away result */ - if (!slow) - ret_val = e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data); - -out: - return ret_val; -} - -/** * __e1000_read_phy_reg_hv - Read HV PHY register * @hw: pointer to the HW structure * @offset: register offset to be read @@ -2839,7 +2784,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2847,16 +2791,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, return ret_val; } - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - /* 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, @@ -2893,10 +2827,6 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, data); out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); - if (!locked) hw->phy.ops.release(hw); @@ -2948,7 +2878,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, s32 ret_val; u16 page = BM_PHY_REG_PAGE(offset); u16 reg = BM_PHY_REG_NUM(offset); - bool in_slow_mode = false; if (!locked) { ret_val = hw->phy.ops.acquire(hw); @@ -2956,16 +2885,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, return ret_val; } - /* Workaround failure in MDIO access while cable is disconnected */ - if ((hw->phy.type == e1000_phy_82577) && - !(er32(STATUS) & E1000_STATUS_LU)) { - ret_val = e1000_set_mdio_slow_mode_hv(hw, true); - if (ret_val) - goto out; - - in_slow_mode = true; - } - /* 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, @@ -3019,10 +2938,6 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, data); out: - /* Revert to MDIO fast mode, if applicable */ - if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) - ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); - if (!locked) hw->phy.ops.release(hw); |