diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2008-08-08 03:08:43 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-08-14 04:43:16 -0400 |
commit | 092bc57184842229ee41f87d9c408a3f1302aaa6 (patch) | |
tree | 0ad474c92d86f8490ed211f56f49923c3d31e6e3 /drivers/net/netxen | |
parent | 15eef1e1b718667981da92d2fa18283f181c117c (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.c | 123 |
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 | ||
150 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; | 150 | static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG; |
151 | 151 | ||
152 | static void netxen_nic_disable_int(struct netxen_adapter *adapter) | 152 | static 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 | ||
190 | static void netxen_nic_enable_int(struct netxen_adapter *adapter) | 157 | static 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 | ||
224 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | 166 | static 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); |
1148 | err_out_free_rxbuf: | 1099 | err_out_free_rxbuf: |
1149 | netxen_release_rx_buffers(adapter); | 1100 | netxen_release_rx_buffers(adapter); |
1101 | err_out_free_hw: | ||
1150 | netxen_free_hw_resources(adapter); | 1102 | netxen_free_hw_resources(adapter); |
1151 | err_out_free_sw: | 1103 | err_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 | ||
1539 | static inline void | ||
1540 | netxen_handle_int(struct netxen_adapter *adapter) | ||
1541 | { | ||
1542 | netxen_nic_disable_int(adapter); | ||
1543 | napi_schedule(&adapter->napi); | ||
1544 | } | ||
1545 | |||
1546 | static irqreturn_t netxen_intr(int irq, void *data) | 1491 | static 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 | ||