diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 306 |
1 files changed, 188 insertions, 118 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 137fb579bd15..4e32bb678ea9 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -76,6 +76,8 @@ static void netxen_nic_poll_controller(struct net_device *netdev); | |||
76 | #endif | 76 | #endif |
77 | static irqreturn_t netxen_intr(int irq, void *data); | 77 | static irqreturn_t netxen_intr(int irq, void *data); |
78 | 78 | ||
79 | int physical_port[] = {0, 1, 2, 3}; | ||
80 | |||
79 | /* PCI Device ID Table */ | 81 | /* PCI Device ID Table */ |
80 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { | 82 | static struct pci_device_id netxen_pci_tbl[] __devinitdata = { |
81 | {PCI_DEVICE(0x4040, 0x0001)}, | 83 | {PCI_DEVICE(0x4040, 0x0001)}, |
@@ -174,6 +176,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
174 | void __iomem *mem_ptr0 = NULL; | 176 | void __iomem *mem_ptr0 = NULL; |
175 | void __iomem *mem_ptr1 = NULL; | 177 | void __iomem *mem_ptr1 = NULL; |
176 | void __iomem *mem_ptr2 = NULL; | 178 | void __iomem *mem_ptr2 = NULL; |
179 | unsigned long first_page_group_end; | ||
180 | unsigned long first_page_group_start; | ||
181 | |||
177 | 182 | ||
178 | u8 __iomem *db_ptr = NULL; | 183 | u8 __iomem *db_ptr = NULL; |
179 | unsigned long mem_base, mem_len, db_base, db_len; | 184 | unsigned long mem_base, mem_len, db_base, db_len; |
@@ -183,11 +188,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
183 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; | 188 | struct netxen_rcv_desc_ctx *rcv_desc = NULL; |
184 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; | 189 | struct netxen_cmd_buffer *cmd_buf_arr = NULL; |
185 | u64 mac_addr[FLASH_NUM_PORTS + 1]; | 190 | u64 mac_addr[FLASH_NUM_PORTS + 1]; |
186 | static int valid_mac = 0; | 191 | int valid_mac = 0; |
187 | static int netxen_probe_flag; | 192 | u32 val; |
188 | int pci_func_id = PCI_FUNC(pdev->devfn); | 193 | int pci_func_id = PCI_FUNC(pdev->devfn); |
189 | 194 | ||
190 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); | 195 | printk(KERN_INFO "%s \n", netxen_nic_driver_string); |
196 | |||
191 | if (pdev->class != 0x020000) { | 197 | if (pdev->class != 0x020000) { |
192 | printk(KERN_ERR"NetXen function %d, class %x will not" | 198 | printk(KERN_ERR"NetXen function %d, class %x will not" |
193 | "be enabled.\n",pci_func_id, pdev->class); | 199 | "be enabled.\n",pci_func_id, pdev->class); |
@@ -234,19 +240,35 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
234 | 240 | ||
235 | adapter->ahw.pdev = pdev; | 241 | adapter->ahw.pdev = pdev; |
236 | adapter->ahw.pci_func = pci_func_id; | 242 | adapter->ahw.pci_func = pci_func_id; |
243 | spin_lock_init(&adapter->tx_lock); | ||
244 | spin_lock_init(&adapter->lock); | ||
237 | 245 | ||
238 | /* remap phys address */ | 246 | /* remap phys address */ |
239 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ | 247 | mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */ |
240 | mem_len = pci_resource_len(pdev, 0); | 248 | mem_len = pci_resource_len(pdev, 0); |
241 | 249 | ||
242 | /* 128 Meg of memory */ | 250 | /* 128 Meg of memory */ |
243 | mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); | 251 | if (mem_len == NETXEN_PCI_128MB_SIZE) { |
244 | mem_ptr1 = | 252 | mem_ptr0 = ioremap(mem_base, FIRST_PAGE_GROUP_SIZE); |
245 | ioremap(mem_base + SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_SIZE); | 253 | mem_ptr1 = ioremap(mem_base + SECOND_PAGE_GROUP_START, |
246 | mem_ptr2 = | 254 | SECOND_PAGE_GROUP_SIZE); |
247 | ioremap(mem_base + THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | 255 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START, |
256 | THIRD_PAGE_GROUP_SIZE); | ||
257 | first_page_group_start = FIRST_PAGE_GROUP_START; | ||
258 | first_page_group_end = FIRST_PAGE_GROUP_END; | ||
259 | } else if (mem_len == NETXEN_PCI_32MB_SIZE) { | ||
260 | mem_ptr1 = ioremap(mem_base, SECOND_PAGE_GROUP_SIZE); | ||
261 | mem_ptr2 = ioremap(mem_base + THIRD_PAGE_GROUP_START - | ||
262 | SECOND_PAGE_GROUP_START, THIRD_PAGE_GROUP_SIZE); | ||
263 | first_page_group_start = 0; | ||
264 | first_page_group_end = 0; | ||
265 | } else { | ||
266 | err = -EIO; | ||
267 | goto err_out_free_netdev; | ||
268 | } | ||
248 | 269 | ||
249 | if ((mem_ptr0 == 0UL) || (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { | 270 | if (((mem_ptr0 == 0UL) && (mem_len == NETXEN_PCI_128MB_SIZE)) || |
271 | (mem_ptr1 == 0UL) || (mem_ptr2 == 0UL)) { | ||
250 | DPRINTK(ERR, | 272 | DPRINTK(ERR, |
251 | "Cannot remap adapter memory aborting.:" | 273 | "Cannot remap adapter memory aborting.:" |
252 | "0 -> %p, 1 -> %p, 2 -> %p\n", | 274 | "0 -> %p, 1 -> %p, 2 -> %p\n", |
@@ -276,17 +298,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
276 | } | 298 | } |
277 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); | 299 | DPRINTK(INFO, "doorbell ioremaped at %p\n", db_ptr); |
278 | 300 | ||
279 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS; | 301 | adapter->ahw.pci_base0 = mem_ptr0; |
280 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | 302 | adapter->ahw.first_page_group_start = first_page_group_start; |
281 | (adapter->ahw.boardcfg.board_type == | 303 | adapter->ahw.first_page_group_end = first_page_group_end; |
282 | NETXEN_BRDTYPE_P2_SB31_2G)) | 304 | adapter->ahw.pci_base1 = mem_ptr1; |
283 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | 305 | adapter->ahw.pci_base2 = mem_ptr2; |
284 | else | 306 | adapter->ahw.db_base = db_ptr; |
285 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | 307 | adapter->ahw.db_len = db_len; |
286 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
287 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
288 | |||
289 | pci_set_drvdata(pdev, netdev); | ||
290 | 308 | ||
291 | adapter->netdev = netdev; | 309 | adapter->netdev = netdev; |
292 | adapter->pdev = pdev; | 310 | adapter->pdev = pdev; |
@@ -295,6 +313,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
295 | netdev->open = netxen_nic_open; | 313 | netdev->open = netxen_nic_open; |
296 | netdev->stop = netxen_nic_close; | 314 | netdev->stop = netxen_nic_close; |
297 | netdev->hard_start_xmit = netxen_nic_xmit_frame; | 315 | netdev->hard_start_xmit = netxen_nic_xmit_frame; |
316 | netdev->get_stats = netxen_nic_get_stats; | ||
298 | netdev->set_multicast_list = netxen_nic_set_multi; | 317 | netdev->set_multicast_list = netxen_nic_set_multi; |
299 | netdev->set_mac_address = netxen_nic_set_mac; | 318 | netdev->set_mac_address = netxen_nic_set_mac; |
300 | netdev->change_mtu = netxen_nic_change_mtu; | 319 | netdev->change_mtu = netxen_nic_change_mtu; |
@@ -324,6 +343,42 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
324 | } else | 343 | } else |
325 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | 344 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; |
326 | 345 | ||
346 | netdev->irq = pdev->irq; | ||
347 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | ||
348 | |||
349 | /* | ||
350 | * Set the CRB window to invalid. If any register in window 0 is | ||
351 | * accessed it should set the window to 0 and then reset it to 1. | ||
352 | */ | ||
353 | adapter->curr_window = 255; | ||
354 | |||
355 | /* initialize the adapter */ | ||
356 | netxen_initialize_adapter_hw(adapter); | ||
357 | |||
358 | #ifdef CONFIG_PPC | ||
359 | if ((adapter->ahw.boardcfg.board_type == | ||
360 | NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) && | ||
361 | (pci_func_id == 2)) | ||
362 | goto err_out_free_adapter; | ||
363 | #endif /* CONFIG_PPC */ | ||
364 | |||
365 | /* | ||
366 | * Adapter in our case is quad port so initialize it before | ||
367 | * initializing the ports | ||
368 | */ | ||
369 | |||
370 | netxen_initialize_adapter_ops(adapter); | ||
371 | |||
372 | adapter->max_tx_desc_count = MAX_CMD_DESCRIPTORS_HOST; | ||
373 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB35_4G) || | ||
374 | (adapter->ahw.boardcfg.board_type == | ||
375 | NETXEN_BRDTYPE_P2_SB31_2G)) | ||
376 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_1G; | ||
377 | else | ||
378 | adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS; | ||
379 | adapter->max_jumbo_rx_desc_count = MAX_JUMBO_RCV_DESCRIPTORS; | ||
380 | adapter->max_lro_rx_desc_count = MAX_LRO_RCV_DESCRIPTORS; | ||
381 | |||
327 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); | 382 | cmd_buf_arr = (struct netxen_cmd_buffer *)vmalloc(TX_RINGSIZE); |
328 | if (cmd_buf_arr == NULL) { | 383 | if (cmd_buf_arr == NULL) { |
329 | printk(KERN_ERR | 384 | printk(KERN_ERR |
@@ -333,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
333 | goto err_out_free_adapter; | 388 | goto err_out_free_adapter; |
334 | } | 389 | } |
335 | memset(cmd_buf_arr, 0, TX_RINGSIZE); | 390 | memset(cmd_buf_arr, 0, TX_RINGSIZE); |
391 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
336 | 392 | ||
337 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 393 | for (i = 0; i < MAX_RCV_CTX; ++i) { |
338 | recv_ctx = &adapter->recv_ctx[i]; | 394 | recv_ctx = &adapter->recv_ctx[i]; |
@@ -380,23 +436,11 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
380 | 436 | ||
381 | } | 437 | } |
382 | 438 | ||
383 | adapter->cmd_buf_arr = cmd_buf_arr; | ||
384 | adapter->ahw.pci_base0 = mem_ptr0; | ||
385 | adapter->ahw.pci_base1 = mem_ptr1; | ||
386 | adapter->ahw.pci_base2 = mem_ptr2; | ||
387 | adapter->ahw.db_base = db_ptr; | ||
388 | adapter->ahw.db_len = db_len; | ||
389 | spin_lock_init(&adapter->tx_lock); | ||
390 | spin_lock_init(&adapter->lock); | ||
391 | /* initialize the adapter */ | ||
392 | netxen_initialize_adapter_hw(adapter); | ||
393 | |||
394 | netxen_initialize_adapter_ops(adapter); | ||
395 | |||
396 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ | 439 | netxen_initialize_adapter_sw(adapter); /* initialize the buffers in adapter */ |
440 | |||
397 | /* Mezz cards have PCI function 0,2,3 enabled */ | 441 | /* Mezz cards have PCI function 0,2,3 enabled */ |
398 | if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) | 442 | if ((adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) |
399 | if (pci_func_id >= 2) | 443 | && (pci_func_id >= 2)) |
400 | adapter->portnum = pci_func_id - 2; | 444 | adapter->portnum = pci_func_id - 2; |
401 | 445 | ||
402 | #ifdef CONFIG_IA64 | 446 | #ifdef CONFIG_IA64 |
@@ -407,16 +451,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
407 | } | 451 | } |
408 | #endif | 452 | #endif |
409 | 453 | ||
410 | /* | ||
411 | * Set the CRB window to invalid. If any register in window 0 is | ||
412 | * accessed it should set the window to 0 and then reset it to 1. | ||
413 | */ | ||
414 | adapter->curr_window = 255; | ||
415 | /* | ||
416 | * Adapter in our case is quad port so initialize it before | ||
417 | * initializing the ports | ||
418 | */ | ||
419 | |||
420 | init_timer(&adapter->watchdog_timer); | 454 | init_timer(&adapter->watchdog_timer); |
421 | adapter->ahw.xg_linkup = 0; | 455 | adapter->ahw.xg_linkup = 0; |
422 | adapter->watchdog_timer.function = &netxen_watchdog; | 456 | adapter->watchdog_timer.function = &netxen_watchdog; |
@@ -426,8 +460,12 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
426 | adapter->proc_cmd_buf_counter = 0; | 460 | adapter->proc_cmd_buf_counter = 0; |
427 | adapter->ahw.revision_id = nx_p2_id; | 461 | adapter->ahw.revision_id = nx_p2_id; |
428 | 462 | ||
463 | /* make sure Window == 1 */ | ||
464 | netxen_nic_pci_change_crbwindow(adapter, 1); | ||
465 | |||
429 | netxen_nic_update_cmd_producer(adapter, 0); | 466 | netxen_nic_update_cmd_producer(adapter, 0); |
430 | netxen_nic_update_cmd_consumer(adapter, 0); | 467 | netxen_nic_update_cmd_consumer(adapter, 0); |
468 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); | ||
431 | 469 | ||
432 | if (netxen_is_flash_supported(adapter) == 0 && | 470 | if (netxen_is_flash_supported(adapter) == 0 && |
433 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) | 471 | netxen_get_flash_mac_addr(adapter, mac_addr) == 0) |
@@ -463,20 +501,41 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
463 | } | 501 | } |
464 | } | 502 | } |
465 | 503 | ||
466 | /* | 504 | if (adapter->portnum == 0) { |
467 | * Initialize all the CRB registers here. | ||
468 | */ | ||
469 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_PRODUCER_OFFSET)); | ||
470 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMD_CONSUMER_OFFSET)); | ||
471 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_HOST_CMD_ADDR_LO)); | ||
472 | |||
473 | /* do this before waking up pegs so that we have valid dummy dma addr */ | ||
474 | if (adapter->portnum == 0) | ||
475 | err = netxen_initialize_adapter_offload(adapter); | 505 | err = netxen_initialize_adapter_offload(adapter); |
476 | if (err) | 506 | if (err) |
477 | goto err_out_free_dev; | 507 | goto err_out_free_rx_buffer; |
508 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
509 | NETXEN_CAM_RAM(0x1fc))); | ||
510 | if (val == 0x55555555) { | ||
511 | /* This is the first boot after power up */ | ||
512 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | ||
513 | NETXEN_ROMUSB_GLB_SW_RESET)); | ||
514 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | ||
515 | if (val != 0x80000f) { | ||
516 | /* clear the register for future unloads/loads */ | ||
517 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
518 | NETXEN_CAM_RAM(0x1fc))); | ||
519 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | ||
520 | err = -ENODEV; | ||
521 | goto err_out_free_dev; | ||
522 | } | ||
523 | |||
524 | /* clear the register for future unloads/loads */ | ||
525 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
526 | NETXEN_CAM_RAM(0x1fc))); | ||
527 | } | ||
528 | printk(KERN_INFO "State: 0x%0x\n", | ||
529 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | ||
530 | |||
531 | /* | ||
532 | * Tell the hardware our version number. | ||
533 | */ | ||
534 | i = (_NETXEN_NIC_LINUX_MAJOR << 16) | ||
535 | | ((_NETXEN_NIC_LINUX_MINOR << 8)) | ||
536 | | (_NETXEN_NIC_LINUX_SUBVERSION); | ||
537 | writel(i, NETXEN_CRB_NORMALIZE(adapter, CRB_DRIVER_VERSION)); | ||
478 | 538 | ||
479 | if (netxen_probe_flag == 0) { | ||
480 | /* Unlock the HW, prompting the boot sequence */ | 539 | /* Unlock the HW, prompting the boot sequence */ |
481 | writel(1, | 540 | writel(1, |
482 | NETXEN_CRB_NORMALIZE(adapter, | 541 | NETXEN_CRB_NORMALIZE(adapter, |
@@ -485,26 +544,25 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
485 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 544 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
486 | } | 545 | } |
487 | 546 | ||
488 | if(netxen_probe_flag == 0) { | ||
489 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
490 | netxen_pinit_from_rom(adapter, 0); | ||
491 | udelay(500); | ||
492 | netxen_load_firmware(adapter); | ||
493 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
494 | } | ||
495 | /* | 547 | /* |
496 | * delay a while to ensure that the Pegs are up & running. | 548 | * See if the firmware gave us a virtual-physical port mapping. |
497 | * Otherwise, we might see some flaky behaviour. | ||
498 | */ | 549 | */ |
499 | udelay(100); | 550 | i = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_V2P(adapter->portnum))); |
500 | INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task); | 551 | if (i != 0x55555555) |
501 | netxen_nic_erase_pxe(adapter); | 552 | physical_port[adapter->portnum] = i; |
553 | |||
502 | netif_carrier_off(netdev); | 554 | netif_carrier_off(netdev); |
503 | netif_stop_queue(netdev); | 555 | netif_stop_queue(netdev); |
504 | 556 | ||
505 | if((err = register_netdev(netdev))) | 557 | if ((err = register_netdev(netdev))) { |
506 | DPRINTK(1, ERR, "register_netdev failed port #%d" | 558 | printk(KERN_ERR "%s: register_netdev failed port #%d" |
507 | " aborting\n", i+1); | 559 | " aborting\n", netxen_nic_driver_name, |
560 | adapter->portnum); | ||
561 | err = -EIO; | ||
562 | goto err_out_free_dev; | ||
563 | } | ||
564 | |||
565 | pci_set_drvdata(pdev, adapter); | ||
508 | 566 | ||
509 | switch (adapter->ahw.board_type) { | 567 | switch (adapter->ahw.board_type) { |
510 | case NETXEN_NIC_GBE: | 568 | case NETXEN_NIC_GBE: |
@@ -519,21 +577,14 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
519 | } | 577 | } |
520 | 578 | ||
521 | adapter->driver_mismatch = 0; | 579 | adapter->driver_mismatch = 0; |
522 | if(netxen_probe_flag == 0) | ||
523 | netxen_probe_flag ++; | ||
524 | 580 | ||
525 | return 0; | 581 | return 0; |
526 | 582 | ||
527 | err_out_free_dev: | 583 | err_out_free_dev: |
528 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | 584 | if (adapter->portnum == 0) |
529 | pci_disable_msi(pdev); | 585 | netxen_free_adapter_offload(adapter); |
530 | |||
531 | unregister_netdev(adapter->netdev); | ||
532 | free_netdev(adapter->netdev); | ||
533 | |||
534 | netxen_free_adapter_offload(adapter); | ||
535 | 586 | ||
536 | err_out_free_rx_buffer: | 587 | err_out_free_rx_buffer: |
537 | for (i = 0; i < MAX_RCV_CTX; ++i) { | 588 | for (i = 0; i < MAX_RCV_CTX; ++i) { |
538 | recv_ctx = &adapter->recv_ctx[i]; | 589 | recv_ctx = &adapter->recv_ctx[i]; |
539 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 590 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { |
@@ -546,14 +597,16 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
546 | } | 597 | } |
547 | vfree(cmd_buf_arr); | 598 | vfree(cmd_buf_arr); |
548 | 599 | ||
549 | err_out_free_adapter: | 600 | err_out_free_adapter: |
601 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) | ||
602 | pci_disable_msi(pdev); | ||
603 | |||
550 | pci_set_drvdata(pdev, NULL); | 604 | pci_set_drvdata(pdev, NULL); |
551 | kfree(adapter); | ||
552 | 605 | ||
553 | if (db_ptr) | 606 | if (db_ptr) |
554 | iounmap(db_ptr); | 607 | iounmap(db_ptr); |
555 | 608 | ||
556 | err_out_iounmap: | 609 | err_out_iounmap: |
557 | if (mem_ptr0) | 610 | if (mem_ptr0) |
558 | iounmap(mem_ptr0); | 611 | iounmap(mem_ptr0); |
559 | if (mem_ptr1) | 612 | if (mem_ptr1) |
@@ -561,9 +614,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
561 | if (mem_ptr2) | 614 | if (mem_ptr2) |
562 | iounmap(mem_ptr2); | 615 | iounmap(mem_ptr2); |
563 | 616 | ||
564 | err_out_free_res: | 617 | err_out_free_netdev: |
618 | free_netdev(netdev); | ||
619 | |||
620 | err_out_free_res: | ||
565 | pci_release_regions(pdev); | 621 | pci_release_regions(pdev); |
566 | err_out_disable_pdev: | 622 | |
623 | err_out_disable_pdev: | ||
567 | pci_disable_device(pdev); | 624 | pci_disable_device(pdev); |
568 | return err; | 625 | return err; |
569 | } | 626 | } |
@@ -578,36 +635,39 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
578 | int i; | 635 | int i; |
579 | int ctxid, ring; | 636 | int ctxid, ring; |
580 | 637 | ||
581 | netdev = pci_get_drvdata(pdev); | 638 | adapter = pci_get_drvdata(pdev); |
582 | adapter = netdev_priv(netdev); | ||
583 | if (adapter == NULL) | 639 | if (adapter == NULL) |
584 | return; | 640 | return; |
585 | 641 | ||
642 | netdev = adapter->netdev; | ||
643 | |||
644 | netxen_nic_disable_int(adapter); | ||
645 | if (adapter->irq) | ||
646 | free_irq(adapter->irq, adapter); | ||
647 | |||
586 | if (adapter->stop_port) | 648 | if (adapter->stop_port) |
587 | adapter->stop_port(adapter); | 649 | adapter->stop_port(adapter); |
588 | 650 | ||
651 | if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) | ||
652 | pci_disable_msi(pdev); | ||
653 | |||
654 | if (adapter->portnum == 0) | ||
655 | netxen_free_adapter_offload(adapter); | ||
656 | |||
589 | if (adapter->irq) | 657 | if (adapter->irq) |
590 | free_irq(adapter->irq, adapter); | 658 | free_irq(adapter->irq, adapter); |
591 | if(adapter->portnum == 0) { | 659 | if(adapter->portnum == 0) { |
592 | /* leave the hw in the same state as reboot */ | 660 | /* leave the hw in the same state as reboot */ |
593 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 661 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); |
594 | netxen_pinit_from_rom(adapter, 0); | 662 | netxen_pinit_from_rom(adapter, 0); |
663 | udelay(500); | ||
595 | netxen_load_firmware(adapter); | 664 | netxen_load_firmware(adapter); |
596 | netxen_free_adapter_offload(adapter); | 665 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
597 | } | 666 | } |
598 | 667 | ||
599 | udelay(500); | ||
600 | |||
601 | if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) | ||
602 | pci_disable_msi(pdev); | ||
603 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) | 668 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) |
604 | netxen_free_hw_resources(adapter); | 669 | netxen_free_hw_resources(adapter); |
605 | 670 | ||
606 | iounmap(adapter->ahw.db_base); | ||
607 | iounmap(adapter->ahw.pci_base0); | ||
608 | iounmap(adapter->ahw.pci_base1); | ||
609 | iounmap(adapter->ahw.pci_base2); | ||
610 | |||
611 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | 671 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { |
612 | recv_ctx = &adapter->recv_ctx[ctxid]; | 672 | recv_ctx = &adapter->recv_ctx[ctxid]; |
613 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { | 673 | for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { |
@@ -626,14 +686,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
626 | } | 686 | } |
627 | } | 687 | } |
628 | 688 | ||
629 | vfree(adapter->cmd_buf_arr); | ||
630 | unregister_netdev(netdev); | 689 | unregister_netdev(netdev); |
631 | free_netdev(netdev); | 690 | |
691 | vfree(adapter->cmd_buf_arr); | ||
692 | |||
693 | iounmap(adapter->ahw.db_base); | ||
694 | iounmap(adapter->ahw.pci_base0); | ||
695 | iounmap(adapter->ahw.pci_base1); | ||
696 | iounmap(adapter->ahw.pci_base2); | ||
632 | 697 | ||
633 | pci_release_regions(pdev); | 698 | pci_release_regions(pdev); |
634 | pci_disable_device(pdev); | 699 | pci_disable_device(pdev); |
635 | pci_set_drvdata(pdev, NULL); | 700 | pci_set_drvdata(pdev, NULL); |
636 | 701 | ||
702 | free_netdev(netdev); | ||
637 | } | 703 | } |
638 | 704 | ||
639 | /* | 705 | /* |
@@ -668,9 +734,9 @@ static int netxen_nic_open(struct net_device *netdev) | |||
668 | netxen_post_rx_buffers(adapter, ctx, ring); | 734 | netxen_post_rx_buffers(adapter, ctx, ring); |
669 | } | 735 | } |
670 | adapter->irq = adapter->ahw.pdev->irq; | 736 | adapter->irq = adapter->ahw.pdev->irq; |
671 | err = request_irq(adapter->ahw.pdev->irq, &netxen_intr, | 737 | err = request_irq(adapter->ahw.pdev->irq, netxen_intr, |
672 | IRQF_SHARED | IRQF_SAMPLE_RANDOM, | 738 | SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, |
673 | netdev->name, adapter); | 739 | adapter); |
674 | if (err) { | 740 | if (err) { |
675 | printk(KERN_ERR "request_irq failed with: %d\n", err); | 741 | printk(KERN_ERR "request_irq failed with: %d\n", err); |
676 | netxen_free_hw_resources(adapter); | 742 | netxen_free_hw_resources(adapter); |
@@ -690,10 +756,9 @@ static int netxen_nic_open(struct net_device *netdev) | |||
690 | adapter->macaddr_set(adapter, netdev->dev_addr); | 756 | adapter->macaddr_set(adapter, netdev->dev_addr); |
691 | if (adapter->init_port | 757 | if (adapter->init_port |
692 | && adapter->init_port(adapter, adapter->portnum) != 0) { | 758 | && adapter->init_port(adapter, adapter->portnum) != 0) { |
759 | del_timer_sync(&adapter->watchdog_timer); | ||
693 | printk(KERN_ERR "%s: Failed to initialize port %d\n", | 760 | printk(KERN_ERR "%s: Failed to initialize port %d\n", |
694 | netxen_nic_driver_name, adapter->portnum); | 761 | netxen_nic_driver_name, adapter->portnum); |
695 | free_irq(adapter->irq, adapter); | ||
696 | netxen_free_hw_resources(adapter); | ||
697 | return -EIO; | 762 | return -EIO; |
698 | } | 763 | } |
699 | 764 | ||
@@ -722,10 +787,6 @@ static int netxen_nic_close(struct net_device *netdev) | |||
722 | netif_carrier_off(netdev); | 787 | netif_carrier_off(netdev); |
723 | netif_stop_queue(netdev); | 788 | netif_stop_queue(netdev); |
724 | 789 | ||
725 | netxen_nic_disable_int(adapter); | ||
726 | if (adapter->irq) | ||
727 | free_irq(adapter->irq, adapter); | ||
728 | |||
729 | cmd_buff = adapter->cmd_buf_arr; | 790 | cmd_buff = adapter->cmd_buf_arr; |
730 | for (i = 0; i < adapter->max_tx_desc_count; i++) { | 791 | for (i = 0; i < adapter->max_tx_desc_count; i++) { |
731 | buffrag = cmd_buff->frag_array; | 792 | buffrag = cmd_buff->frag_array; |
@@ -879,6 +940,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
879 | netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); | 940 | netxen_set_cmd_desc_opcode(hwdesc, TX_ETHER_PKT); |
880 | 941 | ||
881 | netxen_set_cmd_desc_port(hwdesc, adapter->portnum); | 942 | netxen_set_cmd_desc_port(hwdesc, adapter->portnum); |
943 | netxen_set_cmd_desc_ctxid(hwdesc, adapter->portnum); | ||
882 | hwdesc->buffer1_length = cpu_to_le16(first_seg_len); | 944 | hwdesc->buffer1_length = cpu_to_le16(first_seg_len); |
883 | hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); | 945 | hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma); |
884 | 946 | ||
@@ -968,9 +1030,18 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
968 | producer = get_next_index(producer, max_tx_desc_count); | 1030 | producer = get_next_index(producer, max_tx_desc_count); |
969 | } | 1031 | } |
970 | } | 1032 | } |
1033 | |||
1034 | i = netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); | ||
1035 | |||
1036 | hw->cmd_desc_head[saved_producer].flags_opcode = | ||
1037 | cpu_to_le16(hw->cmd_desc_head[saved_producer].flags_opcode); | ||
1038 | hw->cmd_desc_head[saved_producer].num_of_buffers_total_length = | ||
1039 | cpu_to_le32(hw->cmd_desc_head[saved_producer]. | ||
1040 | num_of_buffers_total_length); | ||
1041 | |||
971 | spin_lock_bh(&adapter->tx_lock); | 1042 | spin_lock_bh(&adapter->tx_lock); |
972 | adapter->stats.txbytes += | 1043 | adapter->stats.txbytes += i; |
973 | netxen_get_cmd_desc_totallength(&hw->cmd_desc_head[saved_producer]); | 1044 | |
974 | /* Code to update the adapter considering how many producer threads | 1045 | /* Code to update the adapter considering how many producer threads |
975 | are currently working */ | 1046 | are currently working */ |
976 | if ((--adapter->num_threads) == 0) { | 1047 | if ((--adapter->num_threads) == 0) { |
@@ -1010,18 +1081,17 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1010 | { | 1081 | { |
1011 | struct netxen_adapter *adapter = | 1082 | struct netxen_adapter *adapter = |
1012 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1083 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1013 | struct net_device *netdev = adapter->netdev; | ||
1014 | unsigned long flags; | 1084 | unsigned long flags; |
1015 | 1085 | ||
1016 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1086 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1017 | netxen_nic_driver_name, netdev->name); | 1087 | netxen_nic_driver_name, adapter->netdev->name); |
1018 | 1088 | ||
1019 | spin_lock_irqsave(&adapter->lock, flags); | 1089 | spin_lock_irqsave(&adapter->lock, flags); |
1020 | netxen_nic_close(netdev); | 1090 | netxen_nic_close(adapter->netdev); |
1021 | netxen_nic_open(netdev); | 1091 | netxen_nic_open(adapter->netdev); |
1022 | spin_unlock_irqrestore(&adapter->lock, flags); | 1092 | spin_unlock_irqrestore(&adapter->lock, flags); |
1023 | netdev->trans_start = jiffies; | 1093 | adapter->netdev->trans_start = jiffies; |
1024 | netif_wake_queue(netdev); | 1094 | netif_wake_queue(adapter->netdev); |
1025 | } | 1095 | } |
1026 | 1096 | ||
1027 | static int | 1097 | static int |