|
@@ -1179,8 +1179,8 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
|
*
|
|
|
* Writes a packet as immediate data into a Tx descriptor. The packet
|
|
|
* contains a work request at its beginning. We must write the packet
|
|
|
- * carefully so the SGE doesn't read accidentally before it's written in
|
|
|
- * its entirety.
|
|
|
+ * carefully so the SGE doesn't read it accidentally before it's written
|
|
|
+ * in its entirety.
|
|
|
*/
|
|
|
static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
|
|
|
unsigned int len, unsigned int gen)
|
|
@@ -1188,7 +1188,11 @@ static inline void write_imm(struct tx_desc *d, struct sk_buff *skb,
|
|
|
struct work_request_hdr *from = (struct work_request_hdr *)skb->data;
|
|
|
struct work_request_hdr *to = (struct work_request_hdr *)d;
|
|
|
|
|
|
- memcpy(&to[1], &from[1], len - sizeof(*from));
|
|
|
+ if (likely(!skb->data_len))
|
|
|
+ memcpy(&to[1], &from[1], len - sizeof(*from));
|
|
|
+ else
|
|
|
+ skb_copy_bits(skb, sizeof(*from), &to[1], len - sizeof(*from));
|
|
|
+
|
|
|
to->wr_hi = from->wr_hi | htonl(F_WR_SOP | F_WR_EOP |
|
|
|
V_WR_BCNTLFLT(len & 7));
|
|
|
wmb();
|
|
@@ -1258,7 +1262,7 @@ static inline void reclaim_completed_tx_imm(struct sge_txq *q)
|
|
|
|
|
|
static inline int immediate(const struct sk_buff *skb)
|
|
|
{
|
|
|
- return skb->len <= WR_LEN && !skb->data_len;
|
|
|
+ return skb->len <= WR_LEN;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1464,12 +1468,13 @@ static void write_ofld_wr(struct adapter *adap, struct sk_buff *skb,
|
|
|
*/
|
|
|
static inline unsigned int calc_tx_descs_ofld(const struct sk_buff *skb)
|
|
|
{
|
|
|
- unsigned int flits, cnt = skb_shinfo(skb)->nr_frags;
|
|
|
+ unsigned int flits, cnt;
|
|
|
|
|
|
- if (skb->len <= WR_LEN && cnt == 0)
|
|
|
+ if (skb->len <= WR_LEN)
|
|
|
return 1; /* packet fits as immediate data */
|
|
|
|
|
|
flits = skb_transport_offset(skb) / 8; /* headers */
|
|
|
+ cnt = skb_shinfo(skb)->nr_frags;
|
|
|
if (skb->tail != skb->transport_header)
|
|
|
cnt++;
|
|
|
return flits_to_desc(flits + sgl_len(cnt));
|