[PATCH 3.10 07/16] tg3: Work around HW/FW limitations with vlan encapsulated frames

From: Greg Kroah-Hartman
Date: Sun Oct 12 2014 - 22:25:50 EST


3.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vlad Yasevich <vyasevich@xxxxxxxxx>

[ Upstream commit 476c18850c6cbaa3f2bb661ae9710645081563b9 ]

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 <prashant@xxxxxxxxxxxx>
CC: Michael Chan <mchan@xxxxxxxxxxxx>
Signed-off-by: Vladislav Yasevich <vyasevic@xxxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/net/ethernet/broadcom/tg3.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)

--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -7759,8 +7759,6 @@ static netdev_tx_t tg3_start_xmit(struct

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) {
@@ -7776,6 +7774,13 @@ static netdev_tx_t tg3_start_xmit(struct

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, skb);
+
if (!skb_is_gso_v6(skb)) {
iph->check = 0;
iph->tot_len = htons(mss + hdr_len);
@@ -7822,6 +7827,17 @@ static netdev_tx_t tg3_start_xmit(struct
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) &&


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/