aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c210
1 files changed, 96 insertions, 114 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 7615c715e66e..32bb47adbe39 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)
@@ -501,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
501 adapter->msix_entries[i].entry = i; 443 adapter->msix_entries[i].entry = i;
502} 444}
503 445
446static int
447netxen_read_mac_addr(struct netxen_adapter *adapter)
448{
449 int i;
450 unsigned char *p;
451 __le64 mac_addr;
452 DECLARE_MAC_BUF(mac);
453 struct net_device *netdev = adapter->netdev;
454 struct pci_dev *pdev = adapter->pdev;
455
456 if (netxen_is_flash_supported(adapter) != 0)
457 return -EIO;
458
459 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
460 if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
461 return -EIO;
462 } else {
463 if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
464 return -EIO;
465 }
466
467 p = (unsigned char *)&mac_addr;
468 for (i = 0; i < 6; i++)
469 netdev->dev_addr[i] = *(p + 5 - i);
470
471 memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
472
473 /* set station address */
474
475 if (!is_valid_ether_addr(netdev->perm_addr)) {
476 dev_warn(&pdev->dev, "Bad MAC address %s.\n",
477 print_mac(mac, netdev->dev_addr));
478 } else
479 adapter->macaddr_set(adapter, netdev->dev_addr);
480
481 return 0;
482}
483
504/* 484/*
505 * netxen_nic_probe() 485 * netxen_nic_probe()
506 * 486 *
@@ -529,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
529 unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0; 509 unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
530 int i = 0, err; 510 int i = 0, err;
531 int first_driver, first_boot; 511 int first_driver, first_boot;
532 __le64 mac_addr[FLASH_NUM_PORTS + 1];
533 u32 val; 512 u32 val;
534 int pci_func_id = PCI_FUNC(pdev->devfn); 513 int pci_func_id = PCI_FUNC(pdev->devfn);
535 DECLARE_MAC_BUF(mac);
536 struct netxen_legacy_intr_set *legacy_intrp; 514 struct netxen_legacy_intr_set *legacy_intrp;
537 uint8_t revision_id; 515 uint8_t revision_id;
538 516
@@ -545,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
545 return -ENODEV; 523 return -ENODEV;
546 } 524 }
547 525
526 if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
527 printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
528 "will not be enabled.\n",
529 NX_P3_A0, NX_P3_B1);
530 return -ENODEV;
531 }
532
548 if ((err = pci_enable_device(pdev))) 533 if ((err = pci_enable_device(pdev)))
549 return err; 534 return err;
550 535
@@ -898,34 +883,14 @@ request_msi:
898 goto err_out_disable_msi; 883 goto err_out_disable_msi;
899 884
900 init_timer(&adapter->watchdog_timer); 885 init_timer(&adapter->watchdog_timer);
901 adapter->ahw.linkup = 0;
902 adapter->watchdog_timer.function = &netxen_watchdog; 886 adapter->watchdog_timer.function = &netxen_watchdog;
903 adapter->watchdog_timer.data = (unsigned long)adapter; 887 adapter->watchdog_timer.data = (unsigned long)adapter;
904 INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task); 888 INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
905 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); 889 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
906 890
907 if (netxen_is_flash_supported(adapter) == 0 && 891 err = netxen_read_mac_addr(adapter);
908 netxen_get_flash_mac_addr(adapter, mac_addr) == 0) { 892 if (err)
909 unsigned char *p; 893 dev_warn(&pdev->dev, "failed to read mac addr\n");
910
911 p = (unsigned char *)&mac_addr[adapter->portnum];
912 netdev->dev_addr[0] = *(p + 5);
913 netdev->dev_addr[1] = *(p + 4);
914 netdev->dev_addr[2] = *(p + 3);
915 netdev->dev_addr[3] = *(p + 2);
916 netdev->dev_addr[4] = *(p + 1);
917 netdev->dev_addr[5] = *(p + 0);
918
919 memcpy(netdev->perm_addr, netdev->dev_addr,
920 netdev->addr_len);
921 if (!is_valid_ether_addr(netdev->perm_addr)) {
922 printk(KERN_ERR "%s: Bad MAC address %s.\n",
923 netxen_nic_driver_name,
924 print_mac(mac, netdev->dev_addr));
925 } else {
926 adapter->macaddr_set(adapter, netdev->dev_addr);
927 }
928 }
929 894
930 netif_carrier_off(netdev); 895 netif_carrier_off(netdev);
931 netif_stop_queue(netdev); 896 netif_stop_queue(netdev);
@@ -1000,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1000 965
1001 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 966 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
1002 netxen_free_hw_resources(adapter); 967 netxen_free_hw_resources(adapter);
968 netxen_release_rx_buffers(adapter);
1003 netxen_free_sw_resources(adapter); 969 netxen_free_sw_resources(adapter);
1004 } 970 }
1005 971
@@ -1069,6 +1035,15 @@ static int netxen_nic_open(struct net_device *netdev)
1069 goto err_out_free_sw; 1035 goto err_out_free_sw;
1070 } 1036 }
1071 1037
1038 if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
1039 (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
1040 printk(KERN_ERR "%s: Firmware interrupt scheme is "
1041 "incompatible with driver\n",
1042 netdev->name);
1043 adapter->driver_mismatch = 1;
1044 goto err_out_free_hw;
1045 }
1046
1072 if (adapter->fw_major < 4) { 1047 if (adapter->fw_major < 4) {
1073 adapter->crb_addr_cmd_producer = 1048 adapter->crb_addr_cmd_producer =
1074 crb_cmd_producer[adapter->portnum]; 1049 crb_cmd_producer[adapter->portnum];
@@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
1094 flags, netdev->name, adapter); 1069 flags, netdev->name, adapter);
1095 if (err) { 1070 if (err) {
1096 printk(KERN_ERR "request_irq failed with: %d\n", err); 1071 printk(KERN_ERR "request_irq failed with: %d\n", err);
1097 goto err_out_free_hw; 1072 goto err_out_free_rxbuf;
1098 } 1073 }
1099 1074
1100 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC; 1075 adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@@ -1116,6 +1091,7 @@ static int netxen_nic_open(struct net_device *netdev)
1116 if (adapter->set_mtu) 1091 if (adapter->set_mtu)
1117 adapter->set_mtu(adapter, netdev->mtu); 1092 adapter->set_mtu(adapter, netdev->mtu);
1118 1093
1094 adapter->ahw.linkup = 0;
1119 mod_timer(&adapter->watchdog_timer, jiffies); 1095 mod_timer(&adapter->watchdog_timer, jiffies);
1120 1096
1121 napi_enable(&adapter->napi); 1097 napi_enable(&adapter->napi);
@@ -1127,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
1127 1103
1128err_out_free_irq: 1104err_out_free_irq:
1129 free_irq(adapter->irq, adapter); 1105 free_irq(adapter->irq, adapter);
1106err_out_free_rxbuf:
1107 netxen_release_rx_buffers(adapter);
1130err_out_free_hw: 1108err_out_free_hw:
1131 netxen_free_hw_resources(adapter); 1109 netxen_free_hw_resources(adapter);
1132err_out_free_sw: 1110err_out_free_sw:
@@ -1152,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
1152 1130
1153 netxen_release_tx_buffers(adapter); 1131 netxen_release_tx_buffers(adapter);
1154 1132
1155 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 1133 FLUSH_SCHEDULED_WORK();
1156 FLUSH_SCHEDULED_WORK(); 1134 del_timer_sync(&adapter->watchdog_timer);
1157 del_timer_sync(&adapter->watchdog_timer);
1158 }
1159 1135
1160 return 0; 1136 return 0;
1161} 1137}
@@ -1458,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
1458 1434
1459 netxen_nic_handle_phy_intr(adapter); 1435 netxen_nic_handle_phy_intr(adapter);
1460 1436
1461 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1437 if (netif_running(adapter->netdev))
1438 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
1462} 1439}
1463 1440
1464static void netxen_tx_timeout(struct net_device *netdev) 1441static void netxen_tx_timeout(struct net_device *netdev)
@@ -1518,18 +1495,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
1518 return stats; 1495 return stats;
1519} 1496}
1520 1497
1521static inline void
1522netxen_handle_int(struct netxen_adapter *adapter)
1523{
1524 netxen_nic_disable_int(adapter);
1525 napi_schedule(&adapter->napi);
1526}
1527
1528static irqreturn_t netxen_intr(int irq, void *data) 1498static irqreturn_t netxen_intr(int irq, void *data)
1529{ 1499{
1530 struct netxen_adapter *adapter = data; 1500 struct netxen_adapter *adapter = data;
1531 u32 our_int = 0;
1532
1533 u32 status = 0; 1501 u32 status = 0;
1534 1502
1535 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR); 1503 status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1544,22 +1512,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
1544 if (!ISR_LEGACY_INT_TRIGGERED(status)) 1512 if (!ISR_LEGACY_INT_TRIGGERED(status))
1545 return IRQ_NONE; 1513 return IRQ_NONE;
1546 1514
1547 } else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1515 } else {
1516 unsigned long our_int = 0;
1548 1517
1549 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR); 1518 our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
1519
1550 /* not our interrupt */ 1520 /* not our interrupt */
1551 if ((our_int & (0x80 << adapter->portnum)) == 0) 1521 if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
1552 return IRQ_NONE; 1522 return IRQ_NONE;
1553 1523
1554 if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { 1524 /* claim interrupt */
1555 /* claim interrupt */ 1525 adapter->pci_write_normalize(adapter,
1556 adapter->pci_write_normalize(adapter, 1526 CRB_INT_VECTOR, (our_int & 0xffffffff));
1557 CRB_INT_VECTOR,
1558 our_int & ~((u32)(0x80 << adapter->portnum)));
1559 }
1560 } 1527 }
1561 1528
1562 netxen_handle_int(adapter); 1529 /* clear interrupt */
1530 if (adapter->fw_major < 4)
1531 netxen_nic_disable_int(adapter);
1532
1533 adapter->pci_write_immediate(adapter,
1534 adapter->legacy_intr.tgt_status_reg,
1535 0xffffffff);
1536 /* read twice to ensure write is flushed */
1537 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1538 adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
1539
1540 napi_schedule(&adapter->napi);
1563 1541
1564 return IRQ_HANDLED; 1542 return IRQ_HANDLED;
1565} 1543}
@@ -1568,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
1568{ 1546{
1569 struct netxen_adapter *adapter = data; 1547 struct netxen_adapter *adapter = data;
1570 1548
1571 netxen_handle_int(adapter); 1549 /* clear interrupt */
1550 adapter->pci_write_immediate(adapter,
1551 msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
1552
1553 napi_schedule(&adapter->napi);
1572 return IRQ_HANDLED; 1554 return IRQ_HANDLED;
1573} 1555}
1574 1556