diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-12 03:32:41 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-12 03:32:41 +0300 |
commit | 4162cf64973df51fc885825bc9ca4d055891c49f (patch) | |
tree | f218c7bd298f4d41be94d08a314eb9fbc3fcb4ea /drivers/net/e1000e | |
parent | fb7b5a956992fdc53d0b9c8ea29b51b92839dc1b (diff) | |
parent | 343a8d13aae58dec562dbb5c7d48a53e9b847871 (diff) | |
download | linux-4162cf64973df51fc885825bc9ca4d055891c49f.tar.xz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (67 commits)
cxgb4vf: recover from failure in cxgb4vf_open()
netfilter: ebtables: make broute table work again
netfilter: fix race in conntrack between dump_table and destroy
ah: reload pointers to skb data after calling skb_cow_data()
ah: update maximum truncated ICV length
xfrm: check trunc_len in XFRMA_ALG_AUTH_TRUNC
ehea: Increase the skb array usage
net/fec: remove config FEC2 as it's used nowhere
pcnet_cs: add new_id
tcp: disallow bind() to reuse addr/port
net/r8169: Update the function of parsing firmware
net: ppp: use {get,put}_unaligned_be{16,32}
CAIF: Fix IPv6 support in receive path for GPRS/3G
arp: allow to invalidate specific ARP entries
net_sched: factorize qdisc stats handling
mlx4: Call alloc_etherdev to allocate RX and TX queues
net: Add alloc_netdev_mqs function
caif: don't set connection request param size before copying data
cxgb4vf: fix mailbox data/control coherency domain race
qlcnic: change module parameter permissions
...
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/82571.c | 77 | ||||
-rw-r--r-- | drivers/net/e1000e/e1000.h | 3 | ||||
-rw-r--r-- | drivers/net/e1000e/es2lan.c | 4 | ||||
-rw-r--r-- | drivers/net/e1000e/ethtool.c | 54 | ||||
-rw-r--r-- | drivers/net/e1000e/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 77 | ||||
-rw-r--r-- | drivers/net/e1000e/lib.c | 3 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 53 | ||||
-rw-r--r-- | drivers/net/e1000e/phy.c | 40 |
9 files changed, 188 insertions, 124 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index e57e4097ef1b..cb6c7b1c1fb8 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -78,6 +78,8 @@ 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. @@ -113,6 +115,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) 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; @@ -121,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; } /** @@ -649,6 +660,58 @@ static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) } /** + * 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 * @hw: pointer to the HW structure * @@ -956,7 +1019,7 @@ 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, ctrl_ext, icr; + u32 ctrl, ctrl_ext; s32 ret_val; /* @@ -1040,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 */ diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 2c913b8e9116..5255be753746 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" @@ -496,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; diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c index b18c644e13d1..e45a61c8930a 100644 --- a/drivers/net/e1000e/es2lan.c +++ b/drivers/net/e1000e/es2lan.c @@ -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 affcacf6f5a9..f8ed03dab9b1 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c @@ -624,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); } @@ -1704,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 */ @@ -1717,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; @@ -1732,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; @@ -1755,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); } diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h index ba302a5c2c30..e774380c7cec 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 d86cc0832720..5328a2927731 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -1395,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 @@ -1453,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 */ @@ -2977,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; /* @@ -3067,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; @@ -3118,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; @@ -3276,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; } @@ -3342,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; @@ -3361,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; @@ -3646,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; @@ -3660,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); } /** @@ -3672,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); } /** @@ -3704,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); } /** @@ -3735,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); } /** @@ -3844,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 7e55170a601e..ff2872153b21 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c @@ -1135,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; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index fe50242aa9e6..fa5b60452547 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1980,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; @@ -2005,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; @@ -2445,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; } @@ -2734,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 */ @@ -3184,7 +3187,6 @@ void e1000e_reset(struct e1000_adapter *adapter) ew32(PBA, pba); } - /* * flow control settings * @@ -3272,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); @@ -3285,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) && @@ -3570,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); } @@ -3634,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: @@ -3689,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)) @@ -5209,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); @@ -5366,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; } @@ -5613,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); } @@ -5636,7 +5646,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) ret_val = e1000_read_pba_string_generic(hw, pba_str, E1000_PBANUM_LENGTH); if (ret_val) - strcpy(pba_str, "Unknown"); + 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); } @@ -5963,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; @@ -5982,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: @@ -6053,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/phy.c b/drivers/net/e1000e/phy.c index 1781efeb55e3..a640f1c369ae 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -637,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; @@ -651,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; @@ -774,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; } @@ -1319,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); @@ -3071,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; @@ -3092,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; @@ -3119,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) @@ -3142,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; @@ -3212,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; @@ -3224,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; @@ -3258,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; |