Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/jkirsher/net...
authorDavid S. Miller <davem@davemloft.net>
Sun, 15 May 2011 05:08:23 +0000 (01:08 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 15 May 2011 05:08:23 +0000 (01:08 -0400)
13 files changed:
drivers/net/e1000e/lib.c
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_mbx.h
drivers/net/ixgbe/ixgbe_sriov.c
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ixgbevf/ixgbevf_main.c
drivers/net/ixgbevf/mbx.h
drivers/net/ixgbevf/vf.c
drivers/net/ixgbevf/vf.h

index 6432ddab40ce88912bfb03acd8e6f6a9b00ba151..dd8ab05b559086c56c677be53dd19159afed1f5a 100644 (file)
@@ -144,7 +144,7 @@ void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value)
  *  @hw: pointer to the HW structure
  *  @rar_count: receive address registers
  *
- *  Setups the receive address registers by setting the base receive address
+ *  Setup the receive address registers by setting the base receive address
  *  register to the devices MAC address and clearing all the other receive
  *  address registers to 0.
  **/
@@ -1181,7 +1181,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                         * of pause frames.  In this case, we had to advertise
                         * FULL flow control because we could not advertise Rx
                         * ONLY. Hence, we must now check to see if we need to
-                        * turn OFF  the TRANSMISSION of PAUSE frames.
+                        * turn OFF the TRANSMISSION of PAUSE frames.
                         */
                        if (hw->fc.requested_mode == e1000_fc_full) {
                                hw->fc.current_mode = e1000_fc_full;
index 37ff531d59c00fd5717644b0b24eea264ef9fe7c..e467b20ed1f00f8b4fa6d506efcf019aefe6fefd 100644 (file)
 #define IXGBE_MAX_VF_FUNCTIONS          64
 #define IXGBE_MAX_VFTA_ENTRIES          128
 #define MAX_EMULATION_MAC_ADDRS         16
+#define IXGBE_MAX_PF_MACVLANS           15
 #define VMDQ_P(p)   ((p) + adapter->num_vfs)
 
 struct vf_data_storage {
@@ -121,6 +122,15 @@ struct vf_data_storage {
        u16 tx_rate;
 };
 
+struct vf_macvlans {
+       struct list_head l;
+       int vf;
+       int rar_entry;
+       bool free;
+       bool is_macvlan;
+       u8 vf_macvlan[ETH_ALEN];
+};
+
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
 struct ixgbe_tx_buffer {
@@ -331,10 +341,52 @@ struct ixgbe_q_vector {
 
 /* board specific private data structure */
 struct ixgbe_adapter {
-       struct timer_list watchdog_timer;
+       unsigned long state;
+
+       /* Some features need tri-state capability,
+        * thus the additional *_CAPABLE flags.
+        */
+       u32 flags;
+#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
+#define IXGBE_FLAG_MSI_CAPABLE                  (u32)(1 << 1)
+#define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 2)
+#define IXGBE_FLAG_MSIX_CAPABLE                 (u32)(1 << 3)
+#define IXGBE_FLAG_MSIX_ENABLED                 (u32)(1 << 4)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 6)
+#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 7)
+#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 8)
+#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 9)
+#define IXGBE_FLAG_DCA_ENABLED                  (u32)(1 << 10)
+#define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 11)
+#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 12)
+#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 14)
+#define IXGBE_FLAG_RSS_ENABLED                  (u32)(1 << 16)
+#define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
+#define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
+#define IXGBE_FLAG_VMDQ_ENABLED                 (u32)(1 << 19)
+#define IXGBE_FLAG_FAN_FAIL_CAPABLE             (u32)(1 << 20)
+#define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 22)
+#define IXGBE_FLAG_NEED_LINK_CONFIG             (u32)(1 << 23)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 25)
+#define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 27)
+#define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 29)
+
+       u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1)
+#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE         (u32)(1 << 2)
+#define IXGBE_FLAG2_TEMP_SENSOR_EVENT           (u32)(1 << 3)
+#define IXGBE_FLAG2_SEARCH_FOR_SFP              (u32)(1 << 4)
+#define IXGBE_FLAG2_SFP_NEEDS_RESET             (u32)(1 << 5)
+#define IXGBE_FLAG2_RESET_REQUESTED             (u32)(1 << 6)
+#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT        (u32)(1 << 7)
+
        unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
        u16 bd_number;
-       struct work_struct reset_task;
        struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
 
        /* DCB parameters */
@@ -377,43 +429,6 @@ struct ixgbe_adapter {
        u32 alloc_rx_page_failed;
        u32 alloc_rx_buff_failed;
 
-       /* Some features need tri-state capability,
-        * thus the additional *_CAPABLE flags.
-        */
-       u32 flags;
-#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
-#define IXGBE_FLAG_MSI_CAPABLE                  (u32)(1 << 1)
-#define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 2)
-#define IXGBE_FLAG_MSIX_CAPABLE                 (u32)(1 << 3)
-#define IXGBE_FLAG_MSIX_ENABLED                 (u32)(1 << 4)
-#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 6)
-#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 7)
-#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 8)
-#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 9)
-#define IXGBE_FLAG_DCA_ENABLED                  (u32)(1 << 10)
-#define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 11)
-#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 12)
-#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 13)
-#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 14)
-#define IXGBE_FLAG_RSS_ENABLED                  (u32)(1 << 16)
-#define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
-#define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
-#define IXGBE_FLAG_VMDQ_ENABLED                 (u32)(1 << 19)
-#define IXGBE_FLAG_FAN_FAIL_CAPABLE             (u32)(1 << 20)
-#define IXGBE_FLAG_NEED_LINK_UPDATE             (u32)(1 << 22)
-#define IXGBE_FLAG_IN_SFP_LINK_TASK             (u32)(1 << 23)
-#define IXGBE_FLAG_IN_SFP_MOD_TASK              (u32)(1 << 24)
-#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 25)
-#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 26)
-#define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 27)
-#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 28)
-#define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 29)
-#define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 30)
-
-       u32 flags2;
-#define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1)
-#define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1)
-#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE         (u32)(1 << 2)
 /* default to trying for four seconds */
 #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
 
@@ -434,7 +449,6 @@ struct ixgbe_adapter {
        u32 rx_eitr_param;
        u32 tx_eitr_param;
 
-       unsigned long state;
        u64 tx_busy;
        unsigned int tx_ring_count;
        unsigned int rx_ring_count;
@@ -443,15 +457,12 @@ struct ixgbe_adapter {
        bool link_up;
        unsigned long link_check_timeout;
 
-       struct work_struct watchdog_task;
-       struct work_struct sfp_task;
-       struct timer_list sfp_timer;
-       struct work_struct multispeed_fiber_task;
-       struct work_struct sfp_config_module_task;
+       struct work_struct service_task;
+       struct timer_list service_timer;
        u32 fdir_pballoc;
        u32 atr_sample_rate;
+       unsigned long fdir_overflow; /* number of times ATR was backed off */
        spinlock_t fdir_perfect_lock;
-       struct work_struct fdir_reinit_task;
 #ifdef IXGBE_FCOE
        struct ixgbe_fcoe fcoe;
 #endif /* IXGBE_FCOE */
@@ -462,7 +473,6 @@ struct ixgbe_adapter {
 
        int node;
        u32 led_reg;
-       struct work_struct check_overtemp_task;
        u32 interrupt_event;
        char lsc_int_name[IFNAMSIZ + 9];
 
@@ -471,13 +481,17 @@ struct ixgbe_adapter {
        unsigned int num_vfs;
        struct vf_data_storage *vfinfo;
        int vf_rate_link_speed;
+       struct vf_macvlans vf_mvs;
+       struct vf_macvlans *mv_list;
+       bool antispoofing_enabled;
 };
 
 enum ixbge_state_t {
        __IXGBE_TESTING,
        __IXGBE_RESETTING,
        __IXGBE_DOWN,
-       __IXGBE_SFP_MODULE_NOT_FOUND
+       __IXGBE_SERVICE_SCHED,
+       __IXGBE_IN_SFP_INIT,
 };
 
 struct ixgbe_rsc_cb {
index dba5ca6e35c48caeee516e12d3d0a4e8aeed8389..8ee661245af39a055bad37177961807fdfe822ad 100644 (file)
@@ -368,6 +368,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82599_T3_LOM:
                media_type = ixgbe_media_type_copper;
                break;
+       case IXGBE_DEV_ID_82599_LS:
+               media_type = ixgbe_media_type_fiber_lco;
+               break;
        default:
                media_type = ixgbe_media_type_unknown;
                break;
index c4730cd39b22434a3165ad09bf61c1cd03f41f02..b894b42a741caf3fe315e5a64ced94f009d9e581 100644 (file)
@@ -1189,6 +1189,28 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
                udelay(50);
        }
 
+       if (i == timeout) {
+               hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
+                      "not granted.\n");
+               /*
+                * this release is particularly important because our attempts
+                * above to get the semaphore may have succeeded, and if there
+                * was a timeout, we should unconditionally clear the semaphore
+                * bits to free the driver to make progress
+                */
+               ixgbe_release_eeprom_semaphore(hw);
+
+               udelay(50);
+               /*
+                * one last try
+                * If the SMBI bit is 0 when we read it, then the bit will be
+                * set and we have the semaphore
+                */
+               swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+               if (!(swsm & IXGBE_SWSM_SMBI))
+                       status = 0;
+       }
+
        /* Now get the semaphore between SW/FW through the SWESMBI bit */
        if (status == 0) {
                for (i = 0; i < timeout; i++) {
index 1fdd075afe799b37b451917af5197212a6ff1e76..cb1555bc85480d8bd934a2680b24f2fb08be6f54 100644 (file)
@@ -84,6 +84,7 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
        {"fdir_match", IXGBE_STAT(stats.fdirmatch)},
        {"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
+       {"fdir_overflow", IXGBE_STAT(fdir_overflow)},
        {"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)},
        {"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)},
        {"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
index a3e384bc50fe006aac1f986ac64561a3b1ea8a48..2dce3d0381881887d3adafed71c50bdb8e34bdc6 100644 (file)
@@ -126,6 +126,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
         board_X540 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2),
         board_82599 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS),
+        board_82599 },
 
        /* required last entry */
        {0, }
@@ -191,6 +193,22 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter)
        adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
 }
 
+static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
+{
+       if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+           !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
+               schedule_work(&adapter->service_task);
+}
+
+static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
+{
+       BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
+
+       /* flush memory to make sure state is correct before next watchog */
+       smp_mb__before_clear_bit();
+       clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+}
+
 struct ixgbe_reg_info {
        u32 ofs;
        char *name;
@@ -817,7 +835,19 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_ring *tx_ring)
 #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
        MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
 
-static void ixgbe_tx_timeout(struct net_device *netdev);
+/**
+ * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout
+ * @adapter: driver private struct
+ **/
+static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
+{
+
+       /* Do the reset outside of interrupt context */
+       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+               adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+               ixgbe_service_event_schedule(adapter);
+       }
+}
 
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
@@ -899,7 +929,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
                        adapter->tx_timeout_count + 1, tx_ring->queue_index);
 
                /* schedule immediate reset if we believe we hung */
-               ixgbe_tx_timeout(adapter->netdev);
+               ixgbe_tx_timeout_reset(adapter);
 
                /* the adapter is about to reset, no point in enabling stuff */
                return true;
@@ -1797,35 +1827,51 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
 }
 
 /**
- * ixgbe_check_overtemp_task - worker thread to check over tempurature
- * @work: pointer to work_struct containing our data
+ * ixgbe_check_overtemp_subtask - check for over tempurature
+ * @adapter: pointer to adapter
  **/
-static void ixgbe_check_overtemp_task(struct work_struct *work)
+static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    check_overtemp_task);
        struct ixgbe_hw *hw = &adapter->hw;
        u32 eicr = adapter->interrupt_event;
 
-       if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE))
+       if (test_bit(__IXGBE_DOWN, &adapter->state))
+               return;
+
+       if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+           !(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_EVENT))
                return;
 
+       adapter->flags2 &= ~IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+
        switch (hw->device_id) {
-       case IXGBE_DEV_ID_82599_T3_LOM: {
-               u32 autoneg;
-               bool link_up = false;
+       case IXGBE_DEV_ID_82599_T3_LOM:
+               /*
+                * Since the warning interrupt is for both ports
+                * we don't have to check if:
+                *  - This interrupt wasn't for our port.
+                *  - We may have missed the interrupt so always have to
+                *    check if we  got a LSC
+                */
+               if (!(eicr & IXGBE_EICR_GPI_SDP0) &&
+                   !(eicr & IXGBE_EICR_LSC))
+                       return;
+
+               if (!(eicr & IXGBE_EICR_LSC) && hw->mac.ops.check_link) {
+                       u32 autoneg;
+                       bool link_up = false;
 
-               if (hw->mac.ops.check_link)
                        hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
 
-               if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
-                   (eicr & IXGBE_EICR_LSC))
-                       /* Check if this is due to overtemp */
-                       if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
-                               break;
-               return;
-       }
+                       if (link_up)
+                               return;
+               }
+
+               /* Check if this is not due to overtemp */
+               if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP)
+                       return;
+
+               break;
        default:
                if (!(eicr & IXGBE_EICR_GPI_SDP0))
                        return;
