aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/marvell/mv643xx_eth.c
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>2014-05-19 12:59:57 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-22 14:57:16 -0400
commit84411f73b8849c494fc6dd3bb6b5f10ee6e58a5b (patch)
tree4604fc6d67cbe7d63e93c474be8d6024646b50a8 /drivers/net/ethernet/marvell/mv643xx_eth.c
parent0a8fa93310779ee5334e64635f98f9c72781e643 (diff)
net: mv643xx_eth: Avoid setting the initial TCP checksum
As specified in the datasheet, the driver can set the "L4Chk_Mode" flag (bit 10) in the Tx descriptor command/status to specify that a frame is not IP fragmented and that the controller is in charge of generating the TCP/IP checksum. This must be used together with the "GL4chk" flag (bit 17). These two flags allow to avoid setting the initial TCP checksum in the l4i_chk field of the Tx descriptor, which is needed to support software TSO. Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/marvell/mv643xx_eth.c')
-rw-r--r--drivers/net/ethernet/marvell/mv643xx_eth.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c
index 14a0dbb6284e..5ad19d2e2f2d 100644
--- a/drivers/net/ethernet/marvell/mv643xx_eth.c
+++ b/drivers/net/ethernet/marvell/mv643xx_eth.c
@@ -250,6 +250,7 @@ struct tx_desc {
250#define GEN_TCP_UDP_CHECKSUM 0x00020000 250#define GEN_TCP_UDP_CHECKSUM 0x00020000
251#define UDP_FRAME 0x00010000 251#define UDP_FRAME 0x00010000
252#define MAC_HDR_EXTRA_4_BYTES 0x00008000 252#define MAC_HDR_EXTRA_4_BYTES 0x00008000
253#define GEN_TCP_UDP_CHK_FULL 0x00000400
253#define MAC_HDR_EXTRA_8_BYTES 0x00000200 254#define MAC_HDR_EXTRA_8_BYTES 0x00000200
254 255
255#define TX_IHL_SHIFT 11 256#define TX_IHL_SHIFT 11
@@ -695,17 +696,19 @@ static int skb_tx_csum(struct mv643xx_eth_private *mp, struct sk_buff *skb,
695 if (tag_bytes & 8) 696 if (tag_bytes & 8)
696 cmd |= MAC_HDR_EXTRA_8_BYTES; 697 cmd |= MAC_HDR_EXTRA_8_BYTES;
697 698
698 cmd |= GEN_TCP_UDP_CHECKSUM | 699 cmd |= GEN_TCP_UDP_CHECKSUM | GEN_TCP_UDP_CHK_FULL |
699 GEN_IP_V4_CHECKSUM | 700 GEN_IP_V4_CHECKSUM |
700 ip_hdr(skb)->ihl << TX_IHL_SHIFT; 701 ip_hdr(skb)->ihl << TX_IHL_SHIFT;
701 702
703 /* TODO: Revisit this. With the usage of GEN_TCP_UDP_CHK_FULL
704 * it seems we don't need to pass the initial checksum. */
702 switch (ip_hdr(skb)->protocol) { 705 switch (ip_hdr(skb)->protocol) {
703 case IPPROTO_UDP: 706 case IPPROTO_UDP:
704 cmd |= UDP_FRAME; 707 cmd |= UDP_FRAME;
705 *l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check)); 708 *l4i_chk = 0;
706 break; 709 break;
707 case IPPROTO_TCP: 710 case IPPROTO_TCP:
708 *l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check)); 711 *l4i_chk = 0;
709 break; 712 break;
710 default: 713 default:
711 WARN(1, "protocol not supported"); 714 WARN(1, "protocol not supported");