netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mv643xx: fix byte order when checksum offload is enabled
@ 2008-01-19 19:27 Byron Bradley
  2008-01-19 20:09 ` Al Viro
  2008-01-19 20:23 ` Dale Farnsworth
  0 siblings, 2 replies; 5+ messages in thread
From: Byron Bradley @ 2008-01-19 19:27 UTC (permalink / raw)
  To: netdev
  Cc: hvr, akpm, Byron Bradley, Dale Farnsworth, Manish Lachwani,
	Tzachi Perelstein

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: Tzachi Perelstein <tzachi@marvell.com>
---

This patch has only been tested on two Marvell Orion based boards so it
should be considered only very lightly tested. It applies against
2.6.24-rc8-mm1.

 drivers/net/mv643xx_eth.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c269..5d16a5d 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1689,7 +1689,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		BUG_ON(skb->protocol != ETH_P_IP);
+		BUG_ON(skb->protocol != htons(ETH_P_IP));
 
 		cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
 			   ETH_GEN_IP_V_4_CHECKSUM  |
@@ -1698,10 +1698,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 		switch (ip_hdr(skb)->protocol) {
 		case IPPROTO_UDP:
 			cmd_sts |= ETH_UDP_FRAME;
-			desc->l4i_chk = udp_hdr(skb)->check;
+			desc->l4i_chk = htons(udp_hdr(skb)->check);
 			break;
 		case IPPROTO_TCP:
-			desc->l4i_chk = tcp_hdr(skb)->check;
+			desc->l4i_chk = htons(tcp_hdr(skb)->check);
 			break;
 		default:
 			BUG();
-- 
1.5.4.rc2.38.gd6da3



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] mv643xx: fix byte order when checksum offload is enabled
  2008-01-19 19:27 [PATCH] mv643xx: fix byte order when checksum offload is enabled Byron Bradley
@ 2008-01-19 20:09 ` Al Viro
  2008-01-20 15:05   ` [PATCH] mv643xx_eth: " Byron Bradley
  2008-01-19 20:23 ` Dale Farnsworth
  1 sibling, 1 reply; 5+ messages in thread
From: Al Viro @ 2008-01-19 20:09 UTC (permalink / raw)
  To: Byron Bradley
  Cc: netdev, hvr, akpm, Dale Farnsworth, Manish Lachwani,
	Tzachi Perelstein

On Sat, Jan 19, 2008 at 07:27:38PM +0000, Byron Bradley wrote:
>  		case IPPROTO_UDP:
>  			cmd_sts |= ETH_UDP_FRAME;
> -			desc->l4i_chk = udp_hdr(skb)->check;
> +			desc->l4i_chk = htons(udp_hdr(skb)->check);
>  			break;
>  		case IPPROTO_TCP:
> -			desc->l4i_chk = tcp_hdr(skb)->check;
> +			desc->l4i_chk = htons(tcp_hdr(skb)->check);
>  			break;

The first part was OK, but this one...  AFAICS, the sucker byteswaps
64bit words in descriptors wholesale, right?  Then the right way to spell
that would be ntohs((__force __be16)....->check).

What's happening here is that we take a fixed-endian (checksum) and then
correct for conversion done in hardware - i.e. we store it in something
that expects a _host_-endian value and would convert that to fixed-endian.
So we need to counter that correction and that's where the damn thing is
coming from.

It's not particulary rare - drivers that do hardware byteswap tend to need
it.  For now I'd suggest explicit form (with force-cast from __csum to
__be16 and ntohs() on top of it); if anybody has good ideas for helper
names, though...  csum_as_le() and csum_as_be(), perhaps?  Interpret
__csum (fixed-endian) and another fixed-endian type, with proper checks;
i.e. something along the lines of
static inline __be16 csum_as_be(__csum sum)
{
	return (__force __be16)sum;
}
and this stuff becoming ntohs(csum_as_be(udp_hdr(skb)->check)), etc.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] mv643xx_eth: fix byte order when checksum offload is enabled
  2008-01-19 19:27 [PATCH] mv643xx: fix byte order when checksum offload is enabled Byron Bradley
  2008-01-19 20:09 ` Al Viro
@ 2008-01-19 20:23 ` Dale Farnsworth
  2008-01-19 20:45   ` Dale Farnsworth
  1 sibling, 1 reply; 5+ messages in thread
From: Dale Farnsworth @ 2008-01-19 20:23 UTC (permalink / raw)
  To: jgarzik
  Cc: netdev, hvr, akpm, Manish Lachwani, Tzachi Perelstein,
	Byron Bradley

From: Byron Bradley <byron.bbradley@gmail.com>

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>
Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
Cc: Manish Lachwani <mlachwani@mvista.com>
Cc: Tzachi Perelstein <tzachi@marvell.com>

---

Byron Bradley wrote:
> This patch has only been tested on two Marvell Orion based boards so it
> should be considered only very lightly tested. It applies against
> 2.6.24-rc8-mm1.

Dale Farnsworth:
Looks good to me and I successfully booted it on a big-endian prpmc2800 board.

Jeff, please pick this up.  My mv643xx queue is otherwise empty.

Thanks,
-Dale

 drivers/net/mv643xx_eth.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c269..5d16a5d 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1689,7 +1689,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		BUG_ON(skb->protocol != ETH_P_IP);
+		BUG_ON(skb->protocol != htons(ETH_P_IP));
 
 		cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
 			   ETH_GEN_IP_V_4_CHECKSUM  |
