diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 579 |
1 files changed, 245 insertions, 334 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index b787b6582e50..2671da20a496 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -9,13 +9,54 @@ | |||
9 | * Written by: Michael Chan (mchan@broadcom.com) | 9 | * Written by: Michael Chan (mchan@broadcom.com) |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/config.h> | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/timer.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/ioport.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/vmalloc.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/dma-mapping.h> | ||
30 | #include <asm/bitops.h> | ||
31 | #include <asm/io.h> | ||
32 | #include <asm/irq.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <asm/byteorder.h> | ||
35 | #include <linux/time.h> | ||
36 | #include <linux/ethtool.h> | ||
37 | #include <linux/mii.h> | ||
38 | #ifdef NETIF_F_HW_VLAN_TX | ||
39 | #include <linux/if_vlan.h> | ||
40 | #define BCM_VLAN 1 | ||
41 | #endif | ||
42 | #ifdef NETIF_F_TSO | ||
43 | #include <net/ip.h> | ||
44 | #include <net/tcp.h> | ||
45 | #include <net/checksum.h> | ||
46 | #define BCM_TSO 1 | ||
47 | #endif | ||
48 | #include <linux/workqueue.h> | ||
49 | #include <linux/crc32.h> | ||
50 | #include <linux/prefetch.h> | ||
51 | #include <linux/cache.h> | ||
52 | |||
12 | #include "bnx2.h" | 53 | #include "bnx2.h" |
13 | #include "bnx2_fw.h" | 54 | #include "bnx2_fw.h" |
14 | 55 | ||
15 | #define DRV_MODULE_NAME "bnx2" | 56 | #define DRV_MODULE_NAME "bnx2" |
16 | #define PFX DRV_MODULE_NAME ": " | 57 | #define PFX DRV_MODULE_NAME ": " |
17 | #define DRV_MODULE_VERSION "1.4.31" | 58 | #define DRV_MODULE_VERSION "1.4.39" |
18 | #define DRV_MODULE_RELDATE "January 19, 2006" | 59 | #define DRV_MODULE_RELDATE "March 22, 2006" |
19 | 60 | ||
20 | #define RUN_AT(x) (jiffies + (x)) | 61 | #define RUN_AT(x) (jiffies + (x)) |
21 | 62 | ||
@@ -313,8 +354,6 @@ bnx2_disable_int(struct bnx2 *bp) | |||
313 | static void | 354 | static void |
314 | bnx2_enable_int(struct bnx2 *bp) | 355 | bnx2_enable_int(struct bnx2 *bp) |
315 | { | 356 | { |
316 | u32 val; | ||
317 | |||
318 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 357 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
319 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | | 358 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | |
320 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); | 359 | BNX2_PCICFG_INT_ACK_CMD_MASK_INT | bp->last_status_idx); |
@@ -322,8 +361,7 @@ bnx2_enable_int(struct bnx2 *bp) | |||
322 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, | 361 | REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, |
323 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); | 362 | BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); |
324 | 363 | ||
325 | val = REG_RD(bp, BNX2_HC_COMMAND); | 364 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); |
326 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); | ||
327 | } | 365 | } |
328 | 366 | ||
329 | static void | 367 | static void |
@@ -360,15 +398,13 @@ bnx2_netif_start(struct bnx2 *bp) | |||
360 | static void | 398 | static void |
361 | bnx2_free_mem(struct bnx2 *bp) | 399 | bnx2_free_mem(struct bnx2 *bp) |
362 | { | 400 | { |
363 | if (bp->stats_blk) { | 401 | int i; |
364 | pci_free_consistent(bp->pdev, sizeof(struct statistics_block), | 402 | |
365 | bp->stats_blk, bp->stats_blk_mapping); | ||
366 | bp->stats_blk = NULL; | ||
367 | } | ||
368 | if (bp->status_blk) { | 403 | if (bp->status_blk) { |
369 | pci_free_consistent(bp->pdev, sizeof(struct status_block), | 404 | pci_free_consistent(bp->pdev, bp->status_stats_size, |
370 | bp->status_blk, bp->status_blk_mapping); | 405 | bp->status_blk, bp->status_blk_mapping); |
371 | bp->status_blk = NULL; | 406 | bp->status_blk = NULL; |
407 | bp->stats_blk = NULL; | ||
372 | } | 408 | } |
373 | if (bp->tx_desc_ring) { | 409 | if (bp->tx_desc_ring) { |
374 | pci_free_consistent(bp->pdev, | 410 | pci_free_consistent(bp->pdev, |
@@ -378,25 +414,28 @@ bnx2_free_mem(struct bnx2 *bp) | |||
378 | } | 414 | } |
379 | kfree(bp->tx_buf_ring); | 415 | kfree(bp->tx_buf_ring); |
380 | bp->tx_buf_ring = NULL; | 416 | bp->tx_buf_ring = NULL; |
381 | if (bp->rx_desc_ring) { | 417 | for (i = 0; i < bp->rx_max_ring; i++) { |
382 | pci_free_consistent(bp->pdev, | 418 | if (bp->rx_desc_ring[i]) |
383 | sizeof(struct rx_bd) * RX_DESC_CNT, | 419 | pci_free_consistent(bp->pdev, |
384 | bp->rx_desc_ring, bp->rx_desc_mapping); | 420 | sizeof(struct rx_bd) * RX_DESC_CNT, |
385 | bp->rx_desc_ring = NULL; | 421 | bp->rx_desc_ring[i], |
386 | } | 422 | bp->rx_desc_mapping[i]); |
387 | kfree(bp->rx_buf_ring); | 423 | bp->rx_desc_ring[i] = NULL; |
424 | } | ||
425 | vfree(bp->rx_buf_ring); | ||
388 | bp->rx_buf_ring = NULL; | 426 | bp->rx_buf_ring = NULL; |
389 | } | 427 | } |
390 | 428 | ||
391 | static int | 429 | static int |
392 | bnx2_alloc_mem(struct bnx2 *bp) | 430 | bnx2_alloc_mem(struct bnx2 *bp) |
393 | { | 431 | { |
394 | bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT, | 432 | int i, status_blk_size; |
395 | GFP_KERNEL); | 433 | |
434 | bp->tx_buf_ring = kzalloc(sizeof(struct sw_bd) * TX_DESC_CNT, | ||
435 | GFP_KERNEL); | ||
396 | if (bp->tx_buf_ring == NULL) | 436 | if (bp->tx_buf_ring == NULL) |
397 | return -ENOMEM; | 437 | return -ENOMEM; |
398 | 438 | ||
399 | memset(bp->tx_buf_ring, 0, sizeof(struct sw_bd) * TX_DESC_CNT); | ||
400 | bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, | 439 | bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, |
401 | sizeof(struct tx_bd) * | 440 | sizeof(struct tx_bd) * |
402 | TX_DESC_CNT, | 441 | TX_DESC_CNT, |
@@ -404,34 +443,40 @@ bnx2_alloc_mem(struct bnx2 *bp) | |||
404 | if (bp->tx_desc_ring == NULL) | 443 | if (bp->tx_desc_ring == NULL) |
405 | goto alloc_mem_err; | 444 | goto alloc_mem_err; |
406 | 445 | ||
407 | bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT, | 446 | bp->rx_buf_ring = vmalloc(sizeof(struct sw_bd) * RX_DESC_CNT * |
408 | GFP_KERNEL); | 447 | bp->rx_max_ring); |
409 | if (bp->rx_buf_ring == NULL) | 448 | if (bp->rx_buf_ring == NULL) |
410 | goto alloc_mem_err; | 449 | goto alloc_mem_err; |
411 | 450 | ||
412 | memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT); | 451 | memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT * |
413 | bp->rx_desc_ring = pci_alloc_consistent(bp->pdev, | 452 | bp->rx_max_ring); |
414 | sizeof(struct rx_bd) * | 453 | |
415 | RX_DESC_CNT, | 454 | for (i = 0; i < bp->rx_max_ring; i++) { |
416 | &bp->rx_desc_mapping); | 455 | bp->rx_desc_ring[i] = |
417 | if (bp->rx_desc_ring == NULL) | 456 | pci_alloc_consistent(bp->pdev, |
418 | goto alloc_mem_err; | 457 | sizeof(struct rx_bd) * RX_DESC_CNT, |
458 | &bp->rx_desc_mapping[i]); | ||
459 | if (bp->rx_desc_ring[i] == NULL) | ||
460 | goto alloc_mem_err; | ||
461 | |||
462 | } | ||
463 | |||
464 | /* Combine status and statistics blocks into one allocation. */ | ||
465 | status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block)); | ||
466 | bp->status_stats_size = status_blk_size + | ||
467 | sizeof(struct statistics_block); | ||
419 | 468 | ||
420 | bp->status_blk = pci_alloc_consistent(bp->pdev, | 469 | bp->status_blk = pci_alloc_consistent(bp->pdev, bp->status_stats_size, |
421 | sizeof(struct status_block), | ||
422 | &bp->status_blk_mapping); | 470 | &bp->status_blk_mapping); |
423 | if (bp->status_blk == NULL) | 471 | if (bp->status_blk == NULL) |
424 | goto alloc_mem_err; | 472 | goto alloc_mem_err; |
425 | 473 | ||
426 | memset(bp->status_blk, 0, sizeof(struct status_block)); | 474 | memset(bp->status_blk, 0, bp->status_stats_size); |
427 | 475 | ||
428 | bp->stats_blk = pci_alloc_consistent(bp->pdev, | 476 | bp->stats_blk = (void *) ((unsigned long) bp->status_blk + |
429 | sizeof(struct statistics_block), | 477 | status_blk_size); |
430 | &bp->stats_blk_mapping); | ||
431 | if (bp->stats_blk == NULL) | ||
432 | goto alloc_mem_err; | ||
433 | 478 | ||
434 | memset(bp->stats_blk, 0, sizeof(struct statistics_block)); | 479 | bp->stats_blk_mapping = bp->status_blk_mapping + status_blk_size; |
435 | 480 | ||
436 | return 0; | 481 | return 0; |
437 | 482 | ||
@@ -1520,7 +1565,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) | |||
1520 | struct sk_buff *skb; | 1565 | struct sk_buff *skb; |
1521 | struct sw_bd *rx_buf = &bp->rx_buf_ring[index]; | 1566 | struct sw_bd *rx_buf = &bp->rx_buf_ring[index]; |
1522 | dma_addr_t mapping; | 1567 | dma_addr_t mapping; |
1523 | struct rx_bd *rxbd = &bp->rx_desc_ring[index]; | 1568 | struct rx_bd *rxbd = &bp->rx_desc_ring[RX_RING(index)][RX_IDX(index)]; |
1524 | unsigned long align; | 1569 | unsigned long align; |
1525 | 1570 | ||
1526 | skb = dev_alloc_skb(bp->rx_buf_size); | 1571 | skb = dev_alloc_skb(bp->rx_buf_size); |
@@ -1656,23 +1701,30 @@ static inline void | |||
1656 | bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, | 1701 | bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, |
1657 | u16 cons, u16 prod) | 1702 | u16 cons, u16 prod) |
1658 | { | 1703 | { |
1659 | struct sw_bd *cons_rx_buf = &bp->rx_buf_ring[cons]; | 1704 | struct sw_bd *cons_rx_buf, *prod_rx_buf; |
1660 | struct sw_bd *prod_rx_buf = &bp->rx_buf_ring[prod]; | 1705 | struct rx_bd *cons_bd, *prod_bd; |
1661 | struct rx_bd *cons_bd = &bp->rx_desc_ring[cons]; | 1706 | |
1662 | struct rx_bd *prod_bd = &bp->rx_desc_ring[prod]; | 1707 | cons_rx_buf = &bp->rx_buf_ring[cons]; |
1708 | prod_rx_buf = &bp->rx_buf_ring[prod]; | ||
1663 | 1709 | ||
1664 | pci_dma_sync_single_for_device(bp->pdev, | 1710 | pci_dma_sync_single_for_device(bp->pdev, |
1665 | pci_unmap_addr(cons_rx_buf, mapping), | 1711 | pci_unmap_addr(cons_rx_buf, mapping), |
1666 | bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); | 1712 | bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); |
1667 | 1713 | ||
1668 | prod_rx_buf->skb = cons_rx_buf->skb; | 1714 | bp->rx_prod_bseq += bp->rx_buf_use_size; |
1669 | pci_unmap_addr_set(prod_rx_buf, mapping, | ||
1670 | pci_unmap_addr(cons_rx_buf, mapping)); | ||
1671 | 1715 | ||
1672 | memcpy(prod_bd, cons_bd, 8); | 1716 | prod_rx_buf->skb = skb; |
1673 | 1717 | ||
1674 | bp->rx_prod_bseq += bp->rx_buf_use_size; | 1718 | if (cons == prod) |
1719 | return; | ||
1675 | 1720 | ||
1721 | pci_unmap_addr_set(prod_rx_buf, mapping, | ||
1722 | pci_unmap_addr(cons_rx_buf, mapping)); | ||
1723 | |||
1724 | cons_bd = &bp->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)]; | ||
1725 | prod_bd = &bp->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)]; | ||
1726 | prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi; | ||
1727 | prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo; | ||
1676 | } | 1728 | } |
1677 | 1729 | ||
1678 | static int | 1730 | static int |
@@ -1699,14 +1751,19 @@ bnx2_rx_int(struct bnx2 *bp, int budget) | |||
1699 | u32 status; | 1751 | u32 status; |
1700 | struct sw_bd *rx_buf; | 1752 | struct sw_bd *rx_buf; |
1701 | struct sk_buff *skb; | 1753 | struct sk_buff *skb; |
1754 | dma_addr_t dma_addr; | ||
1702 | 1755 | ||
1703 | sw_ring_cons = RX_RING_IDX(sw_cons); | 1756 | sw_ring_cons = RX_RING_IDX(sw_cons); |
1704 | sw_ring_prod = RX_RING_IDX(sw_prod); | 1757 | sw_ring_prod = RX_RING_IDX(sw_prod); |
1705 | 1758 | ||
1706 | rx_buf = &bp->rx_buf_ring[sw_ring_cons]; | 1759 | rx_buf = &bp->rx_buf_ring[sw_ring_cons]; |
1707 | skb = rx_buf->skb; | 1760 | skb = rx_buf->skb; |
1708 | pci_dma_sync_single_for_cpu(bp->pdev, | 1761 | |
1709 | pci_unmap_addr(rx_buf, mapping), | 1762 | rx_buf->skb = NULL; |
1763 | |||
1764 | dma_addr = pci_unmap_addr(rx_buf, mapping); | ||
1765 | |||
1766 | pci_dma_sync_single_for_cpu(bp->pdev, dma_addr, | ||
1710 | bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); | 1767 | bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); |
1711 | 1768 | ||
1712 | rx_hdr = (struct l2_fhdr *) skb->data; | 1769 | rx_hdr = (struct l2_fhdr *) skb->data; |
@@ -1747,8 +1804,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget) | |||
1747 | skb = new_skb; | 1804 | skb = new_skb; |
1748 | } | 1805 | } |
1749 | else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) { | 1806 | else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) { |
1750 | pci_unmap_single(bp->pdev, | 1807 | pci_unmap_single(bp->pdev, dma_addr, |
1751 | pci_unmap_addr(rx_buf, mapping), | ||
1752 | bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); | 1808 | bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); |
1753 | 1809 | ||
1754 | skb_reserve(skb, bp->rx_offset); | 1810 | skb_reserve(skb, bp->rx_offset); |
@@ -1794,8 +1850,6 @@ reuse_rx: | |||
1794 | rx_pkt++; | 1850 | rx_pkt++; |
1795 | 1851 | ||
1796 | next_rx: | 1852 | next_rx: |
1797 | rx_buf->skb = NULL; | ||
1798 | |||
1799 | sw_cons = NEXT_RX_BD(sw_cons); | 1853 | sw_cons = NEXT_RX_BD(sw_cons); |
1800 | sw_prod = NEXT_RX_BD(sw_prod); | 1854 | sw_prod = NEXT_RX_BD(sw_prod); |
1801 | 1855 | ||
@@ -1906,6 +1960,13 @@ bnx2_poll(struct net_device *dev, int *budget) | |||
1906 | spin_lock(&bp->phy_lock); | 1960 | spin_lock(&bp->phy_lock); |
1907 | bnx2_phy_int(bp); | 1961 | bnx2_phy_int(bp); |
1908 | spin_unlock(&bp->phy_lock); | 1962 | spin_unlock(&bp->phy_lock); |
1963 | |||
1964 | /* This is needed to take care of transient status | ||
1965 | * during link changes. | ||
1966 | */ | ||
1967 | REG_WR(bp, BNX2_HC_COMMAND, | ||
1968 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | ||
1969 | REG_RD(bp, BNX2_HC_COMMAND); | ||
1909 | } | 1970 | } |
1910 | 1971 | ||
1911 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) | 1972 | if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons) |
@@ -3287,6 +3348,8 @@ bnx2_init_chip(struct bnx2 *bp) | |||
3287 | 3348 | ||
3288 | udelay(20); | 3349 | udelay(20); |
3289 | 3350 | ||
3351 | bp->hc_cmd = REG_RD(bp, BNX2_HC_COMMAND); | ||
3352 | |||
3290 | return rc; | 3353 | return rc; |
3291 | } | 3354 | } |
3292 | 3355 | ||
@@ -3340,27 +3403,35 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
3340 | bp->hw_rx_cons = 0; | 3403 | bp->hw_rx_cons = 0; |
3341 | bp->rx_prod_bseq = 0; | 3404 | bp->rx_prod_bseq = 0; |
3342 | 3405 | ||
3343 | rxbd = &bp->rx_desc_ring[0]; | 3406 | for (i = 0; i < bp->rx_max_ring; i++) { |
3344 | for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { | 3407 | int j; |
3345 | rxbd->rx_bd_len = bp->rx_buf_use_size; | ||
3346 | rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; | ||
3347 | } | ||
3348 | 3408 | ||
3349 | rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32; | 3409 | rxbd = &bp->rx_desc_ring[i][0]; |
3350 | rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; | 3410 | for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) { |
3411 | rxbd->rx_bd_len = bp->rx_buf_use_size; | ||
3412 | rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; | ||
3413 | } | ||
3414 | if (i == (bp->rx_max_ring - 1)) | ||
3415 | j = 0; | ||
3416 | else | ||
3417 | j = i + 1; | ||
3418 | rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping[j] >> 32; | ||
3419 | rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping[j] & | ||
3420 | 0xffffffff; | ||
3421 | } | ||
3351 | 3422 | ||
3352 | val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; | 3423 | val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; |
3353 | val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; | 3424 | val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; |
3354 | val |= 0x02 << 8; | 3425 | val |= 0x02 << 8; |
3355 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); | 3426 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); |
3356 | 3427 | ||
3357 | val = (u64) bp->rx_desc_mapping >> 32; | 3428 | val = (u64) bp->rx_desc_mapping[0] >> 32; |
3358 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val); | 3429 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val); |
3359 | 3430 | ||
3360 | val = (u64) bp->rx_desc_mapping & 0xffffffff; | 3431 | val = (u64) bp->rx_desc_mapping[0] & 0xffffffff; |
3361 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); | 3432 | CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); |
3362 | 3433 | ||
3363 | for ( ;ring_prod < bp->rx_ring_size; ) { | 3434 | for (i = 0; i < bp->rx_ring_size; i++) { |
3364 | if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) { | 3435 | if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) { |
3365 | break; | 3436 | break; |
3366 | } | 3437 | } |
@@ -3375,6 +3446,29 @@ bnx2_init_rx_ring(struct bnx2 *bp) | |||
3375 | } | 3446 | } |
3376 | 3447 | ||
3377 | static void | 3448 | static void |
3449 | bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size) | ||
3450 | { | ||
3451 | u32 num_rings, max; | ||
3452 | |||
3453 | bp->rx_ring_size = size; | ||
3454 | num_rings = 1; | ||
3455 | while (size > MAX_RX_DESC_CNT) { | ||
3456 | size -= MAX_RX_DESC_CNT; | ||
3457 | num_rings++; | ||
3458 | } | ||
3459 | /* round to next power of 2 */ | ||
3460 | max = MAX_RX_RINGS; | ||
3461 | while ((max & num_rings) == 0) | ||
3462 | max >>= 1; | ||
3463 | |||
3464 | if (num_rings != max) | ||
3465 | max <<= 1; | ||
3466 | |||
3467 | bp->rx_max_ring = max; | ||
3468 | bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1; | ||
3469 | } | ||
3470 | |||
3471 | static void | ||
3378 | bnx2_free_tx_skbs(struct bnx2 *bp) | 3472 | bnx2_free_tx_skbs(struct bnx2 *bp) |
3379 | { | 3473 | { |
3380 | int i; | 3474 | int i; |
@@ -3419,7 +3513,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp) | |||
3419 | if (bp->rx_buf_ring == NULL) | 3513 | if (bp->rx_buf_ring == NULL) |
3420 | return; | 3514 | return; |
3421 | 3515 | ||
3422 | for (i = 0; i < RX_DESC_CNT; i++) { | 3516 | for (i = 0; i < bp->rx_max_ring_idx; i++) { |
3423 | struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; | 3517 | struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; |
3424 | struct sk_buff *skb = rx_buf->skb; | 3518 | struct sk_buff *skb = rx_buf->skb; |
3425 | 3519 | ||
@@ -3506,74 +3600,9 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3506 | { 0x0c00, 0, 0x00000000, 0x00000001 }, | 3600 | { 0x0c00, 0, 0x00000000, 0x00000001 }, |
3507 | { 0x0c04, 0, 0x00000000, 0x03ff0001 }, | 3601 | { 0x0c04, 0, 0x00000000, 0x03ff0001 }, |
3508 | { 0x0c08, 0, 0x0f0ff073, 0x00000000 }, | 3602 | { 0x0c08, 0, 0x0f0ff073, 0x00000000 }, |
3509 | { 0x0c0c, 0, 0x00ffffff, 0x00000000 }, | ||
3510 | { 0x0c30, 0, 0x00000000, 0xffffffff }, | ||
3511 | { 0x0c34, 0, 0x00000000, 0xffffffff }, | ||
3512 | { 0x0c38, 0, 0x00000000, 0xffffffff }, | ||
3513 | { 0x0c3c, 0, 0x00000000, 0xffffffff }, | ||
3514 | { 0x0c40, 0, 0x00000000, 0xffffffff }, | ||
3515 | { 0x0c44, 0, 0x00000000, 0xffffffff }, | ||
3516 | { 0x0c48, 0, 0x00000000, 0x0007ffff }, | ||
3517 | { 0x0c4c, 0, 0x00000000, 0xffffffff }, | ||
3518 | { 0x0c50, 0, 0x00000000, 0xffffffff }, | ||
3519 | { 0x0c54, 0, 0x00000000, 0xffffffff }, | ||
3520 | { 0x0c58, 0, 0x00000000, 0xffffffff }, | ||
3521 | { 0x0c5c, 0, 0x00000000, 0xffffffff }, | ||
3522 | { 0x0c60, 0, 0x00000000, 0xffffffff }, | ||
3523 | { 0x0c64, 0, 0x00000000, 0xffffffff }, | ||
3524 | { 0x0c68, 0, 0x00000000, 0xffffffff }, | ||
3525 | { 0x0c6c, 0, 0x00000000, 0xffffffff }, | ||
3526 | { 0x0c70, 0, 0x00000000, 0xffffffff }, | ||
3527 | { 0x0c74, 0, 0x00000000, 0xffffffff }, | ||
3528 | { 0x0c78, 0, 0x00000000, 0xffffffff }, | ||
3529 | { 0x0c7c, 0, 0x00000000, 0xffffffff }, | ||
3530 | { 0x0c80, 0, 0x00000000, 0xffffffff }, | ||
3531 | { 0x0c84, 0, 0x00000000, 0xffffffff }, | ||
3532 | { 0x0c88, 0, 0x00000000, 0xffffffff }, | ||
3533 | { 0x0c8c, 0, 0x00000000, 0xffffffff }, | ||
3534 | { 0x0c90, 0, 0x00000000, 0xffffffff }, | ||
3535 | { 0x0c94, 0, 0x00000000, 0xffffffff }, | ||
3536 | { 0x0c98, 0, 0x00000000, 0xffffffff }, | ||
3537 | { 0x0c9c, 0, 0x00000000, 0xffffffff }, | ||
3538 | { 0x0ca0, 0, 0x00000000, 0xffffffff }, | ||
3539 | { 0x0ca4, 0, 0x00000000, 0xffffffff }, | ||
3540 | { 0x0ca8, 0, 0x00000000, 0x0007ffff }, | ||
3541 | { 0x0cac, 0, 0x00000000, 0xffffffff }, | ||
3542 | { 0x0cb0, 0, 0x00000000, 0xffffffff }, | ||
3543 | { 0x0cb4, 0, 0x00000000, 0xffffffff }, | ||
3544 | { 0x0cb8, 0, 0x00000000, 0xffffffff }, | ||
3545 | { 0x0cbc, 0, 0x00000000, 0xffffffff }, | ||
3546 | { 0x0cc0, 0, 0x00000000, 0xffffffff }, | ||
3547 | { 0x0cc4, 0, 0x00000000, 0xffffffff }, | ||
3548 | { 0x0cc8, 0, 0x00000000, 0xffffffff }, | ||
3549 | { 0x0ccc, 0, 0x00000000, 0xffffffff }, | ||
3550 | { 0x0cd0, 0, 0x00000000, 0xffffffff }, | ||
3551 | { 0x0cd4, 0, 0x00000000, 0xffffffff }, | ||
3552 | { 0x0cd8, 0, 0x00000000, 0xffffffff }, | ||
3553 | { 0x0cdc, 0, 0x00000000, 0xffffffff }, | ||
3554 | { 0x0ce0, 0, 0x00000000, 0xffffffff }, | ||
3555 | { 0x0ce4, 0, 0x00000000, 0xffffffff }, | ||
3556 | { 0x0ce8, 0, 0x00000000, 0xffffffff }, | ||
3557 | { 0x0cec, 0, 0x00000000, 0xffffffff }, | ||
3558 | { 0x0cf0, 0, 0x00000000, 0xffffffff }, | ||
3559 | { 0x0cf4, 0, 0x00000000, 0xffffffff }, | ||
3560 | { 0x0cf8, 0, 0x00000000, 0xffffffff }, | ||
3561 | { 0x0cfc, 0, 0x00000000, 0xffffffff }, | ||
3562 | { 0x0d00, 0, 0x00000000, 0xffffffff }, | ||
3563 | { 0x0d04, 0, 0x00000000, 0xffffffff }, | ||
3564 | 3603 | ||
3565 | { 0x1000, 0, 0x00000000, 0x00000001 }, | 3604 | { 0x1000, 0, 0x00000000, 0x00000001 }, |
3566 | { 0x1004, 0, 0x00000000, 0x000f0001 }, | 3605 | { 0x1004, 0, 0x00000000, 0x000f0001 }, |
3567 | { 0x1044, 0, 0x00000000, 0xffc003ff }, | ||
3568 | { 0x1080, 0, 0x00000000, 0x0001ffff }, | ||
3569 | { 0x1084, 0, 0x00000000, 0xffffffff }, | ||
3570 | { 0x1088, 0, 0x00000000, 0xffffffff }, | ||
3571 | { 0x108c, 0, 0x00000000, 0xffffffff }, | ||
3572 | { 0x1090, 0, 0x00000000, 0xffffffff }, | ||
3573 | { 0x1094, 0, 0x00000000, 0xffffffff }, | ||
3574 | { 0x1098, 0, 0x00000000, 0xffffffff }, | ||
3575 | { 0x109c, 0, 0x00000000, 0xffffffff }, | ||
3576 | { 0x10a0, 0, 0x00000000, 0xffffffff }, | ||
3577 | 3606 | ||
3578 | { 0x1408, 0, 0x01c00800, 0x00000000 }, | 3607 | { 0x1408, 0, 0x01c00800, 0x00000000 }, |
3579 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, | 3608 | { 0x149c, 0, 0x8000ffff, 0x00000000 }, |
@@ -3585,111 +3614,9 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3585 | { 0x14c4, 0, 0x00003fff, 0x00000000 }, | 3614 | { 0x14c4, 0, 0x00003fff, 0x00000000 }, |
3586 | { 0x14cc, 0, 0x00000000, 0x00000001 }, | 3615 | { 0x14cc, 0, 0x00000000, 0x00000001 }, |
3587 | { 0x14d0, 0, 0xffffffff, 0x00000000 }, | 3616 | { 0x14d0, 0, 0xffffffff, 0x00000000 }, |
3588 | { 0x1500, 0, 0x00000000, 0xffffffff }, | ||
3589 | { 0x1504, 0, 0x00000000, 0xffffffff }, | ||
3590 | { 0x1508, 0, 0x00000000, 0xffffffff }, | ||
3591 | { 0x150c, 0, 0x00000000, 0xffffffff }, | ||
3592 | { 0x1510, 0, 0x00000000, 0xffffffff }, | ||
3593 | { 0x1514, 0, 0x00000000, 0xffffffff }, | ||
3594 | { 0x1518, 0, 0x00000000, 0xffffffff }, | ||
3595 | { 0x151c, 0, 0x00000000, 0xffffffff }, | ||
3596 | { 0x1520, 0, 0x00000000, 0xffffffff }, | ||
3597 | { 0x1524, 0, 0x00000000, 0xffffffff }, | ||
3598 | { 0x1528, 0, 0x00000000, 0xffffffff }, | ||
3599 | { 0x152c, 0, 0x00000000, 0xffffffff }, | ||
3600 | { 0x1530, 0, 0x00000000, 0xffffffff }, | ||
3601 | { 0x1534, 0, 0x00000000, 0xffffffff }, | ||
3602 | { 0x1538, 0, 0x00000000, 0xffffffff }, | ||
3603 | { 0x153c, 0, 0x00000000, 0xffffffff }, | ||
3604 | { 0x1540, 0, 0x00000000, 0xffffffff }, | ||
3605 | { 0x1544, 0, 0x00000000, 0xffffffff }, | ||
3606 | { 0x1548, 0, 0x00000000, 0xffffffff }, | ||
3607 | { 0x154c, 0, 0x00000000, 0xffffffff }, | ||
3608 | { 0x1550, 0, 0x00000000, 0xffffffff }, | ||
3609 | { 0x1554, 0, 0x00000000, 0xffffffff }, | ||
3610 | { 0x1558, 0, 0x00000000, 0xffffffff }, | ||
3611 | { 0x1600, 0, 0x00000000, 0xffffffff }, | ||
3612 | { 0x1604, 0, 0x00000000, 0xffffffff }, | ||
3613 | { 0x1608, 0, 0x00000000, 0xffffffff }, | ||
3614 | { 0x160c, 0, 0x00000000, 0xffffffff }, | ||
3615 | { 0x1610, 0, 0x00000000, 0xffffffff }, | ||
3616 | { 0x1614, 0, 0x00000000, 0xffffffff }, | ||
3617 | { 0x1618, 0, 0x00000000, 0xffffffff }, | ||
3618 | { 0x161c, 0, 0x00000000, 0xffffffff }, | ||
3619 | { 0x1620, 0, 0x00000000, 0xffffffff }, | ||
3620 | { 0x1624, 0, 0x00000000, 0xffffffff }, | ||
3621 | { 0x1628, 0, 0x00000000, 0xffffffff }, | ||
3622 | { 0x162c, 0, 0x00000000, 0xffffffff }, | ||
3623 | { 0x1630, 0, 0x00000000, 0xffffffff }, | ||
3624 | { 0x1634, 0, 0x00000000, 0xffffffff }, | ||
3625 | { 0x1638, 0, 0x00000000, 0xffffffff }, | ||
3626 | { 0x163c, 0, 0x00000000, 0xffffffff }, | ||
3627 | { 0x1640, 0, 0x00000000, 0xffffffff }, | ||
3628 | { 0x1644, 0, 0x00000000, 0xffffffff }, | ||
3629 | { 0x1648, 0, 0x00000000, 0xffffffff }, | ||
3630 | { 0x164c, 0, 0x00000000, 0xffffffff }, | ||
3631 | { 0x1650, 0, 0x00000000, 0xffffffff }, | ||
3632 | { 0x1654, 0, 0x00000000, 0xffffffff }, | ||
3633 | 3617 | ||
3634 | { 0x1800, 0, 0x00000000, 0x00000001 }, | 3618 | { 0x1800, 0, 0x00000000, 0x00000001 }, |
3635 | { 0x1804, 0, 0x00000000, 0x00000003 }, | 3619 | { 0x1804, 0, 0x00000000, 0x00000003 }, |
3636 | { 0x1840, 0, 0x00000000, 0xffffffff }, | ||
3637 | { 0x1844, 0, 0x00000000, 0xffffffff }, | ||
3638 | { 0x1848, 0, 0x00000000, 0xffffffff }, | ||
3639 | { 0x184c, 0, 0x00000000, 0xffffffff }, | ||
3640 | { 0x1850, 0, 0x00000000, 0xffffffff }, | ||
3641 | { 0x1900, 0, 0x7ffbffff, 0x00000000 }, | ||
3642 | { 0x1904, 0, 0xffffffff, 0x00000000 }, | ||
3643 | { 0x190c, 0, 0xffffffff, 0x00000000 }, | ||
3644 | { 0x1914, 0, 0xffffffff, 0x00000000 }, | ||
3645 | { 0x191c, 0, 0xffffffff, 0x00000000 }, | ||
3646 | { 0x1924, 0, 0xffffffff, 0x00000000 }, | ||
3647 | { 0x192c, 0, 0xffffffff, 0x00000000 }, | ||
3648 | { 0x1934, 0, 0xffffffff, 0x00000000 }, | ||
3649 | { 0x193c, 0, 0xffffffff, 0x00000000 }, | ||
3650 | { 0x1944, 0, 0xffffffff, 0x00000000 }, | ||
3651 | { 0x194c, 0, 0xffffffff, 0x00000000 }, | ||
3652 | { 0x1954, 0, 0xffffffff, 0x00000000 }, | ||
3653 | { 0x195c, 0, 0xffffffff, 0x00000000 }, | ||
3654 | { 0x1964, 0, 0xffffffff, 0x00000000 }, | ||
3655 | { 0x196c, 0, 0xffffffff, 0x00000000 }, | ||
3656 | { 0x1974, 0, 0xffffffff, 0x00000000 }, | ||
3657 | { 0x197c, 0, 0xffffffff, 0x00000000 }, | ||
3658 | { 0x1980, 0, 0x0700ffff, 0x00000000 }, | ||
3659 | |||
3660 | { 0x1c00, 0, 0x00000000, 0x00000001 }, | ||
3661 | { 0x1c04, 0, 0x00000000, 0x00000003 }, | ||
3662 | { 0x1c08, 0, 0x0000000f, 0x00000000 }, | ||
3663 | { 0x1c40, 0, 0x00000000, 0xffffffff }, | ||
3664 | { 0x1c44, 0, 0x00000000, 0xffffffff }, | ||
3665 | { 0x1c48, 0, 0x00000000, 0xffffffff }, | ||
3666 | { 0x1c4c, 0, 0x00000000, 0xffffffff }, | ||
3667 | { 0x1c50, 0, 0x00000000, 0xffffffff }, | ||
3668 | { 0x1d00, 0, 0x7ffbffff, 0x00000000 }, | ||
3669 | { 0x1d04, 0, 0xffffffff, 0x00000000 }, | ||
3670 | { 0x1d0c, 0, 0xffffffff, 0x00000000 }, | ||
3671 | { 0x1d14, 0, 0xffffffff, 0x00000000 }, | ||
3672 | { 0x1d1c, 0, 0xffffffff, 0x00000000 }, | ||
3673 | { 0x1d24, 0, 0xffffffff, 0x00000000 }, | ||
3674 | { 0x1d2c, 0, 0xffffffff, 0x00000000 }, | ||
3675 | { 0x1d34, 0, 0xffffffff, 0x00000000 }, | ||
3676 | { 0x1d3c, 0, 0xffffffff, 0x00000000 }, | ||
3677 | { 0x1d44, 0, 0xffffffff, 0x00000000 }, | ||
3678 | { 0x1d4c, 0, 0xffffffff, 0x00000000 }, | ||
3679 | { 0x1d54, 0, 0xffffffff, 0x00000000 }, | ||
3680 | { 0x1d5c, 0, 0xffffffff, 0x00000000 }, | ||
3681 | { 0x1d64, 0, 0xffffffff, 0x00000000 }, | ||
3682 | { 0x1d6c, 0, 0xffffffff, 0x00000000 }, | ||
3683 | { 0x1d74, 0, 0xffffffff, 0x00000000 }, | ||
3684 | { 0x1d7c, 0, 0xffffffff, 0x00000000 }, | ||
3685 | { 0x1d80, 0, 0x0700ffff, 0x00000000 }, | ||
3686 | |||
3687 | { 0x2004, 0, 0x00000000, 0x0337000f }, | ||
3688 | { 0x2008, 0, 0xffffffff, 0x00000000 }, | ||
3689 | { 0x200c, 0, 0xffffffff, 0x00000000 }, | ||
3690 | { 0x2010, 0, 0xffffffff, 0x00000000 }, | ||
3691 | { 0x2014, 0, 0x801fff80, 0x00000000 }, | ||
3692 | { 0x2018, 0, 0x000003ff, 0x00000000 }, | ||
3693 | 3620 | ||
3694 | { 0x2800, 0, 0x00000000, 0x00000001 }, | 3621 | { 0x2800, 0, 0x00000000, 0x00000001 }, |
3695 | { 0x2804, 0, 0x00000000, 0x00003f01 }, | 3622 | { 0x2804, 0, 0x00000000, 0x00003f01 }, |
@@ -3707,16 +3634,6 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3707 | { 0x2c00, 0, 0x00000000, 0x00000011 }, | 3634 | { 0x2c00, 0, 0x00000000, 0x00000011 }, |
3708 | { 0x2c04, 0, 0x00000000, 0x00030007 }, | 3635 | { 0x2c04, 0, 0x00000000, 0x00030007 }, |
3709 | 3636 | ||
3710 | { 0x3000, 0, 0x00000000, 0x00000001 }, | ||
3711 | { 0x3004, 0, 0x00000000, 0x007007ff }, | ||
3712 | { 0x3008, 0, 0x00000003, 0x00000000 }, | ||
3713 | { 0x300c, 0, 0xffffffff, 0x00000000 }, | ||
3714 | { 0x3010, 0, 0xffffffff, 0x00000000 }, | ||
3715 | { 0x3014, 0, 0xffffffff, 0x00000000 }, | ||
3716 | { 0x3034, 0, 0xffffffff, 0x00000000 }, | ||
3717 | { 0x3038, 0, 0xffffffff, 0x00000000 }, | ||
3718 | { 0x3050, 0, 0x00000001, 0x00000000 }, | ||
3719 | |||
3720 | { 0x3c00, 0, 0x00000000, 0x00000001 }, | 3637 | { 0x3c00, 0, 0x00000000, 0x00000001 }, |
3721 | { 0x3c04, 0, 0x00000000, 0x00070000 }, | 3638 | { 0x3c04, 0, 0x00000000, 0x00070000 }, |
3722 | { 0x3c08, 0, 0x00007f71, 0x07f00000 }, | 3639 | { 0x3c08, 0, 0x00007f71, 0x07f00000 }, |
@@ -3726,88 +3643,11 @@ bnx2_test_registers(struct bnx2 *bp) | |||
3726 | { 0x3c18, 0, 0x00000000, 0xffffffff }, | 3643 | { 0x3c18, 0, 0x00000000, 0xffffffff }, |
3727 | { 0x3c1c, 0, 0xfffff000, 0x00000000 }, | 3644 | { 0x3c1c, 0, 0xfffff000, 0x00000000 }, |
3728 | { 0x3c20, 0, 0xffffff00, 0x00000000 }, | 3645 | { 0x3c20, 0, 0xffffff00, 0x00000000 }, |
3729 | { 0x3c24, 0, 0xffffffff, 0x00000000 }, | ||
3730 | { 0x3c28, 0, 0xffffffff, 0x00000000 }, | ||
3731 | { 0x3c2c, 0, 0xffffffff, 0x00000000 }, | ||
3732 | { 0x3c30, 0, 0xffffffff, 0x00000000 }, | ||
3733 | { 0x3c34, 0, 0xffffffff, 0x00000000 }, | ||
3734 | { 0x3c38, 0, 0xffffffff, 0x00000000 }, | ||
3735 | { 0x3c3c, 0, 0xffffffff, 0x00000000 }, | ||
3736 | { 0x3c40, 0, 0xffffffff, 0x00000000 }, | ||
3737 | { 0x3c44, 0, 0xffffffff, 0x00000000 }, | ||
3738 | { 0x3c48, 0, 0xffffffff, 0x00000000 }, | ||
3739 | { 0x3c4c, 0, 0xffffffff, 0x00000000 }, | ||
3740 | { 0x3c50, 0, 0xffffffff, 0x00000000 }, | ||
3741 | { 0x3c54, 0, 0xffffffff, 0x00000000 }, | ||
3742 | { 0x3c58, 0, 0xffffffff, 0x00000000 }, | ||
3743 | { 0x3c5c, 0, 0xffffffff, 0x00000000 }, | ||
3744 | { 0x3c60, 0, 0xffffffff, 0x00000000 }, | ||
3745 | { 0x3c64, 0, 0xffffffff, 0x00000000 }, | ||
3746 | { 0x3c68, 0, 0xffffffff, 0x00000000 }, | ||
3747 | { 0x3c6c, 0, 0xffffffff, 0x00000000 }, | ||
3748 | { 0x3c70, 0, 0xffffffff, 0x00000000 }, | ||
3749 | { 0x3c74, 0, 0x0000003f, 0x00000000 }, | ||
3750 | { 0x3c78, 0, 0x00000000, 0x00000000 }, | ||
3751 | { 0x3c7c, 0, 0x00000000, 0x00000000 }, | ||
3752 | { 0x3c80, 0, 0x3fffffff, 0x00000000 }, | ||
3753 | { 0x3c84, 0, 0x0000003f, 0x00000000 }, | ||
3754 | { 0x3c88, 0, 0x00000000, 0xffffffff }, | ||
3755 | { 0x3c8c, 0, 0x00000000, 0xffffffff }, | ||
3756 | |||
3757 | { 0x4000, 0, 0x00000000, 0x00000001 }, | ||
3758 | { 0x4004, 0, 0x00000000, 0x00030000 }, | ||
3759 | { 0x4008, 0, 0x00000ff0, 0x00000000 }, | ||
3760 | { 0x400c, 0, 0xffffffff, 0x00000000 }, | ||
3761 | { 0x4088, 0, 0x00000000, 0x00070303 }, | ||
3762 | |||
3763 | { 0x4400, 0, 0x00000000, 0x00000001 }, | ||
3764 | { 0x4404, 0, 0x00000000, 0x00003f01 }, | ||
3765 | { 0x4408, 0, 0x7fff00ff, 0x00000000 }, | ||
3766 | { 0x440c, 0, 0xffffffff, 0x00000000 }, | ||
3767 | { 0x4410, 0, 0xffff, 0x0000 }, | ||
3768 | { 0x4414, 0, 0xffff, 0x0000 }, | ||
3769 | { 0x4418, 0, 0xffff, 0x0000 }, | ||
3770 | { 0x441c, 0, 0xffff, 0x0000 }, | ||
3771 | { 0x4428, 0, 0xffffffff, 0x00000000 }, | ||
3772 | { 0x442c, 0, 0xffffffff, 0x00000000 }, | ||
3773 | { 0x4430, 0, 0xffffffff, 0x00000000 }, | ||
3774 | { 0x4434, 0, 0xffffffff, 0x00000000 }, | ||
3775 | { 0x4438, 0, 0xffffffff, 0x00000000 }, | ||
3776 | { 0x443c, 0, 0xffffffff, 0x00000000 }, | ||
3777 | { 0x4440, 0, 0xffffffff, 0x00000000 }, | ||
3778 | { 0x4444, 0, 0xffffffff, 0x00000000 }, | ||
3779 | |||
3780 | { 0x4c00, 0, 0x00000000, 0x00000001 }, | ||
3781 | { 0x4c04, 0, 0x00000000, 0x0000003f }, | ||
3782 | { 0x4c08, 0, 0xffffffff, 0x00000000 }, | ||
3783 | { 0x4c0c, 0, 0x0007fc00, 0x00000000 }, | ||
3784 | { 0x4c10, 0, 0x80003fe0, 0x00000000 }, | ||
3785 | { 0x4c14, 0, 0xffffffff, 0x00000000 }, | ||
3786 | { 0x4c44, 0, 0x00000000, 0x9fff9fff }, | ||
3787 | { 0x4c48, 0, 0x00000000, 0xb3009fff }, | ||
3788 | { 0x4c4c, 0, 0x00000000, 0x77f33b30 }, | ||
3789 | { 0x4c50, 0, 0x00000000, 0xffffffff }, | ||
3790 | 3646 | ||
3791 | { 0x5004, 0, 0x00000000, 0x0000007f }, | 3647 | { 0x5004, 0, 0x00000000, 0x0000007f }, |
3792 | { 0x5008, 0, 0x0f0007ff, 0x00000000 }, | 3648 | { 0x5008, 0, 0x0f0007ff, 0x00000000 }, |
3793 | { 0x500c, 0, 0xf800f800, 0x07ff07ff }, | 3649 | { 0x500c, 0, 0xf800f800, 0x07ff07ff }, |
3794 | 3650 | ||
3795 | { 0x5400, 0, 0x00000008, 0x00000001 }, | ||
3796 | { 0x5404, 0, 0x00000000, 0x0000003f }, | ||
3797 | { 0x5408, 0, 0x0000001f, 0x00000000 }, | ||
3798 | { 0x540c, 0, 0xffffffff, 0x00000000 }, | ||
3799 | { 0x5410, 0, 0xffffffff, 0x00000000 }, | ||
3800 | { 0x5414, 0, 0x0000ffff, 0x00000000 }, | ||
3801 | { 0x5418, 0, 0x0000ffff, 0x00000000 }, | ||
3802 | { 0x541c, 0, 0x0000ffff, 0x00000000 }, | ||
3803 | { 0x5420, 0, 0x0000ffff, 0x00000000 }, | ||
3804 | { 0x5428, 0, 0x000000ff, 0x00000000 }, | ||
3805 | { 0x542c, 0, 0xff00ffff, 0x00000000 }, | ||
3806 | { 0x5430, 0, 0x001fff80, 0x00000000 }, | ||
3807 | { 0x5438, 0, 0xffffffff, 0x00000000 }, | ||
3808 | { 0x543c, 0, 0xffffffff, 0x00000000 }, | ||
3809 | { 0x5440, 0, 0xf800f800, 0x07ff07ff }, | ||
3810 | |||
3811 | { 0x5c00, 0, 0x00000000, 0x00000001 }, | 3651 | { 0x5c00, 0, 0x00000000, 0x00000001 }, |
3812 | { 0x5c04, 0, 0x00000000, 0x0003000f }, | 3652 | { 0x5c04, 0, 0x00000000, 0x0003000f }, |
3813 | { 0x5c08, 0, 0x00000003, 0x00000000 }, | 3653 | { 0x5c08, 0, 0x00000003, 0x00000000 }, |
@@ -3949,7 +3789,6 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
3949 | struct sk_buff *skb, *rx_skb; | 3789 | struct sk_buff *skb, *rx_skb; |
3950 | unsigned char *packet; | 3790 | unsigned char *packet; |
3951 | u16 rx_start_idx, rx_idx; | 3791 | u16 rx_start_idx, rx_idx; |
3952 | u32 val; | ||
3953 | dma_addr_t map; | 3792 | dma_addr_t map; |
3954 | struct tx_bd *txbd; | 3793 | struct tx_bd *txbd; |
3955 | struct sw_bd *rx_buf; | 3794 | struct sw_bd *rx_buf; |
@@ -3980,8 +3819,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
3980 | map = pci_map_single(bp->pdev, skb->data, pkt_size, | 3819 | map = pci_map_single(bp->pdev, skb->data, pkt_size, |
3981 | PCI_DMA_TODEVICE); | 3820 | PCI_DMA_TODEVICE); |
3982 | 3821 | ||
3983 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3822 | REG_WR(bp, BNX2_HC_COMMAND, |
3984 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | 3823 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); |
3824 | |||
3985 | REG_RD(bp, BNX2_HC_COMMAND); | 3825 | REG_RD(bp, BNX2_HC_COMMAND); |
3986 | 3826 | ||
3987 | udelay(5); | 3827 | udelay(5); |
@@ -4005,8 +3845,9 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode) | |||
4005 | 3845 | ||
4006 | udelay(100); | 3846 | udelay(100); |
4007 | 3847 | ||
4008 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3848 | REG_WR(bp, BNX2_HC_COMMAND, |
4009 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); | 3849 | bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT); |
3850 | |||
4010 | REG_RD(bp, BNX2_HC_COMMAND); | 3851 | REG_RD(bp, BNX2_HC_COMMAND); |
4011 | 3852 | ||
4012 | udelay(5); | 3853 | udelay(5); |
@@ -4142,7 +3983,6 @@ static int | |||
4142 | bnx2_test_intr(struct bnx2 *bp) | 3983 | bnx2_test_intr(struct bnx2 *bp) |
4143 | { | 3984 | { |
4144 | int i; | 3985 | int i; |
4145 | u32 val; | ||
4146 | u16 status_idx; | 3986 | u16 status_idx; |
4147 | 3987 | ||
4148 | if (!netif_running(bp->dev)) | 3988 | if (!netif_running(bp->dev)) |
@@ -4151,8 +3991,7 @@ bnx2_test_intr(struct bnx2 *bp) | |||
4151 | status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; | 3991 | status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; |
4152 | 3992 | ||
4153 | /* This register is not touched during run-time. */ | 3993 | /* This register is not touched during run-time. */ |
4154 | val = REG_RD(bp, BNX2_HC_COMMAND); | 3994 | REG_WR(bp, BNX2_HC_COMMAND, bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW); |
4155 | REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); | ||
4156 | REG_RD(bp, BNX2_HC_COMMAND); | 3995 | REG_RD(bp, BNX2_HC_COMMAND); |
4157 | 3996 | ||
4158 | for (i = 0; i < 10; i++) { | 3997 | for (i = 0; i < 10; i++) { |
@@ -4794,6 +4633,64 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
4794 | info->fw_version[5] = 0; | 4633 | info->fw_version[5] = 0; |
4795 | } | 4634 | } |
4796 | 4635 | ||
4636 | #define BNX2_REGDUMP_LEN (32 * 1024) | ||
4637 | |||
4638 | static int | ||
4639 | bnx2_get_regs_len(struct net_device *dev) | ||
4640 | { | ||
4641 | return BNX2_REGDUMP_LEN; | ||
4642 | } | ||
4643 | |||
4644 | static void | ||
4645 | bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p) | ||
4646 | { | ||
4647 | u32 *p = _p, i, offset; | ||
4648 | u8 *orig_p = _p; | ||
4649 | struct bnx2 *bp = netdev_priv(dev); | ||
4650 | u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c, | ||
4651 | 0x0800, 0x0880, 0x0c00, 0x0c10, | ||
4652 | 0x0c30, 0x0d08, 0x1000, 0x101c, | ||
4653 | 0x1040, 0x1048, 0x1080, 0x10a4, | ||
4654 | 0x1400, 0x1490, 0x1498, 0x14f0, | ||
4655 | 0x1500, 0x155c, 0x1580, 0x15dc, | ||
4656 | 0x1600, 0x1658, 0x1680, 0x16d8, | ||
4657 | 0x1800, 0x1820, 0x1840, 0x1854, | ||
4658 | 0x1880, 0x1894, 0x1900, 0x1984, | ||
4659 | 0x1c00, 0x1c0c, 0x1c40, 0x1c54, | ||
4660 | 0x1c80, 0x1c94, 0x1d00, 0x1d84, | ||
4661 | 0x2000, 0x2030, 0x23c0, 0x2400, | ||
4662 | 0x2800, 0x2820, 0x2830, 0x2850, | ||
4663 | 0x2b40, 0x2c10, 0x2fc0, 0x3058, | ||
4664 | 0x3c00, 0x3c94, 0x4000, 0x4010, | ||
4665 | 0x4080, 0x4090, 0x43c0, 0x4458, | ||
4666 | 0x4c00, 0x4c18, 0x4c40, 0x4c54, | ||
4667 | 0x4fc0, 0x5010, 0x53c0, 0x5444, | ||
4668 | 0x5c00, 0x5c18, 0x5c80, 0x5c90, | ||
4669 | 0x5fc0, 0x6000, 0x6400, 0x6428, | ||
4670 | 0x6800, 0x6848, 0x684c, 0x6860, | ||
4671 | 0x6888, 0x6910, 0x8000 }; | ||
4672 | |||
4673 | regs->version = 0; | ||
4674 | |||
4675 | memset(p, 0, BNX2_REGDUMP_LEN); | ||
4676 | |||
4677 | if (!netif_running(bp->dev)) | ||
4678 | return; | ||
4679 | |||
4680 | i = 0; | ||
4681 | offset = reg_boundaries[0]; | ||
4682 | p += offset; | ||
4683 | while (offset < BNX2_REGDUMP_LEN) { | ||
4684 | *p++ = REG_RD(bp, offset); | ||
4685 | offset += 4; | ||
4686 | if (offset == reg_boundaries[i + 1]) { | ||
4687 | offset = reg_boundaries[i + 2]; | ||
4688 | p = (u32 *) (orig_p + offset); | ||
4689 | i += 2; | ||
4690 | } | ||
4691 | } | ||
4692 | } | ||
4693 | |||
4797 | static void | 4694 | static void |
4798 | bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 4695 | bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
4799 | { | 4696 | { |
@@ -4979,7 +4876,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | |||
4979 | { | 4876 | { |
4980 | struct bnx2 *bp = netdev_priv(dev); | 4877 | struct bnx2 *bp = netdev_priv(dev); |
4981 | 4878 | ||
4982 | ering->rx_max_pending = MAX_RX_DESC_CNT; | 4879 | ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT; |
4983 | ering->rx_mini_max_pending = 0; | 4880 | ering->rx_mini_max_pending = 0; |
4984 | ering->rx_jumbo_max_pending = 0; | 4881 | ering->rx_jumbo_max_pending = 0; |
4985 | 4882 | ||
@@ -4996,17 +4893,28 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | |||
4996 | { | 4893 | { |
4997 | struct bnx2 *bp = netdev_priv(dev); | 4894 | struct bnx2 *bp = netdev_priv(dev); |
4998 | 4895 | ||
4999 | if ((ering->rx_pending > MAX_RX_DESC_CNT) || | 4896 | if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) || |
5000 | (ering->tx_pending > MAX_TX_DESC_CNT) || | 4897 | (ering->tx_pending > MAX_TX_DESC_CNT) || |
5001 | (ering->tx_pending <= MAX_SKB_FRAGS)) { | 4898 | (ering->tx_pending <= MAX_SKB_FRAGS)) { |
5002 | 4899 | ||
5003 | return -EINVAL; | 4900 | return -EINVAL; |
5004 | } | 4901 | } |
5005 | bp->rx_ring_size = ering->rx_pending; | 4902 | if (netif_running(bp->dev)) { |
4903 | bnx2_netif_stop(bp); | ||
4904 | bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); | ||
4905 | bnx2_free_skbs(bp); | ||
4906 | bnx2_free_mem(bp); | ||
4907 | } | ||
4908 | |||
4909 | bnx2_set_rx_ring_size(bp, ering->rx_pending); | ||
5006 | bp->tx_ring_size = ering->tx_pending; | 4910 | bp->tx_ring_size = ering->tx_pending; |
5007 | 4911 | ||
5008 | if (netif_running(bp->dev)) { | 4912 | if (netif_running(bp->dev)) { |
5009 | bnx2_netif_stop(bp); | 4913 | int rc; |
4914 | |||
4915 | rc = bnx2_alloc_mem(bp); | ||
4916 | if (rc) | ||
4917 | return rc; | ||
5010 | bnx2_init_nic(bp); | 4918 | bnx2_init_nic(bp); |
5011 | bnx2_netif_start(bp); | 4919 | bnx2_netif_start(bp); |
5012 | } | 4920 | } |
@@ -5360,6 +5268,8 @@ static struct ethtool_ops bnx2_ethtool_ops = { | |||
5360 | .get_settings = bnx2_get_settings, | 5268 | .get_settings = bnx2_get_settings, |
5361 | .set_settings = bnx2_set_settings, | 5269 | .set_settings = bnx2_set_settings, |
5362 | .get_drvinfo = bnx2_get_drvinfo, | 5270 | .get_drvinfo = bnx2_get_drvinfo, |
5271 | .get_regs_len = bnx2_get_regs_len, | ||
5272 | .get_regs = bnx2_get_regs, | ||
5363 | .get_wol = bnx2_get_wol, | 5273 | .get_wol = bnx2_get_wol, |
5364 | .set_wol = bnx2_set_wol, | 5274 | .set_wol = bnx2_set_wol, |
5365 | .nway_reset = bnx2_nway_reset, | 5275 | .nway_reset = bnx2_nway_reset, |
@@ -5678,7 +5588,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5678 | bp->mac_addr[5] = (u8) reg; | 5588 | bp->mac_addr[5] = (u8) reg; |
5679 | 5589 | ||
5680 | bp->tx_ring_size = MAX_TX_DESC_CNT; | 5590 | bp->tx_ring_size = MAX_TX_DESC_CNT; |
5681 | bp->rx_ring_size = 100; | 5591 | bnx2_set_rx_ring_size(bp, 100); |
5682 | 5592 | ||
5683 | bp->rx_csum = 1; | 5593 | bp->rx_csum = 1; |
5684 | 5594 | ||
@@ -5897,6 +5807,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5897 | if (!netif_running(dev)) | 5807 | if (!netif_running(dev)) |
5898 | return 0; | 5808 | return 0; |
5899 | 5809 | ||
5810 | flush_scheduled_work(); | ||
5900 | bnx2_netif_stop(bp); | 5811 | bnx2_netif_stop(bp); |
5901 | netif_device_detach(dev); | 5812 | netif_device_detach(dev); |
5902 | del_timer_sync(&bp->timer); | 5813 | del_timer_sync(&bp->timer); |