#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/pci.h>
+#include <linux/pci-aspm.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/if_ether.h>
-
+#include <linux/aer.h>
+#ifdef CONFIG_IGB_DCA
+#include <linux/dca.h>
+#endif
#include "igb.h"
-#define DRV_VERSION "1.0.8-k2"
+#define DRV_VERSION "1.2.45-k2"
char igb_driver_name[] = "igb";
char igb_driver_version[] = DRV_VERSION;
static const char igb_driver_string[] =
"Intel(R) Gigabit Ethernet Network Driver";
-static const char igb_copyright[] = "Copyright (c) 2007 Intel Corporation.";
-
+static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
};
static struct pci_device_id igb_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_FIBER), board_82575 },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
static void igb_free_all_rx_resources(struct igb_adapter *);
-static void igb_free_tx_resources(struct igb_adapter *, struct igb_ring *);
-static void igb_free_rx_resources(struct igb_adapter *, struct igb_ring *);
void igb_update_stats(struct igb_adapter *);
static int igb_probe(struct pci_dev *, const struct pci_device_id *);
static void __devexit igb_remove(struct pci_dev *pdev);
static void igb_setup_rctl(struct igb_adapter *);
static void igb_clean_all_tx_rings(struct igb_adapter *);
static void igb_clean_all_rx_rings(struct igb_adapter *);
-static void igb_clean_tx_ring(struct igb_adapter *, struct igb_ring *);
-static void igb_clean_rx_ring(struct igb_adapter *, struct igb_ring *);
+static void igb_clean_tx_ring(struct igb_ring *);
+static void igb_clean_rx_ring(struct igb_ring *);
static void igb_set_multi(struct net_device *);
static void igb_update_phy_info(unsigned long);
static void igb_watchdog(unsigned long);
static irqreturn_t igb_msix_rx(int irq, void *);
static irqreturn_t igb_msix_tx(int irq, void *);
static int igb_clean_rx_ring_msix(struct napi_struct *, int);
-static bool igb_clean_tx_irq(struct igb_adapter *, struct igb_ring *);
-static int igb_clean(struct napi_struct *, int);
-static bool igb_clean_rx_irq_adv(struct igb_adapter *,
- struct igb_ring *, int *, int);
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *,
- struct igb_ring *, int);
+#ifdef CONFIG_IGB_DCA
+static void igb_update_rx_dca(struct igb_ring *);
+static void igb_update_tx_dca(struct igb_ring *);
+static void igb_setup_dca(struct igb_adapter *);
+#endif /* CONFIG_IGB_DCA */
+static bool igb_clean_tx_irq(struct igb_ring *);
+static int igb_poll(struct napi_struct *, int);
+static bool igb_clean_rx_irq_adv(struct igb_ring *, int *, int);
+static void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
+#ifdef CONFIG_IGB_LRO
+static int igb_get_skb_hdr(struct sk_buff *skb, void **, void **, u64 *, void *);
+#endif
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
static int igb_resume(struct pci_dev *);
#endif
static void igb_shutdown(struct pci_dev *);
+#ifdef CONFIG_IGB_DCA
+static int igb_notify_dca(struct notifier_block *, unsigned long, void *);
+static struct notifier_block dca_notifier = {
+ .notifier_call = igb_notify_dca,
+ .next = NULL,
+ .priority = 0
+};
+#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
/* for netdump / net console */
.err_handler = &igb_err_handler
};
+static int global_quad_port_a; /* global quad port a indication */
+
MODULE_AUTHOR("Intel Corporation, <e1000-devel@lists.sourceforge.net>");
MODULE_DESCRIPTION("Intel(R) Gigabit Ethernet Network Driver");
MODULE_LICENSE("GPL");
printk(KERN_INFO "%s\n", igb_copyright);
+ global_quad_port_a = 0;
+
ret = pci_register_driver(&igb_driver);
+#ifdef CONFIG_IGB_DCA
+ dca_register_notify(&dca_notifier);
+#endif
return ret;
}
**/
static void __exit igb_exit_module(void)
{
+#ifdef CONFIG_IGB_DCA
+ dca_unregister_notify(&dca_notifier);
+#endif
pci_unregister_driver(&igb_driver);
}
module_exit(igb_exit_module);
+#define Q_IDX_82576(i) (((i & 0x1) << 3) + (i >> 1))
+/**
+ * igb_cache_ring_register - Descriptor ring to register mapping
+ * @adapter: board private structure to initialize
+ *
+ * Once we know the feature-set enabled for the device, we'll cache
+ * the register offset the descriptor ring is assigned to.
+ **/
+static void igb_cache_ring_register(struct igb_adapter *adapter)
+{
+ int i;
+
+ switch (adapter->hw.mac.type) {
+ case e1000_82576:
+ /* The queues are allocated for virtualization such that VF 0
+ * is allocated queues 0 and 8, VF 1 queues 1 and 9, etc.
+ * In order to avoid collision we start at the first free queue
+ * and continue consuming queues in the same sequence
+ */
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].reg_idx = Q_IDX_82576(i);
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].reg_idx = Q_IDX_82576(i);
+ break;
+ case e1000_82575:
+ default:
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ adapter->rx_ring[i].reg_idx = i;
+ for (i = 0; i < adapter->num_tx_queues; i++)
+ adapter->tx_ring[i].reg_idx = i;
+ break;
+ }
+}
+
/**
* igb_alloc_queues - Allocate memory for all rings
* @adapter: board private structure to initialize
return -ENOMEM;
}
+ adapter->rx_ring->buddy = adapter->tx_ring;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ struct igb_ring *ring = &(adapter->tx_ring[i]);
+ ring->count = adapter->tx_ring_count;
+ ring->adapter = adapter;
+ ring->queue_index = i;
+ }
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
+ ring->count = adapter->rx_ring_count;
ring->adapter = adapter;
+ ring->queue_index = i;
ring->itr_register = E1000_ITR;
- if (!ring->napi.poll)
- netif_napi_add(adapter->netdev, &ring->napi, igb_clean,
- adapter->napi.weight /
- adapter->num_rx_queues);
+ /* set a default napi handler for each rx_ring */
+ netif_napi_add(adapter->netdev, &ring->napi, igb_poll, 64);
}
+
+ igb_cache_ring_register(adapter);
return 0;
}
+static void igb_free_queues(struct igb_adapter *adapter)
+{
+ int i;
+
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ netif_napi_del(&adapter->rx_ring[i].napi);
+
+ kfree(adapter->tx_ring);
+ kfree(adapter->rx_ring);
+}
+
#define IGB_N0_QUEUE -1
static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
int tx_queue, int msix_vector)
{
u32 msixbm = 0;
struct e1000_hw *hw = &adapter->hw;
+ u32 ivar, index;
+
+ switch (hw->mac.type) {
+ case e1000_82575:
/* The 82575 assigns vectors using a bitmask, which matches the
bitmask for the EICR/EIMS/EIMC registers. To assign one
or more queues to a vector, we write the appropriate bits
E1000_EICR_TX_QUEUE0 << tx_queue;
}
array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
+ break;
+ case e1000_82576:
+ /* 82576 uses a table-based method for assigning vectors.
+ Each queue has a single entry in the table to which we write
+ a vector number along with a "valid" bit. Sadly, the layout
+ of the table is somewhat counterintuitive. */
+ if (rx_queue > IGB_N0_QUEUE) {
+ index = (rx_queue >> 1);
+ ivar = array_rd32(E1000_IVAR0, index);
+ if (rx_queue & 0x1) {
+ /* vector goes into third byte of register */
+ ivar = ivar & 0xFF00FFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 16;
+ } else {
+ /* vector goes into low byte of register */
+ ivar = ivar & 0xFFFFFF00;
+ ivar |= msix_vector | E1000_IVAR_VALID;
+ }
+ adapter->rx_ring[rx_queue].eims_value= 1 << msix_vector;
+ array_wr32(E1000_IVAR0, index, ivar);
+ }
+ if (tx_queue > IGB_N0_QUEUE) {
+ index = (tx_queue >> 1);
+ ivar = array_rd32(E1000_IVAR0, index);
+ if (tx_queue & 0x1) {
+ /* vector goes into high byte of register */
+ ivar = ivar & 0x00FFFFFF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 24;
+ } else {
+ /* vector goes into second byte of register */
+ ivar = ivar & 0xFFFF00FF;
+ ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
+ }
+ adapter->tx_ring[tx_queue].eims_value= 1 << msix_vector;
+ array_wr32(E1000_IVAR0, index, ivar);
+ }
+ break;
+ default:
+ BUG();
+ break;
+ }
}
/**
struct e1000_hw *hw = &adapter->hw;
adapter->eims_enable_mask = 0;
+ if (hw->mac.type == e1000_82576)
+ /* Turn on MSI-X capability first, or our settings
+ * won't stick. And it will take days to debug. */
+ wr32(E1000_GPIE, E1000_GPIE_MSIX_MODE |
+ E1000_GPIE_PBA | E1000_GPIE_EIAME |
+ E1000_GPIE_NSICR);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *tx_ring = &adapter->tx_ring[i];
igb_assign_vector(adapter, IGB_N0_QUEUE, i, vector++);
adapter->eims_enable_mask |= tx_ring->eims_value;
if (tx_ring->itr_val)
- writel(1000000000 / (tx_ring->itr_val * 256),
+ writel(tx_ring->itr_val,
hw->hw_addr + tx_ring->itr_register);
else
writel(1, hw->hw_addr + tx_ring->itr_register);
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *rx_ring = &adapter->rx_ring[i];
+ rx_ring->buddy = NULL;
igb_assign_vector(adapter, i, IGB_N0_QUEUE, vector++);
adapter->eims_enable_mask |= rx_ring->eims_value;
if (rx_ring->itr_val)
- writel(1000000000 / (rx_ring->itr_val * 256),
+ writel(rx_ring->itr_val,
hw->hw_addr + rx_ring->itr_register);
else
writel(1, hw->hw_addr + rx_ring->itr_register);
/* set vector for other causes, i.e. link changes */
+ switch (hw->mac.type) {
+ case e1000_82575:
array_wr32(E1000_MSIXBM(0), vector++,
E1000_EIMS_OTHER);
- /* disable IAM for ICR interrupt bits */
- wr32(E1000_IAM, 0);
-
tmp = rd32(E1000_CTRL_EXT);
/* enable MSI-X PBA support*/
tmp |= E1000_CTRL_EXT_PBA_CLR;
wr32(E1000_CTRL_EXT, tmp);
adapter->eims_enable_mask |= E1000_EIMS_OTHER;
+ adapter->eims_other = E1000_EIMS_OTHER;
+ break;
+
+ case e1000_82576:
+ tmp = (vector++ | E1000_IVAR_VALID) << 8;
+ wr32(E1000_IVAR_MISC, tmp);
+
+ adapter->eims_enable_mask = (1 << (vector)) - 1;
+ adapter->eims_other = 1 << (vector - 1);
+ break;
+ default:
+ /* do nothing, since nothing else supports MSI-X */
+ break;
+ } /* switch (hw->mac.type) */
wrfl();
}
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *ring = &(adapter->tx_ring[i]);
- sprintf(ring->name, "%s-tx%d", netdev->name, i);
+ sprintf(ring->name, "%s-tx-%d", netdev->name, i);
err = request_irq(adapter->msix_entries[vector].vector,
&igb_msix_tx, 0, ring->name,
&(adapter->tx_ring[i]));
if (err)
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
- ring->itr_val = adapter->itr;
+ ring->itr_val = 976; /* ~4000 ints/sec */
vector++;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
if (strlen(netdev->name) < (IFNAMSIZ - 5))
- sprintf(ring->name, "%s-rx%d", netdev->name, i);
+ sprintf(ring->name, "%s-rx-%d", netdev->name, i);
else
memcpy(ring->name, netdev->name, IFNAMSIZ);
err = request_irq(adapter->msix_entries[vector].vector,
goto out;
ring->itr_register = E1000_EITR(0) + (vector << 2);
ring->itr_val = adapter->itr;
+ /* overwrite the poll routine for MSIX, we've already done
+ * netif_napi_add */
+ ring->napi.poll = &igb_clean_rx_ring_msix;
vector++;
}
if (err)
goto out;
- adapter->napi.poll = igb_clean_rx_ring_msix;
- for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].napi.poll = adapter->napi.poll;
igb_configure_msix(adapter);
return 0;
out:
pci_disable_msix(adapter->pdev);
kfree(adapter->msix_entries);
adapter->msix_entries = NULL;
- } else if (adapter->msi_enabled)
+ } else if (adapter->flags & IGB_FLAG_HAS_MSI)
pci_disable_msi(adapter->pdev);
return;
}
adapter->msix_entries,
numvecs);
if (err == 0)
- return;
+ goto out;
igb_reset_interrupt_capability(adapter);
/* If we can't do MSI-X, try MSI */
msi_only:
adapter->num_rx_queues = 1;
+ adapter->num_tx_queues = 1;
if (!pci_enable_msi(adapter->pdev))
- adapter->msi_enabled = 1;
+ adapter->flags |= IGB_FLAG_HAS_MSI;
+out:
+ /* Notify the stack of the (possibly) reduced Tx Queue count. */
+ adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
return;
}
if (adapter->msix_entries) {
err = igb_request_msix(adapter);
- if (!err) {
- /* enable IAM, auto-mask,
- * DO NOT USE EIAM or IAM in legacy mode */
- wr32(E1000_IAM, IMS_ENABLE_MASK);
+ if (!err)
goto request_done;
- }
/* fall back to MSI */
igb_reset_interrupt_capability(adapter);
if (!pci_enable_msi(adapter->pdev))
- adapter->msi_enabled = 1;
+ adapter->flags |= IGB_FLAG_HAS_MSI;
igb_free_all_tx_resources(adapter);
igb_free_all_rx_resources(adapter);
adapter->num_rx_queues = 1;
igb_alloc_queues(adapter);
+ } else {
+ switch (hw->mac.type) {
+ case e1000_82575:
+ wr32(E1000_MSIXBM(0),
+ (E1000_EICR_RX_QUEUE0 | E1000_EIMS_OTHER));
+ break;
+ case e1000_82576:
+ wr32(E1000_IVAR0, E1000_IVAR_VALID);
+ break;
+ default:
+ break;
+ }
}
- if (adapter->msi_enabled) {
+
+ if (adapter->flags & IGB_FLAG_HAS_MSI) {
err = request_irq(adapter->pdev->irq, &igb_intr_msi, 0,
netdev->name, netdev);
if (!err)
goto request_done;
/* fall back to legacy interrupts */
igb_reset_interrupt_capability(adapter);
- adapter->msi_enabled = 0;
+ adapter->flags &= ~IGB_FLAG_HAS_MSI;
}
err = request_irq(adapter->pdev->irq, &igb_intr, IRQF_SHARED,
struct e1000_hw *hw = &adapter->hw;
if (adapter->msix_entries) {
+ wr32(E1000_EIAM, 0);
wr32(E1000_EIMC, ~0);
wr32(E1000_EIAC, 0);
}
+
+ wr32(E1000_IAM, 0);
wr32(E1000_IMC, ~0);
wrfl();
synchronize_irq(adapter->pdev->irq);
struct e1000_hw *hw = &adapter->hw;
if (adapter->msix_entries) {
- wr32(E1000_EIMS,
- adapter->eims_enable_mask);
- wr32(E1000_EIAC,
- adapter->eims_enable_mask);
+ wr32(E1000_EIAC, adapter->eims_enable_mask);
+ wr32(E1000_EIAM, adapter->eims_enable_mask);
+ wr32(E1000_EIMS, adapter->eims_enable_mask);
wr32(E1000_IMS, E1000_IMS_LSC);
- } else
- wr32(E1000_IMS, IMS_ENABLE_MASK);
+ } else {
+ wr32(E1000_IMS, IMS_ENABLE_MASK);
+ wr32(E1000_IAM, IMS_ENABLE_MASK);
+ }
}
static void igb_update_mng_vlan(struct igb_adapter *adapter)
ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
}
-static void igb_init_manageability(struct igb_adapter *adapter)
-{
- struct e1000_hw *hw = &adapter->hw;
-
- if (adapter->en_mng_pt) {
- u32 manc2h = rd32(E1000_MANC2H);
- u32 manc = rd32(E1000_MANC);
-
- /* enable receiving management packets to the host */
- /* this will probably generate destination unreachable messages
- * from the host OS, but the packets will be handled on SMBUS */
- manc |= E1000_MANC_EN_MNG2HOST;
-#define E1000_MNG2HOST_PORT_623 (1 << 5)
-#define E1000_MNG2HOST_PORT_664 (1 << 6)
- manc2h |= E1000_MNG2HOST_PORT_623;
- manc2h |= E1000_MNG2HOST_PORT_664;
- wr32(E1000_MANC2H, manc2h);
-
- wr32(E1000_MANC, manc);
- }
-}
-
/**
* igb_configure - configure the hardware for RX and TX
* @adapter: private board structure
igb_set_multi(netdev);
igb_restore_vlan(adapter);
- igb_init_manageability(adapter);
igb_configure_tx(adapter);
igb_setup_rctl(adapter);
igb_configure_rx(adapter);
+
+ igb_rx_fifo_flush_82575(&adapter->hw);
+
/* call IGB_DESC_UNUSED which always leaves
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &adapter->rx_ring[i];
- igb_alloc_rx_buffers_adv(adapter, ring, IGB_DESC_UNUSED(ring));
+ igb_alloc_rx_buffers_adv(ring, IGB_DESC_UNUSED(ring));
}
clear_bit(__IGB_DOWN, &adapter->state);
- napi_enable(&adapter->napi);
-
- if (adapter->msix_entries) {
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_enable(&adapter->rx_ring[i].napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_ring[i].napi);
+ if (adapter->msix_entries)
igb_configure_msix(adapter);
- }
/* Clear any pending interrupts. */
rd32(E1000_ICR);
wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
tctl = rd32(E1000_TCTL);
wrfl();
msleep(10);
- napi_disable(&adapter->napi);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_disable(&adapter->rx_ring[i].napi);
- if (adapter->msix_entries)
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_disable(&adapter->rx_ring[i].napi);
igb_irq_disable(adapter);
del_timer_sync(&adapter->watchdog_timer);
void igb_reset(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
- struct e1000_fc_info *fc = &adapter->hw.fc;
+ struct e1000_mac_info *mac = &hw->mac;
+ struct e1000_fc_info *fc = &hw->fc;
u32 pba = 0, tx_space, min_tx_space, min_rx_space;
u16 hwm;
/* Repartition Pba for greater than 9k mtu
* To take effect CTRL.RST is required.
*/
+ if (mac->type != e1000_82576) {
pba = E1000_PBA_34K;
+ }
+ else {
+ pba = E1000_PBA_64K;
+ }
- if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
+ if ((adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+ (mac->type < e1000_82576)) {
/* adjust PBA for jumbo frames */
wr32(E1000_PBA, pba);
if (pba < min_rx_space)
pba = min_rx_space;
}
+ wr32(E1000_PBA, pba);
}
- wr32(E1000_PBA, pba);
/* flow control settings */
/* The high water mark must be low enough to fit one full frame
* - 90% of the Rx FIFO size, or
* - the full Rx FIFO size minus one full frame */
hwm = min(((pba << 10) * 9 / 10),
- ((pba << 10) - adapter->max_frame_size));
+ ((pba << 10) - 2 * adapter->max_frame_size));
- fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
- fc->low_water = fc->high_water - 8;
+ if (mac->type < e1000_82576) {
+ fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
+ fc->low_water = fc->high_water - 8;
+ } else {
+ fc->high_water = hwm & 0xFFF0; /* 16-byte granularity */
+ fc->low_water = fc->high_water - 16;
+ }
fc->pause_time = 0xFFFF;
fc->send_xon = 1;
fc->type = fc->original_type;
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
igb_reset_adaptive(&adapter->hw);
- if (adapter->hw.phy.ops.get_phy_info)
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+ igb_get_phy_info(&adapter->hw);
}
/**
+ * igb_is_need_ioport - determine if an adapter needs ioport resources or not
+ * @pdev: PCI device information struct
+ *
+ * Returns true if an adapter needs ioport resources
+ **/
+static int igb_is_need_ioport(struct pci_dev *pdev)
+{
+ switch (pdev->device) {
+ /* Currently there are no adapters that need ioport resources */
+ default:
+ return false;
+ }
+}
+
+static const struct net_device_ops igb_netdev_ops = {
+ .ndo_open = igb_open,
+ .ndo_stop = igb_close,
+ .ndo_start_xmit = igb_xmit_frame_adv,
+ .ndo_get_stats = igb_get_stats,
+ .ndo_set_multicast_list = igb_set_multi,
+ .ndo_set_mac_address = igb_set_mac,
+ .ndo_change_mtu = igb_change_mtu,
+ .ndo_do_ioctl = igb_ioctl,
+ .ndo_tx_timeout = igb_tx_timeout,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_vlan_rx_register = igb_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = igb_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = igb_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = igb_netpoll,
+#endif
+};
+
+/**
* igb_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in igb_pci_tbl
struct net_device *netdev;
struct igb_adapter *adapter;
struct e1000_hw *hw;
+ struct pci_dev *us_dev;
const struct e1000_info *ei = igb_info_tbl[ent->driver_data];
unsigned long mmio_start, mmio_len;
- static int cards_found;
- int i, err, pci_using_dac;
- u16 eeprom_data = 0;
+ int i, err, pci_using_dac, pos;
+ u16 eeprom_data = 0, state = 0;
u16 eeprom_apme_mask = IGB_EEPROM_APME;
u32 part_num;
+ int bars, need_ioport;
- err = pci_enable_device(pdev);
+ /* do not allocate ioport bars when not needed */
+ need_ioport = igb_is_need_ioport(pdev);
+ if (need_ioport) {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
+ err = pci_enable_device(pdev);
+ } else {
+ bars = pci_select_bars(pdev, IORESOURCE_MEM);
+ err = pci_enable_device_mem(pdev);
+ }
if (err)
return err;
}
}
- err = pci_request_regions(pdev, igb_driver_name);
+ /* 82575 requires that the pci-e link partner disable the L0s state */
+ switch (pdev->device) {
+ case E1000_DEV_ID_82575EB_COPPER:
+ case E1000_DEV_ID_82575EB_FIBER_SERDES:
+ case E1000_DEV_ID_82575GB_QUAD_COPPER:
+ us_dev = pdev->bus->self;
+ pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
+ if (pos) {
+ pci_read_config_word(us_dev, pos + PCI_EXP_LNKCTL,
+ &state);
+ state &= ~PCIE_LINK_STATE_L0S;
+ pci_write_config_word(us_dev, pos + PCI_EXP_LNKCTL,
+ state);
+ dev_info(&pdev->dev,
+ "Disabling ASPM L0s upstream switch port %s\n",
+ pci_name(us_dev));
+ }
+ default:
+ break;
+ }
+
+ err = pci_request_selected_regions(pdev, bars, igb_driver_name);
if (err)
goto err_pci_reg;
+ err = pci_enable_pcie_error_reporting(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_enable_pcie_error_reporting failed "
+ "0x%x\n", err);
+ /* non-fatal, continue */
+ }
+
pci_set_master(pdev);
pci_save_state(pdev);
err = -ENOMEM;
- netdev = alloc_etherdev(sizeof(struct igb_adapter));
+ netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
if (!netdev)
goto err_alloc_etherdev;
hw = &adapter->hw;
hw->back = adapter;
adapter->msg_enable = NETIF_MSG_DRV | NETIF_MSG_PROBE;
+ adapter->bars = bars;
+ adapter->need_ioport = need_ioport;
mmio_start = pci_resource_start(pdev, 0);
mmio_len = pci_resource_len(pdev, 0);
if (!adapter->hw.hw_addr)
goto err_ioremap;
- netdev->open = &igb_open;
- netdev->stop = &igb_close;
- netdev->get_stats = &igb_get_stats;
- netdev->set_multicast_list = &igb_set_multi;
- netdev->set_mac_address = &igb_set_mac;
- netdev->change_mtu = &igb_change_mtu;
- netdev->do_ioctl = &igb_ioctl;
+ netdev->netdev_ops = &igb_netdev_ops;
igb_set_ethtool_ops(netdev);
- netdev->tx_timeout = &igb_tx_timeout;
netdev->watchdog_timeo = 5 * HZ;
- netif_napi_add(netdev, &adapter->napi, igb_clean, 64);
- netdev->vlan_rx_register = igb_vlan_rx_register;
- netdev->vlan_rx_add_vid = igb_vlan_rx_add_vid;
- netdev->vlan_rx_kill_vid = igb_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
- netdev->poll_controller = igb_netpoll;
-#endif
- netdev->hard_start_xmit = &igb_xmit_frame_adv;
strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
netdev->mem_start = mmio_start;
netdev->mem_end = mmio_start + mmio_len;
- adapter->bd_number = cards_found;
-
/* PCI config space info */
hw->vendor_id = pdev->vendor;
hw->device_id = pdev->device;
igb_get_bus_info_pcie(hw);
+ /* set flags */
+ switch (hw->mac.type) {
+ case e1000_82576:
+ case e1000_82575:
+ adapter->flags |= IGB_FLAG_HAS_DCA;
+ adapter->flags |= IGB_FLAG_NEED_CTX_IDX;
+ break;
+ default:
+ break;
+ }
+
hw->phy.autoneg_wait_to_complete = false;
hw->mac.adaptive_ifs = true;
netdev->features |= NETIF_F_TSO;
netdev->features |= NETIF_F_TSO6;
+#ifdef CONFIG_IGB_LRO
+ netdev->features |= NETIF_F_LRO;
+#endif
+
netdev->vlan_features |= NETIF_F_TSO;
netdev->vlan_features |= NETIF_F_TSO6;
netdev->vlan_features |= NETIF_F_HW_CSUM;
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82575EB_FIBER_SERDES:
+ case E1000_DEV_ID_82576_FIBER:
+ case E1000_DEV_ID_82576_SERDES:
/* Wake events only supported on port A for dual fiber
* regardless of eeprom setting */
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
/* initialize the wol settings based on the eeprom settings */
adapter->wol = adapter->eeprom_wol;
+ device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
/* reset the hardware with the new settings */
igb_reset(adapter);
/* tell the stack to leave us alone until igb_open() is called */
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
+#ifdef CONFIG_IGB_DCA
+ if ((adapter->flags & IGB_FLAG_HAS_DCA) &&
+ (dca_add_requester(&pdev->dev) == 0)) {
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
+ dev_info(&pdev->dev, "DCA enabled\n");
+ /* Always use CB2 mode, difference is masked
+ * in the CB driver. */
+ wr32(E1000_DCA_CTRL, 2);
+ igb_setup_dca(adapter);
+ }
+#endif
+
dev_info(&pdev->dev, "Intel(R) Gigabit Ethernet Network Connection\n");
/* print bus type/speed/width info */
- dev_info(&pdev->dev,
- "%s: (PCIe:%s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+ dev_info(&pdev->dev, "%s: (PCIe:%s:%s) %pM\n",
netdev->name,
((hw->bus.speed == e1000_bus_speed_2500)
? "2.5Gb/s" : "unknown"),
((hw->bus.width == e1000_bus_width_pcie_x4)
? "Width x4" : (hw->bus.width == e1000_bus_width_pcie_x1)
? "Width x1" : "unknown"),
- netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
- netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+ netdev->dev_addr);
igb_read_part_num(hw, &part_num);
dev_info(&pdev->dev, "%s: PBA No: %06x-%03x\n", netdev->name,
dev_info(&pdev->dev,
"Using %s interrupts. %d rx queue(s), %d tx queue(s)\n",
adapter->msix_entries ? "MSI-X" :
- adapter->msi_enabled ? "MSI" : "legacy",
+ (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
adapter->num_rx_queues, adapter->num_tx_queues);
- cards_found++;
return 0;
err_register:
igb_release_hw_control(adapter);
err_eeprom:
if (!igb_check_reset_block(hw))
- hw->phy.ops.reset_phy(hw);
+ igb_reset_phy(hw);
if (hw->flash_address)
iounmap(hw->flash_address);
igb_remove_device(hw);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ igb_free_queues(adapter);
err_sw_init:
err_hw_init:
iounmap(hw->hw_addr);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, bars);
err_pci_reg:
err_dma:
pci_disable_device(pdev);
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_IGB_DCA
+ struct e1000_hw *hw = &adapter->hw;
+#endif
+ int err;
/* flush_scheduled work may reschedule our watchdog task, so
* explicitly disable watchdog tasks from being rescheduled */
flush_scheduled_work();
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+ dev_info(&pdev->dev, "DCA disabled\n");
+ dca_remove_requester(&pdev->dev);
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+ wr32(E1000_DCA_CTRL, 1);
+ }
+#endif
+
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
igb_release_hw_control(adapter);
unregister_netdev(netdev);
if (!igb_check_reset_block(&adapter->hw))
- adapter->hw.phy.ops.reset_phy(&adapter->hw);
+ igb_reset_phy(&adapter->hw);
igb_remove_device(&adapter->hw);
igb_reset_interrupt_capability(adapter);
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
+ igb_free_queues(adapter);
iounmap(adapter->hw.hw_addr);
if (adapter->hw.flash_address)
iounmap(adapter->hw.flash_address);
- pci_release_regions(pdev);
+ pci_release_selected_regions(pdev, adapter->bars);
free_netdev(netdev);
+ err = pci_disable_pcie_error_reporting(pdev);
+ if (err)
+ dev_err(&pdev->dev,
+ "pci_disable_pcie_error_reporting failed 0x%x\n", err);
+
pci_disable_device(pdev);
}
pci_read_config_word(pdev, PCI_COMMAND, &hw->bus.pci_cmd_word);
+ adapter->tx_ring_count = IGB_DEFAULT_TXD;
+ adapter->rx_ring_count = IGB_DEFAULT_RXD;
adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
adapter->rx_ps_hdr_size = 0; /* disable packet split */
adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
/* Number of supported queues. */
/* Having more queues than CPUs doesn't make sense. */
- adapter->num_tx_queues = 1;
- adapter->num_rx_queues = min(IGB_MAX_RX_QUEUES, num_online_cpus());
+ adapter->num_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus());
+ adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus());
+ /* This call may decrease the number of queues depending on
+ * interrupt mode. */
igb_set_interrupt_capability(adapter);
if (igb_alloc_queues(adapter)) {
/* From here on the code is the same as igb_up() */
clear_bit(__IGB_DOWN, &adapter->state);
- napi_enable(&adapter->napi);
- if (adapter->msix_entries)
- for (i = 0; i < adapter->num_rx_queues; i++)
- napi_enable(&adapter->rx_ring[i].napi);
-
- igb_irq_enable(adapter);
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ napi_enable(&adapter->rx_ring[i].napi);
/* Clear any pending interrupts. */
rd32(E1000_ICR);
+
+ igb_irq_enable(adapter);
+
+ netif_tx_start_all_queues(netdev);
+
/* Fire a link status change interrupt to start the watchdog. */
wr32(E1000_ICS, E1000_ICS_LSC);
memset(tx_ring->buffer_info, 0, size);
/* round up to nearest 4K */
- tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc)
- + sizeof(u32);
+ tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
tx_ring->size = ALIGN(tx_ring->size, 4096);
tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
tx_ring->adapter = adapter;
tx_ring->next_to_use = 0;
tx_ring->next_to_clean = 0;
- spin_lock_init(&tx_ring->tx_clean_lock);
- spin_lock_init(&tx_ring->tx_lock);
return 0;
err:
static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
{
int i, err = 0;
+ int r_idx;
for (i = 0; i < adapter->num_tx_queues; i++) {
err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
dev_err(&adapter->pdev->dev,
"Allocation for Tx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_tx_resources(adapter,
- &adapter->tx_ring[i]);
+ igb_free_tx_resources(&adapter->tx_ring[i]);
break;
}
}
+ for (i = 0; i < IGB_MAX_TX_QUEUES; i++) {
+ r_idx = i % adapter->num_tx_queues;
+ adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
+ }
return err;
}
**/
static void igb_configure_tx(struct igb_adapter *adapter)
{
- u64 tdba, tdwba;
+ u64 tdba;
struct e1000_hw *hw = &adapter->hw;
u32 tctl;
u32 txdctl, txctrl;
- int i;
+ int i, j;
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *ring = &(adapter->tx_ring[i]);
-
- wr32(E1000_TDLEN(i),
+ j = ring->reg_idx;
+ wr32(E1000_TDLEN(j),
ring->count * sizeof(struct e1000_tx_desc));
tdba = ring->dma;
- wr32(E1000_TDBAL(i),
+ wr32(E1000_TDBAL(j),
tdba & 0x00000000ffffffffULL);
- wr32(E1000_TDBAH(i), tdba >> 32);
+ wr32(E1000_TDBAH(j), tdba >> 32);
- tdwba = ring->dma + ring->count * sizeof(struct e1000_tx_desc);
- tdwba |= 1; /* enable head wb */
- wr32(E1000_TDWBAL(i),
- tdwba & 0x00000000ffffffffULL);
- wr32(E1000_TDWBAH(i), tdwba >> 32);
-
- ring->head = E1000_TDH(i);
- ring->tail = E1000_TDT(i);
+ ring->head = E1000_TDH(j);
+ ring->tail = E1000_TDT(j);
writel(0, hw->hw_addr + ring->tail);
writel(0, hw->hw_addr + ring->head);
- txdctl = rd32(E1000_TXDCTL(i));
+ txdctl = rd32(E1000_TXDCTL(j));
txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
- wr32(E1000_TXDCTL(i), txdctl);
+ wr32(E1000_TXDCTL(j), txdctl);
/* Turn off Relaxed Ordering on head write-backs. The
* writebacks MUST be delivered in order or it will
* completely screw up our bookeeping.
*/
- txctrl = rd32(E1000_DCA_TXCTRL(i));
+ txctrl = rd32(E1000_DCA_TXCTRL(j));
txctrl &= ~E1000_DCA_TXCTRL_TX_WB_RO_EN;
- wr32(E1000_DCA_TXCTRL(i), txctrl);
+ wr32(E1000_DCA_TXCTRL(j), txctrl);
}
struct pci_dev *pdev = adapter->pdev;
int size, desc_len;
+#ifdef CONFIG_IGB_LRO
+ size = sizeof(struct net_lro_desc) * MAX_LRO_DESCRIPTORS;
+ rx_ring->lro_mgr.lro_arr = vmalloc(size);
+ if (!rx_ring->lro_mgr.lro_arr)
+ goto err;
+ memset(rx_ring->lro_mgr.lro_arr, 0, size);
+#endif
+
size = sizeof(struct igb_buffer) * rx_ring->count;
rx_ring->buffer_info = vmalloc(size);
if (!rx_ring->buffer_info)
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
- rx_ring->pending_skb = NULL;
rx_ring->adapter = adapter;
- /* FIXME: do we want to setup ring->napi->poll here? */
- rx_ring->napi.poll = adapter->napi.poll;
return 0;
err:
+#ifdef CONFIG_IGB_LRO
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
+#endif
vfree(rx_ring->buffer_info);
dev_err(&adapter->pdev->dev, "Unable to allocate memory for "
"the receive descriptor ring\n");
dev_err(&adapter->pdev->dev,
"Allocation for Rx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_rx_resources(adapter,
- &adapter->rx_ring[i]);
+ igb_free_rx_resources(&adapter->rx_ring[i]);
break;
}
}
struct e1000_hw *hw = &adapter->hw;
u32 rctl;
u32 srrctl = 0;
- int i;
+ int i, j;
rctl = rd32(E1000_RCTL);
rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
+ rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
- rctl |= E1000_RCTL_EN | E1000_RCTL_BAM |
- E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
+ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_RDMTS_HALF |
(adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
- /* disable the stripping of CRC because it breaks
- * BMC firmware connected over SMBUS
- rctl |= E1000_RCTL_SECRC;
+ /*
+ * enable stripping of CRC. It's unlikely this will break BMC
+ * redirection as it did with e1000. Newer features require
+ * that the HW strips the CRC.
*/
+ rctl |= E1000_RCTL_SECRC;
- rctl &= ~E1000_RCTL_SBP;
+ /*
+ * disable store bad packets, long packet enable, and clear size bits.
+ */
+ rctl &= ~(E1000_RCTL_SBP | E1000_RCTL_LPE | E1000_RCTL_SZ_256);
- if (adapter->netdev->mtu <= ETH_DATA_LEN)
- rctl &= ~E1000_RCTL_LPE;
- else
+ if (adapter->netdev->mtu > ETH_DATA_LEN)
rctl |= E1000_RCTL_LPE;
- if (adapter->rx_buffer_len <= IGB_RXBUFFER_2048) {
- /* Setup buffer sizes */
- rctl &= ~E1000_RCTL_SZ_4096;
- rctl |= E1000_RCTL_BSEX;
- switch (adapter->rx_buffer_len) {
- case IGB_RXBUFFER_256:
- rctl |= E1000_RCTL_SZ_256;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case IGB_RXBUFFER_512:
- rctl |= E1000_RCTL_SZ_512;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case IGB_RXBUFFER_1024:
- rctl |= E1000_RCTL_SZ_1024;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case IGB_RXBUFFER_2048:
- default:
- rctl |= E1000_RCTL_SZ_2048;
- rctl &= ~E1000_RCTL_BSEX;
- break;
- case IGB_RXBUFFER_4096:
- rctl |= E1000_RCTL_SZ_4096;
- break;
- case IGB_RXBUFFER_8192:
- rctl |= E1000_RCTL_SZ_8192;
- break;
- case IGB_RXBUFFER_16384:
- rctl |= E1000_RCTL_SZ_16384;
- break;
- }
- } else {
- rctl &= ~E1000_RCTL_BSEX;
- srrctl = adapter->rx_buffer_len >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+
+ /* Setup buffer sizes */
+ switch (adapter->rx_buffer_len) {
+ case IGB_RXBUFFER_256:
+ rctl |= E1000_RCTL_SZ_256;
+ break;
+ case IGB_RXBUFFER_512:
+ rctl |= E1000_RCTL_SZ_512;
+ break;
+ default:
+ srrctl = ALIGN(adapter->rx_buffer_len, 1024)
+ >> E1000_SRRCTL_BSIZEPKT_SHIFT;
+ break;
}
/* 82575 and greater support packet-split where the protocol
* so only enable packet split for jumbo frames */
if (rctl & E1000_RCTL_LPE) {
adapter->rx_ps_hdr_size = IGB_RXBUFFER_128;
- srrctl = adapter->rx_ps_hdr_size <<
+ srrctl |= adapter->rx_ps_hdr_size <<
E1000_SRRCTL_BSIZEHDRSIZE_SHIFT;
- /* buffer size is ALWAYS one page */
- srrctl |= PAGE_SIZE >> E1000_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= E1000_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
} else {
adapter->rx_ps_hdr_size = 0;
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
- for (i = 0; i < adapter->num_rx_queues; i++)
- wr32(E1000_SRRCTL(i), srrctl);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ j = adapter->rx_ring[i].reg_idx;
+ wr32(E1000_SRRCTL(j), srrctl);
+ }
wr32(E1000_RCTL, rctl);
}
struct e1000_hw *hw = &adapter->hw;
u32 rctl, rxcsum;
u32 rxdctl;
- int i;
+ int i, j;
/* disable receives while setting up the descriptors */
rctl = rd32(E1000_RCTL);
mdelay(10);
if (adapter->itr_setting > 3)
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
+ wr32(E1000_ITR, adapter->itr);
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring */
for (i = 0; i < adapter->num_rx_queues; i++) {
struct igb_ring *ring = &(adapter->rx_ring[i]);
+ j = ring->reg_idx;
rdba = ring->dma;
- wr32(E1000_RDBAL(i),
+ wr32(E1000_RDBAL(j),
rdba & 0x00000000ffffffffULL);
- wr32(E1000_RDBAH(i), rdba >> 32);
- wr32(E1000_RDLEN(i),
+ wr32(E1000_RDBAH(j), rdba >> 32);
+ wr32(E1000_RDLEN(j),
ring->count * sizeof(union e1000_adv_rx_desc));
- ring->head = E1000_RDH(i);
- ring->tail = E1000_RDT(i);
+ ring->head = E1000_RDH(j);
+ ring->tail = E1000_RDT(j);
writel(0, hw->hw_addr + ring->tail);
writel(0, hw->hw_addr + ring->head);
- rxdctl = rd32(E1000_RXDCTL(i));
+ rxdctl = rd32(E1000_RXDCTL(j));
rxdctl |= E1000_RXDCTL_QUEUE_ENABLE;
rxdctl &= 0xFFF00000;
rxdctl |= IGB_RX_PTHRESH;
rxdctl |= IGB_RX_HTHRESH << 8;
rxdctl |= IGB_RX_WTHRESH << 16;
- wr32(E1000_RXDCTL(i), rxdctl);
+ wr32(E1000_RXDCTL(j), rxdctl);
+#ifdef CONFIG_IGB_LRO
+ /* Intitial LRO Settings */
+ ring->lro_mgr.max_aggr = MAX_LRO_AGGR;
+ ring->lro_mgr.max_desc = MAX_LRO_DESCRIPTORS;
+ ring->lro_mgr.get_skb_header = igb_get_skb_hdr;
+ ring->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
+ ring->lro_mgr.dev = adapter->netdev;
+ ring->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY;
+ ring->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
+#endif
}
if (adapter->num_rx_queues > 1) {
get_random_bytes(&random[0], 40);
- shift = 6;
+ if (hw->mac.type >= e1000_82576)
+ shift = 0;
+ else
+ shift = 6;
for (j = 0; j < (32 * 4); j++) {
reta.bytes[j & 3] =
- (j % adapter->num_rx_queues) << shift;
+ adapter->rx_ring[(j % adapter->num_rx_queues)].reg_idx << shift;
if ((j & 3) == 3)
writel(reta.dword,
hw->hw_addr + E1000_RETA(0) + (j & ~3));
/**
* igb_free_tx_resources - Free Tx Resources per Queue
- * @adapter: board private structure
* @tx_ring: Tx descriptor ring for a specific queue
*
* Free all transmit software resources
**/
-static void igb_free_tx_resources(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+void igb_free_tx_resources(struct igb_ring *tx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = tx_ring->adapter->pdev;
- igb_clean_tx_ring(adapter, tx_ring);
+ igb_clean_tx_ring(tx_ring);
vfree(tx_ring->buffer_info);
tx_ring->buffer_info = NULL;
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(adapter, &adapter->tx_ring[i]);
+ igb_free_tx_resources(&adapter->tx_ring[i]);
}
static void igb_unmap_and_free_tx_resource(struct igb_adapter *adapter,
/**
* igb_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
* @tx_ring: ring to be cleaned
**/
-static void igb_clean_tx_ring(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+static void igb_clean_tx_ring(struct igb_ring *tx_ring)
{
+ struct igb_adapter *adapter = tx_ring->adapter;
struct igb_buffer *buffer_info;
unsigned long size;
unsigned int i;
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_ring(adapter, &adapter->tx_ring[i]);
+ igb_clean_tx_ring(&adapter->tx_ring[i]);
}
/**
* igb_free_rx_resources - Free Rx Resources
- * @adapter: board private structure
* @rx_ring: ring to clean the resources from
*
* Free all receive software resources
**/
-static void igb_free_rx_resources(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+void igb_free_rx_resources(struct igb_ring *rx_ring)
{
- struct pci_dev *pdev = adapter->pdev;
+ struct pci_dev *pdev = rx_ring->adapter->pdev;
- igb_clean_rx_ring(adapter, rx_ring);
+ igb_clean_rx_ring(rx_ring);
vfree(rx_ring->buffer_info);
rx_ring->buffer_info = NULL;
+#ifdef CONFIG_IGB_LRO
+ vfree(rx_ring->lro_mgr.lro_arr);
+ rx_ring->lro_mgr.lro_arr = NULL;
+#endif
+
pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
rx_ring->desc = NULL;
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(adapter, &adapter->rx_ring[i]);
+ igb_free_rx_resources(&adapter->rx_ring[i]);
}
/**
* igb_clean_rx_ring - Free Rx Buffers per Queue
- * @adapter: board private structure
* @rx_ring: ring to free buffers from
**/
-static void igb_clean_rx_ring(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+static void igb_clean_rx_ring(struct igb_ring *rx_ring)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct igb_buffer *buffer_info;
struct pci_dev *pdev = adapter->pdev;
unsigned long size;
buffer_info->skb = NULL;
}
if (buffer_info->page) {
- pci_unmap_page(pdev, buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ if (buffer_info->page_dma)
+ pci_unmap_page(pdev, buffer_info->page_dma,
+ PAGE_SIZE / 2,
+ PCI_DMA_FROMDEVICE);
put_page(buffer_info->page);
buffer_info->page = NULL;
buffer_info->page_dma = 0;
+ buffer_info->page_offset = 0;
}
}
- /* there also may be some cached data from a chained receive */
- if (rx_ring->pending_skb) {
- dev_kfree_skb(rx_ring->pending_skb);
- rx_ring->pending_skb = NULL;
- }
-
size = sizeof(struct igb_buffer) * rx_ring->count;
memset(rx_ring->buffer_info, 0, size);
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_ring(adapter, &adapter->rx_ring[i]);
+ igb_clean_rx_ring(&adapter->rx_ring[i]);
}
/**
rctl = rd32(E1000_RCTL);
- if (netdev->flags & IFF_PROMISC)
+ if (netdev->flags & IFF_PROMISC) {
rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
- else if (netdev->flags & IFF_ALLMULTI) {
- rctl |= E1000_RCTL_MPE;
- rctl &= ~E1000_RCTL_UPE;
- } else
- rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
-
+ rctl &= ~E1000_RCTL_VFE;
+ } else {
+ if (netdev->flags & IFF_ALLMULTI) {
+ rctl |= E1000_RCTL_MPE;
+ rctl &= ~E1000_RCTL_UPE;
+ } else
+ rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
+ rctl |= E1000_RCTL_VFE;
+ }
wr32(E1000_RCTL, rctl);
if (!netdev->mc_count) {
/* nothing to program, so clear mc list */
- igb_update_mc_addr_list(hw, NULL, 0, 1,
+ igb_update_mc_addr_list_82575(hw, NULL, 0, 1,
mac->rar_entry_count);
return;
}
memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
mc_ptr = mc_ptr->next;
}
- igb_update_mc_addr_list(hw, mta_list, i, 1, mac->rar_entry_count);
+ igb_update_mc_addr_list_82575(hw, mta_list, i, 1,
+ mac->rar_entry_count);
kfree(mta_list);
}
static void igb_update_phy_info(unsigned long data)
{
struct igb_adapter *adapter = (struct igb_adapter *) data;
- if (adapter->hw.phy.ops.get_phy_info)
- adapter->hw.phy.ops.get_phy_info(&adapter->hw);
+ igb_get_phy_info(&adapter->hw);
}
/**
struct igb_ring *tx_ring = adapter->tx_ring;
struct e1000_mac_info *mac = &adapter->hw.mac;
u32 link;
+ u32 eics = 0;
s32 ret_val;
+ int i;
if ((netif_carrier_ok(netdev)) &&
(rd32(E1000_STATUS) & E1000_STATUS_LU))
&adapter->link_duplex);
ctrl = rd32(E1000_CTRL);
- dev_info(&adapter->pdev->dev,
- "NIC Link is Up %d Mbps %s, "
+ /* Links status message must follow this format */
+ printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s, "
"Flow Control: %s\n",
+ netdev->name,
adapter->link_speed,
adapter->link_duplex == FULL_DUPLEX ?
"Full Duplex" : "Half Duplex",
}
netif_carrier_on(netdev);
- netif_wake_queue(netdev);
+ netif_tx_wake_all_queues(netdev);
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
if (netif_carrier_ok(netdev)) {
adapter->link_speed = 0;
adapter->link_duplex = 0;
- dev_info(&adapter->pdev->dev, "NIC Link is Down\n");
+ /* Links status message must follow this format */
+ printk(KERN_INFO "igb: %s NIC Link is Down\n",
+ netdev->name);
netif_carrier_off(netdev);
- netif_stop_queue(netdev);
+ netif_tx_stop_all_queues(netdev);
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->phy_info_timer,
round_jiffies(jiffies + 2 * HZ));
}
/* Cause software interrupt to ensure rx ring is cleaned */
- wr32(E1000_ICS, E1000_ICS_RXDMT0);
+ if (adapter->msix_entries) {
+ for (i = 0; i < adapter->num_rx_queues; i++)
+ eics |= adapter->rx_ring[i].eims_value;
+ wr32(E1000_EICS, eics);
+ } else {
+ wr32(E1000_ICS, E1000_ICS_RXDMT0);
+ }
/* Force detection of hung controller every watchdog period */
tx_ring->detect_tx_hung = true;
};
-static void igb_lower_rx_eitr(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
+/**
+ * igb_update_ring_itr - update the dynamic ITR value based on packet size
+ *
+ * Stores a new ITR value based on strictly on packet size. This
+ * algorithm is less sophisticated than that used in igb_update_itr,
+ * due to the difficulty of synchronizing statistics across multiple
+ * receive rings. The divisors and thresholds used by this fuction
+ * were determined based on theoretical maximum wire speed and testing
+ * data, in order to minimize response time while increasing bulk
+ * throughput.
+ * This functionality is controlled by the InterruptThrottleRate module
+ * parameter (see igb_param.c)
+ * NOTE: This function is called only when operating in a multiqueue
+ * receive environment.
+ * @rx_ring: pointer to ring
+ **/
+static void igb_update_ring_itr(struct igb_ring *rx_ring)
{
- struct e1000_hw *hw = &adapter->hw;
- int new_val;
+ int new_val = rx_ring->itr_val;
+ int avg_wire_size = 0;
+ struct igb_adapter *adapter = rx_ring->adapter;
- new_val = rx_ring->itr_val / 2;
- if (new_val < IGB_MIN_DYN_ITR)
- new_val = IGB_MIN_DYN_ITR;
+ if (!rx_ring->total_packets)
+ goto clear_counts; /* no packets, so don't do anything */
- if (new_val != rx_ring->itr_val) {
- rx_ring->itr_val = new_val;
- wr32(rx_ring->itr_register,
- 1000000000 / (new_val * 256));
+ /* For non-gigabit speeds, just fix the interrupt rate at 4000
+ * ints/sec - ITR timer value of 120 ticks.
+ */
+ if (adapter->link_speed != SPEED_1000) {
+ new_val = 120;
+ goto set_itr_val;
}
-}
+ avg_wire_size = rx_ring->total_bytes / rx_ring->total_packets;
-static void igb_raise_rx_eitr(struct igb_adapter *adapter,
- struct igb_ring *rx_ring)
-{
- struct e1000_hw *hw = &adapter->hw;
- int new_val;
+ /* Add 24 bytes to size to account for CRC, preamble, and gap */
+ avg_wire_size += 24;
+
+ /* Don't starve jumbo frames */
+ avg_wire_size = min(avg_wire_size, 3000);
- new_val = rx_ring->itr_val * 2;
- if (new_val > IGB_MAX_DYN_ITR)
- new_val = IGB_MAX_DYN_ITR;
+ /* Give a little boost to mid-size frames */
+ if ((avg_wire_size > 300) && (avg_wire_size < 1200))
+ new_val = avg_wire_size / 3;
+ else
+ new_val = avg_wire_size / 2;
+set_itr_val:
if (new_val != rx_ring->itr_val) {
rx_ring->itr_val = new_val;
- wr32(rx_ring->itr_register,
- 1000000000 / (new_val * 256));
+ rx_ring->set_itr = 1;
}
+clear_counts:
+ rx_ring->total_bytes = 0;
+ rx_ring->total_packets = 0;
}
/**
return retval;
}
-static void igb_set_itr(struct igb_adapter *adapter, u16 itr_register,
- int rx_only)
+static void igb_set_itr(struct igb_adapter *adapter)
{
u16 current_itr;
u32 new_itr = adapter->itr;
adapter->rx_itr,
adapter->rx_ring->total_packets,
adapter->rx_ring->total_bytes);
- /* conservative mode (itr 3) eliminates the lowest_latency setting */
- if (adapter->itr_setting == 3 && adapter->rx_itr == lowest_latency)
- adapter->rx_itr = low_latency;
- if (!rx_only) {
+ if (adapter->rx_ring->buddy) {
adapter->tx_itr = igb_update_itr(adapter,
adapter->tx_itr,
adapter->tx_ring->total_packets,
adapter->tx_ring->total_bytes);
- /* conservative mode (itr 3) eliminates the
- * lowest_latency setting */
- if (adapter->itr_setting == 3 &&
- adapter->tx_itr == lowest_latency)
- adapter->tx_itr = low_latency;
current_itr = max(adapter->rx_itr, adapter->tx_itr);
} else {
current_itr = adapter->rx_itr;
}
+ /* conservative mode (itr 3) eliminates the lowest_latency setting */
+ if (adapter->itr_setting == 3 &&
+ current_itr == lowest_latency)
+ current_itr = low_latency;
+
switch (current_itr) {
/* counts and packets in update_itr are dependent on these numbers */
case lowest_latency:
}
set_itr_now:
+ adapter->rx_ring->total_bytes = 0;
+ adapter->rx_ring->total_packets = 0;
+ if (adapter->rx_ring->buddy) {
+ adapter->rx_ring->buddy->total_bytes = 0;
+ adapter->rx_ring->buddy->total_packets = 0;
+ }
+
if (new_itr != adapter->itr) {
/* this attempts to bias the interrupt rate towards Bulk
* by adding intermediate steps when interrupt rate is
* ends up being correct.
*/
adapter->itr = new_itr;
- adapter->set_itr = 1;
+ adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+ adapter->rx_ring->set_itr = 1;
}
return;
mss_l4len_idx = (skb_shinfo(skb)->gso_size << E1000_ADVTXD_MSS_SHIFT);
mss_l4len_idx |= (l4len << E1000_ADVTXD_L4LEN_SHIFT);
- /* Context index must be unique per ring. Luckily, so is the interrupt
- * mask value. */
- mss_l4len_idx |= tx_ring->eims_value >> 4;
+ /* Context index must be unique per ring. */
+ if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+ mss_l4len_idx |= tx_ring->queue_index << 4;
context_desc->mss_l4len_idx = cpu_to_le32(mss_l4len_idx);
context_desc->seqnum_seed = 0;
buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
buffer_info->dma = 0;
i++;
if (i == tx_ring->count)
context_desc->type_tucmd_mlhl = cpu_to_le32(tu_cmd);
context_desc->seqnum_seed = 0;
- context_desc->mss_l4len_idx =
- cpu_to_le32(tx_ring->eims_value >> 4);
+ if (adapter->flags & IGB_FLAG_NEED_CTX_IDX)
+ context_desc->mss_l4len_idx =
+ cpu_to_le32(tx_ring->queue_index << 4);
buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
buffer_info->dma = 0;
i++;
#define IGB_MAX_DATA_PER_TXD (1<<IGB_MAX_TXD_PWR)
static inline int igb_tx_map_adv(struct igb_adapter *adapter,
- struct igb_ring *tx_ring,
- struct sk_buff *skb)
+ struct igb_ring *tx_ring, struct sk_buff *skb,
+ unsigned int first)
{
struct igb_buffer *buffer_info;
unsigned int len = skb_headlen(skb);
buffer_info->length = len;
/* set time_stamp *before* dma to help avoid a possible race */
buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
buffer_info->dma = pci_map_single(adapter->pdev, skb->data, len,
PCI_DMA_TODEVICE);
count++;
BUG_ON(len >= IGB_MAX_DATA_PER_TXD);
buffer_info->length = len;
buffer_info->time_stamp = jiffies;
+ buffer_info->next_to_watch = i;
buffer_info->dma = pci_map_page(adapter->pdev,
frag->page,
frag->page_offset,
i = 0;
}
- i = (i == 0) ? tx_ring->count - 1 : i - 1;
+ i = ((i == 0) ? tx_ring->count - 1 : i - 1);
tx_ring->buffer_info[i].skb = skb;
+ tx_ring->buffer_info[first].next_to_watch = i;
return count;
}
olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
}
- if (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
- IGB_TX_FLAGS_VLAN))
- olinfo_status |= tx_ring->eims_value >> 4;
+ if ((adapter->flags & IGB_FLAG_NEED_CTX_IDX) &&
+ (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
+ IGB_TX_FLAGS_VLAN)))
+ olinfo_status |= tx_ring->queue_index << 4;
olinfo_status |= ((paylen - hdr_len) << E1000_ADVTXD_PAYLEN_SHIFT);
{
struct igb_adapter *adapter = netdev_priv(netdev);
- netif_stop_queue(netdev);
+ netif_stop_subqueue(netdev, tx_ring->queue_index);
+
/* Herbert's original patch had:
* smp_mb__after_netif_stop_queue();
* but since that doesn't exist yet, just open code it. */
return -EBUSY;
/* A reprieve! */
- netif_start_queue(netdev);
+ netif_wake_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
return 0;
}
struct igb_ring *tx_ring)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ unsigned int first;
unsigned int tx_flags = 0;
unsigned int len;
- unsigned long irq_flags;
u8 hdr_len = 0;
int tso = 0;
return NETDEV_TX_OK;
}
- if (!spin_trylock_irqsave(&tx_ring->tx_lock, irq_flags))
- /* Collision - tell upper layer to requeue */
- return NETDEV_TX_LOCKED;
-
/* need: 1 descriptor per page,
* + 2 desc gap to keep tail from touching head,
* + 1 desc for skb->data,
* otherwise try next time */
if (igb_maybe_stop_tx(netdev, tx_ring, skb_shinfo(skb)->nr_frags + 4)) {
/* this is a hard error */
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_BUSY;
}
+ skb_orphan(skb);
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
tx_flags |= (vlan_tx_tag_get(skb) << IGB_TX_FLAGS_VLAN_SHIFT);
}
+ if (skb->protocol == htons(ETH_P_IP))
+ tx_flags |= IGB_TX_FLAGS_IPV4;
+
+ first = tx_ring->next_to_use;
+
tso = skb_is_gso(skb) ? igb_tso_adv(adapter, tx_ring, skb, tx_flags,
&hdr_len) : 0;
if (tso < 0) {
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_OK;
}
if (skb->ip_summed == CHECKSUM_PARTIAL)
tx_flags |= IGB_TX_FLAGS_CSUM;
- if (skb->protocol == htons(ETH_P_IP))
- tx_flags |= IGB_TX_FLAGS_IPV4;
-
igb_tx_queue_adv(adapter, tx_ring, tx_flags,
- igb_tx_map_adv(adapter, tx_ring, skb),
+ igb_tx_map_adv(adapter, tx_ring, skb, first),
skb->len, hdr_len);
netdev->trans_start = jiffies;
/* Make sure there is space in the ring for the next send. */
igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
- spin_unlock_irqrestore(&tx_ring->tx_lock, irq_flags);
return NETDEV_TX_OK;
}
static int igb_xmit_frame_adv(struct sk_buff *skb, struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- struct igb_ring *tx_ring = &adapter->tx_ring[0];
+ struct igb_ring *tx_ring;
+
+ int r_idx = 0;
+ r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
+ tx_ring = adapter->multi_tx_table[r_idx];
/* This goes back to the question of how to logically map a tx queue
* to a flow. Right now, performance is impacted slightly negatively
else if (max_frame <= IGB_RXBUFFER_2048)
adapter->rx_buffer_len = IGB_RXBUFFER_2048;
else
- adapter->rx_buffer_len = IGB_RXBUFFER_4096;
+#if (PAGE_SIZE / 2) > IGB_RXBUFFER_16384
+ adapter->rx_buffer_len = IGB_RXBUFFER_16384;
+#else
+ adapter->rx_buffer_len = PAGE_SIZE / 2;
+#endif
/* adjust allocation if LPE protects us, and we aren't using SBP */
if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
(max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))
/* Phy Stats */
if (hw->phy.media_type == e1000_media_type_copper) {
if ((adapter->link_speed == SPEED_1000) &&
- (!hw->phy.ops.read_phy_reg(hw, PHY_1000T_STATUS,
+ (!igb_read_phy_reg(hw, PHY_1000T_STATUS,
&phy_tmp))) {
phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
adapter->phy_stats.idle_errors += phy_tmp;
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 eicr;
- /* disable interrupts from the "other" bit, avoid re-entry */
- wr32(E1000_EIMC, E1000_EIMS_OTHER);
-
- eicr = rd32(E1000_EICR);
-
- if (eicr & E1000_EIMS_OTHER) {
- u32 icr = rd32(E1000_ICR);
- /* reading ICR causes bit 31 of EICR to be cleared */
- if (!(icr & E1000_ICR_LSC))
- goto no_link_interrupt;
- hw->mac.get_link_status = 1;
- /* guard against interrupt when we're going down */
- if (!test_bit(__IGB_DOWN, &adapter->state))
- mod_timer(&adapter->watchdog_timer, jiffies + 1);
- }
+ u32 icr = rd32(E1000_ICR);
+ /* reading ICR causes bit 31 of EICR to be cleared */
+ if (!(icr & E1000_ICR_LSC))
+ goto no_link_interrupt;
+ hw->mac.get_link_status = 1;
+ /* guard against interrupt when we're going down */
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ mod_timer(&adapter->watchdog_timer, jiffies + 1);
+
no_link_interrupt:
wr32(E1000_IMS, E1000_IMS_LSC);
- wr32(E1000_EIMS, E1000_EIMS_OTHER);
+ wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED;
}
struct igb_adapter *adapter = tx_ring->adapter;
struct e1000_hw *hw = &adapter->hw;
- if (!tx_ring->itr_val)
- wr32(E1000_EIMC, tx_ring->eims_value);
-
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(tx_ring);
+#endif
tx_ring->total_bytes = 0;
tx_ring->total_packets = 0;
- if (!igb_clean_tx_irq(adapter, tx_ring))
+
+ /* auto mask will automatically reenable the interrupt when we write
+ * EICS */
+ if (!igb_clean_tx_irq(tx_ring))
/* Ring was not completely cleaned, so fire another interrupt */
wr32(E1000_EICS, tx_ring->eims_value);
-
- if (!tx_ring->itr_val)
+ else
wr32(E1000_EIMS, tx_ring->eims_value);
+
return IRQ_HANDLED;
}
+static void igb_write_itr(struct igb_ring *ring)
+{
+ struct e1000_hw *hw = &ring->adapter->hw;
+ if ((ring->adapter->itr_setting & 3) && ring->set_itr) {
+ switch (hw->mac.type) {
+ case e1000_82576:
+ wr32(ring->itr_register,
+ ring->itr_val |
+ 0x80000000);
+ break;
+ default:
+ wr32(ring->itr_register,
+ ring->itr_val |
+ (ring->itr_val << 16));
+ break;
+ }
+ ring->set_itr = 0;
+ }
+}
+
static irqreturn_t igb_msix_rx(int irq, void *data)
{
struct igb_ring *rx_ring = data;
struct igb_adapter *adapter = rx_ring->adapter;
- struct e1000_hw *hw = &adapter->hw;
- if (!rx_ring->itr_val)
- wr32(E1000_EIMC, rx_ring->eims_value);
+ /* Write the ITR value calculated at the end of the
+ * previous interrupt.
+ */
+
+ igb_write_itr(rx_ring);
- if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi)) {
- rx_ring->total_bytes = 0;
- rx_ring->total_packets = 0;
- rx_ring->no_itr_adjust = 0;
- __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
- } else {
- if (!rx_ring->no_itr_adjust) {
- igb_lower_rx_eitr(adapter, rx_ring);
- rx_ring->no_itr_adjust = 1;
+ if (netif_rx_schedule_prep(&rx_ring->napi))
+ __netif_rx_schedule(&rx_ring->napi);
+
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
+#endif
+ return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_IGB_DCA
+static void igb_update_rx_dca(struct igb_ring *rx_ring)
+{
+ u32 dca_rxctrl;
+ struct igb_adapter *adapter = rx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ int cpu = get_cpu();
+ int q = rx_ring->reg_idx;
+
+ if (rx_ring->cpu != cpu) {
+ dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
+ if (hw->mac.type == e1000_82576) {
+ dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK_82576;
+ dca_rxctrl |= dca_get_tag(cpu) <<
+ E1000_DCA_RXCTRL_CPUID_SHIFT;
+ } else {
+ dca_rxctrl &= ~E1000_DCA_RXCTRL_CPUID_MASK;
+ dca_rxctrl |= dca_get_tag(cpu);
}
+ dca_rxctrl |= E1000_DCA_RXCTRL_DESC_DCA_EN;
+ dca_rxctrl |= E1000_DCA_RXCTRL_HEAD_DCA_EN;
+ dca_rxctrl |= E1000_DCA_RXCTRL_DATA_DCA_EN;
+ wr32(E1000_DCA_RXCTRL(q), dca_rxctrl);
+ rx_ring->cpu = cpu;
}
+ put_cpu();
+}
- return IRQ_HANDLED;
+static void igb_update_tx_dca(struct igb_ring *tx_ring)
+{
+ u32 dca_txctrl;
+ struct igb_adapter *adapter = tx_ring->adapter;
+ struct e1000_hw *hw = &adapter->hw;
+ int cpu = get_cpu();
+ int q = tx_ring->reg_idx;
+
+ if (tx_ring->cpu != cpu) {
+ dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
+ if (hw->mac.type == e1000_82576) {
+ dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK_82576;
+ dca_txctrl |= dca_get_tag(cpu) <<
+ E1000_DCA_TXCTRL_CPUID_SHIFT;
+ } else {
+ dca_txctrl &= ~E1000_DCA_TXCTRL_CPUID_MASK;
+ dca_txctrl |= dca_get_tag(cpu);
+ }
+ dca_txctrl |= E1000_DCA_TXCTRL_DESC_DCA_EN;
+ wr32(E1000_DCA_TXCTRL(q), dca_txctrl);
+ tx_ring->cpu = cpu;
+ }
+ put_cpu();
}
+static void igb_setup_dca(struct igb_adapter *adapter)
+{
+ int i;
+
+ if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
+ return;
+
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ adapter->tx_ring[i].cpu = -1;
+ igb_update_tx_dca(&adapter->tx_ring[i]);
+ }
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ adapter->rx_ring[i].cpu = -1;
+ igb_update_rx_dca(&adapter->rx_ring[i]);
+ }
+}
+
+static int __igb_notify_dca(struct device *dev, void *data)
+{
+ struct net_device *netdev = dev_get_drvdata(dev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ unsigned long event = *(unsigned long *)data;
+
+ if (!(adapter->flags & IGB_FLAG_HAS_DCA))
+ goto out;
+
+ switch (event) {
+ case DCA_PROVIDER_ADD:
+ /* if already enabled, don't do it again */
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ break;
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
+ /* Always use CB2 mode, difference is masked
+ * in the CB driver. */
+ wr32(E1000_DCA_CTRL, 2);
+ if (dca_add_requester(dev) == 0) {
+ dev_info(&adapter->pdev->dev, "DCA enabled\n");
+ igb_setup_dca(adapter);
+ break;
+ }
+ /* Fall Through since DCA is disabled. */
+ case DCA_PROVIDER_REMOVE:
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
+ /* without this a class_device is left
+ * hanging around in the sysfs model */
+ dca_remove_requester(dev);
+ dev_info(&adapter->pdev->dev, "DCA disabled\n");
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
+ wr32(E1000_DCA_CTRL, 1);
+ }
+ break;
+ }
+out:
+ return 0;
+}
+
+static int igb_notify_dca(struct notifier_block *nb, unsigned long event,
+ void *p)
+{
+ int ret_val;
+
+ ret_val = driver_for_each_device(&igb_driver.driver, NULL, &event,
+ __igb_notify_dca);
+
+ return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
+}
+#endif /* CONFIG_IGB_DCA */
/**
* igb_intr_msi - Interrupt Handler
{
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
- struct napi_struct *napi = &adapter->napi;
struct e1000_hw *hw = &adapter->hw;
/* read ICR disables interrupts using IAM */
u32 icr = rd32(E1000_ICR);
- /* Write the ITR value calculated at the end of the
- * previous interrupt.
- */
- if (adapter->set_itr) {
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
- adapter->set_itr = 0;
- }
+ igb_write_itr(adapter->rx_ring);
- /* read ICR disables interrupts using IAM */
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
if (!test_bit(__IGB_DOWN, &adapter->state))
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(netdev, napi)) {
- adapter->tx_ring->total_bytes = 0;
- adapter->tx_ring->total_packets = 0;
- adapter->rx_ring->total_bytes = 0;
- adapter->rx_ring->total_packets = 0;
- __netif_rx_schedule(netdev, napi);
- }
+ netif_rx_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
{
struct net_device *netdev = data;
struct igb_adapter *adapter = netdev_priv(netdev);
- struct napi_struct *napi = &adapter->napi;
struct e1000_hw *hw = &adapter->hw;
/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked. No
* need for the IMC write */
if (!icr)
return IRQ_NONE; /* Not our interrupt */
- /* Write the ITR value calculated at the end of the
- * previous interrupt.
- */
- if (adapter->set_itr) {
- wr32(E1000_ITR,
- 1000000000 / (adapter->itr * 256));
- adapter->set_itr = 0;
- }
+ igb_write_itr(adapter->rx_ring);
/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
* not set, then the adapter didn't send an interrupt */
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- if (netif_rx_schedule_prep(netdev, napi)) {
- adapter->tx_ring->total_bytes = 0;
- adapter->rx_ring->total_bytes = 0;
- adapter->tx_ring->total_packets = 0;
- adapter->rx_ring->total_packets = 0;
- __netif_rx_schedule(netdev, napi);
- }
+ netif_rx_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
/**
- * igb_clean - NAPI Rx polling callback
- * @adapter: board private structure
+ * igb_poll - NAPI Rx polling callback
+ * @napi: napi polling structure
+ * @budget: count of how many packets we should handle
**/
-static int igb_clean(struct napi_struct *napi, int budget)
+static int igb_poll(struct napi_struct *napi, int budget)
{
- struct igb_adapter *adapter = container_of(napi, struct igb_adapter,
- napi);
+ struct igb_ring *rx_ring = container_of(napi, struct igb_ring, napi);
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
- int tx_clean_complete = 1, work_done = 0;
- int i;
-
- /* Must NOT use netdev_priv macro here. */
- adapter = netdev->priv;
+ int tx_clean_complete, work_done = 0;
- /* Keep link state information with original netdev */
- if (!netif_carrier_ok(netdev))
- goto quit_polling;
-
- /* igb_clean is called per-cpu. This lock protects tx_ring[i] from
- * being cleaned by multiple cpus simultaneously. A failure obtaining
- * the lock means tx_ring[i] is currently being cleaned anyway. */
- for (i = 0; i < adapter->num_tx_queues; i++) {
- if (spin_trylock(&adapter->tx_ring[i].tx_clean_lock)) {
- tx_clean_complete &= igb_clean_tx_irq(adapter,
- &adapter->tx_ring[i]);
- spin_unlock(&adapter->tx_ring[i].tx_clean_lock);
- }
- }
+ /* this poll routine only supports one tx and one rx queue */
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_tx_dca(&adapter->tx_ring[0]);
+#endif
+ tx_clean_complete = igb_clean_tx_irq(&adapter->tx_ring[0]);
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i], &work_done,
- adapter->rx_ring[i].napi.weight);
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(&adapter->rx_ring[0]);
+#endif
+ igb_clean_rx_irq_adv(&adapter->rx_ring[0], &work_done, budget);
/* If no Tx and not enough Rx work done, exit the polling mode */
if ((tx_clean_complete && (work_done < budget)) ||
!netif_running(netdev)) {
-quit_polling:
if (adapter->itr_setting & 3)
- igb_set_itr(adapter, E1000_ITR, false);
- netif_rx_complete(netdev, napi);
+ igb_set_itr(adapter);
+ netif_rx_complete(napi);
if (!test_bit(__IGB_DOWN, &adapter->state))
igb_irq_enable(adapter);
return 0;
struct net_device *netdev = adapter->netdev;
int work_done = 0;
- /* Keep link state information with original netdev */
- if (!netif_carrier_ok(netdev))
- goto quit_polling;
-
- igb_clean_rx_irq_adv(adapter, rx_ring, &work_done, budget);
+#ifdef CONFIG_IGB_DCA
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
+ igb_update_rx_dca(rx_ring);
+#endif
+ igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
/* If not enough Rx work done, exit the polling mode */
if ((work_done == 0) || !netif_running(netdev)) {
-quit_polling:
- netif_rx_complete(netdev, napi);
-
- wr32(E1000_EIMS, rx_ring->eims_value);
- if ((adapter->itr_setting & 3) && !rx_ring->no_itr_adjust &&
- (rx_ring->total_packets > IGB_DYN_ITR_PACKET_THRESHOLD)) {
- int mean_size = rx_ring->total_bytes /
- rx_ring->total_packets;
- if (mean_size < IGB_DYN_ITR_LENGTH_LOW)
- igb_raise_rx_eitr(adapter, rx_ring);
- else if (mean_size > IGB_DYN_ITR_LENGTH_HIGH)
- igb_lower_rx_eitr(adapter, rx_ring);
+ netif_rx_complete(napi);
+
+ if (adapter->itr_setting & 3) {
+ if (adapter->num_rx_queues == 1)
+ igb_set_itr(adapter);
+ else
+ igb_update_ring_itr(rx_ring);
}
+
+ if (!test_bit(__IGB_DOWN, &adapter->state))
+ wr32(E1000_EIMS, rx_ring->eims_value);
+
return 0;
}
return 1;
}
-static inline u32 get_head(struct igb_ring *tx_ring)
-{
- void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count;
- return le32_to_cpu(*(volatile __le32 *)end);
-}
-
/**
* igb_clean_tx_irq - Reclaim resources after transmit completes
* @adapter: board private structure
* returns true if ring is completely cleaned
**/
-static bool igb_clean_tx_irq(struct igb_adapter *adapter,
- struct igb_ring *tx_ring)
+static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
{
+ struct igb_adapter *adapter = tx_ring->adapter;
struct net_device *netdev = adapter->netdev;
struct e1000_hw *hw = &adapter->hw;
- struct e1000_tx_desc *tx_desc;
struct igb_buffer *buffer_info;
struct sk_buff *skb;
- unsigned int i;
- u32 head, oldhead;
- unsigned int count = 0;
- bool cleaned = false;
- bool retval = true;
+ union e1000_adv_tx_desc *tx_desc, *eop_desc;
unsigned int total_bytes = 0, total_packets = 0;
+ unsigned int i, eop, count = 0;
+ bool cleaned = false;
- rmb();
- head = get_head(tx_ring);
i = tx_ring->next_to_clean;
- while (1) {
- while (i != head) {
- cleaned = true;
- tx_desc = E1000_TX_DESC(*tx_ring, i);
+ eop = tx_ring->buffer_info[i].next_to_watch;
+ eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
+
+ while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+ (count < tx_ring->count)) {
+ for (cleaned = false; !cleaned; count++) {
+ tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
+ cleaned = (i == eop);
skb = buffer_info->skb;
if (skb) {
}
igb_unmap_and_free_tx_resource(adapter, buffer_info);
- tx_desc->upper.data = 0;
+ tx_desc->wb.status = 0;
i++;
if (i == tx_ring->count)
i = 0;
-
- count++;
- if (count == IGB_MAX_TX_CLEAN) {
- retval = false;
- goto done_cleaning;
- }
}
- oldhead = head;
- rmb();
- head = get_head(tx_ring);
- if (head == oldhead)
- goto done_cleaning;
- } /* while (1) */
-
-done_cleaning:
+
+ eop = tx_ring->buffer_info[i].next_to_watch;
+ eop_desc = E1000_TX_DESC_ADV(*tx_ring, eop);
+ }
+
tx_ring->next_to_clean = i;
- if (unlikely(cleaned &&
+ if (unlikely(count &&
netif_carrier_ok(netdev) &&
IGB_DESC_UNUSED(tx_ring) >= IGB_TX_QUEUE_WAKE)) {
/* Make sure that anybody stopping the queue after this
* sees the new next_to_clean.
*/
smp_mb();
- if (netif_queue_stopped(netdev) &&
+ if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!(test_bit(__IGB_DOWN, &adapter->state))) {
- netif_wake_queue(netdev);
+ netif_wake_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
}
}
&& !(rd32(E1000_STATUS) &
E1000_STATUS_TXOFF)) {
- tx_desc = E1000_TX_DESC(*tx_ring, i);
/* detected Tx unit hang */
dev_err(&adapter->pdev->dev,
"Detected Tx Unit Hang\n"
- " Tx Queue <%lu>\n"
+ " Tx Queue <%d>\n"
" TDH <%x>\n"
" TDT <%x>\n"
" next_to_use <%x>\n"
" next_to_clean <%x>\n"
- " head (WB) <%x>\n"
"buffer_info[next_to_clean]\n"
" time_stamp <%lx>\n"
+ " next_to_watch <%x>\n"
" jiffies <%lx>\n"
" desc.status <%x>\n",
- (unsigned long)((tx_ring - adapter->tx_ring) /
- sizeof(struct igb_ring)),
+ tx_ring->queue_index,
readl(adapter->hw.hw_addr + tx_ring->head),
readl(adapter->hw.hw_addr + tx_ring->tail),
tx_ring->next_to_use,
tx_ring->next_to_clean,
- head,
tx_ring->buffer_info[i].time_stamp,
+ eop,
jiffies,
- tx_desc->upper.fields.status);
- netif_stop_queue(netdev);
+ eop_desc->wb.status);
+ netif_stop_subqueue(netdev, tx_ring->queue_index);
}
}
tx_ring->total_bytes += total_bytes;
tx_ring->total_packets += total_packets;
+ tx_ring->tx_stats.bytes += total_bytes;
+ tx_ring->tx_stats.packets += total_packets;
adapter->net_stats.tx_bytes += total_bytes;
adapter->net_stats.tx_packets += total_packets;
- return retval;
+ return (count < tx_ring->count);
}
+#ifdef CONFIG_IGB_LRO
+ /**
+ * igb_get_skb_hdr - helper function for LRO header processing
+ * @skb: pointer to sk_buff to be added to LRO packet
+ * @iphdr: pointer to ip header structure
+ * @tcph: pointer to tcp header structure
+ * @hdr_flags: pointer to header flags
+ * @priv: pointer to the receive descriptor for the current sk_buff
+ **/
+static int igb_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
+ u64 *hdr_flags, void *priv)
+{
+ union e1000_adv_rx_desc *rx_desc = priv;
+ u16 pkt_type = rx_desc->wb.lower.lo_dword.pkt_info &
+ (E1000_RXDADV_PKTTYPE_IPV4 | E1000_RXDADV_PKTTYPE_TCP);
+
+ /* Verify that this is a valid IPv4 TCP packet */
+ if (pkt_type != (E1000_RXDADV_PKTTYPE_IPV4 |
+ E1000_RXDADV_PKTTYPE_TCP))
+ return -1;
+
+ /* Set network headers */
+ skb_reset_network_header(skb);
+ skb_set_transport_header(skb, ip_hdrlen(skb));
+ *iphdr = ip_hdr(skb);
+ *tcph = tcp_hdr(skb);
+ *hdr_flags = LRO_IPV4 | LRO_TCP;
+
+ return 0;
+
+}
+#endif /* CONFIG_IGB_LRO */
/**
* igb_receive_skb - helper function to handle rx indications
- * @adapter: board private structure
+ * @ring: pointer to receive ring receving this packet
* @status: descriptor status field as written by hardware
* @vlan: descriptor vlan field as written by hardware (no le/be conversion)
* @skb: pointer to sk_buff to be indicated to stack
**/
-static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
- struct sk_buff *skb)
+static void igb_receive_skb(struct igb_ring *ring, u8 status,
+ union e1000_adv_rx_desc * rx_desc,
+ struct sk_buff *skb)
{
- if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
- vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
- le16_to_cpu(vlan) &
- E1000_RXD_SPC_VLAN_MASK);
- else
- netif_receive_skb(skb);
+ struct igb_adapter * adapter = ring->adapter;
+ bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
+
+#ifdef CONFIG_IGB_LRO
+ if (adapter->netdev->features & NETIF_F_LRO &&
+ skb->ip_summed == CHECKSUM_UNNECESSARY) {
+ if (vlan_extracted)
+ lro_vlan_hwaccel_receive_skb(&ring->lro_mgr, skb,
+ adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan),
+ rx_desc);
+ else
+ lro_receive_skb(&ring->lro_mgr,skb, rx_desc);
+ ring->lro_used = 1;
+ } else {
+#endif
+ if (vlan_extracted)
+ vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
+ le16_to_cpu(rx_desc->wb.upper.vlan));
+ else
+
+ netif_receive_skb(skb);
+#ifdef CONFIG_IGB_LRO
+ }
+#endif
}
adapter->hw_csum_good++;
}
-static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
- struct igb_ring *rx_ring,
- int *work_done, int budget)
+static bool igb_clean_rx_irq_adv(struct igb_ring *rx_ring,
+ int *work_done, int budget)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc , *next_rxd;
struct igb_buffer *buffer_info , *next_buffer;
struct sk_buff *skb;
- unsigned int i, j;
+ unsigned int i;
u32 length, hlen, staterr;
bool cleaned = false;
int cleaned_count = 0;
cleaned = true;
cleaned_count++;
- if (rx_ring->pending_skb != NULL) {
- skb = rx_ring->pending_skb;
- rx_ring->pending_skb = NULL;
- j = rx_ring->pending_skb_page;
- } else {
- skb = buffer_info->skb;
- prefetch(skb->data - NET_IP_ALIGN);
- buffer_info->skb = NULL;
- if (hlen) {
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_ps_hdr_size +
- NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- skb_put(skb, hlen);
- } else {
- pci_unmap_single(pdev, buffer_info->dma,
- adapter->rx_buffer_len +
- NET_IP_ALIGN,
- PCI_DMA_FROMDEVICE);
- skb_put(skb, length);
- goto send_up;
- }
- j = 0;
+ skb = buffer_info->skb;
+ prefetch(skb->data - NET_IP_ALIGN);
+ buffer_info->skb = NULL;
+ if (!adapter->rx_ps_hdr_size) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_buffer_len +
+ NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, length);
+ goto send_up;
+ }
+
+ if (!skb_shinfo(skb)->nr_frags) {
+ pci_unmap_single(pdev, buffer_info->dma,
+ adapter->rx_ps_hdr_size +
+ NET_IP_ALIGN,
+ PCI_DMA_FROMDEVICE);
+ skb_put(skb, hlen);
}
- while (length) {
+ if (length) {
pci_unmap_page(pdev, buffer_info->page_dma,
- PAGE_SIZE, PCI_DMA_FROMDEVICE);
+ PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
buffer_info->page_dma = 0;
- skb_fill_page_desc(skb, j, buffer_info->page,
- 0, length);
- buffer_info->page = NULL;
+
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags++,
+ buffer_info->page,
+ buffer_info->page_offset,
+ length);
+
+ if ((adapter->rx_buffer_len > (PAGE_SIZE / 2)) ||
+ (page_count(buffer_info->page) != 1))
+ buffer_info->page = NULL;
+ else
+ get_page(buffer_info->page);
skb->len += length;
skb->data_len += length;
- skb->truesize += length;
- rx_desc->wb.upper.status_error = 0;
- if (staterr & E1000_RXD_STAT_EOP)
- break;
- j++;
- cleaned_count++;
- i++;
- if (i == rx_ring->count)
- i = 0;
-
- buffer_info = &rx_ring->buffer_info[i];
- rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
- staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
- length = le16_to_cpu(rx_desc->wb.upper.length);
- if (!(staterr & E1000_RXD_STAT_DD)) {
- rx_ring->pending_skb = skb;
- rx_ring->pending_skb_page = j;
- goto out;
- }
+ skb->truesize += length;
}
send_up:
- pskb_trim(skb, skb->len - 4);
i++;
if (i == rx_ring->count)
i = 0;
prefetch(next_rxd);
next_buffer = &rx_ring->buffer_info[i];
+ if (!(staterr & E1000_RXD_STAT_EOP)) {
+ buffer_info->skb = next_buffer->skb;
+ buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
+ goto next_desc;
+ }
+
if (staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK) {
dev_kfree_skb_irq(skb);
goto next_desc;
}
- rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
total_bytes += skb->len;
total_packets++;
skb->protocol = eth_type_trans(skb, netdev);
- igb_receive_skb(adapter, staterr, rx_desc->wb.upper.vlan, skb);
-
- netdev->last_rx = jiffies;
+ igb_receive_skb(rx_ring, staterr, rx_desc, skb);
next_desc:
rx_desc->wb.upper.status_error = 0;
/* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= IGB_RX_BUFFER_WRITE) {
- igb_alloc_rx_buffers_adv(adapter, rx_ring,
- cleaned_count);
+ igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
cleaned_count = 0;
}
staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
}
-out:
+
rx_ring->next_to_clean = i;
cleaned_count = IGB_DESC_UNUSED(rx_ring);
+#ifdef CONFIG_IGB_LRO
+ if (rx_ring->lro_used) {
+ lro_flush_all(&rx_ring->lro_mgr);
+ rx_ring->lro_used = 0;
+ }
+#endif
+
if (cleaned_count)
- igb_alloc_rx_buffers_adv(adapter, rx_ring, cleaned_count);
+ igb_alloc_rx_buffers_adv(rx_ring, cleaned_count);
rx_ring->total_packets += total_packets;
rx_ring->total_bytes += total_bytes;
* igb_alloc_rx_buffers_adv - Replace used receive buffers; packet split
* @adapter: address of board private structure
**/
-static void igb_alloc_rx_buffers_adv(struct igb_adapter *adapter,
- struct igb_ring *rx_ring,
+static void igb_alloc_rx_buffers_adv(struct igb_ring *rx_ring,
int cleaned_count)
{
+ struct igb_adapter *adapter = rx_ring->adapter;
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
union e1000_adv_rx_desc *rx_desc;
while (cleaned_count--) {
rx_desc = E1000_RX_DESC_ADV(*rx_ring, i);
- if (adapter->rx_ps_hdr_size && !buffer_info->page) {
- buffer_info->page = alloc_page(GFP_ATOMIC);
+ if (adapter->rx_ps_hdr_size && !buffer_info->page_dma) {
if (!buffer_info->page) {
- adapter->alloc_rx_buff_failed++;
- goto no_buffers;
+ buffer_info->page = alloc_page(GFP_ATOMIC);
+ if (!buffer_info->page) {
+ adapter->alloc_rx_buff_failed++;
+ goto no_buffers;
+ }
+ buffer_info->page_offset = 0;
+ } else {
+ buffer_info->page_offset ^= PAGE_SIZE / 2;
}
buffer_info->page_dma =
pci_map_page(pdev,
buffer_info->page,
- 0, PAGE_SIZE,
+ buffer_info->page_offset,
+ PAGE_SIZE / 2,
PCI_DMA_FROMDEVICE);
}
case SIOCGMIIREG:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- if (adapter->hw.phy.ops.read_phy_reg(&adapter->hw,
- data->reg_num
- & 0x1F, &data->val_out))
+ if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+ &data->val_out))
return -EIO;
break;
case SIOCSMIIREG:
/* enable VLAN receive filtering */
rctl = rd32(E1000_RCTL);
- rctl |= E1000_RCTL_VFE;
rctl &= ~E1000_RCTL_CFIEN;
wr32(E1000_RCTL, rctl);
igb_update_mng_vlan(adapter);
ctrl &= ~E1000_CTRL_VME;
wr32(E1000_CTRL, ctrl);
- /* disable VLAN filtering */
- rctl = rd32(E1000_RCTL);
- rctl &= ~E1000_RCTL_VFE;
- wr32(E1000_RCTL, rctl);
if (adapter->mng_vlan_id != (u16)IGB_MNG_VLAN_NONE) {
igb_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
adapter->mng_vlan_id = IGB_MNG_VLAN_NONE;
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
- u32 ctrl, ctrl_ext, rctl, status;
+ u32 ctrl, rctl, status;
u32 wufc = adapter->wol;
#ifdef CONFIG_PM
int retval = 0;
netif_device_detach(netdev);
- if (netif_running(netdev)) {
- WARN_ON(test_bit(__IGB_RESETTING, &adapter->state));
- igb_down(adapter);
- igb_free_irq(adapter);
- }
+ if (netif_running(netdev))
+ igb_close(netdev);
+
+ igb_reset_interrupt_capability(adapter);
+
+ igb_free_queues(adapter);
#ifdef CONFIG_PM
retval = pci_save_state(pdev);
ctrl |= E1000_CTRL_ADVD3WUC;
wr32(E1000_CTRL, ctrl);
- if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
- adapter->hw.phy.media_type ==
- e1000_media_type_internal_serdes) {
- /* keep the laser running in D3 */
- ctrl_ext = rd32(E1000_CTRL_EXT);
- ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
- wr32(E1000_CTRL_EXT, ctrl_ext);
- }
-
/* Allow time for pending master requests to run */
igb_disable_pcie_master(&adapter->hw);
wr32(E1000_WUC, E1000_WUC_PME_EN);
wr32(E1000_WUFC, wufc);
- pci_enable_wake(pdev, PCI_D3hot, 1);
- pci_enable_wake(pdev, PCI_D3cold, 1);
} else {
wr32(E1000_WUC, 0);
wr32(E1000_WUFC, 0);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
}
- /* make sure adapter isn't asleep if manageability is enabled */
- if (adapter->en_mng_pt) {
+ /* make sure adapter isn't asleep if manageability/wol is enabled */
+ if (wufc || adapter->en_mng_pt) {
pci_enable_wake(pdev, PCI_D3hot, 1);
pci_enable_wake(pdev, PCI_D3cold, 1);
+ } else {
+ igb_shutdown_fiber_serdes_link_82575(hw);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
}
/* Release control of h/w to f/w. If f/w is AMT enabled, this
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
- err = pci_enable_device(pdev);
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
if (err) {
dev_err(&pdev->dev,
"igb: Cannot enable PCI device from suspend\n");
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
- if (netif_running(netdev)) {
- err = igb_request_irq(adapter);
- if (err)
- return err;
+ igb_set_interrupt_capability(adapter);
+
+ if (igb_alloc_queues(adapter)) {
+ dev_err(&pdev->dev, "Unable to allocate memory for queues\n");
+ return -ENOMEM;
}
/* e1000_power_up_phy(adapter); */
igb_reset(adapter);
wr32(E1000_WUS, ~0);
- igb_init_manageability(adapter);
-
- if (netif_running(netdev))
- igb_up(adapter);
+ if (netif_running(netdev)) {
+ err = igb_open(netdev);
+ if (err)
+ return err;
+ }
netif_device_attach(netdev);
int work_done = 0;
igb_irq_disable(adapter);
+ adapter->flags |= IGB_FLAG_IN_NETPOLL;
+
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+ igb_clean_tx_irq(&adapter->tx_ring[i]);
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_irq_adv(adapter, &adapter->rx_ring[i],
+ igb_clean_rx_irq_adv(&adapter->rx_ring[i],
&work_done,
adapter->rx_ring[i].napi.weight);
+ adapter->flags &= ~IGB_FLAG_IN_NETPOLL;
igb_irq_enable(adapter);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
struct e1000_hw *hw = &adapter->hw;
+ pci_ers_result_t result;
+ int err;
+
+ if (adapter->need_ioport)
+ err = pci_enable_device(pdev);
+ else
+ err = pci_enable_device_mem(pdev);
- if (pci_enable_device(pdev)) {
+ if (err) {
dev_err(&pdev->dev,
"Cannot re-enable PCI device after reset.\n");
- return PCI_ERS_RESULT_DISCONNECT;
- }
- pci_set_master(pdev);
- pci_restore_state(pdev);
+ result = PCI_ERS_RESULT_DISCONNECT;
+ } else {
+ pci_set_master(pdev);
+ pci_restore_state(pdev);
- pci_enable_wake(pdev, PCI_D3hot, 0);
- pci_enable_wake(pdev, PCI_D3cold, 0);
+ pci_enable_wake(pdev, PCI_D3hot, 0);
+ pci_enable_wake(pdev, PCI_D3cold, 0);
- igb_reset(adapter);
- wr32(E1000_WUS, ~0);
+ igb_reset(adapter);
+ wr32(E1000_WUS, ~0);
+ result = PCI_ERS_RESULT_RECOVERED;
+ }
- return PCI_ERS_RESULT_RECOVERED;
+ err = pci_cleanup_aer_uncorrect_error_status(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "pci_cleanup_aer_uncorrect_error_status "
+ "failed 0x%0x\n", err);
+ /* non-fatal, continue */
+ }
+
+ return result;
}
/**
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
- igb_init_manageability(adapter);
-
if (netif_running(netdev)) {
if (igb_up(adapter)) {
dev_err(&pdev->dev, "igb_up failed after reset\n");
/* let the f/w know that the h/w is now under the control of the
* driver. */
igb_get_hw_control(adapter);
-
}
/* igb_main.c */