summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2009-08-18 15:17:06 +0000
committerDavid S. Miller <davem@davemloft.net>2009-08-18 20:26:43 -0700
commit5dce95e5687a5a335202b03d133c1b4411ef7ce3 (patch)
tree3bb90badb02e92ccd2607e4312116819d424ee7b
parentd6e74b6b7eda3584a403eebae27f9591a1d9c9ff (diff)
sky2: transmit ring 64 bit conservation
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>
-rw-r--r--drivers/net/sky2.c17
-rw-r--r--drivers/net/sky2.h1
2 files changed, 12 insertions, 6 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index fb841c815b5..88041e57887 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -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;
}
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 65b94c366fb..feb3204134e 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -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;