* Re: [PATCH, RFC] RCU : OOM avoidance and lower latency
From: David S. Miller @ 2006-01-07 7:44 UTC (permalink / raw)
To: dada1; +Cc: ak, paulmck, alan, torvalds, linux-kernel, dipankar, manfred,
netdev
In-Reply-To: <43BF6F0B.4060108@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Sat, 07 Jan 2006 08:34:35 +0100
> I agree, I do use a hashed spinlock array on my local tree for TCP,
> mainly to reduce the hash table size by a 2 factor.
So what do you think about going to a single spinlock for the
routing cache?
^ permalink raw reply
* Re: [PATCH, RFC] RCU : OOM avoidance and lower latency
From: Eric Dumazet @ 2006-01-07 7:53 UTC (permalink / raw)
To: David S. Miller
Cc: ak, paulmck, alan, torvalds, linux-kernel, dipankar, manfred,
netdev
In-Reply-To: <20060106.234440.53993868.davem@davemloft.net>
David S. Miller a écrit :
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Sat, 07 Jan 2006 08:34:35 +0100
>
>> I agree, I do use a hashed spinlock array on my local tree for TCP,
>> mainly to reduce the hash table size by a 2 factor.
>
> So what do you think about going to a single spinlock for the
> routing cache?
I have no problem with this, since the biggest server I have is 4 way, but are
you sure big machines wont suffer from this single spinlock ?
Also I dont understand what you want to do after this single spinlock patch.
How is it supposed to help the 'ip route flush cache' problem ?
In my case, I have about 600.000 dst-entries :
# grep ip_dst /proc/slabinfo
ip_dst_cache 616250 622440 320 12 1 : tunables 54 27 8 :
slabdata 51870 51870 0
Eric
^ permalink raw reply
* Re: [PATCH, RFC] RCU : OOM avoidance and lower latency
From: Eric Dumazet @ 2006-01-07 8:30 UTC (permalink / raw)
To: David S. Miller
Cc: ak, paulmck, alan, torvalds, linux-kernel, dipankar, manfred,
netdev
In-Reply-To: <20060106.161721.124249301.davem@davemloft.net>
David S. Miller a écrit :
>
> Eric, how important do you honestly think the per-hashchain spinlocks
> are? That's the big barrier from making rt_secret_rebuild() a simple
> rehash instead of flushing the whole table as it does now.
>
No problem for me in going to a single spinlock.
I did the hashed spinlock patch in order to reduce the size of the route hash
table and not hurting big NUMA machines. If you think a single spinlock is OK,
that's even better !
> The lock is only grabbed for updates, and the access to these locks is
> random and as such probably non-local when taken anyways. Back before
> we used RCU for reads, this array-of-spinlock thing made a lot more
> sense.
>
> I mean something like this patch:
>
> +static DEFINE_SPINLOCK(rt_hash_lock);
Just one point : This should be cache_line aligned, and use one full cache
line to avoid false sharing at least. (If a cpu takes the lock, no need to
invalidate *rt_hash_table for all other cpus)
Eric
^ permalink raw reply
* Re: [PATCH, RFC] RCU : OOM avoidance and lower latency
From: David S. Miller @ 2006-01-07 8:36 UTC (permalink / raw)
To: dada1; +Cc: ak, paulmck, alan, torvalds, linux-kernel, dipankar, manfred,
netdev
In-Reply-To: <43BF7390.6050005@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Sat, 07 Jan 2006 08:53:52 +0100
> I have no problem with this, since the biggest server I have is 4
> way, but are you sure big machines wont suffer from this single
> spinlock ?
It is the main question.
> Also I dont understand what you want to do after this single
> spinlock patch. How is it supposed to help the 'ip route flush
> cache' problem ? In my case, I have about 600.000 dst-entries :
I don't claim to have a solution to this problem currently.
Doing RCU and going through the whole DST GC machinery is overkill for
an active system. So, perhaps a very simple solution will do:
1) On rt_run_flush(), do not rt_free(), instead collect all active
routing cache entries onto a global list, begin a timer to
fire in 10 seconds (or some sysctl configurable amount).
2) When a new routing cache entry is needed, check the global
list appended to in #1 above first, failing that do dst_alloc()
as is done currently.
3) If timer expires, rt_free() any entries in the global list.
The missing trick is how to ensure RCU semantics when reallocating
from the global list.
The idea is that an active system will immediately repopulate itself
with all of these entries just flushed from the table.
RCU really doesn't handle this kind of problem very well. It truly
excels when work is generated by process context work, not interrupt
work.
^ permalink raw reply
* Re: State of the Union: Wireless
From: Denis Vlasenko @ 2006-01-07 14:49 UTC (permalink / raw)
To: Johannes Berg; +Cc: Jeff Garzik, netdev, linux-kernel
In-Reply-To: <1136547084.4037.41.camel@localhost>
On Friday 06 January 2006 13:31, Johannes Berg wrote:
> On Fri, 2006-01-06 at 12:00 +0100, Michael Buesch wrote:
>
> > * "master" interface as real device node
> > * Virtual interfaces (net_devices)
>
> I didn't want to spam the netdev wiki with this (yet) so I collected
> some more structured things outside. Anyone feel free to edit:
> http://softmac.sipsolutions.net/802.11
I am confused.
There is
http://softmac.sipsolutions.net/softmac-snapshot.tar.bz2
at http://softmac.sipsolutions.net/SoftMAC,
page also says "Projects using this layer: * Broadcom 43xx driver"
but Broadcom driver page at ftp://ftp.berlios.de/pub/bcm43xx/snapshots/softmac/
has ftp://ftp.berlios.de/pub/bcm43xx/snapshots/softmac/ieee80211softmac-20060107.tar.bz2
which is not the same. For example, ieee80211softmac.h file exists in both
tarballs but is not identical.
Suppose one wants to use softmac in a project. What tarball contains
the bleeding edge of softmac?
> I'll move that content to the netdev wiki if anyone else thinks it would
> be a good way forward to start with requirements, API issues and
> similar.
>
> Until we get there, we'll fix up softmac to make it usable for most
> people in basic station mode without any kind of virtual devices, which
> will need some slight changes to the current ieee80211.
--
vda
^ permalink raw reply
* [RFC: 2.6 patch] net/ipv4/ip_output.c: make ip_fragment() static
From: Adrian Bunk @ 2006-01-07 18:15 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
Since there's no longer any external user of ip_fragment() we can make
it static.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
include/net/ip.h | 1 -
net/ipv4/ip_output.c | 5 +++--
2 files changed, 3 insertions(+), 3 deletions(-)
--- linux-2.6.15-mm2-full/include/net/ip.h.old 2006-01-07 17:12:04.000000000 +0100
+++ linux-2.6.15-mm2-full/include/net/ip.h 2006-01-07 17:12:11.000000000 +0100
@@ -95,7 +95,6 @@
extern int ip_mr_input(struct sk_buff *skb);
extern int ip_output(struct sk_buff *skb);
extern int ip_mc_output(struct sk_buff *skb);
-extern int ip_fragment(struct sk_buff *skb, int (*out)(struct sk_buff*));
extern int ip_do_nat(struct sk_buff *skb);
extern void ip_send_check(struct iphdr *ip);
extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok);
--- linux-2.6.15-mm2-full/net/ipv4/ip_output.c.old 2006-01-07 17:12:21.000000000 +0100
+++ linux-2.6.15-mm2-full/net/ipv4/ip_output.c 2006-01-07 17:21:33.000000000 +0100
@@ -85,6 +85,8 @@
int sysctl_ip_default_ttl = IPDEFTTL;
+static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*));
+
/* Generate a checksum for an outgoing IP datagram. */
__inline__ void ip_send_check(struct iphdr *iph)
{
@@ -409,7 +411,7 @@
* single device frame, and queue such a frame for sending.
*/
-int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
+static int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
{
struct iphdr *iph;
int raw = 0;
@@ -1391,7 +1393,6 @@
#endif
}
-EXPORT_SYMBOL(ip_fragment);
EXPORT_SYMBOL(ip_generic_getfrag);
EXPORT_SYMBOL(ip_queue_xmit);
EXPORT_SYMBOL(ip_send_check);
^ permalink raw reply
* [2.6 patch] net/ipv6/: small cleanups
From: Adrian Bunk @ 2006-01-07 18:17 UTC (permalink / raw)
To: netdev; +Cc: linux-kernel
This patch contains the following cleanups:
- addrconf.c: make addrconf_dad_stop() static
- inet6_connection_sock.c should #include <net/inet6_connection_sock.h>
for getting the prototypes of it's global functions
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
net/ipv6/addrconf.c | 2 +-
net/ipv6/inet6_connection_sock.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
--- linux-2.6.15-mm2-full/net/ipv6/addrconf.c.old 2006-01-07 17:30:04.000000000 +0100
+++ linux-2.6.15-mm2-full/net/ipv6/addrconf.c 2006-01-07 17:30:13.000000000 +0100
@@ -1228,7 +1228,7 @@
/* Gets referenced address, destroys ifaddr */
-void addrconf_dad_stop(struct inet6_ifaddr *ifp)
+static void addrconf_dad_stop(struct inet6_ifaddr *ifp)
{
if (ifp->flags&IFA_F_PERMANENT) {
spin_lock_bh(&ifp->lock);
--- linux-2.6.15-mm2-full/net/ipv6/inet6_connection_sock.c.old 2006-01-07 17:30:42.000000000 +0100
+++ linux-2.6.15-mm2-full/net/ipv6/inet6_connection_sock.c 2006-01-07 17:30:57.000000000 +0100
@@ -25,6 +25,7 @@
#include <net/inet_hashtables.h>
#include <net/ip6_route.h>
#include <net/sock.h>
+#include <net/inet6_connection_sock.h>
int inet6_csk_bind_conflict(const struct sock *sk,
const struct inet_bind_bucket *tb)
^ permalink raw reply
* Re: [PATCH, RFC] RCU : OOM avoidance and lower latency
From: Paul E. McKenney @ 2006-01-07 20:30 UTC (permalink / raw)
To: David S. Miller
Cc: dada1, ak, alan, torvalds, linux-kernel, dipankar, manfred,
netdev
In-Reply-To: <20060107.003625.50986701.davem@davemloft.net>
On Sat, Jan 07, 2006 at 12:36:25AM -0800, David S. Miller wrote:
> From: Eric Dumazet <dada1@cosmosbay.com>
> Date: Sat, 07 Jan 2006 08:53:52 +0100
>
> > I have no problem with this, since the biggest server I have is 4
> > way, but are you sure big machines wont suffer from this single
> > spinlock ?
>
> It is the main question.
>
> > Also I dont understand what you want to do after this single
> > spinlock patch. How is it supposed to help the 'ip route flush
> > cache' problem ? In my case, I have about 600.000 dst-entries :
>
> I don't claim to have a solution to this problem currently.
>
> Doing RCU and going through the whole DST GC machinery is overkill for
> an active system. So, perhaps a very simple solution will do:
>
> 1) On rt_run_flush(), do not rt_free(), instead collect all active
> routing cache entries onto a global list, begin a timer to
> fire in 10 seconds (or some sysctl configurable amount).
>
> 2) When a new routing cache entry is needed, check the global
> list appended to in #1 above first, failing that do dst_alloc()
> as is done currently.
>
> 3) If timer expires, rt_free() any entries in the global list.
>
> The missing trick is how to ensure RCU semantics when reallocating
> from the global list.
The straightforward ways of doing this require a per-entry lock in
addition to the dst_entry reference count -- lots of read-side overhead.
More complex approaches use a generation number that is incremented
when adding to or removing from the global list. When the generation
number overflows, unconditionally rt_free() it rather than adding
to the global list again. Then there needs to be some clever code
on the read side to detect the case when the generation number
changes while acquiring a reference. And memory barriers. Also
lots of read-side overhead. Also, it is now -always- necessary to
acquire a reference on the read-side.
> The idea is that an active system will immediately repopulate itself
> with all of these entries just flushed from the table.
>
> RCU really doesn't handle this kind of problem very well. It truly
> excels when work is generated by process context work, not interrupt
> work.
Sounds like a challenge to me. ;-)
Well, one possible way to attack Eric's workload might be the following:
o Size the hash table to strike the appropriate balance between
read-side search overhead and memory consumption. Call the
number of hash-chain headers N.
o Create a hashed array of locks sized to allow the update to
proceed sufficiently quickly. Call the number of locks M,
probably a power of two. This means that M CPUs can be doing
the update in parallel.
o Create an array of M^2 list headers (call it xfer[][]), but
since this is only needed during an update, it can be allocated
and deallocated if need be. (Me, with my big-server experience,
would probably just create the array, since M is not likely to
be too large. But your mileage may vary. And you really only
need M*(M-1) list headers, but that makes the index calculation
a bit more annoying.)
o Use a two-phase update. In the first phase, each updating
CPU acquires the corresponding lock and removes entries from
the corresponding partition of the hash table. If the new
location of a given entry falls into the same partition, it
is added back to the appropriate hash chain of that partition.
Otherwise, add the entry to xfer[dst][src], where "src" and
"dst" are indexes of the corresponding partitions.
o When all CPUs finish removing entries from their partition,
they check into a barrier. Once all have checked in, they
can start the second phase of the update.
o In the second phase, each CPU removes the entries from the
xfer array that are destined for its partition and adds them
to the hash chain that they are destined for.
Some commentary and variations, in the hope that this inspires someone
to come up with an even better idea:
o Unless M is at least three, there is no performance gain
over a single global lock with a single CPU doing the update,
since each element must now undergo four list operations rather
than just two.
o The xfer[][] array must have each entry cache-aligned, or
you lose big on cacheline effects. Note that it is -not-
sufficient to simply align the rows or the columns, since
each CPU has its own column when inserting and its own
row when removing from xfer[][].
o And the data-skew effects are less severe if this procedure
runs from process context. A spinning barrier must be used
otherwise. But note that the per-partition locks could remain
spinlocks, only the barrier need involve sleeping (in case
that helps, am getting a bit ahead of my understanding of
this part of the kernel).
So I half-agree with Dave -- this works better if the bulk
update is done in process context, however, updates involving
single entries being individually added and removed from the
hash table can be done from interrupt context.
o One (more complex!) way to reduce the effect of data skew to
partition the array based on the number of elements in each
partition rather than by the number of chains, but this would
require a second barrier that is completed before dropping locks
in order to avoid messing up concurrent single-element updates.
And this only handles the phase-1 data-skew effects. It is
possible to handle phase-2 data skew as well, but it takes an
up-front full-table scan and so it is not clear how it could
possibly be a performance win.
o Note that routing slows down significantly while an update is
in progress, because on average only half of the entries are
in the hash table during the update. I have no idea whether
or not this is acceptable. I am assuming that the same
mechanism that prevents two concurrent route-cache misses
from inserting two entries from the same route would also
prevent adding a new entry when one was already in the
xfer array.
Thoughts?
Thanx, Paul
^ permalink raw reply
* Re: [RFC: 2.6 patch] net/ipv4/ip_output.c: make ip_fragment() static
From: David S. Miller @ 2006-01-07 21:23 UTC (permalink / raw)
To: bunk; +Cc: netdev, linux-kernel
In-Reply-To: <20060107181533.GO3774@stusta.de>
From: Adrian Bunk <bunk@stusta.de>
Date: Sat, 7 Jan 2006 19:15:33 +0100
> Since there's no longer any external user of ip_fragment() we can make
> it static.
>
> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Works for me, applied.
Thanks.
^ permalink raw reply
* Re: [2.6 patch] net/ipv6/: small cleanups
From: David S. Miller @ 2006-01-07 21:24 UTC (permalink / raw)
To: bunk; +Cc: netdev, linux-kernel
In-Reply-To: <20060107181723.GP3774@stusta.de>
From: Adrian Bunk <bunk@stusta.de>
Date: Sat, 7 Jan 2006 19:17:23 +0100
> This patch contains the following cleanups:
> - addrconf.c: make addrconf_dad_stop() static
> - inet6_connection_sock.c should #include <net/inet6_connection_sock.h>
> for getting the prototypes of it's global functions
>
> Signed-off-by: Adrian Bunk <bunk@stusta.de>
Also applied, thanks.
^ permalink raw reply
* [RFC: 2.6 patch] kernel/posix-timers.c: remove do_posix_clock_notimer_create()
From: Adrian Bunk @ 2006-01-07 22:32 UTC (permalink / raw)
To: george; +Cc: netdev, linux-kernel
Is there any reason for this function that is neither used nor has any
real contents?
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
include/linux/posix-timers.h | 1 -
kernel/posix-timers.c | 6 ------
2 files changed, 7 deletions(-)
--- linux-2.6.15-mm2-full/include/linux/posix-timers.h.old 2006-01-07 23:13:08.000000000 +0100
+++ linux-2.6.15-mm2-full/include/linux/posix-timers.h 2006-01-07 23:13:17.000000000 +0100
@@ -84,7 +84,6 @@
void register_posix_clock(const clockid_t clock_id, struct k_clock *new_clock);
/* error handlers for timer_create, nanosleep and settime */
-int do_posix_clock_notimer_create(struct k_itimer *timer);
int do_posix_clock_nonanosleep(const clockid_t, int flags, struct timespec *,
struct timespec __user *);
int do_posix_clock_nosettime(const clockid_t, struct timespec *tp);
--- linux-2.6.15-mm2-full/kernel/posix-timers.c.old 2006-01-07 23:13:25.000000000 +0100
+++ linux-2.6.15-mm2-full/kernel/posix-timers.c 2006-01-07 23:13:30.000000000 +0100
@@ -875,12 +875,6 @@
}
EXPORT_SYMBOL_GPL(do_posix_clock_nosettime);
-int do_posix_clock_notimer_create(struct k_itimer *timer)
-{
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(do_posix_clock_notimer_create);
-
int do_posix_clock_nonanosleep(const clockid_t clock, int flags,
struct timespec *t, struct timespec __user *r)
{
^ permalink raw reply
* [W1]: Remove incorrect MODULE_ALIAS
From: Patrick McHardy @ 2006-01-07 23:44 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: Kernel Netdev Mailing List, Linux Kernel Mailing List
[-- Attachment #1: Type: text/plain, Size: 0 bytes --]
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 978 bytes --]
[W1]: Remove incorrect MODULE_ALIAS
The w1 netlink socket is created by a hardware specific driver calling
w1_add_master_device, so there is no point in including a module alias
for netlink autoloading in the core.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
commit a8657adb8c04bbe30544306ec55005a635ba65fd
tree 2c029cf104239958220629d34c76c7290bd99e43
parent b73952761225e41cb81afe157cb312a594a95693
author Patrick McHardy <kaber@trash.net> Sun, 08 Jan 2006 00:42:42 +0100
committer Patrick McHardy <kaber@trash.net> Sun, 08 Jan 2006 00:42:42 +0100
drivers/w1/w1_int.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index c3f67ea..e2920f0 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -217,5 +217,3 @@ void w1_remove_master_device(struct w1_b
EXPORT_SYMBOL(w1_add_master_device);
EXPORT_SYMBOL(w1_remove_master_device);
-
-MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_W1);
^ permalink raw reply related
* Re: (2nd try) [PATCH] corruption during e100 MDI register access
From: Jesse Brandeburg @ 2006-01-08 5:33 UTC (permalink / raw)
To: ODonnell, Michael; +Cc: bonding-devel, linux-kernel, NetDEV list
In-Reply-To: <92952AEF1F064042B6EF2522E0EEF43703225312@EXNA.corp.stratus.com>
On 1/6/06, ODonnell, Michael <Michael.ODonnell@stratus.com> wrote:
> [ 2nd transmission. Microsoft mailer "helpfully"
> reformatted the patch in the last one... :-( ]
>
> Greetings,
>
> We have identified two related bugs in the e100 driver and we request
> that they be repaired in the official Intel version of the driver.
>
> Both bugs are related to manipulation of the MDI control register.
>
> The first problem is that the Ready bit is being ignored when
> writing to the Control register; we noticed this because the Linux
> bonding driver would occasionally come to the spurious conclusion
> that the link was down when querying Link State. It turned out
> that by failing to wait for a previous command to complete it was
> selecting what was essentially a random register in the MDI register
> set. When we added code that waits for the Ready bit (as shown in
> the patch file below) all such problems ceased.
damn, you know I had seen this on one machine only, and the machine
had other problems, so i thought it wasn't e100. I can't quite figure
out why we haven't seen this more often given how long the bug appears
to have existed.
> The second problem is that, although access to the MDI registers
> involves multiple steps which must not be intermixed, nothing was
> defending against two or more threads attempting simultaneous access.
> The most obvious situation where such interference could occur
> involves the watchdog versus ioctl paths, but there are probably
> others, so we recommend the locking shown in our patch file.
Agreed, but once again I am simply amazed this has been there so long.
I think these are both good patches and I'll ack this and absorb it
for our next release. It will be a bit before its completely through
our process but its okay with me if this goes into the kernel now.
Jesse
^ permalink raw reply
* Re: [W1]: Remove incorrect MODULE_ALIAS
From: Evgeniy Polyakov @ 2006-01-08 9:40 UTC (permalink / raw)
To: Patrick McHardy
Cc: Kernel Netdev Mailing List, Linux Kernel Mailing List, GregKH
In-Reply-To: <43C0524F.1030602@trash.net>
On Sun, Jan 08, 2006 at 12:44:15AM +0100, Patrick McHardy (kaber@trash.net) wrote:
> [W1]: Remove incorrect MODULE_ALIAS
>
> The w1 netlink socket is created by a hardware specific driver calling
> w1_add_master_device, so there is no point in including a module alias
> for netlink autoloading in the core.
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
ACK.
Thanks, Patrick.
> ---
> commit a8657adb8c04bbe30544306ec55005a635ba65fd
> tree 2c029cf104239958220629d34c76c7290bd99e43
> parent b73952761225e41cb81afe157cb312a594a95693
> author Patrick McHardy <kaber@trash.net> Sun, 08 Jan 2006 00:42:42 +0100
> committer Patrick McHardy <kaber@trash.net> Sun, 08 Jan 2006 00:42:42 +0100
>
> drivers/w1/w1_int.c | 2 --
> 1 files changed, 0 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
> index c3f67ea..e2920f0 100644
> --- a/drivers/w1/w1_int.c
> +++ b/drivers/w1/w1_int.c
> @@ -217,5 +217,3 @@ void w1_remove_master_device(struct w1_b
>
> EXPORT_SYMBOL(w1_add_master_device);
> EXPORT_SYMBOL(w1_remove_master_device);
> -
> -MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_W1);
--
Evgeniy Polyakov
^ permalink raw reply
* [2.6.15] running tcpdump on 3c905b causes freeze (reproducable)
From: Folkert van Heusden @ 2006-01-08 11:43 UTC (permalink / raw)
To: akpm, netdev, linux-kernel
Hi,
My system freezes (crashes) when I run tcpdump on the interface
connected to a 3c905b card. I've tried swapping the card for an other
3c905b card but that did not help. 2 out of 3 times the last message on
the console is "Transmit error, Tx status register 82". sysreq+t doesn't
work. Not only tcpdump, any program which put the interface into
promisques mode makes the system crash. All other interfaces (eth0 and
eth2) are fine. I tried starting the system with 'debug=7' attached to
the modprobe for the module but then the system crashes with a
"vortex_error() status=0x8081".
The tcpdump-problem is reproducable, in fact: the system crashes always
when I run tcpdump on that interface.
This seems to be the only problem with that system: no other crashes or
segfaults or anything out of the ordinary.
kernel 2.6.15
3.2GHz P4, HT enabled, 2GB ram
[ 13.422920] ACPI: PCI Interrupt 0000:02:09.0[A] -> GSI 21 (level, low) -> IRQ 16
[ 13.423004] 3c59x: Donald Becker and others. www.scyld.com/network/vortex.html
[ 13.423051] 0000:02:09.0: 3Com PCI 3c905B Cyclone 100baseTx at f8882400. Vers LK1.1.19
[ 13.445519] ACPI: PCI Interrupt 0000:02:09.0[A] -> GSI 21 (level, low) -> IRQ 16
02:09.0 Ethernet controller: 3Com Corporation 3c905B 100BaseTX [Cyclone] (rev 30)
Subsystem: 3Com Corporation 3C905B Fast Etherlink XL 10/100
Flags: bus master, medium devsel, latency 64, IRQ 16
I/O ports at d880 [size=128]
Memory at feaff400 (32-bit, non-prefetchable) [size=128]
Expansion ROM at fe700000 [disabled] [size=128K]
Capabilities: [dc] Power Management version 1
00: b7 10 55 90 17 01 10 02 30 00 00 02 04 40 00 00
10: 81 d8 00 00 00 f4 af fe 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 b7 10 55 90
30: 00 00 ac fe dc 00 00 00 00 00 00 00 05 01 0a 0a
UTP connected to a switching hub
vortex-diag.c:v2.16 1/12/2004 Donald Becker (becker@scyld.com)
http://www.scyld.com/diag/index.html
Index #1: Found a 3c905B Cyclone 100baseTx adapter at 0xd880.
Station address 00:50:da:df:1d:3a.
Receive mode is 0x07: Normal unicast and all multicast.
The Vortex chip may be active, so FIFO registers will not be read.
To see all register values use the '-f' flag.
Initial window 4, registers values by window:
Window 0: 0000 0000 0000 0000 f5f5 00bf 0000 0000.
Window 1: FIFO FIFO 0000 0000 0000 0000 0000 2000.
Window 2: 5000 dfda 3a1d 0000 0000 0000 000a 4000.
Window 3: 0000 0180 05ea 0020 000a 0800 0800 6000.
Window 4: 0000 0000 0000 0cd8 0003 8880 0000 8000.
Window 5: 1ffc 0000 0000 0600 0807 06ce 06c6 a000.
Window 6: 0000 0000 0000 da00 1000 4a47 52cf c000.
Window 7: 0000 0000 0000 0000 0000 0000 0000 e000.
Vortex chip registers at 0xd880
0xD890: **FIFO** 00000000 0000001c *STATUS*
0xD8A0: 00000020 00000000 00080000 00000004
0xD8B0: 00000000 e7be1842 377a9110 00080004
0xD8C0: 008b890f 00000000 00000000 00000000
0xD8D0: 00000000 00000000 00000000 00000000
0xD8E0: 00000000 00000000 00000000 00000000
0xD8F0: 00009000 00000000 01600160 00000000
DMA control register is 00000020.
Tx list starts at 00000000.
Tx FIFO thresholds: min. burst 256 bytes, priority with 128 bytes to empty.
Rx FIFO thresholds: min. burst 256 bytes, priority with 128 bytes to full.
Poll period Tx 00 ns., Rx 0 ns.
Maximum burst recorded Tx 352, Rx 352.
Indication enable is 06c6, interrupt enable is 06ce.
No interrupt sources are pending.
Transceiver/media interfaces available: 100baseTx 10baseT.
Transceiver type in use: Autonegotiate.
MAC settings: full-duplex.
Station address set to 00:50:da:df:1d:3a.
Configuration options 000a.
EEPROM format 64x16, configuration table at offset 0:
00: 0050 dadf 1d3a 9055 002d 0036 4258 6d50
0x08: 2971 0000 0050 dadf 1d3a 0010 0000 0022
0x10: 32a2 0000 0000 0180 0000 0000 0000 10b7
0x18: 9055 000a 0000 0000 0000 0000 0000 0000
0x20: 00ea 0000 0000 0000 0000 0000 0000 0000
0x28: 0000 0000 0000 0000 0000 0000 0000 0000
...
The word-wide EEPROM checksum is 0x30f7.
Saved EEPROM settings of a 3Com Vortex/Boomerang:
3Com Node Address 00:50:DA:DF:1D:3A (used as a unique ID only).
OEM Station address 00:50:DA:DF:1D:3A (used as the ethernet address).
Device ID 9055, Manufacturer ID 6d50.
Manufacture date (MM/DD/YYYY) 1/13/2000, division 6, product XB.
No BIOS ROM is present.
Transceiver selection: Autonegotiate.
Options: negotiated duplex, link beat required.
PCI bus requested settings -- minimum grant 10, maximum latency 10 (250ns units).
PCI Subsystem IDs: Vendor 10b7 Device 9055.
100baseTx 10baseT.
Vortex format checksum is incorrect (82 vs. 10b7).
Cyclone format checksum is correct (0xea vs. 0xea).
Hurricane format checksum is correct (0xea vs. 0xea).
mii-diag.c:v2.11 3/21/2005 Donald Becker (becker@scyld.com)
http://www.scyld.com/diag/index.html
Using the new SIOCGMIIPHY value on PHY 24 (BMCR 0x3000).
The autonegotiated capability is 01e0.
The autonegotiated media type is 100baseTx-FD.
Basic mode control register 0x3000: Auto-negotiation enabled.
You have link beat, and everything is working OK.
This transceiver is capable of 100baseTx-FD 100baseTx 10baseT-FD 10baseT.
Able to perform Auto-negotiation, negotiation complete.
Your link partner advertised 45e1: Flow-control 100baseTx-FD 100baseTx 10baseT-FD 10baseT, w/ 802.3X flow control.
End of basic transceiver information.
MII PHY #24 transceiver registers:
3000 786d 0000 0000 01e1 45e1 0005 2801
0000 0000 0000 0000 0000 0000 0000 0000
8000 0afb f5ff 0000 0000 0005 2001 0000
0000 2050 0003 1c11 019a 1000 0000 0000
CPU0 CPU1
0: 39275 36446 IO-APIC-edge timer
1: 8 0 IO-APIC-edge i8042
4: 375 293 IO-APIC-edge serial
7: 0 0 IO-APIC-edge parport0
9: 0 0 IO-APIC-level acpi
12: 101 0 IO-APIC-edge i8042
14: 8133 6029 IO-APIC-edge ide0
15: 26 0 IO-APIC-edge ide1
16: 59024 10 IO-APIC-level eth0, eth1
17: 0 0 IO-APIC-level uhci_hcd:usb5
18: 294950 389876 IO-APIC-level ehci_hcd:usb1, uhci_hcd:usb8, wcfxo
19: 841 1620 IO-APIC-level ehci_hcd:usb2, bttv0
20: 13095 10832 IO-APIC-level uhci_hcd:usb3, uhci_hcd:usb6
21: 125 0 IO-APIC-level uhci_hcd:usb4
22: 76446 65337 IO-APIC-level uhci_hcd:usb7
23: 92265 73603 IO-APIC-level Intel ICH5
NMI: 0 0
LOC: 75664 75663
ERR: 0
MIS: 10
Folkert van Heusden
--
Try MultiTail! Multiple windows with logfiles, filtered with regular
expressions, colored output, etc. etc. www.vanheusden.com/multitail/
----------------------------------------------------------------------
Get your PGP/GPG key signed at www.biglumber.com!
----------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com
^ permalink raw reply
* network code assertion failed
From: CaT @ 2006-01-08 23:22 UTC (permalink / raw)
To: linux-kernel; +Cc: netdev
I've been looking through logfiles for strange things that may have
occoured whilst I was away and I spotted this:
UDP: bad checksum. From 68.56.220.203:19520 to x.x.x.x:33435 ulen 8
printk: 22 messages suppressed.
UDP: bad checksum. From 68.56.220.203:19520 to x.x.x.x:33438 ulen 8
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/core/stream.c (279)
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/ipv4/af_inet.c (148)
cdrom: open failed.
cdrom: open failed.
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/core/stream.c (279)
KERNEL: assertion (!sk->sk_forward_alloc) failed at net/ipv4/af_inet.c (148)
TCP: Treason uncloaked! Peer 61.69.94.12:60121/80 shrinks window 146488137:146489597. Repaired.
Can't really give more info on it as the messages were not logged to
syslog and so I can't check out the timing and hence check for
strangeness elsewhere. I am wondering if it would've caused the
webserver to not be able to get a listen socket as it failed during the
break though.
Kernel is 2.6.14.3.
Network part of the .config is:
CONFIG_NET=y
CONFIG_NET_KEY=y
CONFIG_INET=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
CONFIG_NETFILTER=y
CONFIG_NET_CLS_ROUTE=y
CONFIG_NETDEVICES=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_NF_QUEUE=y
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_MATCH_LIMIT=y
CONFIG_IP_NF_MATCH_IPRANGE=y
CONFIG_IP_NF_MATCH_MAC=y
CONFIG_IP_NF_MATCH_PKTTYPE=y
CONFIG_IP_NF_MATCH_MARK=y
CONFIG_IP_NF_MATCH_MULTIPORT=y
CONFIG_IP_NF_MATCH_TOS=y
CONFIG_IP_NF_MATCH_RECENT=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_DSCP=y
CONFIG_IP_NF_MATCH_AH_ESP=y
CONFIG_IP_NF_MATCH_LENGTH=y
CONFIG_IP_NF_MATCH_TTL=y
CONFIG_IP_NF_MATCH_TCPMSS=y
CONFIG_IP_NF_MATCH_OWNER=y
CONFIG_IP_NF_MATCH_ADDRTYPE=y
CONFIG_IP_NF_MATCH_REALM=y
CONFIG_IP_NF_MATCH_SCTP=y
CONFIG_IP_NF_MATCH_DCCP=y
CONFIG_IP_NF_MATCH_COMMENT=y
CONFIG_IP_NF_MATCH_HASHLIMIT=y
CONFIG_IP_NF_MATCH_STRING=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_TARGET_LOG=y
CONFIG_IP_NF_TARGET_ULOG=y
CONFIG_IP_NF_TARGET_TCPMSS=y
CONFIG_IP_NF_TARGET_NFQUEUE=y
CONFIG_IP_NF_MANGLE=y
CONFIG_IP_NF_TARGET_TOS=y
CONFIG_IP_NF_TARGET_ECN=y
CONFIG_IP_NF_TARGET_DSCP=y
CONFIG_IP_NF_TARGET_MARK=y
CONFIG_IP_NF_TARGET_CLASSIFY=y
CONFIG_IP_NF_TARGET_TTL=y
CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
There are two routing tables (created with 'ip rule add') for two interfaces
also. Both interfaces are e1000s.
--
"To the extent that we overreact, we proffer the terrorists the
greatest tribute."
- High Court Judge Michael Kirby
^ permalink raw reply
* [PATCH] net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
From: Shaun Pereira @ 2006-01-09 6:46 UTC (permalink / raw)
To: Arnd Bergmann, linux-kenel, netdev, Andi Kleen; +Cc: SP
Hi all,
The attached patch is a follow up to a post made earlier to this site
with regard to 32 bit (socket layer) ioctl emulation for 64 bit kernels.
I needed to implement 32 bit userland ioctl support for modular (x.25)
socket ioctls in a 64 bit kernel. With the removal of the
register_ioctl32_conversion() function from the kernel, one of the
suggestions made by Andi was "to just extend the socket code to add a
compat_ioctl vector to the socket options"
With Arnd's help (see previous mails with subject = 32 bit (socket
layer) ioctl emulation for 64 bit kernels) I have prepared the following
patchand tested with with x25 over tcp on a x26_64 kernel.
Since we are interested in ioctl's from userspace I have not added the
.compat_ioctl function pointer to struct net_device. The assumption
being once the userspace data has reached the kernel via the socket api,
if the socket layer protocol knows how to handle the data, it will
prepare it for the device.
Am not too sure whether struct proto requires modification. Since it is
allocated dynamically in the protocol layer I have left it alone;no
compat_ioctl. Also it seems like the socket layer would know how to
"ioctl" the transport layer, userspace does not need to know about
this?
But if any of this is incorrect and needs to be changed please advise
and I will make the changes accordingly. If this patch is accepted I
would be in a position to submit a patch for x25 (32 bit userspace
for 64 bit kernel).
Many thanks for your help
Regards
Shaun
diff -uprN -X dontdiff linux-2.6.15-vanilla/include/linux/net.h
linux-2.6.15/include/linux/net.h
--- linux-2.6.15-vanilla/include/linux/net.h 2006-01-03
14:21:10.000000000 +1100
+++ linux-2.6.15/include/linux/net.h 2006-01-09 15:59:49.000000000 +1100
@@ -143,6 +143,10 @@ struct proto_ops {
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
unsigned long arg);
+#ifdef CONFIG_COMPAT
+ int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
+ unsigned long arg);
+#endif
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
@@ -205,6 +209,7 @@ extern int kernel_recvmsg(struct
#ifndef CONFIG_SMP
#define SOCKOPS_WRAPPED(name) name
#define SOCKOPS_WRAP(name, fam)
+#define SOCKOPS_COMPAT_WRAP(name, fam)
#else
#define SOCKOPS_WRAPPED(name) __unlocked_##name
@@ -279,6 +284,60 @@ static struct proto_ops name##_ops = {
.recvmsg = __lock_##name##_recvmsg, \
.mmap = __lock_##name##_mmap, \
};
+
+#define SOCKOPS_COMPAT_WRAP(name, fam) \
+SOCKCALL_WRAP(name, release, (struct socket *sock), (sock)) \
+SOCKCALL_WRAP(name, bind, (struct socket *sock, struct sockaddr *uaddr,
int addr_len), \
+ (sock, uaddr, addr_len)) \
+SOCKCALL_WRAP(name, connect, (struct socket *sock, struct sockaddr *
uaddr, \
+ int addr_len, int flags), \
+ (sock, uaddr, addr_len, flags)) \
+SOCKCALL_WRAP(name, socketpair, (struct socket *sock1, struct socket
*sock2), \
+ (sock1, sock2)) \
+SOCKCALL_WRAP(name, accept, (struct socket *sock, struct socket
*newsock, \
+ int flags), (sock, newsock, flags)) \
+SOCKCALL_WRAP(name, getname, (struct socket *sock, struct sockaddr
*uaddr, \
+ int *addr_len, int peer), (sock, uaddr, addr_len, peer)) \
+SOCKCALL_UWRAP(name, poll, (struct file *file, struct socket *sock,
struct poll_table_struct *wait), \
+ (file, sock, wait)) \
+SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \
+ unsigned long arg), (sock, cmd, arg)) \
+SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int
cmd, \
+ unsigned long arg), (sock, cmd, arg)) \
+SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock,
len)) \
+SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock,
flags)) \
+SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int
optname, \
+ char __user *optval, int optlen), (sock, level, optname, optval,
optlen)) \
+SOCKCALL_WRAP(name, getsockopt, (struct socket *sock, int level, int
optname, \
+ char __user *optval, int __user *optlen), (sock, level, optname,
optval, optlen)) \
+SOCKCALL_WRAP(name, sendmsg, (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t len), \
+ (iocb, sock, m, len)) \
+SOCKCALL_WRAP(name, recvmsg, (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t len, int flags), \
+ (iocb, sock, m, len, flags)) \
+SOCKCALL_WRAP(name, mmap, (struct file *file, struct socket *sock,
struct vm_area_struct *vma), \
+ (file, sock, vma)) \
+ \
+static struct proto_ops name##_ops = { \
+ .family = fam, \
+ .owner = THIS_MODULE, \
+ .release = __lock_##name##_release, \
+ .bind = __lock_##name##_bind, \
+ .connect = __lock_##name##_connect, \
+ .socketpair = __lock_##name##_socketpair, \
+ .accept = __lock_##name##_accept, \
+ .getname = __lock_##name##_getname, \
+ .poll = __lock_##name##_poll, \
+ .ioctl = __lock_##name##_ioctl, \
+ .compat_ioctl = __lock_##name##_compat_ioctl, \
+ .listen = __lock_##name##_listen, \
+ .shutdown = __lock_##name##_shutdown, \
+ .setsockopt = __lock_##name##_setsockopt, \
+ .getsockopt = __lock_##name##_getsockopt, \
+ .sendmsg = __lock_##name##_sendmsg, \
+ .recvmsg = __lock_##name##_recvmsg, \
+ .mmap = __lock_##name##_mmap, \
+};
+
#endif
#define MODULE_ALIAS_NETPROTO(proto) \
diff -uprN -X dontdiff linux-2.6.15-vanilla/net/socket.c
linux-2.6.15/net/socket.c
--- linux-2.6.15-vanilla/net/socket.c 2006-01-03 14:21:10.000000000
+1100
+++ linux-2.6.15/net/socket.c 2006-01-09 15:59:49.000000000 +1100
@@ -109,6 +109,10 @@ static unsigned int sock_poll(struct fil
struct poll_table_struct *wait);
static long sock_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg);
+#endif
static int sock_fasync(int fd, struct file *filp, int on);
static ssize_t sock_readv(struct file *file, const struct iovec
*vector,
unsigned long count, loff_t *ppos);
@@ -130,6 +134,9 @@ static struct file_operations socket_fil
.aio_write = sock_aio_write,
.poll = sock_poll,
.unlocked_ioctl = sock_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = compat_sock_ioctl,
+#endif
.mmap = sock_mmap,
.open = sock_no_open, /* special open code to disallow open via /proc
*/
.release = sock_close,
@@ -2084,6 +2091,20 @@ void socket_seq_show(struct seq_file *se
}
#endif /* CONFIG_PROC_FS */
+#ifdef CONFIG_COMPAT
+static long compat_sock_ioctl(struct file *file, unsigned cmd, unsigned
long arg)
+{
+ struct socket *sock;
+ sock = file->private_data;
+
+ int ret = -ENOIOCTLCMD;
+ if(sock->ops->compat_ioctl) {
+ ret = sock->ops->compat_ioctl(sock,cmd,arg);
+ }
+ return ret;
+}
+#endif
+
/* ABI emulation layers need these two */
EXPORT_SYMBOL(move_addr_to_kernel);
EXPORT_SYMBOL(move_addr_to_user);
^ permalink raw reply
* Re: [PATCH] net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
From: Arnd Bergmann @ 2006-01-09 10:54 UTC (permalink / raw)
To: spereira; +Cc: linux-kenel, netdev, Andi Kleen, SP
In-Reply-To: <1136789216.6653.17.camel@spereira05.tusc.com.au>
On Monday 09 January 2006 06:46, Shaun Pereira wrote:
> Hi all,
> The attached patch is a follow up to a post made earlier to this site
> with regard to 32 bit (socket layer) ioctl emulation for 64 bit kernels.
Ok, cool. Note that I also posted a longer series of patches that does
this and much more. Unfortunately, I have suspended working on it for
now, so it's probably better to first get your stuff in.
> I needed to implement 32 bit userland ioctl support for modular (x.25)
> socket ioctls in a 64 bit kernel. With the removal of the
> register_ioctl32_conversion() function from the kernel, one of the
> suggestions made by Andi was "to just extend the socket code to add a
> compat_ioctl vector to the socket options"
>
> With Arnd's help (see previous mails with subject = 32 bit (socket
> layer) ioctl emulation for 64 bit kernels) I have prepared the following
> patchand tested with with x25 over tcp on a x26_64 kernel.
>
> Since we are interested in ioctl's from userspace I have not added the
> .compat_ioctl function pointer to struct net_device. The assumption
> being once the userspace data has reached the kernel via the socket api,
> if the socket layer protocol knows how to handle the data, it will
> prepare it for the device.
I think we need to have it in the long run, but if you don't need it
for x25, then it's not your call to implement net_device->compat_ioctl.
I've been thinking about how to get it right before, but did not
reach a proper conclusion, since dev_ioctl is called in so many places
that would all need to be changed for this.
> Am not too sure whether struct proto requires modification. Since it is
> allocated dynamically in the protocol layer I have left it alone;no
> compat_ioctl. Also it seems like the socket layer would know how to
> "ioctl" the transport layer, userspace does not need to know about
> this?
The proto ioctls are all forwarded from sock ioctls, so in theory
it would be needed.
> But if any of this is incorrect and needs to be changed please advise
> and I will make the changes accordingly. If this patch is accepted I
> would be in a position to submit a patch for x25 (32 bit userspace
> for 64 bit kernel).
Please post that patch now as well, just make a series out of this
socket compat_ioctl patch and your x25 patch so it becomes clear
that they depend on each other. It should be easier to justify the
infrastructure patch when there is an actual user for it ;-)
> @@ -143,6 +143,10 @@ struct proto_ops {
> struct poll_table_struct *wait);
> int (*ioctl) (struct socket *sock, unsigned int cmd,
> unsigned long arg);
> +#ifdef CONFIG_COMPAT
> + int (*compat_ioctl) (struct socket *sock, unsigned int cmd,
> + unsigned long arg);
> +#endif
> int (*listen) (struct socket *sock, int len);
> int (*shutdown) (struct socket *sock, int flags);
> int (*setsockopt)(struct socket *sock, int level,
...
> +
> +#define SOCKOPS_COMPAT_WRAP(name, fam) \
> +SOCKCALL_WRAP(name, release, (struct socket *sock), (sock)) \
> +SOCKCALL_WRAP(name, bind, (struct socket *sock, struct sockaddr *uaddr,
> int addr_len), \
> + (sock, uaddr, addr_len))
I really don't like the way you are extending the SOCKCALL_WRAP
mechanism like this. Ideally, you should convert the x25 layer to
not need SOCKOPS_WRAP at all.
Besides x25, only four other users of this remain, all others have
gotten rid of it. If you have a really good reason to keep it, it's
probably easier to add the compat_ioctl method unconditionally so
you don't need two different version of SOCKOPS_WRAP.
Making it unconditional would also help with those protocols that
have only compatible ioctl handlers and could then also point
.compat_ioctl to their native ioctl method without needing #ifdef
around it.
Arnd <><
^ permalink raw reply
* Re: [PATCH] net: 32 bit (socket layer) ioctl emulation for 64 bit kernels
From: Arnaldo Carvalho de Melo @ 2006-01-09 11:31 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: spereira, linux-kenel, netdev, Andi Kleen, SP
In-Reply-To: <200601091054.35010.arnd@arndb.de>
On 1/9/06, Arnd Bergmann <arnd@arndb.de> wrote:
> On Monday 09 January 2006 06:46, Shaun Pereira wrote:
> > Since we are interested in ioctl's from userspace I have not added the
> > .compat_ioctl function pointer to struct net_device. The assumption
> > being once the userspace data has reached the kernel via the socket api,
> > if the socket layer protocol knows how to handle the data, it will
> > prepare it for the device.
>
> I think we need to have it in the long run, but if you don't need it
> for x25, then it's not your call to implement net_device->compat_ioctl.
> I've been thinking about how to get it right before, but did not
> reach a proper conclusion, since dev_ioctl is called in so many places
> that would all need to be changed for this.
Nowadays dev_ioctl is only called from one funcion: sock_ioctl in
net/socket.c, this is after a recent changeset by hch.
- Arnaldo
^ permalink raw reply
* Re: [2.6.15] running tcpdump on 3c905b causes freeze (reproducable)
From: Andrew Morton @ 2006-01-09 12:11 UTC (permalink / raw)
To: Folkert van Heusden; +Cc: netdev, linux-kernel
In-Reply-To: <20060108114305.GA32425@vanheusden.com>
Folkert van Heusden <folkert@vanheusden.com> wrote:
>
> My system freezes (crashes) when I run tcpdump on the interface
> connected to a 3c905b card.
Works for me with a 3c980-TX. I can dig out a 905b.
Please send the exact commands which you're using to demonstrate this -
sufficient info for me to get as close as possible to what you're doing.
Have you tried enabling the NMI watchdog? Enable CONFIG_X86_LOCAL_APIC and
boot with `nmi_watchdog=1' on the command line, make sure that the NMI line
of /proc/interrupts is incrementing.
^ permalink raw reply
* Re: [2.6.15] running tcpdump on 3c905b causes freeze (reproducable)
From: Folkert van Heusden @ 2006-01-09 14:45 UTC (permalink / raw)
To: Andrew Morton; +Cc: netdev, linux-kernel
In-Reply-To: <20060109041114.6e797a9b.akpm@osdl.org>
> > My system freezes (crashes) when I run tcpdump on the interface
> > connected to a 3c905b card.
> Works for me with a 3c980-TX. I can dig out a 905b.
> Please send the exact commands which you're using to demonstrate this -
> sufficient info for me to get as close as possible to what you're doing.
The exact command is:
tcpdump -i eth1
Yes, it is that simple. Not only tcpdump gives this problem; iftop as
well.
> Have you tried enabling the NMI watchdog? Enable CONFIG_X86_LOCAL_APIC and
> boot with `nmi_watchdog=1' on the command line, make sure that the NMI line
> of /proc/interrupts is incrementing.
I'll give it a try. I've added it to the append-line in the lilo config.
Am now compiling the kernel.
Folkert van Heusden
--
Try MultiTail! Multiple windows with logfiles, filtered with regular
expressions, colored output, etc. etc. www.vanheusden.com/multitail/
----------------------------------------------------------------------
Get your PGP/GPG key signed at www.biglumber.com!
----------------------------------------------------------------------
Phone: +31-6-41278122, PGP-key: 1F28D8AE, www.vanheusden.com
^ permalink raw reply
* [patch] ipw2100: support WEXT-18 enc_capa v2
From: Dan Williams @ 2006-01-09 15:39 UTC (permalink / raw)
To: Jeff Garzik; +Cc: jketreno, netdev, ipw2100-devel
In-Reply-To: <43C282A5.6010609@pobox.com>
Hi,
This patch allows ipw2100 driver to advertise the WPA-related encryption
options that it does really support. It's necessary to work correctly
with NetworkManager and other programs that actually check driver & card
capabilities.
Signed-off-by: Dan Williams <dcbw@redhat.com>
--- ipw2100.c.nowpa 2006-01-08 14:04:00.000000000 -0500
+++ ipw2100.c 2006-01-08 15:47:37.000000000 -0500
@@ -7236,7 +7236,7 @@
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
+ range->we_version_source = 18;
// range->retry_capa; /* What retry options are supported */
// range->retry_flags; /* How to decode max/min retry limit */
@@ -7262,6 +7262,9 @@
}
range->num_frequency = val;
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
IPW_DEBUG_WX("GET Range\n");
return 0;
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
^ permalink raw reply
* Re: [patch] ipw2100: support WEXT-18 enc_capa v2
From: Jeff Garzik @ 2006-01-09 15:43 UTC (permalink / raw)
To: Dan Williams; +Cc: jketreno, netdev, ipw2100-devel
In-Reply-To: <1136821181.7941.9.camel@dhcp83-115.boston.redhat.com>
Dan Williams wrote:
> Hi,
>
> This patch allows ipw2100 driver to advertise the WPA-related encryption
> options that it does really support. It's necessary to work correctly
> with NetworkManager and other programs that actually check driver & card
> capabilities.
>
> Signed-off-by: Dan Williams <dcbw@redhat.com>
>
> --- ipw2100.c.nowpa 2006-01-08 14:04:00.000000000 -0500
> +++ ipw2100.c 2006-01-08 15:47:37.000000000 -0500
Malformed patch:
Applying 'ipw2100: support WEXT-18 enc_capa v2'
error: ipw2100.c: does not exist in index
Please resend in correct format (applies with 'patch -sp1').
Jeff
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
^ permalink raw reply
* [patch] ipw2100: support WEXT-18 enc_capa v3
From: Dan Williams @ 2006-01-09 15:54 UTC (permalink / raw)
To: Jeff Garzik; +Cc: jketreno, netdev, ipw2100-devel
In-Reply-To: <43C282A5.6010609@pobox.com>
Hi,
This patch allows ipw2100 driver to advertise the WPA-related encryption
options that it does really support. It's necessary to work correctly
with NetworkManager and other programs that actually check driver & card
capabilities.
Signed-off-by: Dan Williams <dcbw@redhat.com>
--- a/drivers/net/wireless/ipw2100.c 2006-01-08 14:04:00.000000000 -0500
+++ b/drivers/net/wireless/ipw2100.c 2006-01-08 15:47:37.000000000 -0500
@@ -7236,7 +7236,7 @@
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
+ range->we_version_source = 18;
// range->retry_capa; /* What retry options are supported */
// range->retry_flags; /* How to decode max/min retry limit */
@@ -7262,6 +7262,9 @@
}
range->num_frequency = val;
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
IPW_DEBUG_WX("GET Range\n");
return 0;
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
^ permalink raw reply
* [git patches] 2.6.x net driver updates
From: Jeff Garzik @ 2006-01-09 17:10 UTC (permalink / raw)
To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel
Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
to receive the following updates:
Documentation/networking/bonding.txt | 2
MAINTAINERS | 1
drivers/net/3c503.c | 16 +--
drivers/net/Kconfig | 4
drivers/net/ac3200.c | 16 +--
drivers/net/bonding/bonding.h | 8 -
drivers/net/e1000/e1000_param.c | 10 +-
drivers/net/e2100.c | 14 +-
drivers/net/es3210.c | 14 +-
drivers/net/forcedeth.c | 164 +++++++++++++++++++++--------------
drivers/net/gianfar.h | 4
drivers/net/hp-plus.c | 12 +-
drivers/net/hp.c | 12 +-
drivers/net/ibm_emac/ibm_emac.h | 3
drivers/net/ibm_emac/ibm_emac_core.c | 2
drivers/net/lance.c | 22 ++--
drivers/net/lne390.c | 14 +-
drivers/net/mv643xx_eth.c | 2
drivers/net/ne.c | 18 +--
drivers/net/ne2.c | 16 +--
drivers/net/sk98lin/skge.c | 129 ++++++++++++++++-----------
drivers/net/smc-ultra.c | 24 ++---
drivers/net/tulip/tulip_core.c | 2
drivers/net/wd.c | 14 +-
drivers/net/wireless/ipw2100.c | 5 -
net/ieee80211/ieee80211_crypt_wep.c | 61 +++++++++----
net/ieee80211/ieee80211_tx.c | 2
net/ieee80211/ieee80211_wx.c | 2
28 files changed, 341 insertions(+), 252 deletions(-)
Adrian Bunk:
drivers/net/Kconfig: indentation fix
drivers/net/bonding/bonding.h: "extern inline" -> "static inline"
drivers/net/gianfar.h: "extern inline" -> "static inline"
Ayaz Abdulla:
forcedeth: TSO fix for large buffers
Christoph Dworzak:
tulip: enable multiport NIC BIOS fixups for x86_64
Dan Williams:
[patch] ipw2100: support WEXT-18 enc_capa v3
Denis Vlasenko:
fix a few "warning: 'cleanup_card' defined but not used"
Eric Paris:
update bonding.txt to not show ip address on slaves
Eugene Surovegin:
PPC44x EMAC driver: disable TX status deferral in half-duplex mode
Franck:
Add MIPS dependency for dm9000 driver
Johannes Berg:
ieee80211: enable hw wep where host has to build IV
Kenji Kaneshige:
e1000: Fix invalid memory reference
Olaf Hering:
remove bouncing mail address of mv643xx_eth maintainer
Stephen Hemminger:
sk98lin: routine called from probe marked __init
sk98lin: not doing high dma properly
sk98lin: error handling on dual port board
sk98lin: use kzalloc
sk98lin: error handling on probe
sk98lin: error handling of pci setup
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index b0fe41d..8d8b4e5 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -945,7 +945,6 @@ bond0 Link encap:Ethernet HWaddr 00
collisions:0 txqueuelen:0
eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
- inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0
TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0
@@ -953,7 +952,6 @@ eth0 Link encap:Ethernet HWaddr 00
Interrupt:10 Base address:0x1080
eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
- inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0
TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0
diff --git a/MAINTAINERS b/MAINTAINERS
index 76dc820..270e28c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1697,7 +1697,6 @@ S: Maintained
MARVELL MV64340 ETHERNET DRIVER
P: Manish Lachwani
-M: Manish_Lachwani@pmc-sierra.com
L: linux-mips@linux-mips.org
L: netdev@vger.kernel.org
S: Supported
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index 5c5eebd..dcc98af 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -148,14 +148,6 @@ el2_pio_probe(struct net_device *dev)
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: el2_close() handles free_irq */
- release_region(dev->base_addr, EL2_IO_EXTENT);
- if (ei_status.mem)
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init el2_probe(int unit)
{
@@ -726,6 +718,14 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ /* NB: el2_close() handles free_irq */
+ release_region(dev->base_addr, EL2_IO_EXTENT);
+ if (ei_status.mem)
+ iounmap(ei_status.mem);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1960961..733bc25 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -129,7 +129,7 @@ config NET_SB1000
If you don't have this card, of course say N.
- source "drivers/net/arcnet/Kconfig"
+source "drivers/net/arcnet/Kconfig"
source "drivers/net/phy/Kconfig"
@@ -844,7 +844,7 @@ config SMC9194
config DM9000
tristate "DM9000 support"
- depends on ARM && NET_ETHERNET
+ depends on (ARM || MIPS) && NET_ETHERNET
select CRC32
select MII
---help---
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 8a0af54..7952dc6 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -123,14 +123,6 @@ static int __init do_ac3200_probe(struct
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- /* Someday free_irq may be in ac_close_card() */
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, AC_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init ac3200_probe(int unit)
{
@@ -406,6 +398,14 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ /* Someday free_irq may be in ac_close_card() */
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, AC_IO_EXTENT);
+ iounmap(ei_status.mem);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 015c7f1..f20bb85 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -205,7 +205,7 @@ struct bonding {
*
* Caller must hold bond lock for read
*/
-extern inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
+static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct net_device *slave_dev)
{
struct slave *slave = NULL;
int i;
@@ -219,7 +219,7 @@ extern inline struct slave *bond_get_sla
return slave;
}
-extern inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
+static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
{
if (!slave || !slave->dev->master) {
return NULL;
@@ -228,13 +228,13 @@ extern inline struct bonding *bond_get_b
return (struct bonding *)slave->dev->master->priv;
}
-extern inline void bond_set_slave_inactive_flags(struct slave *slave)
+static inline void bond_set_slave_inactive_flags(struct slave *slave)
{
slave->state = BOND_STATE_BACKUP;
slave->dev->flags |= IFF_NOARP;
}
-extern inline void bond_set_slave_active_flags(struct slave *slave)
+static inline void bond_set_slave_active_flags(struct slave *slave)
{
slave->state = BOND_STATE_ACTIVE;
slave->dev->flags &= ~IFF_NOARP;
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 38695d5..ccbbe5a 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -545,7 +545,7 @@ e1000_check_fiber_options(struct e1000_a
static void __devinit
e1000_check_copper_options(struct e1000_adapter *adapter)
{
- int speed, dplx;
+ int speed, dplx, an;
int bd = adapter->bd_number;
{ /* Speed */
@@ -641,8 +641,12 @@ e1000_check_copper_options(struct e1000_
.p = an_list }}
};
- int an = AutoNeg[bd];
- e1000_validate_option(&an, &opt, adapter);
+ if (num_AutoNeg > bd) {
+ an = AutoNeg[bd];
+ e1000_validate_option(&an, &opt, adapter);
+ } else {
+ an = opt.def;
+ }
adapter->hw.autoneg_advertised = an;
}
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index f5a4dd7..e5c5cd2 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -140,13 +140,6 @@ static int __init do_e2100_probe(struct
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: e21_close() handles free_irq */
- iounmap(ei_status.mem);
- release_region(dev->base_addr, E21_IO_EXTENT);
-}
-
#ifndef MODULE
struct net_device * __init e2100_probe(int unit)
{
@@ -463,6 +456,13 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ /* NB: e21_close() handles free_irq */
+ iounmap(ei_status.mem);
+ release_region(dev->base_addr, E21_IO_EXTENT);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/es3210.c b/drivers/net/es3210.c
index 50f8e23..6b0ab1e 100644
--- a/drivers/net/es3210.c
+++ b/drivers/net/es3210.c
@@ -155,13 +155,6 @@ static int __init do_es_probe(struct net
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, ES_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init es_probe(int unit)
{
@@ -456,6 +449,13 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, ES_IO_EXTENT);
+ iounmap(ei_status.mem);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index c39344a..3682ec6 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -101,6 +101,7 @@
* 0.46: 20 Oct 2005: Add irq optimization modes.
* 0.47: 26 Oct 2005: Add phyaddr 0 in phy scan.
* 0.48: 24 Dec 2005: Disable TSO, bugfix for pci_map_single
+ * 0.49: 10 Dec 2005: Fix tso for large buffers.
*
* Known bugs:
* We suspect that on some hardware no TX done interrupts are generated.
@@ -112,7 +113,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.48"
+#define FORCEDETH_VERSION "0.49"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -349,6 +350,8 @@ typedef union _ring_type {
#define NV_TX2_VALID (1<<31)
#define NV_TX2_TSO (1<<28)
#define NV_TX2_TSO_SHIFT 14
+#define NV_TX2_TSO_MAX_SHIFT 14
+#define NV_TX2_TSO_MAX_SIZE (1<<NV_TX2_TSO_MAX_SHIFT)
#define NV_TX2_CHECKSUM_L3 (1<<27)
#define NV_TX2_CHECKSUM_L4 (1<<26)
@@ -408,15 +411,15 @@ typedef union _ring_type {
#define NV_WATCHDOG_TIMEO (5*HZ)
#define RX_RING 128
-#define TX_RING 64
+#define TX_RING 256
/*
* If your nic mysteriously hangs then try to reduce the limits
* to 1/0: It might be required to set NV_TX_LASTPACKET in the
* last valid ring entry. But this would be impossible to
* implement - probably a disassembly error.
*/
-#define TX_LIMIT_STOP 63
-#define TX_LIMIT_START 62
+#define TX_LIMIT_STOP 255
+#define TX_LIMIT_START 254
/* rx/tx mac addr + type + vlan + align + slack*/
#define NV_RX_HEADERS (64)
@@ -535,6 +538,7 @@ struct fe_priv {
unsigned int next_tx, nic_tx;
struct sk_buff *tx_skbuff[TX_RING];
dma_addr_t tx_dma[TX_RING];
+ unsigned int tx_dma_len[TX_RING];
u32 tx_flags;
};
@@ -935,6 +939,7 @@ static void nv_init_tx(struct net_device
else
np->tx_ring.ex[i].FlagLen = 0;
np->tx_skbuff[i] = NULL;
+ np->tx_dma[i] = 0;
}
}
@@ -945,30 +950,27 @@ static int nv_init_ring(struct net_devic
return nv_alloc_rx(dev);
}
-static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
+static int nv_release_txskb(struct net_device *dev, unsigned int skbnr)
{
struct fe_priv *np = netdev_priv(dev);
- struct sk_buff *skb = np->tx_skbuff[skbnr];
- unsigned int j, entry, fragments;
-
- dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
- dev->name, skbnr, np->tx_skbuff[skbnr]);
-
- entry = skbnr;
- if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
- for (j = fragments; j >= 1; j--) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
- pci_unmap_page(np->pci_dev, np->tx_dma[entry],
- frag->size,
- PCI_DMA_TODEVICE);
- entry = (entry - 1) % TX_RING;
- }
+
+ dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d\n",
+ dev->name, skbnr);
+
+ if (np->tx_dma[skbnr]) {
+ pci_unmap_page(np->pci_dev, np->tx_dma[skbnr],
+ np->tx_dma_len[skbnr],
+ PCI_DMA_TODEVICE);
+ np->tx_dma[skbnr] = 0;
+ }
+
+ if (np->tx_skbuff[skbnr]) {
+ dev_kfree_skb_irq(np->tx_skbuff[skbnr]);
+ np->tx_skbuff[skbnr] = NULL;
+ return 1;
+ } else {
+ return 0;
}
- pci_unmap_single(np->pci_dev, np->tx_dma[entry],
- skb->len - skb->data_len,
- PCI_DMA_TODEVICE);
- dev_kfree_skb_irq(skb);
- np->tx_skbuff[skbnr] = NULL;
}
static void nv_drain_tx(struct net_device *dev)
@@ -981,10 +983,8 @@ static void nv_drain_tx(struct net_devic
np->tx_ring.orig[i].FlagLen = 0;
else
np->tx_ring.ex[i].FlagLen = 0;
- if (np->tx_skbuff[i]) {
- nv_release_txskb(dev, i);
+ if (nv_release_txskb(dev, i))
np->stats.tx_dropped++;
- }
}
}
@@ -1021,68 +1021,105 @@ static void drain_ring(struct net_device
static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct fe_priv *np = netdev_priv(dev);
+ u32 tx_flags = 0;
u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
unsigned int fragments = skb_shinfo(skb)->nr_frags;
- unsigned int nr = (np->next_tx + fragments) % TX_RING;
+ unsigned int nr = (np->next_tx - 1) % TX_RING;
+ unsigned int start_nr = np->next_tx % TX_RING;
unsigned int i;
+ u32 offset = 0;
+ u32 bcnt;
+ u32 size = skb->len-skb->data_len;
+ u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
+
+ /* add fragments to entries count */
+ for (i = 0; i < fragments; i++) {
+ entries += (skb_shinfo(skb)->frags[i].size >> NV_TX2_TSO_MAX_SHIFT) +
+ ((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
+ }
spin_lock_irq(&np->lock);
- if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
+ if ((np->next_tx - np->nic_tx + entries - 1) > TX_LIMIT_STOP) {
spin_unlock_irq(&np->lock);
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
}
- np->tx_skbuff[nr] = skb;
-
- if (fragments) {
- dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
- /* setup descriptors in reverse order */
- for (i = fragments; i >= 1; i--) {
- skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
- np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
- PCI_DMA_TODEVICE);
+ /* setup the header buffer */
+ do {
+ bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
+ nr = (nr + 1) % TX_RING;
+
+ np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data + offset, bcnt,
+ PCI_DMA_TODEVICE);
+ np->tx_dma_len[nr] = bcnt;
+
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+ np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
+ } else {
+ np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
+ np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
+ }
+ tx_flags = np->tx_flags;
+ offset += bcnt;
+ size -= bcnt;
+ } while(size);
+
+ /* setup the fragments */
+ for (i = 0; i < fragments; i++) {
+ skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ u32 size = frag->size;
+ offset = 0;
+
+ do {
+ bcnt = (size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : size;
+ nr = (nr + 1) % TX_RING;
+
+ np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset+offset, bcnt,
+ PCI_DMA_TODEVICE);
+ np->tx_dma_len[nr] = bcnt;
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
- np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ np->tx_ring.orig[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
} else {
np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
- np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+ np->tx_ring.ex[nr].FlagLen = cpu_to_le32((bcnt-1) | tx_flags);
}
-
- nr = (nr - 1) % TX_RING;
+ offset += bcnt;
+ size -= bcnt;
+ } while (size);
+ }
- if (np->desc_ver == DESC_VER_1)
- tx_flags_extra &= ~NV_TX_LASTPACKET;
- else
- tx_flags_extra &= ~NV_TX2_LASTPACKET;
- }
+ /* set last fragment flag */
+ if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+ np->tx_ring.orig[nr].FlagLen |= cpu_to_le32(tx_flags_extra);
+ } else {
+ np->tx_ring.ex[nr].FlagLen |= cpu_to_le32(tx_flags_extra);
}
+ np->tx_skbuff[nr] = skb;
+
#ifdef NETIF_F_TSO
if (skb_shinfo(skb)->tso_size)
- tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
+ tx_flags_extra = NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
else
#endif
- tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+ tx_flags_extra = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
- np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
- PCI_DMA_TODEVICE);
-
+ /* set tx flags */
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
- np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
- np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ np->tx_ring.orig[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra);
} else {
- np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
- np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
- np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+ np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra);
}
- dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
- dev->name, np->next_tx, tx_flags_extra);
+ dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n",
+ dev->name, np->next_tx, entries, tx_flags_extra);
{
int j;
for (j=0; j<64; j++) {
@@ -1093,7 +1130,7 @@ static int nv_start_xmit(struct sk_buff
dprintk("\n");
}
- np->next_tx += 1 + fragments;
+ np->next_tx += entries;
dev->trans_start = jiffies;
spin_unlock_irq(&np->lock);
@@ -1140,7 +1177,6 @@ static void nv_tx_done(struct net_device
np->stats.tx_packets++;
np->stats.tx_bytes += skb->len;
}
- nv_release_txskb(dev, i);
}
} else {
if (Flags & NV_TX2_LASTPACKET) {
@@ -1156,9 +1192,9 @@ static void nv_tx_done(struct net_device
np->stats.tx_packets++;
np->stats.tx_bytes += skb->len;
}
- nv_release_txskb(dev, i);
}
}
+ nv_release_txskb(dev, i);
np->nic_tx++;
}
if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@@ -2456,7 +2492,7 @@ static int __devinit nv_probe(struct pci
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
#ifdef NETIF_F_TSO
- /* disabled dev->features |= NETIF_F_TSO; */
+ dev->features |= NETIF_F_TSO;
#endif
}
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 94a91da..cb9d66a 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -718,14 +718,14 @@ struct gfar_private {
uint32_t msg_enable;
};
-extern inline u32 gfar_read(volatile unsigned *addr)
+static inline u32 gfar_read(volatile unsigned *addr)
{
u32 val;
val = in_be32(addr);
return val;
}
-extern inline void gfar_write(volatile unsigned *addr, u32 val)
+static inline void gfar_write(volatile unsigned *addr, u32 val)
{
out_be32(addr, val);
}
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index 0abf5dd..74e167e 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -138,12 +138,6 @@ static int __init do_hpp_probe(struct ne
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: hpp_close() handles free_irq */
- release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
-}
-
#ifndef MODULE
struct net_device * __init hp_plus_probe(int unit)
{
@@ -473,6 +467,12 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ /* NB: hpp_close() handles free_irq */
+ release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/hp.c b/drivers/net/hp.c
index 59cf841..cf9fb36 100644
--- a/drivers/net/hp.c
+++ b/drivers/net/hp.c
@@ -102,12 +102,6 @@ static int __init do_hp_probe(struct net
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
-}
-
#ifndef MODULE
struct net_device * __init hp_probe(int unit)
{
@@ -444,6 +438,12 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/ibm_emac/ibm_emac.h b/drivers/net/ibm_emac/ibm_emac.h
index 644edbf..c2dae60 100644
--- a/drivers/net/ibm_emac/ibm_emac.h
+++ b/drivers/net/ibm_emac/ibm_emac.h
@@ -110,6 +110,7 @@ struct emac_regs {
#define EMAC_MR1_TFS_2K 0x00080000
#define EMAC_MR1_TR0_MULT 0x00008000
#define EMAC_MR1_JPSM 0x00000000
+#define EMAC_MR1_MWSW_001 0x00000000
#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR0_MULT)
#else
#define EMAC_MR1_RFS_4K 0x00180000
@@ -130,7 +131,7 @@ struct emac_regs {
(freq) <= 83 ? EMAC_MR1_OBCI_83 : \
(freq) <= 100 ? EMAC_MR1_OBCI_100 : EMAC_MR1_OBCI_100P)
#define EMAC_MR1_BASE(opb) (EMAC_MR1_TFS_2K | EMAC_MR1_TR | \
- EMAC_MR1_MWSW_001 | EMAC_MR1_OBCI(opb))
+ EMAC_MR1_OBCI(opb))
#endif
/* EMACx_TMR0 */
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c
index 1da8a66..591c586 100644
--- a/drivers/net/ibm_emac/ibm_emac_core.c
+++ b/drivers/net/ibm_emac/ibm_emac_core.c
@@ -408,7 +408,7 @@ static int emac_configure(struct ocp_ene
/* Mode register */
r = EMAC_MR1_BASE(emac_opb_mhz()) | EMAC_MR1_VLE | EMAC_MR1_IST;
if (dev->phy.duplex == DUPLEX_FULL)
- r |= EMAC_MR1_FDE;
+ r |= EMAC_MR1_FDE | EMAC_MR1_MWSW_001;
dev->stop_timeout = STOP_TIMEOUT_10;
switch (dev->phy.speed) {
case SPEED_1000:
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 1d75ca0..d1d714f 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -309,17 +309,6 @@ static void lance_tx_timeout (struct net
\f
-static void cleanup_card(struct net_device *dev)
-{
- struct lance_private *lp = dev->priv;
- if (dev->dma != 4)
- free_dma(dev->dma);
- release_region(dev->base_addr, LANCE_TOTAL_SIZE);
- kfree(lp->tx_bounce_buffs);
- kfree((void*)lp->rx_buffs);
- kfree(lp);
-}
-
#ifdef MODULE
#define MAX_CARDS 8 /* Max number of interfaces (cards) per module */
@@ -367,6 +356,17 @@ int init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ struct lance_private *lp = dev->priv;
+ if (dev->dma != 4)
+ free_dma(dev->dma);
+ release_region(dev->base_addr, LANCE_TOTAL_SIZE);
+ kfree(lp->tx_bounce_buffs);
+ kfree((void*)lp->rx_buffs);
+ kfree(lp);
+}
+
void cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 309d254..646e89f 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -145,13 +145,6 @@ static int __init do_lne390_probe(struct
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, LNE390_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init lne390_probe(int unit)
{
@@ -440,6 +433,13 @@ int init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, LNE390_IO_EXTENT);
+ iounmap(ei_status.mem);
+}
+
void cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 3cb9b3f..22c3a37 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -6,7 +6,7 @@
* Copyright (C) 2002 rabeeh@galileo.co.il
*
* Copyright (C) 2003 PMC-Sierra, Inc.,
- * written by Manish Lachwani (lachwani@pmc-sierra.com)
+ * written by Manish Lachwani
*
* Copyright (C) 2003 Ralf Baechle <ralf@linux-mips.org>
*
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 0de8fdd..94f782d 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -212,15 +212,6 @@ static int __init do_ne_probe(struct net
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
- if (idev)
- pnp_device_detach(idev);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
-}
-
#ifndef MODULE
struct net_device * __init ne_probe(int unit)
{
@@ -859,6 +850,15 @@ int init_module(void)
return -ENODEV;
}
+static void cleanup_card(struct net_device *dev)
+{
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+ if (idev)
+ pnp_device_detach(idev);
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+}
+
void cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
index 6d62ada..e6df375 100644
--- a/drivers/net/ne2.c
+++ b/drivers/net/ne2.c
@@ -278,14 +278,6 @@ static int __init do_ne2_probe(struct ne
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- mca_mark_as_unused(ei_status.priv);
- mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
- free_irq(dev->irq, dev);
- release_region(dev->base_addr, NE_IO_EXTENT);
-}
-
#ifndef MODULE
struct net_device * __init ne2_probe(int unit)
{
@@ -812,6 +804,14 @@ int init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ mca_mark_as_unused(ei_status.priv);
+ mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE_IO_EXTENT);
+}
+
void cleanup_module(void)
{
int this_dev;
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 9a76ac1..197edd7 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -282,26 +282,22 @@ SK_U32 Val) /* pointer to store the rea
* Description:
* This function initialize the PCI resources and IO
*
- * Returns: N/A
- *
+ * Returns:
+ * 0 - indicate everything worked ok.
+ * != 0 - error indication
*/
-int SkGeInitPCI(SK_AC *pAC)
+static __devinit int SkGeInitPCI(SK_AC *pAC)
{
struct SK_NET_DEVICE *dev = pAC->dev[0];
struct pci_dev *pdev = pAC->PciDev;
int retval;
- if (pci_enable_device(pdev) != 0) {
- return 1;
- }
-
dev->mem_start = pci_resource_start (pdev, 0);
pci_set_master(pdev);
- if (pci_request_regions(pdev, "sk98lin") != 0) {
- retval = 2;
- goto out_disable;
- }
+ retval = pci_request_regions(pdev, "sk98lin");
+ if (retval)
+ goto out;
#ifdef SK_BIG_ENDIAN
/*
@@ -320,9 +316,8 @@ int SkGeInitPCI(SK_AC *pAC)
* Remap the regs into kernel space.
*/
pAC->IoBase = ioremap_nocache(dev->mem_start, 0x4000);
-
- if (!pAC->IoBase){
- retval = 3;
+ if (!pAC->IoBase) {
+ retval = -EIO;
goto out_release;
}
@@ -330,8 +325,7 @@ int SkGeInitPCI(SK_AC *pAC)
out_release:
pci_release_regions(pdev);
- out_disable:
- pci_disable_device(pdev);
+ out:
return retval;
}
@@ -492,7 +486,7 @@ module_param_array(AutoSizing, charp, NU
* 0, if everything is ok
* !=0, on error
*/
-static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
+static int __devinit SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC)
{
short i;
unsigned long Flags;
@@ -529,7 +523,7 @@ SK_BOOL DualNet;
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) {
printk("HWInit (0) failed.\n");
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return(-EAGAIN);
+ return -EIO;
}
SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA);
SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA);
@@ -551,7 +545,7 @@ SK_BOOL DualNet;
if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) {
printk("sk98lin: HWInit (1) failed.\n");
spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
- return(-EAGAIN);
+ return -EIO;
}
SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO);
SkEventInit(pAC, pAC->IoBase, SK_INIT_IO);
@@ -583,20 +577,20 @@ SK_BOOL DualNet;
} else {
printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n",
pAC->GIni.GIMacsFound);
- return -EAGAIN;
+ return -EIO;
}
if (Ret) {
printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n",
dev->irq);
- return -EAGAIN;
+ return Ret;
}
pAC->AllocFlag |= SK_ALLOC_IRQ;
/* Alloc memory for this board (Mem for RxD/TxD) : */
if(!BoardAllocMem(pAC)) {
printk("No memory for descriptor rings.\n");
- return(-EAGAIN);
+ return -ENOMEM;
}
BoardInitMem(pAC);
@@ -612,7 +606,7 @@ SK_BOOL DualNet;
DualNet)) {
BoardFreeMem(pAC);
printk("sk98lin: SkGeInitAssignRamToQueues failed.\n");
- return(-EAGAIN);
+ return -EIO;
}
return (0);
@@ -633,8 +627,7 @@ SK_BOOL DualNet;
* SK_TRUE, if all memory could be allocated
* SK_FALSE, if not
*/
-static SK_BOOL BoardAllocMem(
-SK_AC *pAC)
+static __devinit SK_BOOL BoardAllocMem(SK_AC *pAC)
{
caddr_t pDescrMem; /* pointer to descriptor memory area */
size_t AllocLength; /* length of complete descriptor area */
@@ -727,8 +720,7 @@ size_t AllocLength; /* length of comple
*
* Returns: N/A
*/
-static void BoardInitMem(
-SK_AC *pAC) /* pointer to adapter context */
+static __devinit void BoardInitMem(SK_AC *pAC)
{
int i; /* loop counter */
int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/
@@ -4776,32 +4768,47 @@ static int __devinit skge_probe_one(stru
struct net_device *dev = NULL;
static int boards_found = 0;
int error = -ENODEV;
+ int using_dac = 0;
char DeviceStr[80];
if (pci_enable_device(pdev))
goto out;
/* Configure DMA attributes. */
- if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
- pci_set_dma_mask(pdev, DMA_32BIT_MASK))
- goto out_disable_device;
-
+ if (sizeof(dma_addr_t) > sizeof(u32) &&
+ !(error = pci_set_dma_mask(pdev, DMA_64BIT_MASK))) {
+ using_dac = 1;
+ error = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+ if (error < 0) {
+ printk(KERN_ERR "sk98lin %s unable to obtain 64 bit DMA "
+ "for consistent allocations\n", pci_name(pdev));
+ goto out_disable_device;
+ }
+ } else {
+ error = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (error) {
+ printk(KERN_ERR "sk98lin %s no usable DMA configuration\n",
+ pci_name(pdev));
+ goto out_disable_device;
+ }
+ }
- if ((dev = alloc_etherdev(sizeof(DEV_NET))) == NULL) {
- printk(KERN_ERR "Unable to allocate etherdev "
+ error = -ENOMEM;
+ dev = alloc_etherdev(sizeof(DEV_NET));
+ if (!dev) {
+ printk(KERN_ERR "sk98lin: unable to allocate etherdev "
"structure!\n");
goto out_disable_device;
}
pNet = netdev_priv(dev);
- pNet->pAC = kmalloc(sizeof(SK_AC), GFP_KERNEL);
+ pNet->pAC = kzalloc(sizeof(SK_AC), GFP_KERNEL);
if (!pNet->pAC) {
- printk(KERN_ERR "Unable to allocate adapter "
+ printk(KERN_ERR "sk98lin: unable to allocate adapter "
"structure!\n");
goto out_free_netdev;
}
- memset(pNet->pAC, 0, sizeof(SK_AC));
pAC = pNet->pAC;
pAC->PciDev = pdev;
@@ -4810,6 +4817,7 @@ static int __devinit skge_probe_one(stru
pAC->CheckQueue = SK_FALSE;
dev->irq = pdev->irq;
+
error = SkGeInitPCI(pAC);
if (error) {
printk(KERN_ERR "sk98lin: PCI setup failed: %i\n", error);
@@ -4844,19 +4852,25 @@ static int __devinit skge_probe_one(stru
#endif
}
+ if (using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
+
pAC->Index = boards_found++;
- if (SkGeBoardInit(dev, pAC))
+ error = SkGeBoardInit(dev, pAC);
+ if (error)
goto out_free_netdev;
/* Read Adapter name from VPD */
if (ProductStr(pAC, DeviceStr, sizeof(DeviceStr)) != 0) {
+ error = -EIO;
printk(KERN_ERR "sk98lin: Could not read VPD data.\n");
goto out_free_resources;
}
/* Register net device */
- if (register_netdev(dev)) {
+ error = register_netdev(dev);
+ if (error) {
printk(KERN_ERR "sk98lin: Could not register device.\n");
goto out_free_resources;
}
@@ -4883,15 +4897,17 @@ static int __devinit skge_probe_one(stru
boards_found++;
+ pci_set_drvdata(pdev, dev);
+
/* More then one port found */
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) {
- if ((dev = alloc_etherdev(sizeof(DEV_NET))) == 0) {
- printk(KERN_ERR "Unable to allocate etherdev "
+ dev = alloc_etherdev(sizeof(DEV_NET));
+ if (!dev) {
+ printk(KERN_ERR "sk98lin: unable to allocate etherdev "
"structure!\n");
- goto out;
+ goto single_port;
}
- pAC->dev[1] = dev;
pNet = netdev_priv(dev);
pNet->PortNr = 1;
pNet->NetNr = 1;
@@ -4920,20 +4936,28 @@ static int __devinit skge_probe_one(stru
#endif
}
- if (register_netdev(dev)) {
- printk(KERN_ERR "sk98lin: Could not register device for seconf port.\n");
+ if (using_dac)
+ dev->features |= NETIF_F_HIGHDMA;
+
+ error = register_netdev(dev);
+ if (error) {
+ printk(KERN_ERR "sk98lin: Could not register device"
+ " for second port. (%d)\n", error);
free_netdev(dev);
- pAC->dev[1] = pAC->dev[0];
- } else {
- memcpy(&dev->dev_addr,
- &pAC->Addr.Net[1].CurrentMacAddress, 6);
- memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
- printk("%s: %s\n", dev->name, DeviceStr);
- printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
+ goto single_port;
}
+
+ pAC->dev[1] = dev;
+ memcpy(&dev->dev_addr,
+ &pAC->Addr.Net[1].CurrentMacAddress, 6);
+ memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
+ printk("%s: %s\n", dev->name, DeviceStr);
+ printk(" PrefPort:B RlmtMode:Dual Check Link State\n");
}
+single_port:
+
/* Save the hardware revision */
pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) +
(pAC->GIni.GIPciHwRev & 0x0F);
@@ -4945,7 +4969,6 @@ static int __devinit skge_probe_one(stru
memset(&pAC->PnmiBackup, 0, sizeof(SK_PNMI_STRUCT_DATA));
memcpy(&pAC->PnmiBackup, &pAC->PnmiStruct, sizeof(SK_PNMI_STRUCT_DATA));
- pci_set_drvdata(pdev, dev);
return 0;
out_free_resources:
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index ba8593a..3db30cd 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -168,18 +168,6 @@ static int __init do_ultra_probe(struct
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- /* NB: ultra_close_card() does free_irq */
-#ifdef __ISAPNP__
- struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
- if (idev)
- pnp_device_detach(idev);
-#endif
- release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init ultra_probe(int unit)
{
@@ -594,6 +582,18 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ /* NB: ultra_close_card() does free_irq */
+#ifdef __ISAPNP__
+ struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+ if (idev)
+ pnp_device_detach(idev);
+#endif
+ release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT);
+ iounmap(ei_status.mem);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 125ed00..c67c912 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1564,7 +1564,7 @@ static int __devinit tulip_init_one (str
dev->dev_addr, 6);
}
#endif
-#if defined(__i386__) /* Patch up x86 BIOS bug. */
+#if defined(__i386__) || defined(__x86_64__) /* Patch up x86 BIOS bug. */
if (last_irq)
irq = last_irq;
#endif
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index b03feae..7caa8dc 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -127,13 +127,6 @@ static int __init do_wd_probe(struct net
return -ENODEV;
}
-static void cleanup_card(struct net_device *dev)
-{
- free_irq(dev->irq, dev);
- release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
- iounmap(ei_status.mem);
-}
-
#ifndef MODULE
struct net_device * __init wd_probe(int unit)
{
@@ -538,6 +531,13 @@ init_module(void)
return -ENXIO;
}
+static void cleanup_card(struct net_device *dev)
+{
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
+ iounmap(ei_status.mem);
+}
+
void
cleanup_module(void)
{
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 44cd3fc..cf05661 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -7153,7 +7153,7 @@ static int ipw2100_wx_get_range(struct n
/* Set the Wireless Extension versions */
range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
+ range->we_version_source = 18;
// range->retry_capa; /* What retry options are supported */
// range->retry_flags; /* How to decode max/min retry limit */
@@ -7184,6 +7184,9 @@ static int ipw2100_wx_get_range(struct n
IW_EVENT_CAPA_MASK(SIOCGIWAP));
range->event_capa[1] = IW_EVENT_CAPA_K_1;
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+
IPW_DEBUG_WX("GET Range\n");
return 0;
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 073aebd..f8dca31 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -75,22 +75,14 @@ static void prism2_wep_deinit(void *priv
kfree(priv);
}
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+/* Add WEP IV/key info to a frame that has at least 4 bytes of headroom */
+static int prism2_wep_build_iv(struct sk_buff *skb, int hdr_len, void *priv)
{
struct prism2_wep_data *wep = priv;
- u32 crc, klen, len;
- u8 key[WEP_KEY_LEN + 3];
- u8 *pos, *icv;
- struct scatterlist sg;
-
- if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
+ u32 klen, len;
+ u8 *pos;
+
+ if (skb_headroom(skb) < 4 || skb->len < hdr_len)
return -1;
len = skb->len - hdr_len;
@@ -112,15 +104,47 @@ static int prism2_wep_encrypt(struct sk_
}
/* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- *pos++ = key[2] = wep->iv & 0xff;
+ *pos++ = (wep->iv >> 16) & 0xff;
+ *pos++ = (wep->iv >> 8) & 0xff;
+ *pos++ = wep->iv & 0xff;
*pos++ = wep->key_idx << 6;
+ return 0;
+}
+
+/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
+ * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
+ * so the payload length increases with 8 bytes.
+ *
+ * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
+ */
+static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
+{
+ struct prism2_wep_data *wep = priv;
+ u32 crc, klen, len;
+ u8 *pos, *icv;
+ struct scatterlist sg;
+ u8 key[WEP_KEY_LEN + 3];
+
+ /* other checks are in prism2_wep_build_iv */
+ if (skb_tailroom(skb) < 4)
+ return -1;
+
+ /* add the IV to the frame */
+ if (prism2_wep_build_iv(skb, hdr_len, priv))
+ return -1;
+
+ /* Copy the IV into the first 3 bytes of the key */
+ memcpy(key, skb->data + hdr_len, 3);
+
/* Copy rest of the WEP key (the secret part) */
memcpy(key + 3, wep->key, wep->key_len);
+
+ len = skb->len - hdr_len - 4;
+ pos = skb->data + hdr_len + 4;
+ klen = 3 + wep->key_len;
- /* Append little-endian CRC32 and encrypt it to produce ICV */
+ /* Append little-endian CRC32 over only the data and encrypt it to produce ICV */
crc = ~crc32_le(~0, pos, len);
icv = skb_put(skb, 4);
icv[0] = crc;
@@ -231,6 +255,7 @@ static struct ieee80211_crypto_ops ieee8
.name = "WEP",
.init = prism2_wep_init,
.deinit = prism2_wep_deinit,
+ .build_iv = prism2_wep_build_iv,
.encrypt_mpdu = prism2_wep_encrypt,
.decrypt_mpdu = prism2_wep_decrypt,
.encrypt_msdu = NULL,
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index 445f206..e5b33c8 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -288,7 +288,7 @@ int ieee80211_xmit(struct sk_buff *skb,
/* Determine total amount of storage required for TXB packets */
bytes = skb->len + SNAP_SIZE + sizeof(u16);
- if (host_encrypt)
+ if (host_encrypt || host_build_iv)
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
IEEE80211_FCTL_PROTECTED;
else
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 181755f..406d5b9 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -284,7 +284,7 @@ int ieee80211_wx_set_encode(struct ieee8
};
int i, key, key_provided, len;
struct ieee80211_crypt_data **crypt;
- int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
+ int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
IEEE80211_DEBUG_WX("SET_ENCODE\n");
^ 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