Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH] [RFC] 3c509: convert to isa_driver and pnp_driver v2
From: Jeff Garzik @ 2008-02-02 20:50 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: netdev, Linux Kernel, Andrew Morton
In-Reply-To: <200802021925.36552.linux@rainbow-software.org>

Ondrej Zary wrote:
> Hello,
> this is second version of the patch. Autoloading using udev works fine with 
> PnP card. Hibernation now works both in PnP and ISA modes. The I/O address 
> used for non-pnp ISA card detection is now not released as it's needed to 
> wake up the card.
> 
> Manual irq and transceiver settings aren't implemented yet. Operation with 
> multiple cards is not tested - I'll try 3 cards in both PnP and ISA modes. 
> There is some code that is the same in each of the 4 probe functions (isa, 
> pnp, eisa and mca), which should be probably separated into a function.
> 
> I have no EISA or MCA machine so I hope that I didn't break them.

Looks pretty good at first glance...

I'll throw it in my queue.  Want to add a signed-off-by:  ?

	Jeff




^ permalink raw reply

* Re: [PATCH] [RFC] 3c509: convert to isa_driver and pnp_driver v2
From: Pekka Enberg @ 2008-02-02 21:07 UTC (permalink / raw)
  To: Ondrej Zary; +Cc: netdev, Linux Kernel, Jeff Garzik
In-Reply-To: <200802021925.36552.linux@rainbow-software.org>

Hi,

On Feb 2, 2008 8:25 PM, Ondrej Zary <linux@rainbow-software.org> wrote:
> +//static __be16 el3_phys_addr[EL3_MAX_CARDS][3];

[snip]

> +//#if defined(CONFIG_MCA) || defined(CONFIG_EISA)

[snip]

> +//     while (el3_probe(el3_cards) == 0) {
> +//             if (irq[el3_cards] > 1)
> +//                     el3_root_dev->irq = irq[el3_cards];
> +//             if (xcvr[el3_cards] >= 0)
> +//                     el3_root_dev->if_port = xcvr[el3_cards];
> +//             el3_cards++;
> +//     }

You might want to consider dropping these hunks...

^ permalink raw reply

* Re: [PATCH] [RFC] 3c509: convert to isa_driver and pnp_driver v2
From: Ondrej Zary @ 2008-02-02 21:08 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, Linux Kernel, Andrew Morton
In-Reply-To: <47A4D791.3050700@garzik.org>

On Saturday 02 February 2008 21:50:25 Jeff Garzik wrote:
> Ondrej Zary wrote:
> > Hello,
> > this is second version of the patch. Autoloading using udev works fine
> > with PnP card. Hibernation now works both in PnP and ISA modes. The I/O
> > address used for non-pnp ISA card detection is now not released as it's
> > needed to wake up the card.
> >
> > Manual irq and transceiver settings aren't implemented yet. Operation
> > with multiple cards is not tested - I'll try 3 cards in both PnP and ISA
> > modes. There is some code that is the same in each of the 4 probe
> > functions (isa, pnp, eisa and mca), which should be probably separated
> > into a function.
> >
> > I have no EISA or MCA machine so I hope that I didn't break them.
>
> Looks pretty good at first glance...
>
> I'll throw it in my queue.  Want to add a signed-off-by:  ?
>
> 	Jeff

I think that the ISA resume will not work with more than 1 card. I'll fix that 
first and test with 3 cards. So the next version can include signed-off-by.

I also wonder about the old el3_cleanup_module() function - it called 
el3_common_remove for all cards. With isa_driver and pnp_driver, it oopsed - 
I think that's because the remove() functions were called by driver core on 
isa_unregister_driver (and pnp_unregister_driver) - but what about MCA and 
EISA?

-- 
Ondrej Zary

^ permalink raw reply

* [2.6 patch] net/phy/fixed.c: fix a use-after-free
From: Adrian Bunk @ 2008-02-02 21:15 UTC (permalink / raw)
  To: Anton Vorontsov, Vitaly Bordug, Jeff Garzik; +Cc: netdev

This patch fixes a use-after-free introduced by
commit a79d8e93d300adb84cccc38ac396cfb118c238ad and spotted by the 
Coverity checker.

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---
20c51455b2faed63c3026fd4d7139e5a6a917d31 
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 73b6d39..ca9b040 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -236,12 +236,12 @@ module_init(fixed_mdio_bus_init);
 static void __exit fixed_mdio_bus_exit(void)
 {
 	struct fixed_mdio_bus *fmb = &platform_fmb;
-	struct fixed_phy *fp;
+	struct fixed_phy *fp, *tmp;
 
 	mdiobus_unregister(&fmb->mii_bus);
 	platform_device_unregister(pdev);
 
-	list_for_each_entry(fp, &fmb->phys, node) {
+	list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
 		list_del(&fp->node);
 		kfree(fp);
 	}


^ permalink raw reply related

* inet6_hash_connect() no longer uses secure_ipv6_port_ephemeral()
From: Adrian Bunk @ 2008-02-02 21:14 UTC (permalink / raw)
  To: Pavel Emelyanov, David S. Miller; +Cc: netdev

I do not claim to understand this code, but it doesn't seem to be 
intentional that after commit 5ee31fc1ecdcbc234c8c56dcacef87c8e09909d8 
inet6_hash_connect() now uses secure_ipv4_port_ephemeral() instead of 
secure_ipv6_port_ephemeral() (inet6_sk_port_offset() is no longer 
used and __inet_hash_connect() uses secure_ipv4_port_ephemeral()
through inet_sk_port_offset())?

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply

* [2.6 patch] xfrm4_beet_input(): fix an if()
From: Adrian Bunk @ 2008-02-02 21:16 UTC (permalink / raw)
  To: Herbert Xu, David S. Miller; +Cc: netdev

A bug every C programmer makes at some point in time...

Signed-off-by: Adrian Bunk <bunk@kernel.org>

---
3125760a05c6e97097882a810dc1c5342296aae9 
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index e093a7b..b47030b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -102,7 +102,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 
 		XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
 
-		if (!pskb_may_pull(skb, phlen));
+		if (!pskb_may_pull(skb, phlen))
 			goto out;
 		__skb_pull(skb, phlen);
 	}


^ permalink raw reply related

* Re: [PATCH] [RFC] 3c509: convert to isa_driver and pnp_driver v2
From: Ondrej Zary @ 2008-02-02 21:28 UTC (permalink / raw)
  To: Pekka Enberg; +Cc: netdev, Linux Kernel, Jeff Garzik
In-Reply-To: <84144f020802021307ja672fdfl29e54483e9f900d@mail.gmail.com>

On Saturday 02 February 2008 22:07:20 Pekka Enberg wrote:
> Hi,
>
> On Feb 2, 2008 8:25 PM, Ondrej Zary <linux@rainbow-software.org> wrote:
> > +//static __be16 el3_phys_addr[EL3_MAX_CARDS][3];
>
> [snip]
>
> > +//#if defined(CONFIG_MCA) || defined(CONFIG_EISA)
>
> [snip]
>
> > +//     while (el3_probe(el3_cards) == 0) {
> > +//             if (irq[el3_cards] > 1)
> > +//                     el3_root_dev->irq = irq[el3_cards];
> > +//             if (xcvr[el3_cards] >= 0)
> > +//                     el3_root_dev->if_port = xcvr[el3_cards];
> > +//             el3_cards++;
> > +//     }
>
> You might want to consider dropping these hunks...

Yes, they're going away. The last one is there just as a reminder that the irq 
and xcvr parameters should be used in the ISA code.

-- 
Ondrej Zary

^ permalink raw reply

* [PATCH] [XFRM] BEET: Remove extra semicolon after if
From: Ilpo Järvinen @ 2008-02-02 21:53 UTC (permalink / raw)
  To: David Miller, Herbert Xu; +Cc: Netdev

[-- Attachment #1: Type: TEXT/PLAIN, Size: 638 bytes --]


Once again, one of this kind tries to creep in.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/ipv4/xfrm4_mode_beet.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index e093a7b..b47030b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -102,7 +102,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
 
 		XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
 
-		if (!pskb_may_pull(skb, phlen));
+		if (!pskb_may_pull(skb, phlen))
 			goto out;
 		__skb_pull(skb, phlen);
 	}
-- 
1.5.2.2

^ permalink raw reply related

* Re: kernel panic on 2.6.24 with esfq patch applied
From: Jarek Poplawski @ 2008-02-02 22:19 UTC (permalink / raw)
  To: Corey Hickey; +Cc: Denys Fedoryshchenko, netdev
In-Reply-To: <47A444A8.8020304@fatooh.org>

