Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d71e1be8 authored by Dhananjay Phadke's avatar Dhananjay Phadke Committed by Jeff Garzik
Browse files

netxen: fix legacy interrupts



Fix legacy interrupt mode for NX3031 chips, read pci interrupt state
in hardware to guard against spurious interrupt.

Signed-off-by: default avatarDhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent a70f9393
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -843,9 +843,11 @@ enum {

#define PCIE_SETUP_FUNCTION	(0x12040)
#define PCIE_SETUP_FUNCTION2	(0x12048)
#define PCIE_MISCCFG_RC         (0x1206c)
#define PCIE_TGT_SPLIT_CHICKEN	(0x12080)
#define PCIE_CHICKEN3		(0x120c8)

#define ISR_INT_STATE_REG       (NETXEN_PCIX_PS_REG(PCIE_MISCCFG_RC))
#define PCIE_MAX_MASTER_SPLIT	(0x14048)

#define NETXEN_PORT_MODE_NONE		0
@@ -861,6 +863,7 @@ enum {
#define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL		(0x14)

#define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
#define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)

/*
 * PCI Interrupt Vector Values.
+31 −17
Original line number Diff line number Diff line
@@ -166,7 +166,8 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
		do {
			adapter->pci_write_immediate(adapter,
					ISR_INT_TARGET_STATUS, 0xffffffff);
					adapter->legacy_intr.tgt_status_reg,
					0xffffffff);
			mask = adapter->pci_read_immediate(adapter,
					ISR_INT_VECTOR);
			if (!(mask & 0x80))
@@ -175,7 +176,7 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
		} while (--retries);

		if (!retries) {
			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
			printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
					netxen_nic_driver_name);
		}
	} else {
@@ -190,8 +191,6 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)
{
	u32 mask;

	DPRINTK(1, INFO, "Entered ISR Enable \n");

	if (adapter->intr_scheme != -1 &&
		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
		switch (adapter->ahw.board_type) {
@@ -213,16 +212,13 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)

	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
		mask = 0xbff;
		if (adapter->intr_scheme != -1 &&
			adapter->intr_scheme != INTR_SCHEME_PERPORT) {
		if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
			adapter->pci_write_immediate(adapter,
				adapter->legacy_intr.tgt_mask_reg, mask);
		else
			adapter->pci_write_normalize(adapter,
					CRB_INT_VECTOR, 0);
	}
		adapter->pci_write_immediate(adapter,
				ISR_INT_TARGET_MASK, mask);
	}

	DPRINTK(1, INFO, "Done with enable Int\n");
}

static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -1538,6 +1534,22 @@ static irqreturn_t netxen_intr(int irq, void *data)
	struct netxen_adapter *adapter = data;
	u32 our_int = 0;

	u32 status = 0;

	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);

	if (!(status & adapter->legacy_intr.int_vec_bit))
		return IRQ_NONE;

	if (adapter->ahw.revision_id >= NX_P3_B1) {
		/* check interrupt state machine, to be sure */
		status = adapter->pci_read_immediate(adapter,
				ISR_INT_STATE_REG);
		if (!ISR_LEGACY_INT_TRIGGERED(status))
			return IRQ_NONE;

	} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {

		our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
		/* not our interrupt */
		if ((our_int & (0x80 << adapter->portnum)) == 0)
@@ -1545,9 +1557,11 @@ static irqreturn_t netxen_intr(int irq, void *data)

		if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
			/* claim interrupt */
		adapter->pci_write_normalize(adapter, CRB_INT_VECTOR,
			adapter->pci_write_normalize(adapter,
				CRB_INT_VECTOR,
				our_int & ~((u32)(0x80 << adapter->portnum)));
		}
	}

	netxen_handle_int(adapter);