aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2007-08-21 23:49:15 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:48 -0400
commit27186dc325c3bbb937a27a2467cefd64e2505158 (patch)
tree20dab934c51ce84b400e99dd8f61d89411d692d8
parent6e3f03b72c1e11e19ea233a411a782f7231ba13f (diff)
cxgb3 - use immediate data for offload Tx
Send small TX_DATA work requests as immediate data even when there are fragments. this avoids doing multiple DMAs for small fragmented packets. The driver already implements this optimization for small contiguous packets. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/cxgb3/sge.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 9233bbba9e91..540ce5fa1d32 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1179,8 +1179,8 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
1179 * 1179 *
1180 * Writes a packet as immediate data into a Tx descriptor. The packet 1180 * Writes a packet as immediate data into a Tx descriptor. The packet
1181 * contains a work request at its beginning. We must write the packet 1181 * contains a work request at its beginning. We must write the packet
1182 * carefully so the SGE doesn't read accidentally before it's written in 1182 * carefully so the SGE doesn't read it accidentally before it's written
1183 * its entirety. 1183 * in its entirety.
1184 */ 1184 */
1185static inline void write_imm(struct tx_desc *d, struct sk_buff *skb, 1185static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
1186 unsigned int len, unsigned int gen) 1186 unsigned int len, unsigned int gen)
@@ -1188,7 +1188,11 @@ static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
1188 struct work_request_hdr *from = (struct work_request_hdr *)skb->data; 1188 struct work_request_hdr *from = (struct work_request_hdr *)skb->data;
1189 struct work_request_hdr *to = (struct work_request_hdr *)d; 1189 struct work_request_hdr *to = (struct work_request_hdr *)d;
1190 1190
1191 memcpy(&to[1], &from[1], len - sizeof(*from)); 1191 if (likely(!skb->data_len))
1192 memcpy(&to[1], &from[1], len - sizeof(*from));
1193 else
1194 skb_copy_bits(skb, sizeof(*from), &to[1], len - sizeof(*from));
1195
1192 to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP | 1196 to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP |
1193 V_WR_BCNTLFLT(len & 7)); 1197 V_WR_BCNTLFLT(len & 7));
1194 wmb(); 1198 wmb();
@@ -1258,7 +1262,7 @@ static inline void reclaim_completed_tx_imm(struct sge_txq *q)
1258 1262
1259static inline int immediate(const struct sk_buff *skb) 1263static inline int immediate(const struct sk_buff *skb)
1260{ 1264{
1261 return skb->len <= WR_LEN && !skb->data_len; 1265 return skb->len <= WR_LEN;
1262} 1266}
1263 1267
1264/** 1268/**
@@ -1464,12 +1468,13 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
1464 */ 1468 */
1465static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb) 1469static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
1466{ 1470{
1467 unsigned int flits, cnt = skb_shinfo(skb)->nr_frags; 1471 unsigned int flits, cnt;
1468 1472
1469 if (skb->len <= WR_LEN && cnt == 0) 1473 if (skb->len <= WR_LEN)
1470 return 1; /* packet fits as immediate data */ 1474 return 1; /* packet fits as immediate data */
1471 1475
1472 flits = skb_transport_offset(skb) / 8; /* headers */ 1476 flits = skb_transport_offset(skb) / 8; /* headers */
1477 cnt = skb_shinfo(skb)->nr_frags;
1473 if (skb->tail != skb->transport_header) 1478 if (skb->tail != skb->transport_header)
1474 cnt++; 1479 cnt++;
1475 return flits_to_desc(flits + sgl_len(cnt)); 1480 return flits_to_desc(flits + sgl_len(cnt));