Corey Hickey wrote, On 02/02/2008 11:23 AM:
 ...

> I'd rather you were using my recent patches to SFQ instead of ESFQ. I
> was able to crash a 2.6.24 user-mode Linux with ESFQ as well; I don't
> know if that's what you encountered, but the SFQ patches should be
> better anyway.
> 
> http://fatooh.org/esfq-2.6/sfq-2.6.24.tar.bz2
> http://fatooh.org/esfq-2.6/

Hi Corey!

I've just had a look at your site, and see you're a bit disappointed about
the reception of your patches here. I don't use nor know about your work
(maybe some time...), and wish you better public here, but maybe you'll
find this story interesting: a few years ago, when I didn't even think of
reading netdev, I quite often visited pages of such projects as HTB (not
in every distro yet), IMQ or Julian Anastasov's. They were quite popular
subjects on admins lists, and I really admired people around these
projects, while the main kernel was something big and anonymous (no idea
e.g. about D. Miller). For the same reason I knew more about people from
iptables project - only because there was a need to visit this for some
non standard modules, and about A. Kuznetsov - only because of patching
iproute for HTB!!! (Only later I found that Alexey did more than needed
for several such HTBs.) So, it seems there could be good side of such
unofficial status too - if you only have something really useful for
others...

Cheers,
Jarek P.

^ permalink raw reply

* Re: [2.6 patch] xfrm4_beet_input(): fix an if()
From: Herbert Xu @ 2008-02-02 22:22 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: David S. Miller, netdev
In-Reply-To: <20080202211635.GF9375@cs181133002.pp.htv.fi>

On Sat, Feb 02, 2008 at 11:16:35PM +0200, Adrian Bunk wrote:
> A bug every C programmer makes at some point in time...
> 
> Signed-off-by: Adrian Bunk <bunk@kernel.org>

Good catch!

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] [XFRM] BEET: Remove extra semicolon after if
From: Herbert Xu @ 2008-02-02 22:22 UTC (permalink / raw)
  To: Ilpo Järvinen; +Cc: David Miller, Netdev
In-Reply-To: <Pine.LNX.4.64.0802022351510.2526@kivilampi-30.cs.helsinki.fi>

On Sat, Feb 02, 2008 at 11:53:29PM +0200, Ilpo Järvinen wrote:
> 
> Once again, one of this kind tries to creep in.
> 
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>

Heh, Adrian got there first :)

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: kernel panic on 2.6.24 with esfq patch applied
From: Corey Hickey @ 2008-02-02 22:53 UTC (permalink / raw)
  To: Jarek Poplawski, Linux Netdev List
In-Reply-To: <47A4EC88.1010602@gmail.com>

Jarek Poplawski wrote:
> Hi Corey!
> 
> I've just had a look at your site, and see you're a bit disappointed about
> the reception of your patches here. I don't use nor know about your work
> (maybe some time...), and wish you better public here, but maybe you'll
> find this story interesting: a few years ago, when I didn't even think of
> reading netdev, I quite often visited pages of such projects as HTB (not
> in every distro yet), IMQ or Julian Anastasov's. They were quite popular
> subjects on admins lists, and I really admired people around these
> projects, while the main kernel was something big and anonymous (no idea
> e.g. about D. Miller). For the same reason I knew more about people from
> iptables project - only because there was a need to visit this for some
> non standard modules, and about A. Kuznetsov - only because of patching
> iproute for HTB!!! (Only later I found that Alexey did more than needed
> for several such HTBs.) So, it seems there could be good side of such
> unofficial status too - if you only have something really useful for
> others...

Thank you for the words of encouragement, but don't worry: I'm not going
to run away and hide just yet. :)  I was a bit discouraged about not
getting reviews for the more recent patch submissions, though, and I
hope I don't come across as bitter about that. Patch review is a lot of
work, and I definitely appreciate the comments I received earlier--I was
able to make many improvements as a result.

In any case, kernel development progresses, and I now have to update my
patches so they can apply to current git. The ball has rolled back into
my court of its own accord; perhaps the playing field isn't level. ;)

-Corey

^ permalink raw reply

* Re: [PATCH] Disable TSO for non standard qdiscs
From: Herbert Xu @ 2008-02-02 22:57 UTC (permalink / raw)
  To: Andi Kleen; +Cc: shemminger, andi, kaber, netdev
In-Reply-To: <20080131185328.GD4671@one.firstfloor.org>

Andi Kleen <andi@firstfloor.org> wrote:
>> Then change TBF to use skb_gso_segment?  Be careful, the fact that
> 
> That doesn't help because it wants to interleave packets
> from different streams to get everything fair and smooth. The only 
> good way to handle that is to split it up and the simplest way to do 
> this is to just tell TCP to not do GSO in the first place.

Actually if we're going to do this I'd prefer you to call skb_gso_segment
instead because that lets us at least bypass netfilter which is one of
the key benefits of software GSO.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [PATCH] Disable TSO for non standard qdiscs
From: Herbert Xu @ 2008-02-02 22:59 UTC (permalink / raw)
  To: Andi Kleen; +Cc: rick.jones2, andi, netdev, davem
In-Reply-To: <20080201043113.GA10720@one.firstfloor.org>

Andi Kleen <andi@firstfloor.org> wrote:
> 
> Hmm, that would probably be possible for TBF, but I'm not sure this can be
> really done in a useful way for the more complicated qdiscs. Especially
> since they would likely need to turn on/off GSO regularly when dynamic
> circumstances change and there is not really a good way to affect a socket 
> after it was created.

You don't need to change the socket if you just call skb_gso_segment
when necessary.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Re: [NET_SCHED 00/04]: External SFQ classifiers/flow classifier
From: Corey Hickey @ 2008-02-02 23:23 UTC (permalink / raw)
  To: Patrick McHardy, Linux Netdev List
In-Reply-To: <20080131175758.25151.20370.sendpatchset@localhost.localdomain>

Patrick McHardy wrote:
> These patches add support for external classifiers to SFQ and add a
> new "flow" classifier, which can do hashing based on user-specified
> keys or deterministic mapping of keys to classes. Additionally there
> is a patch to make the SFQ queues visisble as classes to verify that
> the hash is indeed doing something useful and a patch to consifiy
> struct tcf_ext_map, which I had queued in the same tree.

Excellent! I'm glad this is applied. I'm having trouble figuring out how
it works, though. As a test, I'm trying to set up SFQ equivalent to
ESFQ's "hash dst". Here's what I do, and this is what I get:

------------------------------------------------------------------------
# ./tc qdisc add dev eth0 root handle 1: sfq
# ./tc filter add dev eth0 parent 1: flow hash keys dst
RTNETLINK answers: Invalid argument
We have an error talking to the kernel
------------------------------------------------------------------------

I've tried a few different keys with the same results. I don't know what
I'm doing wrong, or even where to start figuring it out. Can you point
me in the right direction?

Here are some details that may be pertinent:

- current net-2.6 git (I double-checked)
- CONFIG_NET_CLS_FLOW=y
- current iproute2 git
- running on amd64 user-mode Linux


Thanks,
Corey

^ permalink raw reply

* Re: xfrm_input() and ->seq oddities
From: Herbert Xu @ 2008-02-03  0:20 UTC (permalink / raw)
  To: Al Viro; +Cc: David Miller, netdev
In-Reply-To: <20080202235827.GP27894@ZenIV.linux.org.uk>

On Sat, Feb 02, 2008 at 11:58:27PM +0000, Al Viro wrote:
> 	What's going on with XFRM_SKB_CB(skb)->seq?  Almost all users
> expect it to be u32 (feeding it to htonl()), except xfrm_input().
> That one expects __be32 in there - check what it does to seq and
> you'll see.  Moreover, it updates the sucker in a way that makes
> sense only for __be32.

My bad.

> 	a) are we just missing ntohl() and htonl() in obvious places
> in xfrm_input()?

It's semantically correct.  However, my mistake that I'm mixing the
input sequence number which is network endian with the output sequence
number which is host endian (and 64-bit).

> 	b) WTF is it declared as 64bit, anyway?

For extended sequence numbers which we'll support soon (I hope).

[IPSEC]: Fix bogus usage of u64 on input sequence number

Al Viro spotted a bogus use of u64 on the input sequence number which
is big-endian.  This patch fixes it by giving the input sequence number
its own member in the xfrm_skb_cb structure.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index ac72116..eea7785 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -508,7 +508,10 @@ struct xfrm_skb_cb {
         } header;
 
         /* Sequence number for replay protection. */
