Commit 147b2c8c authored by Dongdong Deng's avatar Dongdong Deng Committed by Jeff Kirsher
Browse files

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: default avatarDongdong Deng <dongdong.deng@windriver.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 1b98c2bb
Loading
Loading
Loading
Loading
+45 −4
Original line number Diff line number Diff line
@@ -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);

	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