"Intel(R) Gigabit Ethernet Network Driver";
static const char igb_copyright[] = "Copyright (c) 2008 Intel Corporation.";
-
static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
};
.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_DCA
dca_register_notify(&dca_notifier);
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->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;
#ifdef CONFIG_NETDEVICES_MULTIQUEUE
/* Notify the stack of the (possibly) reduced Tx Queue count. */
/* 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;
}
}
- 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,
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;
* lan on a particular port */
switch (pdev->device) {
case E1000_DEV_ID_82575GB_QUAD_COPPER:
- case E1000_DEV_ID_82576_QUAD_COPPER:
adapter->eeprom_wol = 0;
break;
case E1000_DEV_ID_82575EB_FIBER_SERDES:
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 */
goto err_register;
#ifdef CONFIG_DCA
- if (dca_add_requester(&pdev->dev) == 0) {
- adapter->dca_enabled = true;
+ 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. */
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);
return 0;
flush_scheduled_work();
#ifdef CONFIG_DCA
- if (adapter->dca_enabled) {
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED) {
dev_info(&pdev->dev, "DCA disabled\n");
dca_remove_requester(&pdev->dev);
- adapter->dca_enabled = false;
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
wr32(E1000_DCA_CTRL, 1);
}
#endif
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;
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->queue_index << 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->dma = 0;
olinfo_status |= E1000_TXD_POPTS_TXSM << 8;
}
- if (tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_TSO |
- IGB_TX_FLAGS_VLAN))
+ 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);
if (!tx_ring->itr_val)
wr32(E1000_EIMC, tx_ring->eims_value);
#ifdef CONFIG_DCA
- if (adapter->dca_enabled)
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_tx_dca(tx_ring);
#endif
tx_ring->total_bytes = 0;
__netif_rx_schedule(adapter->netdev, &rx_ring->napi);
#ifdef CONFIG_DCA
- if (adapter->dca_enabled)
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring);
#endif
return IRQ_HANDLED;
{
int i;
- if (!(adapter->dca_enabled))
+ if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
return;
for (i = 0; i < adapter->num_tx_queues; i++) {
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->dca_enabled)
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
break;
- adapter->dca_enabled = true;
+ adapter->flags |= IGB_FLAG_DCA_ENABLED;
/* Always use CB2 mode, difference is masked
* in the CB driver. */
wr32(E1000_DCA_CTRL, 2);
}
/* Fall Through since DCA is disabled. */
case DCA_PROVIDER_REMOVE:
- if (adapter->dca_enabled) {
+ 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->dca_enabled = false;
+ adapter->flags &= ~IGB_FLAG_DCA_ENABLED;
wr32(E1000_DCA_CTRL, 1);
}
break;
}
-
+out:
return 0;
}
/* this poll routine only supports one tx and one rx queue */
#ifdef CONFIG_DCA
- if (adapter->dca_enabled)
+ 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
- if (adapter->dca_enabled)
+ 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);
goto quit_polling;
#ifdef CONFIG_DCA
- if (adapter->dca_enabled)
+ if (adapter->flags & IGB_FLAG_DCA_ENABLED)
igb_update_rx_dca(rx_ring);
#endif
igb_clean_rx_irq_adv(rx_ring, &work_done, budget);
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->tx_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 */