-        u64 seq;
+	union {
+		u64 output;
+		__be32 input;
+	} seq;
 };
 
 #define XFRM_SKB_CB(__skb) ((struct xfrm_skb_cb *)&((__skb)->cb[0]))
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 9d4555e..8219b7e 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -96,7 +96,7 @@ static int ah_output(struct xfrm_state *x, struct sk_buff *skb)
 
 	ah->reserved = 0;
 	ah->spi = x->id.spi;
-	ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+	ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
 
 	spin_lock_bh(&x->lock);
 	err = ah_mac_digest(ahp, skb, ah->auth_data);
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 258d176..091e670 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -199,7 +199,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 	}
 
 	esph->spi = x->id.spi;
-	esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+	esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
 
 	sg_init_table(sg, nfrags);
 	skb_to_sgvec(skb, sg,
@@ -210,7 +210,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
 	aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
 	aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
 	aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
-	aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+	aead_givcrypt_set_giv(req, esph->enc_data,
+			      XFRM_SKB_CB(skb)->seq.output);
 
 	ESP_SKB_CB(skb)->tmp = tmp;
 	err = crypto_aead_givencrypt(req);
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index 379c8e0..2ff0c82 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -283,7 +283,7 @@ static int ah6_output(struct xfrm_state *x, struct sk_buff *skb)
 
 	ah->reserved = 0;
 	ah->spi = x->id.spi;
-	ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+	ah->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
 
 	spin_lock_bh(&x->lock);
 	err = ah_mac_digest(ahp, skb, ah->auth_data);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 8e0f142..0ec1402 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -188,7 +188,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 	*skb_mac_header(skb) = IPPROTO_ESP;
 
 	esph->spi = x->id.spi;
-	esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq);
+	esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output);
 
 	sg_init_table(sg, nfrags);
 	skb_to_sgvec(skb, sg,
@@ -199,7 +199,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
 	aead_givcrypt_set_callback(req, 0, esp_output_done, skb);
 	aead_givcrypt_set_crypt(req, sg, sg, clen, iv);
 	aead_givcrypt_set_assoc(req, asg, sizeof(*esph));
-	aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq);
+	aead_givcrypt_set_giv(req, esph->enc_data,
+			      XFRM_SKB_CB(skb)->seq.output);
 
 	ESP_SKB_CB(skb)->tmp = tmp;
 	err = crypto_aead_givencrypt(req);
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 4d6ebc6..62188c6 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -109,7 +109,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 	if (encap_type < 0) {
 		async = 1;
 		x = xfrm_input_state(skb);
-		seq = XFRM_SKB_CB(skb)->seq;
+		seq = XFRM_SKB_CB(skb)->seq.input;
 		goto resume;
 	}
 
@@ -175,7 +175,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 
 		spin_unlock(&x->lock);
 
-		XFRM_SKB_CB(skb)->seq = seq;
+		XFRM_SKB_CB(skb)->seq.input = seq;
 
 		nexthdr = x->type->input(x, skb);
 
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index fc69036..569d377 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -62,7 +62,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 		}
 
 		if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
-			XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
+			XFRM_SKB_CB(skb)->seq.output = ++x->replay.oseq;
 			if (unlikely(x->replay.oseq == 0)) {
 				XFRM_INC_STATS(LINUX_MIB_XFRMOUTSTATESEQERROR);
 				x->replay.oseq--;

^ permalink raw reply related

* Re: xfrm_input() and ->seq oddities
From: Al Viro @ 2008-02-03  0:37 UTC (permalink / raw)
  To: Herbert Xu; +Cc: David Miller, netdev
In-Reply-To: <20080203002019.GA32295@gondor.apana.org.au>

On Sun, Feb 03, 2008 at 11:20:19AM +1100, Herbert Xu wrote:
> Al Viro spotted a bogus use of u64 on the input sequence number which
> is big-endian.  This patch fixes it by giving the input sequence number
> its own member in the xfrm_skb_cb structure.

This is still very odd...  Where do you initialize ->seq.input?  What
guarantees that async call of xfrm_input() will be always preceded by
at least one non-async one?

^ permalink raw reply

* Re: [PATCH] Unbreak sky2 on 88E8039 with current git
From: Petr Vandrovec @ 2008-02-03  0:57 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev, linux-kernel
In-Reply-To: <20080202120203.5387d1cb@extreme>

Stephen Hemminger wrote:
> On Sat, 2 Feb 2008 11:52:43 +0100
> Petr Vandrovec <petr@vandrovec.name> wrote:
> 
>> Hello,
>>   since I synced my tree to Linus's one two days ago, sky2's packet receiption
>> dies almost instantly.  Device still transmits packets, but no receive.  
>> Fortunately fix is simple, unfortunately I do not know why fix works...
>>
>> Commit f03b865491c2f30f2a4d77cdafc69c978ceb38a0 (sky2: align IP header on Rx
>> if possible) stopped aligning receive buffers on devices which do not need
>> HANG_CHECK.  Unfortunately there is at least one device (mine, Yukon FE, rev 3)
>> which is not happy if receive buffer is not aligned.  I have no idea which
>> other chips/revisions are affected as well.
>>
>> Without patch 'ping -f -b 192.168.101.255' RX count stops incrementing in less
>> than 50 packets.  With patch in place it can run like before, for hours...
>> Box is an AMD rev F processor, with nVidia's MCP61 chipset.
>> 							Petr
> 
> I don't have a Yukon FE, but I believe that the Yukon FE does have a ram
> buffer, so you HANG_CHECK should be enabled for that device. You can check
> by running:
> 	ethtool -d eth0 | grep 'Ram Buffer'
> With ram buffer (like XL, EC)
> 	
> # ethtool -d eth0 | grep 'Ram Buffer'
> Ram Buffer                   0x18
> 
> No ram buffer (like EC-U, FE+, ...)
> # ethtool -d eth0 | grep 'Ram Buffer'
> Ram Buffer                   0x00

Some small one (if it is size):

gwy:~# ethtool -d eth0 | grep 'Ram'
Ram Buffer                   0x01

I've never observed hang on that device, and I have it for over year. I 
stress it sufficiently to kill EC rev 2 I have in the notebook when I 
copy some data between these two boxes, but this FE never hung.
							Petr


^ permalink raw reply

* latest git compile error in net/sched/cls_flow.c
From: Li Zefan @ 2008-02-03  1:44 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: David Miller, LKML, netdev


I made a randconfig, and got the following error:

net/sched/cls_flow.c: In function 'flow_dump':
net/sched/cls_flow.c:598: error: 'struct tcf_ematch_tree' has no member named 'hdr'
make[2]: *** [net/sched/cls_flow.o] Error 1
make[1]: *** [net/sched] Error 2
make: *** [net] Error 2

seems it's caused by the following config options:
CONFIG_NET_EMATCH=n
CONFIG_NET_CLS_FLOW=y


^ permalink raw reply

* [PATCH 03/10] atl1: fix broken TSO
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn
In-Reply-To: <1202003412-4028-1-git-send-email-jacliburn@bellsouth.net>

The L1 tx packet descriptor expects TCP Header Length to be expressed as a
number of 32-bit dwords.  The atl1 driver uses tcp_hdrlen() to populate the
field, but tcp_hdrlen() returns the header length in bytes, not in dwords.
Add a shift to convert tcp_hdrlen() to dwords when we write it to the tpd.

Also, some of our bit assignments are made to the wrong tpd words.  Change
those to the correct words.

Finally, since all this fixes TSO, enable TSO by default.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
---
 drivers/net/atlx/atl1.c |   29 +++++++++++------------------
 1 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index a84c97c..8a26dad 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -36,7 +36,6 @@
  * A very incomplete list of things that need to be dealt with:
  *
  * TODO:
- * Fix TSO; tx performance is horrible with TSO enabled.
  * Wake on LAN.
  * Add more ethtool functions.
  * Fix abstruse irq enable/disable condition described here:
@@ -1308,8 +1307,8 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
 				tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
 
 			tso->tsopl |= (iph->ihl &
-				CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT;
-			tso->tsopl |= (tcp_hdrlen(skb) &
+				TSO_PARAM_IPHL_MASK) << TSO_PARAM_IPHL_SHIFT;
+			tso->tsopl |= ((tcp_hdrlen(skb) >> 2) &
 				TSO_PARAM_TCPHDRLEN_MASK) <<
 				TSO_PARAM_TCPHDRLEN_SHIFT;
 			tso->tsopl |= (skb_shinfo(skb)->gso_size &
@@ -1472,8 +1471,8 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
 		tpd->desc.tso.tsopl = descr->tso.tsopl;
 		tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
 		tpd->desc.data = descr->data;
-		tpd->desc.csum.csumpu |= (cpu_to_le16(buffer_info->length) &
-			CSUM_PARAM_BUFLEN_MASK) << CSUM_PARAM_BUFLEN_SHIFT;
+		tpd->desc.tso.tsopu |= (cpu_to_le16(buffer_info->length) &
+			TSO_PARAM_BUFLEN_MASK) << TSO_PARAM_BUFLEN_SHIFT;
 
 		val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
 			TSO_PARAM_SEGMENT_MASK;
@@ -1481,7 +1480,7 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
 			tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT;
 
 		if (j == (count - 1))
-			tpd->desc.csum.csumpl |= 1 << CSUM_PARAM_EOP_SHIFT;
+			tpd->desc.tso.tsopl |= 1 << TSO_PARAM_EOP_SHIFT;
 
 		if (++tpd_next_to_use == tpd_ring->count)
 			tpd_next_to_use = 0;
@@ -1574,9 +1573,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		vlan_tag = vlan_tx_tag_get(skb);
 		vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
 			((vlan_tag >> 9) & 0x8);
-		param.csum.csumpl |= 1 << CSUM_PARAM_INSVLAG_SHIFT;
-		param.csum.csumpu |= (vlan_tag & CSUM_PARAM_VALANTAG_MASK) <<
-			CSUM_PARAM_VALAN_SHIFT;
+		param.tso.tsopl |= 1 << TSO_PARAM_INSVLAG_SHIFT;
+		param.tso.tsopu |= (vlan_tag & TSO_PARAM_VLANTAG_MASK) <<
+			TSO_PARAM_VLAN_SHIFT;
 	}
 
 	tso = atl1_tso(adapter, skb, &param.tso);
@@ -1595,8 +1594,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		}
 	}
 
