aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByron Bradley <byron.bbradley@gmail.com>2008-02-05 02:47:15 -0500
committerJeff Garzik <jeff@garzik.org>2008-02-05 13:31:11 -0500
commit324ff2c1793b6d3d5c377cf6de2ada9b49af227a (patch)
treee512aa45a121841f2f989aa5201b17533a97bee4
parent39dbd9587bebedbd72be9a8a30a8c4783f3ef7eb (diff)
mv643xx_eth: fix byte order when checksum offload is enabled
The Marvell Orion system on chips have an integrated mv643xx MAC. On these little endian ARM devices mv643xx will oops when checksum offload is enabled. Swapping the byte order of the protocol and checksum solves this problem. Signed-off-by: Byron Bradley <byron.bbradley@gmail.com> Cc: Dale Farnsworth <dale@farnsworth.org> Cc: Manish Lachwani <mlachwani@mvista.com> Cc: Jeff Garzik <jeff@garzik.org> Cc: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/mv643xx_eth.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c2699d5e1..b528ce77c406 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1652,6 +1652,11 @@ static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
1652 } 1652 }
1653} 1653}
1654 1654
1655static inline __be16 sum16_as_be(__sum16 sum)
1656{
1657 return (__force __be16)sum;
1658}
1659
1655/** 1660/**
1656 * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw 1661 * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw
1657 * 1662 *
@@ -1689,7 +1694,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
1689 desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); 1694 desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
1690 1695
1691 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1696 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1692 BUG_ON(skb->protocol != ETH_P_IP); 1697 BUG_ON(skb->protocol != htons(ETH_P_IP));
1693 1698
1694 cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | 1699 cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
1695 ETH_GEN_IP_V_4_CHECKSUM | 1700 ETH_GEN_IP_V_4_CHECKSUM |
@@ -1698,10 +1703,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
1698 switch (ip_hdr(skb)->protocol) { 1703 switch (ip_hdr(skb)->protocol) {
1699 case IPPROTO_UDP: 1704 case IPPROTO_UDP:
1700 cmd_sts |= ETH_UDP_FRAME; 1705 cmd_sts |= ETH_UDP_FRAME;
1701 desc->l4i_chk = udp_hdr(skb)->check; 1706 desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
1702 break; 1707 break;
1703 case IPPROTO_TCP: 1708 case IPPROTO_TCP:
1704 desc->l4i_chk = tcp_hdr(skb)->check; 1709 desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
1705 break; 1710 break;
1706 default: 1711 default:
1707 BUG(); 1712 BUG();