aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-03-20 20:49:20 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-20 20:49:20 -0500
commit13daffa2f2ba65674e7816a0e95e7b93246cb686 (patch)
tree3170a19dfba530398d4f12e54a21400254fa98b1 /drivers/net/bnx2.c
parent236b6394bb49ea58465c6f935a286d2342576f8d (diff)
[BNX2]: Support larger rx ring sizes (part 1)
Increase maximum receive ring size from 255 to 1020 by supporting up to 4 linked pages of receive descriptors. To accomodate the higher memory usage, each physical descriptor page is allocated separately and the software ring that keeps track of the SKBs and the DMA addresses is allocated using vmalloc. Some of the receive-related fields in the bp structure are re- organized a bit for better locality of reference. The max. was reduced to 1020 from 4080 after discussion with David Miller. This patch contains ring init code changes only. This next patch contains rx data path code changes. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r--drivers/net/bnx2.c117
1 files changed, 85 insertions, 32 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 0d592f7c3a99..03c47cf04e90 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -360,6 +360,8 @@ bnx2_netif_start(struct bnx2 *bp)
360static void 360static void
361bnx2_free_mem(struct bnx2 *bp) 361bnx2_free_mem(struct bnx2 *bp)
362{ 362{
363 int i;
364
363 if (bp->stats_blk) { 365 if (bp->stats_blk) {
364 pci_free_consistent(bp->pdev, sizeof(struct statistics_block), 366 pci_free_consistent(bp->pdev, sizeof(struct statistics_block),
365 bp->stats_blk, bp->stats_blk_mapping); 367 bp->stats_blk, bp->stats_blk_mapping);
@@ -378,19 +380,23 @@ bnx2_free_mem(struct bnx2 *bp)
378 } 380 }
379 kfree(bp->tx_buf_ring); 381 kfree(bp->tx_buf_ring);
380 bp->tx_buf_ring = NULL; 382 bp->tx_buf_ring = NULL;
381 if (bp->rx_desc_ring) { 383 for (i = 0; i < bp->rx_max_ring; i++) {
382 pci_free_consistent(bp->pdev, 384 if (bp->rx_desc_ring[i])
383 sizeof(struct rx_bd) * RX_DESC_CNT, 385 pci_free_consistent(bp->pdev,
384 bp->rx_desc_ring, bp->rx_desc_mapping); 386 sizeof(struct rx_bd) * RX_DESC_CNT,
385 bp->rx_desc_ring = NULL; 387 bp->rx_desc_ring[i],
386 } 388 bp->rx_desc_mapping[i]);
387 kfree(bp->rx_buf_ring); 389 bp->rx_desc_ring[i] = NULL;
390 }
391 vfree(bp->rx_buf_ring);
388 bp->rx_buf_ring = NULL; 392 bp->rx_buf_ring = NULL;
389} 393}
390 394
391static int 395static int
392bnx2_alloc_mem(struct bnx2 *bp) 396bnx2_alloc_mem(struct bnx2 *bp)
393{ 397{
398 int i;
399
394 bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT, 400 bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
395 GFP_KERNEL); 401 GFP_KERNEL);
396 if (bp->tx_buf_ring == NULL) 402 if (bp->tx_buf_ring == NULL)
@@ -404,18 +410,23 @@ bnx2_alloc_mem(struct bnx2 *bp)
404 if (bp->tx_desc_ring == NULL) 410 if (bp->tx_desc_ring == NULL)
405 goto alloc_mem_err; 411 goto alloc_mem_err;
406 412
407 bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT, 413 bp->rx_buf_ring = vmalloc(sizeof(struct sw_bd) * RX_DESC_CNT *
408 GFP_KERNEL); 414 bp->rx_max_ring);
409 if (bp->rx_buf_ring == NULL) 415 if (bp->rx_buf_ring == NULL)
410 goto alloc_mem_err; 416 goto alloc_mem_err;
411 417
412 memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT); 418 memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT *
413 bp->rx_desc_ring = pci_alloc_consistent(bp->pdev, 419 bp->rx_max_ring);
414 sizeof(struct rx_bd) * 420
415 RX_DESC_CNT, 421 for (i = 0; i < bp->rx_max_ring; i++) {
416 &bp->rx_desc_mapping); 422 bp->rx_desc_ring[i] =
417 if (bp->rx_desc_ring == NULL) 423 pci_alloc_consistent(bp->pdev,
418 goto alloc_mem_err; 424 sizeof(struct rx_bd) * RX_DESC_CNT,
425 &bp->rx_desc_mapping[i]);
426 if (bp->rx_desc_ring[i] == NULL)
427 goto alloc_mem_err;
428
429 }
419 430
420 bp->status_blk = pci_alloc_consistent(bp->pdev, 431 bp->status_blk = pci_alloc_consistent(bp->pdev,
421 sizeof(struct status_block), 432 sizeof(struct status_block),
@@ -1520,7 +1531,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
1520 struct sk_buff *skb; 1531 struct sk_buff *skb;
1521 struct sw_bd *rx_buf = &bp->rx_buf_ring[index]; 1532 struct sw_bd *rx_buf = &bp->rx_buf_ring[index];
1522 dma_addr_t mapping; 1533 dma_addr_t mapping;
1523 struct rx_bd *rxbd = &bp->rx_desc_ring[index]; 1534 struct rx_bd *rxbd = &bp->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
1524 unsigned long align; 1535 unsigned long align;
1525 1536
1526 skb = dev_alloc_skb(bp->rx_buf_size); 1537 skb = dev_alloc_skb(bp->rx_buf_size);
@@ -3349,24 +3360,32 @@ bnx2_init_rx_ring(struct bnx2 *bp)
3349 bp->hw_rx_cons = 0; 3360 bp->hw_rx_cons = 0;
3350 bp->rx_prod_bseq = 0; 3361 bp->rx_prod_bseq = 0;
3351 3362
3352 rxbd = &bp->rx_desc_ring[0]; 3363 for (i = 0; i < bp->rx_max_ring; i++) {
3353 for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { 3364 int j;
3354 rxbd->rx_bd_len = bp->rx_buf_use_size;
3355 rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
3356 }
3357 3365
3358 rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32; 3366 rxbd = &bp->rx_desc_ring[i][0];
3359 rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; 3367 for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) {
3368 rxbd->rx_bd_len = bp->rx_buf_use_size;
3369 rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
3370 }
3371 if (i == (bp->rx_max_ring - 1))
3372 j = 0;
3373 else
3374 j = i + 1;
3375 rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping[j] >> 32;
3376 rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping[j] &
3377 0xffffffff;
3378 }
3360 3379
3361 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; 3380 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
3362 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; 3381 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
3363 val |= 0x02 << 8; 3382 val |= 0x02 << 8;
3364 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); 3383 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
3365 3384
3366 val = (u64) bp->rx_desc_mapping >> 32; 3385 val = (u64) bp->rx_desc_mapping[0] >> 32;
3367 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val); 3386 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val);
3368 3387
3369 val = (u64) bp->rx_desc_mapping & 0xffffffff; 3388 val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
3370 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); 3389 CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
3371 3390
3372 for (i = 0; i < bp->rx_ring_size; i++) { 3391 for (i = 0; i < bp->rx_ring_size; i++) {
@@ -3384,6 +3403,29 @@ bnx2_init_rx_ring(struct bnx2 *bp)
3384} 3403}
3385 3404
3386static void 3405static void
3406bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
3407{
3408 u32 num_rings, max;
3409
3410 bp->rx_ring_size = size;
3411 num_rings = 1;
3412 while (size > MAX_RX_DESC_CNT) {
3413 size -= MAX_RX_DESC_CNT;
3414 num_rings++;
3415 }
3416 /* round to next power of 2 */
3417 max = MAX_RX_RINGS;
3418 while ((max & num_rings) == 0)
3419 max >>= 1;
3420
3421 if (num_rings != max)
3422 max <<= 1;
3423
3424 bp->rx_max_ring = max;
3425 bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
3426}
3427
3428static void
3387bnx2_free_tx_skbs(struct bnx2 *bp) 3429bnx2_free_tx_skbs(struct bnx2 *bp)
3388{ 3430{
3389 int i; 3431 int i;
@@ -3428,7 +3470,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
3428 if (bp->rx_buf_ring == NULL) 3470 if (bp->rx_buf_ring == NULL)
3429 return; 3471 return;
3430 3472
3431 for (i = 0; i < RX_DESC_CNT; i++) { 3473 for (i = 0; i < bp->rx_max_ring_idx; i++) {
3432 struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; 3474 struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
3433 struct sk_buff *skb = rx_buf->skb; 3475 struct sk_buff *skb = rx_buf->skb;
3434 3476
@@ -4792,7 +4834,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
4792{ 4834{
4793 struct bnx2 *bp = netdev_priv(dev); 4835 struct bnx2 *bp = netdev_priv(dev);
4794 4836
4795 ering->rx_max_pending = MAX_RX_DESC_CNT; 4837 ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
4796 ering->rx_mini_max_pending = 0; 4838 ering->rx_mini_max_pending = 0;
4797 ering->rx_jumbo_max_pending = 0; 4839 ering->rx_jumbo_max_pending = 0;
4798 4840
@@ -4809,17 +4851,28 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
4809{ 4851{
4810 struct bnx2 *bp = netdev_priv(dev); 4852 struct bnx2 *bp = netdev_priv(dev);
4811 4853
4812 if ((ering->rx_pending > MAX_RX_DESC_CNT) || 4854 if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) ||
4813 (ering->tx_pending > MAX_TX_DESC_CNT) || 4855 (ering->tx_pending > MAX_TX_DESC_CNT) ||
4814 (ering->tx_pending <= MAX_SKB_FRAGS)) { 4856 (ering->tx_pending <= MAX_SKB_FRAGS)) {
4815 4857
4816 return -EINVAL; 4858 return -EINVAL;
4817 } 4859 }
4818 bp->rx_ring_size = ering->rx_pending; 4860 if (netif_running(bp->dev)) {
4861 bnx2_netif_stop(bp);
4862 bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
4863 bnx2_free_skbs(bp);
4864 bnx2_free_mem(bp);
4865 }
4866
4867 bnx2_set_rx_ring_size(bp, ering->rx_pending);
4819 bp->tx_ring_size = ering->tx_pending; 4868 bp->tx_ring_size = ering->tx_pending;
4820 4869
4821 if (netif_running(bp->dev)) { 4870 if (netif_running(bp->dev)) {
4822 bnx2_netif_stop(bp); 4871 int rc;
4872
4873 rc = bnx2_alloc_mem(bp);
4874 if (rc)
4875 return rc;
4823 bnx2_init_nic(bp); 4876 bnx2_init_nic(bp);
4824 bnx2_netif_start(bp); 4877 bnx2_netif_start(bp);
4825 } 4878 }
@@ -5493,7 +5546,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
5493 bp->mac_addr[5] = (u8) reg; 5546 bp->mac_addr[5] = (u8) reg;
5494 5547
5495 bp->tx_ring_size = MAX_TX_DESC_CNT; 5548 bp->tx_ring_size = MAX_TX_DESC_CNT;
5496 bp->rx_ring_size = 100; 5549 bnx2_set_rx_ring_size(bp, 100);
5497 5550
5498 bp->rx_csum = 1; 5551 bp->rx_csum = 1;
5499 5552