-	val = (param.csum.csumpl >> CSUM_PARAM_SEGMENT_SHIFT) &
-		CSUM_PARAM_SEGMENT_MASK;
+	val = (param.tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
+		TSO_PARAM_SEGMENT_MASK;
 	atl1_tx_map(adapter, skb, 1 == val);
 	atl1_tx_queue(adapter, count, &param);
 	netdev->trans_start = jiffies;
@@ -2091,13 +2090,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	netdev->features = NETIF_F_HW_CSUM;
 	netdev->features |= NETIF_F_SG;
 	netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-
-	/*
-	 * FIXME - Until tso performance gets fixed, disable the feature.
-	 * Enable it with ethtool -K if desired.
-	 */
-	/* netdev->features |= NETIF_F_TSO; */
-
+	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_LLTX;
 
 	/*
-- 
1.5.3.8


^ permalink raw reply related

* [PATCH 04/10] atl1: add ethtool register dump
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn
In-Reply-To: <1202003412-4028-1-git-send-email-jacliburn@bellsouth.net>

Add the ethtool register dump option to the atl1 driver.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
---
 drivers/net/atlx/atl1.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/atlx/atl1.h |    1 +
 2 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 8a26dad..1f564f0 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2513,6 +2513,57 @@ static int atl1_set_wol(struct net_device *netdev,
 	return 0;
 }
 
+static int atl1_get_regs_len(struct net_device *netdev)
+{
+	return ATL1_REG_COUNT * sizeof(u32);
+}
+
+static void atl1_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
+	void *p)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+	unsigned int i;
+	u32 *regbuf = p;
+
+	for (i = 0; i < ATL1_REG_COUNT; i++) {
+		/*
+		 * This switch statement avoids reserved regions
+		 * of register space.
+		 */
+		switch (i) {
+		case 6 ... 9:
+		case 14:
+		case 29 ... 31:
+		case 34 ... 63:
+		case 75 ... 127:
+		case 136 ... 1023:
+		case 1027 ... 1087:
+		case 1091 ... 1151:
+		case 1194 ... 1195:
+		case 1200 ... 1201:
+		case 1206 ... 1213:
+		case 1216 ... 1279:
+		case 1290 ... 1311:
+		case 1323 ... 1343:
+		case 1358 ... 1359:
+		case 1368 ... 1375:
+		case 1378 ... 1383:
+		case 1388 ... 1391:
+		case 1393 ... 1395:
+		case 1402 ... 1403:
+		case 1410 ... 1471:
+		case 1522 ... 1535:
+			/* reserved region; don't read it */
+			regbuf[i] = 0;
+			break;
+		default:
+			/* unreserved region */
+			regbuf[i] = ioread32(hw->hw_addr + (i * sizeof(u32)));
+		}
+	}
+}
+
 static void atl1_get_ringparam(struct net_device *netdev,
 	struct ethtool_ringparam *ring)
 {
@@ -2703,6 +2754,8 @@ const struct ethtool_ops atl1_ethtool_ops = {
 	.get_drvinfo		= atl1_get_drvinfo,
 	.get_wol		= atl1_get_wol,
 	.set_wol		= atl1_set_wol,
+	.get_regs_len		= atl1_get_regs_len,
+	.get_regs		= atl1_get_regs,
 	.get_ringparam		= atl1_get_ringparam,
 	.set_ringparam		= atl1_set_ringparam,
 	.get_pauseparam		= atl1_get_pauseparam,
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 538948d..30c5a8d 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -584,6 +584,7 @@ enum atl1_dma_req_block {
 #define ATL1_DEFAULT_RFD	512
 #define ATL1_MIN_RFD		128
 #define ATL1_MAX_RFD		2048
+#define ATL1_REG_COUNT		1538
 
 #define ATL1_GET_DESC(R, i, type)	(&(((type *)((R)->desc))[i]))
 #define ATL1_RFD_DESC(R, i)	ATL1_GET_DESC(R, i, struct rx_free_desc)
-- 
1.5.3.8


^ permalink raw reply related

* [PATCH 01/10] atl1: relocate atl1 driver to /drivers/net/atlx
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn

In preparation for a future Atheros L2 NIC driver (called atl2), relocate
the atl1 driver into a new /drivers/net/atlx directory that will ultimately
be shared with the future atl2 driver.

Signed-off-by: Chris Snook <csnook@redhat.com>
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
 drivers/net/Makefile                      |    2 +-
 drivers/net/{atl1 => atlx}/Makefile       |    0 
 drivers/net/{atl1 => atlx}/atl1.h         |    0 
 drivers/net/{atl1 => atlx}/atl1_ethtool.c |    0 
 drivers/net/{atl1 => atlx}/atl1_hw.c      |    0 
 drivers/net/{atl1 => atlx}/atl1_hw.h      |    0 
 drivers/net/{atl1 => atlx}/atl1_main.c    |    0 
 drivers/net/{atl1 => atlx}/atl1_param.c   |    0 
 8 files changed, 1 insertions(+), 1 deletions(-)
 rename drivers/net/{atl1 => atlx}/Makefile (100%)
 rename drivers/net/{atl1 => atlx}/atl1.h (100%)
 rename drivers/net/{atl1 => atlx}/atl1_ethtool.c (100%)
 rename drivers/net/{atl1 => atlx}/atl1_hw.c (100%)
 rename drivers/net/{atl1 => atlx}/atl1_hw.h (100%)
 rename drivers/net/{atl1 => atlx}/atl1_main.c (100%)
 rename drivers/net/{atl1 => atlx}/atl1_param.c (100%)

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9fc7794..ae11d5e 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -15,7 +15,7 @@ obj-$(CONFIG_CHELSIO_T3) += cxgb3/
 obj-$(CONFIG_EHEA) += ehea/
 obj-$(CONFIG_CAN) += can/
 obj-$(CONFIG_BONDING) += bonding/
-obj-$(CONFIG_ATL1) += atl1/
+obj-$(CONFIG_ATL1) += atlx/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
 obj-$(CONFIG_TEHUTI) += tehuti.o
 
diff --git a/drivers/net/atl1/Makefile b/drivers/net/atlx/Makefile
similarity index 100%
rename from drivers/net/atl1/Makefile
rename to drivers/net/atlx/Makefile
diff --git a/drivers/net/atl1/atl1.h b/drivers/net/atlx/atl1.h
similarity index 100%
rename from drivers/net/atl1/atl1.h
rename to drivers/net/atlx/atl1.h
diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atlx/atl1_ethtool.c
similarity index 100%
rename from drivers/net/atl1/atl1_ethtool.c
rename to drivers/net/atlx/atl1_ethtool.c
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atlx/atl1_hw.c
similarity index 100%
rename from drivers/net/atl1/atl1_hw.c
rename to drivers/net/atlx/atl1_hw.c
diff --git a/drivers/net/atl1/atl1_hw.h b/drivers/net/atlx/atl1_hw.h
similarity index 100%
rename from drivers/net/atl1/atl1_hw.h
rename to drivers/net/atlx/atl1_hw.h
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atlx/atl1_main.c
similarity index 100%
rename from drivers/net/atl1/atl1_main.c
rename to drivers/net/atlx/atl1_main.c
diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atlx/atl1_param.c
similarity index 100%
rename from drivers/net/atl1/atl1_param.c
rename to drivers/net/atlx/atl1_param.c
-- 
1.5.3.8


^ permalink raw reply related

* [PATCH 05/10] atl1: simplify tx packet descriptor
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn
In-Reply-To: <1202003412-4028-1-git-send-email-jacliburn@bellsouth.net>

The transmit packet descriptor consists of four 32-bit words, with word 3
upper bits overloaded depending upon the condition of its bits 3 and 4.
The driver currently duplicates all word 2 and some word 3 register bit
definitions unnecessarily and also uses a set of nested structures in its
definition of the TPD without good cause. This patch adds a lengthy
comment describing the TPD, eliminates duplicate TPD bit definitions,
and simplifies the TPD structure itself. It also expands the TSO check
to correctly handle custom checksum versus TSO processing using the revised
TPD definitions. Finally, shorten some variable names in the transmit
processing path to reduce line lengths, rename some variables to better
describe their purpose (e.g., nseg versus m), and add a comment or two
to better describe what the code is doing.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
---
 drivers/net/atlx/atl1.c |  265 +++++++++++++++++++++++++----------------------
 drivers/net/atlx/atl1.h |  201 +++++++++++++++++++-----------------
 2 files changed, 246 insertions(+), 220 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 1f564f0..f4add3c 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1259,8 +1259,6 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
 			dev_kfree_skb_irq(buffer_info->skb);
 			buffer_info->skb = NULL;
 		}
-		tpd->buffer_addr = 0;
-		tpd->desc.data = 0;
 
 		if (++sw_tpd_next_to_clean == tpd_ring->count)
 			sw_tpd_next_to_clean = 0;
@@ -1282,48 +1280,69 @@ static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
 }
 
 static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
-			 struct tso_param *tso)
+	struct tx_packet_desc *ptpd)
 {
-	/* We enter this function holding a spinlock. */
-	u8 ipofst;
+	/* spinlock held */
+	u8 hdr_len, ip_off;
+	u32 real_len;
 	int err;
 
 	if (skb_shinfo(skb)->gso_size) {
 		if (skb_header_cloned(skb)) {
 			err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
 			if (unlikely(err))
-				return err;
+				return -1;
 		}
 
 		if (skb->protocol == ntohs(ETH_P_IP)) {
 			struct iphdr *iph = ip_hdr(skb);
 
-			iph->tot_len = 0;
+			real_len = (((unsigned char *)iph - skb->data) +
+				ntohs(iph->tot_len));
+			if (real_len < skb->len)
+				pskb_trim(skb, real_len);
+			hdr_len = (skb_transport_offset(skb) + tcp_hdrlen(skb));
+			if (skb->len == hdr_len) {
+				iph->check = 0;
+				tcp_hdr(skb)->check =
+					~csum_tcpudp_magic(iph->saddr,
+					iph->daddr, tcp_hdrlen(skb),
+					IPPROTO_TCP, 0);
+				ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+					TPD_IPHL_SHIFT;
+				ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+					TPD_TCPHDRLEN_MASK) <<
+					TPD_TCPHDRLEN_SHIFT;
+				ptpd->word3 |= 1 << TPD_IP_CSUM_SHIFT;
+				ptpd->word3 |= 1 << TPD_TCP_CSUM_SHIFT;
+				return 1;
+			}
+
 			iph->check = 0;
 			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-				iph->daddr, 0, IPPROTO_TCP, 0);
-			ipofst = skb_network_offset(skb);
-			if (ipofst != ETH_HLEN) /* 802.3 frame */
-				tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
-
-			tso->tsopl |= (iph->ihl &
-				TSO_PARAM_IPHL_MASK) << TSO_PARAM_IPHL_SHIFT;
-			tso->tsopl |= ((tcp_hdrlen(skb) >> 2) &
-				TSO_PARAM_TCPHDRLEN_MASK) <<
-				TSO_PARAM_TCPHDRLEN_SHIFT;
-			tso->tsopl |= (skb_shinfo(skb)->gso_size &
-				TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT;
-			tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT;
-			tso->tsopl |= 1 << TSO_PARAM_TCPCKSUM_SHIFT;
-			tso->tsopl |= 1 << TSO_PARAM_SEGMENT_SHIFT;
-			return true;
+					iph->daddr, 0, IPPROTO_TCP, 0);
+			ip_off = (unsigned char *)iph -
+				(unsigned char *) skb_network_header(skb);
+			if (ip_off == 8) /* 802.3-SNAP frame */
+				ptpd->word3 |= 1 << TPD_ETHTYPE_SHIFT;
+			else if (ip_off != 0)
+				return -2;
+
+			ptpd->word3 |= (iph->ihl & TPD_IPHL_MASK) <<
+				TPD_IPHL_SHIFT;
+			ptpd->word3 |= ((tcp_hdrlen(skb) >> 2) &
+				TPD_TCPHDRLEN_MASK) << TPD_TCPHDRLEN_SHIFT;
+			ptpd->word3 |= (skb_shinfo(skb)->gso_size &
+				TPD_MSS_MASK) << TPD_MSS_SHIFT;
+			ptpd->word3 |= 1 << TPD_SEGMENT_EN_SHIFT;
+			return 3;
 		}
 	}
 	return false;
 }
 
 static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