@@ -1835,8 +1881,8 @@ static void ixgbe_check_overtemp_task(struct work_struct *work)
               "Network adapter has been stopped because it has over heated. "
               "Restart the computer. If the problem persists, "
               "power off the system and replace the adapter\n");
-       /* write to clear the interrupt */
-       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+
+       adapter->interrupt_event = 0;
 }
 
 static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
@@ -1858,15 +1904,19 @@ static void ixgbe_check_sfp_event(struct ixgbe_adapter *adapter, u32 eicr)
        if (eicr & IXGBE_EICR_GPI_SDP2) {
                /* Clear the interrupt */
                IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
-               if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       schedule_work(&adapter->sfp_config_module_task);
+               if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+                       adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+                       ixgbe_service_event_schedule(adapter);
+               }
        }
 
        if (eicr & IXGBE_EICR_GPI_SDP1) {
                /* Clear the interrupt */
                IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
-               if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       schedule_work(&adapter->multispeed_fiber_task);
+               if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+                       adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+                       ixgbe_service_event_schedule(adapter);
+               }
        }
 }
 
@@ -1880,7 +1930,7 @@ static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
        if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
                IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
                IXGBE_WRITE_FLUSH(hw);
-               schedule_work(&adapter->watchdog_task);
+               ixgbe_service_event_schedule(adapter);
        }
 }
 
@@ -1908,26 +1958,32 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
 
        switch (hw->mac.type) {
        case ixgbe_mac_82599EB:
-               ixgbe_check_sfp_event(adapter, eicr);
-               if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
-                   ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
-                       adapter->interrupt_event = eicr;
-                       schedule_work(&adapter->check_overtemp_task);
-               }
-               /* now fallthrough to handle Flow Director */
        case ixgbe_mac_X540:
                /* Handle Flow Director Full threshold interrupt */
                if (eicr & IXGBE_EICR_FLOW_DIR) {
+                       int reinit_count = 0;
                        int i;
-                       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
-                       /* Disable transmits before FDIR Re-initialization */
-                       netif_tx_stop_all_queues(netdev);
                        for (i = 0; i < adapter->num_tx_queues; i++) {
-                               struct ixgbe_ring *tx_ring =
-                                                           adapter->tx_ring[i];
+                               struct ixgbe_ring *ring = adapter->tx_ring[i];
                                if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
-                                                      &tx_ring->state))
-                                       schedule_work(&adapter->fdir_reinit_task);
+                                                      &ring->state))
+                                       reinit_count++;
+                       }
+                       if (reinit_count) {
+                               /* no more flow director interrupts until after init */
+                               IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
+                               eicr &= ~IXGBE_EICR_FLOW_DIR;
+                               adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
+                               ixgbe_service_event_schedule(adapter);
+                       }
+               }
+               ixgbe_check_sfp_event(adapter, eicr);
+               if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+                   ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+                       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+                               adapter->interrupt_event = eicr;
+                               adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+                               ixgbe_service_event_schedule(adapter);
                        }
                }
                break;
@@ -1937,8 +1993,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
 
        ixgbe_check_fan_failure(adapter, eicr);
 
+       /* re-enable the original interrupt state, no lsc, no queues */
        if (!test_bit(__IXGBE_DOWN, &adapter->state))
-               IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
+               IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr &
+                               ~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE));
 
        return IRQ_HANDLED;
 }
@@ -2523,8 +2581,11 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
                ixgbe_check_sfp_event(adapter, eicr);
                if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
                    ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
-                       adapter->interrupt_event = eicr;
-                       schedule_work(&adapter->check_overtemp_task);
+                       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+                               adapter->interrupt_event = eicr;
+                               adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+                               ixgbe_service_event_schedule(adapter);
+                       }
                }
                break;
        default:
@@ -3188,7 +3249,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
        /* enable Tx loopback for VF/PF communication */
        IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
        /* Enable MAC Anti-Spoofing */
-       hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
+       hw->mac.ops.set_mac_anti_spoofing(hw,
+                                         (adapter->antispoofing_enabled =
+                                          (adapter->num_vfs != 0)),
                                          adapter->num_vfs);
 }
 
@@ -3497,7 +3560,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
        unsigned int vfn = adapter->num_vfs;
-       unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1);
+       unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
        int count = 0;
 
        /* return ENOMEM indicating insufficient memory for addresses */
@@ -3770,31 +3833,16 @@ static inline bool ixgbe_is_sfp(struct ixgbe_hw *hw)
  **/
 static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_hw *hw = &adapter->hw;
+       /*
+        * We are assuming the worst case scenerio here, and that
+        * is that an SFP was inserted/removed after the reset
+        * but before SFP detection was enabled.  As such the best
+        * solution is to just start searching as soon as we start
+        */
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+               adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-               if (hw->phy.multispeed_fiber) {
-                       /*
-                        * In multispeed fiber setups, the device may not have
-                        * had a physical connection when the driver loaded.
-                        * If that's the case, the initial link configuration
-                        * couldn't get the MAC into 10G or 1G mode, so we'll
-                        * never have a link status change interrupt fire.
-                        * We need to try and force an autonegotiation
-                        * session, then bring up link.
-                        */
-                       if (hw->mac.ops.setup_sfp)
-                               hw->mac.ops.setup_sfp(hw);
-                       if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
-                               schedule_work(&adapter->multispeed_fiber_task);
-               } else {
-                       /*
-                        * Direct Attach Cu and non-multispeed fiber modules
-                        * still need to be configured properly prior to
-                        * attempting link.
-                        */
-                       if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
-                               schedule_work(&adapter->sfp_config_module_task);
-               }
+       adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
 }
 
 /**
@@ -3924,17 +3972,6 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
                        e_crit(drv, "Fan has stopped, replace the adapter\n");
        }
 
-       /*
-        * For hot-pluggable SFP+ devices, a new SFP+ module may have
-        * arrived before interrupts were enabled but after probe.  Such
-        * devices wouldn't have their type identified yet. We need to
-        * kick off the SFP+ module setup first, then try to bring up link.
-        * If we're not hot-pluggable SFP+, we just need to configure link
-        * and bring it up.
-        */
-       if (hw->phy.type == ixgbe_phy_none)
-               schedule_work(&adapter->sfp_config_module_task);
-
        /* enable transmits */
        netif_tx_start_all_queues(adapter->netdev);
 
@@ -3942,7 +3979,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
         * link up interrupt but shouldn't be a problem */
        adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
        adapter->link_check_timeout = jiffies;
-       mod_timer(&adapter->watchdog_timer, jiffies);
+       mod_timer(&adapter->service_timer, jiffies);
 
        /* Set PF Reset Done bit so PF/VF Mail Ops can work */
        ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -3955,6 +3992,9 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
 {
        WARN_ON(in_interrupt());
+       /* put off any impending NetWatchDogTimeout */
+       adapter->netdev->trans_start = jiffies;
+
        while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
                usleep_range(1000, 2000);
        ixgbe_down(adapter);
@@ -3983,10 +4023,20 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
        struct ixgbe_hw *hw = &adapter->hw;
        int err;
 
+       /* lock SFP init bit to prevent race conditions with the watchdog */
+       while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+               usleep_range(1000, 2000);
+
+       /* clear all SFP and link config related flags while holding SFP_INIT */
+       adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
+                            IXGBE_FLAG2_SFP_NEEDS_RESET);
+       adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
        err = hw->mac.ops.init_hw(hw);
        switch (err) {
        case 0:
        case IXGBE_ERR_SFP_NOT_PRESENT:
+       case IXGBE_ERR_SFP_NOT_SUPPORTED:
                break;
        case IXGBE_ERR_MASTER_REQUESTS_PENDING:
                e_dev_err("master disable timed out\n");
@@ -4004,6 +4054,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
                e_dev_err("Hardware Error: %d\n", err);
        }
 
+       clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
        /* reprogram the RAR[0] in case user changed it. */
        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
                            IXGBE_RAH_AV);
@@ -4132,26 +4184,12 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
        u32 rxctrl;
-       u32 txdctl;
        int i;
        int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
        /* signal that we are down to the interrupt handler */
        set_bit(__IXGBE_DOWN, &adapter->state);
 