@@ -1698,10 +1698,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 		switch (ip_hdr(skb)->protocol) {
 		case IPPROTO_UDP:
 			cmd_sts |= ETH_UDP_FRAME;
-			desc->l4i_chk = udp_hdr(skb)->check;
+			desc->l4i_chk = htons(udp_hdr(skb)->check);
 			break;
 		case IPPROTO_TCP:
-			desc->l4i_chk = tcp_hdr(skb)->check;
+			desc->l4i_chk = htons(tcp_hdr(skb)->check);
 			break;
 		default:
 			BUG();
-- 
1.5.4.rc2.38.gd6da3



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] mv643xx_eth: fix byte order when checksum offload is enabled
  2008-01-19 20:23 ` Dale Farnsworth
@ 2008-01-19 20:45   ` Dale Farnsworth
  0 siblings, 0 replies; 5+ messages in thread
From: Dale Farnsworth @ 2008-01-19 20:45 UTC (permalink / raw)
  To: jgarzik
  Cc: netdev, hvr, akpm, Manish Lachwani, Tzachi Perelstein,
	Byron Bradley

OK, after digesting Al Viro's comments on this, I agree with him
and retract this.  These multiple byte swaps sure are confusing.

Byron, would you please resubmit?

Thanks,
-Dale

On Sat, Jan 19, 2008 at 01:23:01PM -0700, Dale Farnsworth wrote:
> From: Byron Bradley <byron.bbradley@gmail.com>
> 
> 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>
> Signed-off-by: Dale Farnsworth <dale@farnsworth.org>
> Cc: Manish Lachwani <mlachwani@mvista.com>
> Cc: Tzachi Perelstein <tzachi@marvell.com>
> 
> ---
> 
> Byron Bradley wrote:
> > This patch has only been tested on two Marvell Orion based boards so it
> > should be considered only very lightly tested. It applies against
> > 2.6.24-rc8-mm1.
> 
> Dale Farnsworth:
> Looks good to me and I successfully booted it on a big-endian prpmc2800 board.
> 
> Jeff, please pick this up.  My mv643xx queue is otherwise empty.
> 
> Thanks,
> -Dale
> 
>  drivers/net/mv643xx_eth.c |    6 +++---
>  1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
> index 651c269..5d16a5d 100644
> --- a/drivers/net/mv643xx_eth.c
> +++ b/drivers/net/mv643xx_eth.c
> @@ -1689,7 +1689,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
>  	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
>  
>  	if (skb->ip_summed == CHECKSUM_PARTIAL) {
> -		BUG_ON(skb->protocol != ETH_P_IP);
> +		BUG_ON(skb->protocol != htons(ETH_P_IP));
>  
>  		cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
>  			   ETH_GEN_IP_V_4_CHECKSUM  |
> @@ -1698,10 +1698,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
>  		switch (ip_hdr(skb)->protocol) {
>  		case IPPROTO_UDP:
>  			cmd_sts |= ETH_UDP_FRAME;
> -			desc->l4i_chk = udp_hdr(skb)->check;
> +			desc->l4i_chk = htons(udp_hdr(skb)->check);
>  			break;
>  		case IPPROTO_TCP:
> -			desc->l4i_chk = tcp_hdr(skb)->check;
> +			desc->l4i_chk = htons(tcp_hdr(skb)->check);
>  			break;
>  		default:
>  			BUG();
> -- 
> 1.5.4.rc2.38.gd6da3
> 
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] mv643xx_eth: fix byte order when checksum offload is enabled
  2008-01-19 20:09 ` Al Viro
@ 2008-01-20 15:05   ` Byron Bradley
  0 siblings, 0 replies; 5+ messages in thread
From: Byron Bradley @ 2008-01-20 15:05 UTC (permalink / raw)
  To: Al Viro
  Cc: Byron Bradley, netdev, hvr, akpm, Dale Farnsworth,
	Manish Lachwani, Tzachi Perelstein

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>
---

Resubmitted after comments from Al Viro. udp_hdr(skb)->check returns
a __sum16 so I have called the function sum16_as_be(). Again lightly
tested only on two Marvell Orion boards.

 drivers/net/mv643xx_eth.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c269..b528ce7 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,
 	}
 }

+static inline __be16 sum16_as_be(__sum16 sum)
+{
+	return (__force __be16)sum;
+}
+
 /**
  * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw
  *
@@ -1689,7 +1694,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);

 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		BUG_ON(skb->protocol != ETH_P_IP);
+		BUG_ON(skb->protocol != htons(ETH_P_IP));

 		cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
 			   ETH_GEN_IP_V_4_CHECKSUM  |
@@ -1698,10 +1703,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 		switch (ip_hdr(skb)->protocol) {
 		case IPPROTO_UDP:
 			cmd_sts |= ETH_UDP_FRAME;
-			desc->l4i_chk = udp_hdr(skb)->check;
+			desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
 			break;
 		case IPPROTO_TCP:
-			desc->l4i_chk = tcp_hdr(skb)->check;
+			desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
 			break;
 		default:
 			BUG();
-- 
1.5.4.rc2.38.gd6da3



^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2008-01-20 15:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-19 19:27 [PATCH] mv643xx: fix byte order when checksum offload is enabled Byron Bradley
2008-01-19 20:09 ` Al Viro
2008-01-20 15:05   ` [PATCH] mv643xx_eth: " Byron Bradley
2008-01-19 20:23 ` Dale Farnsworth
2008-01-19 20:45   ` Dale Farnsworth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).