Commit 35f3625c authored by Maxime Chevallier's avatar Maxime Chevallier Committed by David S. Miller

net: mvpp2: Extract the correct ethtype from the skb for tx csum offload

When offloading the L3 and L4 csum computation on TX, we need to extract
the l3_proto from the ethtype, independently of the presence of a vlan
tag.

The actual driver uses skb->protocol as-is, resulting in packets with
the wrong L4 checksum being sent when there's a vlan tag in the packet
header and checksum offloading is enabled.

This commit makes use of vlan_protocol_get() to get the correct ethtype
regardless the presence of a vlan tag.

Fixes: 3f518509 ("ethernet: Add new driver for Marvell Armada 375 network unit")
Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a688caa3
...@@ -1725,7 +1725,7 @@ static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq) ...@@ -1725,7 +1725,7 @@ static void mvpp2_txq_desc_put(struct mvpp2_tx_queue *txq)
} }
/* Set Tx descriptors fields relevant for CSUM calculation */ /* Set Tx descriptors fields relevant for CSUM calculation */
static u32 mvpp2_txq_desc_csum(int l3_offs, int l3_proto, static u32 mvpp2_txq_desc_csum(int l3_offs, __be16 l3_proto,
int ip_hdr_len, int l4_proto) int ip_hdr_len, int l4_proto)
{ {
u32 command; u32 command;
...@@ -2600,14 +2600,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb) ...@@ -2600,14 +2600,15 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb->ip_summed == CHECKSUM_PARTIAL) {
int ip_hdr_len = 0; int ip_hdr_len = 0;
u8 l4_proto; u8 l4_proto;
__be16 l3_proto = vlan_get_protocol(skb);
if (skb->protocol == htons(ETH_P_IP)) { if (l3_proto == htons(ETH_P_IP)) {
struct iphdr *ip4h = ip_hdr(skb); struct iphdr *ip4h = ip_hdr(skb);
/* Calculate IPv4 checksum and L4 checksum */ /* Calculate IPv4 checksum and L4 checksum */
ip_hdr_len = ip4h->ihl; ip_hdr_len = ip4h->ihl;
l4_proto = ip4h->protocol; l4_proto = ip4h->protocol;
} else if (skb->protocol == htons(ETH_P_IPV6)) { } else if (l3_proto == htons(ETH_P_IPV6)) {
struct ipv6hdr *ip6h = ipv6_hdr(skb); struct ipv6hdr *ip6h = ipv6_hdr(skb);
/* Read l4_protocol from one of IPv6 extra headers */ /* Read l4_protocol from one of IPv6 extra headers */
...@@ -2619,7 +2620,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb) ...@@ -2619,7 +2620,7 @@ static u32 mvpp2_skb_tx_csum(struct mvpp2_port *port, struct sk_buff *skb)
} }
return mvpp2_txq_desc_csum(skb_network_offset(skb), return mvpp2_txq_desc_csum(skb_network_offset(skb),
skb->protocol, ip_hdr_len, l4_proto); l3_proto, ip_hdr_len, l4_proto);
} }
return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE; return MVPP2_TXD_L4_CSUM_NOT | MVPP2_TXD_IP_CSUM_DISABLE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment