Skip to content

Commit

Permalink
[BNX2]: Add init. code to handle RX pages.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Michael Chan authored and David S. Miller committed Jan 28, 2008
1 parent 110d0ef commit 47bf424
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 2 deletions.
104 changes: 102 additions & 2 deletions drivers/net/bnx2.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,16 @@ bnx2_free_mem(struct bnx2 *bp)
}
vfree(bp->rx_buf_ring);
bp->rx_buf_ring = NULL;
for (i = 0; i < bp->rx_max_pg_ring; i++) {
if (bp->rx_pg_desc_ring[i])
pci_free_consistent(bp->pdev, RXBD_RING_SIZE,
bp->rx_pg_desc_ring[i],
bp->rx_pg_desc_mapping[i]);
bp->rx_pg_desc_ring[i] = NULL;
}
if (bp->rx_pg_ring)
vfree(bp->rx_pg_ring);
bp->rx_pg_ring = NULL;
}

static int
Expand Down Expand Up @@ -514,6 +524,25 @@ bnx2_alloc_mem(struct bnx2 *bp)

}

if (bp->rx_pg_ring_size) {
bp->rx_pg_ring = vmalloc(SW_RXPG_RING_SIZE *
bp->rx_max_pg_ring);
if (bp->rx_pg_ring == NULL)
goto alloc_mem_err;

memset(bp->rx_pg_ring, 0, SW_RXPG_RING_SIZE *
bp->rx_max_pg_ring);
}

for (i = 0; i < bp->rx_max_pg_ring; i++) {
bp->rx_pg_desc_ring[i] =
pci_alloc_consistent(bp->pdev, RXBD_RING_SIZE,
&bp->rx_pg_desc_mapping[i]);
if (bp->rx_pg_desc_ring[i] == NULL)
goto alloc_mem_err;

}

/* Combine status and statistics blocks into one allocation. */
status_blk_size = L1_CACHE_ALIGN(sizeof(struct status_block));
bp->status_stats_size = status_blk_size +
Expand Down Expand Up @@ -2194,6 +2223,42 @@ bnx2_set_mac_addr(struct bnx2 *bp)
REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val);
}

static inline int
bnx2_alloc_rx_page(struct bnx2 *bp, u16 index)
{
dma_addr_t mapping;
struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
struct rx_bd *rxbd =
&bp->rx_pg_desc_ring[RX_RING(index)][RX_IDX(index)];
struct page *page = alloc_page(GFP_ATOMIC);

if (!page)
return -ENOMEM;
mapping = pci_map_page(bp->pdev, page, 0, PAGE_SIZE,
PCI_DMA_FROMDEVICE);
rx_pg->page = page;
pci_unmap_addr_set(rx_pg, mapping, mapping);
rxbd->rx_bd_haddr_hi = (u64) mapping >> 32;
rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff;
return 0;
}

static void
bnx2_free_rx_page(struct bnx2 *bp, u16 index)
{
struct sw_pg *rx_pg = &bp->rx_pg_ring[index];
struct page *page = rx_pg->page;

if (!page)
return;

pci_unmap_page(bp->pdev, pci_unmap_addr(rx_pg, mapping), PAGE_SIZE,
PCI_DMA_FROMDEVICE);

__free_page(page);
rx_pg->page = NULL;
}

static inline int
bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
{
Expand Down Expand Up @@ -4213,11 +4278,31 @@ bnx2_init_rx_ring(struct bnx2 *bp)
bp->rx_prod = 0;
bp->rx_cons = 0;
bp->rx_prod_bseq = 0;
bp->rx_pg_prod = 0;
bp->rx_pg_cons = 0;

bnx2_init_rxbd_rings(bp->rx_desc_ring, bp->rx_desc_mapping,
bp->rx_buf_use_size, bp->rx_max_ring);

CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, 0);
if (bp->rx_pg_ring_size) {
bnx2_init_rxbd_rings(bp->rx_pg_desc_ring,
bp->rx_pg_desc_mapping,
PAGE_SIZE, bp->rx_max_pg_ring);
val = (bp->rx_buf_use_size << 16) | PAGE_SIZE;
CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_PG_BUF_SIZE, val);
CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_RBDC_KEY,
BNX2_L2CTX_RBDC_JUMBO_KEY);

val = (u64) bp->rx_pg_desc_mapping[0] >> 32;
CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_HI, val);

val = (u64) bp->rx_pg_desc_mapping[0] & 0xffffffff;
CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_PG_BDHADDR_LO, val);

if (CHIP_NUM(bp) == CHIP_NUM_5709)
REG_WR(bp, BNX2_MQ_MAP_L2_3, BNX2_MQ_MAP_L2_3_DEFAULT);
}

val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
Expand All @@ -4230,6 +4315,15 @@ bnx2_init_rx_ring(struct bnx2 *bp)
val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
CTX_WR(bp, rx_cid_addr, BNX2_L2CTX_NX_BDHADDR_LO, val);

ring_prod = prod = bp->rx_pg_prod;
for (i = 0; i < bp->rx_pg_ring_size; i++) {
if (bnx2_alloc_rx_page(bp, ring_prod) < 0)
break;
prod = NEXT_RX_BD(prod);
ring_prod = RX_PG_RING_IDX(prod);
}
bp->rx_pg_prod = prod;

ring_prod = prod = bp->rx_prod;
for (i = 0; i < bp->rx_ring_size; i++) {
if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) {
Expand All @@ -4240,6 +4334,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
}
bp->rx_prod = prod;

REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_PG_BDIDX, bp->rx_pg_prod);
REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod);

REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
Expand Down Expand Up @@ -4273,6 +4368,9 @@ bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
rx_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8;

bp->rx_copy_thresh = RX_COPY_THRESH;
bp->rx_pg_ring_size = 0;
bp->rx_max_pg_ring = 0;
bp->rx_max_pg_ring_idx = 0;

bp->rx_buf_use_size = rx_size;
/* hw alignment */
Expand Down Expand Up @@ -4341,6 +4439,8 @@ bnx2_free_rx_skbs(struct bnx2 *bp)

dev_kfree_skb(skb);
}
for (i = 0; i < bp->rx_max_pg_ring_idx; i++)
bnx2_free_rx_page(bp, i);
}

static void
Expand Down Expand Up @@ -5813,11 +5913,11 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)

ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
ering->rx_mini_max_pending = 0;
ering->rx_jumbo_max_pending = 0;
ering->rx_jumbo_max_pending = MAX_TOTAL_RX_PG_DESC_CNT;

ering->rx_pending = bp->rx_ring_size;
ering->rx_mini_pending = 0;
ering->rx_jumbo_pending = 0;
ering->rx_jumbo_pending = bp->rx_pg_ring_size;

ering->tx_max_pending = MAX_TX_DESC_CNT;
ering->tx_pending = bp->tx_ring_size;
Expand Down
28 changes: 28 additions & 0 deletions drivers/net/bnx2.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ struct l2_fhdr {
#define BNX2_L2CTX_HOST_PG_BDIDX 0x00000044
#define BNX2_L2CTX_PG_BUF_SIZE 0x00000048
#define BNX2_L2CTX_RBDC_KEY 0x0000004c
#define BNX2_L2CTX_RBDC_JUMBO_KEY 0x3ffe
#define BNX2_L2CTX_NX_PG_BDHADDR_HI 0x00000050
#define BNX2_L2CTX_NX_PG_BDHADDR_LO 0x00000054

Expand Down Expand Up @@ -4450,6 +4451,14 @@ struct l2_fhdr {
#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0)
#define BNX2_MQ_MEM_RD_DATA2_VALUE_XI (0x7fffffffL<<0)

#define BNX2_MQ_MAP_L2_3 0x00003d2c
#define BNX2_MQ_MAP_L2_3_MQ_OFFSET (0xffL<<0)
#define BNX2_MQ_MAP_L2_3_SZ (0x3L<<8)
#define BNX2_MQ_MAP_L2_3_CTX_OFFSET (0x2ffL<<10)
#define BNX2_MQ_MAP_L2_3_BIN_OFFSET (0x7L<<23)
#define BNX2_MQ_MAP_L2_3_ARM (0x3L<<26)
#define BNX2_MQ_MAP_L2_3_ENA (0x1L<<31)
#define BNX2_MQ_MAP_L2_3_DEFAULT 0x82004646

/*
* tsch_reg definition
Expand Down Expand Up @@ -6360,9 +6369,11 @@ struct l2_fhdr {
#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)

#define MAX_RX_RINGS 4
#define MAX_RX_PG_RINGS 16
#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd))
#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
#define MAX_TOTAL_RX_PG_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_PG_RINGS)

#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \
(MAX_TX_DESC_CNT - 1)) ? \
Expand All @@ -6375,6 +6386,7 @@ struct l2_fhdr {
(x) + 2 : (x) + 1

#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
#define RX_PG_RING_IDX(x) ((x) & bp->rx_max_pg_ring_idx)

#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> (BCM_PAGE_BITS - 4))
#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
Expand Down Expand Up @@ -6413,7 +6425,13 @@ struct sw_bd {
DECLARE_PCI_UNMAP_ADDR(mapping)
};

struct sw_pg {
struct page *page;
DECLARE_PCI_UNMAP_ADDR(mapping)
};

#define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
#define SW_RXPG_RING_SIZE (sizeof(struct sw_pg) * RX_DESC_CNT)
#define RXBD_RING_SIZE (sizeof(struct rx_bd) * RX_DESC_CNT)
#define SW_TXBD_RING_SIZE (sizeof(struct sw_bd) * TX_DESC_CNT)
#define TXBD_RING_SIZE (sizeof(struct tx_bd) * TX_DESC_CNT)
Expand Down Expand Up @@ -6520,15 +6538,21 @@ struct bnx2 {
u32 rx_buf_size; /* with alignment */
u32 rx_copy_thresh;
u32 rx_max_ring_idx;
u32 rx_max_pg_ring_idx;

u32 rx_prod_bseq;
u16 rx_prod;
u16 rx_cons;

u16 rx_pg_prod;
u16 rx_pg_cons;

u32 rx_csum;

struct sw_bd *rx_buf_ring;
struct rx_bd *rx_desc_ring[MAX_RX_RINGS];
struct sw_pg *rx_pg_ring;
struct rx_bd *rx_pg_desc_ring[MAX_RX_PG_RINGS];

/* TX constants */
struct tx_bd *tx_desc_ring;
Expand Down Expand Up @@ -6616,6 +6640,10 @@ struct bnx2 {
int rx_ring_size;
dma_addr_t rx_desc_mapping[MAX_RX_RINGS];

int rx_max_pg_ring;
int rx_pg_ring_size;
dma_addr_t rx_pg_desc_mapping[MAX_RX_PG_RINGS];

u16 tx_quick_cons_trip;
u16 tx_quick_cons_trip_int;
u16 rx_quick_cons_trip;
Expand Down

0 comments on commit 47bf424

Please sign in to comment.