* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: Andrey Savochkin @ 2006-06-28 16:58 UTC (permalink / raw)
To: hadi
Cc: Eric W. Biederman, Dave Hansen, Ben Greear, Daniel Lezcano,
linux-kernel, netdev, serue, clg, Andrew Morton, dev, devel, sam,
viro, Alexey Kuznetsov, Herbert Poetzl
In-Reply-To: <1151511455.5160.48.camel@jzny2>
On Wed, Jun 28, 2006 at 12:17:35PM -0400, jamal wrote:
>
> On Wed, 2006-28-06 at 18:19 +0400, Andrey Savochkin wrote:
> >
> > Seeing guestXX-eth0 interfaces by standard tools has certain attractive
> > sides. But it creates a lot of undesired side effects.
> >
>
> I apologize because i butted into the discussion without perhaps reading
> the full thread.
Your comments are quite welcome
>
> > For example, ntpd queries all network devices by the same ioctls as ifconfig,
> > and creates separate sockets bound to IP addresses of each device, which is
> > certainly not desired with namespaces.
> >
>
> Ok, so the problem is that ntp in this case runs on the host side as
yes
> opposed to the guest? This would explain why Eric is reacting vehemently
> to the suggestion.
:)
And I actually do not want to distinguish host and guest sides much.
They are namespaces in the first place.
Parent namespace may have some capabilities to manipulate its child
namespaces, like donate its own device to one of its children.
But it comes secondary to having namespace isolation borders.
In particular, because most cases of cross-namespace interaction lead to
failures of formal security models and inability to migrate
namespaces between computers.
>
> > Or more subtle question: do you want hotplug events to be generated when
> > guest0-eth0 interface comes up in the root namespace, and standard scripts
> > to try to set some IP address on this interface?..
> >
>
> yes, thats what i was thinking. Even go further and actually create
> guestxx-eth0 on the host (which results in creating eth0 on the guest)
> and other things.
This actually goes in the opposite direction to what I keep in mind.
I want to offload as much as possible of network administration work to
guests. Delegation of management is one of the motivating factors
behind covering not only sockets but devices, routes, and so on by the
namespace patches.
>
> > In my opinion, the downside of this scheme overweights possible advantages,
> > and I'm personally quite happy with running commands with switched namespace,
> > like
> > vzctl exec guest0 ip addr list
> > vzctl exec guest0 ip link set eth0 up
> > and so on.
>
> Ok, above may be good enough and doesnt require any state it seems on
> the host side.
> I got motivated when the word "migration" was mentioned. I understood it
> to be meaning that a guest may become inoperative for some reason and
> that its info will be transfered to another guest which may be local or
> even remote. In such a case, clearly one would need a protocol and the
> state of all guests sitting at the host. Maybe i am over-reaching.
Migration will work inside the kernel, so it has full access
to whatever state information it needs.
Best regards
Andrey
^ permalink raw reply
* Re: [patch 3/4] Network namespaces: IPv4 FIB/routing in namespaces
From: Daniel Lezcano @ 2006-06-28 16:56 UTC (permalink / raw)
To: Kirill Korotaev
Cc: Andrey Savochkin, linux-kernel, netdev, serue, haveblue, clg,
Andrew Morton, herbert, devel, sam, ebiederm, viro, alexey
In-Reply-To: <44A29379.6060609@sw.ru>
Kirill Korotaev wrote:
>>>>> Structures related to IPv4 rounting (FIB and routing cache)
>>>>> are made per-namespace.
>>>
>>>
>>> Hi Andrey,
>>>
>>> if the ressources are private to the namespace, how do you will
>>> handle NFS mounted before creating the network namespace ? Do you
>>> take care of that or simply assume you can't access NFS anymore ?
>>
>>
>>
>> This is a question that brings up another level of interaction between
>> networking and the rest of kernel code.
>> Solution that I use now makes the NFS communication part always run in
>> the root namespace. This is discussable, of course, but it's a far more
>> complicated matter than just device lists or routing :)
>
> if we had containers (not namespaces) then it would be also possible to
> run NFS in context of the appropriate container and thus each user could
> mount NFS itself with correct networking context.
I was asking the question because in some case, we want a lightweight
container for running applications (aka application container) who need
to share the filesystem and it will be too bad to have a network
namespace which brings isolation and prevents to implement application
containers. By the way, I agree from a point of view of a system
container, a complete network isolation is perfect.
Regards.
Daniel.
^ permalink raw reply
* Re: [RFT PATCH] pcnet32: NAPI support
From: Don Fry @ 2006-06-28 16:55 UTC (permalink / raw)
To: Lennart Sorensen; +Cc: netdev
In-Reply-To: <20060628144010.GA1446@csclub.uwaterloo.ca>
On Wed, Jun 28, 2006 at 10:40:10AM -0400, Lennart Sorensen wrote:
> On Fri, Jun 23, 2006 at 02:32:12PM -0700, Don Fry wrote:
> > This set of changes combines the work done by Len Sorensen and myself to
> > add compile time support for NAPI for the pcnet32 driver. I have tested
> > it on ia32 and ppc64 hardware with various versions of the pcnet32
> > adapter. I have also made a few changes requested by Jon Mason, but the
> > substitution of the many magic numbers in the driver is not yet done.
> >
> > If no-one encounters any problems when testing this, I will break up the
> > several changes, into proper patches and submit them next week.
>
> Well so far this is working for me. It is a somewhat different layout
> of the interrupt handler so it took me a bit of work to get the features
> I need patched in, but in the end I ended up with simpler code as a
> reesult, so I am quite happy with the new layout. The driver works on
> everything I have to try it on so far.
>
<snip>
Yes, I saw the debug statements when creating the email and was too lazy
to remove them and create a new patch. The patch needs to be broken up
into functional pieces anyway, so since it has passed all of my testing
as well, I will start on that...
>
> So yep, looks pretty good to me. Those two debug statements are my only
> comments on it.
>
> Len Sorensen
--
Don Fry
brazilnut@us.ibm.com
^ permalink raw reply
* [2.6 patch] drivers/net/irda/mcs7780.c: make struct mcs_driver static
From: Adrian Bunk @ 2006-06-28 16:54 UTC (permalink / raw)
To: Andrew Morton; +Cc: Samuel Ortiz, netdev, linux-kernel
This patch makes a needlessly global struct static.
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
This patch was already sent on:
- 22 Jun 2006
--- linux-2.6.17-mm1-full/drivers/net/irda/mcs7780.c.old 2006-06-22 00:38:41.000000000 +0200
+++ linux-2.6.17-mm1-full/drivers/net/irda/mcs7780.c 2006-06-22 00:38:50.000000000 +0200
@@ -101,7 +101,7 @@
module_param(transceiver_type, int, 0444);
MODULE_PARM_DESC(transceiver_type, "IR transceiver type, see mcs7780.h.");
-struct usb_driver mcs_driver = {
+static struct usb_driver mcs_driver = {
.name = "mcs7780",
.probe = mcs_probe,
.disconnect = mcs_disconnect,
^ permalink raw reply
* [2.6 patch] net/dccp/: possible cleanups
From: Adrian Bunk @ 2006-06-28 16:54 UTC (permalink / raw)
To: acme; +Cc: dccp, linux-kernel, netdev
This patch contains the following possible cleanups:
- sysctl.c: the Kconfig rules already disallow CONFIG_SYSCTL=n,
there's no need for an additional check
- proper extern declarations for some variables in dccp.h
- make the following needlessly global function static:
- ipv4.c: dccp_v4_checksum()
- #if 0 the following unused functions:
- ackvec.c: dccp_ackvector_print()
- ackvec.c: dccp_ackvec_print()
- output.c: dccp_send_delayed_ack()
Signed-off-by: Adrian Bunk <bunk@stusta.de>
---
net/dccp/ackvec.c | 4 ++--
net/dccp/dccp.h | 11 +++++++----
net/dccp/ipv4.c | 9 +++++----
net/dccp/output.c | 2 ++
net/dccp/sysctl.c | 11 +----------
5 files changed, 17 insertions(+), 20 deletions(-)
--- linux-2.6.17-mm2-full/net/dccp/ackvec.c.old 2006-06-27 03:39:45.000000000 +0200
+++ linux-2.6.17-mm2-full/net/dccp/ackvec.c 2006-06-27 03:40:26.000000000 +0200
@@ -320,7 +320,7 @@
return -EILSEQ;
}
-#ifdef CONFIG_IP_DCCP_DEBUG
+#if 0
void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
{
if (!dccp_debug)
@@ -346,7 +346,7 @@
av->dccpav_buf + av->dccpav_buf_head,
av->dccpav_vec_len);
}
-#endif
+#endif /* 0 */
static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
struct dccp_ackvec_record *avr)
--- linux-2.6.17-mm2-full/net/dccp/dccp.h.old 2006-06-27 03:42:17.000000000 +0200
+++ linux-2.6.17-mm2-full/net/dccp/dccp.h 2006-06-27 03:45:06.000000000 +0200
@@ -33,6 +33,13 @@
#define dccp_pr_debug_cat(format, a...)
#endif
+extern int dccp_feat_default_sequence_window;
+extern int dccp_feat_default_rx_ccid;
+extern int dccp_feat_default_tx_ccid;
+extern int dccp_feat_default_ack_ratio;
+extern int dccp_feat_default_send_ack_vector;
+extern int dccp_feat_default_send_ndp_count;
+
extern struct inet_hashinfo dccp_hashinfo;
extern atomic_t dccp_orphan_count;
@@ -119,7 +126,6 @@
extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
extern void dccp_send_ack(struct sock *sk);
-extern void dccp_send_delayed_ack(struct sock *sk);
extern void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type);
@@ -215,9 +221,6 @@
extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
int addr_len);
-extern int dccp_v4_checksum(const struct sk_buff *skb,
- const __be32 saddr, const __be32 daddr);
-
extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code);
extern void dccp_send_close(struct sock *sk, const int active);
extern int dccp_invalid_packet(struct sk_buff *skb);
--- linux-2.6.17-mm2-full/net/dccp/sysctl.c.old 2006-06-27 03:40:57.000000000 +0200
+++ linux-2.6.17-mm2-full/net/dccp/sysctl.c 2006-06-27 03:42:55.000000000 +0200
@@ -13,16 +13,7 @@
#include <linux/mm.h>
#include <linux/sysctl.h>
-#ifndef CONFIG_SYSCTL
-#error This file should not be compiled without CONFIG_SYSCTL defined
-#endif
-
-extern int dccp_feat_default_sequence_window;
-extern int dccp_feat_default_rx_ccid;
-extern int dccp_feat_default_tx_ccid;
-extern int dccp_feat_default_ack_ratio;
-extern int dccp_feat_default_send_ack_vector;
-extern int dccp_feat_default_send_ndp_count;
+#include "dccp.h"
static struct ctl_table dccp_default_table[] = {
{
--- linux-2.6.17-mm2-full/net/dccp/ipv4.c.old 2006-06-27 03:43:27.000000000 +0200
+++ linux-2.6.17-mm2-full/net/dccp/ipv4.c 2006-06-27 03:44:50.000000000 +0200
@@ -39,6 +39,9 @@
*/
static struct socket *dccp_v4_ctl_socket;
+static int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
+ const __be32 daddr);
+
static int dccp_v4_get_port(struct sock *sk, const unsigned short snum)
{
return inet_csk_get_port(&dccp_hashinfo, sk, snum,
@@ -623,8 +626,8 @@
return sk;
}
-int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
- const __be32 daddr)
+static int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
+ const __be32 daddr)
{
const struct dccp_hdr* dh = dccp_hdr(skb);
int checksum_len;
@@ -643,8 +646,6 @@
IPPROTO_DCCP, tmp);
}
-EXPORT_SYMBOL_GPL(dccp_v4_checksum);
-
static int dccp_v4_verify_checksum(struct sk_buff *skb,
const __be32 saddr, const __be32 daddr)
{
--- linux-2.6.17-mm2-full/net/dccp/output.c.old 2006-06-27 03:45:13.000000000 +0200
+++ linux-2.6.17-mm2-full/net/dccp/output.c 2006-06-27 03:45:28.000000000 +0200
@@ -484,6 +484,7 @@
EXPORT_SYMBOL_GPL(dccp_send_ack);
+#if 0
void dccp_send_delayed_ack(struct sock *sk)
{
struct inet_connection_sock *icsk = inet_csk(sk);
@@ -513,6 +514,7 @@
icsk->icsk_ack.timeout = timeout;
sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
}
+#endif /* 0 */
void dccp_send_sync(struct sock *sk, const u64 seq,
const enum dccp_pkt_type pkt_type)
^ permalink raw reply
* Re: Network namespaces a path to mergable code.
From: Eric W. Biederman @ 2006-06-28 16:51 UTC (permalink / raw)
To: Andrey Savochkin
Cc: dlezcano, linux-kernel, netdev, serue, haveblue, clg,
Andrew Morton, dev, herbert, devel, sam, viro, Alexey Kuznetsov
In-Reply-To: <20060628150605.A29274@castle.nmd.msu.ru>
Andrey Savochkin <saw@swsoft.com> writes:
> Ok, fine.
> Now I'm working on socket code.
>
> We still have a question about implicit vs explicit function parameters.
> This question becomes more important for sockets: if we want to allow to use
> sockets belonging to namespaces other than the current one, we need to do
> something about it.
There seems to be some real benefit to that. Especially for things like NFS,
that captures the context at mount time. It might as well keep the namespace
in it's socket.
> One possible option to resolve this question is to show 2 relatively short
> patches just introducing namespaces for sockets in 2 ways: with explicit
> function parameters and using implicit current context.
> Then people can compare them and vote.
> Do you think it's worth the effort?
Given that we have two strong opinions in different directions I think it
is worth the effort to resolve this.
In a slightly different vein your second patch introduced a lot
of #ifdef CONFIG_NET_NS in C files. That is something we need to look closely
at.
So I think the abstraction that we use to access per network namespace
variables needs some work if we are going to allow the ability to compile
out all of the namespace code. The explicit versus implicit lookup is just
one dimension of that problem.
>> All minor things. The typo I was referring to was a section where the
>> original iteration was on an ifp variable and you called it dev
>> without changing the rest of the code in that section.
>>
>> The only big issue was that the patch too big, and should be split
>> into a patchset for better review. One patch for the new functions,
>> and the an additional patch for each driver/subsystem hunk describing
>> why that chunk needed to be changed.
>
> I'll split the patch.
Thanks.
>> I'm still curious why many of those chunks can't use existing helper
>> functions, to be cleaned up.
>
> What helper functions are you referring to?
Basically most of the device list walker functions live in.
net/core/dev.c
I don't know if the cases you fixed could have used any of those
helper functions but it certainly has me asking that question.
A general pattern that happens in cleanups is the discovery
that code using an old interface in a problematic way really
could be done much better another way. I didn't dig enough
to see if that was the case in any of the code that you changed.
Eric
^ permalink raw reply
* Re: Please pull 'upstream' branch of wireless-2.6
From: Michael Buesch @ 2006-06-28 16:32 UTC (permalink / raw)
To: Larry Finger; +Cc: John W. Linville, netdev
In-Reply-To: <44A2A872.3050905@lwfinger.net>
On Wednesday 28 June 2006 18:04, Larry Finger wrote:
> Michael Buesch wrote:
> >
> > It appears to be an older card. There are quite some
> > special codepaths for this, I think.
>
> Yes, I bought this card before the G specifications were finalized.
Oh, very interresting. I did not know that these old cards
were pre-standard.
> For the past 12 hours, I have been printing the delay time for the cases where it took more
> than 2 passes through the loop. There have been single instances of 3 and 4 usec; otherwise the
> delay is much longer, with the largest delay at 750 usec. The long delays are always found during
> scanning, associating, and authenticating. I use WPA with wpa_supplicant.
Oh, well. Forget it all.
I remembered the code wrong.
At the moment I looked at the code and it has the opposite semantics.
It loops to wait for the READY bit to appear.
Well, I would say your old device simply takes this long
to disable and there is no bug.
Oh, well...
> One other little problem. If I do an ifdown/ifup sequence without unloading the bcm43xx module, I
> get a failure of the assert(bcm->mac_suspended >= 0) at the beginning of bcm43xx_mac_suspend.
Unrelated known bug.
I will do a patch, soon.
--
Greetings Michael.
^ permalink raw reply
* Enjoy the newest It is fully guaranteed it will help you to shoot more and more
From: Boris @ 2006-06-28 16:31 UTC (permalink / raw)
To: newbie-owner
Hi,
Prolong your ssex. You have small peeniis? How would you like a much bigger peenis? See it here: http://ihlmail.com/gal/ms
Learn to say no It will be of more use to you than to be able to read Latin A bird in the hand is worth two in the bush. For jealousy is the rage of a man: therefore he will not spare in the day of vengeance. An ounce of practice is worth a pound of precept A golden key opens all doors.
^ permalink raw reply
* RE: TOE, etc.
From: Caitlin Bestler @ 2006-06-28 16:25 UTC (permalink / raw)
To: Herbert Xu, David Miller; +Cc: jgarzik, swise, netdev
Herbert Xu wrote:
>
> Yes, however I think the same argument could be applied to TOE.
>
> With their RDMA NIC, we'll have TCP/SCTP connections that
> bypass netfilter, tc, IPsec, AF_PACKET/tcpdump and the rest
> of our stack while at the same time it is using the same IP
> address as us and deciding what packets we will or won't see.
>
The whole point of the patches that opengrid has proposed is to
allow control of these issues to remain with the kernel. That is
where the ownership of the IP address logically resides, and system
administrators will expect to be able to use one set of tools to
control what is done with a given IP address.
The bypassing is already going on with iSCSI devices and with
InfiniBand devices that use IP addresses. An RDMA/IP device just
makes it harder to ignore this problem, but the problem was already
there. SDP over IB is presented to Linux users essentially as a
TOE service. Connections are made with IP and socket semantics,
and yet there is no co-ordination on routes/netfilter/etc.
I'll state right up front that I think stateful offload, when
co-ordinated with the OS, is better than stateless offload --
especially at 10G speeds.
But for plain TCP connections there are stateless offloads
available. As a product architect I am already seeking as
many ways as possible to support stateless offload as efficiently
as possible to keep that option viable for Linux users for as
high of a rate as possible. That is why we are very interested
in exploring a hardware friendly definition of vj_netchannels.
But with RDMA things are different. There is no such thing as
stateless RDMA. It is not RDMA over TCP that requires stateful
offload, it is RDMA itself. RDMA over InfiniBand is just as
much of a stateful offload as RDMA over TCP.
It is possible to build RDMA over TCP as a service that merely
uses memory mappping services in a mysterious way but is not
integrated with the network stack at all. That is essentially
how RDMA over IB is currently working.
But I believe that integrating control over the IP address,
and the associated netfilter/routing/arp/pmtu/etc issues,
is the correct path. This logic should not be duplicated,
and its control must not be split.
^ permalink raw reply
* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: jamal @ 2006-06-28 16:17 UTC (permalink / raw)
To: Andrey Savochkin
Cc: Eric W. Biederman, Dave Hansen, Ben Greear, Daniel Lezcano,
linux-kernel, netdev, serue, clg, Andrew Morton, dev, devel, sam,
viro, Alexey Kuznetsov, Herbert Poetzl
In-Reply-To: <20060628181900.A31885@castle.nmd.msu.ru>
Andrey,
On Wed, 2006-28-06 at 18:19 +0400, Andrey Savochkin wrote:
> Hi Jamal,
>
> On Wed, Jun 28, 2006 at 09:53:23AM -0400, jamal wrote:
> >
>
> Seeing guestXX-eth0 interfaces by standard tools has certain attractive
> sides. But it creates a lot of undesired side effects.
>
I apologize because i butted into the discussion without perhaps reading
the full thread.
> For example, ntpd queries all network devices by the same ioctls as ifconfig,
> and creates separate sockets bound to IP addresses of each device, which is
> certainly not desired with namespaces.
>
Ok, so the problem is that ntp in this case runs on the host side as
opposed to the guest? This would explain why Eric is reacting vehemently
to the suggestion.
> Or more subtle question: do you want hotplug events to be generated when
> guest0-eth0 interface comes up in the root namespace, and standard scripts
> to try to set some IP address on this interface?..
>
yes, thats what i was thinking. Even go further and actually create
guestxx-eth0 on the host (which results in creating eth0 on the guest)
and other things.
> In my opinion, the downside of this scheme overweights possible advantages,
> and I'm personally quite happy with running commands with switched namespace,
> like
> vzctl exec guest0 ip addr list
> vzctl exec guest0 ip link set eth0 up
> and so on.
Ok, above may be good enough and doesnt require any state it seems on
the host side.
I got motivated when the word "migration" was mentioned. I understood it
to be meaning that a guest may become inoperative for some reason and
that its info will be transfered to another guest which may be local or
even remote. In such a case, clearly one would need a protocol and the
state of all guests sitting at the host. Maybe i am over-reaching.
cheers,
jamal
^ permalink raw reply
* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: Eric W. Biederman @ 2006-06-28 16:10 UTC (permalink / raw)
To: Herbert Poetzl
Cc: Kirill Korotaev, Daniel Lezcano, Andrey Savochkin, linux-kernel,
netdev, serue, haveblue, clg, Andrew Morton, devel, sam, viro,
Alexey Kuznetsov
In-Reply-To: <20060628141148.GA5572@MAIL.13thfloor.at>
Herbert Poetzl <herbert@13thfloor.at> writes:
>> Have a few more network interfaces for a layer 2 solution
>> is fundamental. Believing without proof and after arguments
>> to the contrary that you have not contradicted that a layer 2
>> solution is inherently slower is non-productive.
>
> assuming that it will not be slower, although it
> will now pass two network stacks and the bridging
> code is non-productive too, let's see how it goes
> but do not ignore the overhead just because it
> might simplify the implementation ...
Sure. Mostly I have set it aside because the overhead
is not horrible and it is a very specific case that
can be heavily optimized if the core infrastructure is
solid.
>> Arguing that a layer 2 only solution most prove itself on
>> guest to guest communication is also non-productive.
>>
>> So just to sink one additional nail in the coffin of the silly
>> guest to guest communication issue. For any two guests where
>> fast communication between them is really important I can run
>> an additional interface pair that requires no routing or bridging.
>> Given that the implementation of the tunnel device is essentially
>> the same as the loopback interface and that I make only one
>> trip through the network stack there will be no performance overhead.
>
> that is a good argument and I think I'm perfectly
> fine with this, given that the implementation
> allows that (i.e. the network stack can handle
> two interfaces with the same IP assigned and will
> choose the local interface over the remote one
> when the traffic will be between guests)
Yep. That exists today. The network stack prefers routes
as specific as possible.
>> Similarly for any critical guest communication to the outside world
>> I can give the guest a real network adapter.
>
> with a single MAC assigned, that is, I presume?
Yes.
>
> guess that's what this discussion is about,
> finding out the various aspects how isolation
> and/or vitrtualization can be accomplished and
> what features we consider common/useful enough
> for mainline ... for me that is still in the
> brainstorming phase, although several 'working
> prototypes' already exist. IMHO the next step
> is to collect a set of representative use cases
> and test them with each implementation, regarding
> performance, usability and practicability
I am fairly strongly convinced a layer 2 solution will
do fine. So for me it is a matter of proving that
and ensuring a good implementation.
> not necessarily, but I _know_ that the overhead
> added at layer 3 is unmeasureable, and it still
> needs to be proven that this is true for a layer
> 2 solution (which I'd actually prefer, because
> it solves the protocol _and_ setup issues)
That is a good perspective. Layer 3 is free, is layer 2 also free?
Unless the cache miss penalty is a killer layer 2 should come very
close. Of course VJ recently gave some evidence that packet processing
is dominated by cache misses.
>> >From what I have seen of layer 3 solutions it is a
>> bloody maintenance nightmare, and an inflexible mess.
>
> that is your opinion, I really doubt that you
> will have less maintenance when you apply policy
> to the guests ...
Yes and mostly of the layer 3 things that I implemented.
At a moderately fundamental level I see layer 3 implementations
being a special case that is a tangent from the rest of the
networking code. So I don't see a real synthesis with what
the rest of the networking stack is doing. Plus all of the
limitations that come with a layer 3 implementation.
> example here (just to clarify):
>
> - let's assume we have eth0 on the host and in
> guest A and B, with the following setup:
>
> eth0(H) 192.168.0.1/24
> eth0(A) 10.0.1.1/16 10.0.1.2/16
> eth0(B) 10.0.2.1/16
>
> - now what keeps guest B from jsut assigning
> 10.0.2.2/16 to eth0? you need some kind of
> mechanism to prevent that, and/or to block
> the packets using inappropriate IPs
>
> * in the first case, i.e. you prevent assigning
> certain IPs inside a guest, you get a semantic
> change in the behaviour compared to a normal
> system, but there is no additional overhead
> on the communication
>
> * in the second case, you have to maintain the
> policy mechanism and keep it in sync with the
> guest configuration (somehow), and of course
> you have to verify every communication
>
> - OTOH, if you do not care about collisions
> basically assuming the point "that's like
> a hub on a network, if there are two guests
> with the same ip, it will be trouble, but
> that's okay" then this becomes a real issue
> for providers with potentially 'evil' customers
So linux when serving as a router has strong filter capabilities.
So we can either use the strong network filtering linux already has
making work for the host administrator who has poorly behaved customers.
Or we can simply not give those poorly behaved guests CAP_NET_ADMIN,
and assign the IP address at guest startup before dropping the
capability. At which point the guest cannot misbehave.
Eric
^ permalink raw reply
* Re: Please pull 'upstream' branch of wireless-2.6
From: Larry Finger @ 2006-06-28 16:04 UTC (permalink / raw)
To: Michael Buesch; +Cc: John W. Linville, netdev
In-Reply-To: <200606281634.24160.mb@bu3sch.de>
Michael Buesch wrote:
>
> It appears to be an older card. There are quite some
> special codepaths for this, I think.
Yes, I bought this card before the G specifications were finalized.
> Well, we did not want to have the card, because at this point
> it did not make sense. We all have 4306 cards.
> But now it appears that this card seems to have some special
> things (because it is older than ours).
>
> Well, how to debug.
> We are waiting for the IRQ Reason register there.
> Actually, we are waiting for the "no IRQ pending, but READY signal"
> state. Your card does not completely (?) clear the bits after MAC
> shutdown. So very helpful would be to print out in the loop the
> value. We know, that the card generates silly IRQs, that we did
> not ask for. That may happen here, too. So it _may_ help to
> mask out unwanted IRQs before the if-check. But I would first
> like to see a log of the reason-value on each iteration until it succeeds.
First of all, I have a udelay(1) in the wait loop. I have also moved the udelay to the top of the
loop. For the past 12 hours, I have been printing the delay time for the cases where it took more
than 2 passes through the loop. There have been single instances of 3 and 4 usec; otherwise the
delay is much longer, with the largest delay at 750 usec. The long delays are always found during
scanning, associating, and authenticating. I use WPA with wpa_supplicant.
Since adding the dump of IRQ reason, every case that took more than 1 pass through the loop has had
an IRQ reason of 0x0580 for every pass in the loop. Your idea about the silly IRQ's seems to be
right. I'll let you know if I get any results that are different.
One other little problem. If I do an ifdown/ifup sequence without unloading the bcm43xx module, I
get a failure of the assert(bcm->mac_suspended >= 0) at the beginning of bcm43xx_mac_suspend.
Larry
^ permalink raw reply
* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: Eric W. Biederman @ 2006-06-28 15:36 UTC (permalink / raw)
To: Sam Vilain, Herbert Poetzl
Cc: Kirill Korotaev, Daniel Lezcano, Andrey Savochkin, linux-kernel,
netdev, serue, haveblue, clg, Andrew Morton, devel, viro,
Alexey Kuznetsov
In-Reply-To: <20060628141548.GB5572@MAIL.13thfloor.at>
Herbert Poetzl <herbert@13thfloor.at> writes:
> On Wed, Jun 28, 2006 at 06:31:05PM +1200, Sam Vilain wrote:
>> Eric W. Biederman wrote:
>> > Have a few more network interfaces for a layer 2 solution
>> > is fundamental. Believing without proof and after arguments
>> > to the contrary that you have not contradicted that a layer 2
>> > solution is inherently slower is non-productive. Arguing
>> > that a layer 2 only solution most prove itself on guest to guest
>> > communication is also non-productive.
>> >
>>
>> Yes, it does break what some people consider to be a sanity condition
>> when you don't have loopback anymore within a guest. I once experimented
>> with using 127.* addresses for per-guest loopback devices with vserver
>> to fix this, but that couldn't work without fixing glibc to not make
>> assumptions deep in the bowels of the resolver. I logged a fault with
>> gnu.org and you can guess where it went :-).
>
> this is what the lo* patches address, by providing
> the required loopback isolation and providing lo
> inside a guest (i.e. it looks and feels like a
> normal system, except that you cannot modify the
> interfaces from inside)
Ok. This is new. How do you talk between guests now?
Before those patches it was through IP addresses on the loopback interface
as I recall.
>> > With a guest with 4 IPs
>> > 10.0.0.1 192.168.0.1 172.16.0.1 127.0.0.1
>> > How do you make INADDR_ANY work with just filtering at bind time?
>> >
>>
>> It used to just bind to the first one. Don't know if it still does.
>
> no, it _alway_ binds to INADDR_ANY and checks
> against other sockets (in the same context)
> comparing the lists of assigned IPs (the subset)
>
> so all checks happen at bind/connect time and
> always against the set of IPs, only exception is
> a performance optimization we do for single IP
> guests (where INADDR_ANY gets rewritten to the
> single IP)
What is the mechanism there?
My rough extrapolation says this mechanism causes problems when
migrating between machines. In particular it sounds like
only one process can bind to *:80, even if it is only allowed
to accept connections from a subset of those IPs.
So if on another machine I bound something to *:80 and only allowed to
use a different set of IPs and then attempted to migrate it, the
migration would fail because I could not restart the application,
with all of it's layer 3 resources.
To be clear I assume when I migrate I always take my IP address or
addresses with me.
Eric
^ permalink raw reply
* Re: [RFC] Network namespaces a path to mergable code.
From: Eric W. Biederman @ 2006-06-28 15:20 UTC (permalink / raw)
To: Cedric Le Goater
Cc: Andrey Savochkin, dlezcano, linux-kernel, netdev, serue, haveblue,
Andrew Morton, dev, herbert, devel, sam, viro
In-Reply-To: <44A25802.3030006@fr.ibm.com>
Cedric Le Goater <clg@fr.ibm.com> writes:
> How that proposal differs from the initial Daniel's patchset ? how far was
> that patchset to reach a similar agreement ?
My impression is as follows. The OpenVz implementation and mine work
on the same basic principles of handling the network stack at layer 2.
We have our implementation differences but the core ideas are about the
same.
Daniels patch still had elements of layer 3 handling as I recall
and that has problems.
> OK, i wear blue socks :), but I'm not advocating a patchset more than
> another i'm just looking for a shorter path.
Besides laying the foundations. The current conversation seems to be
about understanding the implications of the network stack when
we implement a network namespace.
There is a lot to the networking stack so it takes a while.
In addition this is one part of the problem that everyone has implemented,
so we have several more opinions on how it should be done and what
needs to happen.
Eric
^ permalink raw reply
* Re: [patch 3/4] Network namespaces: IPv4 FIB/routing in namespaces
From: Eric W. Biederman @ 2006-06-28 15:05 UTC (permalink / raw)
To: Daniel Lezcano
Cc: Andrey Savochkin, linux-kernel, netdev, serue, haveblue, clg,
Andrew Morton, dev, herbert, devel, sam, viro
In-Reply-To: <44A28964.2090006@fr.ibm.com>
Daniel Lezcano <dlezcano@fr.ibm.com> writes:
> Daniel Lezcano wrote:
>> Andrey Savochkin wrote:
>>
>>> Structures related to IPv4 rounting (FIB and routing cache)
>>> are made per-namespace.
>
> Hi Andrey,
>
> if the ressources are private to the namespace, how do you will handle NFS
> mounted before creating the network namespace ?
Through the filesystem namespace. It is a weird case but it works :)
> Do you take care of that or simply assume you can't access NFS anymore ?
It is actually a noop. Unless I goofed this is basically handled by
looking at which socket NFS is using to communicate, and plucking the
namespace from there.
As I recall NFS gets the socket at mount time when it still has user
space context available.
So regardless if I implemented it correctly you can implement it that way
and always get the namespace context from whoever implemented it.
Eric
^ permalink raw reply
* Re: RDMA will be reverted
From: Steve Wise @ 2006-06-28 15:01 UTC (permalink / raw)
To: David Miller; +Cc: rolandd, netdev, akpm
In-Reply-To: <20060628.000715.95062023.davem@davemloft.net>
On Wed, 2006-06-28 at 00:07 -0700, David Miller wrote:
> Roland, there is no way in the world we would have let support for
> RDMA into the kernel tree had we seen and reviewed it on netdev. I've
> discussed this with Andrew Morton, and we'd like you to please revert
> all of the RDMA code from Linus's tree immedialtely.
>
> Folks are well aware how against RDMA and TOE type schemes the Linux
> networking developers are. So the fact that none of these RDMA
> changes went up for review on netdev strikes me as just a little bit
> more than suspicious.
>
> Please do not do this again, thank you.
Dave,
There is no support for RDMA/TCP in linux today, nor in Roland's git
tree for that matter. I have posted a patch series for RDMA/TCP core
support to lklm and netdev over the last few weeks and gone through 3
review cycles. (see "iWARP Core Changes" threads). In addition, I
posted the Ammasso RDMA driver for review as well. It also went through
3 review cycles.
Based on review feedback and lack of any serious issues, it was my
understanding that everyone was comfortable with RDMA/TCP. Nothing
underhand was going on here.
Steve.
^ permalink raw reply
* Re: Network namespaces a path to mergable code.
From: Eric W. Biederman @ 2006-06-28 14:56 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Cedric Le Goater, Sam Vilain, Andrey Savochkin, dlezcano,
linux-kernel, netdev, haveblue, Andrew Morton, dev, herbert,
devel, viro, Alexey Kuznetsov, Mark Huang
In-Reply-To: <20060628141539.GA32736@sergelap.austin.ibm.com>
"Serge E. Hallyn" <serue@us.ibm.com> writes:
> Quoting Eric W. Biederman (ebiederm@xmission.com):
>> > I think we're reaching the limits of namespaces. It would be much easier
>> > with a container id in each kernel object we want to isolate.
>>
>> Nope. Except for the fact that names are peculiar (sockets, network
>> device names, IP address, routes...) the network stack splits quite cleanly.
>>
>> I did all of this in a proof of concept mode several months ago and
>> the code is still sitting in my git tree on kernel.org. I even got
>> the generic stack reference counting fixed.
>>
>> Eric
>
> Which branch?
It should be the proof-of-concept branch. It is a development branch so the
history is ugly but the result was fairly decent.
Eric
^ permalink raw reply
* Re: TOE, etc.
From: Steve Wise @ 2006-06-28 14:54 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, jgarzik, netdev
In-Reply-To: <20060628053554.GA5928@gondor.apana.org.au>
On Wed, 2006-06-28 at 15:35 +1000, Herbert Xu wrote:
> On Tue, Jun 27, 2006 at 09:43:23PM -0700, David Miller wrote:
> >
> > Socket state, and that is one thing I don't see them doing yet.
>
> I wonder what happens when the Linux TCP stack attempts to open a
> connection to a remote host when that connection is already open
> in the RDMA NIC? For that matter what happens if a Linux application
> decides to listen on a TCP port already listened on by the RDMA
> NIC?
>
This issue would have to be handled by using seperate IP addresses for
RDMA connections vs native stack TCP.
Consider NFS-RDMA server. Through administration, it would be
configured to listen on the specific rdma ip addresses, and the native
stack tcp ip addresses and thus support both TCP and RDMA NFS
connections.
There are definitely issues with this that could be resolved via tighter
integration, but that seems to not be a goal of the linux community at
this time...
> The only saving grace is that they're only doing RDMA rather than
> arbitrary TCP. However, exactly the same infrastructure can be used
> to do arbitrary TCP should they wish to.
>
> > But we have to realize they've already been given %95 of the
> > interfaces they need to speak IP using our routes and our neighbour
> > entries.
> >
> > Right?
>
> Yes, however I think the same argument could be applied to TOE.
>
> With their RDMA NIC, we'll have TCP/SCTP connections that bypass
> netfilter, tc, IPsec, AF_PACKET/tcpdump and the rest of our stack
> while at the same time it is using the same IP address as us and
> deciding what packets we will or won't see.
>
Doesn't iSCSI have this same issue?
Steve.
^ permalink raw reply
* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: Eric W. Biederman @ 2006-06-28 14:51 UTC (permalink / raw)
To: Dave Hansen
Cc: Herbert Poetzl, Ben Greear, Daniel Lezcano, Andrey Savochkin,
linux-kernel, netdev, serue, clg, Andrew Morton, dev, devel, sam,
viro, Alexey Kuznetsov
In-Reply-To: <1151449973.24103.51.camel@localhost.localdomain>
Dave Hansen <haveblue@us.ibm.com> writes:
> On Wed, 2006-06-28 at 00:52 +0200, Herbert Poetzl wrote:
>> seriously, what I think Eric meant was that it
>> might be nice (especially for migration purposes)
>> to keep the device namespace completely virtualized
>> and not just isolated ...
>
> It might be nice, but it is probably unneeded for an initial
> implementation. In practice, a cluster doing
> checkpoint/restart/migration will already have a system in place for
> assigning unique IPs or other identifiers to each container. It could
> just as easily make sure to assign unique network device names to
> containers.
>
> The issues really only come into play when you have an unstructured set
> of machines and you want to migrate between them without having prepared
> them with any kind of unique net device names beforehand.
>
> It may look weird, but do application really *need* to see eth0 rather
> than eth858354?
Actually there is a very practical reason we don't need to preserve device
names across a migration event between machines, is the only sane thing
to do is to generate a hotplug event that says you have removed the old
interface and added a new interface.
My expectation is that during migration you will wind up with add and
remove events for all of your hardware devices. But most applications
because they do not access hardware devices directly will not care.
I haven't looked closely but I suspect this is one area where a container
style approach will be noticeably different from a Xen or Vmware style
approach.
Eric
^ permalink raw reply
* Re: RDMA will be reverted
From: Tom Tucker @ 2006-06-28 14:56 UTC (permalink / raw)
To: David Miller; +Cc: rolandd, netdev, akpm
In-Reply-To: <20060628.000715.95062023.davem@davemloft.net>
On Wed, 2006-06-28 at 00:07 -0700, David Miller wrote:
> Roland, there is no way in the world we would have let support for
> RDMA into the kernel tree had we seen and reviewed it on netdev. I've
> discussed this with Andrew Morton, and we'd like you to please revert
> all of the RDMA code from Linus's tree immedialtely.
>
> Folks are well aware how against RDMA and TOE type schemes the Linux
> networking developers are. So the fact that none of these RDMA
> changes went up for review on netdev strikes me as just a little bit
> more than suspicious.
>
> Please do not do this again, thank you.
I believe Roland is on vacation (they just had a baby..).
It is my belief that everything that Roland submitted went through both
netdev and lklm reviews.
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [patch 2/6] [Network namespace] Network device sharing by view
From: Eric W. Biederman @ 2006-06-28 14:39 UTC (permalink / raw)
To: hadi
Cc: Herbert Poetzl, Alexey Kuznetsov, viro, sam, devel, dev,
Andrew Morton, clg, serue, netdev, linux-kernel, Andrey Savochkin,
Daniel Lezcano, Ben Greear, Dave Hansen, Alexey Kuznetsov
In-Reply-To: <1151502803.5203.101.camel@jzny2>
jamal <hadi@cyberus.ca> writes:
> On Wed, 2006-28-06 at 15:36 +0200, Herbert Poetzl wrote:
>
>> note: personally I'm absolutely not against virtualizing
>> the device names so that each guest can have a separate
>> name space for devices, but there should be a way to
>> 'see' _and_ 'identify' the interfaces from outside
>> (i.e. host or spectator context)
>>
>
> Makes sense for the host side to have naming convention tied
> to the guest. Example as a prefix: guest0-eth0. Would it not
> be interesting to have the host also manage these interfaces
> via standard tools like ip or ifconfig etc? i.e if i admin up
> guest0-eth0, then the user in guest0 will see its eth0 going
> up.
>
> Anyways, interesting discussion.
Please no.
We really want the fundamental rule that a network device
is tied to a single namespace, and that a socket is tied
to a single namespace. If those two conditions are met
we don't have to tag packets with a namespace identifier.
We only have to modify hash table lookups in the networking
code to look at a namespace tag in addition to the rest because
that is less expensive than allocating new hash tables.
Currently with a network device only being usable in one
network namespace we have the situation where we can
fairly safely give a guest CAP_NET_ADMIN without problems.
In addition currently nothing in the implementation knows about
the hierarchical structure of how the network namespace will be
used. To allow ifconfig guest0-eth0 to work would require
understanding the hierarchical structure and places serious questions
on how safe we can make CAP_NET_ADMIN.
Now I am open to radically different designs if they allow the
implementation cost to be lower and they have clean semantics,
and don't wind up being an ugly unmaintainable wart on the linux
networking stack. The only route I could imagine such a thing coming
from is something like tagging flows, in some netfiler like way.
Which might allow ifconfig guest-eth0 from the host without problems.
But I have not seen such a design.
Eric
^ permalink raw reply
* Re: TOE, etc.
From: Steve Wise @ 2006-06-28 14:41 UTC (permalink / raw)
To: Herbert Xu; +Cc: David Miller, jgarzik, netdev
In-Reply-To: <20060628053554.GA5928@gondor.apana.org.au>
On Wed, 2006-06-28 at 15:35 +1000, Herbert Xu wrote:
> On Tue, Jun 27, 2006 at 09:43:23PM -0700, David Miller wrote:
> >
> > Socket state, and that is one thing I don't see them doing yet.
>
> I wonder what happens when the Linux TCP stack attempts to open a
> connection to a remote host when that connection is already open
> in the RDMA NIC? For that matter what happens if a Linux application
> decides to listen on a TCP port already listened on by the RDMA
> NIC?
>
> The only saving grace is that they're only doing RDMA rather than
> arbitrary TCP. However, exactly the same infrastructure can be used
> to do arbitrary TCP should they wish to.
>
> > But we have to realize they've already been given %95 of the
> > interfaces they need to speak IP using our routes and our neighbour
> > entries.
> >
> > Right?
>
> Yes, however I think the same argument could be applied to TOE.
>
> With their RDMA NIC, we'll have TCP/SCTP connections that bypass
> netfilter, tc, IPsec, AF_PACKET/tcpdump and the rest of our stack
> while at the same time it is using the same IP address as us and
> deciding what packets we will or won't see.
>
Doesn't iSCSI have the same issue? No netfilter, IPsec, tcpdump, etc...
^ permalink raw reply
* Re: [RFT PATCH] pcnet32: NAPI support
From: Lennart Sorensen @ 2006-06-28 14:40 UTC (permalink / raw)
To: Don Fry; +Cc: netdev
In-Reply-To: <20060623213212.GA24388@us.ibm.com>
On Fri, Jun 23, 2006 at 02:32:12PM -0700, Don Fry wrote:
> This set of changes combines the work done by Len Sorensen and myself to
> add compile time support for NAPI for the pcnet32 driver. I have tested
> it on ia32 and ppc64 hardware with various versions of the pcnet32
> adapter. I have also made a few changes requested by Jon Mason, but the
> substitution of the many magic numbers in the driver is not yet done.
>
> If no-one encounters any problems when testing this, I will break up the
> several changes, into proper patches and submit them next week.
Well so far this is working for me. It is a somewhat different layout
of the interrupt handler so it took me a bit of work to get the features
I need patched in, but in the end I ended up with simpler code as a
reesult, so I am quite happy with the new layout. The driver works on
everything I have to try it on so far.
> Signed-off-by: Don Fry <brazilnut@us.ibm.com>
>
>
> --- linux-2.6.17/drivers/net/orig.Kconfig 2006-06-15 11:49:39.000000000 -0700
> +++ linux-2.6.17/drivers/net/Kconfig 2006-06-22 15:44:52.000000000 -0700
> @@ -1272,6 +1272,23 @@ config PCNET32
> <file:Documentation/networking/net-modules.txt>. The module
> will be called pcnet32.
>
> +config PCNET32_NAPI
> + bool "Use RX polling (NAPI) (EXPERIMENTAL)"
> + depends on PCNET32 && EXPERIMENTAL
> + help
> + NAPI is a new driver API designed to reduce CPU and interrupt load
> + when the driver is receiving lots of packets from the card. It is
> + still somewhat experimental and thus not yet enabled by default.
> +
> + If your estimated Rx load is 10kpps or more, or if the card will be
> + deployed on potentially unfriendly networks (e.g. in a firewall),
> + then say Y here.
> +
> + See <file:Documentation/networking/NAPI_HOWTO.txt> for more
> + information.
> +
> + If in doubt, say N.
> +
> config AMD8111_ETH
> tristate "AMD 8111 (new PCI lance) support"
> depends on NET_PCI && PCI
>
> --- linux-2.6.17/drivers/net/orig.pcnet32.c Sat Jun 17 18:49:35 2006
> +++ linux-2.6.17/drivers/net/pcnet32.c Fri Jun 23 13:13:02 2006
> @@ -21,9 +21,15 @@
> *
> *************************************************************************/
>
> +#include <linux/config.h>
> +
> #define DRV_NAME "pcnet32"
> -#define DRV_VERSION "1.32"
> -#define DRV_RELDATE "18.Mar.2006"
> +#ifdef CONFIG_PCNET32_NAPI
> +#define DRV_VERSION "1.33-NAPI"
> +#else
> +#define DRV_VERSION "1.33"
> +#endif
> +#define DRV_RELDATE "23.Jun.2006"
> #define PFX DRV_NAME ": "
>
> static const char *const version =
> @@ -58,18 +64,15 @@ static const char *const version =
> * PCI device identifiers for "new style" Linux PCI Device Drivers
> */
> static struct pci_device_id pcnet32_pci_tbl[] = {
> - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> - { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE,
> - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
> + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE_HOME), },
> + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE), },
>
> /*
> * Adapters that were sold with IBM's RS/6000 or pSeries hardware have
> * the incorrect vendor id.
> */
> - { PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE,
> - PCI_ANY_ID, PCI_ANY_ID,
> - PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, 0},
> + { PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_AMD_LANCE),
> + .class = (PCI_CLASS_NETWORK_ETHERNET << 8), .class_mask = 0xffff00, },
>
> { } /* terminate list */
> };
> @@ -277,13 +280,14 @@ struct pcnet32_private {
> u32 phymask;
> };
>
> -static void pcnet32_probe_vlbus(void);
> static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
> static int pcnet32_probe1(unsigned long, int, struct pci_dev *);
> static int pcnet32_open(struct net_device *);
> static int pcnet32_init_ring(struct net_device *);
> static int pcnet32_start_xmit(struct sk_buff *, struct net_device *);
> -static int pcnet32_rx(struct net_device *);
> +#ifdef CONFIG_PCNET32_NAPI
> +static int pcnet32_poll(struct net_device *dev, int *budget);
> +#endif
> static void pcnet32_tx_timeout(struct net_device *dev);
> static irqreturn_t pcnet32_interrupt(int, void *, struct pt_regs *);
> static int pcnet32_close(struct net_device *);
> @@ -425,6 +429,235 @@ static struct pcnet32_access pcnet32_dwi
> .reset = pcnet32_dwio_reset
> };
>
> +static void pcnet32_netif_stop(struct net_device *dev)
> +{
> + dev->trans_start = jiffies;
> + netif_poll_disable(dev);
> + netif_tx_disable(dev);
> +}
> +
> +static void pcnet32_netif_start(struct net_device *dev)
> +{
> + netif_wake_queue(dev);
> + netif_poll_enable(dev);
> +}
> +
> +/*
> + * Allocate space for the new sized tx ring.
> + * Free old resources
> + * Save new resources.
> + * Any failure keeps old resources.
> + * Must be called with lp->lock held.
> + */
> +static void pcnet32_realloc_tx_ring(struct net_device *dev,
> + struct pcnet32_private *lp,
> + unsigned int size)
> +{
> + dma_addr_t new_ring_dma_addr;
> + dma_addr_t *new_dma_addr_list;
> + struct pcnet32_tx_head *new_tx_ring;
> + struct sk_buff **new_skb_list;
> +
> + pcnet32_purge_tx_ring(dev);
> +
> + new_tx_ring = pci_alloc_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_tx_head) *
> + (1 << size),
> + &new_ring_dma_addr);
> + if (new_tx_ring == NULL) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Consistent memory allocation failed.\n",
> + dev->name);
> + return;
> + }
> + memset(new_tx_ring, 0, sizeof(struct pcnet32_tx_head) * (1 << size));
> +
> + new_dma_addr_list = kcalloc(sizeof(dma_addr_t), (1 << size), GFP_ATOMIC);
> + if (!new_dma_addr_list) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Memory allocation failed.\n", dev->name);
> + goto free_new_tx_ring;
> + }
> +
> + new_skb_list = kcalloc(sizeof(struct sk_buff *), (1 << size), GFP_ATOMIC);
> + if (!new_skb_list) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Memory allocation failed.\n", dev->name);
> + goto free_new_lists;
> + }
> +
> + kfree(lp->tx_skbuff);
> + kfree(lp->tx_dma_addr);
> + pci_free_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_tx_head) *
> + lp->tx_ring_size, lp->tx_ring,
> + lp->tx_ring_dma_addr);
> +
> + lp->tx_ring_size = (1 << size);
> + lp->tx_mod_mask = lp->tx_ring_size - 1;
> + lp->tx_len_bits = (size << 12);
> + lp->tx_ring = new_tx_ring;
> + lp->tx_ring_dma_addr = new_ring_dma_addr;
> + lp->tx_dma_addr = new_dma_addr_list;
> + lp->tx_skbuff = new_skb_list;
> + return;
> +
> + free_new_lists:
> + kfree(new_dma_addr_list);
> + free_new_tx_ring:
> + pci_free_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_tx_head) *
> + (1 << size),
> + new_tx_ring,
> + new_ring_dma_addr);
> + return;
> +}
> +
> +/*
> + * Allocate space for the new sized rx ring.
> + * Re-use old receive buffers.
> + * alloc extra buffers
> + * free unneeded buffers
> + * free unneeded buffers
> + * Save new resources.
> + * Any failure keeps old resources.
> + * Must be called with lp->lock held.
> + */
> +static void pcnet32_realloc_rx_ring(struct net_device *dev,
> + struct pcnet32_private *lp,
> + unsigned int size)
> +{
> + dma_addr_t new_ring_dma_addr;
> + dma_addr_t *new_dma_addr_list;
> + struct pcnet32_rx_head *new_rx_ring;
> + struct sk_buff **new_skb_list;
> + int new, overlap;
> +
> + new_rx_ring = pci_alloc_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_rx_head) *
> + (1 << size),
> + &new_ring_dma_addr);
> + if (new_rx_ring == NULL) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Consistent memory allocation failed.\n",
> + dev->name);
> + return;
> + }
> + memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * (1 << size));
> +
> + new_dma_addr_list = kcalloc(sizeof(dma_addr_t), (1 << size), GFP_ATOMIC);
> + if (!new_dma_addr_list) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Memory allocation failed.\n", dev->name);
> + goto free_new_rx_ring;
> + }
> +
> + new_skb_list = kcalloc(sizeof(struct sk_buff *), (1 << size), GFP_ATOMIC);
> + if (!new_skb_list) {
> + if (pcnet32_debug & NETIF_MSG_DRV)
> + printk("\n" KERN_ERR PFX
> + "%s: Memory allocation failed.\n", dev->name);
> + goto free_new_lists;
> + }
> +
> + /* first copy the current receive buffers */
> + overlap = min(size, lp->rx_ring_size);
> + for (new = 0; new < overlap; new++) {
> + new_rx_ring[new] = lp->rx_ring[new];
> + new_dma_addr_list[new] = lp->rx_dma_addr[new];
> + new_skb_list[new] = lp->rx_skbuff[new];
> + }
> + /* now allocate any new buffers needed */
> + for (; new < size; new++ ) {
> + struct sk_buff *rx_skbuff;
> + new_skb_list[new] = dev_alloc_skb(PKT_BUF_SZ);
> + if (!(rx_skbuff = new_skb_list[new])) {
> + /* keep the original lists and buffers */
> + if (netif_msg_drv(lp))
> + printk(KERN_ERR
> + "%s: pcnet32_realloc_rx_ring dev_alloc_skb failed.\n",
> + dev->name);
> + goto free_all_new;
> + }
> + skb_reserve(rx_skbuff, 2);
> +
> + new_dma_addr_list[new] =
> + pci_map_single(lp->pci_dev, rx_skbuff->data,
> + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> + new_rx_ring[new].base = (u32) le32_to_cpu(new_dma_addr_list[new]);
> + new_rx_ring[new].buf_length = le16_to_cpu(2 - PKT_BUF_SZ);
> + new_rx_ring[new].status = le16_to_cpu(0x8000);
> + }
> + /* and free any unneeded buffers */
> + for (; new < lp->rx_ring_size; new++) {
> + if (lp->rx_skbuff[new]) {
> + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new],
> + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> + dev_kfree_skb(lp->rx_skbuff[new]);
> + }
> + }
> +
> + kfree(lp->rx_skbuff);
> + kfree(lp->rx_dma_addr);
> + pci_free_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_rx_head) *
> + lp->rx_ring_size, lp->rx_ring,
> + lp->rx_ring_dma_addr);
> +
> + lp->rx_ring_size = (1 << size);
> + lp->rx_mod_mask = lp->rx_ring_size - 1;
> + lp->rx_len_bits = (size << 4);
> + lp->rx_ring = new_rx_ring;
> + lp->rx_ring_dma_addr = new_ring_dma_addr;
> + lp->rx_dma_addr = new_dma_addr_list;
> + lp->rx_skbuff = new_skb_list;
> + return;
> +
> + free_all_new:
> + for (; --new >= lp->rx_ring_size; ) {
> + if (new_skb_list[new]) {
> + pci_unmap_single(lp->pci_dev, new_dma_addr_list[new],
> + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> + dev_kfree_skb(new_skb_list[new]);
> + }
> + }
> + kfree(new_skb_list);
> + free_new_lists:
> + kfree(new_dma_addr_list);
> + free_new_rx_ring:
> + pci_free_consistent(lp->pci_dev,
> + sizeof(struct pcnet32_rx_head) *
> + (1 << size),
> + new_rx_ring,
> + new_ring_dma_addr);
> + return;
> +}
> +
> +static void pcnet32_purge_rx_ring(struct net_device *dev)
> +{
> + struct pcnet32_private *lp = dev->priv;
> + int i;
> +
> + /* free all allocated skbuffs */
> + for (i = 0; i < lp->rx_ring_size; i++) {
> + lp->rx_ring[i].status = 0; /* CPU owns buffer */
> + wmb(); /* Make sure adapter sees owner change */
> + if (lp->rx_skbuff[i]) {
> + pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
> + PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> + dev_kfree_skb_any(lp->rx_skbuff[i]);
> + }
> + lp->rx_skbuff[i] = NULL;
> + lp->rx_dma_addr[i] = 0;
> + }
> +}
> +
> +
> #ifdef CONFIG_NET_POLL_CONTROLLER
> static void pcnet32_poll_controller(struct net_device *dev)
> {
> @@ -525,10 +758,10 @@ static void pcnet32_get_ringparam(struct
> {
> struct pcnet32_private *lp = dev->priv;
>
> - ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
> - ering->tx_pending = lp->tx_ring_size - 1;
> - ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
> - ering->rx_pending = lp->rx_ring_size - 1;
> + ering->tx_max_pending = TX_MAX_RING_SIZE;
> + ering->tx_pending = lp->tx_ring_size;
> + ering->rx_max_pending = RX_MAX_RING_SIZE;
> + ering->rx_pending = lp->rx_ring_size;
> }
>
> static int pcnet32_set_ringparam(struct net_device *dev,
> @@ -536,44 +769,44 @@ static int pcnet32_set_ringparam(struct
> {
> struct pcnet32_private *lp = dev->priv;
> unsigned long flags;
> + unsigned int size;
> + ulong ioaddr = dev->base_addr;
> int i;
>
> if (ering->rx_mini_pending || ering->rx_jumbo_pending)
> return -EINVAL;
>
> if (netif_running(dev))
> - pcnet32_close(dev);
> + pcnet32_netif_stop(dev);
>
> spin_lock_irqsave(&lp->lock, flags);
> - pcnet32_free_ring(dev);
> - lp->tx_ring_size =
> - min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
> - lp->rx_ring_size =
> - min(ering->rx_pending, (unsigned int)RX_MAX_RING_SIZE);
> + lp->a.write_csr(ioaddr, 0, 0x0004); /* stop the chip */
> +
> + size = min(ering->tx_pending, (unsigned int)TX_MAX_RING_SIZE);
>
> /* set the minimum ring size to 4, to allow the loopback test to work
> * unchanged.
> */
> for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
> - if (lp->tx_ring_size <= (1 << i))
> + if (size <= (1 << i))
> break;
> }
> - lp->tx_ring_size = (1 << i);
> - lp->tx_mod_mask = lp->tx_ring_size - 1;
> - lp->tx_len_bits = (i << 12);
> -
> + if ((1 << i) != lp->tx_ring_size)
> + pcnet32_realloc_tx_ring(dev, lp, i);
> +
> + size = min(ering->rx_pending, (unsigned int)RX_MAX_RING_SIZE);
> for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
> - if (lp->rx_ring_size <= (1 << i))
> + if (size <= (1 << i))
> break;
> }
> - lp->rx_ring_size = (1 << i);
> - lp->rx_mod_mask = lp->rx_ring_size - 1;
> - lp->rx_len_bits = (i << 4);
> + if ((1 << i) != lp->rx_ring_size)
> + pcnet32_realloc_rx_ring(dev, lp, i);
> +
> + dev->weight = lp->rx_ring_size / 2;
>
> - if (pcnet32_alloc_ring(dev, dev->name)) {
> - pcnet32_free_ring(dev);
> - spin_unlock_irqrestore(&lp->lock, flags);
> - return -ENOMEM;
> + if (netif_running(dev)) {
> + pcnet32_netif_start(dev);
> + pcnet32_restart(dev, 0x0042);
> }
>
> spin_unlock_irqrestore(&lp->lock, flags);
> @@ -583,9 +816,6 @@ static int pcnet32_set_ringparam(struct
> "%s: Ring Param Settings: RX: %d, TX: %d\n", dev->name,
> lp->rx_ring_size, lp->tx_ring_size);
>
> - if (netif_running(dev))
> - pcnet32_open(dev);
> -
> return 0;
> }
>
> @@ -639,25 +869,27 @@ static int pcnet32_loopback_test(struct
> unsigned long flags;
> unsigned long ticks;
>
> - *data1 = 1; /* status of test, default to fail */
> rc = 1; /* default to fail */
>
> if (netif_running(dev))
> +#ifdef CONFIG_PCNET32_NAPI
> + pcnet32_netif_stop(dev);
> +#else
> pcnet32_close(dev);
> +#endif
>
> spin_lock_irqsave(&lp->lock, flags);
> + lp->a.write_csr(ioaddr, 0, 0x0004); /* stop the chip */
> +
> + numbuffs = min(numbuffs, (int)min(lp->rx_ring_size, lp->tx_ring_size));
>
> /* Reset the PCNET32 */
> lp->a.reset(ioaddr);
> + lp->a.write_csr(ioaddr, 4, 0x0915);
>
> /* switch pcnet32 to 32bit mode */
> lp->a.write_bcr(ioaddr, 20, 2);
>
> - lp->init_block.mode =
> - le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
> - lp->init_block.filter[0] = 0;
> - lp->init_block.filter[1] = 0;
> -
> /* purge & init rings but don't actually restart */
> pcnet32_restart(dev, 0x0000);
>
> @@ -704,10 +936,10 @@ static int pcnet32_loopback_test(struct
> }
>
> x = a->read_bcr(ioaddr, 32); /* set internal loopback in BSR32 */
> - x = x | 0x0002;
> - a->write_bcr(ioaddr, 32, x);
> + a->write_bcr(ioaddr, 32, x | 0x0002);
>
> - lp->a.write_csr(ioaddr, 15, 0x0044); /* set int loopback in CSR15 */
> + x = a->read_csr(ioaddr, 15); /* set int loopback in CSR15 */
> + lp->a.write_csr(ioaddr, 15, x | 0x0044);
>
> teststatus = le16_to_cpu(0x8000);
> lp->a.write_csr(ioaddr, 0, 0x0002); /* Set STRT bit */
> @@ -764,25 +996,30 @@ static int pcnet32_loopback_test(struct
> }
> x++;
> }
> - if (!rc) {
> - *data1 = 0;
> - }
>
> clean_up:
> + *data1 = rc;
> pcnet32_purge_tx_ring(dev);
> +
> x = a->read_csr(ioaddr, 15) & 0xFFFF;
> a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */
>
> x = a->read_bcr(ioaddr, 32); /* reset internal loopback */
> - x = x & ~0x0002;
> - a->write_bcr(ioaddr, 32, x);
> -
> - spin_unlock_irqrestore(&lp->lock, flags);
> + a->write_bcr(ioaddr, 32, (x & ~0x0002));
>
> if (netif_running(dev)) {
> +#ifdef CONFIG_PCNET32_NAPI
> + pcnet32_netif_start(dev);
> + pcnet32_restart(dev, 0x0042);
> + spin_unlock_irqrestore(&lp->lock, flags);
> +#else
> + spin_unlock_irqrestore(&lp->lock, flags);
> pcnet32_open(dev);
> +#endif
> } else {
> + pcnet32_purge_rx_ring(dev);
> lp->a.write_bcr(ioaddr, 20, 4); /* return to 16bit mode */
> + spin_unlock_irqrestore(&lp->lock, flags);
> }
>
> return (rc);
> @@ -845,6 +1082,39 @@ static int pcnet32_phys_id(struct net_de
> return 0;
> }
>
> +/*
> + * lp->lock must be held.
> + */
> +static int pcnet32_suspend(struct net_device *dev, unsigned long *flags)
> +{
> + int csr5;
> + struct pcnet32_private *lp = dev->priv;
> + struct pcnet32_access *a = &lp->a;
> + ulong ioaddr = dev->base_addr;
> + int ticks;
> +
> + /* set SUSPEND (SPND) - CSR5 bit 0 */
> + csr5 = a->read_csr(ioaddr, 5);
> + a->write_csr(ioaddr, 5, csr5 | 0x0001);
> +
> + /* poll waiting for bit to be set */
> + ticks = 0;
> + while (!(a->read_csr(ioaddr, 5) & 0x0001)) {
> + spin_unlock_irqrestore(&lp->lock, *flags);
> + mdelay(1);
> + spin_lock_irqsave(&lp->lock, *flags);
> + ticks++;
> + if (ticks > 200) {
> + if (netif_msg_hw(lp))
> + printk(KERN_DEBUG
> + "%s: Error getting into suspend!\n",
> + dev->name);
> + return 0;
> + }
> + }
> + return 1;
> +}
> +
> #define PCNET32_REGS_PER_PHY 32
> #define PCNET32_MAX_PHYS 32
> static int pcnet32_get_regs_len(struct net_device *dev)
> @@ -863,31 +1133,17 @@ static void pcnet32_get_regs(struct net_
> struct pcnet32_private *lp = dev->priv;
> struct pcnet32_access *a = &lp->a;
> ulong ioaddr = dev->base_addr;
> - int ticks;
> unsigned long flags;
>
> spin_lock_irqsave(&lp->lock, flags);
>
> csr0 = a->read_csr(ioaddr, 0);
> if (!(csr0 & 0x0004)) { /* If not stopped */
> - /* set SUSPEND (SPND) - CSR5 bit 0 */
> - a->write_csr(ioaddr, 5, 0x0001);
> -
> - /* poll waiting for bit to be set */
> - ticks = 0;
> - while (!(a->read_csr(ioaddr, 5) & 0x0001)) {
> - spin_unlock_irqrestore(&lp->lock, flags);
> - mdelay(1);
> - spin_lock_irqsave(&lp->lock, flags);
> - ticks++;
> - if (ticks > 200) {
> - if (netif_msg_hw(lp))
> - printk(KERN_DEBUG
> - "%s: Error getting into suspend!\n",
> - dev->name);
> - break;
> - }
> - }
> + if (!pcnet32_suspend(dev, &flags))
> + if (netif_msg_hw(lp))
> + printk(KERN_DEBUG
> + "%s: Error getting into suspend!\n",
> + dev->name);
> }
>
> /* read address PROM */
> @@ -926,8 +1182,11 @@ static void pcnet32_get_regs(struct net_
> }
>
> if (!(csr0 & 0x0004)) { /* If not stopped */
> + int csr5;
> +
> /* clear SUSPEND (SPND) - CSR5 bit 0 */
> - a->write_csr(ioaddr, 5, 0x0000);
> + csr5 = a->read_csr(ioaddr, 5);
> + a->write_csr(ioaddr, 5, csr5 & (~0x0001));
> }
>
> spin_unlock_irqrestore(&lp->lock, flags);
> @@ -958,7 +1217,7 @@ static struct ethtool_ops pcnet32_ethtoo
> /* only probes for non-PCI devices, the rest are handled by
> * pci_register_driver via pcnet32_probe_pci */
>
> -static void __devinit pcnet32_probe_vlbus(void)
> +static void __devinit pcnet32_probe_vlbus(unsigned int *pcnet32_portlist)
> {
> unsigned int *port, ioaddr;
>
> @@ -1396,6 +1655,10 @@ pcnet32_probe1(unsigned long ioaddr, int
> dev->ethtool_ops = &pcnet32_ethtool_ops;
> dev->tx_timeout = pcnet32_tx_timeout;
> dev->watchdog_timeo = (5 * HZ);
> + dev->weight = lp->rx_ring_size / 2;
> +#ifdef CONFIG_PCNET32_NAPI
> + dev->poll = pcnet32_poll;
> +#endif
>
> #ifdef CONFIG_NET_POLL_CONTROLLER
> dev->poll_controller = pcnet32_poll_controller;
> @@ -1763,16 +2026,7 @@ static int pcnet32_open(struct net_devic
>
> err_free_ring:
> /* free any allocated skbuffs */
> - for (i = 0; i < lp->rx_ring_size; i++) {
> - lp->rx_ring[i].status = 0;
> - if (lp->rx_skbuff[i]) {
> - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
> - PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> - dev_kfree_skb(lp->rx_skbuff[i]);
> - }
> - lp->rx_skbuff[i] = NULL;
> - lp->rx_dma_addr[i] = 0;
> - }
> + pcnet32_purge_rx_ring(dev);
>
> /*
> * Switch back to 16bit mode to avoid problems with dumb
> @@ -2004,6 +2258,286 @@ static int pcnet32_start_xmit(struct sk_
> return 0;
> }
>
> +static int pcnet32_rx_entry(struct net_device *dev,
> + struct pcnet32_private *lp,
> + struct pcnet32_rx_head *rxp,
> + int entry)
> +{
> + int status = (short)le16_to_cpu(rxp->status) >> 8;
> + int rx_in_place = 0;
> + struct sk_buff *skb;
> + short pkt_len;
> +
> + if (status != 0x03) { /* There was an error. */
> + /*
> + * There is a tricky error noted by John Murphy,
> + * <murf@perftech.com> to Russ Nelson: Even with full-sized
> + * buffers it's possible for a jabber packet to use two
> + * buffers, with only the last correctly noting the error.
> + */
> + if (status & 0x01) /* Only count a general error at the */
> + lp->stats.rx_errors++; /* end of a packet. */
> + if (status & 0x20)
> + lp->stats.rx_frame_errors++;
> + if (status & 0x10)
> + lp->stats.rx_over_errors++;
> + if (status & 0x08)
> + lp->stats.rx_crc_errors++;
> + if (status & 0x04)
> + lp->stats.rx_fifo_errors++;
> + return 1;
> + }
> +
> + pkt_len = (le32_to_cpu(rxp->msg_length) & 0xfff) - 4;
> +
> + /* Discard oversize frames. */
> + if (unlikely(pkt_len > PKT_BUF_SZ - 2)) {
> + if (netif_msg_drv(lp))
> + printk(KERN_ERR "%s: Impossible packet size %d!\n",
> + dev->name, pkt_len);
> + lp->stats.rx_errors++;
> + return 1;
> + }
> + if (pkt_len < 60) {
> + if (netif_msg_rx_err(lp))
> + printk(KERN_ERR "%s: Runt packet!\n", dev->name);
> + lp->stats.rx_errors++;
> + return 1;
> + }
> +
> + if (pkt_len > rx_copybreak) {
> + struct sk_buff *newskb;
> +
> + if ((newskb = dev_alloc_skb(PKT_BUF_SZ))) {
> + skb_reserve(newskb, 2);
> + skb = lp->rx_skbuff[entry];
> + pci_unmap_single(lp->pci_dev,
> + lp->rx_dma_addr[entry],
> + PKT_BUF_SZ - 2,
> + PCI_DMA_FROMDEVICE);
> + skb_put(skb, pkt_len);
> + lp->rx_skbuff[entry] = newskb;
> + newskb->dev = dev;
> + lp->rx_dma_addr[entry] =
> + pci_map_single(lp->pci_dev,
> + newskb->data,
> + PKT_BUF_SZ - 2,
> + PCI_DMA_FROMDEVICE);
> + rxp->base = le32_to_cpu(lp->rx_dma_addr[entry]);
> + rx_in_place = 1;
> + } else
> + skb = NULL;
> + } else {
> + skb = dev_alloc_skb(pkt_len + 2);
> + }
> +
> + if (skb == NULL) {
> + if (netif_msg_drv(lp))
> + printk(KERN_ERR
> + "%s: Memory squeeze, dropping packet.\n",
> + dev->name);
> + lp->stats.rx_dropped++;
> + return 1;
> + }
> + skb->dev = dev;
> + if (!rx_in_place) {
> + skb_reserve(skb, 2); /* 16 byte align */
> + skb_put(skb, pkt_len); /* Make room */
> + pci_dma_sync_single_for_cpu(lp->pci_dev,
> + lp->rx_dma_addr[entry],
> + PKT_BUF_SZ - 2,
> + PCI_DMA_FROMDEVICE);
> + eth_copy_and_sum(skb,
> + (unsigned char *)(lp->rx_skbuff[entry]->data),
> + pkt_len, 0);
> + pci_dma_sync_single_for_device(lp->pci_dev,
> + lp->rx_dma_addr[entry],
> + PKT_BUF_SZ - 2,
> + PCI_DMA_FROMDEVICE);
> + }
> + lp->stats.rx_bytes += skb->len;
> + lp->stats.rx_packets++;
> + skb->protocol = eth_type_trans(skb, dev);
> +#ifdef CONFIG_PCNET32_NAPI
> + netif_receive_skb(skb);
> +#else
> + netif_rx(skb);
> +#endif
> + dev->last_rx = jiffies;
> + return 1;
> +}
> +
> +static int pcnet32_rx(struct net_device *dev, int quota)
> +{
> + struct pcnet32_private *lp = dev->priv;
> + int entry = lp->cur_rx & lp->rx_mod_mask;
> + struct pcnet32_rx_head *rxp = &lp->rx_ring[entry];
> + int npackets = 0;
> +
> + /* If we own the next entry, it's a new packet. Send it up. */
> + while (quota > npackets && (short)le16_to_cpu(rxp->status) >= 0) {
> + npackets += pcnet32_rx_entry(dev, lp, rxp, entry);
> +//printk("DONF: %s npackets=%d\n", dev->name, npackets);
Should that be in the patch?
> + /*
> + * The docs say that the buffer length isn't touched, but Andrew
> + * Boyd of QNX reports that some revs of the 79C965 clear it.
> + */
> + rxp->buf_length = le16_to_cpu(2 - PKT_BUF_SZ);
> + wmb(); /* Make sure owner changes after others are visible */
> + rxp->status = le16_to_cpu(0x8000);
> + entry = (++lp->cur_rx) & lp->rx_mod_mask;
> + rxp = &lp->rx_ring[entry];
> + }
> +
> + return npackets;
> +}
> +
> +static int pcnet32_tx(struct net_device *dev)
> +{
> + struct pcnet32_private *lp = dev->priv;
> + unsigned int dirty_tx = lp->dirty_tx;
> + int delta;
> + int must_restart = 0;
> +
> + while (dirty_tx != lp->cur_tx) {
> + int entry = dirty_tx & lp->tx_mod_mask;
> + int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
> +
> + if (status < 0)
> + break; /* It still hasn't been Txed */
> +
> + lp->tx_ring[entry].base = 0;
> +
> + if (status & 0x4000) {
> + /* There was an major error, log it. */
> + int err_status =
> + le32_to_cpu(lp->tx_ring[entry].
> + misc);
> + lp->stats.tx_errors++;
> + if (netif_msg_tx_err(lp))
> + printk(KERN_ERR
> + "%s: Tx error status=%04x err_status=%08x\n",
> + dev->name, status,
> + err_status);
> + if (err_status & 0x04000000)
> + lp->stats.tx_aborted_errors++;
> + if (err_status & 0x08000000)
> + lp->stats.tx_carrier_errors++;
> + if (err_status & 0x10000000)
> + lp->stats.tx_window_errors++;
> +#ifndef DO_DXSUFLO
> + if (err_status & 0x40000000) {
> + lp->stats.tx_fifo_errors++;
> + /* Ackk! On FIFO errors the Tx unit is turned off! */
> + /* Remove this verbosity later! */
> + if (netif_msg_tx_err(lp))
> + printk(KERN_ERR
> + "%s: Tx FIFO error!\n",
> + dev->name);
> + must_restart = 1;
> + }
> +#else
> + if (err_status & 0x40000000) {
> + lp->stats.tx_fifo_errors++;
> + if (!lp->dxsuflo) { /* If controller doesn't recover ... */
> + /* Ackk! On FIFO errors the Tx unit is turned off! */
> + /* Remove this verbosity later! */
> + if (netif_msg_tx_err(lp))
> + printk(KERN_ERR
> + "%s: Tx FIFO error!\n",
> + dev->name);
> + must_restart = 1;
> + }
> + }
> +#endif
> + } else {
> + if (status & 0x1800)
> + lp->stats.collisions++;
> + lp->stats.tx_packets++;
> + }
> +
> + /* We must free the original skb */
> + if (lp->tx_skbuff[entry]) {
> + pci_unmap_single(lp->pci_dev,
> + lp->tx_dma_addr[entry],
> + lp->tx_skbuff[entry]->
> + len, PCI_DMA_TODEVICE);
> + dev_kfree_skb_any(lp->tx_skbuff[entry]);
> + lp->tx_skbuff[entry] = NULL;
> + lp->tx_dma_addr[entry] = 0;
> + }
> + dirty_tx++;
> + }
> +
> + delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
> + if (delta > lp->tx_ring_size) {
> + if (netif_msg_drv(lp))
> + printk(KERN_ERR
> + "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
> + dev->name, dirty_tx, lp->cur_tx,
> + lp->tx_full);
> + dirty_tx += lp->tx_ring_size;
> + delta -= lp->tx_ring_size;
> + }
> +
> + if (lp->tx_full &&
> + netif_queue_stopped(dev) &&
> + delta < lp->tx_ring_size - 2) {
> + /* The ring is no longer full, clear tbusy. */
> + lp->tx_full = 0;
> + netif_wake_queue(dev);
> + }
> + lp->dirty_tx = dirty_tx;
> +
> + return must_restart;
> +}
> +
> +#ifdef CONFIG_PCNET32_NAPI
> +static int pcnet32_poll(struct net_device *dev, int *budget)
> +{
> + struct pcnet32_private *lp = dev->priv;
> + int quota = min(dev->quota, *budget);
> + unsigned long ioaddr = dev->base_addr;
> + u16 val;
> + unsigned long flags;
> +
> + quota = pcnet32_rx(dev, quota);
> +
> + spin_lock_irqsave(&lp->lock, flags);
> + if (pcnet32_tx(dev)) {
> + /* reset the chip to clear the error condition, then restart */
> + lp->a.reset(ioaddr);
> + lp->a.write_csr(ioaddr, 4, 0x0915);
> + pcnet32_restart(dev, 0x0002);
> + netif_wake_queue(dev);
> + }
> + spin_unlock_irqrestore(&lp->lock, flags);
> +
> + *budget -= quota;
> + dev->quota -= quota;
> +
> + if (dev->quota == 0) {
> + return 1;
> + }
> +
> + netif_rx_complete(dev);
> +
> + spin_lock_irqsave(&lp->lock, flags);
> +
> + /* clear interrupt masks */
> + val = lp->a.read_csr(ioaddr, 3);
> + val &= 0x00ff;
> + lp->a.write_csr(ioaddr, 3, val);
> +
> + /* Set interrupt enable. */
> + lp->a.write_csr(ioaddr, 0, 0x0040);
> +
> + spin_unlock_irqrestore(&lp->lock, flags);
> +
> + return 0;
> +}
> +#endif
> +
> /* The PCNET32 interrupt handler. */
> static irqreturn_t
> pcnet32_interrupt(int irq, void *dev_id, struct pt_regs *regs)
> @@ -2011,9 +2545,9 @@ pcnet32_interrupt(int irq, void *dev_id,
> struct net_device *dev = dev_id;
> struct pcnet32_private *lp;
> unsigned long ioaddr;
> - u16 csr0, rap;
> int boguscnt = max_interrupt_work;
> - int must_restart;
> + u16 csr0;
> + irqreturn_t rc = IRQ_HANDLED;
>
> if (!dev) {
> if (pcnet32_debug & NETIF_MSG_INTR)
> @@ -2027,141 +2561,33 @@ pcnet32_interrupt(int irq, void *dev_id,
>
> spin_lock(&lp->lock);
>
> - rap = lp->a.read_rap(ioaddr);
> - while ((csr0 = lp->a.read_csr(ioaddr, 0)) & 0x8f00 && --boguscnt >= 0) {
> - if (csr0 == 0xffff) {
> - break; /* PCMCIA remove happened */
> - }
> + csr0 = lp->a.read_csr(ioaddr, 0);
> + if (csr0 == 0xffff) {
> + rc = IRQ_NONE;
> + } else while (csr0 & 0x8f00 && --boguscnt >= 0) {
> /* Acknowledge all of the current interrupt sources ASAP. */
> lp->a.write_csr(ioaddr, 0, csr0 & ~0x004f);
>
> - must_restart = 0;
> -
> if (netif_msg_intr(lp))
> printk(KERN_DEBUG
> "%s: interrupt csr0=%#2.2x new csr=%#2.2x.\n",
> dev->name, csr0, lp->a.read_csr(ioaddr, 0));
>
> - if (csr0 & 0x0400) /* Rx interrupt */
> - pcnet32_rx(dev);
> -
> - if (csr0 & 0x0200) { /* Tx-done interrupt */
> - unsigned int dirty_tx = lp->dirty_tx;
> - int delta;
> -
> - while (dirty_tx != lp->cur_tx) {
> - int entry = dirty_tx & lp->tx_mod_mask;
> - int status =
> - (short)le16_to_cpu(lp->tx_ring[entry].
> - status);
> -
> - if (status < 0)
> - break; /* It still hasn't been Txed */
> -
> - lp->tx_ring[entry].base = 0;
> -
> - if (status & 0x4000) {
> - /* There was an major error, log it. */
> - int err_status =
> - le32_to_cpu(lp->tx_ring[entry].
> - misc);
> - lp->stats.tx_errors++;
> - if (netif_msg_tx_err(lp))
> - printk(KERN_ERR
> - "%s: Tx error status=%04x err_status=%08x\n",
> - dev->name, status,
> - err_status);
> - if (err_status & 0x04000000)
> - lp->stats.tx_aborted_errors++;
> - if (err_status & 0x08000000)
> - lp->stats.tx_carrier_errors++;
> - if (err_status & 0x10000000)
> - lp->stats.tx_window_errors++;
> -#ifndef DO_DXSUFLO
> - if (err_status & 0x40000000) {
> - lp->stats.tx_fifo_errors++;
> - /* Ackk! On FIFO errors the Tx unit is turned off! */
> - /* Remove this verbosity later! */
> - if (netif_msg_tx_err(lp))
> - printk(KERN_ERR
> - "%s: Tx FIFO error! CSR0=%4.4x\n",
> - dev->name, csr0);
> - must_restart = 1;
> - }
> -#else
> - if (err_status & 0x40000000) {
> - lp->stats.tx_fifo_errors++;
> - if (!lp->dxsuflo) { /* If controller doesn't recover ... */
> - /* Ackk! On FIFO errors the Tx unit is turned off! */
> - /* Remove this verbosity later! */
> - if (netif_msg_tx_err
> - (lp))
> - printk(KERN_ERR
> - "%s: Tx FIFO error! CSR0=%4.4x\n",
> - dev->
> - name,
> - csr0);
> - must_restart = 1;
> - }
> - }
> -#endif
> - } else {
> - if (status & 0x1800)
> - lp->stats.collisions++;
> - lp->stats.tx_packets++;
> - }
> -
> - /* We must free the original skb */
> - if (lp->tx_skbuff[entry]) {
> - pci_unmap_single(lp->pci_dev,
> - lp->tx_dma_addr[entry],
> - lp->tx_skbuff[entry]->
> - len, PCI_DMA_TODEVICE);
> - dev_kfree_skb_irq(lp->tx_skbuff[entry]);
> - lp->tx_skbuff[entry] = NULL;
> - lp->tx_dma_addr[entry] = 0;
> - }
> - dirty_tx++;
> - }
> -
> - delta =
> - (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask +
> - lp->tx_ring_size);
> - if (delta > lp->tx_ring_size) {
> - if (netif_msg_drv(lp))
> - printk(KERN_ERR
> - "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
> - dev->name, dirty_tx, lp->cur_tx,
> - lp->tx_full);
> - dirty_tx += lp->tx_ring_size;
> - delta -= lp->tx_ring_size;
> - }
> -
> - if (lp->tx_full &&
> - netif_queue_stopped(dev) &&
> - delta < lp->tx_ring_size - 2) {
> - /* The ring is no longer full, clear tbusy. */
> - lp->tx_full = 0;
> - netif_wake_queue(dev);
> - }
> - lp->dirty_tx = dirty_tx;
> - }
> -
> /* Log misc errors. */
> if (csr0 & 0x4000)
> lp->stats.tx_errors++; /* Tx babble. */
> if (csr0 & 0x1000) {
> /*
> - * this happens when our receive ring is full. This shouldn't
> - * be a problem as we will see normal rx interrupts for the frames
> - * in the receive ring. But there are some PCI chipsets (I can
> - * reproduce this on SP3G with Intel saturn chipset) which have
> - * sometimes problems and will fill up the receive ring with
> - * error descriptors. In this situation we don't get a rx
> - * interrupt, but a missed frame interrupt sooner or later.
> - * So we try to clean up our receive ring here.
> + * This happens when our receive ring is full. This
> + * shouldn't be a problem as we will see normal rx
> + * interrupts for the frames in the receive ring. But
> + * there are some PCI chipsets (I can reproduce this
> + * on SP3G with Intel saturn chipset) which have
> + * sometimes problems and will fill up the receive
> + * ring with error descriptors. In this situation we
> + * don't get a rx interrupt, but a missed frame
> + * interrupt sooner or later.
> */
> - pcnet32_rx(dev);
> lp->stats.rx_errors++; /* Missed a Rx frame. */
> }
> if (csr0 & 0x0800) {
> @@ -2171,19 +2597,34 @@ pcnet32_interrupt(int irq, void *dev_id,
> dev->name, csr0);
> /* unlike for the lance, there is no restart needed */
> }
> -
> - if (must_restart) {
> +#ifdef CONFIG_PCNET32_NAPI
> + if (netif_rx_schedule_prep(dev)) {
> + u16 val;
> + /* set interrupt masks */
> + val = lp->a.read_csr(ioaddr, 3);
> + val |= 0x5f00;
> + lp->a.write_csr(ioaddr, 3, val);
> + __netif_rx_schedule(dev);
> + break;
> + }
> +#else
> +//printk("DONF: %s: weight is %d\n", dev->name, dev->weight);
And the same thing here?
> + pcnet32_rx(dev, dev->weight);
> + if (pcnet32_tx(dev)) {
> /* reset the chip to clear the error condition, then restart */
> lp->a.reset(ioaddr);
> lp->a.write_csr(ioaddr, 4, 0x0915);
> pcnet32_restart(dev, 0x0002);
> netif_wake_queue(dev);
> }
> +#endif
> + csr0 = lp->a.read_csr(ioaddr, 0);
> }
>
> - /* Set interrupt enable. */
> +#ifndef CONFIG_PCNET32_NAPI
> + /*Set interrupt enable. */
> lp->a.write_csr(ioaddr, 0, 0x0040);
> - lp->a.write_rap(ioaddr, rap);
> +#endif
>
> if (netif_msg_intr(lp))
> printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
> @@ -2191,170 +2632,13 @@ pcnet32_interrupt(int irq, void *dev_id,
>
> spin_unlock(&lp->lock);
>
> - return IRQ_HANDLED;
> -}
> -
> -static int pcnet32_rx(struct net_device *dev)
> -{
> - struct pcnet32_private *lp = dev->priv;
> - int entry = lp->cur_rx & lp->rx_mod_mask;
> - int boguscnt = lp->rx_ring_size / 2;
> -
> - /* If we own the next entry, it's a new packet. Send it up. */
> - while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
> - int status = (short)le16_to_cpu(lp->rx_ring[entry].status) >> 8;
> -
> - if (status != 0x03) { /* There was an error. */
> - /*
> - * There is a tricky error noted by John Murphy,
> - * <murf@perftech.com> to Russ Nelson: Even with full-sized
> - * buffers it's possible for a jabber packet to use two
> - * buffers, with only the last correctly noting the error.
> - */
> - if (status & 0x01) /* Only count a general error at the */
> - lp->stats.rx_errors++; /* end of a packet. */
> - if (status & 0x20)
> - lp->stats.rx_frame_errors++;
> - if (status & 0x10)
> - lp->stats.rx_over_errors++;
> - if (status & 0x08)
> - lp->stats.rx_crc_errors++;
> - if (status & 0x04)
> - lp->stats.rx_fifo_errors++;
> - lp->rx_ring[entry].status &= le16_to_cpu(0x03ff);
> - } else {
> - /* Malloc up new buffer, compatible with net-2e. */
> - short pkt_len =
> - (le32_to_cpu(lp->rx_ring[entry].msg_length) & 0xfff)
> - - 4;
> - struct sk_buff *skb;
> -
> - /* Discard oversize frames. */
> - if (unlikely(pkt_len > PKT_BUF_SZ - 2)) {
> - if (netif_msg_drv(lp))
> - printk(KERN_ERR
> - "%s: Impossible packet size %d!\n",
> - dev->name, pkt_len);
> - lp->stats.rx_errors++;
> - } else if (pkt_len < 60) {
> - if (netif_msg_rx_err(lp))
> - printk(KERN_ERR "%s: Runt packet!\n",
> - dev->name);
> - lp->stats.rx_errors++;
> - } else {
> - int rx_in_place = 0;
> -
> - if (pkt_len > rx_copybreak) {
> - struct sk_buff *newskb;
> -
> - if ((newskb =
> - dev_alloc_skb(PKT_BUF_SZ))) {
> - skb_reserve(newskb, 2);
> - skb = lp->rx_skbuff[entry];
> - pci_unmap_single(lp->pci_dev,
> - lp->
> - rx_dma_addr
> - [entry],
> - PKT_BUF_SZ - 2,
> - PCI_DMA_FROMDEVICE);
> - skb_put(skb, pkt_len);
> - lp->rx_skbuff[entry] = newskb;
> - newskb->dev = dev;
> - lp->rx_dma_addr[entry] =
> - pci_map_single(lp->pci_dev,
> - newskb->data,
> - PKT_BUF_SZ -
> - 2,
> - PCI_DMA_FROMDEVICE);
> - lp->rx_ring[entry].base =
> - le32_to_cpu(lp->
> - rx_dma_addr
> - [entry]);
> - rx_in_place = 1;
> - } else
> - skb = NULL;
> - } else {
> - skb = dev_alloc_skb(pkt_len + 2);
> - }
> -
> - if (skb == NULL) {
> - int i;
> - if (netif_msg_drv(lp))
> - printk(KERN_ERR
> - "%s: Memory squeeze, deferring packet.\n",
> - dev->name);
> - for (i = 0; i < lp->rx_ring_size; i++)
> - if ((short)
> - le16_to_cpu(lp->
> - rx_ring[(entry +
> - i)
> - & lp->
> - rx_mod_mask].
> - status) < 0)
> - break;
> -
> - if (i > lp->rx_ring_size - 2) {
> - lp->stats.rx_dropped++;
> - lp->rx_ring[entry].status |=
> - le16_to_cpu(0x8000);
> - wmb(); /* Make sure adapter sees owner change */
> - lp->cur_rx++;
> - }
> - break;
> - }
> - skb->dev = dev;
> - if (!rx_in_place) {
> - skb_reserve(skb, 2); /* 16 byte align */
> - skb_put(skb, pkt_len); /* Make room */
> - pci_dma_sync_single_for_cpu(lp->pci_dev,
> - lp->
> - rx_dma_addr
> - [entry],
> - PKT_BUF_SZ -
> - 2,
> - PCI_DMA_FROMDEVICE);
> - eth_copy_and_sum(skb,
> - (unsigned char *)(lp->
> - rx_skbuff
> - [entry]->
> - data),
> - pkt_len, 0);
> - pci_dma_sync_single_for_device(lp->
> - pci_dev,
> - lp->
> - rx_dma_addr
> - [entry],
> - PKT_BUF_SZ
> - - 2,
> - PCI_DMA_FROMDEVICE);
> - }
> - lp->stats.rx_bytes += skb->len;
> - skb->protocol = eth_type_trans(skb, dev);
> - netif_rx(skb);
> - dev->last_rx = jiffies;
> - lp->stats.rx_packets++;
> - }
> - }
> - /*
> - * The docs say that the buffer length isn't touched, but Andrew Boyd
> - * of QNX reports that some revs of the 79C965 clear it.
> - */
> - lp->rx_ring[entry].buf_length = le16_to_cpu(2 - PKT_BUF_SZ);
> - wmb(); /* Make sure owner changes after all others are visible */
> - lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
> - entry = (++lp->cur_rx) & lp->rx_mod_mask;
> - if (--boguscnt <= 0)
> - break; /* don't stay in loop forever */
> - }
> -
> - return 0;
> + return rc;
> }
>
> static int pcnet32_close(struct net_device *dev)
> {
> unsigned long ioaddr = dev->base_addr;
> struct pcnet32_private *lp = dev->priv;
> - int i;
> unsigned long flags;
>
> del_timer_sync(&lp->watchdog_timer);
> @@ -2385,31 +2669,8 @@ static int pcnet32_close(struct net_devi
>
> spin_lock_irqsave(&lp->lock, flags);
>
> - /* free all allocated skbuffs */
> - for (i = 0; i < lp->rx_ring_size; i++) {
> - lp->rx_ring[i].status = 0;
> - wmb(); /* Make sure adapter sees owner change */
> - if (lp->rx_skbuff[i]) {
> - pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
> - PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
> - dev_kfree_skb(lp->rx_skbuff[i]);
> - }
> - lp->rx_skbuff[i] = NULL;
> - lp->rx_dma_addr[i] = 0;
> - }
> -
> - for (i = 0; i < lp->tx_ring_size; i++) {
> - lp->tx_ring[i].status = 0; /* CPU owns buffer */
> - wmb(); /* Make sure adapter sees owner change */
> - if (lp->tx_skbuff[i]) {
> - pci_unmap_single(lp->pci_dev, lp->tx_dma_addr[i],
> - lp->tx_skbuff[i]->len,
> - PCI_DMA_TODEVICE);
> - dev_kfree_skb(lp->tx_skbuff[i]);
> - }
> - lp->tx_skbuff[i] = NULL;
> - lp->tx_dma_addr[i] = 0;
> - }
> + pcnet32_purge_rx_ring(dev);
> + pcnet32_purge_tx_ring(dev);
>
> spin_unlock_irqrestore(&lp->lock, flags);
>
> @@ -2420,13 +2681,10 @@ static struct net_device_stats *pcnet32_
> {
> struct pcnet32_private *lp = dev->priv;
> unsigned long ioaddr = dev->base_addr;
> - u16 saved_addr;
> unsigned long flags;
>
> spin_lock_irqsave(&lp->lock, flags);
> - saved_addr = lp->a.read_rap(ioaddr);
> lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112);
> - lp->a.write_rap(ioaddr, saved_addr);
> spin_unlock_irqrestore(&lp->lock, flags);
>
> return &lp->stats;
> @@ -2439,6 +2697,7 @@ static void pcnet32_load_multicast(struc
> volatile struct pcnet32_init_block *ib = &lp->init_block;
> volatile u16 *mcast_table = (u16 *) & ib->filter;
> struct dev_mc_list *dmi = dev->mc_list;
> + unsigned long ioaddr = dev->base_addr;
> char *addrs;
> int i;
> u32 crc;
> @@ -2447,6 +2706,10 @@ static void pcnet32_load_multicast(struc
> if (dev->flags & IFF_ALLMULTI) {
> ib->filter[0] = 0xffffffff;
> ib->filter[1] = 0xffffffff;
> + lp->a.write_csr(ioaddr, 8, 0xffff);
> + lp->a.write_csr(ioaddr, 9, 0xffff);
> + lp->a.write_csr(ioaddr, 10, 0xffff);
> + lp->a.write_csr(ioaddr, 11, 0xffff);
> return;
> }
> /* clear the multicast filter */
> @@ -2468,6 +2731,8 @@ static void pcnet32_load_multicast(struc
> le16_to_cpu(le16_to_cpu(mcast_table[crc >> 4]) |
> (1 << (crc & 0xf)));
> }
> + for (i = 0; i < 4; i++)
> + lp->a.write_csr(ioaddr, 8+i, le16_to_cpu(mcast_table[i]));
> return;
> }
>
> @@ -2478,8 +2743,11 @@ static void pcnet32_set_multicast_list(s
> {
> unsigned long ioaddr = dev->base_addr, flags;
> struct pcnet32_private *lp = dev->priv;
> + int csr15, suspended;
>
> spin_lock_irqsave(&lp->lock, flags);
> + suspended = pcnet32_suspend(dev, &flags);
> + csr15 = lp->a.read_csr(ioaddr, 15);
> if (dev->flags & IFF_PROMISC) {
> /* Log any net taps. */
> if (netif_msg_hw(lp))
> @@ -2488,15 +2756,24 @@ static void pcnet32_set_multicast_list(s
> lp->init_block.mode =
> le16_to_cpu(0x8000 | (lp->options & PCNET32_PORT_PORTSEL) <<
> 7);
> + lp->a.write_csr(ioaddr, 15, csr15 | 0x8000);
> } else {
> lp->init_block.mode =
> le16_to_cpu((lp->options & PCNET32_PORT_PORTSEL) << 7);
> + lp->a.write_csr(ioaddr, 15, csr15 & 0x7fff);
> pcnet32_load_multicast(dev);
> }
>
> - lp->a.write_csr(ioaddr, 0, 0x0004); /* Temporarily stop the lance. */
> - pcnet32_restart(dev, 0x0042); /* Resume normal operation */
> - netif_wake_queue(dev);
> + if (suspended) {
> + int csr5;
> + /* clear SUSPEND (SPND) - CSR5 bit 0 */
> + csr5 = lp->a.read_csr(ioaddr, 5);
> + lp->a.write_csr(ioaddr, 5, csr5 & (~0x0001));
> + } else {
> + lp->a.write_csr(ioaddr, 0, 0x0004); /* stop the lance. */
> + pcnet32_restart(dev, 0x0042); /* Resume normal operation */
> + netif_wake_queue(dev);
> + }
>
> spin_unlock_irqrestore(&lp->lock, flags);
> }
> @@ -2736,7 +3013,7 @@ static int __init pcnet32_init_module(vo
>
> /* should we find any remaining VLbus devices ? */
> if (pcnet32vlb)
> - pcnet32_probe_vlbus();
> + pcnet32_probe_vlbus(pcnet32_portlist);
>
> if (cards_found && (pcnet32_debug & NETIF_MSG_PROBE))
> printk(KERN_INFO PFX "%d cards_found.\n", cards_found);
> --
So yep, looks pretty good to me. Those two debug statements are my only
comments on it.
Len Sorensen
^ permalink raw reply
* Re: [patch 3/4] Network namespaces: IPv4 FIB/routing in namespaces
From: Kirill Korotaev @ 2006-06-28 14:34 UTC (permalink / raw)
To: Andrey Savochkin
Cc: Daniel Lezcano, linux-kernel, netdev, serue, haveblue, clg,
Andrew Morton, herbert, devel, sam, ebiederm, viro, alexey,
Cedric Le Goater
In-Reply-To: <20060628183015.B31885@castle.nmd.msu.ru>
>>>>Structures related to IPv4 rounting (FIB and routing cache)
>>>>are made per-namespace.
>>
>>Hi Andrey,
>>
>>if the ressources are private to the namespace, how do you will handle
>>NFS mounted before creating the network namespace ? Do you take care of
>>that or simply assume you can't access NFS anymore ?
>
>
> This is a question that brings up another level of interaction between
> networking and the rest of kernel code.
> Solution that I use now makes the NFS communication part always run in
> the root namespace. This is discussable, of course, but it's a far more
> complicated matter than just device lists or routing :)
if we had containers (not namespaces) then it would be also possible to
run NFS in context of the appropriate container and thus each user could
mount NFS itself with correct networking context.
it's another thing which ties subsytems and makes namespaces ugly :/
Kirill
^ permalink raw reply
* Re: Please pull 'upstream' branch of wireless-2.6
From: Michael Buesch @ 2006-06-28 14:34 UTC (permalink / raw)
To: Larry Finger; +Cc: John W. Linville, netdev
In-Reply-To: <44A19712.40702@lwfinger.net>
On Tuesday 27 June 2006 22:37, Larry Finger wrote:
> Michael Buesch wrote:
> > On Tuesday 27 June 2006 22:06, Larry Finger wrote:
> >> John,
> >>
> >> I would like to find a diplomatic solution to this impasse between Michael and Jeff, which is why
> >> I'm writing to you privately. Michael is correct in that the loop in question will not usually delay
> >
> > private?
>
> I meant it to be private, but screwed up.
>
> >> long; however, on some hardware it takes longer than on his. On mine, I have seen delays as long as
> >> 550 usec.
> >
> > What's the chip?
>
> bcm43xx: Chip ID 0x4306, rev 0x2
> bcm43xx: Number of cores: 6
> bcm43xx: Core 0: ID 0x800, rev 0x2, vendor 0x4243, enabled
> bcm43xx: Core 1: ID 0x812, rev 0x4, vendor 0x4243, disabled
> bcm43xx: Core 2: ID 0x80d, rev 0x1, vendor 0x4243, enabled
> bcm43xx: Core 3: ID 0x807, rev 0x1, vendor 0x4243, disabled
> bcm43xx: Core 4: ID 0x804, rev 0x7, vendor 0x4243, enabled
> bcm43xx: Core 5: ID 0x812, rev 0x4, vendor 0x4243, disabled
> bcm43xx: Ignoring additional 802.11 core.
> bcm43xx: Detected PHY: Version: 1, Type 2, Revision 1
> bcm43xx: Detected Radio: ID: 2205017f (Manuf: 17f Ver: 2050 Rev: 2)
It appears to be an older card. There are quite some
special codepaths for this, I think.
> >> This would make the worst-case delay be 5 msec, but would provide a cushion of 10X the longest I
> >> have seen and should be safe.
> >>
> >> Do you have any suggestions on what should be done next?
> >
> > Leave it as is and find out why it takes so long for your strange card. ;)
>
> I once offered you my second, duplicate card for testing, but never heard back. Do you have any
> ideas regarding diagnostics to see why it takes so long? Remember, this card used to time-out on the
> 1 second delay before the periodic work was restructured.
Well, we did not want to have the card, because at this point
it did not make sense. We all have 4306 cards.
But now it appears that this card seems to have some special
things (because it is older than ours).
Well, how to debug.
We are waiting for the IRQ Reason register there.
Actually, we are waiting for the "no IRQ pending, but READY signal"
state. Your card does not completely (?) clear the bits after MAC
shutdown. So very helpful would be to print out in the loop the
value. We know, that the card generates silly IRQs, that we did
not ask for. That may happen here, too. So it _may_ help to
mask out unwanted IRQs before the if-check. But I would first
like to see a log of the reason-value on each iteration until it succeeds.
--
Greetings Michael.
^ permalink raw reply
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