diff options
author | Dongdong Deng <dongdong.deng@windriver.com> | 2010-11-16 22:50:15 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2010-11-16 22:50:15 -0500 |
commit | 147b2c8cb4f3e16aafc87096365a913d01ee3a21 (patch) | |
tree | 3c65dedd8faf0f02ff01ca0fcc680acc5b273829 /drivers/net/e1000e | |
parent | 1b98c2bb63a4b415d8d894d001b6d0256409e0d9 (diff) |
e1000e: add netpoll support for MSI/MSI-X IRQ modes
With enabling CONFIG_PCI_MSI, e1000e could work in MSI/MSI-X IRQ mode,
and netpoll controller didn't deal with those IRQ modes on e1000e.
This patch add the handling MSI/MSI-X IRQ modes to netpoll controller,
so that netconsole could work with those IRQ modes.
Signed-off-by: Dongdong Deng <dongdong.deng@windriver.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/netdev.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index a6d54e460001..9b3f0a996b00 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -5465,6 +5465,36 @@ static void e1000_shutdown(struct pci_dev *pdev) | |||
5465 | } | 5465 | } |
5466 | 5466 | ||
5467 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5467 | #ifdef CONFIG_NET_POLL_CONTROLLER |
5468 | |||
5469 | static irqreturn_t e1000_intr_msix(int irq, void *data) | ||
5470 | { | ||
5471 | struct net_device *netdev = data; | ||
5472 | struct e1000_adapter *adapter = netdev_priv(netdev); | ||
5473 | int vector, msix_irq; | ||
5474 | |||
5475 | if (adapter->msix_entries) { | ||
5476 | vector = 0; | ||
5477 | msix_irq = adapter->msix_entries[vector].vector; | ||
5478 | disable_irq(msix_irq); | ||
5479 | e1000_intr_msix_rx(msix_irq, netdev); | ||
5480 | enable_irq(msix_irq); | ||
5481 | |||
5482 | vector++; | ||
5483 | msix_irq = adapter->msix_entries[vector].vector; | ||
5484 | disable_irq(msix_irq); | ||
5485 | e1000_intr_msix_tx(msix_irq, netdev); | ||
5486 | enable_irq(msix_irq); | ||
5487 | |||
5488 | vector++; | ||
5489 | msix_irq = adapter->msix_entries[vector].vector; | ||
5490 | disable_irq(msix_irq); | ||
5491 | e1000_msix_other(msix_irq, netdev); | ||
5492 | enable_irq(msix_irq); | ||
5493 | } | ||
5494 | |||
5495 | return IRQ_HANDLED; | ||
5496 | } | ||
5497 | |||
5468 | /* | 5498 | /* |
5469 | * Polling 'interrupt' - used by things like netconsole to send skbs | 5499 | * Polling 'interrupt' - used by things like netconsole to send skbs |
5470 | * without having to re-enable interrupts. It's not called while | 5500 | * without having to re-enable interrupts. It's not called while |
@@ -5474,10 +5504,21 @@ static void e1000_netpoll(struct net_device *netdev) | |||
5474 | { | 5504 | { |
5475 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5505 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5476 | 5506 | ||
5477 | disable_irq(adapter->pdev->irq); | 5507 | switch (adapter->int_mode) { |
5478 | e1000_intr(adapter->pdev->irq, netdev); | 5508 | case E1000E_INT_MODE_MSIX: |
5479 | 5509 | e1000_intr_msix(adapter->pdev->irq, netdev); | |
5480 | enable_irq(adapter->pdev->irq); | 5510 | break; |
5511 | case E1000E_INT_MODE_MSI: | ||
5512 | disable_irq(adapter->pdev->irq); | ||
5513 | e1000_intr_msi(adapter->pdev->irq, netdev); | ||
5514 | enable_irq(adapter->pdev->irq); | ||
5515 | break; | ||
5516 | default: /* E1000E_INT_MODE_LEGACY */ | ||
5517 | disable_irq(adapter->pdev->irq); | ||
5518 | e1000_intr(adapter->pdev->irq, netdev); | ||
5519 | enable_irq(adapter->pdev->irq); | ||
5520 | break; | ||
5521 | } | ||
5481 | } | 5522 | } |
5482 | #endif | 5523 | #endif |
5483 | 5524 | ||