aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2008-08-08 03:08:43 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-08-14 04:43:16 -0400
commit092bc57184842229ee41f87d9c408a3f1302aaa6 (patch)
tree0ad474c92d86f8490ed211f56f49923c3d31e6e3 /drivers/net/netxen
parent15eef1e1b718667981da92d2fa18283f181c117c (diff)
netxen: cleanup interrupt code
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>
Diffstat (limited to 'drivers/net/netxen')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c123
1 files changed, 40 insertions, 83 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index f69807c9432b..3c424a88d8fc 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {
149 149
150static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; 150static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
151 151
152static void netxen_nic_disable_int(struct netxen_adapter *adapter) 152static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
153{ 153{
154 u32 mask = 0x7ff; 154 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
155 int retries = 32;
156 int pci_fn = adapter->ahw.pci_func;
157
158 if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
159 adapter->pci_write_normalize(adapter,
160 adapter->crb_intr_mask, 0);
161
162 if (adapter->intr_scheme != -1 &&
163 adapter->intr_scheme != INTR_SCHEME_PERPORT)
164 adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
165
166 if (!NETXEN_IS_MSI_FAMILY(adapter)) {
167 do {
168 adapter->pci_write_immediate(adapter,
169 adapter->legacy_intr.tgt_status_reg,
170 0xffffffff);
171 mask = adapter->pci_read_immediate(adapter,
172 ISR_INT_VECTOR);
173 if (!(mask & 0x80))
174 break;
175 udelay(10);
176 } while (--retries);
177
178 if (!retries) {
179 printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
180 netxen_nic_driver_name);
181 }
182 } else {
183 if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
184 adapter->pci_write_immediate(adapter,
185 msi_tgt_status[pci_fn], 0xffffffff);
186 }
187 }
188} 155}
189 156
190static void netxen_nic_enable_int(struct netxen_adapter *adapter) 157static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
191{ 158{
192 u32 mask;
193
194 if (adapter->intr_scheme != -1 &&
195 adapter->intr_scheme != INTR_SCHEME_PERPORT) {
196 switch (adapter->ahw.board_type) {
197 case NETXEN_NIC_GBE:
198 mask = 0x77b;
199 break;
200 case NETXEN_NIC_XGBE:
201 mask = 0x77f;
202 break;
203 default:
204 mask = 0x7ff;
205 break;
206 }
207
208 adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
209 }
210
211 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1); 159 adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
212 160
213 if (!NETXEN_IS_MSI_FAMILY(adapter)) { 161 if (!NETXEN_IS_MSI_FAMILY(adapter))
214 mask = 0xbff; 162 adapter->pci_write_immediate(adapter,
215 if (adapter->intr_scheme == INTR_SCHEME_PERPORT) 163 adapter->legacy_intr.tgt_mask_reg, 0xfbff);
216 adapter->pci_write_immediate(adapter,
217 adapter->legacy_intr.tgt_mask_reg, mask);
218 else
219 adapter->pci_write_normalize(adapter,
220 CRB_INT_VECTOR, 0);
221 }
222} 164}
223 165
224static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) 166static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -1086,6 +1028,15 @@ static int netxen_nic_open(struct net_device *netdev)
1086 goto err_out_free_sw; 1028 goto err_out_free_sw;
1087 } 1029 }
1088 1030
1031 if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
1032 (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
1033 printk(KERN_ERR "%s: Firmware interrupt scheme is "
1034 "incompatible with driver\n",
1035 netdev->name);
1036 adapter->driver_mismatch = 1;
1037 goto err_out_free_hw;
1038 }
1039
1089 if (adapter->fw_major < 4) { 1040 if (adapter->fw_major < 4) {
1090 adapter->crb_addr_cmd_producer = 1041 adapter->crb_addr_cmd_producer =
1091 crb_cmd_producer[adapter->portnum]; 1042 crb_cmd_producer[adapter->portnum];
@@ -1147,6 +1098,7 @@ err_out_free_irq:
1147 free_irq(adapter->irq, adapter); 1098 free_irq(adapter->irq, adapter);
1148err_out_free_rxbuf: 1099err_out_free_rxbuf:
1149 netxen_release_rx_buffers(adapter); 1100 netxen_release_rx_buffers(adapter);
1101err_out_free_hw:
1150 netxen_free_hw_resources(adapter); 1102 netxen_free_hw_resources(adapter);
1151err_out_free_sw: 1103err_out_free_sw:
1152 netxen_free_sw_resources(adapter); 1104 netxen_free_sw_resources(adapter);
@@ -1536,18 +1488,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
1536 return stats; 1488 return stats;
1537} 1489}
1538 1490
1539static inline void
1540netxen_handle_int(struct netxen_adapter *adapter)
1541{
1542 netxen_nic_disable_int(adapter);
1543 napi_schedule(&adapter->napi);
1544}
1545
1546static irqreturn_t netxen_intr(int irq, void *data) 1491static irqreturn_t netxen_intr(int irq, void *data)
1547{ 1492{
1548 struct netxen_adapter *adapter = data; 1493 struct netxen_adapter *adapter = data;
1549 u32 our_int = 0;
1550
1551 u32 status = 0; 1494 u32 status = 0;
1552 1495
1553 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); 1496 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1562,22 +1505,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
1562 if (!ISR_LEGACY_INT_TRIGGERED(status)) 1505 if (!ISR_LEGACY_INT_TRIGGERED(status))
1563 return IRQ_NONE; 1506 return IRQ_NONE;
1564 1507
1565 } else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1508 } else {
1509 unsigned long our_int = 0;
1566 1510
1567 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); 1511 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
1512
1568 /* not our interrupt */ 1513 /* not our interrupt */
1569 if ((our_int & (0x80 << adapter->portnum)) == 0) 1514 if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
1570 return IRQ_NONE; 1515 return IRQ_NONE;
1571 1516
1572 if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { 1517 /* claim interrupt */
1573 /* claim interrupt */ 1518 adapter->pci_write_normalize(adapter,
1574 adapter->pci_write_normalize(adapter, 1519 CRB_INT_VECTOR, (our_int & 0xffffffff));
1575 CRB_INT_VECTOR,
1576 our_int & ~((u32)(0x80 << adapter->portnum)));
1577 }
1578 } 1520 }
1579 1521
1580 netxen_handle_int(adapter); 1522 /* clear interrupt */
1523 if (adapter->fw_major < 4)
1524 netxen_nic_disable_int(adapter);
1525
1526 adapter->pci_write_immediate(adapter,
1527 adapter->legacy_intr.tgt_status_reg,
1528 0xffffffff);
1529 /* read twice to ensure write is flushed */
1530 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1531 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1532
1533 napi_schedule(&adapter->napi);
1581 1534
1582 return IRQ_HANDLED; 1535 return IRQ_HANDLED;
1583} 1536}
@@ -1586,7 +1539,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
1586{ 1539{
1587 struct netxen_adapter *adapter = data; 1540 struct netxen_adapter *adapter = data;
1588 1541
1589 netxen_handle_int(adapter); 1542 /* clear interrupt */
1543 adapter->pci_write_immediate(adapter,
1544 msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
1545
1546 napi_schedule(&adapter->napi);
1590 return IRQ_HANDLED; 1547 return IRQ_HANDLED;
1591} 1548}
1592 1549