-       /* disable receive for all VFs and wait one second */
-       if (adapter->num_vfs) {
-               /* ping all the active vfs to let them know we are going down */
-               ixgbe_ping_all_vfs(adapter);
-
-               /* Disable all VFTE/VFRE TX/RX */
-               ixgbe_disable_tx_rx(adapter);
-
-               /* Mark all the VFs as inactive */
-               for (i = 0 ; i < adapter->num_vfs; i++)
-                       adapter->vfinfo[i].clear_to_send = 0;
-       }
-
        /* disable receives */
        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
        IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
@@ -4165,11 +4203,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 
        netif_tx_stop_all_queues(netdev);
 
-       clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-       del_timer_sync(&adapter->sfp_timer);
-       del_timer_sync(&adapter->watchdog_timer);
-       cancel_work_sync(&adapter->watchdog_task);
-
+       /* call carrier off first to avoid false dev_watchdog timeouts */
        netif_carrier_off(netdev);
        netif_tx_disable(netdev);
 
@@ -4177,6 +4211,25 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 
        ixgbe_napi_disable_all(adapter);
 
+       adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
+                            IXGBE_FLAG2_RESET_REQUESTED);
+       adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+
+       del_timer_sync(&adapter->service_timer);
+
+       /* disable receive for all VFs and wait one second */
+       if (adapter->num_vfs) {
+               /* ping all the active vfs to let them know we are going down */
+               ixgbe_ping_all_vfs(adapter);
+
+               /* Disable all VFTE/VFRE TX/RX */
+               ixgbe_disable_tx_rx(adapter);
+
+               /* Mark all the VFs as inactive */
+               for (i = 0 ; i < adapter->num_vfs; i++)
+                       adapter->vfinfo[i].clear_to_send = 0;
+       }
+
        /* Cleanup the affinity_hint CPU mask memory and callback */
        for (i = 0; i < num_q_vectors; i++) {
                struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -4186,21 +4239,13 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
                free_cpumask_var(q_vector->affinity_mask);
        }
 
-       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-               cancel_work_sync(&adapter->fdir_reinit_task);
-
-       if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-               cancel_work_sync(&adapter->check_overtemp_task);
-
        /* disable transmits in the hardware now that interrupts are off */
        for (i = 0; i < adapter->num_tx_queues; i++) {
                u8 reg_idx = adapter->tx_ring[i]->reg_idx;
-               txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
-               IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
-                               (txdctl & ~IXGBE_TXDCTL_ENABLE));
+               IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
        }
-       /* Disable the Tx DMA engine on 82599 */
+
+       /* Disable the Tx DMA engine on 82599 and X540 */
        switch (hw->mac.type) {
        case ixgbe_mac_82599EB:
        case ixgbe_mac_X540:
@@ -4275,25 +4320,8 @@ static void ixgbe_tx_timeout(struct net_device *netdev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-       adapter->tx_timeout_count++;
-
        /* Do the reset outside of interrupt context */
-       schedule_work(&adapter->reset_task);
-}
-
-static void ixgbe_reset_task(struct work_struct *work)
-{
-       struct ixgbe_adapter *adapter;
-       adapter = container_of(work, struct ixgbe_adapter, reset_task);
-
-       /* If we're already down or resetting, just bail */
-       if (test_bit(__IXGBE_DOWN, &adapter->state) ||
-           test_bit(__IXGBE_RESETTING, &adapter->state))
-               return;
-
-       ixgbe_dump(adapter);
-       netdev_err(adapter->netdev, "Reset adapter\n");
-       ixgbe_reinit_locked(adapter);
+       ixgbe_tx_timeout_reset(adapter);
 }
 
 /**
@@ -5145,57 +5173,6 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
        ixgbe_reset_interrupt_capability(adapter);
 }
 
-/**
- * ixgbe_sfp_timer - worker thread to find a missing module
- * @data: pointer to our adapter struct
- **/
-static void ixgbe_sfp_timer(unsigned long data)
-{
-       struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
-
-       /*
-        * Do the sfp_timer outside of interrupt context due to the
-        * delays that sfp+ detection requires
-        */
-       schedule_work(&adapter->sfp_task);
-}
-
-/**
- * ixgbe_sfp_task - worker thread to find a missing module
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_sfp_task(struct work_struct *work)
-{
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    sfp_task);
-       struct ixgbe_hw *hw = &adapter->hw;
-
-       if ((hw->phy.type == ixgbe_phy_nl) &&
-           (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
-               s32 ret = hw->phy.ops.identify_sfp(hw);
-               if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
-                       goto reschedule;
-               ret = hw->phy.ops.reset(hw);
-               if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-                       e_dev_err("failed to initialize because an unsupported "
-                                 "SFP+ module type was detected.\n");
-                       e_dev_err("Reload the driver after installing a "
-                                 "supported module.\n");
-                       unregister_netdev(adapter->netdev);
-               } else {
-                       e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
-               }
-               /* don't need this routine any more */
-               clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-       }
-       return;
-reschedule:
-       if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
-               mod_timer(&adapter->sfp_timer,
-                         round_jiffies(jiffies + (2 * HZ)));
-}
-
 /**
  * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
  * @adapter: board private structure to initialize
@@ -5992,23 +5969,66 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 }
 
 /**
- * ixgbe_watchdog - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
+ * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table
+ * @adapter - pointer to the device adapter structure
  **/
-static void ixgbe_watchdog(unsigned long data)
+static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
        struct ixgbe_hw *hw = &adapter->hw;
-       u64 eics = 0;
        int i;
 
-       /*
-        *  Do the watchdog outside of interrupt context due to the lovely
-        * delays that some of the newer hardware requires
-        */
+       if (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
+               return;
+
+       adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
 
+       /* if interface is down do nothing */
        if (test_bit(__IXGBE_DOWN, &adapter->state))
-               goto watchdog_short_circuit;
+               return;
+
+       /* do nothing if we are not using signature filters */
+       if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE))
+               return;
+
+       adapter->fdir_overflow++;
+
+       if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       set_bit(__IXGBE_TX_FDIR_INIT_DONE,
+                               &(adapter->tx_ring[i]->state));
+               /* re-enable flow director interrupts */
+               IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR);
+       } else {
+               e_err(probe, "failed to finish FDIR re-initialization, "
+                     "ignored adding FDIR ATR filters\n");
+       }
+}
+
+/**
+ * ixgbe_check_hang_subtask - check for hung queues and dropped interrupts
+ * @adapter - pointer to the device adapter structure
+ *
+ * This function serves two purposes.  First it strobes the interrupt lines
+ * in order to make certain interrupts are occuring.  Secondly it sets the
+ * bits needed to check for TX hangs.  As a result we should immediately
+ * determine if a hang has occured.
+ */
+static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       u64 eics = 0;
+       int i;
+
+       /* If we're down or resetting, just bail */
+       if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+           test_bit(__IXGBE_RESETTING, &adapter->state))
+               return;
+
+       /* Force detection of hung controller */
+       if (netif_carrier_ok(adapter->netdev)) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       set_check_for_tx_hang(adapter->tx_ring[i]);
+       }
 
        if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
                /*
@@ -6018,108 +6038,172 @@ static void ixgbe_watchdog(unsigned long data)
                 */
                IXGBE_WRITE_REG(hw, IXGBE_EICS,
                        (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
-               goto watchdog_reschedule;
-       }
-
-       /* get one bit for every active tx/rx interrupt vector */
-       for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
-               struct ixgbe_q_vector *qv = adapter->q_vector[i];
-               if (qv->rxr_count || qv->txr_count)
-                       eics |= ((u64)1 << i);
+       } else {
+               /* get one bit for every active tx/rx interrupt vector */
+               for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+                       struct ixgbe_q_vector *qv = adapter->q_vector[i];
+                       if (qv->rxr_count || qv->txr_count)
+                               eics |= ((u64)1 << i);
+               }
        }
 
