mv643xx_eth: replace array of skbs awaiting transmit completion with a queue
Get rid of the skb pointer array that we currently use for transmit reclaim, and replace it with an skb queue, to which skbuffs are appended when they are passed to the xmit function, and removed from the front and freed when we do transmit queue reclaim and hit a descriptor with the 'owned by device' bit clear and 'last descriptor' bit set. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
This commit is contained in:
parent
a418950c13
commit
99ab08e091
|
@ -336,7 +336,8 @@ struct tx_queue {
|
|||
struct tx_desc *tx_desc_area;
|
||||
dma_addr_t tx_desc_dma;
|
||||
int tx_desc_area_size;
|
||||
struct sk_buff **tx_skb;
|
||||
|
||||
struct sk_buff_head tx_skb;
|
||||
|
||||
unsigned long tx_packets;
|
||||
unsigned long tx_bytes;
|
||||
|
@ -676,10 +677,8 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
|
|||
desc->cmd_sts = BUFFER_OWNED_BY_DMA |
|
||||
ZERO_PADDING | TX_LAST_DESC |
|
||||
TX_ENABLE_INTERRUPT;
|
||||
txq->tx_skb[tx_index] = skb;
|
||||
} else {
|
||||
desc->cmd_sts = BUFFER_OWNED_BY_DMA;
|
||||
txq->tx_skb[tx_index] = NULL;
|
||||
}
|
||||
|
||||
desc->l4i_chk = 0;
|
||||
|
@ -712,13 +711,10 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
|
|||
|
||||
if (nr_frags) {
|
||||
txq_submit_frag_skb(txq, skb);
|
||||
|
||||
length = skb_headlen(skb);
|
||||
txq->tx_skb[tx_index] = NULL;
|
||||
} else {
|
||||
cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
|
||||
length = skb->len;
|
||||
txq->tx_skb[tx_index] = skb;
|
||||
}
|
||||
|
||||
desc->byte_cnt = length;
|
||||
|
@ -772,6 +768,8 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
|
|||
desc->l4i_chk = 0;
|
||||
}
|
||||
|
||||
__skb_queue_tail(&txq->tx_skb, skb);
|
||||
|
||||
/* ensure all other descriptors are written before first cmd_sts */
|
||||
wmb();
|
||||
desc->cmd_sts = cmd_sts;
|
||||
|
@ -884,8 +882,9 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
|
|||
reclaimed++;
|
||||
txq->tx_desc_count--;
|
||||
|
||||
skb = txq->tx_skb[tx_index];
|
||||
txq->tx_skb[tx_index] = NULL;
|
||||
skb = NULL;
|
||||
if (cmd_sts & TX_LAST_DESC)
|
||||
skb = __skb_dequeue(&txq->tx_skb);
|
||||
|
||||
if (cmd_sts & ERROR_SUMMARY) {
|
||||
dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");
|
||||
|
@ -1692,18 +1691,11 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
|
|||
if (txq->tx_desc_area == NULL) {
|
||||
dev_printk(KERN_ERR, &mp->dev->dev,
|
||||
"can't allocate tx ring (%d bytes)\n", size);
|
||||
goto out;
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(txq->tx_desc_area, 0, size);
|
||||
|
||||
txq->tx_desc_area_size = size;
|
||||
txq->tx_skb = kmalloc(txq->tx_ring_size * sizeof(*txq->tx_skb),
|
||||
GFP_KERNEL);
|
||||
if (txq->tx_skb == NULL) {
|
||||
dev_printk(KERN_ERR, &mp->dev->dev,
|
||||
"can't allocate tx skb ring\n");
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
tx_desc = (struct tx_desc *)txq->tx_desc_area;
|
||||
for (i = 0; i < txq->tx_ring_size; i++) {
|
||||
|
@ -1719,18 +1711,9 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
|
|||
nexti * sizeof(struct tx_desc);
|
||||
}
|
||||
|
||||
skb_queue_head_init(&txq->tx_skb);
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
if (index == 0 && size <= mp->tx_desc_sram_size)
|
||||
iounmap(txq->tx_desc_area);
|
||||
else
|
||||
dma_free_coherent(NULL, size,
|
||||
txq->tx_desc_area,
|
||||
txq->tx_desc_dma);
|
||||
|
||||
out:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void txq_deinit(struct tx_queue *txq)
|
||||
|
@ -1748,8 +1731,6 @@ static void txq_deinit(struct tx_queue *txq)
|
|||
else
|
||||
dma_free_coherent(NULL, txq->tx_desc_area_size,
|
||||
txq->tx_desc_area, txq->tx_desc_dma);
|
||||
|
||||
kfree(txq->tx_skb);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue