|
@@ -5465,6 +5465,36 @@ static void e1000_shutdown(struct pci_dev *pdev)
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
|
+
|
|
|
+static irqreturn_t e1000_intr_msix(int irq, void *data)
|
|
|
+{
|
|
|
+ struct net_device *netdev = data;
|
|
|
+ struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
+ int vector, msix_irq;
|
|
|
+
|
|
|
+ if (adapter->msix_entries) {
|
|
|
+ vector = 0;
|
|
|
+ msix_irq = adapter->msix_entries[vector].vector;
|
|
|
+ disable_irq(msix_irq);
|
|
|
+ e1000_intr_msix_rx(msix_irq, netdev);
|
|
|
+ enable_irq(msix_irq);
|
|
|
+
|
|
|
+ vector++;
|
|
|
+ msix_irq = adapter->msix_entries[vector].vector;
|
|
|
+ disable_irq(msix_irq);
|
|
|
+ e1000_intr_msix_tx(msix_irq, netdev);
|
|
|
+ enable_irq(msix_irq);
|
|
|
+
|
|
|
+ vector++;
|
|
|
+ msix_irq = adapter->msix_entries[vector].vector;
|
|
|
+ disable_irq(msix_irq);
|
|
|
+ e1000_msix_other(msix_irq, netdev);
|
|
|
+ enable_irq(msix_irq);
|
|
|
+ }
|
|
|
+
|
|
|
+ return IRQ_HANDLED;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Polling 'interrupt' - used by things like netconsole to send skbs
|
|
|
* without having to re-enable interrupts. It's not called while
|
|
@@ -5474,10 +5504,21 @@ static void e1000_netpoll(struct net_device *netdev)
|
|
|
{
|
|
|
struct e1000_adapter *adapter = netdev_priv(netdev);
|
|
|
|
|
|
- disable_irq(adapter->pdev->irq);
|
|
|
- e1000_intr(adapter->pdev->irq, netdev);
|
|
|
-
|
|
|
- enable_irq(adapter->pdev->irq);
|
|
|
+ switch (adapter->int_mode) {
|
|
|
+ case E1000E_INT_MODE_MSIX:
|
|
|
+ e1000_intr_msix(adapter->pdev->irq, netdev);
|
|
|
+ break;
|
|
|
+ case E1000E_INT_MODE_MSI:
|
|
|
+ disable_irq(adapter->pdev->irq);
|
|
|
+ e1000_intr_msi(adapter->pdev->irq, netdev);
|
|
|
+ enable_irq(adapter->pdev->irq);
|
|
|
+ break;
|
|
|
+ default: /* E1000E_INT_MODE_LEGACY */
|
|
|
+ disable_irq(adapter->pdev->irq);
|
|
|
+ e1000_intr(adapter->pdev->irq, netdev);
|
|
|
+ enable_irq(adapter->pdev->irq);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
#endif
|
|
|
|