-       /* Cause software interrupt to ensure rx rings are cleaned */
+       /* Cause software interrupt to ensure rings are cleaned */
        ixgbe_irq_rearm_queues(adapter, eics);
 
-watchdog_reschedule:
-       /* Reset the timer */
-       mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
-
-watchdog_short_circuit:
-       schedule_work(&adapter->watchdog_task);
 }
 
 /**
- * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_update_link - update the link status
+ * @adapter - pointer to the device adapter structure
+ * @link_speed - pointer to a u32 to store the link_speed
  **/
-static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    multispeed_fiber_task);
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 autoneg;
-       bool negotiation;
+       u32 link_speed = adapter->link_speed;
+       bool link_up = adapter->link_up;
+       int i;
 
-       adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_TASK;
-       autoneg = hw->phy.autoneg_advertised;
-       if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
-               hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
-       hw->mac.autotry_restart = false;
-       if (hw->mac.ops.setup_link)
-               hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
-       adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
-       adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+       if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE))
+               return;
+
+       if (hw->mac.ops.check_link) {
+               hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+       } else {
+               /* always assume link is up, if no check link function */
+               link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+               link_up = true;
+       }
+       if (link_up) {
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+                       for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+                               hw->mac.ops.fc_enable(hw, i);
+               } else {
+                       hw->mac.ops.fc_enable(hw, 0);
+               }
+       }
+
+       if (link_up ||
+           time_after(jiffies, (adapter->link_check_timeout +
+                                IXGBE_TRY_LINK_TIMEOUT))) {
+               adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+               IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+               IXGBE_WRITE_FLUSH(hw);
+       }
+
+       adapter->link_up = link_up;
+       adapter->link_speed = link_speed;
 }
 
 /**
- * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_up - update netif_carrier status and
+ *                             print link up message
+ * @adapter - pointer to the device adapter structure
  **/
-static void ixgbe_sfp_config_module_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    sfp_config_module_task);
+       struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 err;
+       u32 link_speed = adapter->link_speed;
+       bool flow_rx, flow_tx;
 
-       adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+       /* only continue if link was previously down */
+       if (netif_carrier_ok(netdev))
+               return;
 
-       /* Time for electrical oscillations to settle down */
-       msleep(100);
-       err = hw->phy.ops.identify_sfp(hw);
+       adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-       if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-               e_dev_err("failed to initialize because an unsupported SFP+ "
-                         "module type was detected.\n");
-               e_dev_err("Reload the driver after installing a supported "
-                         "module.\n");
-               unregister_netdev(adapter->netdev);
-               return;
+       switch (hw->mac.type) {
+       case ixgbe_mac_82598EB: {
+               u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+               u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+               flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
+               flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
        }
-       if (hw->mac.ops.setup_sfp)
-               hw->mac.ops.setup_sfp(hw);
+               break;
+       case ixgbe_mac_X540:
+       case ixgbe_mac_82599EB: {
+               u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+               u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+               flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
+               flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
+       }
+               break;
+       default:
+               flow_tx = false;
+               flow_rx = false;
+               break;
+       }
+       e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
+              (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+              "10 Gbps" :
+              (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+              "1 Gbps" :
+              (link_speed == IXGBE_LINK_SPEED_100_FULL ?
+              "100 Mbps" :
+              "unknown speed"))),
+              ((flow_rx && flow_tx) ? "RX/TX" :
+              (flow_rx ? "RX" :
+              (flow_tx ? "TX" : "None"))));
 
-       if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
-               /* This will also work for DA Twinax connections */
-               schedule_work(&adapter->multispeed_fiber_task);
-       adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+       netif_carrier_on(netdev);
+#ifdef HAVE_IPLINK_VF_CONFIG
+       ixgbe_check_vf_rate_limit(adapter);
+#endif /* HAVE_IPLINK_VF_CONFIG */
 }
 
 /**
- * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_down - update netif_carrier status and
+ *                               print link down message
+ * @adapter - pointer to the adapter structure
  **/
-static void ixgbe_fdir_reinit_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter* adapter)
 {
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    fdir_reinit_task);
+       struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
+
+       adapter->link_up = false;
+       adapter->link_speed = 0;
+
+       /* only continue if link was up previously */
+       if (!netif_carrier_ok(netdev))
+               return;
+
+       /* poll for SFP+ cable when link is down */
+       if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
+               adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
+
+       e_info(drv, "NIC Link is Down\n");
+       netif_carrier_off(netdev);
+}
+
+/**
+ * ixgbe_watchdog_flush_tx - flush queues on link down
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
+{
        int i;
+       int some_tx_pending = 0;
 
-       if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
-               for (i = 0; i < adapter->num_tx_queues; i++)
-                       set_bit(__IXGBE_TX_FDIR_INIT_DONE,
-                               &(adapter->tx_ring[i]->state));
-       } else {
-               e_err(probe, "failed to finish FDIR re-initialization, "
-                     "ignored adding FDIR ATR filters\n");
+       if (!netif_carrier_ok(adapter->netdev)) {
+               for (i = 0; i < adapter->num_tx_queues; i++) {
+                       struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+                       if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+                               some_tx_pending = 1;
+                               break;
+                       }
+               }
+
+               if (some_tx_pending) {
+                       /* We've lost link, so the controller stops DMA,
+                        * but we've got queued Tx work that's never going
+                        * to get done, so reset controller to flush Tx.
+                        * (Do the reset outside of interrupt context).
+                        */
+                       adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+               }
        }
-       /* Done FDIR Re-initialization, enable transmits */
-       netif_tx_start_all_queues(adapter->netdev);
 }
 
 static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
@@ -6142,133 +6226,186 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
        e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
 }
 
-static DEFINE_MUTEX(ixgbe_watchdog_lock);
+/**
+ * ixgbe_watchdog_subtask - check and bring link up
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
+{
+       /* if interface is down do nothing */
+       if (test_bit(__IXGBE_DOWN, &adapter->state))
+               return;
+
+       ixgbe_watchdog_update_link(adapter);
+
+       if (adapter->link_up)
+               ixgbe_watchdog_link_is_up(adapter);
+       else
+               ixgbe_watchdog_link_is_down(adapter);
+
+       ixgbe_spoof_check(adapter);
+       ixgbe_update_stats(adapter);
+
+       ixgbe_watchdog_flush_tx(adapter);
+}
 
 /**
- * ixgbe_watchdog_task - worker thread to bring link up
- * @work: pointer to work_struct containing our data
+ * ixgbe_sfp_detection_subtask - poll for SFP+ cable
+ * @adapter - the ixgbe adapter structure
  **/
