Skip to content

Commit

Permalink
8139cp: Reduce duplicate csum/tso code in cp_start_xmit()
Browse files Browse the repository at this point in the history
We calculate the value of the opts1 descriptor field in three different
places. With two different behaviours when given an invalid packet to
be checksummed — none of them correct. Sort that out.

Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David Woodhouse authored and David S. Miller committed Sep 23, 2015
1 parent a3b8040 commit 0a5aeee
Showing 1 changed file with 20 additions and 41 deletions.
61 changes: 20 additions & 41 deletions drivers/net/ethernet/realtek/8139cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
{
struct cp_private *cp = netdev_priv(dev);
unsigned entry;
u32 eor, flags;
u32 eor, opts1;
unsigned long intr_flags;
__le32 opts2;
int mss = 0;
Expand All @@ -753,6 +753,21 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
mss = skb_shinfo(skb)->gso_size;

opts2 = cpu_to_le32(cp_tx_vlan_tag(skb));
opts1 = DescOwn;
if (mss)
opts1 |= LargeSend | ((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
if (ip->protocol == IPPROTO_TCP)
opts1 |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
opts1 |= IPCS | UDPCS;
else {
WARN_ONCE(1,
"Net bug: asked to checksum invalid Legacy IP packet\n");
goto out_dma_error;
}
}

if (skb_shinfo(skb)->nr_frags == 0) {
struct cp_desc *txd = &cp->tx_ring[entry];
Expand All @@ -768,21 +783,9 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
txd->addr = cpu_to_le64(mapping);
wmb();

flags = eor | len | DescOwn | FirstFrag | LastFrag;

if (mss)
flags |= LargeSend | ((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_PARTIAL) {
const struct iphdr *ip = ip_hdr(skb);
if (ip->protocol == IPPROTO_TCP)
flags |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
flags |= IPCS | UDPCS;
else
WARN_ON(1); /* we need a WARN() */
}
opts1 |= eor | len | FirstFrag | LastFrag;

txd->opts1 = cpu_to_le32(flags);
txd->opts1 = cpu_to_le32(opts1);
wmb();

cp->tx_skb[entry] = skb;
Expand All @@ -793,7 +796,6 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
u32 first_len, first_eor, ctrl;
dma_addr_t first_mapping;
int frag, first_entry = entry;
const struct iphdr *ip = ip_hdr(skb);

/* We must give this initial chunk to the device last.
* Otherwise we could race with the device.
Expand Down Expand Up @@ -825,19 +827,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,

eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;

ctrl = eor | len | DescOwn;

if (mss)
ctrl |= LargeSend |
((mss & MSSMask) << MSSShift);
else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (ip->protocol == IPPROTO_TCP)
ctrl |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
ctrl |= IPCS | UDPCS;
else
BUG();
}
ctrl = opts1 | eor | len;

if (frag == skb_shinfo(skb)->nr_frags - 1)
ctrl |= LastFrag;
Expand All @@ -857,18 +847,7 @@ static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
txd->addr = cpu_to_le64(first_mapping);
wmb();

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)
ctrl |= IPCS | TCPCS;
else if (ip->protocol == IPPROTO_UDP)
ctrl |= IPCS | UDPCS;
else
BUG();
}

ctrl = opts1 | first_eor | first_len | FirstFrag;
txd->opts1 = cpu_to_le32(ctrl);
wmb();

Expand Down

0 comments on commit 0a5aeee

Please sign in to comment.