sky2: transmit ring 64 bit conservation
authorStephen Hemminger <shemminger@vyatta.com>
Tue, 18 Aug 2009 15:17:06 +0000 (15:17 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Aug 2009 03:26:43 +0000 (20:26 -0700)
This patch saves elements on transmit ring by only updating the upper
64 bit address when it changes. With many workloads skb's are located
in same region, so it saves space.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/sky2.c
drivers/net/sky2.h

index fb841c815b5d9e6e8aa0e825262e59d157cb41b8..88041e57887065add332ad5aa51a5421a554c3b4 100644 (file)
@@ -1016,6 +1016,7 @@ static void tx_init(struct sky2_port *sky2)
        le = get_tx_le(sky2, &sky2->tx_prod);
        le->addr = 0;
        le->opcode = OP_ADDR64 | HW_OWNER;
+       sky2->tx_last_upper = 0;
 }
 
 static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
@@ -1573,8 +1574,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
        struct sky2_tx_le *le = NULL;
        struct tx_ring_info *re;
        unsigned i, len;
-       u16 slot;
        dma_addr_t mapping;
+       u32 upper;
+       u16 slot;
        u16 mss;
        u8 ctrl;
 
@@ -1593,9 +1595,11 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                       dev->name, slot, skb->len);
 
        /* Send high bits if needed */
-       if (sizeof(dma_addr_t) > sizeof(u32)) {
+       upper = upper_32_bits(mapping);
+       if (upper != sky2->tx_last_upper) {
                le = get_tx_le(sky2, &slot);
-               le->addr = cpu_to_le32(upper_32_bits(mapping));
+               le->addr = cpu_to_le32(upper);
+               sky2->tx_last_upper = upper;
                le->opcode = OP_ADDR64 | HW_OWNER;
        }
 
@@ -1681,10 +1685,11 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                if (pci_dma_mapping_error(hw->pdev, mapping))
                        goto mapping_unwind;
 
-               if (sizeof(dma_addr_t) > sizeof(u32)) {
+               upper = upper_32_bits(mapping);
+               if (upper != sky2->tx_last_upper) {
                        le = get_tx_le(sky2, &slot);
-                       le->addr = cpu_to_le32(upper_32_bits(mapping));
-                       le->ctrl = 0;
+                       le->addr = cpu_to_le32(upper);
+                       sky2->tx_last_upper = upper;
                        le->opcode = OP_ADDR64 | HW_OWNER;
                }
 
index 65b94c366fbc365145467b29520f5585297591fa..feb3204134edfdb13a6ef5a9bd5f82051f443d10 100644 (file)
@@ -2017,6 +2017,7 @@ struct sky2_port {
 
        u16                  tx_pending;
        u16                  tx_last_mss;
+       u32                  tx_last_upper;
        u32                  tx_tcpsum;
 
        struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;