-static void ixgbe_watchdog_task(struct work_struct *work)
+static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_adapter *adapter = container_of(work,
-                                                    struct ixgbe_adapter,
-                                                    watchdog_task);
-       struct net_device *netdev = adapter->netdev;
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 link_speed;
-       bool link_up;
-       int i;
-       struct ixgbe_ring *tx_ring;
-       int some_tx_pending = 0;
+       s32 err;
 
-       mutex_lock(&ixgbe_watchdog_lock);
+       /* not searching for SFP so there is nothing to do here */
+       if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
+           !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+               return;
 
-       link_up = adapter->link_up;
-       link_speed = adapter->link_speed;
+       /* someone else is in init, wait until next service event */
+       if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+               return;
 
-       if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
-               hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
-               if (link_up) {
-#ifdef CONFIG_DCB
-                       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                               for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
-                                       hw->mac.ops.fc_enable(hw, i);
-                       } else {
-                               hw->mac.ops.fc_enable(hw, 0);
-                       }
-#else
-                       hw->mac.ops.fc_enable(hw, 0);
-#endif
-               }
+       err = hw->phy.ops.identify_sfp(hw);
+       if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               goto sfp_out;
 
-               if (link_up ||
-                   time_after(jiffies, (adapter->link_check_timeout +
-                                        IXGBE_TRY_LINK_TIMEOUT))) {
-                       adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
-                       IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
-               }
-               adapter->link_up = link_up;
-               adapter->link_speed = link_speed;
+       if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
+               /* If no cable is present, then we need to reset
+                * the next time we find a good cable. */
+               adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
        }
 
-       if (link_up) {
-               if (!netif_carrier_ok(netdev)) {
-                       bool flow_rx, flow_tx;
-
-                       switch (hw->mac.type) {
-                       case ixgbe_mac_82598EB: {
-                               u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-                               u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-                               flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
-                               flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
-                       }
-                               break;
-                       case ixgbe_mac_82599EB:
-                       case ixgbe_mac_X540: {
-                               u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
-                               u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
-                               flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
-                               flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
-                       }
-                               break;
-                       default:
-                               flow_tx = false;
-                               flow_rx = false;
-                               break;
-                       }
+       /* exit on error */
+       if (err)
+               goto sfp_out;
 
-                       e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
-                              (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
-                              "10 Gbps" :
-                              (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
-                              "1 Gbps" :
-                              (link_speed == IXGBE_LINK_SPEED_100_FULL ?
-                              "100 Mbps" :
-                              "unknown speed"))),
-                              ((flow_rx && flow_tx) ? "RX/TX" :
-                              (flow_rx ? "RX" :
-                              (flow_tx ? "TX" : "None"))));
-
-                       netif_carrier_on(netdev);
-                       ixgbe_check_vf_rate_limit(adapter);
-               } else {
-                       /* Force detection of hung controller */
-                       for (i = 0; i < adapter->num_tx_queues; i++) {
-                               tx_ring = adapter->tx_ring[i];
-                               set_check_for_tx_hang(tx_ring);
-                       }
-               }
-       } else {
-               adapter->link_up = false;
-               adapter->link_speed = 0;
-               if (netif_carrier_ok(netdev)) {
-                       e_info(drv, "NIC Link is Down\n");
-                       netif_carrier_off(netdev);
-               }
-       }
+       /* exit if reset not needed */
+       if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+               goto sfp_out;
 
-       if (!netif_carrier_ok(netdev)) {
-               for (i = 0; i < adapter->num_tx_queues; i++) {
-                       tx_ring = adapter->tx_ring[i];
-                       if (tx_ring->next_to_use != tx_ring->next_to_clean) {
-                               some_tx_pending = 1;
-                               break;
-                       }
-               }
+       adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET;
 
-               if (some_tx_pending) {
-                       /* We've lost link, so the controller stops DMA,
-                        * but we've got queued Tx work that's never going
-                        * to get done, so reset controller to flush Tx.
-                        * (Do the reset outside of interrupt context).
-                        */
-                        schedule_work(&adapter->reset_task);
-               }
+       /*
+        * A module may be identified correctly, but the EEPROM may not have
+        * support for that module.  setup_sfp() will fail in that case, so
+        * we should not allow that module to load.
+        */
+       if (hw->mac.type == ixgbe_mac_82598EB)
+               err = hw->phy.ops.reset(hw);
+       else
+               err = hw->mac.ops.setup_sfp(hw);
+
+       if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               goto sfp_out;
+
+       adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+       e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
+
+sfp_out:
+       clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
+       if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) &&
+           (adapter->netdev->reg_state == NETREG_REGISTERED)) {
+               e_dev_err("failed to initialize because an unsupported "
+                         "SFP+ module type was detected.\n");
+               e_dev_err("Reload the driver after installing a "
+                         "supported module.\n");
+               unregister_netdev(adapter->netdev);
        }
+}
 
-       ixgbe_spoof_check(adapter);
-       ixgbe_update_stats(adapter);
-       mutex_unlock(&ixgbe_watchdog_lock);
+/**
+ * ixgbe_sfp_link_config_subtask - set up link SFP after module install
+ * @adapter - the ixgbe adapter structure
+ **/
+static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 autoneg;
+       bool negotiation;
+
+       if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG))
+               return;
+
+       /* someone else is in init, wait until next service event */
+       if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+               return;
+
+       adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
+       autoneg = hw->phy.autoneg_advertised;
+       if ((!autoneg) && (hw->mac.ops.get_link_capabilities))
+               hw->mac.ops.get_link_capabilities(hw, &autoneg, &negotiation);
+       hw->mac.autotry_restart = false;
+       if (hw->mac.ops.setup_link)
+               hw->mac.ops.setup_link(hw, autoneg, negotiation, true);
+
+       adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+       adapter->link_check_timeout = jiffies;
+       clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+}
+
+/**
+ * ixgbe_service_timer - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void ixgbe_service_timer(unsigned long data)
+{
+       struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
+       unsigned long next_event_offset;
+
+       /* poll faster when waiting for link */
+       if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)
+               next_event_offset = HZ / 10;
+       else
+               next_event_offset = HZ * 2;
+
+       /* Reset the timer */
+       mod_timer(&adapter->service_timer, next_event_offset + jiffies);
+
+       ixgbe_service_event_schedule(adapter);
+}
+
+static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
+{
+       if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED))
+               return;
+
+       adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
+
+       /* If we're already down or resetting, just bail */
+       if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+           test_bit(__IXGBE_RESETTING, &adapter->state))
+               return;
+
+       ixgbe_dump(adapter);
+       netdev_err(adapter->netdev, "Reset adapter\n");
+       adapter->tx_timeout_count++;
+
+       ixgbe_reinit_locked(adapter);
+}
+
+/**
+ * ixgbe_service_task - manages and runs subtasks
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_service_task(struct work_struct *work)
+{
+       struct ixgbe_adapter *adapter = container_of(work,
+                                                    struct ixgbe_adapter,
+                                                    service_task);
+
+       ixgbe_reset_subtask(adapter);
+       ixgbe_sfp_detection_subtask(adapter);
+       ixgbe_sfp_link_config_subtask(adapter);
+       ixgbe_check_overtemp_subtask(adapter);
+       ixgbe_watchdog_subtask(adapter);
+       ixgbe_fdir_reinit_subtask(adapter);
+       ixgbe_check_hang_subtask(adapter);
+
+       ixgbe_service_event_complete(adapter);
 }
 
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
@@ -7107,6 +7244,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
 #ifdef CONFIG_PCI_IOV
        struct ixgbe_hw *hw = &adapter->hw;
        int err;
+       int num_vf_macvlans, i;
+       struct vf_macvlans *mv_list;
 
        if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
                return;
@@ -7123,6 +7262,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
                e_err(probe, "Failed to enable PCI sriov: %d\n", err);
                goto err_novfs;
        }
+
+       num_vf_macvlans = hw->mac.num_rar_entries -
+               (IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
+
+       adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
+                                            sizeof(struct vf_macvlans),
+                                            GFP_KERNEL);
+       if (mv_list) {
+               /* Initialize list of VF macvlans */
+               INIT_LIST_HEAD(&adapter->vf_mvs.l);
+               for (i = 0; i < num_vf_macvlans; i++) {
+                       mv_list->vf = -1;
+                       mv_list->free = true;
+                       mv_list->rar_entry = hw->mac.num_rar_entries -
+                               (i + adapter->num_vfs + 1);
+                       list_add(&mv_list->l, &adapter->vf_mvs.l);
+                       mv_list++;
+               }
+       }
+
        /* If call to enable VFs succeeded then allocate memory
         * for per VF control structures.
         */
