diff options
| author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-23 23:44:19 -0500 |
| commit | 1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch) | |
| tree | f5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /drivers/net/bnx2.c | |
| parent | ac58c9059da8886b5e8cde012a80266b18ca146e (diff) | |
| parent | 674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff) | |
Merge branch 'linus'
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); |
