gianfar: Fall back to software tcp/udp checksum on older controllers

As specified by errata eTSEC49 of MPC8548 and errata eTSEC12 of MPC83xx,
older revisions of gianfar controllers will be unable to calculate a TCP/UDP
packet checksum for some alignments of the appropriate FCB. This patch checks
for FCB alignment on such controllers and falls back to software checksumming
if the alignment is known to be bad.

Signed-off-by: Alex Dubov <oakad@yahoo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Alex Dubov and committed by David S. Miller 4363c2fd 99759619

+15 -2
+14 -2
drivers/net/gianfar.c
··· 949 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) 950 priv->errata |= GFAR_ERRATA_A002; 951 952 if (priv->errata) 953 dev_info(dev, "enabled errata workarounds, flags: 0x%x\n", 954 priv->errata); ··· 2159 /* Set up checksumming */ 2160 if (CHECKSUM_PARTIAL == skb->ip_summed) { 2161 fcb = gfar_add_fcb(skb); 2162 - lstatus |= BD_LFLAG(TXBD_TOE); 2163 - gfar_tx_checksum(skb, fcb); 2164 } 2165 2166 if (vlan_tx_tag_present(skb)) {
··· 949 (pvr == 0x80861010 && (mod & 0xfff9) == 0x80c0)) 950 priv->errata |= GFAR_ERRATA_A002; 951 952 + /* MPC8313 Rev < 2.0, MPC8548 rev 2.0 */ 953 + if ((pvr == 0x80850010 && mod == 0x80b0 && rev < 0x0020) || 954 + (pvr == 0x80210020 && mod == 0x8030 && rev == 0x0020)) 955 + priv->errata |= GFAR_ERRATA_12; 956 + 957 if (priv->errata) 958 dev_info(dev, "enabled errata workarounds, flags: 0x%x\n", 959 priv->errata); ··· 2154 /* Set up checksumming */ 2155 if (CHECKSUM_PARTIAL == skb->ip_summed) { 2156 fcb = gfar_add_fcb(skb); 2157 + /* as specified by errata */ 2158 + if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) 2159 + && ((unsigned long)fcb % 0x20) > 0x18)) { 2160 + __skb_pull(skb, GMAC_FCB_LEN); 2161 + skb_checksum_help(skb); 2162 + } else { 2163 + lstatus |= BD_LFLAG(TXBD_TOE); 2164 + gfar_tx_checksum(skb, fcb); 2165 + } 2166 } 2167 2168 if (vlan_tx_tag_present(skb)) {
+1
drivers/net/gianfar.h
··· 1039 GFAR_ERRATA_74 = 0x01, 1040 GFAR_ERRATA_76 = 0x02, 1041 GFAR_ERRATA_A002 = 0x04, 1042 }; 1043 1044 /* Struct stolen almost completely (and shamelessly) from the FCC enet source
··· 1039 GFAR_ERRATA_74 = 0x01, 1040 GFAR_ERRATA_76 = 0x02, 1041 GFAR_ERRATA_A002 = 0x04, 1042 + GFAR_ERRATA_12 = 0x08, /* a.k.a errata eTSEC49 */ 1043 }; 1044 1045 /* Struct stolen almost completely (and shamelessly) from the FCC enet source