diff options
author | Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | 2014-05-19 12:59:57 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-22 14:57:16 -0400 |
commit | 84411f73b8849c494fc6dd3bb6b5f10ee6e58a5b (patch) | |
tree | 4604fc6d67cbe7d63e93c474be8d6024646b50a8 /drivers/net/ethernet/marvell/mv643xx_eth.c | |
parent | 0a8fa93310779ee5334e64635f98f9c72781e643 (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.c | 9 |
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"); |