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: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
This commit is contained in:
Родитель
a70f939338
Коммит
d71e1be8ed
|
@ -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.
|
||||
|
|
|
@ -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,15 +1534,33 @@ static irqreturn_t netxen_intr(int irq, void *data)
|
|||
struct netxen_adapter *adapter = data;
|
||||
u32 our_int = 0;
|
||||
|
||||
our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
|
||||
/* not our interrupt */
|
||||
if ((our_int & (0x80 << adapter->portnum)) == 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->intr_scheme == INTR_SCHEME_PERPORT) {
|
||||
/* claim interrupt */
|
||||
adapter->pci_write_normalize(adapter, CRB_INT_VECTOR,
|
||||
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)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
|
||||
/* claim interrupt */
|
||||
adapter->pci_write_normalize(adapter,
|
||||
CRB_INT_VECTOR,
|
||||
our_int & ~((u32)(0x80 << adapter->portnum)));
|
||||
}
|
||||
}
|
||||
|
||||
netxen_handle_int(adapter);
|
||||
|
|
Загрузка…
Ссылка в новой задаче