@@ -7293,22 +7452,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        hw->phy.mdio.mdio_read = ixgbe_mdio_read;
        hw->phy.mdio.mdio_write = ixgbe_mdio_write;
 
-       /* set up this timer and work struct before calling get_invariants
-        * which might start the timer
-        */
-       init_timer(&adapter->sfp_timer);
-       adapter->sfp_timer.function = ixgbe_sfp_timer;
-       adapter->sfp_timer.data = (unsigned long) adapter;
-
-       INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
-
-       /* multispeed fiber has its own tasklet, called from GPI SDP1 context */
-       INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
-
-       /* a new SFP+ module arrival, called from GPI SDP2 context */
-       INIT_WORK(&adapter->sfp_config_module_task,
-                 ixgbe_sfp_config_module_task);
-
        ii->get_invariants(hw);
 
        /* setup the private structure */
@@ -7342,17 +7485,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        hw->phy.reset_if_overtemp = false;
        if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
            hw->mac.type == ixgbe_mac_82598EB) {
-               /*
-                * Start a kernel thread to watch for a module to arrive.
-                * Only do this for 82598, since 82599 will generate
-                * interrupts on module arrival.
-                */
-               set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-               mod_timer(&adapter->sfp_timer,
-                         round_jiffies(jiffies + (2 * HZ)));
                err = 0;
        } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-               e_dev_err("failed to initialize because an unsupported SFP+ "
+               e_dev_err("failed to load because an unsupported SFP+ "
                          "module type was detected.\n");
                e_dev_err("Reload the driver after installing a supported "
                          "module.\n");
@@ -7444,12 +7579,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
              (hw->mac.type == ixgbe_mac_82599EB))))
                hw->mac.ops.disable_tx_laser(hw);
 
-       init_timer(&adapter->watchdog_timer);
-       adapter->watchdog_timer.function = ixgbe_watchdog;
-       adapter->watchdog_timer.data = (unsigned long)adapter;
+       setup_timer(&adapter->service_timer, &ixgbe_service_timer,
+                   (unsigned long) adapter);
 
-       INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
-       INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
+       INIT_WORK(&adapter->service_task, ixgbe_service_task);
+       clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
 
        err = ixgbe_init_interrupt_scheme(adapter);
        if (err)
@@ -7536,13 +7670,6 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        /* carrier off reporting is important to ethtool even BEFORE open */
        netif_carrier_off(netdev);
 
-       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-               INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
-
-       if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-               INIT_WORK(&adapter->check_overtemp_task,
-                         ixgbe_check_overtemp_task);
 #ifdef CONFIG_IXGBE_DCA
        if (dca_add_requester(&pdev->dev) == 0) {
                adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -7569,11 +7696,7 @@ err_sw_init:
 err_eeprom:
        if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
                ixgbe_disable_sriov(adapter);
-       clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-       del_timer_sync(&adapter->sfp_timer);
-       cancel_work_sync(&adapter->sfp_task);
-       cancel_work_sync(&adapter->multispeed_fiber_task);
-       cancel_work_sync(&adapter->sfp_config_module_task);
+       adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
        iounmap(hw->hw_addr);
 err_ioremap:
        free_netdev(netdev);
@@ -7601,24 +7724,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        struct net_device *netdev = adapter->netdev;
 
        set_bit(__IXGBE_DOWN, &adapter->state);
-
-       /*
-        * The timers may be rescheduled, so explicitly disable them
-        * from being rescheduled.
-        */
-       clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-       del_timer_sync(&adapter->watchdog_timer);
-       del_timer_sync(&adapter->sfp_timer);
-
-       cancel_work_sync(&adapter->watchdog_task);
-       cancel_work_sync(&adapter->sfp_task);
-       cancel_work_sync(&adapter->multispeed_fiber_task);
-       cancel_work_sync(&adapter->sfp_config_module_task);
-       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-               cancel_work_sync(&adapter->fdir_reinit_task);
-       if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-               cancel_work_sync(&adapter->check_overtemp_task);
+       cancel_work_sync(&adapter->service_task);
 
 #ifdef CONFIG_IXGBE_DCA
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
index f53dc5bb28b79ae555b60432140f96d9fefc0a09..b239bdac38da734ebf1de50c5ae8c3409d40a53a 100644 (file)
@@ -67,6 +67,7 @@
 #define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
 #define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
 #define IXGBE_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN      0x06 /* VF requests PF for unicast filter */
 
 /* length of permanent address message returned from PF */
 #define IXGBE_VF_PERMADDR_MSG_LEN 4
index 47650278d414fb81008db36544b4ce01602ead63..ac99b0458fe2f2f6b1e29351465838e696ad9f64 100644 (file)
@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
        return 0;
 }
 
+static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct list_head *pos;
+       struct vf_macvlans *entry;
+
+       list_for_each(pos, &adapter->vf_mvs.l) {
+               entry = list_entry(pos, struct vf_macvlans, l);
+               if (entry->free == false)
+                       hw->mac.ops.set_rar(hw, entry->rar_entry,
+                                           entry->vf_macvlan,
+                                           entry->vf, IXGBE_RAH_AV);
+       }
+}
+
 void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
                        IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
                }
        }
+
+       /* Restore any VF macvlans */
+       ixgbe_restore_vf_macvlans(adapter);
 }
 
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
        return 0;
 }
 
