|
@@ -507,11 +507,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
if (val == 0x55555555) {
|
|
|
/* This is the first boot after power up */
|
|
|
netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
|
|
|
- if (!(val & 0x4)) {
|
|
|
- val |= 0x4;
|
|
|
- netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val);
|
|
|
- netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
|
|
|
- }
|
|
|
+ if (!(val & 0x4)) {
|
|
|
+ val |= 0x4;
|
|
|
+ netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val);
|
|
|
+ netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val);
|
|
|
+ if (!(val & 0x4))
|
|
|
+ printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n",
|
|
|
+ netxen_nic_driver_name);
|
|
|
+ }
|
|
|
val = readl(NETXEN_CRB_NORMALIZE(adapter,
|
|
|
NETXEN_ROMUSB_GLB_SW_RESET));
|
|
|
printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val);
|
|
@@ -523,11 +526,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
err = -ENODEV;
|
|
|
goto err_out_free_dev;
|
|
|
}
|
|
|
-
|
|
|
- /* clear the register for future unloads/loads */
|
|
|
- writel(0, NETXEN_CRB_NORMALIZE(adapter,
|
|
|
- NETXEN_CAM_RAM(0x1fc)));
|
|
|
}
|
|
|
+
|
|
|
+ /* clear the register for future unloads/loads */
|
|
|
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
|
|
|
printk(KERN_INFO "State: 0x%0x\n",
|
|
|
readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
|
|
|
|
|
@@ -545,13 +547,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
|
NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
|
|
|
/* Handshake with the card before we register the devices. */
|
|
|
netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
|
|
|
-
|
|
|
- /* leave the hw in the same state as reboot */
|
|
|
- writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
|
|
|
- netxen_pinit_from_rom(adapter, 0);
|
|
|
- udelay(500);
|
|
|
- netxen_load_firmware(adapter);
|
|
|
- netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -642,8 +637,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
|
|
|
struct netxen_rx_buffer *buffer;
|
|
|
struct netxen_recv_context *recv_ctx;
|
|
|
struct netxen_rcv_desc_ctx *rcv_desc;
|
|
|
- int i;
|
|
|
- int ctxid, ring;
|
|
|
+ int i, ctxid, ring;
|
|
|
+ static int init_firmware_done = 0;
|
|
|
|
|
|
adapter = pci_get_drvdata(pdev);
|
|
|
if (adapter == NULL)
|
|
@@ -651,30 +646,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
|
|
|
|
|
|
netdev = adapter->netdev;
|
|
|
|
|
|
- netxen_nic_disable_int(adapter);
|
|
|
- if (adapter->irq)
|
|
|
- free_irq(adapter->irq, adapter);
|
|
|
-
|
|
|
+ unregister_netdev(netdev);
|
|
|
+
|
|
|
if (adapter->stop_port)
|
|
|
adapter->stop_port(adapter);
|
|
|
|
|
|
- if ((adapter->flags & NETXEN_NIC_MSI_ENABLED))
|
|
|
- pci_disable_msi(pdev);
|
|
|
-
|
|
|
- if (adapter->portnum == 0)
|
|
|
- netxen_free_adapter_offload(adapter);
|
|
|
+ netxen_nic_disable_int(adapter);
|
|
|
|
|
|
- if(adapter->portnum == 0) {
|
|
|
- /* leave the hw in the same state as reboot */
|
|
|
- writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
|
|
|
- netxen_pinit_from_rom(adapter, 0);
|
|
|
- udelay(500);
|
|
|
- netxen_load_firmware(adapter);
|
|
|
- netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
|
|
|
- }
|
|
|
+ if (adapter->irq)
|
|
|
+ free_irq(adapter->irq, adapter);
|
|
|
|
|
|
- if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
|
|
|
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
|
|
|
+ init_firmware_done++;
|
|
|
netxen_free_hw_resources(adapter);
|
|
|
+ }
|
|
|
|
|
|
for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) {
|
|
|
recv_ctx = &adapter->recv_ctx[ctxid];
|
|
@@ -694,17 +679,73 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- unregister_netdev(netdev);
|
|
|
+ if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
|
|
|
+ pci_disable_msi(pdev);
|
|
|
|
|
|
vfree(adapter->cmd_buf_arr);
|
|
|
|
|
|
+ pci_disable_device(pdev);
|
|
|
+
|
|
|
+ if (adapter->portnum == 0) {
|
|
|
+ if (init_firmware_done) {
|
|
|
+ dma_watchdog_shutdown_request(adapter);
|
|
|
+ msleep(100);
|
|
|
+ i = 100;
|
|
|
+ while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
|
|
|
+ printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
|
|
|
+ msleep(100);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i == 0) {
|
|
|
+ printk(KERN_ERR "dma_watchdog_shutdown_request failed\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* clear the register for future unloads/loads */
|
|
|
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
|
|
|
+ printk(KERN_INFO "State: 0x%0x\n",
|
|
|
+ readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
|
|
|
+
|
|
|
+ /* leave the hw in the same state as reboot */
|
|
|
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
|
|
|
+ if (netxen_pinit_from_rom(adapter, 0))
|
|
|
+ return;
|
|
|
+ msleep(1);
|
|
|
+ if (netxen_load_firmware(adapter))
|
|
|
+ return;
|
|
|
+ netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* clear the register for future unloads/loads */
|
|
|
+ writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
|
|
|
+ printk(KERN_INFO "State: 0x%0x\n",
|
|
|
+ readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
|
|
|
+
|
|
|
+ dma_watchdog_shutdown_request(adapter);
|
|
|
+ msleep(100);
|
|
|
+ i = 100;
|
|
|
+ while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
|
|
|
+ printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
|
|
|
+ msleep(100);
|
|
|
+ i--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (i) {
|
|
|
+ netxen_free_adapter_offload(adapter);
|
|
|
+ } else {
|
|
|
+ printk(KERN_ERR "failed to dma shutdown\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
iounmap(adapter->ahw.db_base);
|
|
|
iounmap(adapter->ahw.pci_base0);
|
|
|
iounmap(adapter->ahw.pci_base1);
|
|
|
iounmap(adapter->ahw.pci_base2);
|
|
|
|
|
|
pci_release_regions(pdev);
|
|
|
- pci_disable_device(pdev);
|
|
|
pci_set_drvdata(pdev, NULL);
|
|
|
|
|
|
free_netdev(netdev);
|
|
@@ -801,7 +842,7 @@ static int netxen_nic_close(struct net_device *netdev)
|
|
|
if (buffrag->dma) {
|
|
|
pci_unmap_single(adapter->pdev, buffrag->dma,
|
|
|
buffrag->length, PCI_DMA_TODEVICE);
|
|
|
- buffrag->dma = (u64) NULL;
|
|
|
+ buffrag->dma = 0ULL;
|
|
|
}
|
|
|
for (j = 0; j < cmd_buff->frag_count; j++) {
|
|
|
buffrag++;
|
|
@@ -809,7 +850,7 @@ static int netxen_nic_close(struct net_device *netdev)
|
|
|
pci_unmap_page(adapter->pdev, buffrag->dma,
|
|
|
buffrag->length,
|
|
|
PCI_DMA_TODEVICE);
|
|
|
- buffrag->dma = (u64) NULL;
|
|
|
+ buffrag->dma = 0ULL;
|
|
|
}
|
|
|
}
|
|
|
/* Free the skb we received in netxen_nic_xmit_frame */
|
|
@@ -819,8 +860,10 @@ static int netxen_nic_close(struct net_device *netdev)
|
|
|
}
|
|
|
cmd_buff++;
|
|
|
}
|
|
|
- FLUSH_SCHEDULED_WORK();
|
|
|
- del_timer_sync(&adapter->watchdog_timer);
|
|
|
+ if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
|
|
|
+ FLUSH_SCHEDULED_WORK();
|
|
|
+ del_timer_sync(&adapter->watchdog_timer);
|
|
|
+ }
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -1259,6 +1302,7 @@ static void __exit netxen_exit_module(void)
|
|
|
/*
|
|
|
* Wait for some time to allow the dma to drain, if any.
|
|
|
*/
|
|
|
+ msleep(100);
|
|
|
pci_unregister_driver(&netxen_driver);
|
|
|
destroy_workqueue(netxen_workq);
|
|
|
}
|