]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/mv643xx_eth.c
mv643xx_eth: replace array of skbs awaiting transmit completion with a queue
[linux-2.6-omap-h63xx.git] / drivers / net / mv643xx_eth.c
index 7410eca87823a6ba1cbfb5cd3f8728206548e715..099e0be0d8c3af67daa1907e909a0acaccbf909d 100644 (file)
@@ -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);
        }
 
-       return 0;
+       skb_queue_head_init(&txq->tx_skb);
 
-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;
+       return 0;
 }
 
 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);
 }