+static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
+                               int vf, int index, unsigned char *mac_addr)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct list_head *pos;
+       struct vf_macvlans *entry;
+
+       if (index <= 1) {
+               list_for_each(pos, &adapter->vf_mvs.l) {
+                       entry = list_entry(pos, struct vf_macvlans, l);
+                       if (entry->vf == vf) {
+                               entry->vf = -1;
+                               entry->free = true;
+                               entry->is_macvlan = false;
+                               hw->mac.ops.clear_rar(hw, entry->rar_entry);
+                       }
+               }
+       }
+
+       /*
+        * If index was zero then we were asked to clear the uc list
+        * for the VF.  We're done.
+        */
+       if (!index)
+               return 0;
+
+       entry = NULL;
+
+       list_for_each(pos, &adapter->vf_mvs.l) {
+               entry = list_entry(pos, struct vf_macvlans, l);
+               if (entry->free)
+                       break;
+       }
+
+       /*
+        * If we traversed the entire list and didn't find a free entry
+        * then we're out of space on the RAR table.  Also entry may
+        * be NULL because the original memory allocation for the list
+        * failed, which is not fatal but does mean we can't support
+        * VF requests for MACVLAN because we couldn't allocate
+        * memory for the list management required.
+        */
+       if (!entry || !entry->free)
+               return -ENOSPC;
+
+       entry->free = false;
+       entry->is_macvlan = true;
+       entry->vf = vf;
+       memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
+
+       hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+
+       return 0;
+}
+
 int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
 {
        unsigned char vf_mac_addr[6];
@@ -251,12 +324,12 @@ static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf)
 static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
 {
        u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
-       u32 msgbuf[mbx_size];
+       u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
        struct ixgbe_hw *hw = &adapter->hw;
        s32 retval;
        int entries;
        u16 *hash_list;
-       int add, vid;
+       int add, vid, index;
        u8 *new_mac;
 
        retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
                        retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
                }
                break;
+       case IXGBE_VF_SET_MACVLAN:
+               index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
+                       IXGBE_VT_MSGINFO_SHIFT;
+               /*
+                * If the VF is allowed to set MAC filters then turn off
+                * anti-spoofing to avoid false positives.  An index
+                * greater than 0 will indicate the VF is setting a
+                * macvlan MAC filter.
+                */
+               if (index > 0 && adapter->antispoofing_enabled) {
+                       hw->mac.ops.set_mac_anti_spoofing(hw, false,
+                                                         adapter->num_vfs);
+                       hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
+                       adapter->antispoofing_enabled = false;
+               }
+               retval = ixgbe_set_vf_macvlan(adapter, vf, index,
+                                             (unsigned char *)(&msgbuf[1]));
+               break;
        default:
                e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
                retval = IXGBE_ERR_MBX;
@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
                        goto out;
                ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
                ixgbe_set_vmolr(hw, vf, false);
-               hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+               if (adapter->antispoofing_enabled)
+                       hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
                adapter->vfinfo[vf].pf_vlan = vlan;
                adapter->vfinfo[vf].pf_qos = qos;
                dev_info(&adapter->pdev->dev,
index 70e6870be01f65381241392490fe0674a7fce586..fa43f2507f43f9c1c5e98fdb15736f2579fbd427 100644 (file)
@@ -62,6 +62,7 @@
 #define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
 #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ  0x000C
+#define IXGBE_DEV_ID_82599_LS            0x154F
 #define IXGBE_DEV_ID_X540T               0x1528
 
 /* General Registers */
@@ -2395,6 +2396,7 @@ enum ixgbe_sfp_type {
 enum ixgbe_media_type {
        ixgbe_media_type_unknown = 0,
        ixgbe_media_type_fiber,
+       ixgbe_media_type_fiber_lco,
        ixgbe_media_type_copper,
        ixgbe_media_type_backplane,
        ixgbe_media_type_cx4,
index 05fa7c85deed3351ec9c6ad8069f40c7ceae858b..d7ab202fb95c084baa785074a11f7e64c2777889 100644 (file)
@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter)
        }
 }
 
+static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
+{
+       struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
+       int count = 0;
+
+       if ((netdev_uc_count(netdev)) > 10) {
+               printk(KERN_ERR "Too many unicast filters - No Space\n");
+               return -ENOSPC;
+       }
+
+       if (!netdev_uc_empty(netdev)) {
+               struct netdev_hw_addr *ha;
+               netdev_for_each_uc_addr(ha, netdev) {
+                       hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
+                       udelay(200);
+               }
+       } else {
+               /*
+                * If the list is empty then send message to PF driver to
+                * clear all macvlans on this VF.
+                */
+               hw->mac.ops.set_uc_addr(hw, 0, NULL);
+       }
+
+       return count;
+}
+
 /**
  * ixgbevf_set_rx_mode - Multicast set
  * @netdev: network interface device structure
@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev)
        /* reprogram multicast list */
        if (hw->mac.ops.update_mc_addr_list)
                hw->mac.ops.update_mc_addr_list(hw, netdev);
+
+       ixgbevf_write_uc_addr_list(netdev);
 }
 
 static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
index b2b5bf5daa3d202cc74d8961ca5af9f411604bc1..ea393eb03f3aeba86c4658b0451a54b447e26034 100644 (file)
@@ -81,6 +81,7 @@
 #define IXGBE_VF_SET_MULTICAST    0x03 /* VF requests PF to set MC addr */
 #define IXGBE_VF_SET_VLAN         0x04 /* VF requests PF to set VLAN */
 #define IXGBE_VF_SET_LPE          0x05 /* VF requests PF to set VMOLR.LPE */
+#define IXGBE_VF_SET_MACVLAN      0x06 /* VF requests PF for unicast filter */
 
 /* length of permanent address message returned from PF */
 #define IXGBE_VF_PERMADDR_MSG_LEN 4
index eecd3bf6833f4c6ecd75c110cbcced7ffc2825fc..aa3682e8c473cc84bcf9c6bc0b7d17a12857854d 100644 (file)
@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
        return 0;
 }
 
+static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
+{
+       struct ixgbe_mbx_info *mbx = &hw->mbx;
+       u32 msgbuf[3];
+       u8 *msg_addr = (u8 *)(&msgbuf[1]);
+       s32 ret_val;
+
+       memset(msgbuf, 0, sizeof(msgbuf));
+       /*
+        * If index is one then this is the start of a new list and needs
+        * indication to the PF so it can do it's own list management.
+        * If it is zero then that tells the PF to just clear all of
+        * this VF's macvlans and there is no new list.
+        */
+       msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
+       msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
+       if (addr)
+               memcpy(msg_addr, addr, 6);
+       ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
+
+       if (!ret_val)
+               ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
+
+       msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
+
+       if (!ret_val)
+               if (msgbuf[0] ==
+                   (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
+                       ret_val = -ENOMEM;
+
+       return ret_val;
+}
+
 /**
  *  ixgbevf_set_rar_vf - set device MAC address
  *  @hw: pointer to hardware structure
@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = {
        .check_link          = ixgbevf_check_mac_link_vf,
        .set_rar             = ixgbevf_set_rar_vf,
        .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
+       .set_uc_addr         = ixgbevf_set_uc_addr_vf,
        .set_vfta            = ixgbevf_set_vfta_vf,
 };
 
index 23eb114c149fd21b3f41d200894976ddd9d5ff1f..10306b492ee61b5b9e686503839281b35b9df1fb 100644 (file)
@@ -62,6 +62,7 @@ struct ixgbe_mac_operations {
 
        /* RAR, Multicast, VLAN */
        s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
+       s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
        s32 (*init_rx_addrs)(struct ixgbe_hw *);
        s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
        s32 (*enable_mc)(struct ixgbe_hw *);