-	struct csum_param *csum)
+	struct tx_packet_desc *ptpd)
 {
 	u8 css, cso;
 
@@ -1335,115 +1354,116 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
 				"payload offset not an even number\n");
 			return -1;
 		}
-		csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) <<
-			CSUM_PARAM_PLOADOFFSET_SHIFT;
-		csum->csumpl |= (css & CSUM_PARAM_XSUMOFFSET_MASK) <<
-			CSUM_PARAM_XSUMOFFSET_SHIFT;
-		csum->csumpl |= 1 << CSUM_PARAM_CUSTOMCKSUM_SHIFT;
+		ptpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
+			TPD_PLOADOFFSET_SHIFT;
+		ptpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
+			TPD_CCSUMOFFSET_SHIFT;
+		ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
 		return true;
 	}
-
-	return true;
+	return 0;
 }
 
 static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
-	bool tcp_seg)
+	struct tx_packet_desc *ptpd)
 {
-	/* We enter this function holding a spinlock. */
+	/* spinlock held */
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 	struct atl1_buffer *buffer_info;
+	u16 buf_len = skb->len;
 	struct page *page;
-	int first_buf_len = skb->len;
 	unsigned long offset;
 	unsigned int nr_frags;
 	unsigned int f;
-	u16 tpd_next_to_use;
-	u16 proto_hdr_len;
-	u16 len12;
+	int retval;
+	u16 next_to_use;
+	u16 data_len;
+	u8 hdr_len;
 
-	first_buf_len -= skb->data_len;
+	buf_len -= skb->data_len;
 	nr_frags = skb_shinfo(skb)->nr_frags;
-	tpd_next_to_use = atomic_read(&tpd_ring->next_to_use);
-	buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
+	next_to_use = atomic_read(&tpd_ring->next_to_use);
+	buffer_info = &tpd_ring->buffer_info[next_to_use];
 	if (unlikely(buffer_info->skb))
 		BUG();
 	/* put skb in last TPD */
 	buffer_info->skb = NULL;
 
-	if (tcp_seg) {
-		/* TSO/GSO */
-		proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-		buffer_info->length = proto_hdr_len;
+	retval = (ptpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK;
+	if (retval) {
+		/* TSO */
+		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+		buffer_info->length = hdr_len;
 		page = virt_to_page(skb->data);
 		offset = (unsigned long)skb->data & ~PAGE_MASK;
 		buffer_info->dma = pci_map_page(adapter->pdev, page,
-						offset, proto_hdr_len,
+						offset, hdr_len,
 						PCI_DMA_TODEVICE);
 
-		if (++tpd_next_to_use == tpd_ring->count)
-			tpd_next_to_use = 0;
+		if (++next_to_use == tpd_ring->count)
+			next_to_use = 0;
 
-		if (first_buf_len > proto_hdr_len) {
-			int i, m;
+		if (buf_len > hdr_len) {
+			int i, nseg;
 
-			len12 = first_buf_len - proto_hdr_len;
-			m = (len12 + ATL1_MAX_TX_BUF_LEN - 1) /
+			data_len = buf_len - hdr_len;
+			nseg = (data_len + ATL1_MAX_TX_BUF_LEN - 1) /
 				ATL1_MAX_TX_BUF_LEN;
-			for (i = 0; i < m; i++) {
+			for (i = 0; i < nseg; i++) {
 				buffer_info =
-				    &tpd_ring->buffer_info[tpd_next_to_use];
+				    &tpd_ring->buffer_info[next_to_use];
 				buffer_info->skb = NULL;
 				buffer_info->length =
 				    (ATL1_MAX_TX_BUF_LEN >=
-				     len12) ? ATL1_MAX_TX_BUF_LEN : len12;
-				len12 -= buffer_info->length;
+				     data_len) ? ATL1_MAX_TX_BUF_LEN : data_len;
+				data_len -= buffer_info->length;
 				page = virt_to_page(skb->data +
-					(proto_hdr_len +
-					i * ATL1_MAX_TX_BUF_LEN));
+					(hdr_len + i * ATL1_MAX_TX_BUF_LEN));
 				offset = (unsigned long)(skb->data +
-					(proto_hdr_len +
-					i * ATL1_MAX_TX_BUF_LEN)) & ~PAGE_MASK;
+					(hdr_len + i * ATL1_MAX_TX_BUF_LEN)) &
+					~PAGE_MASK;
 				buffer_info->dma = pci_map_page(adapter->pdev,
 					page, offset, buffer_info->length,
 					PCI_DMA_TODEVICE);
-				if (++tpd_next_to_use == tpd_ring->count)
-					tpd_next_to_use = 0;
+				if (++next_to_use == tpd_ring->count)
+					next_to_use = 0;
 			}
 		}
 	} else {
-		/* not TSO/GSO */
-		buffer_info->length = first_buf_len;
+		/* not TSO */
+		buffer_info->length = buf_len;
 		page = virt_to_page(skb->data);
 		offset = (unsigned long)skb->data & ~PAGE_MASK;
 		buffer_info->dma = pci_map_page(adapter->pdev, page,
-			offset, first_buf_len, PCI_DMA_TODEVICE);
-		if (++tpd_next_to_use == tpd_ring->count)
-			tpd_next_to_use = 0;
+			offset, buf_len, PCI_DMA_TODEVICE);
+		if (++next_to_use == tpd_ring->count)
+			next_to_use = 0;
 	}
 
 	for (f = 0; f < nr_frags; f++) {
 		struct skb_frag_struct *frag;
-		u16 lenf, i, m;
+		u16 i, nseg;
 
 		frag = &skb_shinfo(skb)->frags[f];
-		lenf = frag->size;
+		buf_len = frag->size;
 
-		m = (lenf + ATL1_MAX_TX_BUF_LEN - 1) / ATL1_MAX_TX_BUF_LEN;
-		for (i = 0; i < m; i++) {
-			buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
+		nseg = (buf_len + ATL1_MAX_TX_BUF_LEN - 1) /
+			ATL1_MAX_TX_BUF_LEN;
+		for (i = 0; i < nseg; i++) {
+			buffer_info = &tpd_ring->buffer_info[next_to_use];
 			if (unlikely(buffer_info->skb))
 				BUG();
 			buffer_info->skb = NULL;
-			buffer_info->length = (lenf > ATL1_MAX_TX_BUF_LEN) ?
-				ATL1_MAX_TX_BUF_LEN : lenf;
-			lenf -= buffer_info->length;
+			buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
+				ATL1_MAX_TX_BUF_LEN : buf_len;
+			buf_len -= buffer_info->length;
 			buffer_info->dma = pci_map_page(adapter->pdev,
 				frag->page,
 				frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
 				buffer_info->length, PCI_DMA_TODEVICE);
 
-			if (++tpd_next_to_use == tpd_ring->count)
-				tpd_next_to_use = 0;
+			if (++next_to_use == tpd_ring->count)
+				next_to_use = 0;
 		}
 	}
 
@@ -1451,39 +1471,44 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
 	buffer_info->skb = skb;
 }
 
-static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
-       union tpd_descr *descr)
+static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
+       struct tx_packet_desc *ptpd)
 {
-	/* We enter this function holding a spinlock. */
+	/* spinlock held */
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-	int j;
-	u32 val;
 	struct atl1_buffer *buffer_info;
 	struct tx_packet_desc *tpd;
-	u16 tpd_next_to_use = atomic_read(&tpd_ring->next_to_use);
+	u16 j;
+	u32 val;
+	u16 next_to_use = (u16) atomic_read(&tpd_ring->next_to_use);
 
 	for (j = 0; j < count; j++) {
-		buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
-		tpd = ATL1_TPD_DESC(&adapter->tpd_ring, tpd_next_to_use);
-		tpd->desc.csum.csumpu = descr->csum.csumpu;
-		tpd->desc.csum.csumpl = descr->csum.csumpl;
-		tpd->desc.tso.tsopu = descr->tso.tsopu;
-		tpd->desc.tso.tsopl = descr->tso.tsopl;
+		buffer_info = &tpd_ring->buffer_info[next_to_use];
+		tpd = ATL1_TPD_DESC(&adapter->tpd_ring, next_to_use);
+		if (tpd != ptpd)
+			memcpy(tpd, ptpd, sizeof(struct tx_packet_desc));
 		tpd->buffer_addr = cpu_to_le64(buffer_info->dma);
-		tpd->desc.data = descr->data;
-		tpd->desc.tso.tsopu |= (cpu_to_le16(buffer_info->length) &
-			TSO_PARAM_BUFLEN_MASK) << TSO_PARAM_BUFLEN_SHIFT;
+		tpd->word2 = (cpu_to_le16(buffer_info->length) &
+			TPD_BUFLEN_MASK) << TPD_BUFLEN_SHIFT;
 
-		val = (descr->tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
-			TSO_PARAM_SEGMENT_MASK;
-		if (val && !j)
-			tpd->desc.tso.tsopl |= 1 << TSO_PARAM_HDRFLAG_SHIFT;
+		/*
+		 * if this is the first packet in a TSO chain, set
+		 * TPD_HDRFLAG, otherwise, clear it.
+		 */
+		val = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) &
+			TPD_SEGMENT_EN_MASK;
+		if (val) {
+			if (!j)
+				tpd->word3 |= 1 << TPD_HDRFLAG_SHIFT;
+			else
+				tpd->word3 &= ~(1 << TPD_HDRFLAG_SHIFT);
+		}
 
 		if (j == (count - 1))
-			tpd->desc.tso.tsopl |= 1 << TSO_PARAM_EOP_SHIFT;
+			tpd->word3 |= 1 << TPD_EOP_SHIFT;
 
-		if (++tpd_next_to_use == tpd_ring->count)
-			tpd_next_to_use = 0;
+		if (++next_to_use == tpd_ring->count)
+			next_to_use = 0;
 	}
 	/*
 	 * Force memory writes to complete before letting h/w
@@ -1493,18 +1518,18 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
 	 */
 	wmb();
 
-	atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use);
+	atomic_set(&tpd_ring->next_to_use, next_to_use);
 }
 
 static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 	int len = skb->len;
 	int tso;
 	int count = 1;
 	int ret_val;
