Skip to content

Commit

Permalink
tg3: Lay proucer ring handling groundwork
Browse files Browse the repository at this point in the history
The patch increases the number of producer rings available and
implements the constructor and destructor code that deals with them.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Matt Carlson authored and David S. Miller committed Nov 16, 2009
1 parent 4361935 commit 2b2cdb6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 37 deletions.
85 changes: 49 additions & 36 deletions drivers/net/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@
#define TG3_RX_STD_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_STD_DMA_SZ)
#define TG3_RX_JMB_MAP_SZ TG3_RX_DMA_TO_MAP_SZ(TG3_RX_JMB_DMA_SZ)

#define TG3_RX_STD_BUFF_RING_SIZE \
(sizeof(struct ring_info) * TG3_RX_RING_SIZE)

#define TG3_RX_JMB_BUFF_RING_SIZE \
(sizeof(struct ring_info) * TG3_RX_JUMBO_RING_SIZE)

/* minimum number of free TX descriptors required to wake up TX process */
#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)

Expand Down Expand Up @@ -4397,6 +4403,17 @@ static void tg3_tx(struct tg3_napi *tnapi)
}
}

static void tg3_rx_skb_free(struct tg3 *tp, struct ring_info *ri, u32 map_sz)
{
if (!ri->skb)
return;

pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping),
map_sz, PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(ri->skb);
ri->skb = NULL;
}

/* Returns size of skb allocated or < 0 on error.
*
* We only need to fill in the address because the other members
Expand Down Expand Up @@ -5701,36 +5718,18 @@ static void tg3_rx_prodring_free(struct tg3 *tp,
struct tg3_rx_prodring_set *tpr)
{
int i;
struct ring_info *rxp;

for (i = 0; i < TG3_RX_RING_SIZE; i++) {
rxp = &tpr->rx_std_buffers[i];
if (tpr != &tp->prodring[0])
return;

if (rxp->skb == NULL)
continue;

pci_unmap_single(tp->pdev,
pci_unmap_addr(rxp, mapping),
tp->rx_pkt_map_sz,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(rxp->skb);
rxp->skb = NULL;
}
for (i = 0; i < TG3_RX_RING_SIZE; i++)
tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
tp->rx_pkt_map_sz);

if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++) {
rxp = &tpr->rx_jmb_buffers[i];

if (rxp->skb == NULL)
continue;

pci_unmap_single(tp->pdev,
pci_unmap_addr(rxp, mapping),
TG3_RX_JMB_MAP_SZ,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(rxp->skb);
rxp->skb = NULL;
}
for (i = 0; i < TG3_RX_JUMBO_RING_SIZE; i++)
tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
TG3_RX_JMB_MAP_SZ);
}
}

Expand All @@ -5746,6 +5745,14 @@ static int tg3_rx_prodring_alloc(struct tg3 *tp,
{
u32 i, rx_pkt_dma_sz;

if (tpr != &tp->prodring[0]) {
memset(&tpr->rx_std_buffers[0], 0, TG3_RX_STD_BUFF_RING_SIZE);
if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE)
memset(&tpr->rx_jmb_buffers[0], 0,
TG3_RX_JMB_BUFF_RING_SIZE);
goto done;
}

/* Zero out all descriptors. */
memset(tpr->rx_std, 0, TG3_RX_RING_BYTES);

Expand Down Expand Up @@ -5847,8 +5854,7 @@ static void tg3_rx_prodring_fini(struct tg3 *tp,
static int tg3_rx_prodring_init(struct tg3 *tp,
struct tg3_rx_prodring_set *tpr)
{
tpr->rx_std_buffers = kzalloc(sizeof(struct ring_info) *
TG3_RX_RING_SIZE, GFP_KERNEL);
tpr->rx_std_buffers = kzalloc(TG3_RX_STD_BUFF_RING_SIZE, GFP_KERNEL);
if (!tpr->rx_std_buffers)
return -ENOMEM;

Expand All @@ -5858,8 +5864,7 @@ static int tg3_rx_prodring_init(struct tg3 *tp,
goto err_out;

if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
tpr->rx_jmb_buffers = kzalloc(sizeof(struct ring_info) *
TG3_RX_JUMBO_RING_SIZE,
tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE,
GFP_KERNEL);
if (!tpr->rx_jmb_buffers)
goto err_out;
Expand Down Expand Up @@ -5915,9 +5920,10 @@ static void tg3_free_rings(struct tg3 *tp)

dev_kfree_skb_any(skb);
}
}

tg3_rx_prodring_free(tp, &tp->prodring[0]);
if (tp->irq_cnt == 1 || j != tp->irq_cnt - 1)
tg3_rx_prodring_free(tp, &tp->prodring[j]);
}
}

/* Initialize tx/rx rings for packet processing.
Expand Down Expand Up @@ -5951,9 +5957,13 @@ static int tg3_init_rings(struct tg3 *tp)
tnapi->rx_rcb_ptr = 0;
if (tnapi->rx_rcb)
memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));

if ((tp->irq_cnt == 1 || i != tp->irq_cnt - 1) &&
tg3_rx_prodring_alloc(tp, &tp->prodring[i]))
return -ENOMEM;
}

return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
return 0;
}

/*
Expand Down Expand Up @@ -5997,7 +6007,8 @@ static void tg3_free_consistent(struct tg3 *tp)
tp->hw_stats = NULL;
}

tg3_rx_prodring_fini(tp, &tp->prodring[0]);
for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++)
tg3_rx_prodring_fini(tp, &tp->prodring[i]);
}

/*
Expand All @@ -6008,8 +6019,10 @@ static int tg3_alloc_consistent(struct tg3 *tp)
{
int i;

if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
return -ENOMEM;
for (i = 0; i < (tp->irq_cnt == 1 ? 1 : tp->irq_cnt - 1); i++) {
if (tg3_rx_prodring_init(tp, &tp->prodring[i]))
goto err_out;
}

tp->hw_stats = pci_alloc_consistent(tp->pdev,
sizeof(struct tg3_hw_stats),
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/tg3.h
Original file line number Diff line number Diff line change
Expand Up @@ -2682,7 +2682,7 @@ struct tg3 {
struct vlan_group *vlgrp;
#endif

struct tg3_rx_prodring_set prodring[1];
struct tg3_rx_prodring_set prodring[TG3_IRQ_MAX_VECS - 1];


/* begin "everything else" cacheline(s) section */
Expand Down

0 comments on commit 2b2cdb6

Please sign in to comment.