Skip to content

Commit

Permalink
netxen: cleanup interrupt code
Browse files Browse the repository at this point in the history
Mark interrupt scheme in very old firmware incompatible. Interrupt mask
and status registers are per pci function / port.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Dhananjay Phadke authored and Jeff Garzik committed Aug 14, 2008
1 parent 15eef1e commit 092bc57
Showing 1 changed file with 40 additions and 83 deletions.
123 changes: 40 additions & 83 deletions drivers/net/netxen/netxen_nic_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {

static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;

static void netxen_nic_disable_int(struct netxen_adapter *adapter)
static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
{
u32 mask = 0x7ff;
int retries = 32;
int pci_fn = adapter->ahw.pci_func;

if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
adapter->pci_write_normalize(adapter,
adapter->crb_intr_mask, 0);

if (adapter->intr_scheme != -1 &&
adapter->intr_scheme != INTR_SCHEME_PERPORT)
adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);

if (!NETXEN_IS_MSI_FAMILY(adapter)) {
do {
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
0xffffffff);
mask = adapter->pci_read_immediate(adapter,
ISR_INT_VECTOR);
if (!(mask & 0x80))
break;
udelay(10);
} while (--retries);

if (!retries) {
printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
netxen_nic_driver_name);
}
} else {
if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
adapter->pci_write_immediate(adapter,
msi_tgt_status[pci_fn], 0xffffffff);
}
}
adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
}

static void netxen_nic_enable_int(struct netxen_adapter *adapter)
static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
{
u32 mask;

if (adapter->intr_scheme != -1 &&
adapter->intr_scheme != INTR_SCHEME_PERPORT) {
switch (adapter->ahw.board_type) {
case NETXEN_NIC_GBE:
mask = 0x77b;
break;
case NETXEN_NIC_XGBE:
mask = 0x77f;
break;
default:
mask = 0x7ff;
break;
}

adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
}

adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);

if (!NETXEN_IS_MSI_FAMILY(adapter)) {
mask = 0xbff;
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);
}
if (!NETXEN_IS_MSI_FAMILY(adapter))
adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_mask_reg, 0xfbff);
}

static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
Expand Down Expand Up @@ -1086,6 +1028,15 @@ static int netxen_nic_open(struct net_device *netdev)
goto err_out_free_sw;
}

if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
printk(KERN_ERR "%s: Firmware interrupt scheme is "
"incompatible with driver\n",
netdev->name);
adapter->driver_mismatch = 1;
goto err_out_free_hw;
}

if (adapter->fw_major < 4) {
adapter->crb_addr_cmd_producer =
crb_cmd_producer[adapter->portnum];
Expand Down Expand Up @@ -1147,6 +1098,7 @@ static int netxen_nic_open(struct net_device *netdev)
free_irq(adapter->irq, adapter);
err_out_free_rxbuf:
netxen_release_rx_buffers(adapter);
err_out_free_hw:
netxen_free_hw_resources(adapter);
err_out_free_sw:
netxen_free_sw_resources(adapter);
Expand Down Expand Up @@ -1536,18 +1488,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
return stats;
}

static inline void
netxen_handle_int(struct netxen_adapter *adapter)
{
netxen_nic_disable_int(adapter);
napi_schedule(&adapter->napi);
}

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);
Expand All @@ -1562,22 +1505,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
if (!ISR_LEGACY_INT_TRIGGERED(status))
return IRQ_NONE;

} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
} else {
unsigned long our_int = 0;

our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);

/* not our interrupt */
if ((our_int & (0x80 << adapter->portnum)) == 0)
if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
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)));
}
/* claim interrupt */
adapter->pci_write_normalize(adapter,
CRB_INT_VECTOR, (our_int & 0xffffffff));
}

netxen_handle_int(adapter);
/* clear interrupt */
if (adapter->fw_major < 4)
netxen_nic_disable_int(adapter);

adapter->pci_write_immediate(adapter,
adapter->legacy_intr.tgt_status_reg,
0xffffffff);
/* read twice to ensure write is flushed */
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);

napi_schedule(&adapter->napi);

return IRQ_HANDLED;
}
Expand All @@ -1586,7 +1539,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
{
struct netxen_adapter *adapter = data;

netxen_handle_int(adapter);
/* clear interrupt */
adapter->pci_write_immediate(adapter,
msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);

napi_schedule(&adapter->napi);
return IRQ_HANDLED;
}

Expand Down

0 comments on commit 092bc57

Please sign in to comment.