-	u32 val;
-	union tpd_descr param;
+	struct tx_packet_desc *ptpd;
 	u16 frag_size;
 	u16 vlan_tag;
 	unsigned long flags;
@@ -1515,18 +1540,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	len -= skb->data_len;
 
-	if (unlikely(skb->len == 0)) {
+	if (unlikely(skb->len <= 0)) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
 
-	param.data = 0;
-	param.tso.tsopu = 0;
-	param.tso.tsopl = 0;
-	param.csum.csumpu = 0;
-	param.csum.csumpl = 0;
-
-	/* nr_frags will be nonzero if we're doing scatter/gather (SG) */
 	nr_frags = skb_shinfo(skb)->nr_frags;
 	for (f = 0; f < nr_frags; f++) {
 		frag_size = skb_shinfo(skb)->frags[f].size;
@@ -1535,10 +1553,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 				ATL1_MAX_TX_BUF_LEN;
 	}
 
-	/* mss will be nonzero if we're doing segment offload (TSO/GSO) */
 	mss = skb_shinfo(skb)->gso_size;
 	if (mss) {
-		if (skb->protocol == htons(ETH_P_IP)) {
+		if (skb->protocol == ntohs(ETH_P_IP)) {
 			proto_hdr_len = (skb_transport_offset(skb) +
 					 tcp_hdrlen(skb));
 			if (unlikely(proto_hdr_len > len)) {
@@ -1567,18 +1584,20 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		return NETDEV_TX_BUSY;
 	}
 
-	param.data = 0;
+	ptpd = ATL1_TPD_DESC(tpd_ring,
+		(u16) atomic_read(&tpd_ring->next_to_use));
+	memset(ptpd, 0, sizeof(struct tx_packet_desc));
 
 	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		vlan_tag = vlan_tx_tag_get(skb);
 		vlan_tag = (vlan_tag << 4) | (vlan_tag >> 13) |
 			((vlan_tag >> 9) & 0x8);
-		param.tso.tsopl |= 1 << TSO_PARAM_INSVLAG_SHIFT;
-		param.tso.tsopu |= (vlan_tag & TSO_PARAM_VLANTAG_MASK) <<
-			TSO_PARAM_VLAN_SHIFT;
+		ptpd->word3 |= 1 << TPD_INS_VL_TAG_SHIFT;
+		ptpd->word3 |= (vlan_tag & TPD_VL_TAGGED_MASK) <<
+			TPD_VL_TAGGED_SHIFT;
 	}
 
-	tso = atl1_tso(adapter, skb, &param.tso);
+	tso = atl1_tso(adapter, skb, ptpd);
 	if (tso < 0) {
 		spin_unlock_irqrestore(&adapter->lock, flags);
 		dev_kfree_skb_any(skb);
@@ -1586,7 +1605,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	if (!tso) {
-		ret_val = atl1_tx_csum(adapter, skb, &param.csum);
+		ret_val = atl1_tx_csum(adapter, skb, ptpd);
 		if (ret_val < 0) {
 			spin_unlock_irqrestore(&adapter->lock, flags);
 			dev_kfree_skb_any(skb);
@@ -1594,13 +1613,11 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		}
 	}
 
-	val = (param.tso.tsopl >> TSO_PARAM_SEGMENT_SHIFT) &
-		TSO_PARAM_SEGMENT_MASK;
-	atl1_tx_map(adapter, skb, 1 == val);
-	atl1_tx_queue(adapter, count, &param);
-	netdev->trans_start = jiffies;
-	spin_unlock_irqrestore(&adapter->lock, flags);
+	atl1_tx_map(adapter, skb, ptpd);
+	atl1_tx_queue(adapter, count, ptpd);
 	atl1_update_mailbox(adapter);
+	spin_unlock_irqrestore(&adapter->lock, flags);
+	netdev->trans_start = jiffies;
 	return NETDEV_TX_OK;
 }
 
@@ -2759,7 +2776,7 @@ const struct ethtool_ops atl1_ethtool_ops = {
 	.get_ringparam		= atl1_get_ringparam,
 	.set_ringparam		= atl1_set_ringparam,
 	.get_pauseparam		= atl1_get_pauseparam,
-	.set_pauseparam 	= atl1_set_pauseparam,
+	.set_pauseparam		= atl1_set_pauseparam,
 	.get_rx_csum		= atl1_get_rx_csum,
 	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
 	.get_link		= ethtool_op_get_link,
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 30c5a8d..4d3d65b 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -452,106 +452,115 @@ struct rx_free_desc {
 	/* __attribute__ ((packed)) is required */
 } __attribute__ ((packed));
 
-/* tsopu defines */
-#define TSO_PARAM_BUFLEN_MASK		0x3FFF
-#define TSO_PARAM_BUFLEN_SHIFT		0
-#define TSO_PARAM_DMAINT_MASK		0x0001
-#define TSO_PARAM_DMAINT_SHIFT		14
-#define TSO_PARAM_PKTNT_MASK		0x0001
-#define TSO_PARAM_PKTINT_SHIFT		15
-#define TSO_PARAM_VLANTAG_MASK		0xFFFF
-#define TSO_PARAM_VLAN_SHIFT		16
-
-/* tsopl defines */
-#define TSO_PARAM_EOP_MASK		0x0001
-#define TSO_PARAM_EOP_SHIFT		0
-#define TSO_PARAM_COALESCE_MASK		0x0001
-#define TSO_PARAM_COALESCE_SHIFT	1
-#define TSO_PARAM_INSVLAG_MASK		0x0001
-#define TSO_PARAM_INSVLAG_SHIFT		2
-#define TSO_PARAM_CUSTOMCKSUM_MASK	0x0001
-#define TSO_PARAM_CUSTOMCKSUM_SHIFT	3
-#define TSO_PARAM_SEGMENT_MASK		0x0001
-#define TSO_PARAM_SEGMENT_SHIFT		4
-#define TSO_PARAM_IPCKSUM_MASK		0x0001
-#define TSO_PARAM_IPCKSUM_SHIFT		5
-#define TSO_PARAM_TCPCKSUM_MASK		0x0001
-#define TSO_PARAM_TCPCKSUM_SHIFT	6
-#define TSO_PARAM_UDPCKSUM_MASK		0x0001
-#define TSO_PARAM_UDPCKSUM_SHIFT	7
-#define TSO_PARAM_VLANTAGGED_MASK	0x0001
-#define TSO_PARAM_VLANTAGGED_SHIFT	8
-#define TSO_PARAM_ETHTYPE_MASK		0x0001
-#define TSO_PARAM_ETHTYPE_SHIFT		9
-#define TSO_PARAM_IPHL_MASK		0x000F
-#define TSO_PARAM_IPHL_SHIFT		10
-#define TSO_PARAM_TCPHDRLEN_MASK	0x000F
-#define TSO_PARAM_TCPHDRLEN_SHIFT	14
-#define TSO_PARAM_HDRFLAG_MASK		0x0001
-#define TSO_PARAM_HDRFLAG_SHIFT		18
-#define TSO_PARAM_MSS_MASK		0x1FFF
-#define TSO_PARAM_MSS_SHIFT		19
-
-/* csumpu defines */
-#define CSUM_PARAM_BUFLEN_MASK		0x3FFF
-#define CSUM_PARAM_BUFLEN_SHIFT		0
-#define CSUM_PARAM_DMAINT_MASK		0x0001
-#define CSUM_PARAM_DMAINT_SHIFT		14
-#define CSUM_PARAM_PKTINT_MASK		0x0001
-#define CSUM_PARAM_PKTINT_SHIFT		15
-#define CSUM_PARAM_VALANTAG_MASK	0xFFFF
-#define CSUM_PARAM_VALAN_SHIFT		16
-
-/* csumpl defines*/
-#define CSUM_PARAM_EOP_MASK		0x0001
-#define CSUM_PARAM_EOP_SHIFT		0
-#define CSUM_PARAM_COALESCE_MASK	0x0001
-#define CSUM_PARAM_COALESCE_SHIFT	1
-#define CSUM_PARAM_INSVLAG_MASK		0x0001
-#define CSUM_PARAM_INSVLAG_SHIFT	2
-#define CSUM_PARAM_CUSTOMCKSUM_MASK	0x0001
-#define CSUM_PARAM_CUSTOMCKSUM_SHIFT	3
-#define CSUM_PARAM_SEGMENT_MASK		0x0001
-#define CSUM_PARAM_SEGMENT_SHIFT	4
-#define CSUM_PARAM_IPCKSUM_MASK		0x0001
-#define CSUM_PARAM_IPCKSUM_SHIFT	5
-#define CSUM_PARAM_TCPCKSUM_MASK	0x0001
-#define CSUM_PARAM_TCPCKSUM_SHIFT	6
-#define CSUM_PARAM_UDPCKSUM_MASK	0x0001
-#define CSUM_PARAM_UDPCKSUM_SHIFT	7
-#define CSUM_PARAM_VLANTAGGED_MASK	0x0001
-#define CSUM_PARAM_VLANTAGGED_SHIFT	8
-#define CSUM_PARAM_ETHTYPE_MASK		0x0001
-#define CSUM_PARAM_ETHTYPE_SHIFT	9
-#define CSUM_PARAM_IPHL_MASK		0x000F
-#define CSUM_PARAM_IPHL_SHIFT		10
-#define CSUM_PARAM_PLOADOFFSET_MASK	0x00FF
-#define CSUM_PARAM_PLOADOFFSET_SHIFT	16
-#define CSUM_PARAM_XSUMOFFSET_MASK	0x00FF
-#define CSUM_PARAM_XSUMOFFSET_SHIFT	24
-
-/* TPD descriptor */
-struct tso_param {
-	/* The order of these declarations is important -- don't change it */
-	u32 tsopu;	/* tso_param upper word */
-	u32 tsopl;	/* tso_param lower word */
-};
-
-struct csum_param {
-	/* The order of these declarations is important -- don't change it */
-	u32 csumpu;	/* csum_param upper word */
-	u32 csumpl;	/* csum_param lower word */
-};
+/*
+ * The L1 transmit packet descriptor is comprised of four 32-bit words.
+ *
+ *	31					0
+ *	+---------------------------------------+
+ *      |	Word 0: Buffer addr lo 		|
+ *      +---------------------------------------+
+ *      |	Word 1: Buffer addr hi		|
+ *      +---------------------------------------+
+ *      |		Word 2			|
+ *      +---------------------------------------+
+ *      |		Word 3			|
+ *      +---------------------------------------+
+ *
+ * Words 0 and 1 combine to form a 64-bit buffer address.
+ *
+ * Word 2 is self explanatory in the #define block below.
+ *
+ * Word 3 has two forms, depending upon the state of bits 3 and 4.
+ * If bits 3 and 4 are both zero, then bits 14:31 are unused by the
+ * hardware.  Otherwise, if either bit 3 or 4 is set, the definition
+ * of bits 14:31 vary according to the following depiction.
+ *
+ *	0	End of packet			0	End of packet
+ *	1	Coalesce			1	Coalesce
+ *	2	Insert VLAN tag			2	Insert VLAN tag
+ *	3	Custom csum enable = 0		3	Custom csum enable = 1
+ *	4	Segment enable = 1		4	Segment enable = 0
+ *	5	Generate IP checksum		5	Generate IP checksum
+ *	6	Generate TCP checksum		6	Generate TCP checksum
+ *	7	Generate UDP checksum		7	Generate UDP checksum
+ *	8	VLAN tagged			8	VLAN tagged
+ *	9	Ethernet frame type		9	Ethernet frame type
+ *	10-+ 					10-+
+ *	11 |	IP hdr length (10:13)		11 |	IP hdr length (10:13)
+ *	12 |	(num 32-bit words)		12 |	(num 32-bit words)
+ *	13-+					13-+
+ *	14-+					14	Unused
+ *	15 |	TCP hdr length (14:17)		15	Unused
+ *	16 |	(num 32-bit words)		16-+
+ *	17-+					17 |
+ *	18	Header TPD flag			18 |
+ *	19-+					19 |	Payload offset
+ *	20 |					20 |	    (16:23)
+ *	21 |					21 |
+ *	22 |					22 |
+ *	23 |					23-+
+ *	24 |					24-+
+ *	25 |	MSS (19:31)			25 |
+ *	26 |					26 |
+ *	27 |					27 |	Custom csum offset
+ *	28 |					28 |	     (24:31)
+ *	29 |					29 |
+ *	30 |					30 |
+ *	31-+					31-+
+ */
 
-union tpd_descr {
-	u64 data;
-	struct csum_param csum;
-	struct tso_param tso;
-};
+/* tpd word 2 */
+#define TPD_BUFLEN_MASK		0x3FFF
+#define TPD_BUFLEN_SHIFT	0
+#define TPD_DMAINT_MASK		0x0001
+#define TPD_DMAINT_SHIFT	14
+#define TPD_PKTNT_MASK		0x0001
+#define TPD_PKTINT_SHIFT	15
+#define TPD_VLANTAG_MASK	0xFFFF
+#define TPD_VLAN_SHIFT		16
+
+/* tpd word 3 bits 0:13 */
+#define TPD_EOP_MASK		0x0001
+#define TPD_EOP_SHIFT		0
+#define TPD_COALESCE_MASK	0x0001
+#define TPD_COALESCE_SHIFT	1
+#define TPD_INS_VL_TAG_MASK	0x0001
+#define TPD_INS_VL_TAG_SHIFT	2
+#define TPD_CUST_CSUM_EN_MASK	0x0001
+#define TPD_CUST_CSUM_EN_SHIFT	3
+#define TPD_SEGMENT_EN_MASK	0x0001
+#define TPD_SEGMENT_EN_SHIFT	4
+#define TPD_IP_CSUM_MASK	0x0001
+#define TPD_IP_CSUM_SHIFT	5
+#define TPD_TCP_CSUM_MASK	0x0001
+#define TPD_TCP_CSUM_SHIFT	6
+#define TPD_UDP_CSUM_MASK	0x0001
+#define TPD_UDP_CSUM_SHIFT	7
+#define TPD_VL_TAGGED_MASK	0x0001
+#define TPD_VL_TAGGED_SHIFT	8
+#define TPD_ETHTYPE_MASK	0x0001
+#define TPD_ETHTYPE_SHIFT	9
+#define TPD_IPHL_MASK		0x000F
+#define TPD_IPHL_SHIFT		10
+
+/* tpd word 3 bits 14:31 if segment enabled */
+#define TPD_TCPHDRLEN_MASK	0x000F
+#define TPD_TCPHDRLEN_SHIFT	14
+#define TPD_HDRFLAG_MASK	0x0001
+#define TPD_HDRFLAG_SHIFT	18
+#define TPD_MSS_MASK		0x1FFF
+#define TPD_MSS_SHIFT		19
+
+/* tpd word 3 bits 16:31 if custom csum enabled */
+#define TPD_PLOADOFFSET_MASK	0x00FF
+#define TPD_PLOADOFFSET_SHIFT	16
+#define TPD_CCSUMOFFSET_MASK	0x00FF
+#define TPD_CCSUMOFFSET_SHIFT	24
 
 struct tx_packet_desc {
 	__le64 buffer_addr;
-	union tpd_descr desc;
+	__le32 word2;
+	__le32 word3;
 };
 
 /* DMA Order Settings */
-- 
1.5.3.8


^ permalink raw reply related

* [PATCH 06/10] atl1: use csum_start
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn
In-Reply-To: <1202003412-4028-1-git-send-email-jacliburn@bellsouth.net>

Use skb->csum_start for tx checksum offload preparation. Also swap
the variables css and cso so they hold the intended values of csum
start and offset, respectively.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
---
 drivers/net/atlx/atl1.c |   11 ++++++-----
 1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index f4add3c..9929822 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1347,16 +1347,17 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
 	u8 css, cso;
 
 	if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-		cso = skb_transport_offset(skb);
-		css = cso + skb->csum_offset;
-		if (unlikely(cso & 0x1)) {
+		css = (u8) (skb->csum_start - skb_headroom(skb));
+		cso = css + (u8) skb->csum_offset;
+		if (unlikely(css & 0x1)) {
+			/* L1 hardware requires an even number here */
 			dev_printk(KERN_DEBUG, &adapter->pdev->dev,
 				"payload offset not an even number\n");
 			return -1;
 		}
-		ptpd->word3 |= (cso & TPD_PLOADOFFSET_MASK) <<
+		ptpd->word3 |= (css & TPD_PLOADOFFSET_MASK) <<
 			TPD_PLOADOFFSET_SHIFT;
-		ptpd->word3 |= (css & TPD_CCSUMOFFSET_MASK) <<
+		ptpd->word3 |= (cso & TPD_CCSUMOFFSET_MASK) <<
 			TPD_CCSUMOFFSET_SHIFT;
 		ptpd->word3 |= 1 << TPD_CUST_CSUM_EN_SHIFT;
 		return true;
-- 
1.5.3.8


^ permalink raw reply related

* [PATCH 08/10] atl1: print debug info if rrd error
From: Jay Cliburn @ 2008-02-03  1:50 UTC (permalink / raw)
  To: jeff; +Cc: csnook, netdev, linux-kernel, Jay Cliburn
In-Reply-To: <1202003412-4028-1-git-send-email-jacliburn@bellsouth.net>

Add some debug printks if we encounter a potentially bad receive
return descriptor.

Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
Acked-by: Chris Snook <csnook@redhat.com>
---
 drivers/net/atlx/atl1.c |   26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 51eca23..4e4cb23 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1144,14 +1144,32 @@ chk_rrd:
 			/* check rrd status */
 			if (likely(rrd->num_buf == 1))
 				goto rrd_ok;
+			else if (netif_msg_rx_err(adapter)) {
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"unexpected RRD buffer count\n");
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"rx_buf_len = %d\n",
+					adapter->rx_buffer_len);
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"RRD num_buf = %d\n",
+					rrd->num_buf);
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"RRD pkt_len = %d\n",
+					rrd->xsz.xsum_sz.pkt_size);
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"RRD pkt_flg = 0x%08X\n",
+					rrd->pkt_flg);
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"RRD err_flg = 0x%08X\n",
+					rrd->err_flg);
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"RRD vlan_tag = 0x%08X\n",
+					rrd->vlan_tag);
+			}
 
 			/* rrd seems to be bad */
 			if (unlikely(i-- > 0)) {
 				/* rrd may not be DMAed completely */
-				if (netif_msg_rx_err(adapter))
-					dev_printk(KERN_DEBUG,
-						&adapter->pdev->dev,
-						"unexpected RRD count\n");
 				udelay(1);
 				goto chk_rrd;
 			}
-- 
1.5.3.8


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox