#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>
-#ifdef CONFIG_DCA
+#include <linux/aer.h>
+#ifdef CONFIG_IGB_DCA
#include <linux/dca.h>
#endif
#include "igb.h"
{ 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_82576_QUAD_COPPER), 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_ring *);
-static void igb_free_rx_resources(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 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);
-#ifdef CONFIG_DCA
+#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_DCA */
+#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 int igb_resume(struct pci_dev *);
#endif
static void igb_shutdown(struct pci_dev *);
-#ifdef CONFIG_DCA
+#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,
global_quad_port_a = 0;
ret = pci_register_driver(&igb_driver);
-#ifdef CONFIG_DCA
+#ifdef CONFIG_IGB_DCA
dca_register_notify(&dca_notifier);
#endif
return ret;
**/
static void __exit igb_exit_module(void)
{
-#ifdef CONFIG_DCA
+#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;
/* 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;
}
array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
break;
case e1000_82576:
- /* Kawela uses a table-based method for assigning vectors.
+ /* 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 & 0x7);
+ index = (rx_queue >> 1);
ivar = array_rd32(E1000_IVAR0, index);
- if (rx_queue < 8) {
- /* vector goes into low byte of register */
- ivar = ivar & 0xFFFFFF00;
- ivar |= msix_vector | E1000_IVAR_VALID;
- } else {
+ 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 & 0x7);
+ index = (tx_queue >> 1);
ivar = array_rd32(E1000_IVAR0, index);
- if (tx_queue < 8) {
- /* vector goes into second byte of register */
- ivar = ivar & 0xFFFF00FF;
- ivar |= (msix_vector | E1000_IVAR_VALID) << 8;
- } else {
+ 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);
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);
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,
adapter->msix_entries,
numvecs);
if (err == 0)
- return;
+ goto out;
igb_reset_interrupt_capability(adapter);
adapter->num_tx_queues = 1;
if (!pci_enable_msi(adapter->pdev))
adapter->flags |= IGB_FLAG_HAS_MSI;
-
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+out:
/* Notify the stack of the (possibly) reduced Tx Queue count. */
- adapter->netdev->egress_subqueue_count = adapter->num_tx_queues;
-#endif
+ adapter->netdev->real_num_tx_queues = adapter->num_tx_queues;
return;
}
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);
wr32(E1000_RCTL, rctl & ~E1000_RCTL_EN);
/* flush and sleep below */
- netif_stop_queue(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-#endif
+ netif_tx_stop_all_queues(netdev);
/* disable transmits in the hardware */
tctl = rd32(E1000_TCTL);
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);
}
/**
}
}
+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
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;
- 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;
}
}
+ /* 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;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netdev = alloc_etherdev_mq(sizeof(struct igb_adapter), IGB_MAX_TX_QUEUES);
-#else
- netdev = alloc_etherdev(sizeof(struct igb_adapter));
-#endif /* CONFIG_NETDEVICES_MULTIQUEUE */
if (!netdev)
goto err_alloc_etherdev;
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;
- 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);
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- netdev->features |= NETIF_F_MULTI_QUEUE;
-#endif
-
netdev->features |= NETIF_F_LLTX;
adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
if (rd32(E1000_STATUS) & E1000_STATUS_FUNC_1)
adapter->eeprom_wol = 0;
break;
- case E1000_DEV_ID_82576_QUAD_COPPER:
- /* if quad port adapter, disable WoL on all but port A */
- if (global_quad_port_a != 0)
- adapter->eeprom_wol = 0;
- else
- adapter->flags |= IGB_FLAG_QUAD_PORT_A;
- /* Reset for multiple quad port adapters */
- if (++global_quad_port_a == 4)
- global_quad_port_a = 0;
- break;
}
/* 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);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-#endif
+ netif_tx_stop_all_queues(netdev);
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err)
goto err_register;
-#ifdef CONFIG_DCA
+#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, "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,
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);
{
struct net_device *netdev = pci_get_drvdata(pdev);
struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_DCA
+#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_DCA
+#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
dev_info(&pdev->dev, "DCA disabled\n");
dca_remove_requester(&pdev->dev);
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);
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_rx_queues = min((u32)IGB_MAX_RX_QUEUES, (u32)num_online_cpus());
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
adapter->num_tx_queues = min(IGB_MAX_TX_QUEUES, num_online_cpus());
-#else
- adapter->num_tx_queues = 1;
-#endif /* CONFIG_NET_MULTI_QUEUE_DEVICE */
/* This call may decrease the number of queues depending on
* interrupt mode. */
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,
static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
{
int i, err = 0;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
int r_idx;
-#endif
for (i = 0; i < adapter->num_tx_queues; i++) {
err = igb_setup_tx_resources(adapter, &adapter->tx_ring[i]);
}
}
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
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];
}
-#endif
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 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);
/*
*/
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;
- }
- } 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
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;
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_ring *tx_ring)
+void igb_free_tx_resources(struct igb_ring *tx_ring)
{
struct pci_dev *pdev = tx_ring->adapter->pdev;
/**
* 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_ring *tx_ring)
/**
* 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_ring *rx_ring)
+void igb_free_rx_resources(struct igb_ring *rx_ring)
{
struct pci_dev *pdev = rx_ring->adapter->pdev;
/**
* 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_ring *rx_ring)
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) {
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;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
int i;
-#endif
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);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_wake_subqueue(netdev, i);
-#endif
+ 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);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
- for (i = 0; i < adapter->num_tx_queues; i++)
- netif_stop_subqueue(netdev, i);
-#endif
+ 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;
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)
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;
}
{
struct igb_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_stop_queue(netdev);
-#endif
/* Herbert's original patch had:
* smp_mb__after_netif_stop_queue();
return -EBUSY;
/* A reprieve! */
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
netif_wake_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_wake_queue(netdev);
-#endif
++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;
u8 hdr_len = 0;
/* this is a hard error */
return NETDEV_TX_BUSY;
}
+ skb_orphan(skb);
if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
tx_flags |= IGB_TX_FLAGS_VLAN;
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;
tx_flags |= IGB_TX_FLAGS_CSUM;
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;
struct igb_adapter *adapter = netdev_priv(netdev);
struct igb_ring *tx_ring;
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
int r_idx = 0;
r_idx = skb->queue_mapping & (IGB_MAX_TX_QUEUES - 1);
tx_ring = adapter->multi_tx_table[r_idx];
-#else
- tx_ring = &adapter->tx_ring[0];
-#endif
-
/* This goes back to the question of how to logically map a tx queue
* to a flow. Right now, performance is impacted slightly negatively
/* 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 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_DCA
+#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(tx_ring);
#endif
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;
/* Write the ITR value calculated at the end of the
* previous interrupt.
*/
- if (adapter->set_itr) {
- wr32(rx_ring->itr_register,
- 1000000000 / (rx_ring->itr_val * 256));
- adapter->set_itr = 0;
- }
+ igb_write_itr(rx_ring);
- if (netif_rx_schedule_prep(adapter->netdev, &rx_ring->napi))
- __netif_rx_schedule(adapter->netdev, &rx_ring->napi);
+ if (netif_rx_schedule_prep(&rx_ring->napi))
+ __netif_rx_schedule(&rx_ring->napi);
-#ifdef CONFIG_DCA
+#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring);
#endif
return IRQ_HANDLED;
}
-#ifdef CONFIG_DCA
+#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 - adapter->rx_ring;
+ int q = rx_ring->reg_idx;
if (rx_ring->cpu != cpu) {
dca_rxctrl = rd32(E1000_DCA_RXCTRL(q));
struct igb_adapter *adapter = tx_ring->adapter;
struct e1000_hw *hw = &adapter->hw;
int cpu = get_cpu();
- int q = tx_ring - adapter->tx_ring;
+ int q = tx_ring->reg_idx;
if (tx_ring->cpu != cpu) {
dca_txctrl = rd32(E1000_DCA_TXCTRL(q));
return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
}
-#endif /* CONFIG_DCA */
+#endif /* CONFIG_IGB_DCA */
/**
* igb_intr_msi - Interrupt Handler
/* 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);
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1;
mod_timer(&adapter->watchdog_timer, jiffies + 1);
}
- netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
+ netif_rx_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
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);
}
- netif_rx_schedule(netdev, &adapter->rx_ring[0].napi);
+ netif_rx_schedule(&adapter->rx_ring[0].napi);
return IRQ_HANDLED;
}
int tx_clean_complete, work_done = 0;
/* this poll routine only supports one tx and one rx queue */
-#ifdef CONFIG_DCA
+#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]);
-#ifdef CONFIG_DCA
+#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(&adapter->rx_ring[0]);
#endif
if ((tx_clean_complete && (work_done < budget)) ||
!netif_running(netdev)) {
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;
-
-#ifdef CONFIG_DCA
+#ifdef CONFIG_IGB_DCA
if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring);
#endif
/* 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))
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
static bool igb_clean_tx_irq(struct igb_ring *tx_ring)
{
struct igb_adapter *adapter = tx_ring->adapter;
- struct e1000_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- struct e1000_tx_desc *tx_desc;
+ struct e1000_hw *hw = &adapter->hw;
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();
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
if (__netif_subqueue_stopped(netdev, tx_ring->queue_index) &&
!(test_bit(__IGB_DOWN, &adapter->state))) {
netif_wake_subqueue(netdev, tx_ring->queue_index);
++adapter->restart_queue;
}
-#else
- if (netif_queue_stopped(netdev) &&
- !(test_bit(__IGB_DOWN, &adapter->state))) {
- netif_wake_queue(netdev);
- ++adapter->restart_queue;
- }
-#endif
}
if (tx_ring->detect_tx_hung) {
&& !(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"
" 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",
tx_ring->queue_index,
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);
-#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+ eop_desc->wb.status);
netif_stop_subqueue(netdev, tx_ring->queue_index);
-#else
- netif_stop_queue(netdev);
-#endif
}
}
tx_ring->total_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
next_buffer = &rx_ring->buffer_info[i];
if (!(staterr & E1000_RXD_STAT_EOP)) {
- buffer_info->skb = xchg(&next_buffer->skb, skb);
- buffer_info->dma = xchg(&next_buffer->dma, 0);
+ buffer_info->skb = next_buffer->skb;
+ buffer_info->dma = next_buffer->dma;
+ next_buffer->skb = skb;
+ next_buffer->dma = 0;
goto next_desc;
}
dev_kfree_skb_irq(skb);
goto next_desc;
}
- rx_ring->no_itr_adjust |= (staterr & E1000_RXD_STAT_DYNINT);
total_bytes += skb->len;
total_packets++;
igb_receive_skb(rx_ring, staterr, rx_desc, skb);
- netdev->last_rx = jiffies;
-
next_desc:
rx_desc->wb.upper.status_error = 0;
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;
+ pci_ers_result_t result;
int err;
if (adapter->need_ioport)
err = pci_enable_device(pdev);
else
err = pci_enable_device_mem(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;
+ }
+
+ 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 PCI_ERS_RESULT_RECOVERED;
+ 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 */