summaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/82571.c22
-rw-r--r--drivers/net/e1000e/e1000.h12
-rw-r--r--drivers/net/e1000e/es2lan.c5
-rw-r--r--drivers/net/e1000e/ethtool.c154
-rw-r--r--drivers/net/e1000e/hw.h1
-rw-r--r--drivers/net/e1000e/ich8lan.c16
-rw-r--r--drivers/net/e1000e/lib.c14
-rw-r--r--drivers/net/e1000e/netdev.c213
-rw-r--r--drivers/net/e1000e/phy.c4
9 files changed, 240 insertions, 201 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 89a69035e53..8295f219243 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -300,6 +300,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
func->set_lan_id = e1000_set_lan_id_single_port;
func->check_mng_mode = e1000e_check_mng_mode_generic;
func->led_on = e1000e_led_on_generic;
+ func->blink_led = e1000e_blink_led_generic;
/* FWSM register */
mac->has_fwsm = true;
@@ -320,6 +321,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
default:
func->check_mng_mode = e1000e_check_mng_mode_generic;
func->led_on = e1000e_led_on_generic;
+ func->blink_led = e1000e_blink_led_generic;
/* FWSM register */
mac->has_fwsm = true;
@@ -431,9 +433,6 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
case e1000_82573:
case e1000_82574:
case e1000_82583:
- /* Disable ASPM L0s due to hardware errata */
- e1000e_disable_aspm(adapter->pdev, PCIE_LINK_STATE_L0S);
-
if (pdev->device == E1000_DEV_ID_82573L) {
adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = DEFAULT_JUMBO;
@@ -594,7 +593,7 @@ static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
- msleep(2);
+ usleep_range(2000, 4000);
i++;
} while (i < MDIO_OWNERSHIP_TIMEOUT);
@@ -816,7 +815,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
/* Check for pending operations. */
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
+ usleep_range(1000, 2000);
if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
break;
}
@@ -840,7 +839,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
ew32(EECD, eecd);
for (i = 0; i < E1000_FLASH_UPDATES; i++) {
- msleep(1);
+ usleep_range(1000, 2000);
if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
break;
}
@@ -930,7 +929,7 @@ static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw)
if (er32(EEMNGCTL) &
E1000_NVM_CFG_DONE_PORT_0)
break;
- msleep(1);
+ usleep_range(1000, 2000);
timeout--;
}
if (!timeout) {
@@ -1037,7 +1036,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
/*
* Must acquire the MDIO ownership before MAC reset.
@@ -2066,7 +2065,8 @@ struct e1000_info e1000_82573_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_SWSM_ON_LOAD,
- .flags2 = FLAG2_DISABLE_ASPM_L1,
+ .flags2 = FLAG2_DISABLE_ASPM_L1
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 20,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
@@ -2086,7 +2086,8 @@ struct e1000_info e1000_82574_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
- .flags2 = FLAG2_CHECK_PHY_HANG,
+ .flags2 = FLAG2_CHECK_PHY_HANG
+ | FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = DEFAULT_JUMBO,
.get_variants = e1000_get_variants_82571,
@@ -2104,6 +2105,7 @@ struct e1000_info e1000_82583_info = {
| FLAG_HAS_SMART_POWER_DOWN
| FLAG_HAS_AMT
| FLAG_HAS_CTRLEXT_ON_LOAD,
+ .flags2 = FLAG2_DISABLE_ASPM_L0S,
.pba = 32,
.max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN,
.get_variants = e1000_get_variants_82571,
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 00bf595ebd6..9549879e66a 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -31,6 +31,7 @@
#ifndef _E1000_H_
#define _E1000_H_
+#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
@@ -39,6 +40,7 @@
#include <linux/pci.h>
#include <linux/pci-aspm.h>
#include <linux/crc32.h>
+#include <linux/if_vlan.h>
#include "hw.h"
@@ -280,7 +282,7 @@ struct e1000_adapter {
const struct e1000_info *ei;
- struct vlan_group *vlgrp;
+ unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
u32 bd_number;
u32 rx_buffer_len;
u16 mng_vlan_id;
@@ -389,13 +391,10 @@ struct e1000_adapter {
bool fc_autoneg;
- unsigned long led_status;
-
unsigned int flags;
unsigned int flags2;
struct work_struct downshift_task;
struct work_struct update_phy_task;
- struct work_struct led_blink_task;
struct work_struct print_hang_task;
bool idle_check;
@@ -456,6 +455,7 @@ struct e1000_info {
#define FLAG2_HAS_PHY_STATS (1 << 4)
#define FLAG2_HAS_EEE (1 << 5)
#define FLAG2_DMA_BURST (1 << 6)
+#define FLAG2_DISABLE_ASPM_L0S (1 << 7)
#define FLAG2_DISABLE_AIM (1 << 8)
#define FLAG2_CHECK_PHY_HANG (1 << 9)
@@ -484,7 +484,6 @@ 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);
@@ -502,7 +501,6 @@ 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;
@@ -573,7 +571,7 @@ extern s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data);
extern void e1000e_config_collision_dist(struct e1000_hw *hw);
extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
-extern s32 e1000e_blink_led(struct e1000_hw *hw);
+extern s32 e1000e_blink_led_generic(struct e1000_hw *hw);
extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
extern void e1000e_reset_adaptive(struct e1000_hw *hw);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 2fefa820302..f4bbeb22f51 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -612,7 +612,7 @@ static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw)
while (timeout) {
if (er32(EEMNGCTL) & mask)
break;
- msleep(1);
+ usleep_range(1000, 2000);
timeout--;
}
if (!timeout) {
@@ -802,7 +802,7 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
ctrl = er32(CTRL);
@@ -1434,6 +1434,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
static struct e1000_mac_operations es2_mac_ops = {
.read_mac_addr = e1000_read_mac_addr_80003es2lan,
.id_led_init = e1000e_id_led_init,
+ .blink_led = e1000e_blink_led_generic,
.check_mng_mode = e1000e_check_mng_mode_generic,
/* check_for_link dependent on media type */
.cleanup_led = e1000e_cleanup_led_generic,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 07f09e96e45..859d0d3af6c 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -122,6 +122,7 @@ static int e1000_get_settings(struct net_device *netdev,
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u32 speed;
if (hw->phy.media_type == e1000_media_type_copper) {
@@ -159,23 +160,23 @@ static int e1000_get_settings(struct net_device *netdev,
ecmd->transceiver = XCVR_EXTERNAL;
}
- ecmd->speed = -1;
+ speed = -1;
ecmd->duplex = -1;
if (netif_running(netdev)) {
if (netif_carrier_ok(netdev)) {
- ecmd->speed = adapter->link_speed;
+ speed = adapter->link_speed;
ecmd->duplex = adapter->link_duplex - 1;
}
} else {
u32 status = er32(STATUS);
if (status & E1000_STATUS_LU) {
if (status & E1000_STATUS_SPEED_1000)
- ecmd->speed = 1000;
+ speed = SPEED_1000;
else if (status & E1000_STATUS_SPEED_100)
- ecmd->speed = 100;
+ speed = SPEED_100;
else
- ecmd->speed = 10;
+ speed = SPEED_10;
if (status & E1000_STATUS_FD)
ecmd->duplex = DUPLEX_FULL;
@@ -184,6 +185,7 @@ static int e1000_get_settings(struct net_device *netdev,
}
}
+ ethtool_cmd_speed_set(ecmd, speed);
ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
@@ -198,20 +200,25 @@ static int e1000_get_settings(struct net_device *netdev,
return 0;
}
-static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
{
struct e1000_mac_info *mac = &adapter->hw.mac;
mac->autoneg = 0;
+ /* Make sure dplx is at most 1 bit and lsb of speed is not set
+ * for the switch() below to work */
+ if ((spd & 1) || (dplx & ~1))
+ goto err_inval;
+
/* Fiber NICs only allow 1000 gbps Full duplex */
if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
- spddplx != (SPEED_1000 + DUPLEX_FULL)) {
- e_err("Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ spd != SPEED_1000 &&
+ dplx != DUPLEX_FULL) {
+ goto err_inval;
}
- switch (spddplx) {
+ switch (spd + dplx) {
case SPEED_10 + DUPLEX_HALF:
mac->forced_speed_duplex = ADVERTISE_10_HALF;
break;
@@ -230,10 +237,13 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
break;
case SPEED_1000 + DUPLEX_HALF: /* not supported */
default:
- e_err("Unsupported Speed/Duplex configuration\n");
- return -EINVAL;
+ goto err_inval;
}
return 0;
+
+err_inval:
+ e_err("Unsupported Speed/Duplex configuration\n");
+ return -EINVAL;
}
static int e1000_set_settings(struct net_device *netdev,
@@ -253,7 +263,7 @@ static int e1000_set_settings(struct net_device *netdev,
}
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (ecmd->autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1;
@@ -269,7 +279,8 @@ static int e1000_set_settings(struct net_device *netdev,
if (adapter->fc_autoneg)
hw->fc.requested_mode = e1000_fc_default;
} else {
- if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+ u32 speed = ethtool_cmd_speed(ecmd);
+ if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
clear_bit(__E1000_RESETTING, &adapter->state);
return -EINVAL;
}
@@ -317,7 +328,7 @@ static int e1000_set_pauseparam(struct net_device *netdev,
adapter->fc_autoneg = pause->autoneg;
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (adapter->fc_autoneg == AUTONEG_ENABLE) {
hw->fc.requested_mode = e1000_fc_default;
@@ -673,7 +684,7 @@ static int e1000_set_ringparam(struct net_device *netdev,
return -EINVAL;
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (netif_running(adapter->netdev))
e1000e_down(adapter);
@@ -952,7 +963,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Disable all the interrupts */
ew32(IMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Test each interrupt */
for (i = 0; i < 10; i++) {
@@ -984,7 +995,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMC, mask);
ew32(ICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr & mask) {
*data = 3;
@@ -1002,7 +1013,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMS, mask);
ew32(ICS, mask);
- msleep(10);
+ usleep_range(10000, 20000);
if (!(adapter->test_icr & mask)) {
*data = 4;
@@ -1020,7 +1031,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
adapter->test_icr = 0;
ew32(IMC, ~mask & 0x00007FFF);
ew32(ICS, ~mask & 0x00007FFF);
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->test_icr) {
*data = 5;
@@ -1031,7 +1042,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
/* Disable all the interrupts */
ew32(IMC, 0xFFFFFFFF);
- msleep(10);
+ usleep_range(10000, 20000);
/* Unhook test interrupt handler */
free_irq(irq, netdev);
@@ -1406,7 +1417,7 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
*/
#define E1000_SERDES_LB_ON 0x410
ew32(SCTL, E1000_SERDES_LB_ON);
- msleep(10);
+ usleep_range(10000, 20000);
return 0;
}
@@ -1501,7 +1512,7 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
hw->phy.media_type == e1000_media_type_internal_serdes) {
#define E1000_SERDES_LB_OFF 0x400
ew32(SCTL, E1000_SERDES_LB_OFF);
- msleep(10);
+ usleep_range(10000, 20000);
break;
}
/* Fall Through */
@@ -1851,64 +1862,35 @@ static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
return 0;
}
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define E1000_ID_INTERVAL (HZ/4)
-
-/* bit defines for adapter->led_status */
-#define E1000_LED_ON 0
-
-void e1000e_led_blink_task(struct work_struct *work)
-{
- struct e1000_adapter *adapter = container_of(work,
- struct e1000_adapter, led_blink_task);
-
- if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
- adapter->hw.mac.ops.led_off(&adapter->hw);
- else
- adapter->hw.mac.ops.led_on(&adapter->hw);
-}
-
-static void e1000_led_blink_callback(unsigned long data)
-{
- struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-
- schedule_work(&adapter->led_blink_task);
- mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
-}
-
-static int e1000_phys_id(struct net_device *netdev, u32 data)
+static int e1000_set_phys_id(struct net_device *netdev,
+ enum ethtool_phys_id_state state)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- if (!data)
- data = INT_MAX;
+ switch (state) {
+ case ETHTOOL_ID_ACTIVE:
+ if (!hw->mac.ops.blink_led)
+ return 2; /* cycle on/off twice per second */
- if ((hw->phy.type == e1000_phy_ife) ||
- (hw->mac.type == e1000_pchlan) ||
- (hw->mac.type == e1000_pch2lan) ||
- (hw->mac.type == e1000_82583) ||
- (hw->mac.type == e1000_82574)) {
- if (!adapter->blink_timer.function) {
- init_timer(&adapter->blink_timer);
- adapter->blink_timer.function =
- e1000_led_blink_callback;
- adapter->blink_timer.data = (unsigned long) adapter;
- }
- mod_timer(&adapter->blink_timer, jiffies);
- msleep_interruptible(data * 1000);
- del_timer_sync(&adapter->blink_timer);
+ hw->mac.ops.blink_led(hw);
+ break;
+
+ case ETHTOOL_ID_INACTIVE:
if (hw->phy.type == e1000_phy_ife)
e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
- } else {
- e1000e_blink_led(hw);
- msleep_interruptible(data * 1000);
- }
+ hw->mac.ops.led_off(hw);
+ hw->mac.ops.cleanup_led(hw);
+ break;
- hw->mac.ops.led_off(hw);
- clear_bit(E1000_LED_ON, &adapter->led_status);
- hw->mac.ops.cleanup_led(hw);
+ case ETHTOOL_ID_ON:
+ adapter->hw.mac.ops.led_on(&adapter->hw);
+ break;
+ case ETHTOOL_ID_OFF:
+ adapter->hw.mac.ops.led_off(&adapter->hw);
+ break;
+ }
return 0;
}
@@ -2020,6 +2002,31 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
}
}
+static int e1000e_set_flags(struct net_device *netdev, u32 data)
+{
+ struct e1000_adapter *adapter = netdev_priv(netdev);
+ bool need_reset = false;
+ int rc;
+
+ need_reset = (data & ETH_FLAG_RXVLAN) !=
+ (netdev->features & NETIF_F_HW_VLAN_RX);
+
+ rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
+ ETH_FLAG_TXVLAN);
+
+ if (rc)
+ return rc;
+
+ if (need_reset) {
+ if (netif_running(netdev))
+ e1000e_reinit_locked(adapter);
+ else
+ e1000e_reset(adapter);
+ }
+
+ return 0;
+}
+
static const struct ethtool_ops e1000_ethtool_ops = {
.get_settings = e1000_get_settings,
.set_settings = e1000_set_settings,
@@ -2049,12 +2056,13 @@ static const struct ethtool_ops e1000_ethtool_ops = {
.set_tso = e1000_set_tso,
.self_test = e1000_diag_test,
.get_strings = e1000_get_strings,
- .phys_id = e1000_phys_id,
+ .set_phys_id = e1000_set_phys_id,
.get_ethtool_stats = e1000_get_ethtool_stats,
.get_sset_count = e1000e_get_sset_count,
.get_coalesce = e1000_get_coalesce,
.set_coalesce = e1000_set_coalesce,
.get_flags = ethtool_op_get_flags,
+ .set_flags = e1000e_set_flags,
};
void e1000e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 307e1ec2241..6c2fa8327f5 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -756,6 +756,7 @@ struct e1000_host_mng_command_info {
/* Function pointers and static data for the MAC. */
struct e1000_mac_operations {
s32 (*id_led_init)(struct e1000_hw *);
+ s32 (*blink_led)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
s32 (*check_for_link)(struct e1000_hw *);
s32 (*cleanup_led)(struct e1000_hw *);
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index ce1dbfdca11..3369d1f6a39 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -338,7 +338,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
/* Ungate automatic PHY configuration on non-managed 82579 */
if ((hw->mac.type == e1000_pch2lan) &&
!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
- msleep(10);
+ usleep_range(10000, 20000);
e1000_gate_hw_phy_config_ich8lan(hw, false);
}
@@ -427,7 +427,7 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
phy->id = 0;
while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
(i++ < 100)) {
- msleep(1);
+ usleep_range(1000, 2000);
ret_val = e1000e_get_phy_id(hw);
if (ret_val)
return ret_val;
@@ -564,6 +564,8 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
/* ID LED init */
mac->ops.id_led_init = e1000e_id_led_init;
+ /* blink LED */
+ mac->ops.blink_led = e1000e_blink_led_generic;
/* setup LED */
mac->ops.setup_led = e1000e_setup_led_generic;
/* cleanup LED */
@@ -767,6 +769,8 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
(!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
+
+ hw->mac.ops.blink_led = NULL;
}
if ((adapter->hw.mac.type == e1000_ich8lan) &&
@@ -1704,7 +1708,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
goto out;
/* Allow time for h/w to get to quiescent state after reset */
- msleep(10);
+ usleep_range(10000, 20000);
/* Perform any necessary post-reset workarounds */
switch (hw->mac.type) {
@@ -1737,7 +1741,7 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
if (hw->mac.type == e1000_pch2lan) {
/* Ungate automatic PHY configuration on non-managed 82579 */
if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
- msleep(10);
+ usleep_range(10000, 20000);
e1000_gate_hw_phy_config_ich8lan(hw, false);
}
@@ -2532,7 +2536,7 @@ release:
*/
if (!ret_val) {
e1000e_reload_nvm(hw);
- msleep(10);
+ usleep_range(10000, 20000);
}
out:
@@ -3009,7 +3013,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
ew32(TCTL, E1000_TCTL_PSP);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
/* Workaround for ICH8 bit corruption issue in FIFO memory */
if (hw->mac.type == e1000_ich8lan) {
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 96921de5df2..6432ddab40c 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -868,7 +868,7 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
* milliseconds even if the other end is doing it in SW).
*/
for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
- msleep(10);
+ usleep_range(10000, 20000);
status = er32(STATUS);
if (status & E1000_STATUS_LU)
break;
@@ -930,7 +930,7 @@ s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
ew32(CTRL, ctrl);
e1e_flush();
- msleep(1);
+ usleep_range(1000, 2000);
/*
* For these adapters, the SW definable pin 1 is set when the optics
@@ -1385,7 +1385,7 @@ s32 e1000e_get_auto_rd_done(struct e1000_hw *hw)
while (i < AUTO_READ_DONE_TIMEOUT) {
if (er32(EECD) & E1000_EECD_AUTO_RD)
break;
- msleep(1);
+ usleep_range(1000, 2000);
i++;
}
@@ -1530,12 +1530,12 @@ s32 e1000e_cleanup_led_generic(struct e1000_hw *hw)
}
/**
- * e1000e_blink_led - Blink LED
+ * e1000e_blink_led_generic - Blink LED
* @hw: pointer to the HW structure
*
* Blink the LEDs which are set to be on.
**/
-s32 e1000e_blink_led(struct e1000_hw *hw)
+s32 e1000e_blink_led_generic(struct e1000_hw *hw)
{
u32 ledctl_blink = 0;
u32 i;
@@ -2087,8 +2087,6 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
if (ret_val)
return ret_val;
- msleep(10);
-
while (widx < words) {
u8 write_opcode = NVM_WRITE_OPCODE_SPI;
@@ -2132,7 +2130,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
}
}
- msleep(10);
+ usleep_range(10000, 20000);
nvm->ops.release(hw);
return 0;
}
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 506a0a0043b..0939040305f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -58,6 +58,8 @@
char e1000e_driver_name[] = "e1000e";
const char e1000e_driver_version[] = DRV_VERSION;
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
+
static const struct e1000_info *e1000_info_tbl[] = {
[board_82571] = &e1000_82571_info,
[board_82572] = &e1000_82572_info,
@@ -459,13 +461,13 @@ static void e1000_receive_skb(struct e1000_adapter *adapter,
struct net_device *netdev, struct sk_buff *skb,
u8 status, __le16 vlan)
{
+ u16 tag = le16_to_cpu(vlan);
skb->protocol = eth_type_trans(skb, netdev);
- if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_gro_receive(&adapter->napi, adapter->vlgrp,
- le16_to_cpu(vlan), skb);
- else
- napi_gro_receive(&adapter->napi, skb);
+ if (status & E1000_RXD_STAT_VP)
+ __vlan_hwaccel_put_tag(skb, tag);
+
+ napi_gro_receive(&adapter->napi, skb);
}
/**
@@ -2433,6 +2435,8 @@ static void e1000_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
vfta |= (1 << (vid & 0x1F));
hw->mac.ops.write_vfta(hw, index, vfta);
}
+
+ set_bit(vid, adapter->active_vlans);
}
static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2441,13 +2445,6 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
struct e1000_hw *hw = &adapter->hw;
u32 vfta, index;
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
-
if ((adapter->hw.mng_cookie.status &
E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
(vid == adapter->mng_vlan_id)) {
@@ -2463,93 +2460,105 @@ static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
vfta &= ~(1 << (vid & 0x1F));
hw->mac.ops.write_vfta(hw, index, vfta);
}
+
+ clear_bit(vid, adapter->active_vlans);
}
-static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
+/**
+ * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- u16 vid = adapter->hw.mng_cookie.vlan_id;
- u16 old_vid = adapter->mng_vlan_id;
-
- if (!adapter->vlgrp)
- return;
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl;
- if (!vlan_group_get_device(adapter->vlgrp, vid)) {
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- if (adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
- e1000_vlan_rx_add_vid(netdev, vid);
- adapter->mng_vlan_id = vid;
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+ /* disable VLAN receive filtering */
+ rctl = er32(RCTL);
+ rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
+ ew32(RCTL, rctl);
+
+ if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
+ e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+ adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
}
-
- if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
- (vid != old_vid) &&
- !vlan_group_get_device(adapter->vlgrp, old_vid))
- e1000_vlan_rx_kill_vid(netdev, old_vid);
- } else {
- adapter->mng_vlan_id = vid;
}
}
+/**
+ * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 rctl;
-static void e1000_vlan_rx_register(struct net_device *netdev,
- struct vlan_group *grp)
+ if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+ /* enable VLAN receive filtering */
+ rctl = er32(RCTL);
+ rctl |= E1000_RCTL_VFE;
+ rctl &= ~E1000_RCTL_CFIEN;
+ ew32(RCTL, rctl);
+ }
+}
+
+/**
+ * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
{
- struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, rctl;
+ u32 ctrl;
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_disable(adapter);
- adapter->vlgrp = grp;
+ /* disable VLAN tag insert/strip */
+ ctrl = er32(CTRL);
+ ctrl &= ~E1000_CTRL_VME;
+ ew32(CTRL, ctrl);
+}
- if (grp) {
- /* enable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl |= E1000_CTRL_VME;
- ew32(CTRL, ctrl);
+/**
+ * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
+{
+ struct e1000_hw *hw = &adapter->hw;
+ u32 ctrl;
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- /* enable VLAN receive filtering */
- rctl = er32(RCTL);
- rctl &= ~E1000_RCTL_CFIEN;
- ew32(RCTL, rctl);
- e1000_update_mng_vlan(adapter);
- }
- } else {
- /* disable VLAN tag insert/strip */
- ctrl = er32(CTRL);
- ctrl &= ~E1000_CTRL_VME;
- ew32(CTRL, ctrl);
+ /* enable VLAN tag insert/strip */
+ ctrl = er32(CTRL);
+ ctrl |= E1000_CTRL_VME;
+ ew32(CTRL, ctrl);
+}
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
- if (adapter->mng_vlan_id !=
- (u16)E1000_MNG_VLAN_NONE) {
- e1000_vlan_rx_kill_vid(netdev,
- adapter->mng_vlan_id);
- adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
- }
- }
+static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ u16 vid = adapter->hw.mng_cookie.vlan_id;
+ u16 old_vid = adapter->mng_vlan_id;
+
+ if (adapter->hw.mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
+ e1000_vlan_rx_add_vid(netdev, vid);
+ adapter->mng_vlan_id = vid;
}
- if (!test_bit(__E1000_DOWN, &adapter->state))
- e1000_irq_enable(adapter);
+ if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
+ e1000_vlan_rx_kill_vid(netdev, old_vid);
}
static void e1000_restore_vlan(struct e1000_adapter *adapter)
{
u16 vid;
- e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-
- if (!adapter->vlgrp)
- return;
+ e1000_vlan_rx_add_vid(adapter->netdev, 0);
- for (vid = 0; vid < VLAN_N_VID; vid++) {
- if (!vlan_group_get_device(adapter->vlgrp, vid))
- continue;
+ for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
e1000_vlan_rx_add_vid(adapter->netdev, vid);
- }
}
static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
@@ -2902,7 +2911,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
rctl = er32(RCTL);
ew32(RCTL, rctl & ~E1000_RCTL_EN);
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
if (adapter->flags2 & FLAG2_DMA_BURST) {
/*
@@ -3039,6 +3048,8 @@ static void e1000_set_multi(struct net_device *netdev)
if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
rctl &= ~E1000_RCTL_VFE;
+ /* Do not hardware filter VLANs in promisc mode */
+ e1000e_vlan_filter_disable(adapter);
} else {
if (netdev->flags & IFF_ALLMULTI) {
rctl |= E1000_RCTL_MPE;
@@ -3046,8 +3057,7 @@ static void e1000_set_multi(struct net_device *netdev)
} else {
rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
}
- if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
- rctl |= E1000_RCTL_VFE;
+ e1000e_vlan_filter_enable(adapter);
}
ew32(RCTL, rctl);
@@ -3072,6 +3082,11 @@ static void e1000_set_multi(struct net_device *netdev)
*/
e1000_update_mc_addr_list(hw, NULL, 0);
}
+
+ if (netdev->features & NETIF_F_HW_VLAN_RX)
+ e1000e_vlan_strip_enable(adapter);
+ else
+ e1000e_vlan_strip_disable(adapter);
}
/**
@@ -3383,7 +3398,7 @@ void e1000e_down(struct e1000_adapter *adapter)
ew32(TCTL, tctl);
/* flush both disables and wait for them to finish */
e1e_flush();
- msleep(10);
+ usleep_range(10000, 20000);
napi_disable(&adapter->napi);
e1000_irq_disable(adapter);
@@ -3418,7 +3433,7 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
{
might_sleep();
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
e1000e_down(adapter);
e1000e_up(adapter);
clear_bit(__E1000_RESETTING, &adapter->state);
@@ -3721,10 +3736,8 @@ static int e1000_close(struct net_device *netdev)
* kill manageability vlan ID if supported, but not if a vlan with
* the same ID is registered on the host OS (let 8021q kill it)
*/
- if ((adapter->hw.mng_cookie.status &
- E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
- !(adapter->vlgrp &&
- vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
+ if (adapter->hw.mng_cookie.status &
+ E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
/*
@@ -4328,7 +4341,6 @@ static void e1000_watchdog_task(struct work_struct *work)
link_up:
spin_lock(&adapter->stats64_lock);
e1000e_update_stats(adapter);
- spin_unlock(&adapter->stats64_lock);
mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
adapter->tpt_old = adapter->stats.tpt;
@@ -4339,6 +4351,7 @@ link_up:
adapter->gorc_old = adapter->stats.gorc;
adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
adapter->gotc_old = adapter->stats.gotc;
+ spin_unlock(&adapter->stats64_lock);
e1000e_update_adaptive(&adapter->hw);
@@ -5028,7 +5041,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
}
while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
adapter->max_frame_size = max_frame;
e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
@@ -5373,7 +5386,7 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
}
#endif
-void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
{
dev_info(&pdev->dev, "Disabling ASPM %s %s\n",
(state & PCIE_LINK_STATE_L0S) ? "L0s" : "",
@@ -5393,13 +5406,19 @@ static int __e1000_resume(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
u32 err;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_save_state(pdev);
- if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
e1000e_set_interrupt_capability(adapter);
if (netif_running(netdev)) {
@@ -5643,11 +5662,17 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
struct net_device *netdev = pci_get_drvdata(pdev);
struct e1000_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ u16 aspm_disable_flag = 0;
int err;
pci_ers_result_t result;
+ if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
+
err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
@@ -5714,7 +5739,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
u8 pba_str[E1000_PBANUM_LENGTH];
/* print bus type/speed/width info */
- e_info("(PCI Express:2.5GB/s:%s) %pM\n",
+ e_info("(PCI Express:2.5GT/s:%s) %pM\n",
/* bus width */
((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
"Width x1"),
@@ -5759,7 +5784,6 @@ static const struct net_device_ops e1000e_netdev_ops = {
.ndo_tx_timeout = e1000_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
- .ndo_vlan_rx_register = e1000_vlan_rx_register,
.ndo_vlan_rx_add_vid = e1000_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = e1000_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5789,12 +5813,17 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
resource_size_t flash_start, flash_len;
static int cards_found;
+ u16 aspm_disable_flag = 0;
int i, err, pci_using_dac;
u16 eeprom_data = 0;
u16 eeprom_apme_mask = E1000_EEPROM_APME;
+ if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
+ aspm_disable_flag = PCIE_LINK_STATE_L0S;
if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
- e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+ aspm_disable_flag |= PCIE_LINK_STATE_L1;
+ if (aspm_disable_flag)
+ e1000e_disable_aspm(pdev, aspm_disable_flag);
err = pci_enable_device_mem(pdev);
if (err)
@@ -5991,7 +6020,6 @@ 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;
@@ -6124,7 +6152,6 @@ 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);
if (!(netdev->flags & IFF_UP))
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 6ae31fcfb62..484774c13c2 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -2372,7 +2372,7 @@ s32 e1000e_determine_phy_address(struct e1000_hw *hw)
ret_val = 0;
goto out;
}
- msleep(1);
+ usleep_range(1000, 2000);
i++;
} while (i < 10);
}
@@ -2740,7 +2740,7 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw)
e1e_rphy(hw, PHY_CONTROL, &mii_reg);
mii_reg |= MII_CR_POWER_DOWN;
e1e_wphy(hw, PHY_CONTROL, mii_reg);
- msleep(1);
+ usleep_range(1000, 2000);
}
/**