diff options
author | Michael Chan <mchan@broadcom.com> | 2007-12-12 14:19:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:57:30 -0500 |
commit | 47bf4246a357d36762c9e7c282d7307152eb92e1 (patch) | |
tree | 91f28518be9daf3a2e26efd9efa9bdbb4b664454 | |
parent | 110d0ef9907b519fed1607c73b3ae883f270561e (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>
-rw-r--r-- | drivers/net/bnx2.c | 104 | ||||
-rw-r--r-- | drivers/net/bnx2.h | 28 |
2 files changed, 130 insertions, 2 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index db3b7503bb16..38e8e31cabf3 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 | ||
488 | static int | 498 | static 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 | ||
2197 | static inline int | 2226 | static inline int |
2227 | bnx2_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 | |||
2246 | static void | ||
2247 | bnx2_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 | |||
2262 | static inline int | ||
2198 | bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) | 2263 | bnx2_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 | ||
4346 | static void | 4446 | static 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 8354efc1111d..93c2436cb8b9 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 | ||
6428 | struct 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; |