diff options
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/82571.c | 264 | ||||
-rw-r--r-- | drivers/net/e1000e/defines.h | 9 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 7 | ||||
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 12 | ||||
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 201 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 100 | ||||
-rw-r--r-- | drivers/net/e1000e/lib.c | 144 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 158 | ||||
-rw-r--r-- | drivers/net/e1000e/param.c | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/phy.c | 90 |
11 files changed, 667 insertions, 321 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 7236f1a53ba..cb6c7b1c1fb 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -52,6 +52,7 @@ (ID_LED_DEF1_DEF2)) #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 +#define AN_RETRY_COUNT 5 /* Autoneg Retry Count value */ #define E1000_BASE1000T_STATUS 10 #define E1000_IDLE_ERROR_COUNT_MASK 0xFF #define E1000_RECEIVE_ERROR_COUNTER 21 @@ -74,6 +75,11 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); static s32 e1000_led_on_82574(struct e1000_hw *hw); static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); +static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); +static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); +static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, bool active); +static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active); /** * e1000_init_phy_params_82571 - Init PHY func ptrs. @@ -107,6 +113,10 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) case e1000_82574: case e1000_82583: phy->type = e1000_phy_bm; + phy->ops.acquire = e1000_get_hw_semaphore_82574; + phy->ops.release = e1000_put_hw_semaphore_82574; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82574; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82574; break; default: return -E1000_ERR_PHY; @@ -115,29 +125,36 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) /* This can only be done after all function pointers are setup. */ ret_val = e1000_get_phy_id_82571(hw); + if (ret_val) { + e_dbg("Error getting PHY ID\n"); + return ret_val; + } /* Verify phy id */ switch (hw->mac.type) { case e1000_82571: case e1000_82572: if (phy->id != IGP01E1000_I_PHY_ID) - return -E1000_ERR_PHY; + ret_val = -E1000_ERR_PHY; break; case e1000_82573: if (phy->id != M88E1111_I_PHY_ID) - return -E1000_ERR_PHY; + ret_val = -E1000_ERR_PHY; break; case e1000_82574: case e1000_82583: if (phy->id != BME1000_E_PHY_ID_R2) - return -E1000_ERR_PHY; + ret_val = -E1000_ERR_PHY; break; default: - return -E1000_ERR_PHY; + ret_val = -E1000_ERR_PHY; break; } - return 0; + if (ret_val) + e_dbg("PHY ID unknown: type = 0x%08x\n", phy->id); + + return ret_val; } /** @@ -200,6 +217,17 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) break; } + /* Function Pointers */ + switch (hw->mac.type) { + case e1000_82574: + case e1000_82583: + nvm->ops.acquire = e1000_get_hw_semaphore_82574; + nvm->ops.release = e1000_put_hw_semaphore_82574; + break; + default: + break; + } + return 0; } @@ -542,6 +570,146 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); ew32(SWSM, swsm); } +/** + * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore during reset. + * + **/ +static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) +{ + u32 extcnf_ctrl; + s32 ret_val = 0; + s32 i = 0; + + extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + do { + ew32(EXTCNF_CTRL, extcnf_ctrl); + extcnf_ctrl = er32(EXTCNF_CTRL); + + if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + break; + + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + msleep(2); + i++; + } while (i < MDIO_OWNERSHIP_TIMEOUT); + + if (i == MDIO_OWNERSHIP_TIMEOUT) { + /* Release semaphores */ + e1000_put_hw_semaphore_82573(hw); + e_dbg("Driver can't access the PHY\n"); + ret_val = -E1000_ERR_PHY; + goto out; + } + +out: + return ret_val; +} + +/** + * e1000_put_hw_semaphore_82573 - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used during reset. + * + **/ +static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) +{ + u32 extcnf_ctrl; + + extcnf_ctrl = er32(EXTCNF_CTRL); + extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + ew32(EXTCNF_CTRL, extcnf_ctrl); +} + +static DEFINE_MUTEX(swflag_mutex); + +/** + * e1000_get_hw_semaphore_82574 - 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_82574(struct e1000_hw *hw) +{ + s32 ret_val; + + mutex_lock(&swflag_mutex); + ret_val = e1000_get_hw_semaphore_82573(hw); + if (ret_val) + mutex_unlock(&swflag_mutex); + return ret_val; +} + +/** + * e1000_put_hw_semaphore_82574 - 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_82574(struct e1000_hw *hw) +{ + e1000_put_hw_semaphore_82573(hw); + mutex_unlock(&swflag_mutex); +} + +/** + * e1000_set_d0_lplu_state_82574 - 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. + * 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_82574(struct e1000_hw *hw, bool active) +{ + u16 data = er32(POEMB); + + if (active) + data |= E1000_PHY_CTRL_D0A_LPLU; + else + data &= ~E1000_PHY_CTRL_D0A_LPLU; + + ew32(POEMB, data); + return 0; +} + +/** + * e1000_set_d3_lplu_state_82574 - Sets low power link up state for D3 + * @hw: pointer to the HW structure + * @active: boolean used to enable/disable lplu + * + * The low power link up (lplu) state is set to the power management level D3 + * when active is true, else clear lplu for D3. LPLU + * is used during Dx states where the power conservation is most important. + * During driver activity, SmartSpeed should be enabled so performance is + * maintained. + **/ +static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, bool active) +{ + u16 data = er32(POEMB); + + if (!active) { + data &= ~E1000_PHY_CTRL_NOND0A_LPLU; + } else if ((hw->phy.autoneg_advertised == E1000_ALL_SPEED_DUPLEX) || + (hw->phy.autoneg_advertised == E1000_ALL_NOT_GIG) || + (hw->phy.autoneg_advertised == E1000_ALL_10_SPEED)) { + data |= E1000_PHY_CTRL_NOND0A_LPLU; + } + + ew32(POEMB, data); + return 0; +} /** * e1000_acquire_nvm_82571 - Request for access to the EEPROM @@ -562,8 +730,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82573: - case e1000_82574: - case e1000_82583: break; default: ret_val = e1000e_acquire_nvm(hw); @@ -853,9 +1019,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) **/ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { - u32 ctrl, extcnf_ctrl, ctrl_ext, icr; + u32 ctrl, ctrl_ext; s32 ret_val; - u16 i = 0; /* * Prevent the PCI-E bus from sticking if there is no TLP connection @@ -880,33 +1045,33 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) */ switch (hw->mac.type) { case e1000_82573: + ret_val = e1000_get_hw_semaphore_82573(hw); + break; case e1000_82574: case e1000_82583: - extcnf_ctrl = er32(EXTCNF_CTRL); - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - - do { - ew32(EXTCNF_CTRL, extcnf_ctrl); - extcnf_ctrl = er32(EXTCNF_CTRL); - - if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) - break; - - extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; - - msleep(2); - i++; - } while (i < MDIO_OWNERSHIP_TIMEOUT); + ret_val = e1000_get_hw_semaphore_82574(hw); break; default: break; } + if (ret_val) + e_dbg("Cannot acquire MDIO ownership\n"); ctrl = er32(CTRL); e_dbg("Issuing a global reset to MAC\n"); ew32(CTRL, ctrl | E1000_CTRL_RST); + /* Must release MDIO ownership and mutex after MAC reset. */ + switch (hw->mac.type) { + case e1000_82574: + case e1000_82583: + e1000_put_hw_semaphore_82574(hw); + break; + default: + break; + } + if (hw->nvm.type == e1000_nvm_flash_hw) { udelay(10); ctrl_ext = er32(CTRL_EXT); @@ -938,7 +1103,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) /* Clear any pending interrupt events. */ ew32(IMC, 0xffffffff); - icr = er32(ICR); + er32(ICR); if (hw->mac.type == e1000_82571) { /* Install any alternate MAC address into RAR0 */ @@ -1402,6 +1567,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) u32 rxcw; u32 ctrl; u32 status; + u32 txcw; + u32 i; s32 ret_val = 0; ctrl = er32(CTRL); @@ -1422,8 +1589,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; e_dbg("AN_UP -> AN_PROG\n"); + } else { + mac->serdes_has_link = true; } - break; + break; case e1000_serdes_link_forced_up: /* @@ -1431,8 +1600,10 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) * 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. + * If the partner code word is null, stop forcing + * and restart auto negotiation. */ - if (rxcw & E1000_RXCW_C) { + if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { /* Enable autoneg, and unforce link up */ ew32(TXCW, mac->txcw); ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); @@ -1440,6 +1611,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; e_dbg("FORCED_UP -> AN_PROG\n"); + } else { + mac->serdes_has_link = true; } break; @@ -1495,6 +1668,7 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); mac->serdes_link_state = e1000_serdes_link_autoneg_progress; + mac->serdes_has_link = false; e_dbg("DOWN -> AN_PROG\n"); break; } @@ -1505,16 +1679,32 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) e_dbg("ANYSTATE -> DOWN\n"); } else { /* - * We have sync, and can tolerate one invalid (IV) - * codeword before declaring link down, so reread - * to look again. + * Check several times, if Sync and Config + * both are consistently 1 then simply ignore + * the Invalid bit and restart Autoneg */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_IV) { - mac->serdes_link_state = e1000_serdes_link_down; + for (i = 0; i < AN_RETRY_COUNT; i++) { + udelay(10); + rxcw = er32(RXCW); + if ((rxcw & E1000_RXCW_IV) && + !((rxcw & E1000_RXCW_SYNCH) && + (rxcw & E1000_RXCW_C))) { + mac->serdes_has_link = false; + mac->serdes_link_state = + e1000_serdes_link_down; + e_dbg("ANYSTATE -> DOWN\n"); + break; + } + } + + if (i == AN_RETRY_COUNT) { + txcw = er32(TXCW); + txcw |= E1000_TXCW_ANE; + ew32(TXCW, txcw); + mac->serdes_link_state = + e1000_serdes_link_autoneg_progress; mac->serdes_has_link = false; - e_dbg("ANYSTATE -> DOWN\n"); + e_dbg("ANYSTATE -> AN_PROG\n"); } } } @@ -1897,7 +2087,7 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .flags2 = FLAG2_CHECK_PHY_HANG, - .pba = 36, + .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, @@ -1914,7 +2104,7 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_SMART_POWER_DOWN | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, - .pba = 36, + .pba = 32, .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, .get_variants = e1000_get_variants_82571, .mac_ops = &e82571_mac_ops, diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index d3f7a9c3f97..7245dc2e0b7 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h @@ -488,6 +488,9 @@ #define E1000_BLK_PHY_RESET 12 #define E1000_ERR_SWFW_SYNC 13 #define E1000_NOT_IMPLEMENTED 14 +#define E1000_ERR_INVALID_ARGUMENT 16 +#define E1000_ERR_NO_SPACE 17 +#define E1000_ERR_NVM_PBA_SECTION 18 /* Loop limit on how long we wait for auto-negotiation to complete */ #define FIBER_LINK_UP_LIMIT 50 @@ -516,6 +519,7 @@ #define E1000_TXCW_ANE 0x80000000 /* Auto-neg enable */ /* Receive Configuration Word */ +#define E1000_RXCW_CW 0x0000ffff /* RxConfigWord mask */ #define E1000_RXCW_IV 0x08000000 /* Receive config invalid */ #define E1000_RXCW_C 0x20000000 /* Receive config */ #define E1000_RXCW_SYNCH 0x40000000 /* Receive config synch */ @@ -649,13 +653,16 @@ /* Mask bits for fields in Word 0x03 of the EEPROM */ #define NVM_COMPAT_LOM 0x0800 +/* length of string needed to store PBA number */ +#define E1000_PBANUM_LENGTH 11 + /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ #define NVM_SUM 0xBABA /* PBA (printed board assembly) number words */ #define NVM_PBA_OFFSET_0 8 #define NVM_PBA_OFFSET_1 9 - +#define NVM_PBA_PTR_GUARD 0xFAFA #define NVM_WORD_SIZE_BASE_SHIFT 6 /* NVM Commands - SPI */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index fdc67fead4e..5255be75374 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -38,6 +38,7 @@ #include <linux/netdevice.h> #include <linux/pci.h> #include <linux/pci-aspm.h> +#include <linux/crc32.h> #include "hw.h" @@ -482,6 +483,7 @@ extern const char e1000e_driver_version[]; extern void e1000e_check_options(struct e1000_adapter *adapter); extern void e1000e_set_ethtool_ops(struct net_device *netdev); +extern void e1000e_led_blink_task(struct work_struct *work); extern int e1000e_up(struct e1000_adapter *adapter); extern void e1000e_down(struct e1000_adapter *adapter); @@ -495,6 +497,8 @@ extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); extern void e1000e_update_stats(struct e1000_adapter *adapter); extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); +extern void e1000e_get_hw_control(struct e1000_adapter *adapter); +extern void e1000e_release_hw_control(struct e1000_adapter *adapter); extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state); extern unsigned int copybreak; @@ -513,7 +517,8 @@ extern struct e1000_info e1000_pch_info; extern struct e1000_info e1000_pch2_info; extern struct e1000_info e1000_es2_info; -extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num); +extern s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size); extern s32 e1000e_commit_phy(struct e1000_hw *hw); diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index 24f8ac9cf70..e45a61c8930 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -100,8 +100,8 @@ * 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 const u16 e1000_gg82563_cable_length_table[] = { + 0, 60, 115, 150, 150, 60, 115, 150, 180, 180, 0xFF }; #define GG82563_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_gg82563_cable_length_table) @@ -426,8 +426,8 @@ static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) { u32 swfw_sync; - while (e1000e_get_hw_semaphore(hw) != 0); - /* Empty */ + while (e1000e_get_hw_semaphore(hw) != 0) + ; /* Empty */ swfw_sync = er32(SW_FW_SYNC); swfw_sync &= ~mask; @@ -784,7 +784,7 @@ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, **/ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { - u32 ctrl, icr; + u32 ctrl; s32 ret_val; /* @@ -818,7 +818,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) /* Clear any pending interrupt events. */ ew32(IMC, 0xffffffff); - icr = er32(ICR); + er32(ICR); ret_val = e1000_check_alt_mac_addr_generic(hw); diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 8984d165a39..f8ed03dab9b 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -45,63 +45,67 @@ struct e1000_stats { int stat_offset; }; -#define E1000_STAT(m) E1000_STATS, \ - sizeof(((struct e1000_adapter *)0)->m), \ - offsetof(struct e1000_adapter, m) -#define E1000_NETDEV_STAT(m) NETDEV_STATS, \ - sizeof(((struct net_device *)0)->m), \ - offsetof(struct net_device, m) +#define E1000_STAT(str, m) { \ + .stat_string = str, \ + .type = E1000_STATS, \ + .sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \ + .stat_offset = offsetof(struct e1000_adapter, m) } +#define E1000_NETDEV_STAT(str, m) { \ + .stat_string = str, \ + .type = NETDEV_STATS, \ + .sizeof_stat = sizeof(((struct net_device *)0)->m), \ + .stat_offset = offsetof(struct net_device, 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_NETDEV_STAT(stats.rx_errors) }, - { "tx_errors", E1000_NETDEV_STAT(stats.tx_errors) }, - { "tx_dropped", E1000_NETDEV_STAT(stats.tx_dropped) }, - { "multicast", E1000_STAT(stats.mprc) }, - { "collisions", E1000_STAT(stats.colc) }, - { "rx_length_errors", E1000_NETDEV_STAT(stats.rx_length_errors) }, - { "rx_over_errors", E1000_NETDEV_STAT(stats.rx_over_errors) }, - { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, - { "rx_frame_errors", E1000_NETDEV_STAT(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_NETDEV_STAT(stats.tx_fifo_errors) }, - { "tx_heartbeat_errors", E1000_NETDEV_STAT(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) }, + E1000_STAT("rx_packets", stats.gprc), + E1000_STAT("tx_packets", stats.gptc), + E1000_STAT("rx_bytes", stats.gorc), + E1000_STAT("tx_bytes", stats.gotc), + E1000_STAT("rx_broadcast", stats.bprc), + E1000_STAT("tx_broadcast", stats.bptc), + E1000_STAT("rx_multicast", stats.mprc), + E1000_STAT("tx_multicast", stats.mptc), + E1000_NETDEV_STAT("rx_errors", stats.rx_errors), + E1000_NETDEV_STAT("tx_errors", stats.tx_errors), + E1000_NETDEV_STAT("tx_dropped", stats.tx_dropped), + E1000_STAT("multicast", stats.mprc), + E1000_STAT("collisions", stats.colc), + E1000_NETDEV_STAT("rx_length_errors", stats.rx_length_errors), + E1000_NETDEV_STAT("rx_over_errors", stats.rx_over_errors), + E1000_STAT("rx_crc_errors", stats.crcerrs), + E1000_NETDEV_STAT("rx_frame_errors", stats.rx_frame_errors), + E1000_STAT("rx_no_buffer_count", stats.rnbc), + E1000_STAT("rx_missed_errors", stats.mpc), + E1000_STAT("tx_aborted_errors", stats.ecol), + E1000_STAT("tx_carrier_errors", stats.tncrs), + E1000_NETDEV_STAT("tx_fifo_errors", stats.tx_fifo_errors), + E1000_NETDEV_STAT("tx_heartbeat_errors", stats.tx_heartbeat_errors), + E1000_STAT("tx_window_errors", stats.latecol), + E1000_STAT("tx_abort_late_coll", stats.latecol), + E1000_STAT("tx_deferred_ok", stats.dc), + E1000_STAT("tx_single_coll_ok", stats.scc), + E1000_STAT("tx_multi_coll_ok", stats.mcc), + E1000_STAT("tx_timeout_count", tx_timeout_count), + E1000_STAT("tx_restart_queue", restart_queue), + E1000_STAT("rx_long_length_errors", stats.roc), + E1000_STAT("rx_short_length_errors", stats.ruc), + E1000_STAT("rx_align_errors", stats.algnerrc), + E1000_STAT("tx_tcp_seg_good", stats.tsctc), + E1000_STAT("tx_tcp_seg_failed", stats.tsctfc), + E1000_STAT("rx_flow_control_xon", stats.xonrxc), + E1000_STAT("rx_flow_control_xoff", stats.xoffrxc), + E1000_STAT("tx_flow_control_xon", stats.xontxc), + E1000_STAT("tx_flow_control_xoff", stats.xofftxc), + E1000_STAT("rx_long_byte_count", stats.gorc), + E1000_STAT("rx_csum_offload_good", hw_csum_good), + E1000_STAT("rx_csum_offload_errors", hw_csum_err), + E1000_STAT("rx_header_split", rx_hdr_split), + E1000_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed), + E1000_STAT("tx_smbus", stats.mgptc), + E1000_STAT("rx_smbus", stats.mgprc), + E1000_STAT("dropped_smbus", stats.mgpdc), + E1000_STAT("rx_dma_failed", rx_dma_failed), + E1000_STAT("tx_dma_failed", tx_dma_failed), }; #define E1000_GLOBAL_STATS_LEN ARRAY_SIZE(e1000_gstrings_stats) @@ -194,20 +198,6 @@ static int e1000_get_settings(struct net_device *netdev, return 0; } -static u32 e1000_get_link(struct net_device *netdev) -{ - struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_hw *hw = &adapter->hw; - - /* - * Avoid touching hardware registers when possible, otherwise - * link negotiation can get messed up when user-level scripts - * are rapidly polling the driver to see if link is up. - */ - return netif_running(netdev) ? netif_carrier_ok(netdev) : - !!(er32(STATUS) & E1000_STATUS_LU); -} - static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx) { struct e1000_mac_info *mac = &adapter->hw.mac; @@ -634,20 +624,24 @@ static void e1000_get_drvinfo(struct net_device *netdev, struct e1000_adapter *adapter = netdev_priv(netdev); char firmware_version[32]; - strncpy(drvinfo->driver, e1000e_driver_name, 32); - strncpy(drvinfo->version, e1000e_driver_version, 32); + strncpy(drvinfo->driver, e1000e_driver_name, + sizeof(drvinfo->driver) - 1); + strncpy(drvinfo->version, e1000e_driver_version, + sizeof(drvinfo->version) - 1); /* * EEPROM image version # is reported as firmware version # for * PCI-E controllers */ - sprintf(firmware_version, "%d.%d-%d", + snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d", (adapter->eeprom_vers & 0xF000) >> 12, (adapter->eeprom_vers & 0x0FF0) >> 4, (adapter->eeprom_vers & 0x000F)); - strncpy(drvinfo->fw_version, firmware_version, 32); - strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + strncpy(drvinfo->fw_version, firmware_version, + sizeof(drvinfo->fw_version) - 1); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), + sizeof(drvinfo->bus_info) - 1); drvinfo->regdump_len = e1000_get_regs_len(netdev); drvinfo->eedump_len = e1000_get_eeprom_len(netdev); } @@ -763,8 +757,8 @@ 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}; + 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)); @@ -1263,6 +1257,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) u32 ctrl_reg = 0; u32 stat_reg = 0; u16 phy_reg = 0; + s32 ret_val = 0; hw->mac.autoneg = 0; @@ -1322,7 +1317,13 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) case e1000_phy_82577: case e1000_phy_82578: /* Workaround: K1 must be disabled for stable 1Gbps operation */ + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_err("Cannot setup 1Gbps loopback.\n"); + return ret_val; + } e1000_configure_k1_ich8lan(hw, false); + hw->phy.ops.release(hw); break; case e1000_phy_82579: /* Disable PHY energy detect power down */ @@ -1707,6 +1708,19 @@ static void e1000_diag_test(struct net_device *netdev, bool if_running = netif_running(netdev); set_bit(__E1000_TESTING, &adapter->state); + + if (!if_running) { + /* Get control of and reset hardware */ + if (adapter->flags & FLAG_HAS_AMT) + e1000e_get_hw_control(adapter); + + e1000e_power_up_phy(adapter); + + adapter->hw.phy.autoneg_wait_to_complete = 1; + e1000e_reset(adapter); + adapter->hw.phy.autoneg_wait_to_complete = 0; + } + if (eth_test->flags == ETH_TEST_FL_OFFLINE) { /* Offline tests */ @@ -1720,8 +1734,6 @@ static void e1000_diag_test(struct net_device *netdev, if (if_running) /* indicate we're in test mode */ dev_close(netdev); - else - e1000e_reset(adapter); if (e1000_reg_test(adapter, &data[0])) eth_test->flags |= ETH_TEST_FL_FAILED; @@ -1735,8 +1747,6 @@ static void e1000_diag_test(struct net_device *netdev, eth_test->flags |= ETH_TEST_FL_FAILED; 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; @@ -1758,28 +1768,29 @@ static void e1000_diag_test(struct net_device *netdev, if (if_running) dev_open(netdev); } else { - if (!if_running && (adapter->flags & FLAG_HAS_AMT)) { - clear_bit(__E1000_TESTING, &adapter->state); - dev_open(netdev); - set_bit(__E1000_TESTING, &adapter->state); - } + /* Online tests */ e_info("online testing starting\n"); - /* Online tests */ - if (e1000_link_test(adapter, &data[4])) - eth_test->flags |= ETH_TEST_FL_FAILED; - /* Online tests aren't run; pass by default */ + /* register, eeprom, intr and loopback tests not run online */ data[0] = 0; data[1] = 0; data[2] = 0; data[3] = 0; - if (!if_running && (adapter->flags & FLAG_HAS_AMT)) - dev_close(netdev); + if (e1000_link_test(adapter, &data[4])) + eth_test->flags |= ETH_TEST_FL_FAILED; clear_bit(__E1000_TESTING, &adapter->state); } + + if (!if_running) { + e1000e_reset(adapter); + + if (adapter->flags & FLAG_HAS_AMT) + e1000e_release_hw_control(adapter); + } + msleep_interruptible(4 * 1000); } @@ -1860,7 +1871,7 @@ static int e1000_set_wol(struct net_device *netdev, /* bit defines for adapter->led_status */ #define E1000_LED_ON 0 -static void e1000e_led_blink_task(struct work_struct *work) +void e1000e_led_blink_task(struct work_struct *work) { struct e1000_adapter *adapter = container_of(work, struct e1000_adapter, led_blink_task); @@ -1892,7 +1903,6 @@ static int e1000_phys_id(struct net_device *netdev, u32 data) (hw->mac.type == e1000_pch2lan) || (hw->mac.type == e1000_82583) || (hw->mac.type == e1000_82574)) { - INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); if (!adapter->blink_timer.function) { init_timer(&adapter->blink_timer); adapter->blink_timer.function = @@ -1986,6 +1996,9 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, p = (char *) adapter + e1000_gstrings_stats[i].stat_offset; break; + default: + data[i] = 0; + continue; } data[i] = (e1000_gstrings_stats[i].sizeof_stat == @@ -2024,7 +2037,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .get_msglevel = e1000_get_msglevel, .set_msglevel = e1000_set_msglevel, .nway_reset = e1000_nway_reset, - .get_link = e1000_get_link, + .get_link = ethtool_op_get_link, .get_eeprom_len = e1000_get_eeprom_len, .get_eeprom = e1000_get_eeprom, .set_eeprom = e1000_set_eeprom, diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index ba302a5c2c3..e774380c7ce 100644 --- a/drivers/net/e1000e/hw.h +++ b/drivers/net/e1000e/hw.h @@ -83,6 +83,7 @@ enum e1e_registers { E1000_EXTCNF_CTRL = 0x00F00, /* Extended Configuration Control */ E1000_EXTCNF_SIZE = 0x00F08, /* Extended Configuration Size */ E1000_PHY_CTRL = 0x00F10, /* PHY Control Register in CSR */ +#define E1000_POEMB E1000_PHY_CTRL /* PHY OEM Bits */ E1000_PBA = 0x01000, /* Packet Buffer Allocation - RW */ E1000_PBS = 0x01008, /* Packet Buffer Size */ E1000_EEMNGCTL = 0x01010, /* MNG EEprom Control */ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index e3374d9a247..5328a292773 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -338,12 +338,17 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) } phy->id = e1000_phy_unknown; - ret_val = e1000e_get_phy_id(hw); - if (ret_val) - goto out; - if ((phy->id == 0) || (phy->id == PHY_REVISION_MASK)) { + switch (hw->mac.type) { + default: + ret_val = e1000e_get_phy_id(hw); + if (ret_val) + goto out; + if ((phy->id != 0) && (phy->id != PHY_REVISION_MASK)) + break; + /* fall-through */ + case e1000_pch2lan: /* - * In case the PHY needs to be in mdio slow mode (eg. 82577), + * In case the PHY needs to be in mdio slow mode, * set slow mode and try to get the PHY id again. */ ret_val = e1000_set_mdio_slow_mode_hv(hw); @@ -352,6 +357,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) ret_val = e1000e_get_phy_id(hw); if (ret_val) goto out; + break; } phy->type = e1000e_get_phy_type_from_id(phy->id); @@ -1389,22 +1395,6 @@ void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw) } } -static u32 e1000_calc_rx_da_crc(u8 mac[]) -{ - u32 poly = 0xEDB88320; /* Polynomial for 802.3 CRC calculation */ - u32 i, j, mask, crc; - - crc = 0xffffffff; - for (i = 0; i < 6; i++) { - crc = crc ^ mac[i]; - for (j = 8; j > 0; j--) { - mask = (crc & 1) * (-1); - crc = (crc >> 1) ^ (poly & mask); - } - } - return ~crc; -} - /** * e1000_lv_jumbo_workaround_ich8lan - required for jumbo frame operation * with 82579 PHY @@ -1447,8 +1437,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable) mac_addr[4] = (addr_high & 0xFF); mac_addr[5] = ((addr_high >> 8) & 0xFF); - ew32(PCH_RAICC(i), - e1000_calc_rx_da_crc(mac_addr)); + ew32(PCH_RAICC(i), ~ether_crc_le(ETH_ALEN, mac_addr)); } /* Write Rx addresses to the PHY */ @@ -2303,11 +2292,10 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, */ if (ret_val == 0) { flash_data = er32flash(ICH_FLASH_FDATA0); - if (size == 1) { + if (size == 1) *data = (u8)(flash_data & 0x000000FF); - } else if (size == 2) { + else if (size == 2) *data = (u16)(flash_data & 0x0000FFFF); - } break; } else { /* @@ -2972,7 +2960,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; u16 reg; - u32 ctrl, icr, kab; + u32 ctrl, kab; s32 ret_val; /* @@ -3062,7 +3050,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ew32(CRC_OFFSET, 0x65656565); ew32(IMC, 0xffffffff); - icr = er32(ICR); + er32(ICR); kab = er32(KABGTXD); kab |= E1000_KABGTXD_BGSQLBIAS; @@ -3113,7 +3101,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) * Reset the phy after disabling host wakeup to reset the Rx buffer. */ if (hw->phy.type == e1000_phy_82578) { - hw->phy.ops.read_reg(hw, BM_WUC, &i); + e1e_rphy(hw, BM_WUC, &i); ret_val = e1000_phy_hw_reset_ich8lan(hw); if (ret_val) return ret_val; @@ -3271,9 +3259,8 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) (hw->phy.type == e1000_phy_82577)) { ew32(FCRTV_PCH, hw->fc.refresh_time); - ret_val = hw->phy.ops.write_reg(hw, - PHY_REG(BM_PORT_CTRL_PAGE, 27), - hw->fc.pause_time); + ret_val = e1e_wphy(hw, PHY_REG(BM_PORT_CTRL_PAGE, 27), + hw->fc.pause_time); if (ret_val) return ret_val; } @@ -3337,8 +3324,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) return ret_val; break; case e1000_phy_ife: - ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, - ®_data); + ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, ®_data); if (ret_val) return ret_val; @@ -3356,8 +3342,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) reg_data |= IFE_PMC_AUTO_MDIX; break; } - ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, - reg_data); + ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data); if (ret_val) return ret_val; break; @@ -3591,7 +3576,7 @@ void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw) ew32(PHY_CTRL, phy_ctrl); if (hw->mac.type >= e1000_pchlan) { - e1000_oem_bits_config_ich8lan(hw, true); + e1000_oem_bits_config_ich8lan(hw, false); ret_val = hw->phy.ops.acquire(hw); if (ret_val) return; @@ -3641,7 +3626,8 @@ 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)); + (IFE_PSCL_PROBE_MODE | + IFE_PSCL_PROBE_LEDS_OFF)); ew32(LEDCTL, hw->mac.ledctl_mode1); return 0; @@ -3655,8 +3641,7 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) **/ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw) { - return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_mode1); + return e1e_wphy(hw, HV_LED_CONFIG, (u16)hw->mac.ledctl_mode1); } /** @@ -3667,8 +3652,7 @@ static s32 e1000_setup_led_pchlan(struct e1000_hw *hw) **/ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw) { - return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, - (u16)hw->mac.ledctl_default); + return e1e_wphy(hw, HV_LED_CONFIG, (u16)hw->mac.ledctl_default); } /** @@ -3699,7 +3683,7 @@ static s32 e1000_led_on_pchlan(struct e1000_hw *hw) } } - return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data); + return e1e_wphy(hw, HV_LED_CONFIG, data); } /** @@ -3730,7 +3714,7 @@ static s32 e1000_led_off_pchlan(struct e1000_hw *hw) } } - return hw->phy.ops.write_reg(hw, HV_LED_CONFIG, data); + return e1e_wphy(hw, HV_LED_CONFIG, data); } /** @@ -3839,20 +3823,20 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) if ((hw->phy.type == e1000_phy_82578) || (hw->phy.type == e1000_phy_82579) || (hw->phy.type == e1000_phy_82577)) { - hw->phy.ops.read_reg(hw, HV_SCC_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_SCC_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_ECOL_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_ECOL_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_MCC_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_MCC_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_LATECOL_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_LATECOL_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_COLC_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_COLC_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_DC_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_DC_LOWER, &phy_data); - hw->phy.ops.read_reg(hw, HV_TNCRS_UPPER, &phy_data); - hw->phy.ops.read_reg(hw, HV_TNCRS_LOWER, &phy_data); + e1e_rphy(hw, HV_SCC_UPPER, &phy_data); + e1e_rphy(hw, HV_SCC_LOWER, &phy_data); + e1e_rphy(hw, HV_ECOL_UPPER, &phy_data); + e1e_rphy(hw, HV_ECOL_LOWER, &phy_data); + e1e_rphy(hw, HV_MCC_UPPER, &phy_data); + e1e_rphy(hw, HV_MCC_LOWER, &phy_data); + e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data); + e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data); + e1e_rphy(hw, HV_COLC_UPPER, &phy_data); + e1e_rphy(hw, HV_COLC_LOWER, &phy_data); + e1e_rphy(hw, HV_DC_UPPER, &phy_data); + e1e_rphy(hw, HV_DC_LOWER, &phy_data); + e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data); + e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data); } } diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index 0fd4eb5ac5f..ff2872153b2 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -493,9 +493,8 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw) * different link partner. */ ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { + if (ret_val) e_dbg("Error configuring flow control\n"); - } return ret_val; } @@ -1136,7 +1135,8 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) 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); + ret_val = + e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); if (ret_val) return ret_val; @@ -1496,9 +1496,8 @@ s32 e1000e_setup_led_generic(struct e1000_hw *hw) { u32 ledctl; - if (hw->mac.ops.setup_led != e1000e_setup_led_generic) { + if (hw->mac.ops.setup_led != e1000e_setup_led_generic) return -E1000_ERR_CONFIG; - } if (hw->phy.media_type == e1000_media_type_fiber) { ledctl = er32(LEDCTL); @@ -2139,6 +2138,119 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) } /** + * e1000_read_pba_string_generic - Read device part number + * @hw: pointer to the HW structure + * @pba_num: pointer to device part number + * @pba_num_size: size of part number buffer + * + * Reads the product board assembly (PBA) number from the EEPROM and stores + * the value in pba_num. + **/ +s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + s32 ret_val; + u16 nvm_data; + u16 pba_ptr; + u16 offset; + u16 length; + + if (pba_num == NULL) { + e_dbg("PBA string buffer was null\n"); + ret_val = E1000_ERR_INVALID_ARGUMENT; + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + /* + * if nvm_data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (nvm_data != NVM_PBA_PTR_GUARD) { + e_dbg("NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + e_dbg("PBA string buffer too small\n"); + return E1000_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (nvm_data >> 12) & 0xF; + pba_num[1] = (nvm_data >> 8) & 0xF; + pba_num[2] = (nvm_data >> 4) & 0xF; + pba_num[3] = nvm_data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + goto out; + } + + ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if (length == 0xFFFF || length == 0) { + e_dbg("NVM PBA number section invalid length\n"); + ret_val = E1000_ERR_NVM_PBA_SECTION; + goto out; + } + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + e_dbg("PBA string buffer too small\n"); + ret_val = E1000_ERR_NO_SPACE; + goto out; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + pba_num[offset * 2] = (u8)(nvm_data >> 8); + pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); + } + pba_num[offset * 2] = '\0'; + +out: + return ret_val; +} + +/** * e1000_read_mac_addr_generic - Read device MAC address * @hw: pointer to the HW structure * @@ -2579,25 +2691,3 @@ bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) out: return ret_val; } - -s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num) -{ - s32 ret_val; - u16 nvm_data; - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - *pba_num = (u32)(nvm_data << 16); - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - *pba_num |= nvm_data; - - return 0; -} diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index c4ca1629f53..fa5b6045254 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -54,7 +54,7 @@ #define DRV_EXTRAVERSION "-k2" -#define DRV_VERSION "1.2.7" DRV_EXTRAVERSION +#define DRV_VERSION "1.2.20" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -1325,7 +1325,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, goto next_desc; } -#define rxtop rx_ring->rx_skb_top +#define rxtop (rx_ring->rx_skb_top) if (!(status & E1000_RXD_STAT_EOP)) { /* this descriptor is only the beginning (or middle) */ if (!rxtop) { @@ -1806,9 +1806,8 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) err = pci_enable_msix(adapter->pdev, adapter->msix_entries, adapter->num_vectors); - if (err == 0) { + if (err == 0) return; - } } /* MSI-X failed, so fall through and try MSI */ e_err("Failed to initialize MSI-X interrupts. " @@ -1981,15 +1980,15 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) } /** - * e1000_get_hw_control - get control of the h/w from f/w + * e1000e_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. + * e1000e_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) +void e1000e_get_hw_control(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_ext; @@ -2006,16 +2005,16 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter) } /** - * e1000_release_hw_control - release control of the h/w to f/w + * e1000e_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. + * e1000e_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) +void e1000e_release_hw_control(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 ctrl_ext; @@ -2059,10 +2058,9 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter) int err = -ENOMEM, size; size = sizeof(struct e1000_buffer) * tx_ring->count; - tx_ring->buffer_info = vmalloc(size); + tx_ring->buffer_info = vzalloc(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); @@ -2095,10 +2093,9 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter) int i, size, desc_len, err = -ENOMEM; size = sizeof(struct e1000_buffer) * rx_ring->count; - rx_ring->buffer_info = vmalloc(size); + rx_ring->buffer_info = vzalloc(size); if (!rx_ring->buffer_info) goto err; - memset(rx_ring->buffer_info, 0, size); for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; @@ -2132,7 +2129,7 @@ err_pages: } err: vfree(rx_ring->buffer_info); - e_err("Unable to allocate memory for the transmit descriptor ring\n"); + e_err("Unable to allocate memory for the receive descriptor ring\n"); return err; } @@ -2200,9 +2197,8 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter) e1000_clean_rx_ring(adapter); - for (i = 0; i < rx_ring->count; i++) { + for (i = 0; i < rx_ring->count; i++) kfree(rx_ring->buffer_info[i].ps_pages); - } vfree(rx_ring->buffer_info); rx_ring->buffer_info = NULL; @@ -2242,20 +2238,18 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, /* handle TSO and jumbo frames */ if (bytes/packets > 8000) retval = bulk_latency; - else if ((packets < 5) && (bytes > 512)) { + 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) { + if (bytes/packets > 8000) retval = bulk_latency; - } else if ((packets < 10) || ((bytes/packets) > 1200)) { + else if ((packets < 10) || ((bytes/packets) > 1200)) retval = bulk_latency; - } else if ((packets > 35)) { + else if ((packets > 35)) retval = lowest_latency; - } } else if (bytes/packets > 2000) { retval = bulk_latency; } else if (packets <= 2 && bytes < 512) { @@ -2264,9 +2258,8 @@ static unsigned int e1000_update_itr(struct e1000_adapter *adapter, break; case bulk_latency: /* 250 usec aka 4000 ints/s */ if (bytes > 25000) { - if (packets > 35) { + if (packets > 35) retval = low_latency; - } } else if (bytes < 6000) { retval = low_latency; } @@ -2452,7 +2445,7 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) E1000_MNG_DHCP_COOKIE_STATUS_VLAN) && (vid == adapter->mng_vlan_id)) { /* release control to f/w */ - e1000_release_hw_control(adapter); + e1000e_release_hw_control(adapter); return; } @@ -2741,6 +2734,9 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true); else ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false); + + if (ret_val) + e_dbg("failed to enable jumbo frame workaround mode\n"); } /* Program MC offset vector base */ @@ -3191,7 +3187,6 @@ void e1000e_reset(struct e1000_adapter *adapter) ew32(PBA, pba); } - /* * flow control settings * @@ -3279,7 +3274,7 @@ void e1000e_reset(struct e1000_adapter *adapter) * that the network interface is in control */ if (adapter->flags & FLAG_HAS_AMT) - e1000_get_hw_control(adapter); + e1000e_get_hw_control(adapter); ew32(WUC, 0); @@ -3292,6 +3287,13 @@ void e1000e_reset(struct e1000_adapter *adapter) ew32(VET, ETH_P_8021Q); e1000e_reset_adaptive(hw); + + if (!netif_running(adapter->netdev) && + !test_bit(__E1000_TESTING, &adapter->state)) { + e1000_power_down_phy(adapter); + return; + } + e1000_get_phy_info(hw); if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && @@ -3577,7 +3579,7 @@ static int e1000_open(struct net_device *netdev) * interface is now open and reset the part to a known state. */ if (adapter->flags & FLAG_HAS_AMT) { - e1000_get_hw_control(adapter); + e1000e_get_hw_control(adapter); e1000e_reset(adapter); } @@ -3641,7 +3643,7 @@ static int e1000_open(struct net_device *netdev) return 0; err_req_irq: - e1000_release_hw_control(adapter); + e1000e_release_hw_control(adapter); e1000_power_down_phy(adapter); e1000e_free_rx_resources(adapter); err_setup_rx: @@ -3696,8 +3698,9 @@ static int e1000_close(struct net_device *netdev) * 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); + if ((adapter->flags & FLAG_HAS_AMT) && + !test_bit(__E1000_TESTING, &adapter->state)) + e1000e_release_hw_control(adapter); if ((adapter->flags & FLAG_HAS_ERT) || (adapter->hw.mac.type == e1000_pch2lan)) @@ -4475,7 +4478,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) break; } - css = skb_transport_offset(skb); + css = skb_checksum_start_offset(skb); i = tx_ring->next_to_use; buffer_info = &tx_ring->buffer_info[i]; @@ -4595,7 +4598,7 @@ dma_error: i += tx_ring->count; i--; buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info);; + e1000_put_txbuf(adapter, buffer_info); } return 0; @@ -4631,7 +4634,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, i = tx_ring->next_to_use; - while (count--) { + do { 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); @@ -4642,7 +4645,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, i++; if (i == tx_ring->count) i = 0; - } + } while (--count > 0); tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd); @@ -5216,7 +5219,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, * 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); + e1000e_release_hw_control(adapter); pci_disable_device(pdev); @@ -5373,7 +5376,7 @@ static int __e1000_resume(struct pci_dev *pdev) * under the control of the driver. */ if (!(adapter->flags & FLAG_HAS_AMT)) - e1000_get_hw_control(adapter); + e1000e_get_hw_control(adapter); return 0; } @@ -5465,6 +5468,36 @@ static void e1000_shutdown(struct pci_dev *pdev) } #ifdef CONFIG_NET_POLL_CONTROLLER + +static irqreturn_t e1000_intr_msix(int irq, void *data) +{ + struct net_device *netdev = data; + struct e1000_adapter *adapter = netdev_priv(netdev); + int vector, msix_irq; + + if (adapter->msix_entries) { + vector = 0; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_intr_msix_rx(msix_irq, netdev); + enable_irq(msix_irq); + + vector++; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_intr_msix_tx(msix_irq, netdev); + enable_irq(msix_irq); + + vector++; + msix_irq = adapter->msix_entries[vector].vector; + disable_irq(msix_irq); + e1000_msix_other(msix_irq, netdev); + enable_irq(msix_irq); + } + + return IRQ_HANDLED; +} + /* * Polling 'interrupt' - used by things like netconsole to send skbs * without having to re-enable interrupts. It's not called while @@ -5474,10 +5507,21 @@ static void e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - disable_irq(adapter->pdev->irq); - e1000_intr(adapter->pdev->irq, netdev); - - enable_irq(adapter->pdev->irq); + switch (adapter->int_mode) { + case E1000E_INT_MODE_MSIX: + e1000_intr_msix(adapter->pdev->irq, netdev); + break; + case E1000E_INT_MODE_MSI: + disable_irq(adapter->pdev->irq); + e1000_intr_msi(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); + break; + default: /* E1000E_INT_MODE_LEGACY */ + disable_irq(adapter->pdev->irq); + e1000_intr(adapter->pdev->irq, netdev); + enable_irq(adapter->pdev->irq); + break; + } } #endif @@ -5579,7 +5623,7 @@ static void e1000_io_resume(struct pci_dev *pdev) * under the control of the driver. */ if (!(adapter->flags & FLAG_HAS_AMT)) - e1000_get_hw_control(adapter); + e1000e_get_hw_control(adapter); } @@ -5587,7 +5631,8 @@ 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; + u32 ret_val; + u8 pba_str[E1000_PBANUM_LENGTH]; /* print bus type/speed/width info */ e_info("(PCI Express:2.5GB/s:%s) %pM\n", @@ -5598,9 +5643,12 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) netdev->dev_addr); e_info("Intel(R) PRO/%s Network Connection\n", (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000"); - e1000e_read_pba_num(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)); + ret_val = e1000_read_pba_string_generic(hw, pba_str, + E1000_PBANUM_LENGTH); + if (ret_val) + strncpy((char *)pba_str, "Unknown", sizeof(pba_str) - 1); + e_info("MAC: %d, PHY: %d, PBA No: %s\n", + hw->mac.type, hw->phy.type, pba_str); } static void e1000_eeprom_checks(struct e1000_adapter *adapter) @@ -5864,6 +5912,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround); INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task); INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang); + INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task); /* Initialize link parameters. User can change them with ethtool */ adapter->hw.mac.autoneg = 1; @@ -5924,9 +5973,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev, * under the control of the driver. */ if (!(adapter->flags & FLAG_HAS_AMT)) - e1000_get_hw_control(adapter); + e1000e_get_hw_control(adapter); - strcpy(netdev->name, "eth%d"); + strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1); err = register_netdev(netdev); if (err) goto err_register; @@ -5943,12 +5992,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev, err_register: if (!(adapter->flags & FLAG_HAS_AMT)) - e1000_release_hw_control(adapter); + e1000e_release_hw_control(adapter); err_eeprom: if (!e1000_check_reset_block(&adapter->hw)) e1000_phy_hw_reset(&adapter->hw); err_hw_init: - kfree(adapter->tx_ring); kfree(adapter->rx_ring); err_sw_init: @@ -5984,8 +6032,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev) bool down = test_bit(__E1000_DOWN, &adapter->state); /* - * flush_scheduled work may reschedule our watchdog task, so - * explicitly disable watchdog tasks from being rescheduled + * The timers may be rescheduled, so explicitly disable them + * from being rescheduled. */ if (!down) set_bit(__E1000_DOWN, &adapter->state); @@ -5996,8 +6044,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev) cancel_work_sync(&adapter->watchdog_task); cancel_work_sync(&adapter->downshift_task); cancel_work_sync(&adapter->update_phy_task); + cancel_work_sync(&adapter->led_blink_task); cancel_work_sync(&adapter->print_hang_task); - flush_scheduled_work(); if (!(netdev->flags & IFF_UP)) e1000_power_down_phy(adapter); @@ -6014,7 +6062,7 @@ static void __devexit e1000_remove(struct pci_dev *pdev) * 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); + e1000e_release_hw_control(adapter); e1000e_reset_interrupt_capability(adapter); kfree(adapter->tx_ring); diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c index 3d36911f77f..a9612b0e4bc 100644 --- a/drivers/net/e1000e/param.c +++ b/drivers/net/e1000e/param.c @@ -421,7 +421,7 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) static const struct e1000_option opt = { .type = enable_option, .name = "CRC Stripping", - .err = "defaulting to enabled", + .err = "defaulting to Enabled", .def = OPTION_ENABLED }; diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 3d3dc0c8235..a640f1c369a 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -42,20 +42,20 @@ static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset, u16 *data, bool read); /* Cable length tables */ -static const u16 e1000_m88_cable_length_table[] = - { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; +static const u16 e1000_m88_cable_length_table[] = { + 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; #define M88E1000_CABLE_LENGTH_TABLE_SIZE \ ARRAY_SIZE(e1000_m88_cable_length_table) -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}; +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 \ ARRAY_SIZE(e1000_igp_2_cable_length_table) @@ -226,6 +226,13 @@ s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) } *data = (u16) mdic; + /* + * Allow some time after each MDIC transaction to avoid + * reading duplicate data in the next MDIC transaction. + */ + if (hw->mac.type == e1000_pch2lan) + udelay(100); + return 0; } @@ -279,6 +286,13 @@ s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) return -E1000_ERR_PHY; } + /* + * Allow some time after each MDIC transaction to avoid + * reading duplicate data in the next MDIC transaction. + */ + if (hw->mac.type == e1000_pch2lan) + udelay(100); + return 0; } @@ -623,12 +637,11 @@ s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data) **/ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) { - struct e1000_phy_info *phy = &hw->phy; s32 ret_val; u16 phy_data; /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = phy->ops.read_reg(hw, I82577_CFG_REG, &phy_data); + ret_val = e1e_rphy(hw, I82577_CFG_REG, &phy_data); if (ret_val) goto out; @@ -637,7 +650,7 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) /* Enable downshift */ phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; - ret_val = phy->ops.write_reg(hw, I82577_CFG_REG, phy_data); + ret_val = e1e_wphy(hw, I82577_CFG_REG, phy_data); out: return ret_val; @@ -760,16 +773,14 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw) } if (phy->type == e1000_phy_82578) { - ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); + ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) return ret_val; /* 82578 PHY - set the downshift count to 1x. */ phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE; phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK; - ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); + ret_val = e1e_wphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if (ret_val) return ret_val; } @@ -1043,9 +1054,8 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) e_dbg("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - if (phy->autoneg_mask & ADVERTISE_1000_FULL) { + if (phy->autoneg_mask & ADVERTISE_1000_FULL) ret_val = e1e_wphy(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); - } return ret_val; } @@ -1306,9 +1316,8 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw) * We didn't get link. * Reset the DSP and cross our fingers. */ - ret_val = e1e_wphy(hw, - M88E1000_PHY_PAGE_SELECT, - 0x001d); + ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT, + 0x001d); if (ret_val) return ret_val; ret_val = e1000e_phy_reset_dsp(hw); @@ -1840,11 +1849,12 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw) 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}; + static const u16 agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] = { + IGP02E1000_PHY_AGC_A, + IGP02E1000_PHY_AGC_B, + IGP02E1000_PHY_AGC_C, + IGP02E1000_PHY_AGC_D + }; /* Read the AGC registers for all channels */ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { @@ -3057,12 +3067,12 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) goto out; /* Do not apply workaround if in PHY loopback bit 14 set */ - hw->phy.ops.read_reg(hw, PHY_CONTROL, &data); + e1e_rphy(hw, PHY_CONTROL, &data); if (data & PHY_CONTROL_LB) goto out; /* check if link is up and at 1Gbps */ - ret_val = hw->phy.ops.read_reg(hw, BM_CS_STATUS, &data); + ret_val = e1e_rphy(hw, BM_CS_STATUS, &data); if (ret_val) goto out; @@ -3078,14 +3088,12 @@ s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw) mdelay(200); /* flush the packets in the fifo buffer */ - ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC | - HV_MUX_DATA_CTRL_FORCE_SPEED); + ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC | + HV_MUX_DATA_CTRL_FORCE_SPEED); if (ret_val) goto out; - ret_val = hw->phy.ops.write_reg(hw, HV_MUX_DATA_CTRL, - HV_MUX_DATA_CTRL_GEN_TO_MAC); + ret_val = e1e_wphy(hw, HV_MUX_DATA_CTRL, HV_MUX_DATA_CTRL_GEN_TO_MAC); out: return ret_val; @@ -3105,7 +3113,7 @@ s32 e1000_check_polarity_82577(struct e1000_hw *hw) s32 ret_val; u16 data; - ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data); + ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data); if (!ret_val) phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY) @@ -3128,13 +3136,13 @@ s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw) u16 phy_data; bool link; - ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); + ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_data); if (ret_val) goto out; e1000e_phy_force_speed_duplex_setup(hw, &phy_data); - ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); + ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data); if (ret_val) goto out; @@ -3198,7 +3206,7 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = phy->ops.read_reg(hw, I82577_PHY_STATUS_2, &data); + ret_val = e1e_rphy(hw, I82577_PHY_STATUS_2, &data); if (ret_val) goto out; @@ -3210,7 +3218,7 @@ s32 e1000_get_phy_info_82577(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); + ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data); if (ret_val) goto out; @@ -3244,7 +3252,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw) s32 ret_val; u16 phy_data, length; - ret_val = phy->ops.read_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data); + ret_val = e1e_rphy(hw, I82577_PHY_DIAG_STATUS, &phy_data); if (ret_val) goto out; |