Skip to content

Commit

Permalink
tg3: Work around HW/FW limitations with vlan encapsulated frames
Browse files Browse the repository at this point in the history
TG3 appears to have an issue performing TSO and checksum offloading
correclty when the frame has been vlan encapsulated (non-accelrated).
In these cases, tcp checksum is not correctly updated.

This patch attempts to work around this issue.  After the patch,
802.1ad vlans start working correctly over tg3 devices.

CC: Prashant Sreedharan <[email protected]>
CC: Michael Chan <[email protected]>
Signed-off-by: Vladislav Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
vyasevich authored and davem330 committed Sep 22, 2014
1 parent 07d92d5 commit 476c188
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -7914,8 +7914,6 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)

entry = tnapi->tx_prod;
base_flags = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL)
base_flags |= TXD_FLAG_TCPUDP_CSUM;

mss = skb_shinfo(skb)->gso_size;
if (mss) {
Expand All @@ -7929,6 +7927,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)

hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN;

/* HW/FW can not correctly segment packets that have been
* vlan encapsulated.
*/
if (skb->protocol == htons(ETH_P_8021Q) ||
skb->protocol == htons(ETH_P_8021AD))
return tg3_tso_bug(tp, tnapi, txq, skb);

if (!skb_is_gso_v6(skb)) {
if (unlikely((ETH_HLEN + hdr_len) > 80) &&
tg3_flag(tp, TSO_BUG))
Expand Down Expand Up @@ -7979,6 +7984,17 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
base_flags |= tsflags << 12;
}
}
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
/* HW/FW can not correctly checksum packets that have been
* vlan encapsulated.
*/
if (skb->protocol == htons(ETH_P_8021Q) ||
skb->protocol == htons(ETH_P_8021AD)) {
if (skb_checksum_help(skb))
goto drop;
} else {
base_flags |= TXD_FLAG_TCPUDP_CSUM;
}
}

if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
Expand Down

0 comments on commit 476c188

Please sign in to comment.