|
|
@@ -0,0 +1,38 @@
|
|
|
+--- a/drivers/net/ethernet/marvell/mvneta.c
|
|
|
++++ b/drivers/net/ethernet/marvell/mvneta.c
|
|
|
+@@ -20,6 +20,7 @@
|
|
|
+ #include <linux/mbus.h>
|
|
|
+ #include <linux/module.h>
|
|
|
+ #include <linux/interrupt.h>
|
|
|
++#include <linux/if_vlan.h>
|
|
|
+ #include <net/ip.h>
|
|
|
+ #include <net/ipv6.h>
|
|
|
+ #include <linux/io.h>
|
|
|
+@@ -1380,15 +1381,16 @@ static u32 mvneta_skb_tx_csum(struct mvn
|
|
|
+ {
|
|
|
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
|
|
|
+ int ip_hdr_len = 0;
|
|
|
++ __be16 l3_proto = vlan_get_protocol(skb);
|
|
|
+ u8 l4_proto;
|
|
|
+
|
|
|
+- if (skb->protocol == htons(ETH_P_IP)) {
|
|
|
++ if (l3_proto == htons(ETH_P_IP)) {
|
|
|
+ struct iphdr *ip4h = ip_hdr(skb);
|
|
|
+
|
|
|
+ /* Calculate IPv4 checksum and L4 checksum */
|
|
|
+ ip_hdr_len = ip4h->ihl;
|
|
|
+ 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);
|
|
|
+
|
|
|
+ /* Read l4_protocol from one of IPv6 extra headers */
|
|
|
+@@ -1399,7 +1401,7 @@ static u32 mvneta_skb_tx_csum(struct mvn
|
|
|
+ return MVNETA_TX_L4_CSUM_NOT;
|
|
|
+
|
|
|
+ return mvneta_txq_desc_csum(skb_network_offset(skb),
|
|
|
+- skb->protocol, ip_hdr_len, l4_proto);
|
|
|
++ l3_proto, ip_hdr_len, l4_proto);
|
|
|
+ }
|
|
|
+
|
|
|
+ return MVNETA_TX_L4_CSUM_NOT;
|