* Re: [usb regression] Re: [PATCH 2.6.24-rc3] Fix /proc/net breakage
From: Greg KH @ 2007-12-31 19:26 UTC (permalink / raw)
To: Alan Stern
Cc: Andreas Mohr, Ingo Molnar, Alexey Dobriyan, Andrew Morton,
David Woodhouse, Eric W. Biederman, Linus Torvalds,
Rafael J. Wysocki, Pavel Machek, kernel list, netdev,
Pavel Emelyanov, Denis V. Lunev, USB list
In-Reply-To: <Pine.LNX.4.44L0.0712311237150.7182-100000@iolanthe.rowland.org>
On Mon, Dec 31, 2007 at 12:49:52PM -0500, Alan Stern wrote:
> On Sun, 30 Dec 2007, Greg KH wrote:
>
> > > It looks like Greg misused the debugfs API -- which is ironic, because
> > > he wrote debugfs in the first place! :-)
> >
> > Oh crap, sorry, I did mess that up :(
> >
> > > Let me know if this patch fixes the problem. If it does, I'll submit
> > > it to Greg with all the proper accoutrements.
> >
> > This isn't going to work if CONFIG_DEBUGFS is not enabled either :(
>
> Why not? The debugging files won't be created, true, but the driver
> should work just fine regardless. This is exactly the way uhci-hcd
> behaves, and it hasn't caused any problems.
Ok, you are right, it was late and after some wine and I shouldn't have
been responding to email :)
I'll rework this, and send out a patch tonight or tomorrow when I get a
chance (am on the road right now). We should only care about NULL being
returned here, that's the only "real" error.
And in thinking about it some more, I should go audit all the debugfs
callers to make sure they are doing something sane too, it shouldn't be
this complex at all...
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH] Force UNIX domain sockets to be built in
From: Al Viro @ 2007-12-31 19:38 UTC (permalink / raw)
To: Bodo Eggert; +Cc: David Miller, jengelh, devzero, linux-kernel, bunk, netdev
In-Reply-To: <alpine.LSU.0.999.0712311426520.3761@be1.lrz>
On Mon, Dec 31, 2007 at 03:03:20PM +0100, Bodo Eggert wrote:
> On Mon, 31 Dec 2007, David Miller wrote:
> > From: Bodo Eggert <7eggert@gmx.de>
>
> > > As suggested by Adrian Bunk, UNIX domain sockets should always be built in
> > > on normal systems. This is especially true since udev needs these sockets
> > > and fails to run if UNIX=m.
> > >
> > > Signed-Off-By: Bodo Eggert <7eggert@gmx.de>
> >
> > People who use udev can make sure they have it built into their kernel
> > if they have such a dependency.
> >
> > Not everyone uses udev, and therefore needs AF_UNIX non-modular.
>
> That's why I kept this option for embedded folks.
>
> Is there any benefit for non-embedded systems from having UNIX=m?
udev-free != embedded.
^ permalink raw reply
* Re: 2.6.24-rc6-mm1 - git-lblnet.patch and networking horkage
From: Paul Moore @ 2007-12-31 20:06 UTC (permalink / raw)
To: James Morris; +Cc: Valdis.Kletnieks, akpm, linux-kernel, sds, netdev
In-Reply-To: <200712311213.32515.paul.moore@hp.com>
On Monday 31 December 2007 12:13:32 pm Paul Moore wrote:
> On Wednesday 26 December 2007 4:52:03 pm James Morris wrote:
> > On Thu, 26 Dec 2007, Paul Moore wrote:
> > > As James said I'm away right now and computer access is limited.
> > > However, I'm stuck in the airport right now and spent some time looking
> > > at the code ... Based on what has been found so far I wonder if the
> > > problem isn't a race but a problem of skb->iif never being initialized
> > > correctly? To my untrained eye it looks like __netdev_alloc_skb()
> > > should be setting skb->iif (like it does for skb->dev) but it currently
> > > doesn't.
> >
> > ->iif will be zeroed during skb allocation, then set during
> > netif_receive_skb().
>
> I was able to reproduce this bug this morning by running avahi as James did
> and did a little more digging. I don't have a fix yet, but thought I would
> pass along what I've found in case this triggers a moment of clarity to
> someone out there ...
>
> The skb->iif value appears to be messed up as early as netif_receive_skb(),
> in my case it is set to 196611 (trust me, I don't have that many interfaces
> in my test machine) which causes the ->iif initialization code in
> netif_receive_skb() to be skipped because ->iif is greater than zero. This
> particular packet is locally generated and locally consumed.
>
> Hopefully I'll have a fix later this afternoon but if someone has a bright
> idea I'd love to hear it ...
[NOTE: I added netdev to this thread to gather some input. @netdev folks, the
problem is that the skb->iif field contains garbage in some cases which is
causing problems for some new SELinux network code. The exact problem
probably isn't too important for this discussion, what is important is that
the skb->iif field contains a non-zero garbage value some of the time on
incoming packets.]
I'm pretty certain this is an uninitialized value problem now and not a
use-after-free issue. The invalid/garbage ->iif value seems to only happen
on packets that are generated locally and sent back into the stack for local
consumption, e.g. loopback. These local packets also need to have been
cloned at some point, either on the output or input path.
The problem appears to be a skb_clone() function which does not clear the skb
structure properly and fails to copy the ->iif value from the original skb to
the cloned skb. From what I can tell, there are two possible solutions to
this problem:
1. Clear all of the cloned skb fields in skb_clone() via memset()
2. Copy the ->iif field in __copy_skb_header()
I don't have a good enough understanding of all the details involving skb
memory management to know if option #1 is a Good Idea or not, but option #2
seems much simpler and solves the problem of garbage in the ->iif field. My
preference is to go with option #2 but before I submit a patch does anyone
think this is the wrong solution?
--
paul moore
linux security @ hp
^ permalink raw reply
* Re: 2.6.24-rc6-mm1
From: Torsten Kaiser @ 2007-12-31 20:15 UTC (permalink / raw)
To: Herbert Xu
Cc: Andrew Morton, linux-kernel, Neil Brown, J. Bruce Fields, netdev,
Tom Tucker
In-Reply-To: <64bb37e0712291934o77a3d365h56c9c31ac8437469@mail.gmail.com>
On Dec 30, 2007 4:34 AM, Torsten Kaiser <just.for.lkml@googlemail.com> wrote:
> On Dec 30, 2007 2:30 AM, Herbert Xu <herbert@gondor.apana.org.au> wrote:
> > On Sat, Dec 29, 2007 at 05:51:13PM +0100, Torsten Kaiser wrote:
> > >
> > > > > The cause, why I am resending this: I just got a crash with
> > > > > 2.6.24-rc6-mm1, again looking network related:
> > > > >
> > > > > [93436.933356] WARNING: at include/net/dst.h:165 dst_release()
> > > > > [93436.936685] Pid: 8079, comm: konqueror Not tainted 2.6.24-rc6-mm1 #11
> > > > > [93436.939292]
> > > > > [93436.939293] Call Trace:
> > > > > [93436.939304] [<ffffffff80531d2d>] skb_release_all+0xdd/0x110
> > > > > [93436.939307] [<ffffffff80531311>] __kfree_skb+0x11/0xa0
> > > > > [93436.939309] [<ffffffff805313b7>] kfree_skb+0x17/0x30
> > > > > [93436.939312] [<ffffffff805a0b48>] unix_release_sock+0x128/0x250
> > > > > [93436.939315] [<ffffffff805a0c91>] unix_release+0x21/0x30
> > > > > [93436.939318] [<ffffffff8052b144>] sock_release+0x24/0x90
> > > > > [93436.939320] [<ffffffff8052b656>] sock_close+0x26/0x50
> > > > > [93436.939324] [<ffffffff8029f921>] __fput+0xc1/0x230
> > > > > [93436.939327] [<ffffffff8029fe46>] fput+0x16/0x20
> > > > > [93436.939329] [<ffffffff8029c576>] filp_close+0x56/0x90
> > > > > [93436.939331] [<ffffffff8029de46>] sys_close+0xa6/0x110
> > > > > [93436.939335] [<ffffffff8020b57b>] system_call_after_swapgs+0x7b/0x80
> > >
> > > >From code inspection I would blame the patch "[SKBUFF]: Free old skb
> > > properly in skb_morph" from Herbert Xu. (CC added)
> >
> > I doubt it. skb_morph is only used on IP fragments so I don't see how
> > you could attribute an error from a Unix domain socket to this patch.
>
> That's why I wrote that I do not know much about the network core...
>
> > In any case, Unix socket packets should not have a dst at all so the
> > very fact that you're in that path means that you have some sort of
> > memory corruption.
>
> ... I did not know about the fact that there should not have been an dst.
>
> Its just that this warning was the first nice clue about the memory
> corruption related to networking that I see since 2.6.24-rc3-mm2.
> The time of the patch (Mon, 26 Nov 2007 15:11:19) even fits into the
> window between -rc3-mm1 and -rc3-mm2.
>
> I doubt that the memory corruption is a hardware problem, because the
> system in question is using ECC ram and I did not see any messages
> about corrected/detected errors.
>
> > Is this the very first OOPS/warning that you see? If not you should
> > ignore all but the very first one as that may have left your system
> > in an inconsistent state which may render all subsequent OOPSes and
> > warnings useless.
>
> I looked into the log in question and the only other warning was a
> circular locking dependency that lockdep detected around 1.5 hour
> before this warning.
>
> As reported in my original mail immeadeatly after the warning the
> system OOPSed and hang:
> [93436.947241] general protection fault: 0000 [1] SMP
> -> first OOPS
> [93436.947243] last sysfs file:
> /sys/devices/pci0000:00/0000:00:0f.0/0000:01:00.1/irq
> [93436.947245] CPU 1
> [93436.947246] Modules linked in: radeon drm nfsd exportfs w83792d
> ipv6 tuner tea5767 tda8290 tuner_xc2
> 028 tda9887 tuner_simple mt20xx tea5761 tvaudio msp3400 bttv ir_common
> compat_ioctl32 videobuf_dma_sg v
> ideobuf_core btcx_risc tveeprom usbhid videodev v4l2_common hid
> v4l1_compat pata_amd sg i2c_nforce2
> [93436.947257] Pid: 8079, comm: konqueror Not tainted 2.6.24-rc6-mm1 #11
> -> not tainted by a previous OOPS
>
> [93436.947259] RIP: 0010:[<ffffffff80531438>] [<ffffffff80531438>]
> skb_drop_list+0x18/0x30
> [93436.947262] RSP: 0018:ffff810005f4fda8 EFLAGS: 00010286
> [93436.947263] RAX: ab1ed5ca5b74e7de RBX: ab1ed5ca5b74e7de RCX: 000000000000d135
> [93436.947265] RDX: ffff81011d089a80 RSI: 0000000000000001 RDI: ffff81011d089a88
> [93436.947266] RBP: ffff810005f4fdb8 R08: 0000000000000001 R09: 0000000000000006
> [93436.947268] R10: 0000000000000000 R11: 0000000000000000 R12: ffff8100de02c500
> [93436.947269] R13: ffff81011c188a00 R14: 0000000000000001 R15: ffff81011c189198
> [93436.947271] FS: 00007fb5bde0d700(0000) GS:ffff81007ff22000(0000)
> knlGS:0000000000000000
> [93436.947273] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> [93436.947274] CR2: 00007fb5bdd76000 CR3: 00000000664d5000 CR4: 00000000000006e0
> [93436.947276] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [93436.947277] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [93436.947279] Process konqueror (pid: 8079, threadinfo
> ffff810005f4e000, task ffff8100a1dec000)
> [93436.947281] Stack: ffff810005f4fdd8 ffff810116c86140
> ffff810005f4fdd8 ffffffff805314ae
> [93436.947284] ffff810116c86140 ffff8100de02c500 ffff810005f4fdf8
> ffffffff80531cf0
> [93436.947286] ffff8100de02c500 ffff81011c188b48 ffff810005f4fe18
> ffffffff80531311
> [93436.947288] Call Trace:
> [93436.947290] [<ffffffff805314ae>] skb_release_data+0x5e/0xa0
> [93436.947293] [<ffffffff80531cf0>] skb_release_all+0xa0/0x110
> [93436.947295] [<ffffffff80531311>] __kfree_skb+0x11/0xa0
> [93436.947297] [<ffffffff805313b7>] kfree_skb+0x17/0x30
> [93436.947299] [<ffffffff805a0b48>] unix_release_sock+0x128/0x250
> [93436.947302] [<ffffffff805a0c91>] unix_release+0x21/0x30
> [93436.947304] [<ffffffff8052b144>] sock_release+0x24/0x90
> [93436.947307] [<ffffffff8052b656>] sock_close+0x26/0x50
> [93436.947309] [<ffffffff8029f921>] __fput+0xc1/0x230
> [93436.947312] [<ffffffff8029fe46>] fput+0x16/0x20
> [93436.947314] [<ffffffff8029c576>] filp_close+0x56/0x90
> [93436.947316] [<ffffffff8029de46>] sys_close+0xa6/0x110
> [93436.947319] [<ffffffff8020b57b>] system_call_after_swapgs+0x7b/0x80
> [93436.947322]
> [93436.947322]
> [93436.947323] Code: 48 8b 18 48 89 c7 e8 5d ff ff ff 48 85 db 75 ed 48 83 c4 08
> [93436.947328] RIP [<ffffffff80531438>] skb_drop_list+0x18/0x30
> [93436.947330] RSP <ffff810005f4fda8>
> [93436.947332] ---[ end trace befb7cc3528ab3b1 ]---
>
> Your patch just fit so "good" to my problems:
> * it had the correct time frame for 2.6.24-rc3-mm2
> * it looked guilty at changing the refcounting of __refcnt because of
> the added dst_release()
> * it added other release / freeing operations so that a use-after-free
> memory corruption seemed possible
>
> I just have no better idea to what caused this OOPS and the other
> hangs in -rc3-mm2.
After testing the patch from http://lkml.org/lkml/2007/12/30/210 the
system hung again after building ~10 packages from the last kde4
release candidate. (see other mail)
I then tried to "fix" it with this suspect.
I changed "skb_release_all(dst);" back to "skb_release_data(dst);" in
skb_morph() (net/core/skbuff.c).
I'm now at 205 of 210 packages completed without a further hang. I
also do not see an obvious memory leak.
(All of these tests where done on 2.6.24-rc3-mm2, as I'm relative
sure, that doing these compiles will trigger the error on that kernel
version)
Torsten
^ permalink raw reply
* Re: [PATCH] USB VID/PID clash between pegasus and hci_usb drivers
From: Marcel Holtmann @ 2007-12-31 20:54 UTC (permalink / raw)
To: Chris Rankin; +Cc: netdev, gregkh
In-Reply-To: <520598.94496.qm@web52904.mail.re2.yahoo.com>
Hi Chris,
> As requested, here is the patch for the pegasus driver to resolve its VID/PID clash with the
> Belkin bluetooth adaptor.
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Regards
Marcel
^ permalink raw reply
* Re: 2.6.24-rc6-mm1 - git-lblnet.patch and networking horkage
From: James Morris @ 2007-12-31 21:46 UTC (permalink / raw)
To: Paul Moore; +Cc: Valdis.Kletnieks, akpm, linux-kernel, sds, netdev
In-Reply-To: <200712311506.15230.paul.moore@hp.com>
On Mon, 31 Dec 2007, Paul Moore wrote:
> I'm pretty certain this is an uninitialized value problem now and not a
> use-after-free issue. The invalid/garbage ->iif value seems to only happen
> on packets that are generated locally and sent back into the stack for local
> consumption, e.g. loopback. These local packets also need to have been
> cloned at some point, either on the output or input path.
I think we need to find out exactly what's happening, first.
> The problem appears to be a skb_clone() function which does not clear the skb
> structure properly and fails to copy the ->iif value from the original skb to
> the cloned skb. From what I can tell, there are two possible solutions to
> this problem:
>
> 1. Clear all of the cloned skb fields in skb_clone() via memset()
Sounds like it's not going to fly for performance reasons in any case.
> 2. Copy the ->iif field in __copy_skb_header()
Seems valid.
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply
* Re: [PATCH] Re: Nested VLAN causes recursive locking error
From: Jarek Poplawski @ 2007-12-31 21:59 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Chuck Ebbert, Netdev
In-Reply-To: <20071231174555.GA3097@ami.dom.local>
On Mon, Dec 31, 2007 at 06:45:55PM +0100, Jarek Poplawski wrote:
> On Mon, Dec 31, 2007 at 04:04:17PM +0100, Patrick McHardy wrote:
...
> > That will increment the subclass globally, but it should actually just
> > use real_dev->subclass + 1. [...]
...
> to two subclasses - any nested vlan gets second. Otherwise, it seems
> there is some place needed to store these subclasses or use some
> unofficial checks on lockdep's structures?
...It seems there is simply needed additional macro in lockdep's API
to retrieve a subclass number from a lock! It would be at least
'strange' to have to save this doubly.
Jarek P.
^ permalink raw reply
* Re: 2.6.24-rc6-mm1 - git-lblnet.patch and networking horkage
From: Paul Moore @ 2007-12-31 22:01 UTC (permalink / raw)
To: James Morris; +Cc: Valdis.Kletnieks, akpm, linux-kernel, sds, netdev
In-Reply-To: <Xine.LNX.4.64.0801010841060.25768@us.intercode.com.au>
On Monday 31 December 2007 4:46:09 pm James Morris wrote:
> On Mon, 31 Dec 2007, Paul Moore wrote:
> > I'm pretty certain this is an uninitialized value problem now and not a
> > use-after-free issue. The invalid/garbage ->iif value seems to only
> > happen on packets that are generated locally and sent back into the stack
> > for local consumption, e.g. loopback. These local packets also need to
> > have been cloned at some point, either on the output or input path.
>
> I think we need to find out exactly what's happening, first.
The more I've looked at the code this afternoon, I'm certain this is the case.
I've also been running a patched kernel (using option #2 from below) and all
of the skbs coming up the stack have valid ->iif values. Granted, I haven't
examined the code from the avahi daemon or the tcl test cases and traced the
entire code path through the kernel but I _am_ certain that at some point in
that code path the packet is cloned and due to a problem in skb_clone()
the ->iif field is not copied correctly causing the problems we have all
seen.
How much smoke needs to be coming from the gun? :)
> > The problem appears to be a skb_clone() function which does not clear the
> > skb structure properly and fails to copy the ->iif value from the
> > original skb to the cloned skb. From what I can tell, there are two
> > possible solutions to this problem:
> >
> > 1. Clear all of the cloned skb fields in skb_clone() via memset()
>
> Sounds like it's not going to fly for performance reasons in any case.
That was my gut feeling. I was also a little unsure where exactly the correct
placement should be for the memset() call.
> > 2. Copy the ->iif field in __copy_skb_header()
>
> Seems valid.
Okay, I'll stick with this approach. I'll post a patch backed against
net-2.6.25 tomorrow as an RFC to see if anyone on netdev has any strong
feelings. If no one complains, I'll add it to the lblnet git tree.
--
paul moore
linux security @ hp
^ permalink raw reply
* Re: [PATCH] Force UNIX domain sockets to be built in
From: Jan Engelhardt @ 2007-12-31 22:20 UTC (permalink / raw)
To: Patrick Mau; +Cc: Bodo Eggert, Adrian Bunk, devzero, linux-kernel, netdev
In-Reply-To: <20071231174302.GA1627@oscar.prima.de>
On Dec 31 2007 18:43, Patrick Mau wrote:
>
>May I ask something that might be obvious for most of the
>development community:
>
>Modules have to be loaded in seperate pages, right ?
That seems to be the case, judging from /proc/modules always ending in 000,
meaning each module is aligned at 0x1000 (4096, a page on i386).
Additionally, it looks like 48% of all kernel symbols (from System.map)
are aligned to 16 byte boundaries (what a waste! ;-))
^ permalink raw reply
* Re: [PATCH 1/3] [TCP]: cleanup tcp_{in,out}put.c style
From: David Miller @ 2007-12-31 22:58 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <11991109072239-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Mon, 31 Dec 2007 16:21:45 +0200
> These were manually selected from indent's results which as is
> are too noisy to be of any use without human reason. In addition,
> some extra newlines between function and its comment were removed
> too.
>
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied.
^ permalink raw reply
* Re: [PATCH 2/3] [TCP]: Code duplication removal, added tcp_bound_to_half_wnd()
From: David Miller @ 2007-12-31 22:58 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <11991109072164-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Mon, 31 Dec 2007 16:21:46 +0200
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied.
^ permalink raw reply
* Re: [PATCH 3/3] [TCP]: Remove unnecessary local variable
From: David Miller @ 2007-12-31 22:58 UTC (permalink / raw)
To: ilpo.jarvinen; +Cc: netdev
In-Reply-To: <11991109071896-git-send-email-ilpo.jarvinen@helsinki.fi>
From: "Ilpo_Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Mon, 31 Dec 2007 16:21:47 +0200
> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
Applied.
^ permalink raw reply
* Re: [PATCH 0/4] New interface for memory accounting (take 1)
From: David Miller @ 2007-12-31 23:01 UTC (permalink / raw)
To: dada1
Cc: haoki, herbert, vladislav.yasevich, netdev, lksctp-developers,
tyasui, mhiramat, satoshi.oshima.fk, billfink, andi, johnpol,
shemminger, yoshfuji, yumiko.sugita.yf
In-Reply-To: <47790811.9080004@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Mon, 31 Dec 2007 16:17:37 +0100
> Could you add the following patch, because it apparently was lost
> during the battle :)
>
> Thank you
>
> [PATCH] use SK_MEM_QUANTUM_SHIFT in __sk_mem_reclaim()
>
> Avoid an expensive divide (as done in commit
> 18030477e70a826b91608aee40a987bbd368fec6 but lost in commit
> 23821d2653111d20e75472c8c5003df1a55309a8)
>
>
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Sigh :-/
Thanks for catching this Eric, patch applied.
^ permalink raw reply
* [PATCH 01/26] atl1: relocate atl1 driver to /drivers/net/atlx
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn, Chris Snook
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
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 0e5fde4..14acf84 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
obj-$(CONFIG_CHELSIO_T3) += cxgb3/
obj-$(CONFIG_EHEA) += ehea/
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.3
^ permalink raw reply related
* [PATCH 14/26] atl1: move stray defines to header file
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Move some stray defines out to a header file. Improve indentation from
ghastly to horrid.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 29 ++++++++++++-----------------
drivers/net/atlx/atl1.h | 6 ++++++
2 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 9c86ef4..f40cc6e 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -217,12 +217,6 @@ static s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
return ATLX_ERR_PHY;
}
-#define CUSTOM_SPI_CS_SETUP 2
-#define CUSTOM_SPI_CLK_HI 2
-#define CUSTOM_SPI_CLK_LO 2
-#define CUSTOM_SPI_CS_HOLD 2
-#define CUSTOM_SPI_CS_HI 3
-
static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
{
int i;
@@ -232,17 +226,18 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
iowrite32(addr, hw->hw_addr + REG_SPI_ADDR);
value = SPI_FLASH_CTRL_WAIT_READY |
- (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
- SPI_FLASH_CTRL_CS_SETUP_SHIFT | (CUSTOM_SPI_CLK_HI &
- SPI_FLASH_CTRL_CLK_HI_MASK) <<
- SPI_FLASH_CTRL_CLK_HI_SHIFT | (CUSTOM_SPI_CLK_LO &
- SPI_FLASH_CTRL_CLK_LO_MASK) <<
- SPI_FLASH_CTRL_CLK_LO_SHIFT | (CUSTOM_SPI_CS_HOLD &
- SPI_FLASH_CTRL_CS_HOLD_MASK) <<
- SPI_FLASH_CTRL_CS_HOLD_SHIFT | (CUSTOM_SPI_CS_HI &
- SPI_FLASH_CTRL_CS_HI_MASK) <<
- SPI_FLASH_CTRL_CS_HI_SHIFT | (1 & SPI_FLASH_CTRL_INS_MASK) <<
- SPI_FLASH_CTRL_INS_SHIFT;
+ (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) <<
+ SPI_FLASH_CTRL_CS_SETUP_SHIFT |
+ (CUSTOM_SPI_CLK_HI & SPI_FLASH_CTRL_CLK_HI_MASK) <<
+ SPI_FLASH_CTRL_CLK_HI_SHIFT |
+ (CUSTOM_SPI_CLK_LO & SPI_FLASH_CTRL_CLK_LO_MASK) <<
+ SPI_FLASH_CTRL_CLK_LO_SHIFT |
+ (CUSTOM_SPI_CS_HOLD & SPI_FLASH_CTRL_CS_HOLD_MASK) <<
+ SPI_FLASH_CTRL_CS_HOLD_SHIFT |
+ (CUSTOM_SPI_CS_HI & SPI_FLASH_CTRL_CS_HI_MASK) <<
+ SPI_FLASH_CTRL_CS_HI_SHIFT |
+ (1 & SPI_FLASH_CTRL_INS_MASK) <<
+ SPI_FLASH_CTRL_INS_SHIFT;
iowrite32(value, hw->hw_addr + REG_SPI_FLASH_CTRL);
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 8198f82..3db9a34 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -335,6 +335,12 @@ extern const struct ethtool_ops atl1_ethtool_ops;
#define ATL1_EEDUMP_LEN 48
+#define CUSTOM_SPI_CS_SETUP 2
+#define CUSTOM_SPI_CLK_HI 2
+#define CUSTOM_SPI_CLK_LO 2
+#define CUSTOM_SPI_CS_HOLD 2
+#define CUSTOM_SPI_CS_HI 3
+
/* Statistics counters collected by the MAC */
struct stats_msg_block {
/* rx */
--
1.5.3.3
^ permalink raw reply related
* [PATCH 09/26] atl1: refactor tx processing
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Refactor tx processing to use a less convoluted tx packet descriptor and
to conform generally with the vendor's current version 1.2.40.2.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
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 fb0a0af..b0c3273 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1288,8 +1288,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;
@@ -1311,48 +1309,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;
@@ -1364,115 +1383,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;
}
}
@@ -1480,39 +1500,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
@@ -1522,18 +1547,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;
@@ -1544,18 +1569,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;
@@ -1564,10 +1582,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)) {
@@ -1596,18 +1613,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, ¶m.tso);
+ tso = atl1_tso(adapter, skb, ptpd);
if (tso < 0) {
spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
@@ -1615,7 +1634,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
}
if (!tso) {
- ret_val = atl1_tx_csum(adapter, skb, ¶m.csum);
+ ret_val = atl1_tx_csum(adapter, skb, ptpd);
if (ret_val < 0) {
spin_unlock_irqrestore(&adapter->lock, flags);
dev_kfree_skb_any(skb);
@@ -1623,13 +1642,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, ¶m);
- 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;
}
@@ -2788,7 +2805,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..f50441b 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:15) 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.3
^ permalink raw reply related
* [PATCH 00/26] atl1: divide and modernize
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev
[Neglected to cc netdev in the first wave.]
Hello Jeff,
Happy New Year to you and all.
In preparation for a future atl2 driver for the Atheros L2 10/100 chip,
we propose to move the existing atl1 driver to a new directory
(drivers/net/atlx), then split out functions and definitions that both
atl1 and atl2 can share. The final structure will look like this:
directory or file status
======================= ==========================
drivers/net/atl1/ deleted
drivers/net/atlx/ new
drivers/net/atlx/atl1.c atl1-specific functions
drivers/net/atlx/atl1.h atl1-specific definitions
drivers/net/atlx/atlx.c atl1-atl2 shared functions
drivers/net/atlx/atlx.h atl1-atl2 shared definitions
The first two patches submitted in this patchset accomplish the relocation
by movng the atl1 driver -- lock, stock, and barrel -- over to
drivers/net/atlx, then splitting out shareable functions and definitions.
Some transitory hackery will be present until the atl2 merge. Please
overlook it for now.
The remaining 24 patches bring the atl1 driver up to par with the current
vendor driver version 1.2.40.2. NAPI support is included and it seems
to work, but it needs to be scrutinized by an experienced eye. I had a
hard time finding much current NAPI documentation, so I just hacked at
it by looking at the e1000 driver.
Patch 02/26 is too large for LKML, so it's available at:
ftp://ftp.hogchain.net/pub/linux/attansic/atlx
Or, alternatively, the whole shebang can be pulled from:
git://git.hogchain.net/home/jcliburn/netdev-2.6.git atl1-for-jeff
Table of contents:
---
0001-atl1-relocate-atl1-driver-to-drivers-net-atlx.patch
0002-atl1-move-common-functions-to-atlx-files.patch
0003-atl1-fix-broken-TSO.patch
0004-atl1-add-ethtool-register-dump.patch
0005-atl1-print-debug-info-if-rrd-error.patch
0006-atl1-update-initialization-parameters.patch
0007-atl1-clarify-max-rx-frame-size.patch
0008-atl1-additional-DMA-engine-configuration.patch
0009-atl1-refactor-tx-processing.patch
0010-atl1-use-csum_start.patch
0011-atl1-refactor-initialization-and-startup.patch
0012-atl1-refactor-atl1_probe.patch
0013-atl1-refactor-interrupt-handling.patch
0014-atl1-move-stray-defines-to-header-file.patch
0015-atl1-tidy-up-ring-management.patch
0016-atl1-modernize-check-link-function.patch
0017-atl1-update-phy-config-function.patch
0018-atl1-make-function-static.patch
0019-atl1-modernize-down-up-functions.patch
0020-atl1-update-change-mtu.patch
0021-atl1-update-atl1_close.patch
0022-atl1-update-netpoll.patch
0023-atl1-update-shutdown-and-remove-functions.patch
0024-atl1-update-wake-on-lan.patch
0025-atl1-add-NAPI-support.patch
0026-atl1-remove-experimental-tag-and-clean-up-comments.patch
Summary diffstat:
---
drivers/net/Kconfig | 18 +-
drivers/net/Makefile | 2 +-
drivers/net/atl1/Makefile | 2 -
drivers/net/atl1/atl1.h | 286 ---
drivers/net/atl1/atl1_ethtool.c | 505 ------
drivers/net/atl1/atl1_hw.c | 720 --------
drivers/net/atl1/atl1_hw.h | 946 ----------
drivers/net/atl1/atl1_main.c | 2453 --------------------------
drivers/net/atl1/atl1_param.c | 203 ---
drivers/net/atlx/Makefile | 1 +
drivers/net/atlx/atl1.c | 3648 +++++++++++++++++++++++++++++++++++++++
drivers/net/atlx/atl1.h | 849 +++++++++
drivers/net/atlx/atlx.c | 433 +++++
drivers/net/atlx/atlx.h | 533 ++++++
14 files changed, 5481 insertions(+), 5118 deletions(-)
delete mode 100644 drivers/net/atl1/Makefile
delete mode 100644 drivers/net/atl1/atl1.h
delete mode 100644 drivers/net/atl1/atl1_ethtool.c
delete mode 100644 drivers/net/atl1/atl1_hw.c
delete mode 100644 drivers/net/atl1/atl1_hw.h
delete mode 100644 drivers/net/atl1/atl1_main.c
delete mode 100644 drivers/net/atl1/atl1_param.c
create mode 100644 drivers/net/atlx/Makefile
create mode 100644 drivers/net/atlx/atl1.c
create mode 100644 drivers/net/atlx/atl1.h
create mode 100644 drivers/net/atlx/atlx.c
create mode 100644 drivers/net/atlx/atlx.h
Best regards,
Jay Cliburn
^ permalink raw reply
* [PATCH 07/26] atl1: clarify max rx frame size
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
When we initially set max rx frame size, we don't explicitly allow room for
the VLAN header; it's done later in a somewhat obscure fashion. Let's make
it clear from the top that we've allowed enough room for the VLAN header.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 695dcbc..c93cf19 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -113,7 +113,7 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
struct atl1_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev;
- hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+ hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
adapter->wol = 0;
@@ -744,8 +744,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
/* set Interrupt Clear Timer */
iowrite16(adapter->ict, hw->hw_addr + REG_CMBDISDMA_TIMER);
- /* set MTU, 4 : VLAN */
- iowrite32(hw->max_frame_size + 4, hw->hw_addr + REG_MTU);
+ /* set MTU size */
+ iowrite32(hw->max_frame_size, hw->hw_addr + REG_MTU);
/* jumbo size & rrd retirement timer */
value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)
--
1.5.3.3
^ permalink raw reply related
* [PATCH 03/26] atl1: fix broken TSO
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-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>
---
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 0df3f32..4e98c16 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, ¶m.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, ¶m);
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.3
^ permalink raw reply related
* [PATCH 10/26] atl1: use csum_start
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Use skb->csum_start for tx checksum offload preparation.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
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 b0c3273..31aad9f 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1376,16 +1376,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.3
^ permalink raw reply related
* [PATCH 06/26] atl1: update initialization parameters
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Update initialization parameters to match the current vendor driver
version 1.2.40.2.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 262d3ca..695dcbc 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -136,20 +136,20 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
hw->rfd_fetch_gap = 1;
hw->rx_jumbo_th = adapter->rx_buffer_len / 8;
hw->rx_jumbo_lkah = 1;
- hw->rrd_ret_timer = 16;
- hw->tpd_burst = 4;
+ hw->rrd_ret_timer = 4; /* 8 us */
+ hw->tpd_burst = 8;
hw->tpd_fetch_th = 16;
- hw->txf_burst = 0x100;
+ hw->txf_burst = 0x200;
hw->tx_jumbo_task_th = (hw->max_frame_size + 7) >> 3;
hw->tpd_fetch_gap = 1;
hw->rcb_value = atl1_rcb_64;
hw->dma_ord = atl1_dma_ord_enh;
- hw->dmar_block = atl1_dma_req_256;
- hw->dmaw_block = atl1_dma_req_256;
+ hw->dmar_block = atl1_dma_req_1024;
+ hw->dmaw_block = atl1_dma_req_1024;
hw->cmb_rrd = 4;
hw->cmb_tpd = 4;
- hw->cmb_rx_timer = 1; /* about 2us */
- hw->cmb_tx_timer = 1; /* about 2us */
+ hw->cmb_rx_timer = 2; /* about 4us */
+ hw->cmb_tx_timer = 256; /* about 512us */
hw->smb_timer = 100000; /* about 200ms */
spin_lock_init(&adapter->lock);
--
1.5.3.3
^ permalink raw reply related
* [PATCH 04/26] atl1: add ethtool register dump
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-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>
---
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 4e98c16..239641f 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.3
^ permalink raw reply related
* [PATCH 13/26] atl1: refactor interrupt handling
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Refactor interrupt handling to conform with the current vendor driver
version 1.2.40.2.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 196 ++++++++++++++++++++++-------------------------
drivers/net/atlx/atl1.h | 25 +++++-
drivers/net/atlx/atlx.c | 2 +-
3 files changed, 114 insertions(+), 109 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index d38f26f..9c86ef4 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1740,12 +1740,11 @@ next:
return num_alloc;
}
-static void atl1_intr_rx(struct atl1_adapter *adapter)
+static void atl1_clean_rx_irq(struct atl1_adapter *adapter)
{
+ struct net_device *netdev = adapter->netdev;
int i, count;
- u16 length;
- u16 rrd_next_to_clean;
- u32 value;
+ u16 length, rrd_next_to_clean;
struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
struct atl1_buffer *buffer_info;
@@ -1754,7 +1753,7 @@ static void atl1_intr_rx(struct atl1_adapter *adapter)
count = 0;
- rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
+ rrd_next_to_clean = (u16) atomic_read(&rrd_ring->next_to_clean);
while (1) {
rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
@@ -1795,6 +1794,7 @@ chk_rrd:
/* bad rrd */
dev_printk(KERN_DEBUG, &adapter->pdev->dev,
"bad RRD\n");
+
/* see if update RFD index */
if (rrd->num_buf > 1)
atl1_update_rfd_index(adapter, rrd);
@@ -1823,13 +1823,18 @@ rrd_ok:
count++;
if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
- if (!(rrd->err_flg &
- (ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM
- | ERR_FLAG_LEN))) {
- /* packet error, don't need upstream */
- buffer_info->alloced = 0;
- rrd->xsz.valid = 0;
- continue;
+ if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
+ ERR_FLAG_CODE | ERR_FLAG_OV)) {
+ if (!(netdev->flags & IFF_PROMISC)) {
+ /* packet error, don't need upstream */
+ buffer_info->alloced = 0;
+ rrd->xsz.valid = 0;
+ dev_printk(KERN_DEBUG,
+ &adapter->pdev->dev,
+ "rrd error flag 0x%08X\n",
+ rrd->err_flg);
+ continue;
+ }
}
}
@@ -1862,33 +1867,13 @@ rrd_ok:
}
atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
-
atl1_alloc_rx_buffers(adapter);
- /* update mailbox ? */
- if (count) {
- u32 tpd_next_to_use;
- u32 rfd_next_to_use;
-
- spin_lock(&adapter->mb_lock);
-
- tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
- rfd_next_to_use =
- atomic_read(&adapter->rfd_ring.next_to_use);
- rrd_next_to_clean =
- atomic_read(&adapter->rrd_ring.next_to_clean);
- value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
- MB_RFD_PROD_INDX_SHIFT) |
- ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
- MB_RRD_CONS_INDX_SHIFT) |
- ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
- MB_TPD_PROD_INDX_SHIFT);
- iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
- spin_unlock(&adapter->mb_lock);
- }
+ if (count)
+ atl1_update_mailbox(adapter);
}
-static void atl1_intr_tx(struct atl1_adapter *adapter)
+static bool atl1_clean_tx_irq(struct atl1_adapter *adapter)
{
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
struct atl1_buffer *buffer_info;
@@ -1905,7 +1890,7 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
if (buffer_info->dma) {
pci_unmap_page(adapter->pdev, buffer_info->dma,
- buffer_info->length, PCI_DMA_TODEVICE);
+ buffer_info->length, PCI_DMA_TODEVICE);
buffer_info->dma = 0;
}
@@ -1922,6 +1907,11 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
if (netif_queue_stopped(adapter->netdev)
&& netif_carrier_ok(adapter->netdev))
netif_wake_queue(adapter->netdev);
+
+ if (sw_tpd_next_to_clean == (u16) atomic_read(&tpd_ring->next_to_use))
+ return true;
+ else
+ return false;
}
static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
@@ -2285,80 +2275,75 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
static irqreturn_t atl1_intr(int irq, void *data)
{
struct atl1_adapter *adapter = netdev_priv(data);
+ struct atl1_hw *hw = &adapter->hw;
u32 status;
- u8 update_rx;
int max_ints = 10;
status = adapter->cmb.cmb->int_stats;
if (!status)
return IRQ_NONE;
- update_rx = 0;
-
- do {
- /* clear CMB interrupt status at once */
- adapter->cmb.cmb->int_stats = 0;
-
- if (status & ISR_GPHY) /* clear phy status */
- atlx_clear_phy_int(adapter);
+loopint:
+ /* clear CMB interrupt status at once */
+ adapter->cmb.cmb->int_stats = 0;
- /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
- iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
+ if (status & ISR_GPHY) /* clear phy status */
+ atlx_clear_phy_int(adapter);
- /* check if SMB intr */
- if (status & ISR_SMB)
- atl1_inc_smb(adapter);
+ /* clear ISR status, and Enable CMB DMA/Disable Interrupt */
+ status |= (ISR_DIS_INT | ISR_DIS_DMA);
+ iowrite32(status, adapter->hw.hw_addr + REG_ISR);
- /* check if PCIE PHY Link down */
- if (status & ISR_PHY_LINKDOWN) {
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "pcie phy link down %x\n", status);
- if (netif_running(adapter->netdev)) { /* reset MAC */
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
- return IRQ_HANDLED;
- }
- }
-
- /* check if DMA read/write error ? */
- if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "pcie DMA r/w error (status = 0x%x)\n",
- status);
- iowrite32(0, adapter->hw.hw_addr + REG_IMR);
- schedule_work(&adapter->pcie_dma_to_rst_task);
+ /* check if PCIE PHY Link down */
+ if (status & ISR_PHY_LINKDOWN) {
+ dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+ "pcie phy link down %x\n", status);
+ if (netif_running(adapter->netdev)) {
+ /* reset MAC */
+ iowrite32(0, hw->hw_addr + REG_ISR);
+ iowrite32(0, hw->hw_addr + REG_IMR);
+ ioread32(hw->hw_addr + REG_IMR);
+ schedule_work(&adapter->reset_task);
return IRQ_HANDLED;
}
+ }
- /* link event */
- if (status & ISR_GPHY) {
- adapter->soft_stats.tx_carrier_errors++;
- atl1_check_for_link(adapter);
- }
+ /* check if DMA read/write error ? */
+ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+ dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+ "pcie DMA r/w error (status = 0x%x)\n",
+ status);
+ iowrite32(0, hw->hw_addr + REG_ISR);
+ iowrite32(0, hw->hw_addr + REG_IMR);
+ ioread32(hw->hw_addr + REG_IMR);
+ schedule_work(&adapter->reset_task);
+ return IRQ_HANDLED;
+ }
- /* transmit event */
- if (status & ISR_CMB_TX)
- atl1_intr_tx(adapter);
-
- /* rx exception */
- if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
- ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
- ISR_HOST_RRD_OV | ISR_CMB_RX))) {
- if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
- ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
- ISR_HOST_RRD_OV))
- dev_printk(KERN_DEBUG, &adapter->pdev->dev,
- "rx exception, ISR = 0x%x\n", status);
- atl1_intr_rx(adapter);
- }
+ /* check if SMB intr */
+ if (status & ISR_SMB)
+ atl1_inc_smb(adapter);
- if (--max_ints < 0)
- break;
+ /* link event */
+ if (status & (ISR_GPHY | ISR_MANUAL)) {
+ adapter->soft_stats.tx_carrier_errors++;
+ atl1_check_for_link(adapter);
+ }
+
+ /* transmit event */
+ if (status & ISR_TX_EVENT)
+ atl1_clean_tx_irq(adapter);
- } while ((status = adapter->cmb.cmb->int_stats));
+ /* rx event */
+ if (status & ISR_RX_EVENT)
+ atl1_clean_rx_irq(adapter);
- /* re-enable Interrupt */
- iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
+ status = adapter->cmb.cmb->int_stats;
+ if ((--max_ints > 0) && status)
+ goto loopint;
+
+ /* re-enable interrupts */
+ iowrite32((ISR_DIS_SMB | ISR_DIS_DMA), adapter->hw.hw_addr + REG_ISR);
return IRQ_HANDLED;
}
@@ -2460,16 +2445,22 @@ void atl1_down(struct atl1_adapter *adapter)
atl1_clean_rx_ring(adapter);
}
-static void atl1_tx_timeout_task(struct work_struct *work)
+static void atl1_reinit_locked(struct atl1_adapter *adapter)
{
- struct atl1_adapter *adapter =
- container_of(work, struct atl1_adapter, tx_timeout_task);
- struct net_device *netdev = adapter->netdev;
-
- netif_device_detach(netdev);
+ WARN_ON(in_interrupt());
+ while (test_and_set_bit(__ATL1_RESETTING, &adapter->flags))
+ msleep(1);
atl1_down(adapter);
atl1_up(adapter);
- netif_device_attach(netdev);
+ clear_bit(__ATL1_RESETTING, &adapter->flags);
+}
+
+static void atl1_reset_task(struct work_struct *work)
+{
+ struct atl1_adapter *adapter;
+
+ adapter = container_of(work, struct atl1_adapter, reset_task);
+ atl1_reinit_locked(adapter);
}
/*
@@ -2857,12 +2848,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
adapter->phy_config_timer.data = (unsigned long)adapter;
adapter->phy_timer_pending = false;
- INIT_WORK(&adapter->tx_timeout_task, atl1_tx_timeout_task);
-
+ INIT_WORK(&adapter->reset_task, atl1_reset_task);
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
- INIT_WORK(&adapter->pcie_dma_to_rst_task, atl1_tx_timeout_task);
-
err = register_netdev(netdev);
if (err)
goto err_common;
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 2c2570e..8198f82 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -262,7 +262,7 @@ extern const struct ethtool_ops atl1_ethtool_ops;
#define ISR_RRD_OV 0x20
#define ISR_TXF_UNRUN 0x40
#define ISR_LINK 0x80
-#define ISR_HOST_RFD_UNRUN 0x100
+#define ISR_HOST_RFD_UR 0x100
#define ISR_HOST_RRD_OV 0x200
#define ISR_DMAR_TO_RST 0x400
#define ISR_DMAW_TO_RST 0x800
@@ -288,6 +288,24 @@ extern const struct ethtool_ops atl1_ethtool_ops;
ISR_CMB_TX |\
ISR_CMB_RX)
+#define ISR_TX_EVENT (\
+ ISR_TXF_UNRUN |\
+ ISR_TX_PKT |\
+ ISR_TX_DMA |\
+ ISR_CMB_TX |\
+ ISR_MAC_TX)
+
+#define ISR_RX_EVENT (\
+ ISR_RXF_OV |\
+ ISR_RFD_UNRUN |\
+ ISR_RRD_OV |\
+ ISR_HOST_RFD_UR |\
+ ISR_HOST_RRD_OV |\
+ ISR_RX_PKT |\
+ ISR_RX_DMA |\
+ ISR_CMB_RX |\
+ ISR_MAC_RX)
+
/* Debug Interrupt Mask (enable all interrupt) */
#define IMR_DEBUG_MASK (\
ISR_SMB |\
@@ -762,10 +780,8 @@ struct atl1_adapter {
u32 wol;
u16 link_speed;
u16 link_duplex;
- spinlock_t lock;
- struct work_struct tx_timeout_task;
+ struct work_struct reset_task;
struct work_struct link_chg_task;
- struct work_struct pcie_dma_to_rst_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
bool phy_timer_pending;
@@ -776,6 +792,7 @@ struct atl1_adapter {
/* TX */
struct atl1_tpd_ring tpd_ring;
spinlock_t mb_lock;
+ spinlock_t lock;
/* RX */
struct atl1_rfd_ring rfd_ring;
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index 354050f..18c2d7e 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -204,7 +204,7 @@ static void atlx_tx_timeout(struct net_device *netdev)
{
struct atlx_adapter *adapter = netdev_priv(netdev);
/* Do the reset outside of interrupt context */
- schedule_work(&adapter->tx_timeout_task);
+ schedule_work(&adapter->reset_task);
}
/*
--
1.5.3.3
^ permalink raw reply related
* [PATCH 19/26] atl1: modernize down/up functions
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Update atl1_down() and atl1_up() to conform with the current vendor driver
version 1.2.40.2.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 21 ++++++++-------------
drivers/net/atlx/atl1.h | 1 -
drivers/net/atlx/atlx.c | 2 +-
3 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 7697e80..972de34 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -2388,7 +2388,6 @@ static s32 atl1_up(struct atl1_adapter *adapter)
}
clear_bit(__ATL1_DOWN, &adapter->flags);
- mod_timer(&adapter->watchdog_timer, jiffies + (4 * HZ));
retval = ioread32(&adapter->hw + REG_MASTER_CTRL);
retval |= MASTER_CTRL_MANUAL_INT;
iowrite32(retval, &adapter->hw + REG_MASTER_CTRL);
@@ -2401,21 +2400,18 @@ void atl1_down(struct atl1_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
- del_timer_sync(&adapter->watchdog_timer);
- del_timer_sync(&adapter->phy_config_timer);
- adapter->phy_timer_pending = false;
-
- atlx_irq_disable(adapter);
- free_irq(adapter->pdev->irq, netdev);
- pci_disable_msi(adapter->pdev);
+ set_bit(__ATL1_DOWN, &adapter->flags);
+ netif_stop_queue(netdev);
atl1_reset_hw(&adapter->hw);
adapter->cmb.cmb->int_stats = 0;
-
+ msleep(1);
+ atlx_irq_disable(adapter);
+ del_timer_sync(&adapter->watchdog_timer);
+ del_timer_sync(&adapter->phy_config_timer);
+ clear_bit(0, &adapter->cfg_phy);
+ netif_carrier_off(netdev);
adapter->link_speed = SPEED_0;
adapter->link_duplex = -1;
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
atl1_clean_tx_ring(adapter);
atl1_clean_rx_ring(adapter);
}
@@ -2821,7 +2817,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
init_timer(&adapter->phy_config_timer);
adapter->phy_config_timer.function = &atl1_phy_config;
adapter->phy_config_timer.data = (unsigned long)adapter;
- adapter->phy_timer_pending = false;
INIT_WORK(&adapter->reset_task, atl1_reset_task);
INIT_WORK(&adapter->link_chg_task, atlx_link_chg_task);
diff --git a/drivers/net/atlx/atl1.h b/drivers/net/atlx/atl1.h
index 1f245e0..5187f74 100644
--- a/drivers/net/atlx/atl1.h
+++ b/drivers/net/atlx/atl1.h
@@ -790,7 +790,6 @@ struct atl1_adapter {
struct work_struct link_chg_task;
struct timer_list watchdog_timer;
struct timer_list phy_config_timer;
- bool phy_timer_pending;
unsigned long cfg_phy;
/* all descriptor rings' memory */
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index 18c2d7e..9cc9441 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -91,7 +91,6 @@ static void atlx_check_for_link(struct atlx_adapter *adapter)
u16 phy_data = 0;
spin_lock(&adapter->lock);
- adapter->phy_timer_pending = false;
atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
atlx_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
spin_unlock(&adapter->lock);
@@ -104,6 +103,7 @@ static void atlx_check_for_link(struct atlx_adapter *adapter)
dev_info(&adapter->pdev->dev, "%s link is down\n",
netdev->name);
adapter->link_speed = SPEED_0;
+ clear_bit(0, &adapter->hw.force_ps);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
--
1.5.3.3
^ permalink raw reply related
* [PATCH 08/26] atl1: additional DMA engine configuration
From: Jay Cliburn @ 2008-01-01 2:22 UTC (permalink / raw)
To: netdev; +Cc: Jay Cliburn
In-Reply-To: <1199154173-4058-1-git-send-email-jacliburn@bellsouth.net>
Add DMA engine configuration tweaks per current vendor atl1 driver version
1.2.40.2.
Signed-off-by: Jay Cliburn <jacliburn@bellsouth.net>
---
drivers/net/atlx/atl1.c | 10 ++++++++++
drivers/net/atlx/atlx.h | 6 ++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index c93cf19..fb0a0af 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -666,6 +666,7 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
{
struct atl1_hw *hw = &adapter->hw;
u32 value;
+ u16 x;
/* clear interrupt status */
iowrite32(0xffffffff, adapter->hw.hw_addr + REG_ISR);
@@ -797,6 +798,15 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
iowrite32(value, hw->hw_addr + REG_RXQ_CTRL);
/* config DMA Engine */
+ value = ioread32(hw->hw_addr + REG_DEVICE_CTRL);
+ x = (value >> DEVICE_CTRL_MAX_PAYLOAD_SHIFT) &
+ DEVICE_CTRL_MAX_PAYLOAD_MASK;
+ if (x < hw->dmaw_block)
+ hw->dmaw_block = x;
+ x = (value >> DEVICE_CTRL_MAX_RREQ_SZ_SHIFT) &
+ DEVICE_CTRL_MAX_RREQ_SZ_MASK;
+ if (x < hw->dmar_block)
+ hw->dmar_block = x;
value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
((((u32) hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
diff --git a/drivers/net/atlx/atlx.h b/drivers/net/atlx/atlx.h
index 3be7c09..43b8531 100644
--- a/drivers/net/atlx/atlx.h
+++ b/drivers/net/atlx/atlx.h
@@ -53,6 +53,12 @@ MODULE_VERSION(ATLX_DRIVER_VERSION);
#define REG_PCIE_CAP_LIST 0x58
+#define REG_DEVICE_CTRL 0x60
+#define DEVICE_CTRL_MAX_PAYLOAD_MASK 0x7
+#define DEVICE_CTRL_MAX_PAYLOAD_SHIFT 5
+#define DEVICE_CTRL_MAX_RREQ_SZ_MASK 0x7
+#define DEVICE_CTRL_MAX_RREQ_SZ_SHIFT 12
+
#define REG_VPD_CAP 0x6C
#define VPD_CAP_ID_MASK 0xFF
#define VPD_CAP_ID_SHIFT 0
--
1.5.3.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox