diff options
Diffstat (limited to 'drivers/net/e1000')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 3 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_hw.c | 296 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_hw.h | 310 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 345 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_param.c | 4 |
5 files changed, 568 insertions, 390 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index da459f7177c..fb96c87f9e5 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -100,6 +100,9 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "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) }, }; #define E1000_QUEUE_STATS_LEN 0 diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 3655d902b0b..9be44699300 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -308,141 +308,160 @@ e1000_phy_init_script(struct e1000_hw *hw) int32_t e1000_set_mac_type(struct e1000_hw *hw) { - DEBUGFUNC("e1000_set_mac_type"); - - switch (hw->device_id) { - case E1000_DEV_ID_82542: - switch (hw->revision_id) { - case E1000_82542_2_0_REV_ID: - hw->mac_type = e1000_82542_rev2_0; - break; - case E1000_82542_2_1_REV_ID: - hw->mac_type = e1000_82542_rev2_1; - break; - default: - /* Invalid 82542 revision ID */ - return -E1000_ERR_MAC_TYPE; - } - break; - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - hw->mac_type = e1000_82543; - break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - hw->mac_type = e1000_82544; - break; - case E1000_DEV_ID_82540EM: - case E1000_DEV_ID_82540EM_LOM: - case E1000_DEV_ID_82540EP: - case E1000_DEV_ID_82540EP_LOM: - case E1000_DEV_ID_82540EP_LP: - hw->mac_type = e1000_82540; - break; - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - hw->mac_type = e1000_82545; - break; - case E1000_DEV_ID_82545GM_COPPER: - case E1000_DEV_ID_82545GM_FIBER: - case E1000_DEV_ID_82545GM_SERDES: - hw->mac_type = e1000_82545_rev_3; - break; - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - case E1000_DEV_ID_82546EB_QUAD_COPPER: - hw->mac_type = e1000_82546; - break; - case E1000_DEV_ID_82546GB_COPPER: - case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82546GB_SERDES: - case E1000_DEV_ID_82546GB_PCIE: - case E1000_DEV_ID_82546GB_QUAD_COPPER: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: - hw->mac_type = e1000_82546_rev_3; - break; - case E1000_DEV_ID_82541EI: - case E1000_DEV_ID_82541EI_MOBILE: - case E1000_DEV_ID_82541ER_LOM: - hw->mac_type = e1000_82541; - break; - case E1000_DEV_ID_82541ER: - case E1000_DEV_ID_82541GI: - case E1000_DEV_ID_82541GI_LF: - case E1000_DEV_ID_82541GI_MOBILE: - hw->mac_type = e1000_82541_rev_2; - break; - case E1000_DEV_ID_82547EI: - case E1000_DEV_ID_82547EI_MOBILE: - hw->mac_type = e1000_82547; - break; - case E1000_DEV_ID_82547GI: - hw->mac_type = e1000_82547_rev_2; - break; - case E1000_DEV_ID_82571EB_COPPER: - case E1000_DEV_ID_82571EB_FIBER: - case E1000_DEV_ID_82571EB_SERDES: - case E1000_DEV_ID_82571EB_QUAD_COPPER: - case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: - hw->mac_type = e1000_82571; - break; - case E1000_DEV_ID_82572EI_COPPER: - case E1000_DEV_ID_82572EI_FIBER: - case E1000_DEV_ID_82572EI_SERDES: - case E1000_DEV_ID_82572EI: - hw->mac_type = e1000_82572; - break; - case E1000_DEV_ID_82573E: - case E1000_DEV_ID_82573E_IAMT: - case E1000_DEV_ID_82573L: - hw->mac_type = e1000_82573; - break; - case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: - case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: - case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: - hw->mac_type = e1000_80003es2lan; - break; - case E1000_DEV_ID_ICH8_IGP_M_AMT: - case E1000_DEV_ID_ICH8_IGP_AMT: - case E1000_DEV_ID_ICH8_IGP_C: - case E1000_DEV_ID_ICH8_IFE: - case E1000_DEV_ID_ICH8_IFE_GT: - case E1000_DEV_ID_ICH8_IFE_G: - case E1000_DEV_ID_ICH8_IGP_M: - hw->mac_type = e1000_ich8lan; - break; - default: - /* Should never have loaded on this device */ - return -E1000_ERR_MAC_TYPE; - } - - switch (hw->mac_type) { - case e1000_ich8lan: - hw->swfwhw_semaphore_present = TRUE; - hw->asf_firmware_present = TRUE; - break; - case e1000_80003es2lan: - hw->swfw_sync_present = TRUE; - /* fall through */ - case e1000_82571: - case e1000_82572: - case e1000_82573: - hw->eeprom_semaphore_present = TRUE; - /* fall through */ - case e1000_82541: - case e1000_82547: - case e1000_82541_rev_2: - case e1000_82547_rev_2: - hw->asf_firmware_present = TRUE; - break; - default: - break; - } - - return E1000_SUCCESS; + DEBUGFUNC("e1000_set_mac_type"); + + switch (hw->device_id) { + case E1000_DEV_ID_82542: + switch (hw->revision_id) { + case E1000_82542_2_0_REV_ID: + hw->mac_type = e1000_82542_rev2_0; + break; + case E1000_82542_2_1_REV_ID: + hw->mac_type = e1000_82542_rev2_1; + break; + default: + /* Invalid 82542 revision ID */ + return -E1000_ERR_MAC_TYPE; + } + break; + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + hw->mac_type = e1000_82543; + break; + case E1000_DEV_ID_82544EI_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82544GC_COPPER: + case E1000_DEV_ID_82544GC_LOM: + hw->mac_type = e1000_82544; + break; + case E1000_DEV_ID_82540EM: + case E1000_DEV_ID_82540EM_LOM: + case E1000_DEV_ID_82540EP: + case E1000_DEV_ID_82540EP_LOM: + case E1000_DEV_ID_82540EP_LP: + hw->mac_type = e1000_82540; + break; + case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + hw->mac_type = e1000_82545; + break; + case E1000_DEV_ID_82545GM_COPPER: + case E1000_DEV_ID_82545GM_FIBER: + case E1000_DEV_ID_82545GM_SERDES: + hw->mac_type = e1000_82545_rev_3; + break; + case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_FIBER: + case E1000_DEV_ID_82546EB_QUAD_COPPER: + hw->mac_type = e1000_82546; + break; + case E1000_DEV_ID_82546GB_COPPER: + case E1000_DEV_ID_82546GB_FIBER: + case E1000_DEV_ID_82546GB_SERDES: + case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: + case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: + hw->mac_type = e1000_82546_rev_3; + break; + case E1000_DEV_ID_82541EI: + case E1000_DEV_ID_82541EI_MOBILE: + case E1000_DEV_ID_82541ER_LOM: + hw->mac_type = e1000_82541; + break; + case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI: + case E1000_DEV_ID_82541GI_LF: + case E1000_DEV_ID_82541GI_MOBILE: + hw->mac_type = e1000_82541_rev_2; + break; + case E1000_DEV_ID_82547EI: + case E1000_DEV_ID_82547EI_MOBILE: + hw->mac_type = e1000_82547; + break; + case E1000_DEV_ID_82547GI: + hw->mac_type = e1000_82547_rev_2; + break; + case E1000_DEV_ID_82571EB_COPPER: + case E1000_DEV_ID_82571EB_FIBER: + case E1000_DEV_ID_82571EB_SERDES: + case E1000_DEV_ID_82571EB_QUAD_COPPER: + case E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE: + hw->mac_type = e1000_82571; + break; + case E1000_DEV_ID_82572EI_COPPER: + case E1000_DEV_ID_82572EI_FIBER: + case E1000_DEV_ID_82572EI_SERDES: + case E1000_DEV_ID_82572EI: + hw->mac_type = e1000_82572; + break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + case E1000_DEV_ID_82573L: + hw->mac_type = e1000_82573; + break; + case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_SPT: + case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: + case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: + hw->mac_type = e1000_80003es2lan; + break; + case E1000_DEV_ID_ICH8_IGP_M_AMT: + case E1000_DEV_ID_ICH8_IGP_AMT: + case E1000_DEV_ID_ICH8_IGP_C: + case E1000_DEV_ID_ICH8_IFE: + case E1000_DEV_ID_ICH8_IFE_GT: + case E1000_DEV_ID_ICH8_IFE_G: + case E1000_DEV_ID_ICH8_IGP_M: + hw->mac_type = e1000_ich8lan; + break; + default: + /* Should never have loaded on this device */ + return -E1000_ERR_MAC_TYPE; + } + + switch (hw->mac_type) { + case e1000_ich8lan: + hw->swfwhw_semaphore_present = TRUE; + hw->asf_firmware_present = TRUE; + break; + case e1000_80003es2lan: + hw->swfw_sync_present = TRUE; + /* fall through */ + case e1000_82571: + case e1000_82572: + case e1000_82573: + hw->eeprom_semaphore_present = TRUE; + /* fall through */ + case e1000_82541: + case e1000_82547: + case e1000_82541_rev_2: + case e1000_82547_rev_2: + hw->asf_firmware_present = TRUE; + break; + default: + break; + } + + /* The 82543 chip does not count tx_carrier_errors properly in + * FD mode + */ + if (hw->mac_type == e1000_82543) + hw->bad_tx_carr_stats_fd = TRUE; + + /* capable of receiving management packets to the host */ + if (hw->mac_type >= e1000_82571) + hw->has_manc2h = TRUE; + + /* In rare occasions, ESB2 systems would end up started without + * the RX unit being turned on. + */ + if (hw->mac_type == e1000_80003es2lan) + hw->rx_needs_kicking = TRUE; + + if (hw->mac_type > e1000_82544) + hw->has_smbus = TRUE; + + return E1000_SUCCESS; } /***************************************************************************** @@ -6575,7 +6594,7 @@ e1000_get_bus_info(struct e1000_hw *hw) switch (hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: - hw->bus_type = e1000_bus_type_unknown; + hw->bus_type = e1000_bus_type_pci; hw->bus_speed = e1000_bus_speed_unknown; hw->bus_width = e1000_bus_width_unknown; break; @@ -7817,9 +7836,8 @@ e1000_enable_mng_pass_thru(struct e1000_hw *hw) fwsm = E1000_READ_REG(hw, FWSM); factps = E1000_READ_REG(hw, FACTPS); - if (((fwsm & E1000_FWSM_MODE_MASK) == - (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) && - (factps & E1000_FACTPS_MNGCG)) + if ((((fwsm & E1000_FWSM_MODE_MASK) >> E1000_FWSM_MODE_SHIFT) == + e1000_mng_mode_pt) && !(factps & E1000_FACTPS_MNGCG)) return TRUE; } else if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 3321fb13bfa..d6710588334 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1301,165 +1301,170 @@ struct e1000_ffvt_entry { #define E1000_82542_RSSIR E1000_RSSIR #define E1000_82542_KUMCTRLSTA E1000_KUMCTRLSTA #define E1000_82542_SW_FW_SYNC E1000_SW_FW_SYNC +#define E1000_82542_MANC2H E1000_MANC2H /* Statistics counters collected by the MAC */ struct e1000_hw_stats { - uint64_t crcerrs; - uint64_t algnerrc; - uint64_t symerrs; - uint64_t rxerrc; - uint64_t txerrc; - uint64_t mpc; - uint64_t scc; - uint64_t ecol; - uint64_t mcc; - uint64_t latecol; - uint64_t colc; - uint64_t dc; - uint64_t tncrs; - uint64_t sec; - uint64_t cexterr; - uint64_t rlec; - uint64_t xonrxc; - uint64_t xontxc; - uint64_t xoffrxc; - uint64_t xofftxc; - uint64_t fcruc; - uint64_t prc64; - uint64_t prc127; - uint64_t prc255; - uint64_t prc511; - uint64_t prc1023; - uint64_t prc1522; - uint64_t gprc; - uint64_t bprc; - uint64_t mprc; - uint64_t gptc; - uint64_t gorcl; - uint64_t gorch; - uint64_t gotcl; - uint64_t gotch; - uint64_t rnbc; - uint64_t ruc; - uint64_t rfc; - uint64_t roc; - uint64_t rlerrc; - uint64_t rjc; - uint64_t mgprc; - uint64_t mgpdc; - uint64_t mgptc; - uint64_t torl; - uint64_t torh; - uint64_t totl; - uint64_t toth; - uint64_t tpr; - uint64_t tpt; - uint64_t ptc64; - uint64_t ptc127; - uint64_t ptc255; - uint64_t ptc511; - uint64_t ptc1023; - uint64_t ptc1522; - uint64_t mptc; - uint64_t bptc; - uint64_t tsctc; - uint64_t tsctfc; - uint64_t iac; - uint64_t icrxptc; - uint64_t icrxatc; - uint64_t ictxptc; - uint64_t ictxatc; - uint64_t ictxqec; - uint64_t ictxqmtc; - uint64_t icrxdmtc; - uint64_t icrxoc; + uint64_t crcerrs; + uint64_t algnerrc; + uint64_t symerrs; + uint64_t rxerrc; + uint64_t txerrc; + uint64_t mpc; + uint64_t scc; + uint64_t ecol; + uint64_t mcc; + uint64_t latecol; + uint64_t colc; + uint64_t dc; + uint64_t tncrs; + uint64_t sec; + uint64_t cexterr; + uint64_t rlec; + uint64_t xonrxc; + uint64_t xontxc; + uint64_t xoffrxc; + uint64_t xofftxc; + uint64_t fcruc; + uint64_t prc64; + uint64_t prc127; + uint64_t prc255; + uint64_t prc511; + uint64_t prc1023; + uint64_t prc1522; + uint64_t gprc; + uint64_t bprc; + uint64_t mprc; + uint64_t gptc; + uint64_t gorcl; + uint64_t gorch; + uint64_t gotcl; + uint64_t gotch; + uint64_t rnbc; + uint64_t ruc; + uint64_t rfc; + uint64_t roc; + uint64_t rlerrc; + uint64_t rjc; + uint64_t mgprc; + uint64_t mgpdc; + uint64_t mgptc; + uint64_t torl; + uint64_t torh; + uint64_t totl; + uint64_t toth; + uint64_t tpr; + uint64_t tpt; + uint64_t ptc64; + uint64_t ptc127; + uint64_t ptc255; + uint64_t ptc511; + uint64_t ptc1023; + uint64_t ptc1522; + uint64_t mptc; + uint64_t bptc; + uint64_t tsctc; + uint64_t tsctfc; + uint64_t iac; + uint64_t icrxptc; + uint64_t icrxatc; + uint64_t ictxptc; + uint64_t ictxatc; + uint64_t ictxqec; + uint64_t ictxqmtc; + uint64_t icrxdmtc; + uint64_t icrxoc; }; /* Structure containing variables used by the shared code (e1000_hw.c) */ struct e1000_hw { - uint8_t __iomem *hw_addr; - uint8_t __iomem *flash_address; - e1000_mac_type mac_type; - e1000_phy_type phy_type; - uint32_t phy_init_script; - e1000_media_type media_type; - void *back; - struct e1000_shadow_ram *eeprom_shadow_ram; - uint32_t flash_bank_size; - uint32_t flash_base_addr; - e1000_fc_type fc; - e1000_bus_speed bus_speed; - e1000_bus_width bus_width; - e1000_bus_type bus_type; - struct e1000_eeprom_info eeprom; - e1000_ms_type master_slave; - e1000_ms_type original_master_slave; - e1000_ffe_config ffe_config_state; - uint32_t asf_firmware_present; - uint32_t eeprom_semaphore_present; - uint32_t swfw_sync_present; - uint32_t swfwhw_semaphore_present; - unsigned long io_base; - uint32_t phy_id; - uint32_t phy_revision; - uint32_t phy_addr; - uint32_t original_fc; - uint32_t txcw; - uint32_t autoneg_failed; - uint32_t max_frame_size; - uint32_t min_frame_size; - uint32_t mc_filter_type; - uint32_t num_mc_addrs; - uint32_t collision_delta; - uint32_t tx_packet_delta; - uint32_t ledctl_default; - uint32_t ledctl_mode1; - uint32_t ledctl_mode2; - boolean_t tx_pkt_filtering; - struct e1000_host_mng_dhcp_cookie mng_cookie; - uint16_t phy_spd_default; - uint16_t autoneg_advertised; - uint16_t pci_cmd_word; - uint16_t fc_high_water; - uint16_t fc_low_water; - uint16_t fc_pause_time; - uint16_t current_ifs_val; - uint16_t ifs_min_val; - uint16_t ifs_max_val; - uint16_t ifs_step_size; - uint16_t ifs_ratio; - uint16_t device_id; - uint16_t vendor_id; - uint16_t subsystem_id; - uint16_t subsystem_vendor_id; - uint8_t revision_id; - uint8_t autoneg; - uint8_t mdix; - uint8_t forced_speed_duplex; - uint8_t wait_autoneg_complete; - uint8_t dma_fairness; - uint8_t mac_addr[NODE_ADDRESS_SIZE]; - uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; - boolean_t disable_polarity_correction; - boolean_t speed_downgraded; - e1000_smart_speed smart_speed; - e1000_dsp_config dsp_config_state; - boolean_t get_link_status; - boolean_t serdes_link_down; - boolean_t tbi_compatibility_en; - boolean_t tbi_compatibility_on; - boolean_t laa_is_present; - boolean_t phy_reset_disable; - boolean_t initialize_hw_bits_disable; - boolean_t fc_send_xon; - boolean_t fc_strict_ieee; - boolean_t report_tx_early; - boolean_t adaptive_ifs; - boolean_t ifs_params_forced; - boolean_t in_ifs_mode; - boolean_t mng_reg_access_disabled; - boolean_t leave_av_bit_off; - boolean_t kmrn_lock_loss_workaround_disabled; + uint8_t __iomem *hw_addr; + uint8_t __iomem *flash_address; + e1000_mac_type mac_type; + e1000_phy_type phy_type; + uint32_t phy_init_script; + e1000_media_type media_type; + void *back; + struct e1000_shadow_ram *eeprom_shadow_ram; + uint32_t flash_bank_size; + uint32_t flash_base_addr; + e1000_fc_type fc; + e1000_bus_speed bus_speed; + e1000_bus_width bus_width; + e1000_bus_type bus_type; + struct e1000_eeprom_info eeprom; + e1000_ms_type master_slave; + e1000_ms_type original_master_slave; + e1000_ffe_config ffe_config_state; + uint32_t asf_firmware_present; + uint32_t eeprom_semaphore_present; + uint32_t swfw_sync_present; + uint32_t swfwhw_semaphore_present; + unsigned long io_base; + uint32_t phy_id; + uint32_t phy_revision; + uint32_t phy_addr; + uint32_t original_fc; + uint32_t txcw; + uint32_t autoneg_failed; + uint32_t max_frame_size; + uint32_t min_frame_size; + uint32_t mc_filter_type; + uint32_t num_mc_addrs; + uint32_t collision_delta; + uint32_t tx_packet_delta; + uint32_t ledctl_default; + uint32_t ledctl_mode1; + uint32_t ledctl_mode2; + boolean_t tx_pkt_filtering; + struct e1000_host_mng_dhcp_cookie mng_cookie; + uint16_t phy_spd_default; + uint16_t autoneg_advertised; + uint16_t pci_cmd_word; + uint16_t fc_high_water; + uint16_t fc_low_water; + uint16_t fc_pause_time; + uint16_t current_ifs_val; + uint16_t ifs_min_val; + uint16_t ifs_max_val; + uint16_t ifs_step_size; + uint16_t ifs_ratio; + uint16_t device_id; + uint16_t vendor_id; + uint16_t subsystem_id; + uint16_t subsystem_vendor_id; + uint8_t revision_id; + uint8_t autoneg; + uint8_t mdix; + uint8_t forced_speed_duplex; + uint8_t wait_autoneg_complete; + uint8_t dma_fairness; + uint8_t mac_addr[NODE_ADDRESS_SIZE]; + uint8_t perm_mac_addr[NODE_ADDRESS_SIZE]; + boolean_t disable_polarity_correction; + boolean_t speed_downgraded; + e1000_smart_speed smart_speed; + e1000_dsp_config dsp_config_state; + boolean_t get_link_status; + boolean_t serdes_link_down; + boolean_t tbi_compatibility_en; + boolean_t tbi_compatibility_on; + boolean_t laa_is_present; + boolean_t phy_reset_disable; + boolean_t initialize_hw_bits_disable; + boolean_t fc_send_xon; + boolean_t fc_strict_ieee; + boolean_t report_tx_early; + boolean_t adaptive_ifs; + boolean_t ifs_params_forced; + boolean_t in_ifs_mode; + boolean_t mng_reg_access_disabled; + boolean_t leave_av_bit_off; + boolean_t kmrn_lock_loss_workaround_disabled; + boolean_t bad_tx_carr_stats_fd; + boolean_t has_manc2h; + boolean_t rx_needs_kicking; + boolean_t has_smbus; }; @@ -2418,6 +2423,7 @@ struct e1000_host_command_info { #define E1000_PBA_8K 0x0008 /* 8KB, default Rx allocation */ #define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ +#define E1000_PBA_20K 0x0014 #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 #define E1000_PBA_30K 0x001E diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 73f3a85fd23..4c1ff752048 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -213,6 +213,12 @@ static void e1000_netpoll (struct net_device *netdev); extern void e1000_check_options(struct e1000_adapter *adapter); +#define COPYBREAK_DEFAULT 256 +static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT; +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, + "Maximum size of packet that is copied to a new buffer on receive"); + static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state); static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); @@ -264,7 +270,13 @@ e1000_init_module(void) printk(KERN_INFO "%s\n", e1000_copyright); ret = pci_register_driver(&e1000_driver); - + if (copybreak != COPYBREAK_DEFAULT) { + if (copybreak == 0) + printk(KERN_INFO "e1000: copybreak disabled\n"); + else + printk(KERN_INFO "e1000: copybreak enabled for " + "packets <= %u bytes\n", copybreak); + } return ret; } @@ -464,6 +476,52 @@ e1000_get_hw_control(struct e1000_adapter *adapter) } } +static void +e1000_init_manageability(struct e1000_adapter *adapter) +{ + if (adapter->en_mng_pt) { + uint32_t manc = E1000_READ_REG(&adapter->hw, 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 */ + if (adapter->hw.has_manc2h) { + uint32_t manc2h = E1000_READ_REG(&adapter->hw, MANC2H); + + manc |= E1000_MANC_EN_MNG2HOST; +#define E1000_MNG2HOST_PORT_623 (1 << 5) +#define E1000_MNG2HOST_PORT_664 (1 << 6) + manc2h |= E1000_MNG2HOST_PORT_623; + manc2h |= E1000_MNG2HOST_PORT_664; + E1000_WRITE_REG(&adapter->hw, MANC2H, manc2h); + } + + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } +} + +static void +e1000_release_manageability(struct e1000_adapter *adapter) +{ + if (adapter->en_mng_pt) { + uint32_t manc = E1000_READ_REG(&adapter->hw, MANC); + + /* re-enable hardware interception of ARP */ + manc |= E1000_MANC_ARP_EN; + + if (adapter->hw.has_manc2h) + manc &= ~E1000_MANC_EN_MNG2HOST; + + /* don't explicitly have to mess with MANC2H since + * MANC has an enable disable that gates MANC2H */ + + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } +} + int e1000_up(struct e1000_adapter *adapter) { @@ -475,6 +533,7 @@ e1000_up(struct e1000_adapter *adapter) e1000_set_multi(netdev); e1000_restore_vlan(adapter); + e1000_init_manageability(adapter); e1000_configure_tx(adapter); e1000_setup_rctl(adapter); @@ -497,7 +556,8 @@ e1000_up(struct e1000_adapter *adapter) clear_bit(__E1000_DOWN, &adapter->flags); - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); + /* fire a link change interrupt to start the watchdog */ + E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_LSC); return 0; } @@ -614,16 +674,34 @@ e1000_reinit_locked(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { - uint32_t pba, manc; + uint32_t pba = 0, tx_space, min_tx_space, min_rx_space; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; + boolean_t legacy_pba_adjust = FALSE; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. */ switch (adapter->hw.mac_type) { + case e1000_82542_rev2_0: + case e1000_82542_rev2_1: + case e1000_82543: + case e1000_82544: + case e1000_82540: + case e1000_82541: + case e1000_82541_rev_2: + legacy_pba_adjust = TRUE; + pba = E1000_PBA_48K; + break; + case e1000_82545: + case e1000_82545_rev_3: + case e1000_82546: + case e1000_82546_rev_3: + pba = E1000_PBA_48K; + break; case e1000_82547: case e1000_82547_rev_2: + legacy_pba_adjust = TRUE; pba = E1000_PBA_30K; break; case e1000_82571: @@ -632,27 +710,80 @@ e1000_reset(struct e1000_adapter *adapter) pba = E1000_PBA_38K; break; case e1000_82573: - pba = E1000_PBA_12K; + pba = E1000_PBA_20K; break; case e1000_ich8lan: pba = E1000_PBA_8K; - break; - default: - pba = E1000_PBA_48K; + case e1000_undefined: + case e1000_num_macs: break; } - if ((adapter->hw.mac_type != e1000_82573) && - (adapter->netdev->mtu > E1000_RXBUFFER_8192)) - pba -= 8; /* allocate more FIFO for Tx */ + if (legacy_pba_adjust == TRUE) { + if (adapter->netdev->mtu > E1000_RXBUFFER_8192) + pba -= 8; /* allocate more FIFO for Tx */ + if (adapter->hw.mac_type == e1000_82547) { + adapter->tx_fifo_head = 0; + adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; + adapter->tx_fifo_size = + (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; + atomic_set(&adapter->tx_fifo_stall, 0); + } + } else if (adapter->hw.max_frame_size > MAXIMUM_ETHERNET_FRAME_SIZE) { + /* adjust PBA for jumbo frames */ + E1000_WRITE_REG(&adapter->hw, PBA, pba); + + /* To maintain wire speed transmits, the Tx FIFO should be + * large enough to accomodate two full transmit packets, + * rounded up to the next 1KB and expressed in KB. Likewise, + * the Rx FIFO should be large enough to accomodate at least + * one full receive packet and is similarly rounded up and + * expressed in KB. */ + pba = E1000_READ_REG(&adapter->hw, 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; + /* don't include ethernet FCS because hardware appends/strips */ + min_rx_space = adapter->netdev->mtu + ENET_HEADER_SIZE + + VLAN_TAG_SIZE; + min_tx_space = min_rx_space; + min_tx_space *= 2; + E1000_ROUNDUP(min_tx_space, 1024); + min_tx_space >>= 10; + E1000_ROUNDUP(min_rx_space, 1024); + min_rx_space >>= 10; + + /* 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 = pba - (min_tx_space - tx_space); + + /* PCI/PCIx hardware has PBA alignment constraints */ + switch (adapter->hw.mac_type) { + case e1000_82545 ... e1000_82546_rev_3: + pba &= ~(E1000_PBA_8K - 1); + break; + default: + break; + } - if (adapter->hw.mac_type == e1000_82547) { - adapter->tx_fifo_head = 0; - adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; - adapter->tx_fifo_size = - (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; - atomic_set(&adapter->tx_fifo_stall, 0); + /* if short on rx space, rx wins and must trump tx + * adjustment or use Early Receive if available */ + if (pba < min_rx_space) { + switch (adapter->hw.mac_type) { + case e1000_82573: + /* ERT enabled in e1000_configure_rx */ + break; + default: + pba = min_rx_space; + break; + } + } + } } E1000_WRITE_REG(&adapter->hw, PBA, pba); @@ -685,6 +816,20 @@ e1000_reset(struct e1000_adapter *adapter) if (e1000_init_hw(&adapter->hw)) DPRINTK(PROBE, ERR, "Hardware Error\n"); e1000_update_mng_vlan(adapter); + + /* if (adapter->hwflags & HWFLAGS_PHY_PWR_BIT) { */ + if (adapter->hw.mac_type >= e1000_82544 && + adapter->hw.mac_type <= e1000_82547_rev_2 && + adapter->hw.autoneg == 1 && + adapter->hw.autoneg_advertised == ADVERTISE_1000_FULL) { + uint32_t ctrl = E1000_READ_REG(&adapter->hw, CTRL); + /* clear phy power management bit if we are in gig only mode, + * which if enabled will attempt negotiation to 100Mb, which + * can cause a loss of link at power off or driver unload */ + ctrl &= ~E1000_CTRL_SWDPIN3; + E1000_WRITE_REG(&adapter->hw, CTRL, ctrl); + } + /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); @@ -705,14 +850,7 @@ e1000_reset(struct e1000_adapter *adapter) phy_data); } - if ((adapter->en_mng_pt) && - (adapter->hw.mac_type >= e1000_82540) && - (adapter->hw.mac_type < e1000_82571) && - (adapter->hw.media_type == e1000_media_type_copper)) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } + e1000_release_manageability(adapter); } /** @@ -857,6 +995,12 @@ e1000_probe(struct pci_dev *pdev, (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; +#ifdef CONFIG_DEBUG_SLAB + /* 82544's work arounds do not play nicely with DEBUG SLAB */ + if (adapter->hw.mac_type == e1000_82544) + netdev->features &= ~NETIF_F_TSO; +#endif + #ifdef NETIF_F_TSO6 if (adapter->hw.mac_type > e1000_82547_rev_2) netdev->features |= NETIF_F_TSO6; @@ -1078,22 +1222,13 @@ e1000_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc; #ifdef CONFIG_E1000_NAPI int i; #endif flush_scheduled_work(); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - if (manc & E1000_MANC_SMBUS_EN) { - manc |= E1000_MANC_ARP_EN; - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - } + 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. */ @@ -1531,9 +1666,9 @@ e1000_configure_tx(struct e1000_adapter *adapter) } /* Set the default values for the Tx Inter Packet Gap timer */ - - if (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes) + if (adapter->hw.mac_type <= e1000_82547_rev_2 && + (hw->media_type == e1000_media_type_fiber || + hw->media_type == e1000_media_type_internal_serdes)) tipg = DEFAULT_82543_TIPG_IPGT_FIBER; else tipg = DEFAULT_82543_TIPG_IPGT_COPPER; @@ -2528,6 +2663,13 @@ e1000_watchdog(unsigned long data) netif_wake_queue(netdev); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); adapter->smartspeed = 0; + } else { + /* make sure the receive unit is started */ + if (adapter->hw.rx_needs_kicking) { + struct e1000_hw *hw = &adapter->hw; + uint32_t rctl = E1000_READ_REG(hw, RCTL); + E1000_WRITE_REG(hw, RCTL, rctl | E1000_RCTL_EN); + } } } else { if (netif_carrier_ok(netdev)) { @@ -2628,29 +2770,34 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, if (packets == 0) goto update_itr_done; - switch (itr_setting) { case lowest_latency: - if ((packets < 5) && (bytes > 512)) + /* jumbo frames get bulk treatment*/ + 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) { - if ((packets < 10) || - ((bytes/packets) > 1200)) + /* jumbo frames need bulk latency setting */ + 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 (packets <= 2 && bytes < 512) + } 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; + } else if (bytes < 6000) { + retval = low_latency; } break; } @@ -2679,17 +2826,20 @@ static void e1000_set_itr(struct e1000_adapter *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; + 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); - /* conservative mode eliminates the lowest_latency setting */ - if (current_itr == lowest_latency && (adapter->itr_setting == 3)) - current_itr = low_latency; - switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ case lowest_latency: @@ -3168,6 +3318,16 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) { switch (adapter->hw.mac_type) { unsigned int pull_size; + case e1000_82544: + /* Make sure we have room to chop off 4 bytes, + * and that the end alignment will work out to + * this hardware's requirements + * NOTE: this is a TSO only workaround + * if end byte alignment not correct move us + * into the next dword */ + if ((unsigned long)(skb->tail - 1) & 4) + break; + /* fall through */ case e1000_82571: case e1000_82572: case e1000_82573: @@ -3419,12 +3579,11 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; netdev->mtu = new_mtu; + adapter->hw.max_frame_size = max_frame; if (netif_running(netdev)) e1000_reinit_locked(adapter); - adapter->hw.max_frame_size = max_frame; - return 0; } @@ -3573,6 +3732,11 @@ e1000_update_stats(struct e1000_adapter *adapter) 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; + if (adapter->hw.bad_tx_carr_stats_fd && + adapter->link_duplex == FULL_DUPLEX) { + adapter->net_stats.tx_carrier_errors = 0; + adapter->stats.tncrs = 0; + } /* Tx Dropped needs to be maintained elsewhere */ @@ -3590,6 +3754,13 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->phy_stats.receive_errors += phy_tmp; } + /* Management Stats */ + if (adapter->hw.has_smbus) { + adapter->stats.mgptc += E1000_READ_REG(hw, MGTPTC); + adapter->stats.mgprc += E1000_READ_REG(hw, MGTPRC); + adapter->stats.mgpdc += E1000_READ_REG(hw, MGTPDC); + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); } #ifdef CONFIG_PCI_MSI @@ -3868,11 +4039,11 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, cleaned = (i == eop); if (cleaned) { - /* this packet count is wrong for TSO but has a - * tendency to make dynamic ITR change more - * towards bulk */ + struct sk_buff *skb = buffer_info->skb; + unsigned int segs = skb_shinfo(skb)->gso_segs; + total_tx_packets += segs; total_tx_packets++; - total_tx_bytes += buffer_info->skb->len; + total_tx_bytes += skb->len; } e1000_unmap_and_free_tx_resource(adapter, buffer_info); tx_desc->upper.data = 0; @@ -4094,8 +4265,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, /* code added for copybreak, this should improve * performance for small packets with large amounts * of reassembly being done in the stack */ -#define E1000_CB_LENGTH 256 - if (length < E1000_CB_LENGTH) { + if (length < copybreak) { struct sk_buff *new_skb = netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { @@ -4253,7 +4423,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, /* page alloc/put takes too long and effects small packet * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && ((length + l1) <= adapter->rx_ps_bsize0)) { + if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) { u8 *vaddr; /* there is no documentation about how to call * kmap_atomic, so we can't hold the mapping @@ -4998,7 +5168,7 @@ 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); - uint32_t ctrl, ctrl_ext, rctl, manc, status; + uint32_t ctrl, ctrl_ext, rctl, status; uint32_t wufc = adapter->wol; #ifdef CONFIG_PM int retval = 0; @@ -5067,16 +5237,12 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) pci_enable_wake(pdev, PCI_D3cold, 0); } - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - if (manc & E1000_MANC_SMBUS_EN) { - manc |= E1000_MANC_ARP_EN; - E1000_WRITE_REG(&adapter->hw, MANC, manc); - pci_enable_wake(pdev, PCI_D3hot, 1); - pci_enable_wake(pdev, PCI_D3cold, 1); - } + e1000_release_manageability(adapter); + + /* make sure adapter isn't asleep if manageability is enabled */ + if (adapter->en_mng_pt) { + pci_enable_wake(pdev, PCI_D3hot, 1); + pci_enable_wake(pdev, PCI_D3cold, 1); } if (adapter->hw.phy_type == e1000_phy_igp_3) @@ -5102,7 +5268,7 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc, err; + uint32_t err; pci_set_power_state(pdev, PCI_D0); e1000_pci_restore_state(adapter); @@ -5122,19 +5288,13 @@ e1000_resume(struct pci_dev *pdev) e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); + e1000_init_manageability(adapter); + if (netif_running(netdev)) e1000_up(adapter); netif_device_attach(netdev); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc &= ~(E1000_MANC_ARP_EN); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - /* If the controller is 82573 and f/w is AMT, do not set * DRV_LOAD until the interface is up. For all other cases, * let the f/w know that the h/w is now under the control @@ -5235,7 +5395,8 @@ static void e1000_io_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - uint32_t manc, swsm; + + e1000_init_manageability(adapter); if (netif_running(netdev)) { if (e1000_up(adapter)) { @@ -5246,26 +5407,14 @@ static void e1000_io_resume(struct pci_dev *pdev) netif_device_attach(netdev); - if (adapter->hw.mac_type >= e1000_82540 && - adapter->hw.mac_type < e1000_82571 && - adapter->hw.media_type == e1000_media_type_copper) { - manc = E1000_READ_REG(&adapter->hw, MANC); - manc &= ~(E1000_MANC_ARP_EN); - E1000_WRITE_REG(&adapter->hw, MANC, manc); - } - - switch (adapter->hw.mac_type) { - case e1000_82573: - swsm = E1000_READ_REG(&adapter->hw, SWSM); - E1000_WRITE_REG(&adapter->hw, SWSM, - swsm | E1000_SWSM_DRV_LOAD); - break; - default: - break; - } + /* If the controller is 82573 and f/w is AMT, do not set + * DRV_LOAD until the interface is up. For all other cases, + * let the f/w know that the h/w is now under the control + * of the driver. */ + if (adapter->hw.mac_type != e1000_82573 || + !e1000_check_mng_mode(&adapter->hw)) + e1000_get_hw_control(adapter); - if (netif_running(netdev)) - mod_timer(&adapter->watchdog_timer, jiffies); } /* e1000_main.c */ diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index cbfcd7f2889..cf2a279307e 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -487,7 +487,9 @@ e1000_check_options(struct e1000_adapter *adapter) e1000_validate_option(&adapter->itr, &opt, adapter); /* save the setting, because the dynamic bits change itr */ - adapter->itr_setting = adapter->itr; + /* clear the lower two bits because they are + * used as control */ + adapter->itr_setting = adapter->itr & ~3; break; } } else { |