tg3: Add partial fragment unmapping code
authorMatt Carlson <mcarlson@broadcom.com>
Wed, 27 Jul 2011 14:20:50 +0000 (14:20 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 28 Jul 2011 05:39:31 +0000 (22:39 -0700)
The following patches are going to break skb fragments into smaller
sizes.  This patch attempts to make the change easier to digest by only
addressing the skb teardown portion.

The patch modifies the driver to skip over any BDs that have a flag set
that indicates the BD isn't the beginning of an skb fragment.  Such BDs
were a result of segmentation and do not need a pci_unmap_page() call.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tg3.c
drivers/net/tg3.h

index 3f69f1ace26737e2d4748f8915e3a14d00303288..90b68a229745c3a7fed541b6a7e7d7e31ccda442 100644 (file)
@@ -4840,6 +4840,12 @@ static void tg3_tx(struct tg3_napi *tnapi)
 
                ri->skb = NULL;
 
+               while (ri->fragmented) {
+                       ri->fragmented = false;
+                       sw_idx = NEXT_TX(sw_idx);
+                       ri = &tnapi->tx_buffers[sw_idx];
+               }
+
                sw_idx = NEXT_TX(sw_idx);
 
                for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
@@ -4851,6 +4857,13 @@ static void tg3_tx(struct tg3_napi *tnapi)
                                       dma_unmap_addr(ri, mapping),
                                       skb_shinfo(skb)->frags[i].size,
                                       PCI_DMA_TODEVICE);
+
+                       while (ri->fragmented) {
+                               ri->fragmented = false;
+                               sw_idx = NEXT_TX(sw_idx);
+                               ri = &tnapi->tx_buffers[sw_idx];
+                       }
+
                        sw_idx = NEXT_TX(sw_idx);
                }
 
@@ -5926,6 +5939,13 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
                         dma_unmap_addr(txb, mapping),
                         skb_headlen(skb),
                         PCI_DMA_TODEVICE);
+
+       while (txb->fragmented) {
+               txb->fragmented = false;
+               entry = NEXT_TX(entry);
+               txb = &tnapi->tx_buffers[entry];
+       }
+
        for (i = 0; i < last; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
@@ -5935,6 +5955,12 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
                pci_unmap_page(tnapi->tp->pdev,
                               dma_unmap_addr(txb, mapping),
                               frag->size, PCI_DMA_TODEVICE);
+
+               while (txb->fragmented) {
+                       txb->fragmented = false;
+                       entry = NEXT_TX(entry);
+                       txb = &tnapi->tx_buffers[entry];
+               }
        }
 }
 
index f6986ca50d803c25c7c4d00fd61f62133b5c1926..466dd7add12b5da33634788839ff383e25e76c89 100644 (file)
@@ -2655,6 +2655,7 @@ struct ring_info {
 struct tg3_tx_ring_info {
        struct sk_buff                  *skb;
        DEFINE_DMA_UNMAP_ADDR(mapping);
+       bool                            fragmented;
 };
 
 struct tg3_link_config {