aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2007-12-12 14:19:12 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:57:30 -0500
commit47bf4246a357d36762c9e7c282d7307152eb92e1 (patch)
tree91f28518be9daf3a2e26efd9efa9bdbb4b664454 /drivers
parent110d0ef9907b519fed1607c73b3ae883f270561e (diff)
[BNX2]: Add init. code to handle RX pages.
Add new fields to keep track of the pages and the page rings. Add functions to allocate and free pages. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bnx2.c104
-rw-r--r--drivers/net/bnx2.h28
2 files changed, 130 insertions, 2 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index db3b7503bb1..38e8e31cabf 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -483,6 +483,16 @@ bnx2_free_mem(struct bnx2 *bp)
483 } 483 }
484 vfree(bp->rx_buf_ring); 484 vfree(bp->rx_buf_ring);
485 bp->rx_buf_ring = NULL; 485 bp->rx_buf_ring = NULL;
486 for (i = 0; i < bp->rx_max_pg_ring; i++) {
487 if (bp->rx_pg_desc_ring[i])
488 pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
489 bp->rx_pg_desc_ring[i],
490 bp->rx_pg_desc_mapping[i]);
491 bp->rx_pg_desc_ring[i] = NULL;
492 }
493 if (bp->rx_pg_ring)
494 vfree(bp->rx_pg_ring);
495 bp->rx_pg_ring = NULL;
486} 496}
487 497
488static int 498static int
@@ -514,6 +524,25 @@ bnx2_alloc_mem(struct bnx2 *bp)
514 524
515 } 525 }
516 526
527 if (bp->rx_pg_ring_size) {
528 bp->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
529 bp->rx_max_pg_ring);
530 if (bp->rx_pg_ring == NULL)
531 goto alloc_mem_err;
532
533 memset(bp->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
534 bp->rx_max_pg_ring);
535 }
536
537 for (i = 0; i < bp->rx_max_pg_ring; i++) {
538 bp->rx_pg_desc_ring[i] =
539 pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
540 &bp->rx_pg_desc_mapping[i]);
541 if (bp->rx_pg_desc_ring[i] == NULL)
542 goto alloc_mem_err;
543
544 }
545
517 /* Combine status and statistics blocks into one allocation. */ 546 /* Combine status and statistics blocks into one allocation. */
518 status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block)); 547 status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
519 bp->status_stats_size = status_blk_size + 548 bp->status_stats_size = status_blk_size +
@@ -2195,6 +2224,42 @@ bnx2_set_mac_addr(struct bnx2 *bp)
2195} 2224}
2196 2225
2197static inline int 2226static inline int
2227bnx2_alloc_rx_page(struct bnx2 *bp, u16 index)
2228{
2229 dma_addr_t mapping;
2230 struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
2231 struct rx_bd *rxbd =
2232 &bp->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
2233 struct page *page = alloc_page(GFP_ATOMIC);
2234
2235 if (!page)
2236 return -ENOMEM;
2237 mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
2238 PCI_DMA_FROMDEVICE);
2239 rx_pg->page = page;
2240 pci_unmap_addr_set(rx_pg, mapping, mapping);
2241 rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
2242 rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
2243 return 0;
2244}
2245
2246static void
2247bnx2_free_rx_page(struct bnx2 *bp, u16 index)
2248{
2249 struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
2250 struct page *page = rx_pg->page;
2251
2252 if (!page)
2253 return;
2254
2255 pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
2256 PCI_DMA_FROMDEVICE);
2257
2258 __free_page(page);
2259 rx_pg->page = NULL;
2260}
2261
2262static inline int
2198bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) 2263bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
2199{ 2264{
2200 struct sk_buff *skb; 2265 struct sk_buff *skb;
@@ -4213,11 +4278,31 @@ bnx2_init_rx_ring(struct bnx2 *bp)
4213 bp->rx_prod = 0; 4278 bp->rx_prod = 0;
4214 bp->rx_cons = 0; 4279 bp->rx_cons = 0;
4215 bp->rx_prod_bseq = 0; 4280 bp->rx_prod_bseq = 0;
4281 bp->rx_pg_prod = 0;
4282 bp->rx_pg_cons = 0;
4216 4283
4217 bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping, 4284 bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
4218 bp->rx_buf_use_size, bp->rx_max_ring); 4285 bp->rx_buf_use_size, bp->rx_max_ring);
4219 4286
4220 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0); 4287 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
4288 if (bp->rx_pg_ring_size) {
4289 bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
4290 bp->rx_pg_desc_mapping,
4291 PAGE_SIZE, bp->rx_max_pg_ring);
4292 val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
4293 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
4294 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
4295 BNX2_L2CTX_RBDC_JUMBO_KEY);
4296
4297 val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
4298 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);
4299
4300 val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
4301 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);
4302
4303 if (CHIP_NUM(bp) == CHIP_NUM_5709)
4304 REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
4305 }
4221 4306
4222 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; 4307 val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
4223 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; 4308 val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
@@ -4230,6 +4315,15 @@ bnx2_init_rx_ring(struct bnx2 *bp)
4230 val = (u64) bp->rx_desc_mapping[0] & 0xffffffff; 4315 val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
4231 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val); 4316 CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);
4232 4317
4318 ring_prod = prod = bp->rx_pg_prod;
4319 for (i = 0; i < bp->rx_pg_ring_size; i++) {
4320 if (bnx2_alloc_rx_page(bp, ring_prod) < 0)
4321 break;
4322 prod = NEXT_RX_BD(prod);
4323 ring_prod = RX_PG_RING_IDX(prod);
4324 }
4325 bp->rx_pg_prod = prod;
4326
4233 ring_prod = prod = bp->rx_prod; 4327 ring_prod = prod = bp->rx_prod;
4234 for (i = 0; i < bp->rx_ring_size; i++) { 4328 for (i = 0; i < bp->rx_ring_size; i++) {
4235 if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) { 4329 if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) {
@@ -4240,6 +4334,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
4240 } 4334 }
4241 bp->rx_prod = prod; 4335 bp->rx_prod = prod;
4242 4336
4337 REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX, bp->rx_pg_prod);
4243 REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod); 4338 REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod);
4244 4339
4245 REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); 4340 REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
@@ -4273,6 +4368,9 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
4273 rx_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8; 4368 rx_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;
4274 4369
4275 bp->rx_copy_thresh = RX_COPY_THRESH; 4370 bp->rx_copy_thresh = RX_COPY_THRESH;
4371 bp->rx_pg_ring_size = 0;
4372 bp->rx_max_pg_ring = 0;
4373 bp->rx_max_pg_ring_idx = 0;
4276 4374
4277 bp->rx_buf_use_size = rx_size; 4375 bp->rx_buf_use_size = rx_size;
4278 /* hw alignment */ 4376 /* hw alignment */
@@ -4341,6 +4439,8 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
4341 4439
4342 dev_kfree_skb(skb); 4440 dev_kfree_skb(skb);
4343 } 4441 }
4442 for (i = 0; i < bp->rx_max_pg_ring_idx; i++)
4443 bnx2_free_rx_page(bp, i);
4344} 4444}
4345 4445
4346static void 4446static void
@@ -5813,11 +5913,11 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
5813 5913
5814 ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT; 5914 ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
5815 ering->rx_mini_max_pending = 0; 5915 ering->rx_mini_max_pending = 0;
5816 ering->rx_jumbo_max_pending = 0; 5916 ering->rx_jumbo_max_pending = MAX_TOTAL_RX_PG_DESC_CNT;
5817 5917
5818 ering->rx_pending = bp->rx_ring_size; 5918 ering->rx_pending = bp->rx_ring_size;
5819 ering->rx_mini_pending = 0; 5919 ering->rx_mini_pending = 0;
5820 ering->rx_jumbo_pending = 0; 5920 ering->rx_jumbo_pending = bp->rx_pg_ring_size;
5821 5921
5822 ering->tx_max_pending = MAX_TX_DESC_CNT; 5922 ering->tx_max_pending = MAX_TX_DESC_CNT;
5823 ering->tx_pending = bp->tx_ring_size; 5923 ering->tx_pending = bp->tx_ring_size;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 8354efc1111..93c2436cb8b 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -335,6 +335,7 @@ struct l2_fhdr {
335#define BNX2_L2CTX_HOST_PG_BDIDX 0x00000044 335#define BNX2_L2CTX_HOST_PG_BDIDX 0x00000044
336#define BNX2_L2CTX_PG_BUF_SIZE 0x00000048 336#define BNX2_L2CTX_PG_BUF_SIZE 0x00000048
337#define BNX2_L2CTX_RBDC_KEY 0x0000004c 337#define BNX2_L2CTX_RBDC_KEY 0x0000004c
338#define BNX2_L2CTX_RBDC_JUMBO_KEY 0x3ffe
338#define BNX2_L2CTX_NX_PG_BDHADDR_HI 0x00000050 339#define BNX2_L2CTX_NX_PG_BDHADDR_HI 0x00000050
339#define BNX2_L2CTX_NX_PG_BDHADDR_LO 0x00000054 340#define BNX2_L2CTX_NX_PG_BDHADDR_LO 0x00000054
340 341
@@ -4450,6 +4451,14 @@ struct l2_fhdr {
4450#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0) 4451#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0)
4451#define BNX2_MQ_MEM_RD_DATA2_VALUE_XI (0x7fffffffL<<0) 4452#define BNX2_MQ_MEM_RD_DATA2_VALUE_XI (0x7fffffffL<<0)
4452 4453
4454#define BNX2_MQ_MAP_L2_3 0x00003d2c
4455#define BNX2_MQ_MAP_L2_3_MQ_OFFSET (0xffL<<0)
4456#define BNX2_MQ_MAP_L2_3_SZ (0x3L<<8)
4457#define BNX2_MQ_MAP_L2_3_CTX_OFFSET (0x2ffL<<10)
4458#define BNX2_MQ_MAP_L2_3_BIN_OFFSET (0x7L<<23)
4459#define BNX2_MQ_MAP_L2_3_ARM (0x3L<<26)
4460#define BNX2_MQ_MAP_L2_3_ENA (0x1L<<31)
4461#define BNX2_MQ_MAP_L2_3_DEFAULT 0x82004646
4453 4462
4454/* 4463/*
4455 * tsch_reg definition 4464 * tsch_reg definition
@@ -6360,9 +6369,11 @@ struct l2_fhdr {
6360#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) 6369#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
6361 6370
6362#define MAX_RX_RINGS 4 6371#define MAX_RX_RINGS 4
6372#define MAX_RX_PG_RINGS 16
6363#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) 6373#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd))
6364#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) 6374#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
6365#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS) 6375#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
6376#define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)
6366 6377
6367#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ 6378#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \
6368 (MAX_TX_DESC_CNT - 1)) ? \ 6379 (MAX_TX_DESC_CNT - 1)) ? \
@@ -6375,6 +6386,7 @@ struct l2_fhdr {
6375 (x) + 2 : (x) + 1 6386 (x) + 2 : (x) + 1
6376 6387
6377#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx) 6388#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
6389#define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)
6378 6390
6379#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4)) 6391#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
6380#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT) 6392#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
@@ -6413,7 +6425,13 @@ struct sw_bd {
6413 DECLARE_PCI_UNMAP_ADDR(mapping) 6425 DECLARE_PCI_UNMAP_ADDR(mapping)
6414}; 6426};
6415 6427
6428struct sw_pg {
6429 struct page *page;
6430 DECLARE_PCI_UNMAP_ADDR(mapping)
6431};
6432
6416#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT) 6433#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
6434#define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
6417#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT) 6435#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
6418#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT) 6436#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT)
6419#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT) 6437#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
@@ -6520,15 +6538,21 @@ struct bnx2 {
6520 u32 rx_buf_size; /* with alignment */ 6538 u32 rx_buf_size; /* with alignment */
6521 u32 rx_copy_thresh; 6539 u32 rx_copy_thresh;
6522 u32 rx_max_ring_idx; 6540 u32 rx_max_ring_idx;
6541 u32 rx_max_pg_ring_idx;
6523 6542
6524 u32 rx_prod_bseq; 6543 u32 rx_prod_bseq;
6525 u16 rx_prod; 6544 u16 rx_prod;
6526 u16 rx_cons; 6545 u16 rx_cons;
6527 6546
6547 u16 rx_pg_prod;
6548 u16 rx_pg_cons;
6549
6528 u32 rx_csum; 6550 u32 rx_csum;
6529 6551
6530 struct sw_bd *rx_buf_ring; 6552 struct sw_bd *rx_buf_ring;
6531 struct rx_bd *rx_desc_ring[MAX_RX_RINGS]; 6553 struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
6554 struct sw_pg *rx_pg_ring;
6555 struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];
6532 6556
6533 /* TX constants */ 6557 /* TX constants */
6534 struct tx_bd *tx_desc_ring; 6558 struct tx_bd *tx_desc_ring;
@@ -6616,6 +6640,10 @@ struct bnx2 {
6616 int rx_ring_size; 6640 int rx_ring_size;
6617 dma_addr_t rx_desc_mapping[MAX_RX_RINGS]; 6641 dma_addr_t rx_desc_mapping[MAX_RX_RINGS];
6618 6642
6643 int rx_max_pg_ring;
6644 int rx_pg_ring_size;
6645 dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];
6646
6619 u16 tx_quick_cons_trip; 6647 u16 tx_quick_cons_trip;
6620 u16 tx_quick_cons_trip_int; 6648 u16 tx_quick_cons_trip_int;
6621 u16 rx_quick_cons_trip; 6649 u16 rx_quick_cons_trip;