]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
ixgbe: bump version number
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / intel / ixgbe / ixgbe_main.c
index cc06854296a379a6f5d1fac21ecf9412d94d477b..6d4ada72dfd0a79f1111ff5c48f91ba3e2c862f1 100644 (file)
@@ -64,7 +64,7 @@ char ixgbe_default_device_descr[] =
 static char ixgbe_default_device_descr[] =
                              "Intel(R) 10 Gigabit Network Connection";
 #endif
-#define DRV_VERSION "3.15.1-k"
+#define DRV_VERSION "3.19.1-k"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
                                "Copyright (c) 1999-2013 Intel Corporation.";
@@ -278,10 +278,41 @@ static void ixgbe_check_minimum_link(struct ixgbe_adapter *adapter,
 static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
 {
        if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+           !test_bit(__IXGBE_REMOVING, &adapter->state) &&
            !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
                schedule_work(&adapter->service_task);
 }
 
+static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
+{
+       struct ixgbe_adapter *adapter = hw->back;
+
+       if (!hw->hw_addr)
+               return;
+       hw->hw_addr = NULL;
+       e_dev_err("Adapter removed\n");
+       ixgbe_service_event_schedule(adapter);
+}
+
+void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
+{
+       u32 value;
+
+       /* The following check not only optimizes a bit by not
+        * performing a read on the status register when the
+        * register just read was a status register read that
+        * returned IXGBE_FAILED_READ_REG. It also blocks any
+        * potential recursion.
+        */
+       if (reg == IXGBE_STATUS) {
+               ixgbe_remove_adapter(hw);
+               return;
+       }
+       value = ixgbe_read_reg(hw, IXGBE_STATUS);
+       if (value == IXGBE_FAILED_READ_REG)
+               ixgbe_remove_adapter(hw);
+}
+
 static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
 {
        BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
@@ -1314,7 +1345,7 @@ static inline void ixgbe_release_rx_desc(struct ixgbe_ring *rx_ring, u32 val)
         * such as IA-64).
         */
        wmb();
-       writel(val, rx_ring->tail);
+       ixgbe_write_tail(rx_ring, val);
 }
 
 static bool ixgbe_alloc_mapped_page(struct ixgbe_ring *rx_ring,
@@ -2969,7 +3000,7 @@ void ixgbe_configure_tx_ring(struct ixgbe_adapter *adapter,
                        ring->count * sizeof(union ixgbe_adv_tx_desc));
        IXGBE_WRITE_REG(hw, IXGBE_TDH(reg_idx), 0);
        IXGBE_WRITE_REG(hw, IXGBE_TDT(reg_idx), 0);
-       ring->tail = hw->hw_addr + IXGBE_TDT(reg_idx);
+       ring->tail = adapter->io_addr + IXGBE_TDT(reg_idx);
 
        /*
         * set WTHRESH to encourage burst writeback, it should not be set
@@ -3308,6 +3339,8 @@ static void ixgbe_rx_desc_queue_enable(struct ixgbe_adapter *adapter,
        u32 rxdctl;
        u8 reg_idx = ring->reg_idx;
 
+       if (ixgbe_removed(hw->hw_addr))
+               return;
        /* RXDCTL.EN will return 0 on 82598 if link is down, so skip it */
        if (hw->mac.type == ixgbe_mac_82598EB &&
            !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
@@ -3332,6 +3365,8 @@ void ixgbe_disable_rx_queue(struct ixgbe_adapter *adapter,
        u32 rxdctl;
        u8 reg_idx = ring->reg_idx;
 
+       if (ixgbe_removed(hw->hw_addr))
+               return;
        rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
        rxdctl &= ~IXGBE_RXDCTL_ENABLE;
 
@@ -3372,7 +3407,7 @@ void ixgbe_configure_rx_ring(struct ixgbe_adapter *adapter,
                        ring->count * sizeof(union ixgbe_adv_rx_desc));
        IXGBE_WRITE_REG(hw, IXGBE_RDH(reg_idx), 0);
        IXGBE_WRITE_REG(hw, IXGBE_RDT(reg_idx), 0);
-       ring->tail = hw->hw_addr + IXGBE_RDT(reg_idx);
+       ring->tail = adapter->io_addr + IXGBE_RDT(reg_idx);
 
        ixgbe_configure_srrctl(adapter, ring);
        ixgbe_configure_rscctl(adapter, ring);
@@ -4572,6 +4607,7 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
        if (hw->mac.ops.enable_tx_laser)
                hw->mac.ops.enable_tx_laser(hw);
 
+       smp_mb__before_clear_bit();
        clear_bit(__IXGBE_DOWN, &adapter->state);
        ixgbe_napi_enable_all(adapter);
 
@@ -4656,6 +4692,8 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
        struct ixgbe_hw *hw = &adapter->hw;
        int err;
 
+       if (ixgbe_removed(hw->hw_addr))
+               return;
        /* 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);
@@ -4783,7 +4821,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        int i;
 
        /* signal that we are down to the interrupt handler */
-       set_bit(__IXGBE_DOWN, &adapter->state);
+       if (test_and_set_bit(__IXGBE_DOWN, &adapter->state))
+               return; /* do nothing if already down */
 
        /* disable receives */
        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
@@ -5028,7 +5067,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
 
        /* assign number of SR-IOV VFs */
        if (hw->mac.type != ixgbe_mac_82598EB) {
-               if (max_vfs > 63) {
+               if (max_vfs > IXGBE_MAX_VFS_DRV_LIMIT) {
                        adapter->num_vfs = 0;
                        e_dev_warn("max_vfs parameter out of range. Not assigning any SR-IOV VFs\n");
                } else {
@@ -5874,8 +5913,9 @@ static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
        u64 eics = 0;
        int i;
 
-       /* If we're down or resetting, just bail */
+       /* If we're down, removing or resetting, just bail */
        if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+           test_bit(__IXGBE_REMOVING, &adapter->state) ||
            test_bit(__IXGBE_RESETTING, &adapter->state))
                return;
 
@@ -6122,8 +6162,9 @@ static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
  **/
 static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
 {
-       /* if interface is down do nothing */
+       /* if interface is down, removing or resetting, do nothing */
        if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+           test_bit(__IXGBE_REMOVING, &adapter->state) ||
            test_bit(__IXGBE_RESETTING, &adapter->state))
                return;
 
@@ -6341,8 +6382,9 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
 
        adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
 
-       /* If we're already down or resetting, just bail */
+       /* If we're already down, removing or resetting, just bail */
        if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+           test_bit(__IXGBE_REMOVING, &adapter->state) ||
            test_bit(__IXGBE_RESETTING, &adapter->state))
                return;
 
@@ -6350,7 +6392,9 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
        netdev_err(adapter->netdev, "Reset adapter\n");
        adapter->tx_timeout_count++;
 
+       rtnl_lock();
        ixgbe_reinit_locked(adapter);
+       rtnl_unlock();
 }
 
 /**
@@ -6362,6 +6406,15 @@ static void ixgbe_service_task(struct work_struct *work)
        struct ixgbe_adapter *adapter = container_of(work,
                                                     struct ixgbe_adapter,
                                                     service_task);
+       if (ixgbe_removed(adapter->hw.hw_addr)) {
+               if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+                       rtnl_lock();
+                       ixgbe_down(adapter);
+                       rtnl_unlock();
+               }
+               ixgbe_service_event_complete(adapter);
+               return;
+       }
        ixgbe_reset_subtask(adapter);
        ixgbe_sfp_detection_subtask(adapter);
        ixgbe_sfp_link_config_subtask(adapter);
@@ -6693,7 +6746,7 @@ static void ixgbe_tx_map(struct ixgbe_ring *tx_ring,
        tx_ring->next_to_use = i;
 
        /* notify HW of packet */
-       writel(i, tx_ring->tail);
+       ixgbe_write_tail(tx_ring, i);
 
        return;
 dma_error:
@@ -6827,12 +6880,20 @@ static inline int ixgbe_maybe_stop_tx(struct ixgbe_ring *tx_ring, u16 size)
        return __ixgbe_maybe_stop_tx(tx_ring, size);
 }
 
-#ifdef IXGBE_FCOE
-static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
+static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb,
+                             void *accel_priv)
 {
+       struct ixgbe_fwd_adapter *fwd_adapter = accel_priv;
+#ifdef IXGBE_FCOE
        struct ixgbe_adapter *adapter;
        struct ixgbe_ring_feature *f;
        int txq;
+#endif
+
+       if (fwd_adapter)
+               return skb->queue_mapping + fwd_adapter->tx_base_queue;
+
+#ifdef IXGBE_FCOE
 
        /*
         * only execute the code below if protocol is FCoE
@@ -6858,9 +6919,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
                txq -= f->indices;
 
        return txq + f->offset;
+#else
+       return __netdev_pick_tx(dev, skb);
+#endif
 }
 
-#endif
 netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
                          struct ixgbe_adapter *adapter,
                          struct ixgbe_ring *tx_ring)
@@ -7629,27 +7692,11 @@ static void ixgbe_fwd_del(struct net_device *pdev, void *priv)
        kfree(fwd_adapter);
 }
 
-static netdev_tx_t ixgbe_fwd_xmit(struct sk_buff *skb,
-                                 struct net_device *dev,
-                                 void *priv)
-{
-       struct ixgbe_fwd_adapter *fwd_adapter = priv;
-       unsigned int queue;
-       struct ixgbe_ring *tx_ring;
-
-       queue = skb->queue_mapping + fwd_adapter->tx_base_queue;
-       tx_ring = fwd_adapter->real_adapter->tx_ring[queue];
-
-       return __ixgbe_xmit_frame(skb, dev, tx_ring);
-}
-
 static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_open               = ixgbe_open,
        .ndo_stop               = ixgbe_close,
        .ndo_start_xmit         = ixgbe_xmit_frame,
-#ifdef IXGBE_FCOE
        .ndo_select_queue       = ixgbe_select_queue,
-#endif
        .ndo_set_rx_mode        = ixgbe_set_rx_mode,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = ixgbe_set_mac,
@@ -7689,7 +7736,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_bridge_getlink     = ixgbe_ndo_bridge_getlink,
        .ndo_dfwd_add_station   = ixgbe_fwd_add,
        .ndo_dfwd_del_station   = ixgbe_fwd_del,
-       .ndo_dfwd_start_xmit    = ixgbe_fwd_xmit,
 };
 
 /**
@@ -7881,6 +7927,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
                              pci_resource_len(pdev, 0));
+       adapter->io_addr = hw->hw_addr;
        if (!hw->hw_addr) {
                err = -EIO;
                goto err_ioremap;
@@ -7972,8 +8019,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Mailbox */
        ixgbe_init_mbx_params_pf(hw);
        memcpy(&hw->mbx.ops, ii->mbx_ops, sizeof(hw->mbx.ops));
+       pci_sriov_set_totalvfs(pdev, IXGBE_MAX_VFS_DRV_LIMIT);
        ixgbe_enable_sriov(adapter);
-       pci_sriov_set_totalvfs(pdev, 63);
 skip_sriov:
 
 #endif
@@ -8189,7 +8236,7 @@ err_register:
 err_sw_init:
        ixgbe_disable_sriov(adapter);
        adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
-       iounmap(hw->hw_addr);
+       iounmap(adapter->io_addr);
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
@@ -8217,7 +8264,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
 
        ixgbe_dbg_adapter_exit(adapter);
 
-       set_bit(__IXGBE_DOWN, &adapter->state);
+       set_bit(__IXGBE_REMOVING, &adapter->state);
        cancel_work_sync(&adapter->service_task);
 
 
@@ -8256,7 +8303,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
        kfree(adapter->ixgbe_ieee_ets);
 
 #endif
-       iounmap(adapter->hw.hw_addr);
+       iounmap(adapter->io_addr);
        pci_release_selected_regions(pdev, pci_select_bars(pdev,
                                     IORESOURCE_MEM));