提交 a3b80404 编写于 作者: D David Woodhouse 提交者: David S. Miller

8139cp: Fix TSO/scatter-gather descriptor setup

When sending a TSO frame in multiple buffers, we were neglecting to set
the first descriptor up in TSO mode.
Signed-off-by: NDavid Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 26b0bad6
...@@ -790,7 +790,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, ...@@ -790,7 +790,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
entry, skb->len); entry, skb->len);
} else { } else {
struct cp_desc *txd; struct cp_desc *txd;
u32 first_len, first_eor; u32 first_len, first_eor, ctrl;
dma_addr_t first_mapping; dma_addr_t first_mapping;
int frag, first_entry = entry; int frag, first_entry = entry;
const struct iphdr *ip = ip_hdr(skb); const struct iphdr *ip = ip_hdr(skb);
...@@ -810,7 +810,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, ...@@ -810,7 +810,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; const skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
u32 len; u32 len;
u32 ctrl;
dma_addr_t mapping; dma_addr_t mapping;
entry = NEXT_TX(entry); entry = NEXT_TX(entry);
...@@ -858,20 +857,19 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb, ...@@ -858,20 +857,19 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
txd->addr = cpu_to_le64(first_mapping); txd->addr = cpu_to_le64(first_mapping);
wmb(); wmb();
if (skb->ip_summed == CHECKSUM_PARTIAL) { ctrl = first_eor | first_len | FirstFrag | DescOwn;
if (mss)
ctrl |= LargeSend | ((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (ip->protocol == IPPROTO_TCP) if (ip->protocol == IPPROTO_TCP)
txd->opts1 = cpu_to_le32(first_eor | first_len | ctrl |= IPCS | TCPCS;
FirstFrag | DescOwn |
IPCS | TCPCS);
else if (ip->protocol == IPPROTO_UDP) else if (ip->protocol == IPPROTO_UDP)
txd->opts1 = cpu_to_le32(first_eor | first_len | ctrl |= IPCS | UDPCS;
FirstFrag | DescOwn |
IPCS | UDPCS);
else else
BUG(); BUG();
} else }
txd->opts1 = cpu_to_le32(first_eor | first_len |
FirstFrag | DescOwn); txd->opts1 = cpu_to_le32(ctrl);
wmb(); wmb();
netif_dbg(cp, tx_queued, cp->dev, "tx queued, slots %d-%d, skblen %d\n", netif_dbg(cp, tx_queued, cp->dev, "tx queued, slots %d-%d, skblen %d\n",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册