From bunk@fs.tum.de Sun Aug 1 07:28:14 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 07:28:20 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i71ESAPm020056 for ; Sun, 1 Aug 2004 07:28:13 -0700 Received: (qmail 28287 invoked from network); 1 Aug 2004 14:20:58 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 1 Aug 2004 14:20:58 -0000 Date: Sun, 1 Aug 2004 16:27:59 +0200 From: Adrian Bunk To: Marcelo Tosatti , Stephen Hemminger Cc: linux-kernel@vger.kernel.org, davem@redhat.com, netdev@oss.sgi.com Subject: [2.4 patch] CONFIG_NET_SCH_NETEM Configure.help entry Message-ID: <20040801142759.GQ2746@fs.tum.de> References: <20040731142658.GA6497@logos.cnet> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040731142658.GA6497@logos.cnet> User-Agent: Mutt/1.5.6i X-archive-position: 7388 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev On Sat, Jul 31, 2004 at 11:26:59AM -0300, Marcelo Tosatti wrote: >... > Summary of changes from v2.4.27-rc3 to v2.4.27-rc4 > ============================================ >... > Stephen Hemminger: > o [PKT_SCHED]: Update to network emulation QOS scheduler > o [PKT_SCHED]: One small netem fixes > o [BRIDGE]: Fix assertion failure in 2.4.27-rc3 > o [PKT_SCHED]: netem update for 2.4 >... The Configure.help entry was forgotten: Signed-off-by: Adrian Bunk --- linux-2.4.27-rc4-full/Documentation/Configure.help.old 2004-08-01 16:20:15.000000000 +0200 +++ linux-2.4.27-rc4-full/Documentation/Configure.help 2004-08-01 16:22:23.000000000 +0200 @@ -10949,13 +10949,15 @@ whenever you want). If you want to compile it as a module, say M here and read . -Network delay simualtor -CONFIG_NET_SCH_DELAY - Say Y if you want to delay packets by a fixed amount of - time. This is often useful to simulate network delay when +CONFIG_NET_SCH_NETEM + Say Y if you want to emulate network delay, loss, and packet + re-ordering. This is often useful to simulate networks when testing applications or protocols. - - This code is also available as a module called sch_delay.o + + To compile this driver as a module, choose M here: the module + will be called sch_netem. + + If unsure, say N. Ingress Qdisc CONFIG_NET_SCH_INGRESS From bunk@fs.tum.de Sun Aug 1 07:33:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 07:33:22 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i71EXG3b020415 for ; Sun, 1 Aug 2004 07:33:17 -0700 Received: (qmail 28500 invoked from network); 1 Aug 2004 14:26:05 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 1 Aug 2004 14:26:05 -0000 Date: Sun, 1 Aug 2004 16:33:07 +0200 From: Adrian Bunk To: Stephen Hemminger Cc: linux-kernel@vger.kernel.org, davem@redhat.com, netdev@oss.sgi.com Subject: [2.6 patch] update NET_SCH_NETEM help text Message-ID: <20040801143307.GR2746@fs.tum.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-archive-position: 7389 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev The patch below contains the following changes for the NET_SCH_NETEM help text: - correct the module name - "If unsure, say N." Signed-off-by: Adrian Bunk --- linux-2.6.8-rc2-mm1-full/net/sched/Kconfig.old 2004-08-01 16:28:22.000000000 +0200 +++ linux-2.6.8-rc2-mm1-full/net/sched/Kconfig 2004-08-01 16:29:12.000000000 +0200 @@ -207,19 +207,21 @@ config NET_SCH_NETEM tristate "Network emulator" depends on NET_SCHED help Say Y if you want to emulate network delay, loss, and packet re-ordering. This is often useful to simulate networks when testing applications or protocols. To compile this driver as a module, choose M here: the module - will be called sch_delay. + will be called sch_netem. + + If unsure, say N. config NET_SCH_INGRESS tristate "Ingress Qdisc" depends on NET_SCHED help If you say Y here, you will be able to police incoming bandwidth and drop packets when this bandwidth exceeds your desired rate. If unsure, say Y. From rddunlap@osdl.org Sun Aug 1 10:43:38 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:43:44 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HhbY4027638 for ; Sun, 1 Aug 2004 10:43:38 -0700 Received: from dragon.pdx.osdl.net (dragon.pdx.osdl.net [172.20.1.27]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i71HhP116814; Sun, 1 Aug 2004 10:43:26 -0700 Date: Sun, 1 Aug 2004 10:22:47 -0700 From: "Randy.Dunlap" To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver Message-Id: <20040801102247.33363e99.rddunlap@osdl.org> In-Reply-To: <200407311521.i6VFLcOC022100@nlp0.cs.usyd.edu.au> References: <200407311521.i6VFLcOC022100@nlp0.cs.usyd.edu.au> Organization: OSDL X-Mailer: Sylpheed version 0.9.10 (GTK+ 1.2.10; i686-pc-linux-gnu) X-Face: +5V?h'hZQPB9kW Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7390 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rddunlap@osdl.org Precedence: bulk X-list: netdev (moving this to netdev mailing list) On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | I would like to be able to boot the kernel with parameters that | will allow control of the tulip device. On some ethernet devices | this used to be possible via (something like): | | ether=0,0,1,0,eth0 | | which would pass the four numeric parameters (as, I think, dev->irq, | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | controlled eth0. A convention adopted by some net drivers then allowed | dev->mem_start to be interpretted as a set of flags that would control | device characteristics (e.g. full-duplex vs half-duplex mode). | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | if (dev->mem_start & MEDIA_MASK) | tp->default_port = dev->mem_start & MEDIA_MASK; | | suggests that this might still work. However, I have been unable | to force dev->mem_start in that driver to become non-zero via any | kernel boot-time parameters. My limited understanding of the code | that precedes the above lines in that file suggests that the "dev" | structure is not what it used to be... The driver never calls netdev_boot_setup_check(), which is what would give the driver its command line parameters. Did this work in early 2.6.x? There have been several changes in this area. The driver can't do a simple call to netdev_boot_setup_check() because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, and those values come from PCI config space for PCI drivers. The driver could create a fake for that purpose, but it's more likely that ethtool or mii-tool should be used to change media/speed etc... Although now that I look at the driver source code, I don't see ethtool or mii-tool support for those options. | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | mentions "ether=..." but marks it as obsolete, replaced by | the equivalent "netdev=...". Elsewhere in that file, the entry | for "netdev=..." describes what appears to be the functionality | that I seek. | | So, is it still possible to perform the same sort of control | operations on a tulip driver via kernel boot-time parameters | as one can do via module load-time parameters? If so, how? The current tulip-core driver supports setting only the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image (using mem_start, as you noted above). When modular, it supports that plus forcing full duplex and MTU for jumbo frames. Anyone have more definite answers on this? -- ~Randy From kaber@trash.net Sun Aug 1 10:51:35 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:51:44 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HpYw8028091 for ; Sun, 1 Aug 2004 10:51:35 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 74DC919F353; Sun, 1 Aug 2004 19:51:25 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id B89CB3940EE; Sun, 1 Aug 2004 19:51:20 +0200 (CEST) Message-ID: <410D2E30.2050104@trash.net> Date: Sun, 01 Aug 2004 19:53:52 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: Tomasz Paszkowski Cc: "David S. Miller" , hadi@cyberus.ca, devik@cdi.cz, netdev@oss.sgi.com Subject: Re: Fw: hfsc and huge set of rules References: <20040729211844.61e8d328.davem@redhat.com> <410A2449.3020701@trash.net> <20040730110815.GA7812@krezus.e-wro.net> In-Reply-To: <20040730110815.GA7812@krezus.e-wro.net> Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7391 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev Tomasz Paszkowski wrote: >On Fri, Jul 30, 2004 at 12:34:49PM +0200, Patrick McHardy wrote: > > >>hfsc_destroy_qdisc takes O(n) time wrt. the number of classes, >>but 5-6 seconds is still long. If all these classes contain inner >>qdiscs other than the default, I guess removing the classes from >>dev->qdisc_list in qdisc_destroy takes up most of the time, with >>n O(n) operations. The __qdisc_destroy rcu callback also calls >>reset before destroy, I don't know any qdisc where this is really >>neccessary. Without inner qdiscs, I need to see the script first to >>judge what's going wrong. Tomasz ? >> >> > >http://www.e-wro.pl/~acid/tc.batch.gz. In my opinion it's not the case >of expensive algorithms, but the number of classes. With this rule set loaded >(tc -b tc.batch) command: > >for i in 'e1.903 e0.930 e0.931 e0.932' ; do > tc qdisc del dev ${i} root >done >completly freezes machine for about 5-6 seconds. > > I've done some profiles with your script (on an old kernel without the lockless loopback patch), qdisc_destroy takes up 89% of the time when destroying the qdiscs. These are the exact results: - execute the script on unpatched kernel: time: real 2m28.822s user 0m2.347s sys 2m25.395s top 5 in profile: 799773 65.4986 vmlinux vmlinux qdisc_lookup 199964 16.3763 vmlinux vmlinux qdisc_destroy 92504 7.5758 sch_hfsc.ko sch_hfsc hfsc_adjust_levels 36722 3.0074 sch_hfsc.ko sch_hfsc hfsc_get_class 12471 1.0213 vmlinux vmlinux mark_offset_tsc - execute the script on kernel using double-linked lists for dev->qdisc_list: time: real 0m51.804s user 0m2.286s sys 0m48.795s top 5 in profile: 201152 49.6049 vmlinux vmlinux qdisc_lookup 92706 22.8617 sch_hfsc.ko sch_hfsc hfsc_adjust_levels 37140 9.1589 sch_hfsc.ko sch_hfsc hfsc_get_class 12310 3.0357 sch_hfsc.ko sch_hfsc hfsc_bind_tcf 12190 3.0061 sch_hfsc.ko sch_hfsc hfsc_change_class - destroy the qdiscs on unpatched kernel: time: real 0m13.258s user 0m0.019s sys 0m13.206s top 5 in profile: 29839 89.5367 vmlinux vmlinux qdisc_destroy 1229 3.6878 sch_hfsc.ko sch_hfsc hfsc_reset_class 338 1.0142 vmlinux vmlinux mark_offset_tsc 289 0.8672 vmlinux vmlinux qdisc_reset 287 0.8612 sch_hfsc.ko sch_hfsc rtsc_init - destroy the qdiscs on kernel using double-linked lists for dev->qdisc_list: time: real 0m0.389s user 0m0.019s sys 0m0.363s top 5 in profile: 1261 33.6896 sch_hfsc.ko sch_hfsc hfsc_reset_class 311 8.3088 sch_hfsc.ko sch_hfsc rtsc_init 277 7.4005 vmlinux vmlinux qdisc_reset 187 4.9960 vmlinux vmlinux free_block 181 4.8357 vmlinux vmlinux kfree So double-linked lists clearly solve your problem. Using a hash would speed up creating the qdiscs even more, but it wastes too much memory in my opinion. I'm going to send a patch after I've fixed the other problems with qdisc_destroy. >I was trying do modify the code od hfsc_qdisc_destroy scheduling another >task using schedule_task (), but i don't have enough knowledge to do deal >with proper locking of qdisc structures. > > That doesn't work, hfsc_qdisc_destroy is called under a lock. Regards Patrick From kaber@trash.net Sun Aug 1 10:53:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 10:53:51 -0700 (PDT) Received: from www.legaleagle.de (legaleagle.de [217.160.128.82]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71HrkLp028447 for ; Sun, 1 Aug 2004 10:53:46 -0700 Received: from eru.coreworks.de (unknown [172.16.0.2]) by www.legaleagle.de (Postfix) with ESMTP id 7A7C519F353; Sun, 1 Aug 2004 19:53:37 +0200 (CEST) Received: from trash.net (unknown [172.16.0.123]) by eru.coreworks.de (Postfix) with ESMTP id D39343940EE; Sun, 1 Aug 2004 19:53:32 +0200 (CEST) Message-ID: <410D2EB4.1060205@trash.net> Date: Sun, 01 Aug 2004 19:56:04 +0200 From: Patrick McHardy User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040413 Debian/1.6-5 X-Accept-Language: en MIME-Version: 1.0 To: devik Cc: "David S. Miller" , hadi@cyberus.ca, netdev@oss.sgi.com, tomasz.paszkowski@e-wro.pl Subject: Re: Fw: hfsc and huge set of rules References: In-Reply-To: Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7392 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kaber@trash.net Precedence: bulk X-list: netdev devik wrote: >Also IIRC class lookup is done before each remove. With >hashing size a few tens of buckets the complexity >starts to be very near to O(n^2). > > I think the hash size of HTB, HFSC and CBQ should be increased, the hash function performs well even with 2^16. With HFSC using many classes doesn't scale well right now, but with the rbtree patches it will. Regards Patrick >devik > >On Fri, 30 Jul 2004, Patrick McHardy wrote: > > > >>David S. Miller wrote: >> >> >>>Looks like qdisc destruction has some expensive algorithms. >>>Any quick ideas about the root culprit at least in the hfsc >>>case? He says htb does it too. >>> >>> >>hfsc_destroy_qdisc takes O(n) time wrt. the number of classes, >>but 5-6 seconds is still long. If all these classes contain inner >>qdiscs other than the default, I guess removing the classes from >>dev->qdisc_list in qdisc_destroy takes up most of the time, with >>n O(n) operations. The __qdisc_destroy rcu callback also calls >>reset before destroy, I don't know any qdisc where this is really >>neccessary. Without inner qdiscs, I need to see the script first to >>judge what's going wrong. Tomasz ? >> >> From JDrabb@tampabay.rr.com Sun Aug 1 11:15:54 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 11:16:01 -0700 (PDT) Received: from ms-smtp-03.tampabay.rr.com (ms-smtp-03-smtplb.tampabay.rr.com [65.32.5.133]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71IFrin029245 for ; Sun, 1 Aug 2004 11:15:54 -0700 Received: from [192.168.1.101] (189-66.35-65.tampabay.rr.com [65.35.66.189]) by ms-smtp-03.tampabay.rr.com (8.12.10/8.12.7) with ESMTP id i71IFgfP011721; Sun, 1 Aug 2004 14:15:42 -0400 (EDT) Message-ID: <410D3377.3030505@tampabay.rr.com> Date: Sun, 01 Aug 2004 14:16:23 -0400 From: James Drabb User-Agent: Mozilla Thunderbird 0.7.1 (X11/20040626) X-Accept-Language: en-us, en MIME-Version: 1.0 To: netdev@oss.sgi.com CC: c-d.hailfinger.kernel.2004@gmx.net, manfred@colorfullife.com Subject: forcedeth Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Symantec AntiVirus Scan Engine X-archive-position: 7393 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: JDrabb@tampabay.rr.com Precedence: bulk X-list: netdev I am having some issues with the forcedeth driver. jim@keelie $ modinfo forcedeth parm: max_interrupt_work:forcedeth maximum events handled per interrupt author: Manfred Spraul description: Reverse Engineered nForce ethernet driver license: GPL vermagic: 2.6.7-1 686 REGPARM gcc-3.3 depends: alias: pci:v000010DEd000001C3sv*sd*bc*sc*i* alias: pci:v000010DEd00000066sv*sd*bc*sc*i* alias: pci:v000010DEd000000D6sv*sd*bc*sc*i* jim@keelie $ uname -a Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 GNU/Linux My system is an Athlon XP 2800+, on an MSI K7N2 Delta Mobo based on the NForce 2 chipset. I have a dual boot with WinXP and Fedora Core 2 and spend 99% of my time in FC2. Once in a while I shut the system down. When I boot from a cold boot right into FC2, the forcedeth driver appears not to work. I am not able to get to the net over my cable mode. Bringing eth0 up and down, unplugging the network cable does nothing. However, if I reboot into WinXP, and then reboot right away back into FC2, the forcedeth driver works like a champ. Is there anything I can do to look into what might be causing this issue? Any more information I may be able to send to help? Thanks for any help, -- James Drabb Senior Programmer Davenport, FL USA From scarfboy@gmail.com Sun Aug 1 12:03:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:03:43 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.204]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71J3ajP030662 for ; Sun, 1 Aug 2004 12:03:37 -0700 Received: by mproxy.gmail.com with SMTP id 73so103371rnk for ; Sun, 01 Aug 2004 12:03:32 -0700 (PDT) Received: by 10.38.181.17 with SMTP id d17mr222682rnf; Sun, 01 Aug 2004 12:03:32 -0700 (PDT) Message-ID: Date: Sun, 1 Aug 2004 21:03:32 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: <20040731231836.A31121@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_60_22762740.1091387012317" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> X-archive-position: 7394 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_60_22762740.1091387012317 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline On Sat, 31 Jul 2004 23:18:36 +0200, Francois Romieu wrote: > > Right, both computers now run 2.6.8-rc2-mm1. It's better. Roughly > > speaking, the top *benchmark* speeds, rouding slightly up, are: > > udp: 33MB/s (using ~26Kints) one way, 12MB/s (9Kints/s) the other, > > tcp: 22MB/s (16Kints)one way, 12MB/s (9Kints/s) the other. > > > > (The 9Kints ca be 12 when the packet size is 1K or 2K) > > Can you give a try to a napi version of the module (it is a compile-time > option) ? > You may want higher {r/w}mem_max as well as renicing ksoftirqd with > a strongly < 0 value on the celeron client. That's with NAPI on both. I notice r/wmem has an effect, but it's not much. Although on my new computer it seems moot as there's something weird going on with interrupts with my botherboard. > > Oddly enough, the slow direction is sending from my new computer > > (XP1700, KT333, 1GB ram) to my old (both running linux and the > > mentioned kernel). I'm fairly sure this is due to the fact that my > > The r8169 driver has been reported to be faster on Rx than on Tx so your > observation makes sense. How does that make sense? When one side receives, the other sends, hrm? They're two identical cards, it should be entirely symmetrical assuming equal hardware - not faster on the years older hardware. > [...] > > I guess I'll have to settle for this. I'm just annoyed that the 'giga' > > is basically a joke, especially on my setup. > > It should be possible to make things slightly better for the celeron box > as a client. I'll cook up a patch. The celeron box is the server, that's the entire point. Anyhow, it's much faster in transmission than my new computer right now due to said mobo problem, so I *want* it as the server. > Would you be kind enough to do some ftp transfer test where the celeron > box retrieves data and send the 'vmstat 1' output of the client during > the test ? Sure, but I can tell you right now with reasonable certaintly that my new computer won't top 9000interrupts/sec, i.e. 9000 packets per second, and therefore do the 12MB/s at most, and probably less; interruptwise, my new computer is the bottleneck, and I'm guessing UDP is faster because TCP is limited by the amount of packets, or in the other direction ACKs, it can send per second. Transfers to the celeron are a relatively pointless measure because of my new computer being horribly interrupt limited at the moment. That may have started when I installed the gbit card, but mostly because it disturbs the mobo's precious and unguessable hardware balance. I'll try figuring out if I can solve it, but basically it just involves swapping around cards until it works better, so that'ld take a while. Attached are the vmstats for an ftp and nfs transfer, as measured from my old computer (the nfs and ftp server). Both were going at a pretty low speed, sub-9000 packets; this may have to do with drive fragmentation, my hard drives are rather full at the moment. Also, the logs on the client (my new computer) while sending data to my old one. These were made at a different time, and I believe the transfer rate was better (6MB for ftp, 9MB for nfs) than for the -to-old- logs, which were worse, and varied more. --Bart ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="ftp-put-to-old-computer__lin-mm-to-lin-mm_larger" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="ftp-put-to-old-computer__lin-mm-to-lin-mm_larger" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg IDQ4NTMyICAyOTY0OCAxNzU0NjQgICAgMCAgICAwICAgMTAxICAgIDMxICAyNzMgICAxNjkgMTUg IDIgODAgIDIKIDAgIDAgICAgICAwICA0ODUzMiAgMjk2NDggMTc1NDY4ICAgIDAgICAgMCAgICAg MCAgICAgMCAxMDA3ICAgICA5ICAwICAxIDk5ICAwCiAxICAwICAgICAgMCAgNDU3OTYgIDI5NjQ4 IDE3ODIxMiAgICAwICAgIDAgICAgIDAgICAgIDAgMjg3MyAgICAzNSAgMiAzMyA2NSAgMAogMSAg MCAgICAgIDAgIDM5MjE2ICAyOTY0OCAxODQ1MzIgICAgMCAgICAwICAgICAwICAgICAwIDUxMzEg ICAgMzYgIDcgNzYgMTcgIDAKIDEgIDAgICAgICAwICAzMjgyMCAgMjk2NDggMTkxMzQ4ICAgIDAg ICAgMCAgICAgMCAgICAgMCA0OTM4ICAgIDUyICA3IDc3IDE2ICAwCiAwICAxICAgICAgMCAgMjg3 ODggIDI5OTA4IDE5NTAyOCAgICAwICAgIDAgICAgIDAgIDQ2MjggMzI3NiAgICA0MSAgNCA0NyAy NiAyMwogMSAgMSAgICAgIDAgIDI0MzA4ICAyOTkwOCAxOTkwMjAgICAgMCAgICAwICAgICAwICA4 NjU2IDQyMTEgICAgNDAgIDggOTAgIDAgIDIKIDEgIDAgICAgICAwICAyMDU5NiAgMjk5MDggMjAy NzI0ICAgIDAgICAgMCAgICAgMCAgNjUwMCAzOTY0ICAgMjU3ICA2IDk0ICAwICAwCiAxICAwICAg ICAgMCAgMTM5NDAgIDI5OTA4IDIwOTQwNCAgICAwICAgIDAgICAgIDAgICAgIDAgNTk5NCAgICAx NCAgOCA5MiAgMCAgMAogMSAgMCAgICAgIDAgICA3MjE2ICAyOTkwOCAyMTYxMTYgICAgMCAgICAw ICAgICAwICAgICA4IDU5OTYgICAgMTIgIDYgOTQgIDAgIDAKIDEgIDAgICAgICAwICAgMjQwOCAg Mjk4NDAgMjIxMDg0ICAgIDAgICAgMCAgICAgMCAgICAgOCA1OTMxICAgIDI4ICA4IDkyICAwICAw CiAxICAwICAgICAgMCAgIDI4NTYgIDI5NzQwIDIyMTMyMCAgICAwICAgIDAgICAgIDAgIDExODQg NTU3NCAgICA1MSAgNSA5NSAgMCAgMAogMSAgMSAgICAgIDAgICAyNTM2ICAzMDQwMCAyMjE0MDAg ICAgMCAgICAwICAgICAwICA2NTI0IDQ4ODYgICAgOTAgIDYgOTQgIDAgIDAKIDEgIDIgICAgICAw ICAgMjg1NiAgMzAyNzYgMjIxNTgwICAgIDAgICAgMCAgICAgMCAgNzc4MCA0Mjc5ICAgIDczICA3 IDkzICAwICAwCiAxICAyICAgICAgMCAgIDI0MDggIDMwMjQ4IDIyMjM2OCAgICAwICAgIDAgICAg IDAgIDYzNjggNDI1MSAgICA3MyAgNSA5NSAgMCAgMAogMSAgMiAgICAgIDAgICAyMjQ0ICAyOTkw NCAyMjMyNjAgICAgMCAgICAwICAgICAwICA2MzQ0IDQ5NTIgICAgNjggIDYgOTQgIDAgIDAKIDEg IDIgICAgICAwICAgMzExNiAgMjk2MzYgMjIyOTYwICAgIDAgICAgMCAgICAgMCAgNTI0NCA0MTYz ICAgIDgxICA4IDkyICAwICAwCiAxICAxICAgICAgMCAgIDI0NzIgIDI5NTI4IDIyMzk2OCAgICAw ICAgIDAgICAgIDAgIDU2NjQgNDczMSAgIDEwMSAgNyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAy OTIwICAyOTQxNiAyMjQwMjAgICAgMCAgICAwICAgICAwICAxMjY4IDUxMjQgICAxOTQgIDYgOTQg IDAgIDAKIDEgIDAgICAgICAwICAgMjk4NCAgMjkxMzIgMjI0NjI4ICAgIDAgICAgMCAgICAgMCAg IDYzNiA1ODI1ICAgIDQwICA4IDkyICAwICAwCiAxICAwICAgICAgMCAgIDIyODAgIDI4OTQ0IDIy NTc5NiAgICAwICAgIDAgICAgIDAgIDY2NjggNDgwNyAgICA3MyAgNiA5NCAgMCAgMApwcm9jcyAt LS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVt LS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBz byAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAyICAwICAgICAgMCAgIDIyNjAg IDI4NjY4IDIyNjM1MiAgICAwICAgIDAgICAgIDAgIDM5NzYgNDk3MyAgICA3NyAgNyA5MyAgMCAg MAogMSAgMCAgICAgIDAgICAyNDA4ICAyODQyMCAyMjY2NjQgICAgMCAgICAwICAgICAwICA1MzIw IDQ1MTQgICAgOTYgIDYgOTQgIDAgIDAKIDEgIDEgICAgICAwICAgMjY2NCAgMjgzNjggMjI2NDgw ICAgIDAgICAgMCAgICAgMCAxOTI2NCAzMjYxICAgIDQ0ICA2IDk0ICAwICAwCiAxICAxICAgICAg MCAgIDI0NzYgIDI4Mjg4IDIyNjczMiAgICAwICAgIDAgICAgIDAgMTYxODQgMjEyNCAgIDI1MiAg NyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIwICAyODA1NiAyMjY5NjggICAgMCAgICAwICAg ICAwICAgNTM2IDM4OTggICAgNjcgIDcgOTMgIDAgIDAKIDEgIDAgICAgICAwICAgMjgwNCAgMjc2 OTYgMjI3NzAwICAgIDAgICAgMCAgICAgMCAgICAgOCA1ODYzICAgIDUzICA2IDk0ICAwICAwCiAx ICAwICAgICAgMCAgIDI5ODQgIDI3NTA0IDIyNzkyOCAgICAwICAgIDAgICAgIDAgICAgIDggNTky OSAgICA3MCAgNyA5MyAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIwICAyNzAwOCAyMjg2NDggICAg MCAgICAwICAgICAwICAgICA0IDU5NDkgICAgNTMgIDkgOTEgIDAgIDAKIDEgIDAgICAgICAwICAg MjQwOCAgMjY4NDAgMjI5NDY4ICAgIDAgICAgMCAgICAgMCAgMTQzNiA1NTQzICAgIDUwICA2IDk0 ICAwICAwCiAyICAwICAgICAgMCAgIDI3OTIgIDI2ODA4IDIyODU2MCAgICAwICAgIDAgICAgIDAg MzU1MzIgMzY4NSAgICA0NiAgOCA5MiAgMCAgMAogMSAgMSAgICAgIDAgICAzMDY0ICAyNjcxNiAy Mjg5MTYgICAgMCAgICAwICAgICAwICAgICAwIDIwODUgICAyMTcgIDggOTIgIDAgIDAKIDEgIDAg ICAgICAwICAgMjk4NCAgMjY1MjAgMjI5NTcyICAgIDAgICAgMCAgICAgMCAgIDE2MCAzNzUxICAg IDY5ICA2IDk0ICAwICAwCiAxICAwICAgICAgMCAgIDI1MzYgIDI2MzUyIDIzMDMyNCAgICAwICAg IDAgICAgIDAgICAgIDggNTk1MyAgICA1MCAgOCA5MiAgMCAgMAogMSAgMCAgICAgIDAgICAyOTIw ICAyNDExNiAyMzIzMzIgICAgMCAgICAwICAgICAwICAgICA4IDU4OTQgICAgNTMgIDcgOTMgIDAg IDAKIDEgIDAgICAgICAwICAgMzA0OCAgMjI0MjAgMjM0MTgwICAgIDAgICAgMCAgICAgMCAgICAg NCA1OTQ1ICAgIDQ4ICA2IDk0ICAwICAwCiAxICAwICAgICAgMCAgIDMxMTIgIDIxMDY0IDIzNTM5 NiAgICAwICAgIDAgICAgIDAgIDEzNDggNTQ3NiAgICA1NSAgNyA5MSAgMiAgMAogMSAgMSAgICAg IDAgICAxOTQ0ICAyMDU3MiAyMzY1MDggICAgMCAgICAwICAgICAwIDM1NjUyIDM2MjggICAgNTIg IDYgOTQgIDAgIDAKIDAgIDIgICAgICAwICAgMjEzMiAgMjAwNTYgMjM3MDQ4ICAgIDAgICAgMCAg MTA2NCAgICAgMCAxMTI1ICAgMTUwICA3IDIyICAwIDcwCiAxICAxICAgICAgMCAgIDMxODggIDE4 OTg0IDIzNjQwOCAgICAwICAgIDAgICAyMjQgICAgIDAgMTA3NyAgIDEwOCA2MSAxMCAgMCAyOQog MCAgMCAgICAgIDAgICA0NjE2ICAxODk4NCAyMzY0MDggICAgMCAgICAwICAgICAwICAgMTQ0IDEw MzQgICAgMzQgIDIgIDIgODMgMTMKIDAgIDAgICAgICAwICAgNDYxNiAgMTg5ODQgMjM2NDA4ICAg IDAgICAgMCAgICAgMCAgICAgMCAxMDA2ICAgIDEwICAwICAwIDEwMCAgMApwcm9jcyAtLS0tLS0t LS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVtLS0gLS0t LWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBzbyAgICBi aSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAxICAwICAgICAgMCAxNzg1MTYgIDE4OTg0 ICA2MzY3NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwOSAgICAxMiAgMCAzMyA2NyAgMAogMCAg MCAgICAgIDAgMTc3NTcyICAyMDE4MCAgNjM2ODAgICAgMCAgICAwICAgIDQ4ICAxMTkyIDEwMzMg ICAgNzMgIDEgIDQgNzAgMjUKIDAgIDAgICAgICAwIDE3NzU3MiAgMjAxODAgIDYzNjgwICAgIDAg ICAgMCAgICAgMCAgICAgMCAxMDA4ICAgIDEwICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc3 ODkyICAyMDIxNiAgNjM2ODAgICAgMCAgICAwICAgICAwICAxMTI0IDEyMjQgICAgMzkgIDAgIDMg NDAgNTcKIDAgIDAgICAgICAwIDE3Nzg5MiAgMjAyMTYgIDYzNjg0ICAgIDAgICAgMCAgICAgMCAg ICAgMCAxMDY3ICAgIDEzICAwICAxIDg1IDE0CiAwICAwICAgICAgMCAxNzc4OTIgIDIwMjIwICA2 MzY4OCAgICAwICAgIDAgICAgIDggICAgIDAgMTAxMSAgICAxNiAgMCAgMCA5OSAgMQo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="nfs-to-old-computer__lin-mm-to-lin-mm" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="nfs-to-old-computer__lin-mm-to-lin-mm" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg MTc4MjQwICAyMDM2MCAgNjM2ODggICAgMCAgICAwICAgMTAxICAgIDMzICAyNzYgICAxNjkgMTUg IDIgODAgIDIKIDAgIDAgICAgICAwIDE3ODI0MCAgMjA0MDAgIDYzNjk2ICAgIDAgICAgMCAgICAg OCAgICA2OCAxMDE5ICAgIDI3ICAwICAxIDk2ICAzCiAwICAwICAgICAgMCAxNzgyNDAgIDIwNDAw ICA2MzY5NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwNiAgICAgOCAgMCAgMCAxMDAgIDAKIDAg IDAgICAgICAwIDE3ODI0MCAgMjA0MDAgIDYzNjk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMDA4 ICAgIDE0ICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc4MjQwICAyMDQwMCAgNjM2OTYgICAg MCAgICAwICAgICAwICAgICAwIDEwMDQgICAgMTIgIDAgIDAgMTAwICAwCiAwICAwICAgICAgMCAx NzgyNDAgIDIwNDAwICA2MzY5NiAgICAwICAgIDAgICAgIDAgICAgIDAgMTAwNSAgICAxNCAgMCAg MCAxMDAgIDAKIDAgIDAgICAgICAwIDE3ODI0MCAgMjA0MTIgIDYzNjk2ICAgIDAgICAgMCAgICAg MCAgICAyMCAxMDExICAgIDIwICAwICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTc4MTc2ICAyMDQ2 MCAgNjM2OTYgICAgMCAgICAwICAgICA0ICAgIDcyIDEwMjQgICAgMzcgIDAgIDAgOTkgIDEKIDEg IDAgICAgICAwIDE3MTAxMiAgMjA0NjggIDcwNTEyICAgIDAgICAgMCAgICAgMCAgICAgMCAyNTg5 ICAgMjIyICAwIDc1IDI1ICAwCiAxICAwICAgICAgMCAxNjIyNDQgIDIwNDc2ICA3OTI4MCAgICAw ICAgIDAgICAgIDAgICAgIDAgNTQ5NyAgIDI4OSAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwIDE1 MzczMiAgMjA0ODQgIDg4MDQ4ICAgIDAgICAgMCAgICAgMCAgICAgMCA1NjE4ICAxMjE0ICAwIDEw MCAgMCAgMAogMSAgMSAgICAgIDAgMTQ1NTQwICAyMTAxNiAgOTUyODAgICAgMCAgICAwICAgICAw ICA1ODQ4IDQ4ODcgICA1MjggIDEgOTkgIDAgIDAKIDEgIDEgICAgICAwIDEzOTI2OCAgMjEwMjAg MTAxNTUyICAgIDAgICAgMCAgICAgMCAgNTI3NiA0NDE0ICAxMjYwICAwIDEwMCAgMCAgMAogMSAg MiAgICAgIDAgMTMyMjI4ICAyMTAyOCAxMDg2NTYgICAgMCAgICAwICAgICAwICAyODI4IDQ5OTIg IDU1MDAgIDAgMTAwICAwICAwCiAxICAyICAgICAgMCAxMjUzODAgIDIxMDM2IDExNTQwOCAgICAw ICAgIDAgICAgIDAgIDQzMjAgNDg4NSAgNjAyNCAgMCAxMDAgIDAgIDAKIDEgIDIgICAgICAwIDEx OTA0NCAgMjEwNDAgMTIxODQwICAgIDAgICAgMCAgICAgMCAgNTc2MCA1MzUyICA1ODI5ICAwIDEw MCAgMCAgMAogMSAgMiAgICAgIDAgMTEzOTg4ICAyMTA0OCAxMjY4MzIgICAgMCAgICAwICAgICAw ICA2MTk2IDQyNjggIDQ3MzEgIDEgOTkgIDAgIDAKIDIgIDEgICAgICAwIDEwOTc2NCAgMjEwNTIg MTMwODg4ICAgIDAgICAgMCAgICAgMCAgNTIyNCA0MDExICAzNzY2ICAwIDY0ICAwIDM2CiAxICAw ICAgICAgMCAxMDM4NzYgIDIxMDU2IDEzNjgxMiAgICAwICAgIDAgICAgIDAgIDc4NzYgNDgzMSAg NTYxOCAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwICA5NjUxNiAgMjEwNjQgMTQzOTE2ICAgIDAg ICAgMCAgICAgMCAgICAgMCA1NTI5ICA2NjcxICAwIDEwMCAgMCAgMAogMSAgMCAgICAgIDAgIDkx MzMyICAyMTA2OCAxNDkwNjggICAgMCAgICAwICAgICAwICA5MzQ4IDM4MDQgIDQ4NjQgIDAgMTAw ICAwICAwCnByb2NzIC0tLS0tLS0tLS0tbWVtb3J5LS0tLS0tLS0tLSAtLS1zd2FwLS0gLS0tLS1p by0tLS0gLS1zeXN0ZW0tLSAtLS0tY3B1LS0tLQogciAgYiAgIHN3cGQgICBmcmVlICAgYnVmZiAg Y2FjaGUgICBzaSAgIHNvICAgIGJpICAgIGJvICAgaW4gICAgY3MgdXMgc3kgaWQgd2EKIDIgIDEg ICAgICAwICA4Mjk0OCAgMjEwNzYgMTU3MDY0ICAgIDAgICAgMCAgICAgMCAgNjcyNCA2Mjg3ICA3 NTAzICAwIDEwMCAgMCAgMAogMSAgMSAgICAgIDAgIDc5MzY0ICAyMTM1NiAxNTk4NDggICAgMCAg ICAwICAgICAwIDM2MjIwIDE5NjcgIDI3MTkgIDAgMTAwICAwICAwCiAxICAxICAgICAgMCAgNzYy MjggIDIxMzYwIDE2MzMzNiAgICAwICAgIDAgICAgIDAgICAgIDAgMjA2NCAgMzMzNSAgMCAxMDAg IDAgIDAKIDEgIDAgICAgICAwICA3MTYyMCAgMjEzNjQgMTY4MjI0ICAgIDAgICAgMCAgICAgMCAg IDI4MCAzNDIyICA0NTc2ICAxIDk5ICAwICAwCiAxICAwICAgICAgMCAgNjc3MTYgIDIxNDI0IDE3 MjA5MiAgICAwICAgIDAgICAgIDAgMTA4MDggMzY4MSAgMzc3NSAgMCA1NiAgMCA0NAogMSAgMCAg ICAgIDAgIDU5Mzk2ICAyMTQzMiAxODAyODQgICAgMCAgICAwICAgICAwICAgICAwIDYzNTYgIDc2 NzYgIDAgMTAwICAwICAwCiAxICAwICAgICAgMCAgNTEwMTIgIDIxNDQwIDE4ODUzNiAgICAwICAg IDAgICAgIDAgICAgIDAgNjM3OSAgNzczOSAgMCAxMDAgIDAgIDAKIDEgIDAgICAgICAwICA0MjYy OCAgMjE0NDggMTk2ODM2ICAgIDAgICAgMCAgICAgMCAgICAgMCA2NDY1ICA3NzcyICAwIDEwMCAg MCAgMAogMSAgMSAgICAgIDAgIDM1NDYwICAyMTUzMiAyMDMyNTYgICAgMCAgICAwICAgICAwIDMz MzM2IDQ4MzYgIDU5ODYgIDAgMTAwICAwICAwCiAxICAxICAgICAgMCAgMzIxOTYgIDIxNTM2IDIw Njg1MiAgICAwICAgIDAgICAgIDAgICAgIDAgMjE4MCAgMzQzMCAgMCAxMDAgIDAgIDAKIDEgIDAg ICAgICAwICAyNzkwOCAgMjE1NDAgMjExMjUyICAgIDAgICAgMCAgICAgMCAgIDM3NiAzMDIxICA0 MTY1ICAwIDEwMCAgMCAgMAogMSAgMCAgICAgIDAgIDE5NjUyICAyMTU0OCAyMTk0MjggICAgMCAg ICAwICAgICAwICAgICA0IDYxNTQgIDc2NjEgIDAgMTAwICAwICAwCiAxICAwICAgICAgMCAgMTE1 MjQgIDIxNTU2IDIyNzUwNCAgICAwICAgIDAgICAgIDAgICAgIDQgNjQxNiAgNzU2MyAgMCAxMDAg IDAgIDAKIDEgIDAgICAgICAwICAgMzEyOCAgMjE1NjQgMjM1NzcyICAgIDAgICAgMCAgICAgMCAg ICAgMCA2NDMyICA3NzQ2ICAxIDk5ICAwICAwCiAzICAwICAgICAgMCAgIDIzNTIgIDE3NDI4IDI0 MDk4OCAgICAwICAgIDAgICAgIDAgIDM2MDQgNTQxMSAgNTk4MiAgMCAxMDAgIDAgIDAKIDAgIDIg ICAgICAwICAgMjgxNiAgMTYwODAgMjQxMDY0ICAgIDAgICAgMCAgICAgMCAzMjg2MCA0NjQzICAz MzY0ICAwIDg1ICAwIDE1CiAyICAxICAgICAgMCAgIDI4MzIgIDE1NjA0IDI0MTk0NCAgICAwICAg IDAgICAgIDAgICAyOTIgMjA5MSAgMjU5MSAgMCA4NCAgMCAxNgogMiAgMSAgICAgIDAgICAyNjAw ICAxNDgzNiAyNDM1MDQgICAgMCAgICAwICAgICAwICAzNjQwIDMzNTggIDQxNjcgIDAgMTAwICAw ICAwCiAyICAwICAgICAgMCAgIDI4NTYgIDEzODM2IDI0NDY2NCAgICAwICAgIDAgICAgIDAgIDU3 OTYgNDM5NiAgMTkzMSAgMCAxMDAgIDAgIDAKIDAgIDEgICAgICAwICAgMjIyNCAgMTM1MzIgMjQ1 NzQwICAgIDAgICAgMCAgICAgMCAgNDIyNCAyOTcwICAyMzEyICAwIDM1ICAwIDY1CiAwICAxICAg ICAgMCAgIDMwNjAgIDEzNDA0IDI0NDgyOCAgICAwICAgIDAgICAgIDAgIDgwMjggMTY2MCAgICA1 MiAgMCAgNSAgMCA5NQpwcm9jcyAtLS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0t IC0tLS0taW8tLS0tIC0tc3lzdGVtLS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAg IGJ1ZmYgIGNhY2hlICAgc2kgICBzbyAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdh CiAyICAwICAgICAgMCAgIDI3MzYgIDEzMzgwIDI0NTcwOCAgICAwICAgIDAgICAgIDAgIDMxNDgg MzMxMCAgMjMxNyAgMCA0MiAgMCA1OAogMSAgMCAgICAgIDAgICAyODU2ICAxMjYxNiAyNDY1MDAg ICAgMCAgICAwICAgICAwICAgICAwIDY4OTIgIDU3OTIgIDAgMTAwICAwICAwCiAxICAxICAgICAg MCAgIDI3MzIgIDEyMzk2IDI0NzU0NCAgICAwICAgIDAgICAgIDAgIDI2MjQgNjI4NyAgMTEzMSAg MCAxMDAgIDAgIDAKIDEgIDEgICAgICAwICAgMjUzNiAgMTIxMDAgMjQ4MTk2ICAgIDAgICAgMCAg ICAgMCAxMTQwNCAzOTQwICAgMjUxICAwIDEwMCAgMCAgMAo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="clientlog-ftpput" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="clientlog-ftpput" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg MTk4MzEyICA3MDMzNiAyNTgyNDAgICAgMCAgICAwICAgMjk5ICAgIDg1IDE1MzYgICA3NjcgIDgg IDYgNzggIDgKIDAgIDAgICAgICAwIDE5ODIyOCAgNzAzMzYgMjU4MzA4ICAgIDAgICAgMCAgICA2 OCAgICAgMCAxNDM3ICAgNDYzICAzICAxIDk0ICAyCiAwICAwICAgICAgMCAxOTgyMjggIDcwMzM2 IDI1ODMwOCAgICAwICAgIDAgICAgIDAgICAgIDAgMjAxMyAgMTU4OSAxMSAgNiA4MyAgMAogMCAg MSAgICAgIDAgMTk2NjUyICA3MDM4OCAyNTk4MjAgICAgMCAgICAwICAxNTA2ICAgIDkyIDIzMjkg ICA1NDAgIDIgIDMgODcgIDgKIDAgIDAgICAgICAwIDE5MDI0MCAgNzAzOTIgMjY2MjA4ICAgIDAg ICAgMCAgNjQxNCAgICAgMCA2NTY3ICAgODA4ICAwIDExIDg0ICA1CiAwICAwICAgICAgMCAxODM2 MDQgIDcwNDAwIDI3Mjg2NCAgICAwICAgIDAgIDY2NjIgICAgIDAgNjYxOCAgIDgxNCAgMCAxMCA4 NCAgNgogMCAgMCAgICAgIDAgMTc5MjM2ICA3MDQwNCAyNzcyMTIgICAgMCAgICAwICA0MzU3ICAg ICAwIDUzMDMgIDEzMDUgIDYgMTAgODEgIDMKIDAgIDAgICAgICAwIDE3NTAyNCAgNzA0MDggMjgx NDI0ICAgIDAgICAgMCAgNDIyOCAgICAgMCA0NTQ1ICAgNzEyICAxICA3IDg5ICAzCiAwICAwICAg ICAgMCAxNjc4MzIgIDcwNDI4IDI4ODEzNiAgICAwICAgIDAgIDY3MTggICAgMjAgNzM2OSAgMTAy NiAgOCAxMyA3MyAgNgogMCAgMCAgICAgIDAgMTYwNDkyICA3MDQzMiAyOTQ3OTYgICAgMCAgICAw ICA2NjYzICAgICAwIDY2NDggICA5MDYgIDAgIDkgODUgIDUKIDAgIDAgICAgICAwIDE1MzIzNiAg NzA0NDAgMzAxMzg0ICAgIDAgICAgMCAgNjUzNCAgICAgMCA2NjEyICAgOTA1ICAxIDExIDgzICA1 CiAwICAwICAgICAgMCAxNDU3NDggIDcwNDQ4IDMwODEwOCAgICAwICAgIDAgIDY3OTEgICAgIDAg NjY5NiAgIDkyNiAgMSAxMSA4MSAgNwogMCAgMCAgICAgIDAgMTQyNjEyICA3MDQ0OCAzMTA5NjQg ICAgMCAgICAwICAyODE4ICAgICAwIDM0NzcgICA2NDggIDEgIDUgOTIgIDIKIDAgIDAgICAgICAw IDE0MjYxMiAgNzA0NjAgMzEwOTUyICAgIDAgICAgMCAgICAgMCAgICAyMCAxMTEyICAgNTAwICAw ICAwIDEwMCAgMAogMCAgMCAgICAgIDAgMTM1OTU2ICA3MDQ2OCAzMTY5OTYgICAgMCAgICAwICA2 MDIyICAgICAwIDYxMjkgICA4NTYgIDEgMTAgODQgIDUKIDAgIDAgICAgICAwIDEyODcyNCAgNzA0 NzIgMzIzNTIwICAgIDAgICAgMCAgNjUzNSAgICAgMCA2NjcwICAgODg4ICAxIDEzIDgwICA2CiAw ICAwICAgICAgMCAxMjEzNjQgIDcwNDgwIDMzMDE3NiAgICAwICAgIDAgIDY2NjIgICAgIDAgNjYw NiAgIDg5NCAgMCAxMSA4MyAgNgogMCAgMCAgICAgIDAgMTE0MDA0ICA3MDQ4OCAzMzY4MzIgICAg MCAgICAwICA2NjYzICAgICAwIDY2NzggICA5MjUgIDEgMTIgODEgIDYKIDAgIDAgICAgICAwIDEw NzE1NiAgNzA1MDQgMzQyOTM2ICAgIDAgICAgMCAgNjE1MCAgICAyMCA2MzYwICAgODY3ICAxIDEw IDgyICA2CiAwICAwICAgICAgMCAxMDQzNDAgIDcwNTA4IDM0NTUxNiAgICAwICAgIDAgIDI1NjIg ICAgIDAgMzIwMCAgIDY4NSAgMSAgNSA5MSAgMwogMCAgMCAgICAgIDAgMTAxMzk2ICA3MDUwOCAz NDgxNjggICAgMCAgICAwICAyNjkxICAgICAwIDMzMzggICA2NDUgIDAgIDMgOTUgIDIKcHJvY3Mg LS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAtLXN5c3Rl bS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAgIHNpICAg c28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMiAgMCAgICAgIDAgIDk0MTY0 ICA3MDUxNiAzNTQ3NTYgICAgMCAgICAwICA2NTM0ICAgICAwIDY2OTggICA5MDQgIDEgMTEgODIg IDYKIDAgIDAgICAgICAwICA4Njc0MCAgNzA1MjQgMzYxNDEyICAgIDAgICAgMCAgNjY2MyAgICAg MCA2NjY4ICAgOTM1ICA0IDEyIDc3ICA2CiAwICAwICAgICAgMCAgNzkzODAgIDcwNTQwIDM2ODA2 MCAgICAwICAgIDAgIDY2NjIgICAgMjAgNjY1MSAgIDg5NyAgMSAxMSA4MyAgNQogMCAgMCAgICAg IDAgIDcyMDIwICA3MDU0OCAzNzQ3MTYgICAgMCAgICAwICA2NjYzICAgICAwIDY2ODUgICA5MDMg IDEgMTEgODIgIDYKIDAgIDAgICAgICAwICA2NjcyMCAgNzA1NTIgMzc5Njc2ICAgIDAgICAgMCAg NDk5NyAgICAgMCA1Nzc3ICAgODcxICAyICA4IDg1ICA0CiAxICAwICAgICAgMCAgNjQxNDggIDcw NTU2IDM4MTk4NCAgICAwICAgIDAgIDIzMDYgICAgIDAgMzMwOSAgMTAzOSAgNSAgNiA4NyAgMgog MCAgMCAgICAgIDAgIDYwNzY0ICA3MDU1NiAzODUwNDQgICAgMCAgICAwICAzMDc1ICAgICAwIDQw MTMgICA2MzEgIDEgIDYgOTEgIDIKIDAgIDAgICAgICAwICA1MzQwNCAgNzA1NzYgMzkxNjg4ICAg IDAgICAgMCAgNjY2MiAgICAyMCA3MzAyICAxMzkwICA1IDE1IDc0ICA2CiAxICAwICAgICAgMCAg NDY0MTIgIDcwNTgwIDM5ODAwOCAgICAwICAgIDAgIDYyNzggICAgIDAgNjgyNCAgMTQ1OSAgNiAx NSA3NSAgNAogMCAgMCAgICAgIDAgIDQ2NDEyICA3MDU4MCAzOTgwMDggICAgMCAgICAwICAgICAw ICAgICAwIDExOTEgICA0MDAgIDEgIDEgOTggIDAKIDAgIDAgICAgICAwICA0NjQxMiAgNzA1ODAg Mzk4MDA4ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMDkxICAgMzk2ICAwICAxIDk5ICAwCiAwICAw ICAgICAgMCAgNDY0MTIgIDcwNTgwIDM5ODAwOCAgICAwICAgIDAgICAgIDAgICAgIDAgMTExMyAg IDQzNiAgMSAgMCA5OSAgMAogMCAgMCAgICAgIDAgIDQ2NDEyICA3MDU5MiAzOTc5OTYgICAgMCAg ICAwICAgICAwICAgIDIwIDExMjcgICA1NjMgIDIgIDAgOTggIDAKIDAgIDAgICAgICAwICA0NjQx MiAgNzA1OTIgMzk3OTk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMTcxICAgNjE3ICAzICAxIDk2 ICAwCiAwICAwICAgICAgMCAgNDY0MjggIDcwNTkyIDM5Nzk5NiAgICAwICAgIDAgICAgIDAgICAg IDAgMTMwMCAgIDU4MCAgMyAgMSA5NiAgMAogMCAgMCAgICAgIDAgIDQ2NDI4ICA3MDU5MiAzOTc5 OTYgICAgMCAgICAwICAgICAwICAgICAwIDEwOTcgICA0MDkgIDEgIDAgOTkgIDAKIDAgIDAgICAg ICAwICA0NjQyOCAgNzA1OTIgMzk3OTk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMjAzICAgODA0 ICA1ICAxIDk0ICAwCiAwICAwICAgICAgMCAgNDYzMDAgIDcwNjQwIDM5ODAxNiAgICAwICAgIDAg ICAgIDAgICAxMTIgMTIzNiAgMTI3MyAxMSAgMyA4NiAgMAogMCAgMCAgICAgIDAgIDQ2MzAwICA3 MDY0MCAzOTgwMTYgICAgMCAgICAwICAgICAwICAgICAwIDE1NjggIDE1NzQgMTMgIDQgODMgIDAK IDAgIDAgICAgICAwICA0NjYyMCAgNzA2NDAgMzk4MDE2ICAgIDAgICAgMCAgICAgMCAgICAgMCAy Mjk4ICAxNDM5IDEyICA2IDgyICAwCiAwICAwICAgICAgMCAgNDY2NDggIDcwNjQwIDM5ODAxNiAg ICAwICAgIDAgICAgIDAgICAgIDAgMTQwOCAgIDkwOCAgNSAgMiA5MyAgMAo= ------=_Part_60_22762740.1091387012317 Content-Type: application/octet-stream; name="clientlog-nfsput" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="clientlog-nfsput" cHJvY3MgLS0tLS0tLS0tLS1tZW1vcnktLS0tLS0tLS0tIC0tLXN3YXAtLSAtLS0tLWlvLS0tLSAt LXN5c3RlbS0tIC0tLS1jcHUtLS0tCiByICBiICAgc3dwZCAgIGZyZWUgICBidWZmICBjYWNoZSAg IHNpICAgc28gICAgYmkgICAgYm8gICBpbiAgICBjcyB1cyBzeSBpZCB3YQogMSAgMCAgICAgIDAg IDE2Nzc2IDI5MjAxMiAxNjY5ODggICAgMCAgICAwICAgMjc2ICAgIDg3IDE1MjEgICA3NzAgIDgg IDYgNzggIDgKIDAgIDAgICAgICAwICAxNjc0OCAyOTIwMTIgMTY2OTg4ICAgIDAgICAgMCAgICAg MCAgICAgMCAxNDc2ICAgNDE2ICAzICAxIDk2ICAwCiAwICAwICAgICAgMCAgMTY3NDggMjkyMDEy IDE2Njk4OCAgICAwICAgIDAgICAgIDAgICAgIDAgMjY0MCAgMTU2NCAxMiAgNiA4MiAgMAogMCAg MCAgICAgIDAgIDE2NzQ4IDI5MjAxMiAxNjY5ODggICAgMCAgICAwICAgICAwICAgICAwIDExMDQg ICA0MjYgIDEgIDAgOTkgIDAKIDAgIDAgICAgICAwICAxNjc0OCAyOTIwMTIgMTY2OTg4ICAgIDAg ICAgMCAgICAgMCAgICAgMCAxMjE5ICAgNDM1ICAxICAxIDk4ICAwCiAwICAxICAgICAgMCAgMTUz NTYgMjkyMDUyIDE2ODMwOCAgICAwICAgIDAgICA3NDQgICAgODAgMTI1OSAgIDQ4OCAgMSAgMiA5 MyAgNAogMCAgMSAgICAgIDAgICA1MDM2IDI4NjU4MCAxODQ1MjQgICAgMCAgICAwICA5NDc2ICAg ICAwIDEyODQgICA2MjIgIDMgMTQgIDAgODMKIDAgIDEgICAgICAwICAgNDU4OCAyNzU2MzYgMTk4 ODY4ICAgIDAgICAgMCAgOTM0OCAgICAgMCAxMzAxICAgNjY0ICA0IDE3ICAwIDc5CiAwICAxICAg ICAgMCAgIDQ5NzIgMjY5Mzc2IDIwNjM1MiAgICAwICAgIDAgIDQ2MjUgICAgIDAgMTI2MyAgIDU2 NCAgMSAgOCAgMCA5MQogMSAgMSAgICAgIDAgICA1MjQ4IDI2NDI2OCAyMTIyMDggICAgMCAgICAw ICAzNzI1ICAgICAwIDE0OTUgICA2ODcgIDUgIDggIDAgODcKIDEgIDEgICAgICAwICAgNTI5MiAy Mzg3NjQgMjQzNzY0ICAgIDAgICAgMCAxOTM1OCAgICAxNiAyMTI5ICAxODg2IDE2IDM4ICAwIDQ3 CiAwICAxICAgICAgMCAgIDUxNjQgMjEyMzMyIDI3NDg4OCAgICAwICAgIDAgMTk2MTMgICAgIDgg MjE2MCAgMTAyMyAgNyAzNiAgMCA1NwogMCAgMSAgICAgIDAgICA1MDA4IDE5OTcxMiAyODkxNDAg ICAgMCAgICAwIDE0NzM5ICAgICAwIDM5MzggICA5MjEgIDYgMzIgIDAgNjIKIDAgIDEgICAgICAw ICAgNTM0NCAxODA5ODAgMzEyMDIwICAgIDAgICAgMCAxODU3OCAgICAgMCA4MTE2ICAxMTQ5ICA2 IDQ0ICAwIDQ5CiAwICAxICAgICAgMCAgIDQ5NjAgMTczMDQ4IDMyMjg3NiAgICAwICAgIDAgIDg4 NTIgICAgIDAgNzk4OCAgMTA4NiAgNCAyNSAgMCA3MQogMCAgMSAgICAgIDAgICA1MzYwIDE2MzY0 MCAzMzQxODggICAgMCAgICAwICA4NDc0ICAgICAwIDY1NzggIDEwMTIgIDUgMjIgIDAgNzMKIDAg IDIgICAgICAwICAgNTI4OCAxNTQ2NzYgMzQ2MjgwICAgIDAgICAgMCAgOTczMCAgICAgNCA0NDYz ICAgOTE1ICA0IDIzICAwIDcyCiAwICAyICAgICAgMCAgIDUzNDggMTQ1MTQwIDM1ODMzMiAgICAw ICAgIDAgIDc4MTIgICAgMTIgNzA1NiAgMTE2OCAgNCAyNSAgMCA3MQogMCAgMSAgICAgIDAgICA1 MzY4IDEzOTE1MiAzNjY1NjQgICAgMCAgICAwICA1MDY1ICAgICAwIDc3OTggIDEwNjIgIDMgMTgg IDAgNzkKIDAgIDEgICAgICAwICAgNTAxMiAxMzM3ODAgMzcyODIwICAgIDAgICAgMCAgMzg1NSAg ICAgMCA3ODU0ICAgOTk1ICAzIDE4ICAwIDc5CiAwICAxICAgICAgMCAgIDUwMTIgMTMwMjA4IDM3 NzAwNCAgICAwICAgIDAgIDI1NzEgICAgIDAgNzg0MSAgIDk2NyAgMyAxNCAgMCA4Mwpwcm9jcyAt LS0tLS0tLS0tLW1lbW9yeS0tLS0tLS0tLS0gLS0tc3dhcC0tIC0tLS0taW8tLS0tIC0tc3lzdGVt LS0gLS0tLWNwdS0tLS0KIHIgIGIgICBzd3BkICAgZnJlZSAgIGJ1ZmYgIGNhY2hlICAgc2kgICBz byAgICBiaSAgICBibyAgIGluICAgIGNzIHVzIHN5IGlkIHdhCiAxICAxICAgICAgMCAgIDUxMzYg MTI4MjkyIDM3OTA1NiAgICAwICAgIDAgIDExNjEgICAgIDAgNzI3MCAgMjAzOSAxMiAxNiAgMCA3 MgogMCAgMSAgICAgIDAgICA0NzYwIDEyMDY1NiAzODgzOTIgICAgMCAgICAwICA1OTA0ICAgICAw IDQwNTkgICA4MDUgIDQgMTUgIDAgODEKIDAgIDIgICAgICAwICAgNTUzNiAxMTE2ODggMzk3NDk2 ICAgIDAgICAgMCAgNTc2MiAgICAxMiA0MTk1ICAgODk5ICAzIDE1ICAwIDgyCiAxICAxICAgICAg MCAgIDU1MjggMTA4MDMyIDQwMTc2NCAgICAwICAgIDAgIDI3MjEgICAgIDQgMzYwNSAgIDg1MSAg MyAxMSAgMCA4NgogMCAgMSAgICAgIDAgICA1Mjc2IDEwMDk1MiA0MTAyMDQgICAgMCAgICAwICA1 MjQzICAgICAwIDc2NDEgIDEwNDUgIDIgMjAgIDAgNzgKIDAgIDEgICAgICAwICAgNDYzNiAgOTU1 MzIgNDE3MTg4ICAgIDAgICAgMCAgNDI4OSAgICAgMCA3NjIxICAxMDQyICAzIDE1ICAwIDgxCiAw ICAxICAgICAgMCAgIDU2MTIgIDkwODA4IDQyMTQzNiAgICAwICAgIDAgIDI3ODEgICAgIDAgNzYw OSAgMTA1MyAgMiAxNCAgMCA4NAogMCAgMSAgICAgIDAgICA1Mjc2ICA4MDcyNCA0MzM2OTYgICAg MCAgICAwICA3MjU2ICAgICA0IDc3NDggIDEwOTMgIDMgMjIgIDAgNzQKIDAgIDAgICAgICAwICAg NDkwOCAgNjk4NzIgNDQ2MDQ0ICAgIDAgICAgMCAgNzUzMyAgICAyMCA1MDc0ICAgOTQ4ICA0IDE3 IDYxIDE3CiAwICAwICAgICAgMCAgIDQ5MDggIDY5ODcyIDQ0NjA0NCAgICAwICAgIDAgICAgIDAg ICAgIDAgMzgwMyAgIDYxMCAgMCAgMyA5NyAgMAogMCAgMCAgICAgIDAgICA0OTA4ICA2OTg3MiA0 NDYwNDQgICAgMCAgICAwICAgICAwICAgICAwIDUwNjQgICA3MTMgIDEgIDMgOTYgIDAKIDAgIDAg ICAgICAwICAgNDk3MiAgNjk4NzIgNDQ2MDQ0ICAgIDAgICAgMCAgICAgMCAgICAgMCA2OTc4ICAg ODY0ICAwICA4IDkyICAwCiAwICAwICAgICAgMCAgIDUxNjQgIDY5ODcyIDQ0NjA0NCAgICAwICAg IDAgICAgIDAgICAgIDAgNzQ5MyAgIDkxNCAgMCAgNiA5NCAgMAogMCAgMCAgICAgIDAgICA1MTY0 ICA2OTg4NCA0NDYwMzIgICAgMCAgICAwICAgICAwICAgIDIwIDEyMDcgICA0MTkgIDEgIDEgOTgg IDAKIDAgIDAgICAgICAwICAgNjM4MCAgNjk4ODQgNDQ2MDMyICAgIDAgICAgMCAgICAgMCAgICAg MCA0OTkyICAgNzEyICAwICA2IDk0ICAwCiAwICAwICAgICAgMCAgIDY1MDggIDY5ODg0IDQ0NjAz MiAgICAwICAgIDAgICAgIDAgICAgIDAgNzM5NCAgIDkxNSAgMCAgNSA5NSAgMAogMCAgMCAgICAg IDAgICA2NTcyICA2OTg4NCA0NDYwMzIgICAgMCAgICAwICAgICAwICAgICAwIDM4NTggICA2MTkg IDEgIDUgOTQgIDAKIDAgIDAgICAgICAwICAgNjYzNiAgNjk4ODQgNDQ2MTAwICAgIDAgICAgMCAg ICAxMiAgICAgMCA1NzAwICAgODIwICAxICA0IDk0ICAxCiAwICAwICAgICAgMCAgIDc2MDAgIDY5 OTI4IDQ0NjA1NiAgICAwICAgIDAgICAgIDAgICAxMDQgNTg2MCAgIDc4MyAgMSAgNyA5MiAgMAog MCAgMCAgICAgIDAgICA4MTE2ICA2OTkyOCA0NDYwNTYgICAgMCAgICAwICAgICAwICAgICAwIDU0 ODkgICA3NjIgIDMgIDYgOTEgIDAKIDAgIDAgICAgICAwICAgODQ0MCAgNjk5MjggNDQ2MDU2ICAg IDAgICAgMCAgICAgMCAgICAgMCA2MDIwICAgODUyICAxICA2IDkzICAwCnByb2NzIC0tLS0tLS0t LS0tbWVtb3J5LS0tLS0tLS0tLSAtLS1zd2FwLS0gLS0tLS1pby0tLS0gLS1zeXN0ZW0tLSAtLS0t Y3B1LS0tLQogciAgYiAgIHN3cGQgICBmcmVlICAgYnVmZiAgY2FjaGUgICBzaSAgIHNvICAgIGJp ICAgIGJvICAgaW4gICAgY3MgdXMgc3kgaWQgd2EKIDEgIDAgICAgICAwICAgODU2OCAgNjk5Mjgg NDQ2MDU2ICAgIDAgICAgMCAgICAgMCAgICAgMCA1NDMzICAgODIyICAxICA1IDk0ICAwCiAwICAw ICAgICAgMCAgMTA0ODggIDY5OTQ0IDQ0NjA0MCAgICAwICAgIDAgICAgIDcgICAgIDAgMjA5OSAg IDcyOCAgNCAgNiA4NiAgNAogMCAgMCAgICAgIDAgIDEwNDgwICA2OTk1NiA0NDYwOTYgICAgMCAg ICAwICAgICAwICAgIDIwIDEyMjQgICA5NTIgIDQgIDEgOTUgIDAKIDAgIDAgICAgICAwICAxMDQ4 MCAgNjk5NTYgNDQ2MDk2ICAgIDAgICAgMCAgICAgMCAgICAgMCAxMjgzICAgNDY1ICAyICAxIDk3 ICAwCiAwICAwICAgICAgMCAxOTkyNTIgIDY5OTU2IDI1NzYwMCAgICAwICAgIDAgICAgIDAgICAg IDAgMTc3OSAgMTMwMCAgOSAgNyA4NCAgMAogMCAgMCAgICAgIDAgMTk5MjUyICA2OTk1NiAyNTc2 MDAgICAgMCAgICAwICAgICAwICAgICAwIDE0NDUgIDEyMDUgMTkgIDQgNzcgIDAK ------=_Part_60_22762740.1091387012317-- From jgarzik@pobox.com Sun Aug 1 12:03:48 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:03:53 -0700 (PDT) Received: from www.linux.org.uk (IDENT:93@parcelfarce.linux.theplanet.co.uk [195.92.249.252]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71J3jMr030684 for ; Sun, 1 Aug 2004 12:03:48 -0700 Received: from rdu74-153-143.nc.rr.com ([24.74.153.143] helo=pobox.com) by www.linux.org.uk with asmtp (TLSv1:AES256-SHA:256) (Exim 4.33) id 1BrLcR-0005Pa-LB; Sun, 01 Aug 2004 20:03:39 +0100 Message-ID: <410D3E77.4090303@pobox.com> Date: Sun, 01 Aug 2004 15:03:19 -0400 From: Jeff Garzik User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Chris Wright CC: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH] ethtool_get_regs copy right number of bytes to user References: <20040615155541.Q21045@build.pdx.osdl.net> In-Reply-To: <20040615155541.Q21045@build.pdx.osdl.net> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7395 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jgarzik@pobox.com Precedence: bulk X-list: netdev applied From manfred@colorfullife.com Sun Aug 1 12:13:25 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 12:13:30 -0700 (PDT) Received: from dbl.q-ag.de (dbl.q-ag.de [213.172.117.3] (may be forged)) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71JDNut031783 for ; Sun, 1 Aug 2004 12:13:24 -0700 Received: from colorfullife.com (dbl [127.0.0.1]) by dbl.q-ag.de (8.12.3/8.12.3/Debian-6.6) with ESMTP id i71JCbuG024874; Sun, 1 Aug 2004 21:12:39 +0200 Message-ID: <410D4120.2020604@colorfullife.com> Date: Sun, 01 Aug 2004 21:14:40 +0200 From: Manfred Spraul User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: James Drabb CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> In-Reply-To: <410D3377.3030505@tampabay.rr.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7396 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: manfred@colorfullife.com Precedence: bulk X-list: netdev James Drabb wrote: > jim@keelie $ uname -a > Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 > GNU/Linux There should be a message in the dmesg log about the driver version: If it's less than 0.28: could you try a newer kernel? 0.28 is definitively in 2.5.8-rc1-mm1 and later. I could also send you just the forcedeth.c file, then you don't have to upgrade the whole kernel. > However, if I reboot into WinXP, and then reboot right away back into > FC2, the forcedeth driver works like a champ. Probably the phy reset and/or the media detection do not work properly. That part is completely rewritten in 0.28. I'm interested in two infos: - with 2.6.7 (probably version 0.25), after booting into winXP first: what does # ethtool eth0 report? Then unplug the network cable. Run ethtool again. Does it report "Link detected: No"? What if you plug the network cable back in? - The same thing with the 0.28 driver. Note that the phy initialization in 0.28 is not perfect either: it seems there is a race between the phy reset and the media detection. You might have to wait 2 seconds or so between modprobe and ifup. -- Manfred From JDrabb@tampabay.rr.com Sun Aug 1 15:00:47 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 15:00:54 -0700 (PDT) Received: from ms-smtp-04.tampabay.rr.com (ms-smtp-04-smtplb.tampabay.rr.com [65.32.5.134]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71M0kjG005473 for ; Sun, 1 Aug 2004 15:00:47 -0700 Received: from [192.168.1.101] (189-66.35-65.tampabay.rr.com [65.35.66.189]) by ms-smtp-04.tampabay.rr.com (8.12.10/8.12.7) with ESMTP id i71M0Z7t029887; Sun, 1 Aug 2004 18:00:35 -0400 (EDT) Message-ID: <410D682F.4090809@tampabay.rr.com> Date: Sun, 01 Aug 2004 18:01:19 -0400 From: James Drabb User-Agent: Mozilla Thunderbird 0.7.1 (X11/20040626) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Manfred Spraul CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> <410D4120.2020604@colorfullife.com> In-Reply-To: <410D4120.2020604@colorfullife.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Symantec AntiVirus Scan Engine X-archive-position: 7397 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: JDrabb@tampabay.rr.com Precedence: bulk X-list: netdev Manfred Spraul wrote: > James Drabb wrote: > >> jim@keelie $ uname -a >> Linux keelie 2.6.7-1 #1 Thu Jul 22 11:42:58 CEST 2004 i686 athlon i386 >> GNU/Linux > > > There should be a message in the dmesg log about the driver version: If > it's less than 0.28: could you try a newer kernel? 0.28 is definitively > in 2.5.8-rc1-mm1 and later. I could also send you just the forcedeth.c > file, then you don't have to upgrade the whole kernel. dmesg shows version 0.25. > Probably the phy reset and/or the media detection do not work properly. > That part is completely rewritten in 0.28. > > I'm interested in two infos: > - with 2.6.7 (probably version 0.25), after booting into winXP first: > what does > # ethtool eth0 > report? Then unplug the network cable. Run ethtool again. Does it report > "Link detected: No"? What if you plug the network cable back in? ethtool eth0 shows: Settings for eth0: Supports Wake-on: g Wake-on: d Link detected: yes Unplugging the network cable showed the same settings: Settings for eth0: Supports Wake-on: g Wake-on: d Link detected: yes > -- > Manfred Please send me the latest forcedeth.c and I will give it a go. Do you have the makefile so I can compile the module outside of the kernel? Thanks, Jim Drabb -- James Drabb Senior Programmer Davenport, FL USA From laforge@netfilter.org Sun Aug 1 16:03:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 16:04:03 -0700 (PDT) Received: from ganesha.gnumonks.org (Debian-exim@ganesha.gnumonks.org [213.95.27.120]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i71N3reK007511 for ; Sun, 1 Aug 2004 16:03:55 -0700 Received: from dsl-082-083-225-237.arcor-ip.net ([82.83.225.237] helo=sunbeam.gnumonks.org) by ganesha.gnumonks.org with asmtp (TLSv1:RC4-SHA:128) (Exim 4.30) id 1BrPMl-00027N-JB; Mon, 02 Aug 2004 01:03:43 +0200 Received: from laforge by sunbeam.gnumonks.org with local (Exim 4.34) id 1BrPMg-00050K-Ab; Mon, 02 Aug 2004 01:03:38 +0200 Date: Mon, 2 Aug 2004 01:03:38 +0200 From: Harald Welte To: David Miller Cc: Netfilter Development Mailinglist , netdev@oss.sgi.com, immidi_kiran@yahoo.com Subject: [PATCH 2.6] NETFILTER: new ip_conntrack_sctp Message-ID: <20040801230338.GE18758@sunbeam2> Mail-Followup-To: Harald Welte , David Miller , Netfilter Development Mailinglist , netdev@oss.sgi.com, immidi_kiran@yahoo.com Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="6e7ZaeXHKrTJCxdu" Content-Disposition: inline User-Agent: Mutt/1.5.6+20040523i X-archive-position: 7398 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: laforge@netfilter.org Precedence: bulk X-list: netdev --6e7ZaeXHKrTJCxdu Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi Dave! Incremental to all other patches so far, there is also the new SCTP conntrack helper by Kiran Kumar. Please apply for 2.6.9 ++, thanks. Signed-off-by: Kiran Kumar Immidi Signed-off-by: Harald Welte Please apply, thanks. diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack.h linux-2.6.8-rc2-nf= quilt-nfp/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack.h 200= 4-08-02 00:51:27.793033003 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack.h= 2004-08-02 00:52:49.107882646 +0200 @@ -51,10 +51,12 @@ =20 #include #include +#include =20 /* per conntrack: protocol private data */ union ip_conntrack_proto { /* insert conntrack proto private data here */ + struct ip_ct_sctp sctp; struct ip_ct_tcp tcp; struct ip_ct_icmp icmp; }; diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_sctp.h linux-2.6.8-r= c2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_sctp.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_sctp.= h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_s= ctp.h 2004-08-02 00:52:49.088883383 +0200 @@ -0,0 +1,25 @@ +#ifndef _IP_CONNTRACK_SCTP_H +#define _IP_CONNTRACK_SCTP_H +/* SCTP tracking. */ + +enum sctp_conntrack { + SCTP_CONNTRACK_NONE, + SCTP_CONNTRACK_CLOSED, + SCTP_CONNTRACK_COOKIE_WAIT, + SCTP_CONNTRACK_COOKIE_ECHOED, + SCTP_CONNTRACK_ESTABLISHED, + SCTP_CONNTRACK_SHUTDOWN_SENT, + SCTP_CONNTRACK_SHUTDOWN_RECD, + SCTP_CONNTRACK_SHUTDOWN_ACK_SENT, + SCTP_CONNTRACK_MAX +}; + +struct ip_ct_sctp +{ + enum sctp_conntrack state; + + u_int32_t vtag[IP_CT_DIR_MAX]; + u_int32_t ttag[IP_CT_DIR_MAX]; +}; + +#endif /* _IP_CONNTRACK_SCTP_H */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.6.8-= rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_tuple.h --- linux-2.6.8-rc2-nfquilt/include/linux/netfilter_ipv4/ip_conntrack_tuple= =2Eh 2004-06-16 07:19:43.000000000 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/netfilter_ipv4/ip_conntrack_t= uple.h 2004-08-02 00:52:49.143881251 +0200 @@ -25,6 +25,9 @@ struct { u_int16_t id; } icmp; + struct { + u_int16_t port; + } sctp; }; =20 /* The manipulable part of the tuple. */ @@ -55,6 +58,9 @@ struct { u_int8_t type, code; } icmp; + struct { + u_int16_t port; + } sctp; } u; =20 /* The protocol. */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/include/linux/sysctl.h linux-2.6.8-rc2-nfquilt-nfp/include/lin= ux/sysctl.h --- linux-2.6.8-rc2-nfquilt/include/linux/sysctl.h 2004-08-01 23:52:00.0215= 86979 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/include/linux/sysctl.h 2004-08-02 00:52:49.= 146881135 +0200 @@ -410,6 +410,13 @@ NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=3D12, NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=3D13, NET_IPV4_NF_CONNTRACK_BUCKETS=3D14, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED=3D15, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT=3D16, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED=3D17, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED=3D18, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT=3D19, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD=3D20, + NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT=3D21, }; =20 /* /proc/sys/net/ipv6 */ diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/Kconfig linux-2.6.8-rc2-nfquilt-nfp/net/ipv= 4/netfilter/Kconfig --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/Kconfig 2004-08-02 00:51:27.= 223055074 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/Kconfig 2004-08-02 00:52= :49.115882336 +0200 @@ -636,5 +636,9 @@ tristate 'SCTP protocol match support' depends on IP_NF_IPTABLES =20 +config IP_NF_CT_PROTO_SCTP + tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' + depends on IP_NF_CONNTRACK && EXPERIMENTAL + endmenu =20 diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/Makefile linux-2.6.8-rc2-nfquilt-nfp/net/ip= v4/netfilter/Makefile --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/Makefile 2004-08-02 00:51:27= =2E224055035 +0200 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/Makefile 2004-08-02 00:5= 2:49.117882259 +0200 @@ -19,6 +19,9 @@ # connection tracking obj-$(CONFIG_IP_NF_CONNTRACK) +=3D ip_conntrack.o =20 +# SCTP protocol connection tracking +obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) +=3D ip_conntrack_proto_sctp.o + # connection tracking helpers obj-$(CONFIG_IP_NF_AMANDA) +=3D ip_conntrack_amanda.o obj-$(CONFIG_IP_NF_TFTP) +=3D ip_conntrack_tftp.o diff --exclude-from /sunbeam/home/laforge/scripts/dontdiff -Nru linux-2.6.8= -rc2-nfquilt/net/ipv4/netfilter/ip_conntrack_proto_sctp.c linux-2.6.8-rc2-n= fquilt-nfp/net/ipv4/netfilter/ip_conntrack_proto_sctp.c --- linux-2.6.8-rc2-nfquilt/net/ipv4/netfilter/ip_conntrack_proto_sctp.c 19= 70-01-01 01:00:00.000000000 +0100 +++ linux-2.6.8-rc2-nfquilt-nfp/net/ipv4/netfilter/ip_conntrack_proto_sctp.= c 2004-08-02 00:52:49.098882995 +0200 @@ -0,0 +1,650 @@ +/* + * Connection tracking protocol helper module for SCTP. + *=20 + * SCTP is defined in RFC 2960. References to various sections in this cod= e=20 + * are to this RFC. + *=20 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +/* + * Added support for proc manipulation of timeouts. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__) +#else +#define DEBUGP(format, args...) +#endif + +/* Protects conntrack->proto.sctp */ +static DECLARE_RWLOCK(sctp_lock); + +/* FIXME: Examine ipfilter's timeouts and conntrack transitions more + closely. They're more complex. --RR=20 + + And so for me for SCTP :D -Kiran */ + +static const char *sctp_conntrack_names[] =3D { + "NONE", + "CLOSED", + "COOKIE_WAIT", + "COOKIE_ECHOED", + "ESTABLISHED", + "SHUTDOWN_SENT", + "SHUTDOWN_RECD", + "SHUTDOWN_ACK_SENT", +}; + +#define SECS * HZ +#define MINS * 60 SECS +#define HOURS * 60 MINS +#define DAYS * 24 HOURS + +unsigned long ip_ct_sctp_timeout_closed =3D 10 SECS; +unsigned long ip_ct_sctp_timeout_cookie_wait =3D 3 SECS; +unsigned long ip_ct_sctp_timeout_cookie_echoed =3D 3 SECS; +unsigned long ip_ct_sctp_timeout_established =3D 5 DAYS; +unsigned long ip_ct_sctp_timeout_shutdown_sent =3D 300 SECS / 1000; +unsigned long ip_ct_sctp_timeout_shutdown_recd =3D 300 SECS / 1000; +unsigned long ip_ct_sctp_timeout_shutdown_ack_sent =3D 3 SECS; + +static unsigned long * sctp_timeouts[] +=3D { 0, /* SCTP_CONNTRACK_NONE */ + &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */ + &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */ + &ip_ct_sctp_timeout_cookie_echoed, /* SCTP_CONNTRACK_COOKIE_ECHOED= */ + &ip_ct_sctp_timeout_established, /* SCTP_CONNTRACK_ESTABLISHED */ + &ip_ct_sctp_timeout_shutdown_sent, /* SCTP_CONNTRACK_SHUTDOWN_SENT= */ + &ip_ct_sctp_timeout_shutdown_recd, /* SCTP_CONNTRACK_SHUTDOWN_RECD= */ + &ip_ct_sctp_timeout_shutdown_ack_sent /* SCTP_CONNTRACK_SHUTDOWN_ACK_= SENT */ + }; + +#define sNO SCTP_CONNTRACK_NONE +#define sCL SCTP_CONNTRACK_CLOSED +#define sCW SCTP_CONNTRACK_COOKIE_WAIT +#define sCE SCTP_CONNTRACK_COOKIE_ECHOED +#define sES SCTP_CONNTRACK_ESTABLISHED +#define sSS SCTP_CONNTRACK_SHUTDOWN_SENT +#define sSR SCTP_CONNTRACK_SHUTDOWN_RECD +#define sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT +#define sIV SCTP_CONNTRACK_MAX + +/*=20 + These are the descriptions of the states: + +NOTE: These state names are tantalizingly similar to the states of an=20 +SCTP endpoint. But the interpretation of the states is a little different, +considering that these are the states of the connection and not of an end= =20 +point. Please note the subtleties. -Kiran + +NONE - Nothing so far. +COOKIE WAIT - We have seen an INIT chunk in the original direction, = or also=20 + an INIT_ACK chunk in the reply direction. +COOKIE ECHOED - We have seen a COOKIE_ECHO chunk in the original direc= tion. +ESTABLISHED - We have seen a COOKIE_ACK in the reply direction. +SHUTDOWN_SENT - We have seen a SHUTDOWN chunk in the original directio= n. +SHUTDOWN_RECD - We have seen a SHUTDOWN chunk in the reply directoin. +SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opp= osite + to that of the SHUTDOWN chunk. +CLOSED - We have seen a SHUTDOWN_COMPLETE chunk in the directio= n of=20 + the SHUTDOWN chunk. Connection is closed. +*/ + +/* TODO + - I have assumed that the first INIT is in the original direction.=20 + This messes things when an INIT comes in the reply direction in CLOSED + state. + - Check the error type in the reply dir before transitioning from=20 +cookie echoed to closed. + - Sec 5.2.4 of RFC 2960 + - Multi Homing support. +*/ + +/* SCTP conntrack state transitions */ +static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] =3D { + { +/* ORIGINAL */ +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ +/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA}, +/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA}, +/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, +/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA}, +/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA}, +/* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant have S= tale cookie*/ +/* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big= TODO */ +/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come i= n orig dir */ +/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL} + }, + { +/* REPLY */ +/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ +/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL= Big TODO */ +/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA}, +/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL}, +/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA}, +/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA}, +/* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA}, +/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Cant come i= n reply dir */ +/* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA}, +/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL} + } +}; + +static int sctp_pkt_to_tuple(const struct sk_buff *skb, + unsigned int dataoff, + struct ip_conntrack_tuple *tuple) +{ + sctp_sctphdr_t hdr; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + /* Actually only need first 8 bytes. */ + if (skb_copy_bits(skb, dataoff, &hdr, 8) !=3D 0) + return 0; + + tuple->src.u.sctp.port =3D hdr.source; + tuple->dst.u.sctp.port =3D hdr.dest; + + return 1; +} + +static int sctp_invert_tuple(struct ip_conntrack_tuple *tuple, + const struct ip_conntrack_tuple *orig) +{ + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + tuple->src.u.sctp.port =3D orig->dst.u.sctp.port; + tuple->dst.u.sctp.port =3D orig->src.u.sctp.port; + return 1; +} + +/* Print out the per-protocol part of the tuple. */ +static unsigned int sctp_print_tuple(char *buffer, + const struct ip_conntrack_tuple *tuple) +{ + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + return sprintf(buffer, "sport=3D%hu dport=3D%hu ", + ntohs(tuple->src.u.sctp.port), + ntohs(tuple->dst.u.sctp.port)); +} + +/* Print out the private part of the conntrack. */ +static unsigned int sctp_print_conntrack(char *buffer, + const struct ip_conntrack *conntrack) +{ + enum sctp_conntrack state; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + READ_LOCK(&sctp_lock); + state =3D conntrack->proto.sctp.state; + READ_UNLOCK(&sctp_lock); + + return sprintf(buffer, "%s ", sctp_conntrack_names[state]); +} + +#define for_each_sctp_chunk(skb, sch, offset, count) \ +for (offset =3D skb->nh.iph->ihl * 4 + sizeof (sctp_sctphdr_t), count =3D = 0; \ + offset < skb->len && !skb_copy_bits(skb, offset, &sch, sizeof(sch)); \ + offset +=3D (htons(sch.length) + 3) & ~3, count++) + +/* Some validity checks to make sure the chunks are fine */ +static int do_basic_checks(struct ip_conntrack *conntrack, + const struct sk_buff *skb, + char *map) +{ + u_int32_t offset, count; + sctp_chunkhdr_t sch; + int flag; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + flag =3D 0; + + for_each_sctp_chunk (skb, sch, offset, count) { + DEBUGP("Chunk Num: %d Type: %d\n", count, sch.type); + + if (sch.type =3D=3D SCTP_CID_INIT=20 + || sch.type =3D=3D SCTP_CID_INIT_ACK + || sch.type =3D=3D SCTP_CID_SHUTDOWN_COMPLETE) { + flag =3D 1; + } + + /* Cookie Ack/Echo chunks not the first OR=20 + Init / Init Ack / Shutdown compl chunks not the only chunks */ + if ((sch.type =3D=3D SCTP_CID_COOKIE_ACK=20 + || sch.type =3D=3D SCTP_CID_COOKIE_ECHO + || flag) + && count !=3D0 ) { + DEBUGP("Basic checks failed\n"); + return 1; + } + + if (map) { + set_bit (sch.type, (void *)map); + } + } + + DEBUGP("Basic checks passed\n"); + return 0; +} + +static int new_state(enum ip_conntrack_dir dir, + enum sctp_conntrack cur_state, + int chunk_type) +{ + int i; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + DEBUGP("Chunk type: %d\n", chunk_type); + + switch (chunk_type) { + case SCTP_CID_INIT:=20 + DEBUGP("SCTP_CID_INIT\n"); + i =3D 0; break; + case SCTP_CID_INIT_ACK:=20 + DEBUGP("SCTP_CID_INIT_ACK\n"); + i =3D 1; break; + case SCTP_CID_ABORT:=20 + DEBUGP("SCTP_CID_ABORT\n"); + i =3D 2; break; + case SCTP_CID_SHUTDOWN:=20 + DEBUGP("SCTP_CID_SHUTDOWN\n"); + i =3D 3; break; + case SCTP_CID_SHUTDOWN_ACK:=20 + DEBUGP("SCTP_CID_SHUTDOWN_ACK\n"); + i =3D 4; break; + case SCTP_CID_ERROR:=20 + DEBUGP("SCTP_CID_ERROR\n"); + i =3D 5; break; + case SCTP_CID_COOKIE_ECHO:=20 + DEBUGP("SCTP_CID_COOKIE_ECHO\n"); + i =3D 6; break; + case SCTP_CID_COOKIE_ACK:=20 + DEBUGP("SCTP_CID_COOKIE_ACK\n"); + i =3D 7; break; + case SCTP_CID_SHUTDOWN_COMPLETE:=20 + DEBUGP("SCTP_CID_SHUTDOWN_COMPLETE\n"); + i =3D 8; break; + default: + /* Other chunks like DATA, SACK, HEARTBEAT and + its ACK do not cause a change in state */ + DEBUGP("Unknown chunk type, Will stay in %s\n",=20 + sctp_conntrack_names[cur_state]); + return cur_state; + } + + DEBUGP("dir: %d cur_state: %s chunk_type: %d new_state: %s\n",=20 + dir, sctp_conntrack_names[cur_state], chunk_type, + sctp_conntrack_names[sctp_conntracks[dir][i][cur_state]]); + + return sctp_conntracks[dir][i][cur_state]; +} + +/* Returns verdict for packet, or -1 for invalid. */ +static int sctp_packet(struct ip_conntrack *conntrack, + const struct sk_buff *skb, + enum ip_conntrack_info ctinfo) +{ + enum sctp_conntrack newconntrack, oldsctpstate; + sctp_sctphdr_t sctph; + sctp_chunkhdr_t sch; + u_int32_t offset, count; + char map[256 / sizeof (char)] =3D {0}; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) !=3D = 0) + return -1; + + if (do_basic_checks(conntrack, skb, map) !=3D 0) + return -1; + + /* Check the verification tag (Sec 8.5) */ + if (!test_bit(SCTP_CID_INIT, (void *)map) + && !test_bit(SCTP_CID_SHUTDOWN_COMPLETE, (void *)map) + && !test_bit(SCTP_CID_COOKIE_ECHO, (void *)map) + && !test_bit(SCTP_CID_ABORT, (void *)map) + && !test_bit(SCTP_CID_SHUTDOWN_ACK, (void *)map) + && (sctph.vtag !=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])) { + DEBUGP("Verification tag check failed\n"); + return -1; + } + + oldsctpstate =3D newconntrack =3D SCTP_CONNTRACK_MAX; + for_each_sctp_chunk (skb, sch, offset, count) { + WRITE_LOCK(&sctp_lock); + + /* Special cases of Verification tag check (Sec 8.5.1) */ + if (sch.type =3D=3D SCTP_CID_INIT) { + /* Sec 8.5.1 (A) */ + if (sctph.vtag !=3D 0) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_ABORT) { + /* Sec 8.5.1 (B) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) + && !(sctph.vtag =3D=3D conntrack->proto.sctp.vtag + [1 - CTINFO2DIR(ctinfo)])) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_SHUTDOWN_COMPLETE) { + /* Sec 8.5.1 (C) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)]) + && !(sctph.vtag =3D=3D conntrack->proto.sctp.vtag + [1 - CTINFO2DIR(ctinfo)]=20 + && (sch.flags & 1))) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } else if (sch.type =3D=3D SCTP_CID_COOKIE_ECHO) { + /* Sec 8.5.1 (D) */ + if (!(sctph.vtag =3D=3D conntrack->proto.sctp.vtag[CTINFO2DIR(ctinfo)])= ) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + } + + oldsctpstate =3D conntrack->proto.sctp.state; + newconntrack =3D new_state(CTINFO2DIR(ctinfo), oldsctpstate, sch.type); + + /* Invalid */ + if (newconntrack =3D=3D SCTP_CONNTRACK_MAX) { + DEBUGP("ip_conntrack_sctp: Invalid dir=3D%i ctype=3D%u conntrack=3D%u\n= ", + CTINFO2DIR(ctinfo), sch.type, oldsctpstate); + WRITE_UNLOCK(&sctp_lock); + return -1; + } + + /* If it is an INIT or an INIT ACK note down the vtag */ + if (sch.type =3D=3D SCTP_CID_INIT=20 + || sch.type =3D=3D SCTP_CID_INIT_ACK) { + sctp_inithdr_t inithdr; + + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t), + &inithdr, sizeof(inithdr)) !=3D 0) { + WRITE_UNLOCK(&sctp_lock); + return -1; + } + DEBUGP("Setting vtag %x for dir %d\n",=20 + inithdr.init_tag, CTINFO2DIR(ctinfo)); + conntrack->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =3D inithdr.init_tag; + } + + conntrack->proto.sctp.state =3D newconntrack; + WRITE_UNLOCK(&sctp_lock); + } + + ip_ct_refresh(conntrack, *sctp_timeouts[newconntrack]); + + if (oldsctpstate =3D=3D SCTP_CONNTRACK_COOKIE_ECHOED + && CTINFO2DIR(ctinfo) =3D=3D IP_CT_DIR_REPLY + && newconntrack =3D=3D SCTP_CONNTRACK_ESTABLISHED) { + DEBUGP("Setting assured bit\n"); + set_bit(IPS_ASSURED_BIT, &conntrack->status); + } + + return NF_ACCEPT; +} + +/* Called when a new connection for this protocol found. */ +static int sctp_new(struct ip_conntrack *conntrack,=20 + const struct sk_buff *skb) +{ + enum sctp_conntrack newconntrack; + sctp_sctphdr_t sctph; + sctp_chunkhdr_t sch; + u_int32_t offset, count; + char map[256 / sizeof (char)] =3D {0}; + + DEBUGP(__FUNCTION__); + DEBUGP("\n"); + + if (skb_copy_bits(skb, skb->nh.iph->ihl * 4, &sctph, sizeof(sctph)) !=3D = 0) + return -1; + + if (do_basic_checks(conntrack, skb, map) !=3D 0) + return -1; + + /* If an OOTB packet has any of these chunks discard (Sec 8.4) */ + if ((test_bit (SCTP_CID_ABORT, (void *)map)) + || (test_bit (SCTP_CID_SHUTDOWN_COMPLETE, (void *)map)) + || (test_bit (SCTP_CID_COOKIE_ACK, (void *)map))) { + return -1; + } + + newconntrack =3D SCTP_CONNTRACK_MAX; + for_each_sctp_chunk (skb, sch, offset, count) { + /* Don't need lock here: this conntrack not in circulation yet */ + newconntrack =3D new_state (IP_CT_DIR_ORIGINAL,=20 + SCTP_CONNTRACK_NONE, sch.type); + + /* Invalid: delete conntrack */ + if (newconntrack =3D=3D SCTP_CONNTRACK_MAX) { + DEBUGP("ip_conntrack_sctp: invalid new deleting.\n"); + return 0; + } + + /* Copy the vtag into the state info */ + if (sch.type =3D=3D SCTP_CID_INIT) { + if (sctph.vtag =3D=3D 0) { + sctp_inithdr_t inithdr; + + if (skb_copy_bits(skb, offset + sizeof (sctp_chunkhdr_t),=20 + &inithdr, sizeof(inithdr)) !=3D 0) { + return -1; + } + + DEBUGP("Setting vtag %x for new conn\n",=20 + inithdr.init_tag); + + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =3D=20 + inithdr.init_tag; + } else { + /* Sec 8.5.1 (A) */ + return -1; + } + } + /* If it is a shutdown ack OOTB packet, we expect a return + shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */ + else { + DEBUGP("Setting vtag %x for new conn OOTB\n",=20 + sctph.vtag); + conntrack->proto.sctp.vtag[IP_CT_DIR_REPLY] =3D sctph.vtag; + } + + conntrack->proto.sctp.state =3D newconntrack; + } + + return 1; +} + +static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp, + const struct sk_buff *skb) +{ + /* To be implemented */ + return 0; +} + +struct ip_conntrack_protocol ip_conntrack_protocol_sctp =3D {=20 + .list =3D { NULL, NULL },=20 + .proto =3D IPPROTO_SCTP,=20 + .name =3D "sctp", + .pkt_to_tuple =3D sctp_pkt_to_tuple,=20 + .invert_tuple =3D sctp_invert_tuple,=20 + .print_tuple =3D sctp_print_tuple,=20 + .print_conntrack =3D sctp_print_conntrack, + .packet =3D sctp_packet,=20 + .new =3D sctp_new,=20 + .destroy =3D NULL,=20 + .exp_matches_pkt =3D sctp_exp_matches_pkt,=20 + .me =3D THIS_MODULE=20 +}; + +#ifdef CONFIG_SYSCTL +static ctl_table ip_ct_sysctl_table[] =3D { + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, + .procname =3D "ip_conntrack_sctp_timeout_closed", + .data =3D &ip_ct_sctp_timeout_closed, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, + .procname =3D "ip_conntrack_sctp_timeout_cookie_wait", + .data =3D &ip_ct_sctp_timeout_cookie_wait, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, + .procname =3D "ip_conntrack_sctp_timeout_cookie_echoed", + .data =3D &ip_ct_sctp_timeout_cookie_echoed, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, + .procname =3D "ip_conntrack_sctp_timeout_established", + .data =3D &ip_ct_sctp_timeout_established, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_sent", + .data =3D &ip_ct_sctp_timeout_shutdown_sent, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_recd", + .data =3D &ip_ct_sctp_timeout_shutdown_recd, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { + .ctl_name =3D NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, + .procname =3D "ip_conntrack_sctp_timeout_shutdown_ack_sent", + .data =3D &ip_ct_sctp_timeout_shutdown_ack_sent, + .maxlen =3D sizeof(unsigned int), + .mode =3D 0644, + .proc_handler =3D &proc_dointvec_jiffies, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_netfilter_table[] =3D { + { + .ctl_name =3D NET_IPV4_NETFILTER, + .procname =3D "netfilter", + .mode =3D 0555, + .child =3D ip_ct_sysctl_table, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_ipv4_table[] =3D { + { + .ctl_name =3D NET_IPV4, + .procname =3D "ipv4", + .mode =3D 0555, + .child =3D ip_ct_netfilter_table, + }, + { .ctl_name =3D 0 } +}; + +static ctl_table ip_ct_net_table[] =3D { + { + .ctl_name =3D CTL_NET, + .procname =3D "net", + .mode =3D 0555,=20 + .child =3D ip_ct_ipv4_table, + }, + { .ctl_name =3D 0 } +}; + +static struct ctl_table_header *ip_ct_sysctl_header; +#endif + +int __init init(void) +{ + int ret; + + ret =3D ip_conntrack_protocol_register(&ip_conntrack_protocol_sctp); + if (ret) { + printk("ip_conntrack_proto_sctp: protocol register failed\n"); + goto out; + } + +#ifdef CONFIG_SYSCTL + ip_ct_sysctl_header =3D register_sysctl_table(ip_ct_net_table, 0); + if (ip_ct_sysctl_header =3D=3D NULL) { + printk("ip_conntrack_proto_sctp: can't register to sysctl.\n"); + goto cleanup; + } +#endif + + return ret; + + cleanup: +#ifdef CONFIG_SYSCTL + ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); +#endif + out: + DEBUGP("SCTP conntrack module loading %s\n",=20 + ret ? "failed": "succeeded"); + return ret; +} + +void __exit fini(void) +{ + ip_conntrack_protocol_unregister(&ip_conntrack_protocol_sctp); +#ifdef CONFIG_SYSCTL + unregister_sysctl_table(ip_ct_sysctl_header); +#endif + DEBUGP("SCTP conntrack module unloaded\n"); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kiran Kumar Immidi"); +MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP= "); --=20 - Harald Welte http://www.netfilter.org/ =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D "Fragmentation is like classful addressing -- an interesting early architectural error that shows how much experimentation was going on while IP was being designed." -- Paul Vixie --6e7ZaeXHKrTJCxdu Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFBDXbKXaXGVTD0i/8RAuE0AKCpndyX/rb5mdL8ryi/8ZIk8a8V4gCfWeme AXWAfdrWrFUBmvMdhd9nWIY= =w/3I -----END PGP SIGNATURE----- --6e7ZaeXHKrTJCxdu-- From davem@redhat.com Sun Aug 1 19:23:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:23:07 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722MxAj014040 for ; Sun, 1 Aug 2004 19:23:02 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722Lle1017554; Sun, 1 Aug 2004 22:21:47 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722Lla12942; Sun, 1 Aug 2004 22:21:47 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722L3XV020332; Sun, 1 Aug 2004 22:21:04 -0400 Date: Sun, 1 Aug 2004 19:20:41 -0700 From: "David S. Miller" To: Adrian Bunk Cc: marcelo.tosatti@cyclades.com, shemminger@osdl.org, linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: Re: [2.4 patch] CONFIG_NET_SCH_NETEM Configure.help entry Message-Id: <20040801192041.48bbc395.davem@redhat.com> In-Reply-To: <20040801142759.GQ2746@fs.tum.de> References: <20040731142658.GA6497@logos.cnet> <20040801142759.GQ2746@fs.tum.de> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7399 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev Applied, thanks Adrian. From davem@redhat.com Sun Aug 1 19:23:40 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:23:46 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722NdHk014131 for ; Sun, 1 Aug 2004 19:23:39 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722MWe1017665; Sun, 1 Aug 2004 22:22:32 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722MWa13003; Sun, 1 Aug 2004 22:22:32 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722LmUX020510; Sun, 1 Aug 2004 22:21:49 -0400 Date: Sun, 1 Aug 2004 19:21:26 -0700 From: "David S. Miller" To: Adrian Bunk Cc: shemminger@osdl.org, linux-kernel@vger.kernel.org, netdev@oss.sgi.com Subject: Re: [2.6 patch] update NET_SCH_NETEM help text Message-Id: <20040801192126.064ad0ac.davem@redhat.com> In-Reply-To: <20040801143307.GR2746@fs.tum.de> References: <20040801143307.GR2746@fs.tum.de> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7400 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Sun, 1 Aug 2004 16:33:07 +0200 Adrian Bunk wrote: > The patch below contains the following changes for the NET_SCH_NETEM > help text: > - correct the module name > - "If unsure, say N." Also applied, thanks. From davem@redhat.com Sun Aug 1 19:29:23 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:29:31 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722TNCa014826 for ; Sun, 1 Aug 2004 19:29:23 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722TEe1019278; Sun, 1 Aug 2004 22:29:14 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722TEa14187; Sun, 1 Aug 2004 22:29:14 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722SVQB023174; Sun, 1 Aug 2004 22:28:31 -0400 Date: Sun, 1 Aug 2004 19:28:09 -0700 From: "David S. Miller" To: Harald Welte Cc: netfilter-devel@lists.netfilter.org, netdev@oss.sgi.com, immidi_kiran@yahoo.com Subject: Re: [PATCH 2.6] NETFILTER: new ip_conntrack_sctp Message-Id: <20040801192809.5ab29c25.davem@redhat.com> In-Reply-To: <20040801230338.GE18758@sunbeam2> References: <20040801230338.GE18758@sunbeam2> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7401 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 01:03:38 +0200 Harald Welte wrote: > Incremental to all other patches so far Not really. Harald you really need to fixup your diff scripts wrt. handling non-netfilter files. Every diff you've sent me in this whole set against linux/sysctl.h has rejected, including this one. In this instance, none of the tcp-window-tracking sysctls were in the sysctl.h file you diffed against. I fixed this up by hand, so don't worry about this instance. From werner@almesberger.net Sun Aug 1 19:51:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:51:19 -0700 (PDT) Received: from host.almesberger.net (almesberger.net [63.105.73.238]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722pCle015454 for ; Sun, 1 Aug 2004 19:51:13 -0700 Received: from almesberger.net (vpnwa-home [10.200.0.2]) by host.almesberger.net (8.11.6/8.9.3) with ESMTP id i722pA432049; Sun, 1 Aug 2004 19:51:10 -0700 Received: (from werner@localhost) by almesberger.net (8.11.6/8.11.6) id i722p2T12467; Sun, 1 Aug 2004 23:51:02 -0300 Date: Sun, 1 Aug 2004 23:51:02 -0300 From: Werner Almesberger To: Suparna Bhattacharya Cc: netdev@oss.sgi.com Subject: net-AIO and real-time TCP (blue sky research) Message-ID: <20040801235102.K1276@almesberger.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-archive-position: 7402 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: werner@almesberger.net Precedence: bulk X-list: netdev Hi Suparna, I'm copying this to netdev, because people there may get a good chuckle out of this outlandish idea as well :-) At OLS we were chatting about using AIO also for networking. While this concept didn't seem to rank particularly high on the lunacy scale, it didn't appear overly useful either. About the only possibly interesting new functionality, besides the possibility to connect this with some eccentric TCP offloading and zero-copy scheme, would be - when applied to TCP - to make unACKed data in the out-of-order buffer available to user space. Now, it occurred to me that this may lead to something a lot more exciting: a step towards making TCP real-time capable. I'm using the term "real-time" loosely here, as in "there's a deadline, but we're flexible". I haven't followed what's going on at IETF in that area for a while, and I'm sure plenty of other people must have thought of similar schemes before, but since this seems nicer and maybe even simpler than some, let me describe it anyway. First of all, one of the main complaints of the real-time networking people is that TCP stubbornly insists on retransmitting every single segment until it is absolutely certain that the segment has been received, even if the real-time application has long since moved on. Now, with net-AIO, the application could already get all the data that has arrived after a lost segment. That's a good start, but TCP will still try to retransmit. So the next step would be to have a means to indicate that we've lost interest in the outcome of a pending AIO operation, and - as a side effect - communicate this also to TCP, so that TCP can stop trying, and do something more useful instead. Let's call this operation aio_forget(). For disk IO, this may work just like aio_cancel(). Now, aio_forget() would be a great tool for making TCP blissfully ignorant of any losses, actually making it very TCP-unfriendly. So the next step would be to record the fact that we've just forgotten some segments, but still need to make the peer aware of the fact that there (may) have been losses, and to slow down accordingly. Obviously, if we have reason to believe that the peer already knows of a loss in the general vicinity, no action is needed. Reliably communicating a loss isn't trivial, but there should be good background material in the context of ECN. Of course, if ECN is available, we may just use that. Otherwise, we may have to force a retransmission, to be sure that the peer has noticed. (And, if the forgotten segment(s) should arrive while TCP is trying to indicate a loss, it should stop doing so.) Now, assuming we have a solution for indicating losses that is satisfying both in terms of congestion control and in terms of efficiency, there are still a few things that would be nice to have, that this approach doesn't solve: - message boundaries and segment-message alignment. Not being able to use messages just because a few of their bytes ended up in a lost (and then aio_forgotten) segment would be just too bad. In some cases, it may be possible to just set the MSS to a suitable value. Also, recovering message boundaries after a loss may be tricky. - there's no direct provision for allowing adaptive coding. Of course, this is a fairly orthogonal problem. - as time passes, the sender may want to remove or substitute data it had already enqueued, e.g because there is less bandwidth than originally anticipated. So there may be a place for aio_forget() at the sender side too. Now, why could this scheme be "nicer" than just inventing some new protocol that is designed to do all these things ? The main thing that "looks good" is that this mechanism could use all of TCP, and may not even need major maintenance if some minor aspect of TCP congestion control gets changed. Anyway, this may be peculiar enough for someone to spin the idea a little further. In the worst case, I might just have provided additional evidence that, if you just search long enough, there's a perfectly plausible problem for every solution :-) - Werner -- _________________________________________________________________________ / Werner Almesberger, Buenos Aires, Argentina werner@almesberger.net / /_http://www.almesberger.net/____________________________________________/ From davem@redhat.com Sun Aug 1 19:53:02 2004 Received: with ECARTIS (v1.0.0; list netdev); Sun, 01 Aug 2004 19:53:09 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i722r2QQ015700 for ; Sun, 1 Aug 2004 19:53:02 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i722qfe1023684; Sun, 1 Aug 2004 22:52:41 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i722qfa17865; Sun, 1 Aug 2004 22:52:41 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i722pwgP031055; Sun, 1 Aug 2004 22:51:58 -0400 Date: Sun, 1 Aug 2004 19:51:35 -0700 From: "David S. Miller" To: Kazunori Miyazawa Cc: herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kazunori@miyazawa.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-Id: <20040801195135.16734846.davem@redhat.com> In-Reply-To: <20040730171205.114f22ba.kazunori@miyazawa.org> References: <20040730171205.114f22ba.kazunori@miyazawa.org> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7403 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Fri, 30 Jul 2004 17:12:05 +0900 Kazunori Miyazawa wrote: > I consider copying flowi(fl_rt) uses too much stack at the moment. > I'll re-send the fixed patch again. I agree, and let's defer this patch until we resolve that. It is simple to fix, I think. From herbert@gondor.apana.org.au Mon Aug 2 00:42:34 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 00:43:21 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i727gWcJ028544 for ; Mon, 2 Aug 2004 00:42:33 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrXSX-0000qR-00; Mon, 02 Aug 2004 17:42:14 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrXS7-0004Gy-00; Mon, 02 Aug 2004 17:41:47 +1000 Date: Mon, 2 Aug 2004 17:41:47 +1000 To: Kazunori Miyazawa Cc: davem@redhat.com, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, Alexey Kuznetsov Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-ID: <20040802074147.GA16381@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040730171205.114f22ba.kazunori@miyazawa.org> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7404 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev On Fri, Jul 30, 2004 at 05:12:05PM +0900, Kazunori Miyazawa wrote: > > This patch separates xfrm_lookup from ip6_dst_lookup > to support srcrt correctly. ip6_dst_lookup should be > called with next hop. however xfrm_lookup should be > called with final destination. It fixes them. Thanks for the patch. This raises an interesting question. Is it really correct to look at the first hop address when doing the route lookup? The problem is that if we use the first-hop address as the dst when doing the route lookup then we may end up with incorrect MTU information. This is because the MTU to the final destination may well be smaller than the MTU to the first hop. It seems that Alexey thought about this six years ago according to the rthdr comment in icmpv6_rcv(). Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From herbert@gondor.apana.org.au Mon Aug 2 02:32:07 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:32:16 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729W5sL030546 for ; Mon, 2 Aug 2004 02:32:07 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrZAh-0001VE-00; Mon, 02 Aug 2004 19:31:56 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrZAf-00058H-00; Mon, 02 Aug 2004 19:31:53 +1000 Date: Mon, 2 Aug 2004 19:31:53 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: [1/2] [IPSEC] Remove unnecessary inet_ecn.h inclusions Message-ID: <20040802093153.GA19706@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="GvXjxJ+pjyke8COw" Content-Disposition: inline User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7405 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Dave: This is a couple of clean-ups stemming from the xfrm_output change. I should've removed the inet_ecn.h inclusions in that change as the ECN code has been moved to xfrm[46]_output.c. This patch does exactly that. Signed-off-by: Herbert Xu Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt --GvXjxJ+pjyke8COw Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p1 ===== net/ipv4/ah4.c 1.38 vs edited ===== --- 1.38/net/ipv4/ah4.c 2004-07-30 21:16:40 +10:00 +++ edited/net/ipv4/ah4.c 2004-08-02 17:44:36 +10:00 @@ -1,6 +1,5 @@ #include #include -#include #include #include #include ===== net/ipv4/esp4.c 1.53 vs edited ===== --- 1.53/net/ipv4/esp4.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/esp4.c 2004-08-02 17:44:49 +10:00 @@ -1,6 +1,5 @@ #include #include -#include #include #include #include ===== net/ipv4/ipcomp.c 1.28 vs edited ===== --- 1.28/net/ipv4/ipcomp.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/ipcomp.c 2004-08-02 17:44:55 +10:00 @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include ===== net/ipv4/xfrm4_tunnel.c 1.13 vs edited ===== --- 1.13/net/ipv4/xfrm4_tunnel.c 2004-07-12 20:00:21 +10:00 +++ edited/net/ipv4/xfrm4_tunnel.c 2004-08-02 17:44:30 +10:00 @@ -7,7 +7,6 @@ #include #include #include -#include int xfrm4_tunnel_check_size(struct sk_buff *skb) { ===== net/ipv6/ah6.c 1.38 vs edited ===== --- 1.38/net/ipv6/ah6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/ah6.c 2004-08-02 17:45:20 +10:00 @@ -26,7 +26,6 @@ #include #include -#include #include #include #include ===== net/ipv6/esp6.c 1.34 vs edited ===== --- 1.34/net/ipv6/esp6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/esp6.c 2004-08-02 17:45:23 +10:00 @@ -26,7 +26,6 @@ #include #include -#include #include #include #include ===== net/ipv6/ipcomp6.c 1.19 vs edited ===== --- 1.19/net/ipv6/ipcomp6.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/ipcomp6.c 2004-08-02 17:45:25 +10:00 @@ -32,7 +32,6 @@ */ #include #include -#include #include #include #include --GvXjxJ+pjyke8COw-- From herbert@gondor.apana.org.au Mon Aug 2 02:35:12 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:35:17 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729ZAXZ030888 for ; Mon, 2 Aug 2004 02:35:11 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1BrZDg-0001Ws-00; Mon, 02 Aug 2004 19:35:00 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1BrZDg-00059H-00; Mon, 02 Aug 2004 19:35:00 +1000 Date: Mon, 2 Aug 2004 19:35:00 +1000 To: "David S. Miller" , netdev@oss.sgi.com Subject: [2/2] [IPSEC] Move xfrm[46]_tunnel_check_size into xfrm[46]_output.c Message-ID: <20040802093500.GA19747@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="82I3+IH0IqGh5yIs" Content-Disposition: inline In-Reply-To: <20040802093153.GA19706@gondor.apana.org.au> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7406 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This patch moves xfrm[46]_tunnel_check_size() into xfrm[46]_output.c where it can be made static since it's only used there. While moving the icmp.h inclusions over I also discovered that the tunnel files are missing an inclusion of net/protocol.h. So I've added them as well. Signed-off-by: Herbert Xu Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt --82I3+IH0IqGh5yIs Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=p2 ===== include/net/xfrm.h 1.62 vs edited ===== --- 1.62/include/net/xfrm.h 2004-08-02 07:15:02 +10:00 +++ edited/include/net/xfrm.h 2004-08-02 18:02:32 +10:00 @@ -821,12 +821,10 @@ extern int xfrm4_output(struct sk_buff **pskb); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler); -extern int xfrm4_tunnel_check_size(struct sk_buff *skb); extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp); extern int xfrm6_output(struct sk_buff **pskb); extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); -extern int xfrm6_tunnel_check_size(struct sk_buff *skb); extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); ===== net/ipv4/xfrm4_output.c 1.1 vs edited ===== --- 1.1/net/ipv4/xfrm4_output.c 2004-07-11 04:53:15 +10:00 +++ edited/net/ipv4/xfrm4_output.c 2004-08-02 17:58:15 +10:00 @@ -13,6 +13,7 @@ #include #include #include +#include /* Add encapsulation header. * @@ -65,6 +66,30 @@ top_iph->protocol = IPPROTO_IPIP; memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); +} + +static int xfrm4_tunnel_check_size(struct sk_buff *skb) +{ + int mtu, ret = 0; + struct dst_entry *dst; + struct iphdr *iph = skb->nh.iph; + + if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE) + goto out; + + IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; + + if (!(iph->frag_off & htons(IP_DF))) + goto out; + + dst = skb->dst; + mtu = dst_pmtu(dst) - dst->header_len - dst->trailer_len; + if (skb->len > mtu) { + icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); + ret = -EMSGSIZE; + } +out: + return ret; } int xfrm4_output(struct sk_buff **pskb) ===== net/ipv4/xfrm4_tunnel.c 1.14 vs edited ===== --- 1.14/net/ipv4/xfrm4_tunnel.c 2004-08-02 17:53:26 +10:00 +++ edited/net/ipv4/xfrm4_tunnel.c 2004-08-02 18:06:32 +10:00 @@ -6,31 +6,7 @@ #include #include #include -#include - -int xfrm4_tunnel_check_size(struct sk_buff *skb) -{ - int mtu, ret = 0; - struct dst_entry *dst; - struct iphdr *iph = skb->nh.iph; - - if (IPCB(skb)->flags & IPSKB_XFRM_TUNNEL_SIZE) - goto out; - - IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; - - if (!(iph->frag_off & htons(IP_DF))) - goto out; - - dst = skb->dst; - mtu = dst_pmtu(dst) - dst->header_len - dst->trailer_len; - if (skb->len > mtu) { - icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); - ret = -EMSGSIZE; - } -out: - return ret; -} +#include static int ipip_output(struct sk_buff **pskb) { ===== net/ipv6/xfrm6_output.c 1.1 vs edited ===== --- 1.1/net/ipv6/xfrm6_output.c 2004-07-30 12:17:21 +10:00 +++ edited/net/ipv6/xfrm6_output.c 2004-08-02 18:01:03 +10:00 @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -66,6 +67,23 @@ top_iph->hop_limit = iph->hop_limit; ipv6_addr_copy(&top_iph->saddr, (struct in6_addr *)&x->props.saddr); ipv6_addr_copy(&top_iph->daddr, (struct in6_addr *)&x->id.daddr); +} + +static int xfrm6_tunnel_check_size(struct sk_buff *skb) +{ + int mtu, ret = 0; + struct dst_entry *dst = skb->dst; + + mtu = dst_pmtu(dst) - sizeof(struct ipv6hdr); + if (mtu < IPV6_MIN_MTU) + mtu = IPV6_MIN_MTU; + + if (skb->len > mtu) { + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + ret = -EMSGSIZE; + } + + return ret; } int xfrm6_output(struct sk_buff **pskb) ===== net/ipv6/xfrm6_tunnel.c 1.4 vs edited ===== --- 1.4/net/ipv6/xfrm6_tunnel.c 2004-08-02 07:15:03 +10:00 +++ edited/net/ipv6/xfrm6_tunnel.c 2004-08-02 18:07:06 +10:00 @@ -27,8 +27,8 @@ #include #include #include -#include #include +#include #include #include @@ -342,25 +342,6 @@ } EXPORT_SYMBOL(xfrm6_tunnel_free_spi); - -int xfrm6_tunnel_check_size(struct sk_buff *skb) -{ - int mtu, ret = 0; - struct dst_entry *dst = skb->dst; - - mtu = dst_pmtu(dst) - sizeof(struct ipv6hdr); - if (mtu < IPV6_MIN_MTU) - mtu = IPV6_MIN_MTU; - - if (skb->len > mtu) { - icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); - ret = -EMSGSIZE; - } - - return ret; -} - -EXPORT_SYMBOL(xfrm6_tunnel_check_size); static int xfrm6_tunnel_output(struct sk_buff **pskb) { ===== net/xfrm/xfrm_export.c 1.2 vs edited ===== --- 1.2/net/xfrm/xfrm_export.c 2004-06-18 16:20:58 +10:00 +++ edited/net/xfrm/xfrm_export.c 2004-08-02 17:58:32 +10:00 @@ -35,7 +35,6 @@ EXPORT_SYMBOL(xfrm4_rcv); EXPORT_SYMBOL(xfrm4_tunnel_register); EXPORT_SYMBOL(xfrm4_tunnel_deregister); -EXPORT_SYMBOL(xfrm4_tunnel_check_size); EXPORT_SYMBOL(xfrm_register_type); EXPORT_SYMBOL(xfrm_unregister_type); EXPORT_SYMBOL(xfrm_get_type); --82I3+IH0IqGh5yIs-- From ptsjohol@cc.jyu.fi Mon Aug 2 02:58:13 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 02:58:20 -0700 (PDT) Received: from posti5.jyu.fi (posti5.jyu.fi [130.234.4.34]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i729wCVX002631 for ; Mon, 2 Aug 2004 02:58:13 -0700 Received: from silmu.st.jyu.fi (IDENT:KCtRHLQSWRfY1ggLLWY2hN3kjBDFjO1g@silmu.st.jyu.fi [130.234.4.64]) by posti5.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i729vicn005376; Mon, 2 Aug 2004 12:57:45 +0300 Date: Mon, 2 Aug 2004 12:57:41 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: <20040731143330.A25736@electric-eye.fr.zoreil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti5.jyu.fi; Mon, 02 Aug 2004 12:57:47 +0300 X-archive-position: 7407 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev On Sat, 31 Jul 2004, Francois Romieu wrote: > Pasi Sjoholm : > [interesting report] >> The hardest part is to tell where the problem is but I think that >> rtl8139_poll-function would be good place to start looking for the bug? >> readprofile didn't tell much.. Where to go next? I'm not so good >> programmer that I could find the right place to fix.. > In case it could make a difference: did you check if CONFIG_8139_OLD_RX_RESET > changes the behavior or not ? Yep, I tried that one also, didn't help a thing. > If it does not, I'd welcome a test report + log with the two attached patch > applied. The first one is just a placebo but the second one could help. We are making some sort of a progress but not enough. Patch r8139-20.patch didn't help. I made some printk(...)-debug messages and that part of a code was never ran. With both patch applied and RTL8139DEBUG = 1 I couldn't make the driver crash but without DEBUG it did crash. I assume that it has something to with fact that syslog did take so much io-bandwidth. (a couple of minutes log was ~1GB =)) But without: -- @@ -2024,17 +2024,17 @@ static int rtl8139_rx(struct net_device cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); + } - /* Clear out errors and receive interrupts */ - status = RTL_R16 (IntrStatus) & RxAckBits; - if (likely(status != 0)) { - if (unlikely(status & (RxFIFOOver | RxOverflow))) { - tp->stats.rx_errors++; - if (status & RxFIFOOver) - tp->stats.rx_fifo_errors++; - } - RTL_W16_F (IntrStatus, RxAckBits); + /* Clear out errors and receive interrupts */ + status = RTL_R16 (IntrStatus) & RxAckBits; + if (likely(status != 0)) { + if (unlikely(status & (RxFIFOOver | RxOverflow))) { + tp->stats.rx_errors++; + if (status & RxFIFOOver) + tp->stats.rx_fifo_errors++; } + RTL_W16_F (IntrStatus, RxAckBits); } done: -- the driver crashed... even with debug-option was turned on. Everytime the ksoftirqd started to take cpu-time there were this line in the logs: -- Aug 2 12:10:37 139_interrupt: eth0:..... -- Notice the 139... it should read rtl8139_interrupt: Here is a snapshot from the log file when driver is crashing: Full logfile is available from: http://www.cc.jyu.fi/~ptsjohol/syslog-debug.gz -- Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 03ac BufAddr 036c, free to 039c, Cmd 0c. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0000. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0001. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 0484 BufAddr 0444, free to 0474, Cmd 0c. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0000. Aug 2 12:10:37 139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:10:37 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0010. Aug 2 12:10:37 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. ...... ...... Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. Aug 2 12:12:11 rtl8139_rx: eth0: In rtl8139_rx(), current 04d0 BufAddr 04cc, free to 04c0, Cmd 0d. Aug 2 12:12:11 rtl8139_interrupt: eth0: exiting interrupt, intr_status=0x0050. -- -- Pasi Sjöholm From ptsjohol@cc.jyu.fi Mon Aug 2 03:03:39 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 03:03:44 -0700 (PDT) Received: from posti6.jyu.fi (posti6.jyu.fi [130.234.4.43]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72A3cR6003493 for ; Mon, 2 Aug 2004 03:03:39 -0700 Received: from silmu.st.jyu.fi (IDENT:oxRA6s6O4mJuvi+sWEjRqL5K3wIrdnnK@silmu.st.jyu.fi [130.234.4.64]) by posti6.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i72A3Iob001597; Mon, 2 Aug 2004 13:03:18 +0300 Date: Mon, 2 Aug 2004 13:03:15 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti6.jyu.fi; Mon, 02 Aug 2004 13:03:19 +0300 X-archive-position: 7408 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev I forgot to mention that it was quite hard to crash the driver with that /* Clear out errors and receive interrupts */-patch. Took about 15minutes everytime, when normally it takes about 2mins. On Mon, 2 Aug 2004, Pasi Sjoholm wrote: > With both patch applied and RTL8139DEBUG = 1 I couldn't make the driver > crash but without DEBUG it did crash. I assume that it has something to > with fact that syslog did take so much io-bandwidth. (a couple of minutes log > was ~1GB =)) > > But without: > > -- > @@ -2024,17 +2024,17 @@ static int rtl8139_rx(struct net_device > > cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; > RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); > + } > > - /* Clear out errors and receive interrupts */ > - status = RTL_R16 (IntrStatus) & RxAckBits; > - if (likely(status != 0)) { > - if (unlikely(status & (RxFIFOOver | RxOverflow))) > { > - tp->stats.rx_errors++; > - if (status & RxFIFOOver) > - tp->stats.rx_fifo_errors++; > - } > - RTL_W16_F (IntrStatus, RxAckBits); > + /* Clear out errors and receive interrupts */ > + status = RTL_R16 (IntrStatus) & RxAckBits; > + if (likely(status != 0)) { > + if (unlikely(status & (RxFIFOOver | RxOverflow))) { > + tp->stats.rx_errors++; > + if (status & RxFIFOOver) > + tp->stats.rx_fifo_errors++; > } > + RTL_W16_F (IntrStatus, RxAckBits); > } > > done: > -- > > the driver crashed... even with debug-option was turned on. > Everytime the ksoftirqd started to take cpu-time there were this line in > the logs: From ak@suse.de Mon Aug 2 04:46:42 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 04:46:48 -0700 (PDT) Received: from Cantor.suse.de (cantor.suse.de [195.135.220.2]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72BkfUC009561 for ; Mon, 2 Aug 2004 04:46:41 -0700 Received: from hermes.suse.de (hermes-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by Cantor.suse.de (Postfix) with ESMTP id B3C839A8D29; Mon, 2 Aug 2004 13:45:07 +0200 (CEST) Date: Mon, 2 Aug 2004 13:45:06 +0200 From: Andi Kleen To: "David S. Miller" Cc: Jeff Garzik , tmattox@gmail.com, hadi@cyberus.ca, netdev@oss.sgi.com Subject: Re: [RFC,PATCH] fastroute dead code... Message-ID: <20040802114506.GC25951@wotan.suse.de> References: <20040730060348.GA22854@havoc.gtf.org> <20040730193515.GA11365@havoc.gtf.org> <20040730131004.2be1274d.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040730131004.2be1274d.davem@redhat.com> X-archive-position: 7409 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ak@suse.de Precedence: bulk X-list: netdev On Fri, Jul 30, 2004 at 01:10:04PM -0700, David S. Miller wrote: > On Fri, 30 Jul 2004 15:35:15 -0400 > Jeff Garzik wrote: > > > It is dead code, as-is, in the kernel. It would require patches to > > actually work at all. > > > > It is impossible that fastrouting is being actively used, without patches. > > I totally agree. And people can always resurrect it from the > repository history or an old tarball if they wish. > > I think it should be killed entirely, and that's what I'm going > to do. The s390 people used to use it for local forwarding between partitions. I don't know if they still do however. -Andi > From bruce@cs.usyd.edu.au Mon Aug 2 06:41:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:41:24 -0700 (PDT) Received: from staff.cs.usyd.edu.au (staff.cs.usyd.edu.au [129.78.8.1]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72DfF2n018446 for ; Mon, 2 Aug 2004 06:41:17 -0700 Received: from nlp0.cs.usyd.edu.au. [129.78.10.52] by staff.cs.usyd.edu.au.; Mon, 02 Aug 2004 23:41:09 +1000 Received: from nlp0.cs.usyd.edu.au (localhost.cs.usyd.edu.au [127.0.0.1]) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8) with ESMTP id i72Df9Yo021571 for ; Mon, 2 Aug 2004 23:41:09 +1000 Received: (from bruce@localhost) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8/Submit) id i72Df9TP021569 for netdev@oss.sgi.com; Mon, 2 Aug 2004 23:41:09 +1000 Message-Id: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> Date: Mon, 02 Aug 2004 23:29:20 +1000 From: bruce@it.usyd.edu.au (Bruce Janson) Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver To: netdev@oss.sgi.com Cc: bruce@it.usyd.edu.au X-archive-position: 7410 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bruce@it.usyd.edu.au Precedence: bulk X-list: netdev Hi Randy, Thanks for your reply. From rddunlap@osdl.org Mon Aug 02 03:43:31 2004 ... To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev ... (moving this to netdev mailing list) ... [OK, but please Cc me explicitly as I don't subscribe to netdev.] On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | I would like to be able to boot the kernel with parameters that | will allow control of the tulip device. On some ethernet devices | this used to be possible via (something like): | | ether=0,0,1,0,eth0 | | which would pass the four numeric parameters (as, I think, dev->irq, | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | controlled eth0. A convention adopted by some net drivers then allowed | dev->mem_start to be interpretted as a set of flags that would control | device characteristics (e.g. full-duplex vs half-duplex mode). | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | if (dev->mem_start & MEDIA_MASK) | tp->default_port = dev->mem_start & MEDIA_MASK; | | suggests that this might still work. However, I have been unable | to force dev->mem_start in that driver to become non-zero via any | kernel boot-time parameters. My limited understanding of the code | that precedes the above lines in that file suggests that the "dev" | structure is not what it used to be... The driver never calls netdev_boot_setup_check(), which is what would give the driver its command line parameters. Did this work in early 2.6.x? There have been several changes in this area. ... No idea. This is the first in the 2.6 kernel series that I have tried. The driver can't do a simple call to netdev_boot_setup_check() because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, and those values come from PCI config space for PCI drivers. The driver could create a fake for that purpose, but it's more likely that ethtool or mii-tool should be used to change media/speed etc... Although now that I look at the driver source code, I don't see ethtool or mii-tool support for those options. ... Yes (tried that too :-(). | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | mentions "ether=..." but marks it as obsolete, replaced by | the equivalent "netdev=...". Elsewhere in that file, the entry | for "netdev=..." describes what appears to be the functionality | that I seek. | | So, is it still possible to perform the same sort of control | operations on a tulip driver via kernel boot-time parameters | as one can do via module load-time parameters? If so, how? The current tulip-core driver supports setting only the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image (using mem_start, as you noted above). ... Sorry, I don't follow the above. Would you mind giving me an example, please, of how for the tulip driver I might set the default transceiver (media type) on the kernel boot/command line when the driver is built into the kernel image? Regards, bruce. From shinemohamed_j@naturesoft.net Mon Aug 2 06:54:04 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:54:10 -0700 (PDT) Received: from naturesoft.net ([203.145.184.221]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72Drw4i019218 for ; Mon, 2 Aug 2004 06:54:03 -0700 Received: from shine.naturesoft.com ([192.168.0.84]) by naturesoft.net with esmtp (Exim 3.35 #1) id 1BrcyI-0005qE-00; Mon, 02 Aug 2004 19:05:22 +0530 Subject: [TRIVIAL PATCH]mistake in the comment in include/linux/wireless.h From: Shine Mohamed Jabbar Reply-To: shinemohamed_j@naturesoft.net To: davem@redhat.com Cc: jt@hpl.hp.com, netdev@oss.sgi.com Content-Type: multipart/mixed; boundary="=-kVZOS8vuCIva4VAmkT5m" Organization: Naturesoft Message-Id: <1091454063.25300.109.camel@shine.naturesoft.com> Mime-Version: 1.0 X-Mailer: Ximian Evolution 1.4.6 (1.4.6-2) Date: Mon, 02 Aug 2004 19:11:03 +0530 X-archive-position: 7411 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shinemohamed_j@naturesoft.net Precedence: bulk X-list: netdev --=-kVZOS8vuCIva4VAmkT5m Content-Type: text/plain Content-Transfer-Encoding: 7bit [Resend - forgot to cc to netdev ML] Hi Dave, There is a mistake in the comment given in the include/linux/wireless.h. The given patch will fix it. Please apply if its useful. Regards, Shine Mohamed Jabbar --=-kVZOS8vuCIva4VAmkT5m Content-Description: Content-Disposition: attachment; filename=diff.patch Content-Type: text/x-patch; charset=UTF-8 Content-Transfer-Encoding: 7bit --- linux-2.6.8-rc2-bk11/include/linux/wireless.h.orig 2004-08-02 17:39:11.891418904 +0530 +++ linux-2.6.8-rc2-bk11/include/linux/wireless.h 2004-08-02 17:35:56.309151928 +0530 @@ -47,12 +47,12 @@ * # include/net/iw_handler.h * * Note as well that /proc/net/wireless implementation has now moved in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Wireless Events (2002 -> onward) : * -------------------------------- * Events are defined at the end of this file, and implemented in : - * # include/linux/wireless.c + * # net/core/wireless.c * * Other comments : * -------------- --=-kVZOS8vuCIva4VAmkT5m-- From yoshfuji@linux-ipv6.org Mon Aug 2 06:59:19 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 06:59:26 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72DxJVW019590 for ; Mon, 2 Aug 2004 06:59:19 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id BEE3233CE5; Mon, 2 Aug 2004 22:59:40 +0900 (JST) Date: Mon, 02 Aug 2004 06:59:40 -0700 (PDT) Message-Id: <20040802.065940.86004622.yoshfuji@linux-ipv6.org> To: suckfish@ihug.co.nz Cc: davem@redhat.com, pekkas@netcore.fi, linux-kernel@vger.kernel.org, yoshfuji@linux-ipv6.org, netdev@oss.sgi.com Subject: Re: [PATCH] Trivial ipv6 fix. From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <1091434328.16469.5.camel@localhost.localdomain> References: <1091434328.16469.5.camel@localhost.localdomain> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7412 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <1091434328.16469.5.camel@localhost.localdomain> (at Mon, 02 Aug 2004 20:12:08 +1200), Ralph Loader says: > ipv6_addr_hash doesn't do what it's comment says. The comment was > probably what was intended, not that it'll make much difference in > practice. Oops, David, please apply this. > Signed-off-by: Ralph Loader Signed-off-by: Hideaki YOSHIFUJI ===== include/net/addrconf.h 1.17 vs edited ===== --- 1.17/include/net/addrconf.h 2004-07-29 02:00:50 +09:00 +++ edited/include/net/addrconf.h 2004-08-02 22:57:38 +09:00 @@ -178,8 +178,8 @@ * This will include the IEEE address token on links that support it. */ - word = addr->s6_addr[2] ^ addr->s6_addr32[3]; - word ^= (word>>16); + word = addr->s6_addr32[2] ^ addr->s6_addr32[3]; + word ^= (word >> 16); word ^= (word >> 8); return ((word ^ (word >> 4)) & 0x0f); -- Hideaki YOSHIFUJI @ USAGI Project GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA From kumar.gala@freescale.com Mon Aug 2 06:59:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:00:03 -0700 (PDT) Received: from motgate2.mot.com (motgate2.mot.com [144.189.100.101]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72DxuoY019709 for ; Mon, 2 Aug 2004 06:59:56 -0700 Received: from az33exr02.mot.com (az33exr02.mot.com [10.64.251.232]) by motgate2.mot.com (Motorola/Motgate2) with ESMTP id i72Dt6QO007583; Mon, 2 Aug 2004 06:55:06 -0700 (MST) Received: from [192.168.123.112] ([163.14.1.11]) by az33exr02.mot.com (Motorola/az33exr02) with ESMTP id i72DvZVh017469; Mon, 2 Aug 2004 08:57:35 -0500 In-Reply-To: <41058139.5040400@pobox.com> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> Content-Transfer-Encoding: 7bit Cc: Andy Fleming , Kumar Gala , netdev@oss.sgi.com, dwmw2@infradead.org, hadi@cyberus.ca, Andy Fleming From: Kumar Gala Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 08:59:21 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7413 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev Jeff, Any update on this review of Andy's latest fixes? thanks - kumar On Jul 26, 2004, at 5:10 PM, Jeff Garzik wrote: > Andy Fleming wrote: >> Argh. We found a couple bugs in that last patch. This patch fixes >> those bugs. However, please note that the patch is done against the >> original submission from weeks ago. This patch replaces my most >> recent patch. > > > Thanks, I'll look it over. > > I've been away celebrating (or mourning) my 30th birthday, and have > several patches to run through. I'll add it to the pile, though it > may be a few days before I get to it. > > Jeff From bernie@step.polymtl.ca Mon Aug 2 07:06:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:07:02 -0700 (PDT) Received: from tomts16-srv.bellnexxia.net (tomts16.bellnexxia.net [209.226.175.4]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72E6uAK020279 for ; Mon, 2 Aug 2004 07:06:56 -0700 Received: from [192.168.0.100] ([67.68.201.22]) by tomts16-srv.bellnexxia.net (InterMail vM.5.01.06.10 201-253-122-130-110-20040306) with ESMTP id <20040802140651.YVTU9492.tomts16-srv.bellnexxia.net@[192.168.0.100]> for ; Mon, 2 Aug 2004 10:06:51 -0400 Message-ID: <410E4C16.6070604@step.polymtl.ca> Date: Mon, 02 Aug 2004 10:13:42 -0400 From: Bertrand Guay-Paquet User-Agent: Mozilla Thunderbird 0.7.2 (Windows/20040707) X-Accept-Language: en-us, en MIME-Version: 1.0 To: netdev@oss.sgi.com Subject: skb_clone slower than copying skb data Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7414 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bernie@step.polymtl.ca Precedence: bulk X-list: netdev Hello, I am writing a patch for the usbnet driver to add support for the Prolific PL2501 USB host-to-host cable. My question is entirely related to netdev business however, so please read on. In order to achieve Win32 interropability, the driver needs to receive up to 6 ethernet packets wrapped up in a single skb. My current implementation for reading the contained individual packets is: (simplified to show relevant parts) for (each packet in skb except last one) { length = packet_length(); if (!(skb2 = alloc_skb(length, GFP_ATOMIC))) return -ENOMEM; //Copy the data related to the current ethernet packet memcpy(skb_put(skb2, length), skb->data, length); //Jump to next ethernet packet skb_pull(skb, length); netif_rx(skb2); } //Process last packet netif_rx(skb); ========== This works very well but uses unnecessary memory for the memcpy. I then tried: (again simplified to show relevant parts): for (each packet in skb except last one) { length = packet_length(); if (!(skb2 = skb_clone(skb, GFP_ATOMIC))) return -ENOMEM; //Copy the data related to the current ethernet packet skb_trim(skb2, length); //Jump to next ethernet packet skb_pull(skb, length); netif_rx(skb2); } //Process last packet netif_rx(skb); ========== This works as well, but the throughput is cut in half. How can this be so? Is skb_clone combined with netif_rx supposed to be so slow? I have searched other uses of skb_clone and have not found any similar to mine so I do not know if this is normal behaviour or not. I have tried using skb_clone with 2.4.26 and 2.6.7 with the same results. Any help would be greatly appreciated! Bertrand From SRS0+c8a65e14805b63b7c82e+344+infradead.org+hch@phoenix-150906.srs.infradead.org Mon Aug 2 07:09:33 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:09:40 -0700 (PDT) Received: from phoenix.infradead.org (imladris.demon.co.uk [193.237.130.41]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72E9TPW020621 for ; Mon, 2 Aug 2004 07:09:32 -0700 Received: from hch by phoenix.infradead.org with local (Exim 4.30 #5 (Red Hat Linux)) id 1BrdUv-0001Oz-TA; Mon, 02 Aug 2004 15:09:05 +0100 Date: Mon, 2 Aug 2004 15:09:05 +0100 From: Christoph Hellwig To: Kumar Gala Cc: Jeff Garzik , Andy Fleming , Kumar Gala , netdev@oss.sgi.com, dwmw2@infradead.org, hadi@cyberus.ca, Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Message-ID: <20040802150905.A5381@infradead.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com>; from kumar.gala@freescale.com on Mon, Aug 02, 2004 at 08:59:21AM -0500 X-SRS-Rewrite: SMTP reverse-path rewritten from by phoenix.infradead.org See http://www.infradead.org/rpr.html X-archive-position: 7415 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: hch@infradead.org Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 08:59:21AM -0500, Kumar Gala wrote: > Jeff, > > Any update on this review of Andy's latest fixes? > > thanks > > - kumar So when will you fix the modular compile? From kumar.gala@freescale.com Mon Aug 2 07:12:08 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 07:12:13 -0700 (PDT) Received: from motgate3.mot.com (motgate3.mot.com [144.189.100.103]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72EC851021014 for ; Mon, 2 Aug 2004 07:12:08 -0700 Received: from az33exr02.mot.com (az33exr02.mot.com [10.64.251.232]) by motgate3.mot.com (Motorola/Motgate3) with ESMTP id i72EBkiC003772; Mon, 2 Aug 2004 07:11:49 -0700 (MST) Received: from [192.168.123.112] ([163.14.1.11]) by az33exr02.mot.com (Motorola/az33exr02) with ESMTP id i72E9xVh005035; Mon, 2 Aug 2004 09:10:00 -0500 In-Reply-To: <20040802150905.A5381@infradead.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <40EB89CC.2040100@pobox.com> <10E7AA25-DF50-11D8-90B5-000393C30512@freescale.com> <41058139.5040400@pobox.com> <277DBAC2-E48C-11D8-BC10-000393DBC2E8@freescale.com> <20040802150905.A5381@infradead.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit Cc: Jeff Garzik , , Kumar Gala , , Andy Fleming , From: Kumar Gala Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 09:11:44 -0500 To: Christoph Hellwig X-Mailer: Apple Mail (2.618) X-archive-position: 7416 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev hch, Will look at it today. Was not aware of this still not work. thanks - kumar On Aug 2, 2004, at 9:09 AM, Christoph Hellwig wrote: > On Mon, Aug 02, 2004 at 08:59:21AM -0500, Kumar Gala wrote: >> Jeff, >> >> Any update on this review of Andy's latest fixes? >> >> thanks >> >> - kumar > > So when will you fix the modular compile? From kumar.gala@freescale.com Mon Aug 2 08:26:47 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 08:26:54 -0700 (PDT) Received: from motgate8.mot.com (motgate8.mot.com [129.188.136.8]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72FQla5026193 for ; Mon, 2 Aug 2004 08:26:47 -0700 Received: from il06exr02.mot.com (il06exr02.mot.com [129.188.137.132]) by motgate8.mot.com (Motorola/Motgate8) with ESMTP id i72FRSRC017075; Mon, 2 Aug 2004 08:27:29 -0700 (MST) Received: from [10.82.17.247] ([10.82.17.247]) by il06exr02.mot.com (Motorola/il06exr02) with ESMTP id i72FPMO6000950; Mon, 2 Aug 2004 10:25:23 -0500 In-Reply-To: <9DFF23E1E33391449FDC324526D1F25902833769@sjc1exm02.pmc_nt.nt.pmc-sierra.bc.ca> References: <9DFF23E1E33391449FDC324526D1F25902833769@sjc1exm02.pmc_nt.nt.pmc-sierra.bc.ca> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: <578EC36E-E498-11D8-939F-000393DBC2E8@freescale.com> Content-Transfer-Encoding: 7bit Cc: Jeff Garzik , , , , Ralf Baechle From: Kumar Gala Subject: Re: [RFC,PATCH] fastroute dead code... Date: Mon, 2 Aug 2004 10:26:36 -0500 To: Manish Lachwani X-Mailer: Apple Mail (2.618) X-archive-position: 7417 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kumar.gala@freescale.com Precedence: bulk X-list: netdev I want to say an internal group in Freescale has seen similar style performance improvements for integrated gig-e controllers in 2.4. - kumar On Jul 30, 2004, at 3:31 PM, Manish Lachwani wrote: > Is this a 2.6 issue or a 2.4 issue? This is because I am using 2.4.21 > kernel and so do the customers of the board. This board supports 1.0 > Ghz PMC-Sierra Rm9000 processor. With fast routing, the IP forwarding > numbers are about 900 Kpps. While in the case where there is no fast > routing, the numbers are about 450 Kpps (NAPI enabled) > > I still have not done any 2.6 benchmarking since the board support is > not completely functional in 2.6 as yet. > > Thanks > Manish > > -----Original Message----- > From: jamal [mailto:hadi@cyberus.ca] > Sent: Friday, July 30, 2004 1:35 PM > To: Manish Lachwani > Cc: Jeff Garzik; tmattox@gmail.com; netdev@oss.sgi.com; Ralf Baechle > Subject: Re: [RFC,PATCH] fastroute dead code... > > > On Fri, 2004-07-30 at 16:10, David S. Miller wrote: >> On Fri, 30 Jul 2004 15:35:15 -0400 >> Jeff Garzik wrote: >> >>> It is dead code, as-is, in the kernel. It would require patches to >>> actually work at all. >>> >>> It is impossible that fastrouting is being actively used, without >>> patches. >> >> I totally agree. And people can always resurrect it from the >> repository history or an old tarball if they wish. > > Patches are needed for the driver to use that code. So its not entirely > dead code i.e it is referenced from fastroute enabled drivers. > Sample (really old) code found at: > http://ftp.iasi.roedu.net/mirrors/ftp.inr.ac.ru/ip-routing/fastroute/ > > >> I think it should be killed entirely, and that's what I'm going >> to do. > > Nod from here. > Before you kill it lets hear from Ralf who is acquinted with someone > that uses it and sings praises of it (although i personaly dont believe > it ;->). > > cheers, > jamal From rddunlap@osdl.org Mon Aug 2 08:47:34 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 08:47:39 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72FlV39026753 for ; Mon, 2 Aug 2004 08:47:33 -0700 Received: from midway.verizon.net (build.pdx.osdl.net [172.20.1.2]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72FlG130409; Mon, 2 Aug 2004 08:47:16 -0700 Date: Mon, 2 Aug 2004 08:38:37 -0700 From: "Randy.Dunlap" To: bruce@it.usyd.edu.au (Bruce Janson) Cc: netdev@oss.sgi.com, bruce@it.usyd.edu.au Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver Message-Id: <20040802083837.131a17e3.rddunlap@osdl.org> In-Reply-To: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> References: <200408021341.i72Df9TP021569@nlp0.cs.usyd.edu.au> Organization: OSDL X-Mailer: Sylpheed version 0.9.8a (GTK+ 1.2.10; i686-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7418 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rddunlap@osdl.org Precedence: bulk X-list: netdev On Mon, 02 Aug 2004 23:29:20 +1000 Bruce Janson wrote: | Hi Randy, | Thanks for your reply. | | (moving this to netdev mailing list) | ... | | [OK, but please Cc me explicitly as I don't subscribe to netdev.] | | On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | | | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | | I would like to be able to boot the kernel with parameters that | | will allow control of the tulip device. On some ethernet devices | | this used to be possible via (something like): | | | | ether=0,0,1,0,eth0 | | | | which would pass the four numeric parameters (as, I think, dev->irq, | | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | | controlled eth0. A convention adopted by some net drivers then allowed | | dev->mem_start to be interpretted as a set of flags that would control | | device characteristics (e.g. full-duplex vs half-duplex mode). | | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | | | if (dev->mem_start & MEDIA_MASK) | | tp->default_port = dev->mem_start & MEDIA_MASK; | | | | suggests that this might still work. However, I have been unable | | to force dev->mem_start in that driver to become non-zero via any | | kernel boot-time parameters. My limited understanding of the code | | that precedes the above lines in that file suggests that the "dev" | | structure is not what it used to be... | | The driver never calls netdev_boot_setup_check(), which is | what would give the driver its command line parameters. | | Did this work in early 2.6.x? There have been several changes | in this area. | ... | | No idea. This is the first in the 2.6 kernel series that I have | tried. | | The driver can't do a simple call to netdev_boot_setup_check() | because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, | and those values come from PCI config space for PCI drivers. | The driver could create a fake for that purpose, but it's | more likely that ethtool or mii-tool should be used to change | media/speed etc... Although now that I look at the driver source | code, I don't see ethtool or mii-tool support for those options. | ... | | Yes (tried that too :-(). Which/what have you tried? Is it possible for you to use the tulip driver as modular instead of builtin? With modular, you can set the parameters... but your environment may not allow modular? | | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | | mentions "ether=..." but marks it as obsolete, replaced by | | the equivalent "netdev=...". Elsewhere in that file, the entry | | for "netdev=..." describes what appears to be the functionality | | that I seek. | | | | So, is it still possible to perform the same sort of control | | operations on a tulip driver via kernel boot-time parameters | | as one can do via module load-time parameters? If so, how? | | The current tulip-core driver supports setting only the default transceiver | (media type) on the kernel boot/command line when the driver is built into | the kernel image (using mem_start, as you noted above). | ... | | Sorry, I don't follow the above. Would you mind giving me an example, | please, of how for the tulip driver I might set the default transceiver | (media type) on the kernel boot/command line when the driver is built | into the kernel image? No, I can't. tulip-core uses to mean transceiver, but like I said above, it never calls netdev_boot_setup_check() to get that data, so it's useless currently. Sorry. I'm hoping that someone else will chime in with suggestions for the right thing to do here. -- ~Randy From bruce@cs.usyd.edu.au Mon Aug 2 09:32:43 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 09:32:51 -0700 (PDT) Received: from staff.cs.usyd.edu.au (staff.cs.usyd.edu.au [129.78.8.1]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72GWfit027725 for ; Mon, 2 Aug 2004 09:32:42 -0700 Received: from nlp0.cs.usyd.edu.au. [129.78.10.52] by staff.cs.usyd.edu.au.; Tue, 03 Aug 2004 02:32:34 +1000 Received: from nlp0.cs.usyd.edu.au (localhost.cs.usyd.edu.au [127.0.0.1]) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8) with ESMTP id i72GWYYo022014 for ; Tue, 3 Aug 2004 02:32:34 +1000 Received: (from bruce@localhost) by nlp0.cs.usyd.edu.au (8.12.8/8.12.8/Submit) id i72GWYfs022012 for netdev@oss.sgi.com; Tue, 3 Aug 2004 02:32:34 +1000 Message-Id: <200408021632.i72GWYfs022012@nlp0.cs.usyd.edu.au> Date: Tue, 03 Aug 2004 01:58:46 +1000 From: bruce@it.usyd.edu.au (Bruce Janson) Subject: Re: 2.6.7 kernel boot-time configuration of a non-modular tulip driver To: netdev@oss.sgi.com Cc: bruce@it.usyd.edu.au X-archive-position: 7419 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bruce@it.usyd.edu.au Precedence: bulk X-list: netdev From rddunlap@osdl.org Tue Aug 03 01:47:23 2004 ... On Mon, 02 Aug 2004 23:29:20 +1000 Bruce Janson wrote: ... | On Sun, 01 Aug 2004 00:48:22 +1000 Bruce Janson wrote: | | | I have a linux 2.6.7 kernel which contains a compiled-in tulip driver. | | I would like to be able to boot the kernel with parameters that | | will allow control of the tulip device. On some ethernet devices | | this used to be possible via (something like): | | | | ether=0,0,1,0,eth0 | | | | which would pass the four numeric parameters (as, I think, dev->irq, | | dev->ioaddr, dev->mem_start and dev->mem_end) to the net driver that | | controlled eth0. A convention adopted by some net drivers then allowed | | dev->mem_start to be interpretted as a set of flags that would control | | device characteristics (e.g. full-duplex vs half-duplex mode). | | In .../linux-2.6.7/drivers/net/tulip/tulip_core.c:1587: | | | | if (dev->mem_start & MEDIA_MASK) | | tp->default_port = dev->mem_start & MEDIA_MASK; | | | | suggests that this might still work. However, I have been unable | | to force dev->mem_start in that driver to become non-zero via any | | kernel boot-time parameters. My limited understanding of the code | | that precedes the above lines in that file suggests that the "dev" | | structure is not what it used to be... | | The driver never calls netdev_boot_setup_check(), which is | what would give the driver its command line parameters. | | Did this work in early 2.6.x? There have been several changes | in this area. | ... | | No idea. This is the first in the 2.6 kernel series that I have | tried. | | The driver can't do a simple call to netdev_boot_setup_check() | because that will overwrite dev-> {irq, base_addr, mem_start, mem_end}, | and those values come from PCI config space for PCI drivers. | The driver could create a fake for that purpose, but it's | more likely that ethtool or mii-tool should be used to change | media/speed etc... Although now that I look at the driver source | code, I don't see ethtool or mii-tool support for those options. | ... | | Yes (tried that too :-(). Which/what have you tried? ... By that I meant that I had tried to use ethtool to change settings after boot and found that the tulip driver did not support use of ethtool in that way. I have not tried mii-tool (recently). However, neither of these are a satisfactory solution as I need to have the interace come up in the desired mode initially, not some time later. | | ../linux-2.6.7/Documentation/kernel-parameters.txt:402 still | | mentions "ether=..." but marks it as obsolete, replaced by | | the equivalent "netdev=...". Elsewhere in that file, the entry | | for "netdev=..." describes what appears to be the functionality | | that I seek. | | | | So, is it still possible to perform the same sort of control | | operations on a tulip driver via kernel boot-time parameters | | as one can do via module load-time parameters? If so, how? | | The current tulip-core driver supports setting only the default transceiver | (media type) on the kernel boot/command line when the driver is built into | the kernel image (using mem_start, as you noted above). | ... | | Sorry, I don't follow the above. Would you mind giving me an example, | please, of how for the tulip driver I might set the default transceiver | (media type) on the kernel boot/command line when the driver is built | into the kernel image? No, I can't. tulip-core uses to mean transceiver, but like I said above, it never calls netdev_boot_setup_check() to get that data, so it's useless currently. Sorry. ... No need to apologise. All I wanted to hear was that someone who actually understood the code agreed that the tulip driver, this boot-time parameter setting mechanism and the documentation (such as it is) are currently mutually buggered :-). Now that I know that, I can stop beating my head against the wall trying to work out what I have done wrong and instead, get on with working around this limitation. Many thanks! :-) From rmk+netdev=oss.sgi.com@arm.linux.org.uk Mon Aug 2 12:02:28 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:02:35 -0700 (PDT) Received: from caramon.arm.linux.org.uk (caramon.arm.linux.org.uk [212.18.232.186]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72J2QZR003078 for ; Mon, 2 Aug 2004 12:02:28 -0700 Received: from flint.arm.linux.org.uk ([2002:d412:e8ba:1:201:2ff:fe14:8fad]) by caramon.arm.linux.org.uk with asmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.33) id 1Bri4Z-0004Qi-B6; Mon, 02 Aug 2004 20:02:11 +0100 Received: from rmk by flint.arm.linux.org.uk with local (Exim 4.33) id 1Bri4Y-0002Wk-Cq; Mon, 02 Aug 2004 20:02:10 +0100 Date: Mon, 2 Aug 2004 20:02:10 +0100 From: Russell King To: "David S. Miller" Cc: jgarzik@pobox.com, shemminger@osdl.org, netdev@oss.sgi.com, greg@kroah.com Subject: Re: [Fwd: pcmcia ether drivers can't be unloaded] Message-ID: <20040802200210.A9498@flint.arm.linux.org.uk> References: <41068BEF.7010200@pobox.com> <20040727233614.B30782@flint.arm.linux.org.uk> <20040727171929.17858c7b.davem@redhat.com> <20040728165024.A8475@flint.arm.linux.org.uk> <20040728085419.773c4d94.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <20040728085419.773c4d94.davem@redhat.com>; from davem@redhat.com on Wed, Jul 28, 2004 at 08:54:19AM -0700 X-archive-position: 7420 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: rmk@arm.linux.org.uk Precedence: bulk X-list: netdev On Wed, Jul 28, 2004 at 08:54:19AM -0700, David S. Miller wrote: > On Wed, 28 Jul 2004 16:50:24 +0100 > Russell King wrote: > > > On Tue, Jul 27, 2004 at 05:19:29PM -0700, David S. Miller wrote: > > > I totally disagree. This is a bogus argument for two reasons: > > > > You may disagree, that is your option. However, facts are facts - > > this is how the PCMCIA layer currently works, and short of rewriting > > the whole damned thing it isn't going to change. Sorry. > > Stephen offered a solution, moving this stray refcount into a toplevel > pcmcia bus type object. We are not constrained by how the PCMCIA layer > currently works, just as we were not constrained a year ago by how the > generic network device handling worked when it was totally broken in > this area. We just fixed it instead of whining. Sorry, I'm not the one whining here. I just have _ZERO_ time at the moment because I'm still in Canada and only have sporadic access to stuff. Sorry if this doesn't meet your requirements, but this is the best I can offer you at the moment. In short, my best and only answer is "tough, live with it until I can investigate." -- Russell King Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/ maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/ 2.6 Serial core From manfred@colorfullife.com Mon Aug 2 12:37:31 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:37:40 -0700 (PDT) Received: from dbl.q-ag.de (dbl.q-ag.de [213.172.117.3] (may be forged)) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72JbItf010698 for ; Mon, 2 Aug 2004 12:37:29 -0700 Received: from colorfullife.com (dbl [127.0.0.1]) by dbl.q-ag.de (8.12.3/8.12.3/Debian-6.6) with ESMTP id i72JaXuG014435; Mon, 2 Aug 2004 21:36:34 +0200 Message-ID: <410E9841.8000100@colorfullife.com> Date: Mon, 02 Aug 2004 21:38:41 +0200 From: Manfred Spraul User-Agent: Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.6) Gecko/20040510 X-Accept-Language: en-us, en MIME-Version: 1.0 To: James Drabb CC: netdev@oss.sgi.com, c-d.hailfinger.kernel.2004@gmx.net Subject: Re: forcedeth References: <410D3377.3030505@tampabay.rr.com> <410D4120.2020604@colorfullife.com> <410D682F.4090809@tampabay.rr.com> In-Reply-To: <410D682F.4090809@tampabay.rr.com> Content-Type: multipart/mixed; boundary="------------090405070803030805000201" X-archive-position: 7421 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: manfred@colorfullife.com Precedence: bulk X-list: netdev This is a multi-part message in MIME format. --------------090405070803030805000201 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit James Drabb wrote: >> Manfred > > -- > > Please send me the latest forcedeth.c and I will give it a go. Do you > have the makefile so I can compile the module outside of the kernel? > No - you need the 2.6.7 tree as the base. Attached is the patch against 2.6.7 I'm again interested in the same sequence as you did after booting into WinXP, just without WinXP: modprobe, wait, ifup, ethtool, unplug cable, ethtool, plug cable back in, ethtool Always wait ~ 5 seconds before calling ethtool. The patch is a special version, it already contains a timer that polls for phy state changes and prints them into the kernel log (dmesg). -- Manfred --------------090405070803030805000201 Content-Type: text/plain; name="patch-fff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch-fff" // $Header$ // Kernel Version: // VERSION = 2 // PATCHLEVEL = 6 // SUBLEVEL = 7 // EXTRAVERSION = --- 2.6/drivers/net/forcedeth.c 2004-08-02 21:19:05.979380576 +0200 +++ build-2.6/drivers/net/forcedeth.c 2004-08-02 21:16:47.678405520 +0200 @@ -10,8 +10,11 @@ * trademarks of NVIDIA Corporation in the United States and other * countries. * - * Copyright (C) 2003 Manfred Spraul + * Copyright (C) 2003,4 Manfred Spraul * Copyright (C) 2004 Andrew de Quincey (wol support) + * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane + * IRQ rate fixes, bigendian fixes, cleanups, verification) + * Copyright (c) 2004 NVIDIA Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,15 +63,18 @@ * 0.19: 29 Nov 2003: Handle RxNoBuf, detect & handle invalid mac * addresses, really stop rx if already running * in nv_start_rx, clean up a bit. - * (C) Carl-Daniel Hailfinger * 0.20: 07 Dec 2003: alloc fixes * 0.21: 12 Jan 2004: additional alloc fix, nic polling fix. * 0.22: 19 Jan 2004: reprogram timer to a sane rate, avoid lockup - * on close. - * (C) Carl-Daniel Hailfinger, Manfred Spraul + * on close. * 0.23: 26 Jan 2004: various small cleanups * 0.24: 27 Feb 2004: make driver even less anonymous in backtraces * 0.25: 09 Mar 2004: wol support + * 0.26: 03 Jun 2004: netdriver specific annotation, sparse-related fixes + * 0.27: 19 Jun 2004: Gigabit support, new descriptor rings, + * added CK804/MCP04 device IDs, code fixes + * for registers, link status and other minor fixes. + * 0.28: 21 Jun 2004: Big cleanup, making driver mostly endian safe * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -80,7 +86,8 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.25" +#define FORCEDETH_VERSION "0.28a" +#define DRV_NAME "forcedeth" #include #include @@ -117,12 +124,14 @@ #define DEV_IRQMASK_1 0x0002 #define DEV_IRQMASK_2 0x0004 #define DEV_NEED_TIMERIRQ 0x0008 +#define DEV_NEED_LINKTIMER 0x0010 enum { NvRegIrqStatus = 0x000, #define NVREG_IRQSTAT_MIIEVENT 0x040 #define NVREG_IRQSTAT_MASK 0x1ff NvRegIrqMask = 0x004, +#define NVREG_IRQ_RX_ERROR 0x0001 #define NVREG_IRQ_RX 0x0002 #define NVREG_IRQ_RX_NOBUF 0x0004 #define NVREG_IRQ_TX_ERR 0x0008 @@ -132,7 +141,7 @@ enum { #define NVREG_IRQ_TX1 0x0100 #define NVREG_IRQMASK_WANTED_1 0x005f #define NVREG_IRQMASK_WANTED_2 0x0147 -#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) +#define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) NvRegUnknownSetupReg6 = 0x008, #define NVREG_UNKSETUP6_VAL 3 @@ -159,7 +168,7 @@ enum { NvRegOffloadConfig = 0x90, #define NVREG_OFFLOAD_HOMEPHY 0x601 -#define NVREG_OFFLOAD_NORMAL 0x5ee +#define NVREG_OFFLOAD_NORMAL RX_NIC_BUFSIZE NvRegReceiverControl = 0x094, #define NVREG_RCVCTL_START 0x01 NvRegReceiverStatus = 0x98, @@ -168,6 +177,8 @@ enum { NvRegRandomSeed = 0x9c, #define NVREG_RNDSEED_MASK 0x00ff #define NVREG_RNDSEED_FORCE 0x7f00 +#define NVREG_RNDSEED_FORCE2 0x2d00 +#define NVREG_RNDSEED_FORCE3 0x7400 NvRegUnknownSetupReg1 = 0xA0, #define NVREG_UNKSETUP1_VAL 0x16070f @@ -181,6 +192,9 @@ enum { NvRegMulticastMaskA = 0xB8, NvRegMulticastMaskB = 0xBC, + NvRegPhyInterface = 0xC0, +#define PHY_RGMII 0x10000000 + NvRegTxRingPhysAddr = 0x100, NvRegRxRingPhysAddr = 0x104, NvRegRingSizes = 0x108, @@ -189,12 +203,12 @@ enum { NvRegUnknownTransmitterReg = 0x10c, NvRegLinkSpeed = 0x110, #define NVREG_LINKSPEED_FORCE 0x10000 -#define NVREG_LINKSPEED_10 10 +#define NVREG_LINKSPEED_10 1000 #define NVREG_LINKSPEED_100 100 -#define NVREG_LINKSPEED_1000 1000 +#define NVREG_LINKSPEED_1000 50 NvRegUnknownSetupReg5 = 0x130, #define NVREG_UNKSETUP5_BIT31 (1<<31) - NvRegUnknownSetupReg3 = 0x134, + NvRegUnknownSetupReg3 = 0x13c, #define NVREG_UNKSETUP3_VAL1 0x200010 NvRegTxRxControl = 0x144, #define NVREG_TXRXCTL_KICK 0x0001 @@ -213,15 +227,15 @@ enum { NvRegAdapterControl = 0x188, #define NVREG_ADAPTCTL_START 0x02 #define NVREG_ADAPTCTL_LINKUP 0x04 -#define NVREG_ADAPTCTL_PHYVALID 0x4000 +#define NVREG_ADAPTCTL_PHYVALID 0x40000 #define NVREG_ADAPTCTL_RUNNING 0x100000 #define NVREG_ADAPTCTL_PHYSHIFT 24 NvRegMIISpeed = 0x18c, #define NVREG_MIISPEED_BIT8 (1<<8) #define NVREG_MIIDELAY 5 NvRegMIIControl = 0x190, -#define NVREG_MIICTL_INUSE 0x10000 -#define NVREG_MIICTL_WRITE 0x08000 +#define NVREG_MIICTL_INUSE 0x08000 +#define NVREG_MIICTL_WRITE 0x00400 #define NVREG_MIICTL_ADDRSHIFT 5 NvRegMIIData = 0x194, NvRegWakeUpFlags = 0x200, @@ -253,34 +267,63 @@ enum { #define NVREG_POWERSTATE_D3 0x0003 }; +/* Big endian: should work, but is untested */ struct ring_desc { u32 PacketBuffer; - u16 Length; - u16 Flags; + u32 FlagLen; }; -#define NV_TX_LASTPACKET (1<<0) -#define NV_TX_RETRYERROR (1<<3) -#define NV_TX_LASTPACKET1 (1<<8) -#define NV_TX_DEFERRED (1<<10) -#define NV_TX_CARRIERLOST (1<<11) -#define NV_TX_LATECOLLISION (1<<12) -#define NV_TX_UNDERFLOW (1<<13) -#define NV_TX_ERROR (1<<14) -#define NV_TX_VALID (1<<15) - -#define NV_RX_DESCRIPTORVALID (1<<0) -#define NV_RX_MISSEDFRAME (1<<1) -#define NV_RX_SUBSTRACT1 (1<<3) -#define NV_RX_ERROR1 (1<<7) -#define NV_RX_ERROR2 (1<<8) -#define NV_RX_ERROR3 (1<<9) -#define NV_RX_ERROR4 (1<<10) -#define NV_RX_CRCERR (1<<11) -#define NV_RX_OVERFLOW (1<<12) -#define NV_RX_FRAMINGERR (1<<13) -#define NV_RX_ERROR (1<<14) -#define NV_RX_AVAIL (1<<15) +#define FLAG_MASK_V1 0xffff0000 +#define FLAG_MASK_V2 0xffffc000 +#define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) +#define LEN_MASK_V2 (0xffffffff ^ FLAG_MASK_V2) + +#define NV_TX_LASTPACKET (1<<16) +#define NV_TX_RETRYERROR (1<<19) +#define NV_TX_LASTPACKET1 (1<<24) +#define NV_TX_DEFERRED (1<<26) +#define NV_TX_CARRIERLOST (1<<27) +#define NV_TX_LATECOLLISION (1<<28) +#define NV_TX_UNDERFLOW (1<<29) +#define NV_TX_ERROR (1<<30) +#define NV_TX_VALID (1<<31) + +#define NV_TX2_LASTPACKET (1<<29) +#define NV_TX2_RETRYERROR (1<<18) +#define NV_TX2_LASTPACKET1 (1<<23) +#define NV_TX2_DEFERRED (1<<25) +#define NV_TX2_CARRIERLOST (1<<26) +#define NV_TX2_LATECOLLISION (1<<27) +#define NV_TX2_UNDERFLOW (1<<28) +/* error and valid are the same for both */ +#define NV_TX2_ERROR (1<<30) +#define NV_TX2_VALID (1<<31) + +#define NV_RX_DESCRIPTORVALID (1<<16) +#define NV_RX_MISSEDFRAME (1<<17) +#define NV_RX_SUBSTRACT1 (1<<18) +#define NV_RX_ERROR1 (1<<23) +#define NV_RX_ERROR2 (1<<24) +#define NV_RX_ERROR3 (1<<25) +#define NV_RX_ERROR4 (1<<26) +#define NV_RX_CRCERR (1<<27) +#define NV_RX_OVERFLOW (1<<28) +#define NV_RX_FRAMINGERR (1<<29) +#define NV_RX_ERROR (1<<30) +#define NV_RX_AVAIL (1<<31) + +#define NV_RX2_DESCRIPTORVALID (1<<29) +#define NV_RX2_SUBSTRACT1 (1<<25) +#define NV_RX2_ERROR1 (1<<18) +#define NV_RX2_ERROR2 (1<<19) +#define NV_RX2_ERROR3 (1<<20) +#define NV_RX2_ERROR4 (1<<21) +#define NV_RX2_CRCERR (1<<22) +#define NV_RX2_OVERFLOW (1<<23) +#define NV_RX2_FRAMINGERR (1<<24) +/* error and avail are the same for both */ +#define NV_RX2_ERROR (1<<30) +#define NV_RX2_AVAIL (1<<31) /* Miscelaneous hardware related defines: */ #define NV_PCI_REGSZ 0x270 @@ -306,28 +349,67 @@ struct ring_desc { /* General driver defaults */ #define NV_WATCHDOG_TIMEO (5*HZ) -#define DEFAULT_MTU 1500 /* also maximum supported, at least for now */ #define RX_RING 128 -#define TX_RING 16 -/* limited to 1 packet until we understand NV_TX_LASTPACKET */ -#define TX_LIMIT_STOP 10 -#define TX_LIMIT_START 5 +#define TX_RING 64 +/* + * 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 /* rx/tx mac addr + type + vlan + align + slack*/ -#define RX_NIC_BUFSIZE (DEFAULT_MTU + 64) +#define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) /* even more slack */ -#define RX_ALLOC_BUFSIZE (DEFAULT_MTU + 128) +#define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) #define OOM_REFILL (1+HZ/20) #define POLL_WAIT (1+HZ/100) +#define LINK_TIMEOUT (3*HZ) + +#define DESC_VER_1 0x0 +#define DESC_VER_2 0x02100 + +/* PHY defines */ +#define PHY_OUI_MARVELL 0x5043 +#define PHY_OUI_CICADA 0x03f1 +#define PHYID1_OUI_MASK 0x03ff +#define PHYID1_OUI_SHFT 6 +#define PHYID2_OUI_MASK 0xfc00 +#define PHYID2_OUI_SHFT 10 +#define PHY_INIT1 0x0f000 +#define PHY_INIT2 0x0e00 +#define PHY_INIT3 0x01000 +#define PHY_INIT4 0x0200 +#define PHY_INIT5 0x0004 +#define PHY_INIT6 0x02000 +#define PHY_GIGABIT 0x0100 + +#define PHY_TIMEOUT 0x1 +#define PHY_ERROR 0x2 + +#define PHY_100 0x1 +#define PHY_1000 0x2 +#define PHY_HALF 0x100 + +/* FIXME: MII defines that should be added to */ +#define MII_1000BT_CR 0x09 +#define MII_1000BT_SR 0x0a +#define ADVERTISE_1000FULL 0x0200 +#define ADVERTISE_1000HALF 0x0100 +#define LPA_1000FULL 0x0800 +#define LPA_1000HALF 0x0400 + /* * SMP locking: * All hardware access under dev->priv->lock, except the performance * critical parts: * - rx is (pseudo-) lockless: it relies on the single-threading provided - * by the arch code for interrupts. + * by the arch code for interrupts. * - tx setup is lockless: it relies on dev->xmit_lock. Actual submission * needs dev->priv->lock :-( * - set_multicast_list: preparation lockless, relies on dev->xmit_lock. @@ -345,12 +427,15 @@ struct fe_priv { int duplex; int phyaddr; int wolenabled; + unsigned int phy_oui; + u16 gigabit; /* General data: RO fields */ dma_addr_t ring_addr; struct pci_dev *pci_dev; u32 orig_mac[2]; u32 irqmask; + u32 desc_ver; /* rx specific fields. * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); @@ -363,6 +448,11 @@ struct fe_priv { struct timer_list oom_kick; struct timer_list nic_poll; + /* media detection workaround. + * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); + */ + int need_linktimer; + unsigned long link_timeout; /* * tx specific fields. */ @@ -370,7 +460,7 @@ struct fe_priv { unsigned int next_tx, nic_tx; struct sk_buff *tx_skbuff[TX_RING]; dma_addr_t tx_dma[TX_RING]; - u16 tx_flags; + u32 tx_flags; }; /* @@ -395,6 +485,12 @@ static inline void pci_push(u8 * base) readl(base); } +static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) +{ + return le32_to_cpu(prd->FlagLen) + & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); +} + static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, int delay, int delaymax, const char *msg) { @@ -421,24 +517,18 @@ static int reg_delay(struct net_device * static int mii_rw(struct net_device *dev, int addr, int miireg, int value) { u8 *base = get_hwbase(dev); - int was_running; u32 reg; int retval; writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); - was_running = 0; - reg = readl(base + NvRegAdapterControl); - if (reg & NVREG_ADAPTCTL_RUNNING) { - was_running = 1; - writel(reg & ~NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - } + reg = readl(base + NvRegMIIControl); if (reg & NVREG_MIICTL_INUSE) { writel(NVREG_MIICTL_INUSE, base + NvRegMIIControl); udelay(NV_MIIBUSY_DELAY); } - reg = NVREG_MIICTL_INUSE | (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; + reg = (addr << NVREG_MIICTL_ADDRSHIFT) | miireg; if (value != MII_READ) { writel(value, base + NvRegMIIData); reg |= NVREG_MIICTL_WRITE; @@ -460,19 +550,117 @@ static int mii_rw(struct net_device *dev dev->name, miireg, addr); retval = -1; } else { - /* FIXME: why is that required? */ - udelay(50); retval = readl(base + NvRegMIIData); dprintk(KERN_DEBUG "%s: mii_rw read from reg %d at PHY %d: 0x%x.\n", dev->name, miireg, addr, retval); } - if (was_running) { - reg = readl(base + NvRegAdapterControl); - writel(reg | NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - } + return retval; } +static int phy_reset(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + u32 miicontrol; + unsigned int tries = 0; + + miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + miicontrol |= BMCR_RESET; + if (mii_rw(dev, np->phyaddr, MII_BMCR, miicontrol)) { + return -1; + } + + /* wait for 500ms */ + msleep(500); + + /* must wait till reset is deasserted */ + while (miicontrol & BMCR_RESET) { + msleep(10); + miicontrol = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + /* FIXME: 100 tries seem excessive */ + if (tries++ > 100) + return -1; + } + return 0; +} + +static int phy_init(struct net_device *dev) +{ + struct fe_priv *np = get_nvpriv(dev); + u8 *base = get_hwbase(dev); + u32 phyinterface, phy_reserved, mii_status, mii_control, mii_control_1000,reg; + + /* set advertise register */ + reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); + reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|0x800|0x400); + if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { + printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + /* get phy interface type */ + phyinterface = readl(base + NvRegPhyInterface); + + /* see if gigabit phy */ + mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + if (mii_status & PHY_GIGABIT) { + np->gigabit = PHY_GIGABIT; + mii_control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); + mii_control_1000 &= ~ADVERTISE_1000HALF; + if (phyinterface & PHY_RGMII) + mii_control_1000 |= ADVERTISE_1000FULL; + else + mii_control_1000 &= ~ADVERTISE_1000FULL; + + if (mii_rw(dev, np->phyaddr, MII_1000BT_CR, mii_control_1000)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + else + np->gigabit = 0; + + /* reset the phy */ + if (phy_reset(dev)) { + printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + + /* phy vendor specific configuration */ + if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) { + phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ); + phy_reserved &= ~(PHY_INIT1 | PHY_INIT2); + phy_reserved |= (PHY_INIT3 | PHY_INIT4); + if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ); + phy_reserved |= PHY_INIT5; + if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + if (np->phy_oui == PHY_OUI_CICADA) { + phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ); + phy_reserved |= PHY_INIT6; + if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) { + printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); + return PHY_ERROR; + } + } + + /* restart auto negotiation */ + mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); + mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); + if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { + return PHY_ERROR; + } + + return 0; +} + static void nv_start_rx(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -487,6 +675,8 @@ static void nv_start_rx(struct net_devic writel(np->linkspeed, base + NvRegLinkSpeed); pci_push(base); writel(NVREG_RCVCTL_START, base + NvRegReceiverControl); + dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n", + dev->name, np->duplex, np->linkspeed); pci_push(base); } @@ -497,8 +687,8 @@ static void nv_stop_rx(struct net_device dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name); writel(0, base + NvRegReceiverControl); reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0, - NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); + NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX, + KERN_INFO "nv_stop_rx: ReceiverStatus remained busy"); udelay(NV_RXSTOP_DELAY2); writel(0, base + NvRegLinkSpeed); @@ -520,8 +710,8 @@ static void nv_stop_tx(struct net_device dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name); writel(0, base + NvRegTransmitterControl); reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0, - NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, - KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); + NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX, + KERN_INFO "nv_stop_tx: TransmitterStatus remained busy"); udelay(NV_TXSTOP_DELAY2); writel(0, base + NvRegUnknownTransmitterReg); @@ -529,13 +719,14 @@ static void nv_stop_tx(struct net_device static void nv_txrx_reset(struct net_device *dev) { + struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name); - writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl); pci_push(base); udelay(NV_TXRX_RESET_DELAY); - writel(NVREG_TXRXCTL_BIT2, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl); pci_push(base); } @@ -650,11 +841,12 @@ static int nv_alloc_rx(struct net_device { struct fe_priv *np = get_nvpriv(dev); unsigned int refill_rx = np->refill_rx; + int nr; while (np->cur_rx != refill_rx) { - int nr = refill_rx % RX_RING; struct sk_buff *skb; + nr = refill_rx % RX_RING; if (np->rx_skbuff[nr] == NULL) { skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); @@ -669,10 +861,9 @@ static int nv_alloc_rx(struct net_device np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); - np->rx_ring[nr].Length = cpu_to_le16(RX_NIC_BUFSIZE); wmb(); - np->rx_ring[nr].Flags = cpu_to_le16(NV_RX_AVAIL); - dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", + np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); + dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", dev->name, refill_rx); refill_rx++; } @@ -703,15 +894,13 @@ static int nv_init_ring(struct net_devic int i; np->next_tx = np->nic_tx = 0; - for (i = 0; i < TX_RING; i++) { - np->tx_ring[i].Flags = 0; - } + for (i = 0; i < TX_RING; i++) + np->tx_ring[i].FlagLen = 0; np->cur_rx = RX_RING; np->refill_rx = 0; - for (i = 0; i < RX_RING; i++) { - np->rx_ring[i].Flags = 0; - } + for (i = 0; i < RX_RING; i++) + np->rx_ring[i].FlagLen = 0; return nv_alloc_rx(dev); } @@ -720,7 +909,7 @@ static void nv_drain_tx(struct net_devic struct fe_priv *np = get_nvpriv(dev); int i; for (i = 0; i < TX_RING; i++) { - np->tx_ring[i].Flags = 0; + np->tx_ring[i].FlagLen = 0; if (np->tx_skbuff[i]) { pci_unmap_single(np->pci_dev, np->tx_dma[i], np->tx_skbuff[i]->len, @@ -737,7 +926,7 @@ static void nv_drain_rx(struct net_devic struct fe_priv *np = get_nvpriv(dev); int i; for (i = 0; i < RX_RING; i++) { - np->rx_ring[i].Flags = 0; + np->rx_ring[i].FlagLen = 0; wmb(); if (np->rx_skbuff[i]) { pci_unmap_single(np->pci_dev, np->rx_dma[i], @@ -769,11 +958,10 @@ static int nv_start_xmit(struct sk_buff PCI_DMA_TODEVICE); np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); - np->tx_ring[nr].Length = cpu_to_le16(skb->len-1); spin_lock_irq(&np->lock); wmb(); - np->tx_ring[nr].Flags = np->tx_flags; + np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", dev->name, np->next_tx); { @@ -792,7 +980,7 @@ static int nv_start_xmit(struct sk_buff if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP) netif_stop_queue(dev); spin_unlock_irq(&np->lock); - writel(NVREG_TXRXCTL_KICK, get_hwbase(dev) + NvRegTxRxControl); + writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl); pci_push(get_hwbase(dev)); return 0; } @@ -805,27 +993,42 @@ static int nv_start_xmit(struct sk_buff static void nv_tx_done(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); + u32 Flags; + int i; - while (np->nic_tx < np->next_tx) { - struct ring_desc *prd; - int i = np->nic_tx % TX_RING; + while (np->nic_tx != np->next_tx) { + i = np->nic_tx % TX_RING; - prd = &np->tx_ring[i]; + Flags = le32_to_cpu(np->tx_ring[i].FlagLen); dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", - dev->name, np->nic_tx, prd->Flags); - if (prd->Flags & cpu_to_le16(NV_TX_VALID)) + dev->name, np->nic_tx, Flags); + if (Flags & NV_TX_VALID) break; - if (prd->Flags & cpu_to_le16(NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| - NV_TX_UNDERFLOW|NV_TX_ERROR)) { - if (prd->Flags & cpu_to_le16(NV_TX_UNDERFLOW)) - np->stats.tx_fifo_errors++; - if (prd->Flags & cpu_to_le16(NV_TX_CARRIERLOST)) - np->stats.tx_carrier_errors++; - np->stats.tx_errors++; + if (np->desc_ver == DESC_VER_1) { + if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION| + NV_TX_UNDERFLOW|NV_TX_ERROR)) { + if (Flags & NV_TX_UNDERFLOW) + np->stats.tx_fifo_errors++; + if (Flags & NV_TX_CARRIERLOST) + np->stats.tx_carrier_errors++; + np->stats.tx_errors++; + } else { + np->stats.tx_packets++; + np->stats.tx_bytes += np->tx_skbuff[i]->len; + } } else { - np->stats.tx_packets++; - np->stats.tx_bytes += np->tx_skbuff[i]->len; + if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION| + NV_TX2_UNDERFLOW|NV_TX2_ERROR)) { + if (Flags & NV_TX2_UNDERFLOW) + np->stats.tx_fifo_errors++; + if (Flags & NV_TX2_CARRIERLOST) + np->stats.tx_carrier_errors++; + np->stats.tx_errors++; + } else { + np->stats.tx_packets++; + np->stats.tx_bytes += np->tx_skbuff[i]->len; + } } pci_unmap_single(np->pci_dev, np->tx_dma[i], np->tx_skbuff[i]->len, @@ -875,9 +1078,9 @@ static void nv_tx_timeout(struct net_dev static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); + u32 Flags; for (;;) { - struct ring_desc *prd; struct sk_buff *skb; int len; int i; @@ -885,11 +1088,13 @@ static void nv_rx_process(struct net_dev break; /* we scanned the whole ring - do not continue */ i = np->cur_rx % RX_RING; - prd = &np->rx_ring[i]; + Flags = le32_to_cpu(np->rx_ring[i].FlagLen); + len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver); + dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", - dev->name, np->cur_rx, prd->Flags); + dev->name, np->cur_rx, Flags); - if (prd->Flags & cpu_to_le16(NV_RX_AVAIL)) + if (Flags & NV_RX_AVAIL) break; /* still owned by hardware, */ /* @@ -903,7 +1108,7 @@ static void nv_rx_process(struct net_dev { int j; - dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",prd->Flags); + dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags); for (j=0; j<64; j++) { if ((j%16) == 0) dprintk("\n%03x:", j); @@ -912,41 +1117,69 @@ static void nv_rx_process(struct net_dev dprintk("\n"); } /* look at what we actually got: */ - if (!(prd->Flags & cpu_to_le16(NV_RX_DESCRIPTORVALID))) - goto next_pkt; - - - len = le16_to_cpu(prd->Length); + if (np->desc_ver == DESC_VER_1) { + if (!(Flags & NV_RX_DESCRIPTORVALID)) + goto next_pkt; - if (prd->Flags & cpu_to_le16(NV_RX_MISSEDFRAME)) { - np->stats.rx_missed_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_CRCERR)) { - np->stats.rx_crc_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_OVERFLOW)) { - np->stats.rx_over_errors++; - np->stats.rx_errors++; - goto next_pkt; - } - if (prd->Flags & cpu_to_le16(NV_RX_ERROR)) { - /* framing errors are soft errors, the rest is fatal. */ - if (prd->Flags & cpu_to_le16(NV_RX_FRAMINGERR)) { - if (prd->Flags & cpu_to_le16(NV_RX_SUBSTRACT1)) { - len--; + if (Flags & NV_RX_MISSEDFRAME) { + np->stats.rx_missed_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_OVERFLOW) { + np->stats.rx_over_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX_ERROR) { + /* framing errors are soft errors, the rest is fatal. */ + if (Flags & NV_RX_FRAMINGERR) { + if (Flags & NV_RX_SUBSTRACT1) { + len--; + } + } else { + np->stats.rx_errors++; + goto next_pkt; } - } else { + } + } else { + if (!(Flags & NV_RX2_DESCRIPTORVALID)) + goto next_pkt; + + if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) { + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX2_CRCERR) { + np->stats.rx_crc_errors++; + np->stats.rx_errors++; + goto next_pkt; + } + if (Flags & NV_RX2_OVERFLOW) { + np->stats.rx_over_errors++; np->stats.rx_errors++; goto next_pkt; } + if (Flags & NV_RX2_ERROR) { + /* framing errors are soft errors, the rest is fatal. */ + if (Flags & NV_RX2_FRAMINGERR) { + if (Flags & NV_RX2_SUBSTRACT1) { + len--; + } + } else { + np->stats.rx_errors++; + goto next_pkt; + } + } } /* got a valid packet - forward it to the network core */ skb = np->rx_skbuff[i]; @@ -971,7 +1204,7 @@ next_pkt: */ static int nv_change_mtu(struct net_device *dev, int new_mtu) { - if (new_mtu > DEFAULT_MTU) + if (new_mtu > ETH_DATA_LEN) return -EINVAL; dev->mtu = new_mtu; return 0; @@ -1035,6 +1268,8 @@ static void nv_set_multicast(struct net_ writel(mask[0], base + NvRegMulticastMaskA); writel(mask[1], base + NvRegMulticastMaskB); writel(pff, base + NvRegPacketFilterFlags); + dprintk(KERN_INFO "%s: reconfiguration for multicast lists.\n", + dev->name); nv_start_rx(dev); spin_unlock_irq(&np->lock); } @@ -1042,16 +1277,62 @@ static void nv_set_multicast(struct net_ static int nv_update_linkspeed(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); - int adv, lpa, newls, newdup; + u8 *base = get_hwbase(dev); + int adv, lpa; + int newls = np->linkspeed; + int newdup = np->duplex; + int mii_status; + int retval = 0; + u32 control_1000, status_1000, phyreg; + + /* BMSR_LSTATUS is latched, read it twice: + * we want the current value. + */ + mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); + + if (!(mii_status & BMSR_LSTATUS)) { + dprintk(KERN_DEBUG "%s: no link detected by phy - falling back to 10HD.\n", + dev->name); + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; + newdup = 0; + retval = 0; + goto set_speed; + } + + /* check auto negotiation is complete */ + if (!(mii_status & BMSR_ANEGCOMPLETE)) { + /* still in autonegotiation - configure nic for 10 MBit HD and wait. */ + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; + newdup = 0; + retval = 0; + dprintk(KERN_DEBUG "%s: autoneg not completed - falling back to 10HD.\n", dev->name); + goto set_speed; + } + + retval = 1; + if (np->gigabit == PHY_GIGABIT) { + control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); + status_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_SR, MII_READ); + + if ((control_1000 & ADVERTISE_1000FULL) && + (status_1000 & LPA_1000FULL)) { + dprintk(KERN_DEBUG "%s: nv_update_linkspeed: GBit ethernet detected.\n", + dev->name); + newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_1000; + newdup = 1; + goto set_speed; + } + } adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ); dprintk(KERN_DEBUG "%s: nv_update_linkspeed: PHY advertises 0x%04x, lpa 0x%04x.\n", dev->name, adv, lpa); - /* FIXME: handle parallel detection properly, handle gigabit ethernet */ + /* FIXME: handle parallel detection properly */ lpa = lpa & adv; - if (lpa & LPA_100FULL) { + if (lpa & LPA_100FULL) { newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; newdup = 1; } else if (lpa & LPA_100HALF) { @@ -1068,47 +1349,75 @@ static int nv_update_linkspeed(struct ne newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; newdup = 0; } - if (np->duplex != newdup || np->linkspeed != newls) { - np->duplex = newdup; - np->linkspeed = newls; - return 1; - } - return 0; + +set_speed: + if (np->duplex == newdup && np->linkspeed == newls) + return retval; + + dprintk(KERN_INFO "%s: changing link setting from %d/%d to %d/%d.\n", + dev->name, np->linkspeed, np->duplex, newls, newdup); + + np->duplex = newdup; + np->linkspeed = newls; + + if (np->gigabit == PHY_GIGABIT) { + phyreg = readl(base + NvRegRandomSeed); + phyreg &= ~(0x3FF00); + if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) + phyreg |= NVREG_RNDSEED_FORCE3; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + phyreg |= NVREG_RNDSEED_FORCE2; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + phyreg |= NVREG_RNDSEED_FORCE; + writel(phyreg, base + NvRegRandomSeed); + } + + phyreg = readl(base + NvRegPhyInterface); + phyreg &= ~(PHY_HALF|PHY_100|PHY_1000); + if (np->duplex == 0) + phyreg |= PHY_HALF; + if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100) + phyreg |= PHY_100; + else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000) + phyreg |= PHY_1000; + writel(phyreg, base + NvRegPhyInterface); + + writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), + base + NvRegMisc1); + pci_push(base); + writel(np->linkspeed, base + NvRegLinkSpeed); + pci_push(base); + + return retval; } static void nv_link_irq(struct net_device *dev) { - struct fe_priv *np = get_nvpriv(dev); u8 *base = get_hwbase(dev); u32 miistat; - int miival; miistat = readl(base + NvRegMIIStatus); writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); - printk(KERN_DEBUG "%s: link change notification, status 0x%x.\n", dev->name, miistat); +printk(KERN_INFO "%s: link change notification, status 0x%x.\n", dev->name, miistat); - miival = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); - if (miival & BMSR_ANEGCOMPLETE) { - nv_update_linkspeed(dev); - - if (netif_carrier_ok(dev)) { - nv_stop_rx(dev); + if (miistat & (NVREG_MIISTAT_LINKCHANGE)) { + if (nv_update_linkspeed(dev)) { + if (netif_carrier_ok(dev)) { + nv_stop_rx(dev); + } else { + netif_carrier_on(dev); + printk(KERN_INFO "%s: link up.\n", dev->name); + } + nv_start_rx(dev); } else { - netif_carrier_on(dev); - printk(KERN_INFO "%s: link up.\n", dev->name); - } - writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), - base + NvRegMisc1); - nv_start_rx(dev); - } else { - if (netif_carrier_ok(dev)) { - netif_carrier_off(dev); - printk(KERN_INFO "%s: link down.\n", dev->name); - nv_stop_rx(dev); + if (netif_carrier_ok(dev)) { + netif_carrier_off(dev); + printk(KERN_INFO "%s: link down.\n", dev->name); + nv_stop_rx(dev); + } } - writel(np->linkspeed, base + NvRegLinkSpeed); - pci_push(base); } + dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) @@ -1135,7 +1444,7 @@ static irqreturn_t nv_nic_irq(int foo, v spin_unlock(&np->lock); } - if (events & (NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { + if (events & (NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF)) { nv_rx_process(dev); if (nv_alloc_rx(dev)) { spin_lock(&np->lock); @@ -1150,6 +1459,12 @@ static irqreturn_t nv_nic_irq(int foo, v nv_link_irq(dev); spin_unlock(&np->lock); } + if (np->need_linktimer && time_after(jiffies, np->link_timeout)) { + spin_lock(&np->lock); + nv_link_irq(dev); + spin_unlock(&np->lock); + np->link_timeout = jiffies + LINK_TIMEOUT; + } if (events & (NVREG_IRQ_TX_ERR)) { dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", dev->name, events); @@ -1157,7 +1472,7 @@ static irqreturn_t nv_nic_irq(int foo, v if (events & (NVREG_IRQ_UNKNOWN)) { printk(KERN_DEBUG "%s: received irq with unknown events 0x%x. Please report\n", dev->name, events); - } + } if (i > max_interrupt_work) { spin_lock(&np->lock); /* disable interrupts on the nic */ @@ -1210,21 +1525,27 @@ static int nv_open(struct net_device *de writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(0, base + NvRegPacketFilterFlags); + + writel(0, base + NvRegTransmitterControl); + writel(0, base + NvRegReceiverControl); + writel(0, base + NvRegAdapterControl); + + /* 2) initialize descriptor rings */ + oom = nv_init_ring(dev); + writel(0, base + NvRegLinkSpeed); writel(0, base + NvRegUnknownTransmitterReg); nv_txrx_reset(dev); writel(0, base + NvRegUnknownSetupReg6); - /* 2) initialize descriptor rings */ np->in_shutdown = 0; - oom = nv_init_ring(dev); /* 3) set mac address */ { u32 mac[2]; - mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + + mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); @@ -1232,53 +1553,31 @@ static int nv_open(struct net_device *de writel(mac[1], base + NvRegMacAddrB); } - /* 4) continue setup */ + /* 4) give hw rings */ + writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); + writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); + writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), + base + NvRegRingSizes); + + /* 5) continue setup */ np->linkspeed = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; np->duplex = 0; + + writel(np->linkspeed, base + NvRegLinkSpeed); writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3); - writel(0, base + NvRegTxRxControl); + writel(np->desc_ver, base + NvRegTxRxControl); pci_push(base); - writel(NVREG_TXRXCTL_BIT1, base + NvRegTxRxControl); + writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl); reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31, NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX, KERN_INFO "open: SetupReg5, Bit 31 remained off\n"); - writel(0, base + NvRegUnknownSetupReg4); - - /* 5) Find a suitable PHY */ - writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); - for (i = 1; i < 32; i++) { - int id1, id2; - spin_lock_irq(&np->lock); - id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); - spin_unlock_irq(&np->lock); - if (id1 < 0 || id1 == 0xffff) - continue; - spin_lock_irq(&np->lock); - id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); - spin_unlock_irq(&np->lock); - if (id2 < 0 || id2 == 0xffff) - continue; - dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", - dev->name, id1, id2, i); - np->phyaddr = i; - - spin_lock_irq(&np->lock); - nv_update_linkspeed(dev); - spin_unlock_irq(&np->lock); - - break; - } - if (i == 32) { - printk(KERN_INFO "%s: open: failing due to lack of suitable PHY.\n", - dev->name); - ret = -EINVAL; - goto out_drain; - } + writel(0, base + NvRegUnknownSetupReg4); + writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); + writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); /* 6) continue setup */ - writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD), - base + NvRegMisc1); + writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); @@ -1290,17 +1589,12 @@ static int nv_open(struct net_device *de writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2); writel(NVREG_POLL_DEFAULT, base + NvRegPollingInterval); writel(NVREG_UNKSETUP6_VAL, base + NvRegUnknownSetupReg6); - writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID, + writel((np->phyaddr << NVREG_ADAPTCTL_PHYSHIFT)|NVREG_ADAPTCTL_PHYVALID|NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); + writel(NVREG_MIISPEED_BIT8|NVREG_MIIDELAY, base + NvRegMIISpeed); writel(NVREG_UNKSETUP4_VAL, base + NvRegUnknownSetupReg4); writel(NVREG_WAKEUPFLAGS_VAL, base + NvRegWakeUpFlags); - /* 7) start packet processing */ - writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); - writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); - writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), - base + NvRegRingSizes); - i = readl(base + NvRegPowerState); if ( (i & NVREG_POWERSTATE_POWEREDUP) == 0) writel(NVREG_POWERSTATE_POWEREDUP|i, base + NvRegPowerState); @@ -1308,13 +1602,9 @@ static int nv_open(struct net_device *de pci_push(base); udelay(10); writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState); - writel(NVREG_ADAPTCTL_RUNNING, base + NvRegAdapterControl); - writel(0, base + NvRegIrqMask); pci_push(base); - writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); - pci_push(base); writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); pci_push(base); @@ -1323,6 +1613,7 @@ static int nv_open(struct net_device *de if (ret) goto out_drain; + /* ask for interrupts */ writel(np->irqmask, base + NvRegIrqMask); spin_lock_irq(&np->lock); @@ -1331,18 +1622,27 @@ static int nv_open(struct net_device *de writel(0, base + NvRegMulticastMaskA); writel(0, base + NvRegMulticastMaskB); writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); + /* One manual link speed update: Interrupts are enabled, future link + * speed changes cause interrupts and are handled by nv_link_irq(). + */ + { + u32 miistat; + miistat = readl(base + NvRegMIIStatus); + writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); + dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); + } + ret = nv_update_linkspeed(dev); nv_start_rx(dev); nv_start_tx(dev); netif_start_queue(dev); - if (oom) - mod_timer(&np->oom_kick, jiffies + OOM_REFILL); - if (mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ) & BMSR_ANEGCOMPLETE) { + if (ret) { netif_carrier_on(dev); } else { printk("%s: no link during initialization.\n", dev->name); netif_carrier_off(dev); } - + if (oom) + mod_timer(&np->oom_kick, jiffies + OOM_REFILL); spin_unlock_irq(&np->lock); return 0; @@ -1424,7 +1724,7 @@ static int __devinit nv_probe(struct pci pci_set_master(pci_dev); - err = pci_request_regions(pci_dev, dev->name); + err = pci_request_regions(pci_dev, DRV_NAME); if (err < 0) goto out_disable; @@ -1447,6 +1747,14 @@ static int __devinit nv_probe(struct pci goto out_relreg; } + /* handle different descriptor versions */ + if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || + pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || + pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3) + np->desc_ver = DESC_VER_1; + else + np->desc_ver = DESC_VER_2; + err = -ENOMEM; dev->base_addr = (unsigned long) ioremap(addr, NV_PCI_REGSZ); if (!dev->base_addr) @@ -1506,15 +1814,63 @@ static int __devinit nv_probe(struct pci writel(0, base + NvRegWakeUpFlags); np->wolenabled = 0; - np->tx_flags = cpu_to_le16(NV_TX_LASTPACKET|NV_TX_LASTPACKET1|NV_TX_VALID); - if (id->driver_data & DEV_NEED_LASTPACKET1) - np->tx_flags |= cpu_to_le16(NV_TX_LASTPACKET1); + if (np->desc_ver == DESC_VER_1) { + np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; + if (id->driver_data & DEV_NEED_LASTPACKET1) + np->tx_flags |= NV_TX_LASTPACKET1; + } else { + np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; + if (id->driver_data & DEV_NEED_LASTPACKET1) + np->tx_flags |= NV_TX2_LASTPACKET1; + } if (id->driver_data & DEV_IRQMASK_1) np->irqmask = NVREG_IRQMASK_WANTED_1; if (id->driver_data & DEV_IRQMASK_2) np->irqmask = NVREG_IRQMASK_WANTED_2; if (id->driver_data & DEV_NEED_TIMERIRQ) np->irqmask |= NVREG_IRQ_TIMER; + if (id->driver_data & DEV_NEED_LINKTIMER) { + np->need_linktimer = 1; + np->link_timeout = jiffies + LINK_TIMEOUT; + } else { + np->need_linktimer = 0; + } + + /* find a suitable phy */ + for (i = 1; i < 32; i++) { + int id1, id2; + + spin_lock_irq(&np->lock); + id1 = mii_rw(dev, i, MII_PHYSID1, MII_READ); + spin_unlock_irq(&np->lock); + if (id1 < 0 || id1 == 0xffff) + continue; + spin_lock_irq(&np->lock); + id2 = mii_rw(dev, i, MII_PHYSID2, MII_READ); + spin_unlock_irq(&np->lock); + if (id2 < 0 || id2 == 0xffff) + continue; + + id1 = (id1 & PHYID1_OUI_MASK) << PHYID1_OUI_SHFT; + id2 = (id2 & PHYID2_OUI_MASK) >> PHYID2_OUI_SHFT; + dprintk(KERN_DEBUG "%s: open: Found PHY %04x:%04x at address %d.\n", + pci_name(pci_dev), id1, id2, i); + np->phyaddr = i; + np->phy_oui = id1 | id2; + break; + } + if (i == 32) { + /* PHY in isolate mode? No phy attached and user wants to + * test loopback? Very odd, but can be correct. + */ + printk(KERN_INFO "%s: open: Could not find a valid PHY.\n", + pci_name(pci_dev)); + } + + if (i != 32) { + /* reset it */ + phy_init(dev); + } err = register_netdev(dev); if (err) { @@ -1569,21 +1925,77 @@ static void __devexit nv_remove(struct p static struct pci_device_id pci_tbl[] = { { /* nForce Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x1C3, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_1, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, - .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ, + .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, }, { /* nForce2 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x0066, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_2, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_3, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_4, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, }, { /* nForce3 Ethernet Controller */ .vendor = PCI_VENDOR_ID_NVIDIA, - .device = 0x00D6, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_5, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_6, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* nForce3 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_7, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* CK804 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_8, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* CK804 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_9, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* MCP04 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_10, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, + }, + { /* MCP04 Ethernet Controller */ + .vendor = PCI_VENDOR_ID_NVIDIA, + .device = PCI_DEVICE_ID_NVIDIA_NVENET_11, .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ, @@ -1610,9 +2022,9 @@ static void __exit exit_nic(void) pci_unregister_driver(&driver); } -MODULE_PARM(max_interrupt_work, "i"); +module_param(max_interrupt_work, int, 0); MODULE_PARM_DESC(max_interrupt_work, "forcedeth maximum events handled per interrupt"); - + MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); MODULE_LICENSE("GPL"); --- 2.6/include/linux/pci_ids.h 2004-08-02 21:19:11.940474352 +0200 +++ build-2.6/include/linux/pci_ids.h 2004-08-02 21:17:46.234503640 +0200 @@ -1061,21 +1061,33 @@ #define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 +#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 +#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 +#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 +#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 +#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 +#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 +#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e #define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 #define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da #define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 +#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee #define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 @@ -1103,6 +1115,7 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4 #define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc +#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 #define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 --------------090405070803030805000201-- From vkondra@mail.ru Mon Aug 2 12:39:17 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 12:39:30 -0700 (PDT) Received: from mx2.mail.ru (mx2.mail.ru [194.67.23.122]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72JdGMx011061 for ; Mon, 2 Aug 2004 12:39:16 -0700 Received: from [82.80.15.190] (port=14176 helo=[192.168.10.2]) by mx2.mail.ru with esmtp id 1BrieL-000IEm-00 for netdev@oss.sgi.com; Mon, 02 Aug 2004 23:39:10 +0400 From: Vladimir Kondratiev To: netdev@oss.sgi.com Subject: TGe overview #3 Date: Mon, 2 Aug 2004 22:38:57 +0300 User-Agent: KMail/1.6.82 MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart6500354.cgk6mvoYQD"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Message-Id: <200408022239.04871.vkondra@mail.ru> X-Spam: Not detected X-archive-position: 7422 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: vkondra@mail.ru Precedence: bulk X-list: netdev --nextPart6500354.cgk6mvoYQD Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =46inally, let's review Traffic Streams. There are 2 different concepts: logical layer (admission) and completely ne= w=20 media access mechanism HCCA (Hybrid Coordinator Channel Access). Idea behind HCCA is similar to PCF (Point Coordinator Function) from old=20 802.11 standard. Hybrid Coordinator (HC), which have to be AP, decides who= =20 will talk when. Technically it is implemented as following: All time divided into contention based (EDCA TXOP's) and contention free CA= P=20 (Controlled AccessPhase). When HC want to start CAP, it simply starts it=20 after PIFS interval of idle media. PIFS is shorter then any interval betwee= n=20 EDCA frame exchange sequences, thus HC will preempt any EDCA flow at his=20 will. Then, HC can either transmit frames, or it may send Contention Free=20 Poll (CFP) frame to some STA. This frame gives to the STA "polled" TXOP, in= =20 contrast with EDCA TXOP. CFP frame provides TXOP duration. Now, admission control. For HCCA it is the only mechanism. But, admission=20 control may be activated also for 2 high priority EDCA categories. =46or EDCA it mean the following: one can't use these categories as it was= =20 described in EDCA, instead, TID should be obtained. For EDCA this mechanism= =20 used to control bandwidth allocation. But remember, EDCA is contention base= d=20 policy, without any guarantee. TID's 8-15 dedicates to TS (Traffic Streams). In order to obtain TID, STA=20 should send request to AP. Corresponded frame called ADDTS, it contain=20 traffic specification: requested bandwidth, delay, periodicity, frame size= =20 etc. AP may accept or decline this request. It may also come with counter=20 proposal with different parameters. TS may be up-stream, down-stream, or bi-direction If TS accepted by AP, AP provides schedule information. This information=20 consist of Service Interval (SI) - interval between successive Service=20 Periods (SP), during which AP serves this TS, and Start Time. Start time have the following meaning: STA may request exact timing in ADDT= S=20 request. In this case, it will be served at precise times StartTime+n*SI.=20 This used for power save: STA may identify itself as power down, but wake u= p=20 for its stream. Obvious usage is .11 phones. Here, important QoS related part is: AP admin decides upon admission control policy. For "legacy stations", that= =20 don't speak TS (stations implementing WME spec), it may provide only 2 low= =20 priority access categories. These STA will be severely impacted in=20 performance. STA have to know TGE in order to get real performance. And, STA need to kno= w=20 how to identify streams (RSVP like). One additional feature: DLP (Direct Link Protocol). Unrelated to anything=20 else. Idea is to let 2 stations to talk directly. Link establishment is=20 through AP, but later they send frames directly, reducing media time 2x. Th= is=20 is important for applications like streaming of high definition TV, for whi= ch=20 "usual" way when AP forward frames, is unacceptable. P.S. I did not covered many other stuff which is not related directly to Qo= S. --nextPart6500354.cgk6mvoYQD Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) iD8DBQBBDphYqxdj7mhC6o0RAmzAAKCFDMlYn7QuujVswZshlWPTZehMMQCgpXEw 7UWwHkUzYOgsx0c61i82UpU= =QGXS -----END PGP SIGNATURE----- --nextPart6500354.cgk6mvoYQD-- From akpm@osdl.org Mon Aug 2 14:23:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 14:23:57 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72LNo8Z016626 for ; Mon, 2 Aug 2004 14:23:50 -0700 Received: from akpm.pao.digeo.com (build.pdx.osdl.net [172.20.1.2]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72LNd131100; Mon, 2 Aug 2004 14:23:39 -0700 Date: Mon, 2 Aug 2004 14:27:06 -0700 From: Andrew Morton To: Matthias Andree Cc: netdev@oss.sgi.com Subject: Re: 2.6.8-rc2-mm1 breaks PPPoE for me (was: 2.6.8-rc2-mm1) Message-Id: <20040802142706.46100c6d.akpm@osdl.org> In-Reply-To: <20040731100947.GA7453@merlin.emma.line.org> References: <20040728020444.4dca7e23.akpm@osdl.org> <20040731100947.GA7453@merlin.emma.line.org> X-Mailer: Sylpheed version 0.9.7 (GTK+ 1.2.10; i586-pc-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7423 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: akpm@osdl.org Precedence: bulk X-list: netdev Matthias Andree wrote: > > On Wed, 28 Jul 2004, Andrew Morton wrote: > > > ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.8-rc2/2.6.8-rc2-mm1/ > ... > > gcc35-pppoe.c.patch > > gcc-3.5 fixes > > Andrew, > > I'm not sure if my problem is related to this patch, but in > 2.6.8-rc2-mm1, PPPoE doesn't work for me, kernel compiled with gcc (GCC) > 3.3.1 (SuSE Linux), a vanilla 2.6.7 is fine with the same compiler. > > pppd[5685]: Plugin /usr/lib/pppd/2.4.1/pppoe.so loaded. > pppd[5685]: PPPoE Plugin Initialized > pppd[5685]: pppd 2.4.1 started by root, uid 0 > pppd[5685]: Sending PADI > pppd[5685]: HOST_UNIQ successful match > pppd[5685]: Failed to negotiate PPPoE connection: 25 Inappropriate ioctl for device > pppd[5685]: Exit. > > A successful pppd session start, with 2.6.7, looks like this: > > pppd[5070]: PPPoE Plugin Initialized > pppd[5070]: pppd 2.4.1 started by root, uid 0 > pppd[5070]: Sending PADI > pppd[5070]: HOST_UNIQ successful match > pppd[5070]: HOST_UNIQ successful match > pppd[5070]: Got connection: 164b > pppd[5070]: Connecting PPPoE socket: 00:90:1a:XX:XX:XX 4b16 eth1 0x808a560 > /sbin/hotplug[5166]: INTERFACE=ppp0 > pppd[5070]: Using interface ppp0 > pppd[5070]: Connect: ppp0 <--> eth1 > pppd[5070]: Setting MTU to 1492. > pppd[5070]: Couldn't increase MRU to 1500 > pppd[5070]: Setting MTU to 1492. > pppd[5070]: local IP address 217.81.XXX.XXX > pppd[5070]: remote IP address 217.5.XXX.XXX > pppd[5070]: Script /etc/ppp/ip-up finished (pid 5180), status = 0x0 > I'm a bit stumped by this - I'm not aware of any change which would have caused the pppoe device to start returning -ENOTTY. Is this still happening? Are you sure the relevant modules are loaded? Could you capture an strace of pppd while it's happening? From afleming@freescale.com Mon Aug 2 15:19:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:19:52 -0700 (PDT) Received: from motgate3.mot.com (motgate3.mot.com [144.189.100.103]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72MJhZt018057 for ; Mon, 2 Aug 2004 15:19:46 -0700 Received: from az33exr04.mot.com (pobox4.mot.com [10.64.251.243]) by motgate3.mot.com (Motorola/Motgate3) with ESMTP id i72MJKiC008676; Mon, 2 Aug 2004 15:19:20 -0700 (MST) Received: from [10.82.17.240] ([10.82.17.240]) by az33exr04.mot.com (Motorola/az33exr04) with ESMTP id i72KJBoa015263; Mon, 2 Aug 2004 15:19:11 -0500 In-Reply-To: <20040707032913.GA1822@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: text/plain; charset=US-ASCII; format=flowed Message-Id: Content-Transfer-Encoding: 7bit Cc: Andy Fleming , Kumar Gala , "" , jamal , "" , Christoph Hellwig From: Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 17:19:13 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7424 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: afleming@freescale.com Precedence: bulk X-list: netdev Here's an updated patch which fixes module support which does this: * More cleanup/minor bug fixes * Added locking to PHY read/write wrappers * Fixed module support * Removed fastroute code As before, this patch replaces the previous ones I have submitted. Thanks, Andy Fleming From bunk@fs.tum.de Mon Aug 2 15:33:52 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:33:58 -0700 (PDT) Received: from hermes.fachschaften.tu-muenchen.de (hermes.fachschaften.tu-muenchen.de [129.187.202.12]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i72MXoCC018554 for ; Mon, 2 Aug 2004 15:33:51 -0700 Received: (qmail 22776 invoked from network); 2 Aug 2004 22:26:27 -0000 Received: from mimas.fachschaften.tu-muenchen.de (129.187.202.58) by hermes.fachschaften.tu-muenchen.de with QMQP; 2 Aug 2004 22:26:27 -0000 Date: Tue, 3 Aug 2004 00:33:32 +0200 From: Adrian Bunk To: Jeff Garzik Cc: linux-net@vger.kernel.org, Netdev , linux-kernel@vger.kernel.org Subject: [2.6 patch] fix net/hamradio/dmascc with gcc 3.4 Message-ID: <20040802223332.GP2746@fs.tum.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.6i X-archive-position: 7425 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: bunk@fs.tum.de Precedence: bulk X-list: netdev Trying to compile net/hamradio/dmascc.c in 2.6.8-rc2-mm2 with gcc 3.4 results in compile errors starting with the following: <-- snip --> ... CC drivers/net/hamradio/dmascc.o drivers/net/hamradio/dmascc.c: In function `scc_isr': drivers/net/hamradio/dmascc.c:250: sorry, unimplemented: inlining failed in call to 'z8530_isr': function body not available drivers/net/hamradio/dmascc.c:969: sorry, unimplemented: called from here drivers/net/hamradio/dmascc.c:250: sorry, unimplemented: inlining failed in call to 'z8530_isr': function body not available drivers/net/hamradio/dmascc.c:978: sorry, unimplemented: called from here make[3]: *** [drivers/net/hamradio/dmascc.o] Error 1 <-- snip --> The patch below moves all inline functions above their first caller. diffstat output: drivers/net/hamradio/dmascc.c | 290 ++++++++++++++++------------------ 1 files changed, 144 insertions(+), 146 deletions(-) Signed-off-by: Adrian Bunk --- linux-2.6.7-mm7-full-gcc3.4/drivers/net/hamradio/dmascc.c.old 2004-07-13 00:55:54.000000000 +0200 +++ linux-2.6.7-mm7-full-gcc3.4/drivers/net/hamradio/dmascc.c 2004-07-13 01:01:06.000000000 +0200 @@ -246,8 +246,14 @@ static struct net_device_stats *scc_get_stats(struct net_device *dev); static int scc_set_mac_address(struct net_device *dev, void *sa); -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs); +static inline void tx_on(struct scc_priv *priv); +static inline void rx_on(struct scc_priv *priv); +static inline void rx_off(struct scc_priv *priv); +static void start_timer(struct scc_priv *priv, int t, int r15); +static inline unsigned char random(void); + static inline void z8530_isr(struct scc_info *info); +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs); static void rx_isr(struct scc_priv *priv); static void special_condition(struct scc_priv *priv, int rc); static void rx_bh(void *arg); @@ -255,12 +261,6 @@ static void es_isr(struct scc_priv *priv); static void tm_isr(struct scc_priv *priv); -static inline void tx_on(struct scc_priv *priv); -static inline void rx_on(struct scc_priv *priv); -static inline void rx_off(struct scc_priv *priv); -static void start_timer(struct scc_priv *priv, int t, int r15); -static inline unsigned char random(void); - /* Initialization variables */ @@ -945,42 +945,115 @@ } -static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs) { - struct scc_info *info = dev_id; +static inline void tx_on(struct scc_priv *priv) { + int i, n; + unsigned long flags; - spin_lock(info->priv[0].register_lock); - /* At this point interrupts are enabled, and the interrupt under service - is already acknowledged, but masked off. + if (priv->param.dma >= 0) { + n = (priv->chip == Z85230) ? 3 : 1; + /* Program DMA controller */ + flags = claim_dma_lock(); + set_dma_mode(priv->param.dma, DMA_MODE_WRITE); + set_dma_addr(priv->param.dma, (int) priv->tx_buf[priv->tx_tail]+n); + set_dma_count(priv->param.dma, priv->tx_len[priv->tx_tail]-n); + release_dma_lock(flags); + /* Enable TX underrun interrupt */ + write_scc(priv, R15, TxUIE); + /* Configure DREQ */ + if (priv->type == TYPE_TWIN) + outb((priv->param.dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3, + priv->card_base + TWIN_DMA_CFG); + else + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB); + /* Write first byte(s) */ + spin_lock_irqsave(priv->register_lock, flags); + for (i = 0; i < n; i++) + write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1); + enable_dma(priv->param.dma); + spin_unlock_irqrestore(priv->register_lock, flags); + } else { + write_scc(priv, R15, TxUIE); + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB); + tx_isr(priv); + } + /* Reset EOM latch if we do not have the AUTOEOM feature */ + if (priv->chip == Z8530) write_scc(priv, R0, RES_EOM_L); +} - Interrupt processing: We loop until we know that the IRQ line is - low. If another positive edge occurs afterwards during the ISR, - another interrupt will be triggered by the interrupt controller - as soon as the IRQ level is enabled again (see asm/irq.h). - Bottom-half handlers will be processed after scc_isr(). This is - important, since we only have small ringbuffers and want new data - to be fetched/delivered immediately. */ +static inline void rx_on(struct scc_priv *priv) { + unsigned long flags; - if (info->priv[0].type == TYPE_TWIN) { - int is, card_base = info->priv[0].card_base; - while ((is = ~inb(card_base + TWIN_INT_REG)) & - TWIN_INT_MSK) { - if (is & TWIN_SCC_MSK) { - z8530_isr(info); - } else if (is & TWIN_TMR1_MSK) { - inb(card_base + TWIN_CLR_TMR1); - tm_isr(&info->priv[0]); - } else { - inb(card_base + TWIN_CLR_TMR2); - tm_isr(&info->priv[1]); - } + /* Clear RX FIFO */ + while (read_scc(priv, R0) & Rx_CH_AV) read_scc_data(priv); + priv->rx_over = 0; + if (priv->param.dma >= 0) { + /* Program DMA controller */ + flags = claim_dma_lock(); + set_dma_mode(priv->param.dma, DMA_MODE_READ); + set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]); + set_dma_count(priv->param.dma, BUF_SIZE); + release_dma_lock(flags); + enable_dma(priv->param.dma); + /* Configure PackeTwin DMA */ + if (priv->type == TYPE_TWIN) { + outb((priv->param.dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3, + priv->card_base + TWIN_DMA_CFG); } - } else z8530_isr(info); - spin_unlock(info->priv[0].register_lock); - return IRQ_HANDLED; + /* Sp. cond. intr. only, ext int enable, RX DMA enable */ + write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx | + WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB); + } else { + /* Reset current frame */ + priv->rx_ptr = 0; + /* Intr. on all Rx characters and Sp. cond., ext int enable */ + write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT | + WT_FN_RDYFN); + } + write_scc(priv, R0, ERR_RES); + write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB); +} + + +static inline void rx_off(struct scc_priv *priv) { + /* Disable receiver */ + write_scc(priv, R3, Rx8); + /* Disable DREQ / RX interrupt */ + if (priv->param.dma >= 0 && priv->type == TYPE_TWIN) + outb(0, priv->card_base + TWIN_DMA_CFG); + else + write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN); + /* Disable DMA */ + if (priv->param.dma >= 0) disable_dma(priv->param.dma); +} + + +static void start_timer(struct scc_priv *priv, int t, int r15) { + unsigned long flags; + + outb(priv->tmr_mode, priv->tmr_ctrl); + if (t == 0) { + tm_isr(priv); + } else if (t > 0) { + save_flags(flags); + cli(); + outb(t & 0xFF, priv->tmr_cnt); + outb((t >> 8) & 0xFF, priv->tmr_cnt); + if (priv->type != TYPE_TWIN) { + write_scc(priv, R15, r15 | CTSIE); + priv->rr0 |= CTS; + } + restore_flags(flags); + } } +static inline unsigned char random(void) { + /* See "Numerical Recipes in C", second edition, p. 284 */ + rand = rand * 1664525L + 1013904223L; + return (unsigned char) (rand >> 24); +} + static inline void z8530_isr(struct scc_info *info) { int is, i = 100; @@ -1009,6 +1082,42 @@ } +static irqreturn_t scc_isr(int irq, void *dev_id, struct pt_regs * regs) { + struct scc_info *info = dev_id; + + spin_lock(info->priv[0].register_lock); + /* At this point interrupts are enabled, and the interrupt under service + is already acknowledged, but masked off. + + Interrupt processing: We loop until we know that the IRQ line is + low. If another positive edge occurs afterwards during the ISR, + another interrupt will be triggered by the interrupt controller + as soon as the IRQ level is enabled again (see asm/irq.h). + + Bottom-half handlers will be processed after scc_isr(). This is + important, since we only have small ringbuffers and want new data + to be fetched/delivered immediately. */ + + if (info->priv[0].type == TYPE_TWIN) { + int is, card_base = info->priv[0].card_base; + while ((is = ~inb(card_base + TWIN_INT_REG)) & + TWIN_INT_MSK) { + if (is & TWIN_SCC_MSK) { + z8530_isr(info); + } else if (is & TWIN_TMR1_MSK) { + inb(card_base + TWIN_CLR_TMR1); + tm_isr(&info->priv[0]); + } else { + inb(card_base + TWIN_CLR_TMR2); + tm_isr(&info->priv[1]); + } + } + } else z8530_isr(info); + spin_unlock(info->priv[0].register_lock); + return IRQ_HANDLED; +} + + static void rx_isr(struct scc_priv *priv) { if (priv->param.dma >= 0) { /* Check special condition and perform error reset. See 2.4.7.5. */ @@ -1292,114 +1401,3 @@ break; } } - - -static inline void tx_on(struct scc_priv *priv) { - int i, n; - unsigned long flags; - - if (priv->param.dma >= 0) { - n = (priv->chip == Z85230) ? 3 : 1; - /* Program DMA controller */ - flags = claim_dma_lock(); - set_dma_mode(priv->param.dma, DMA_MODE_WRITE); - set_dma_addr(priv->param.dma, (int) priv->tx_buf[priv->tx_tail]+n); - set_dma_count(priv->param.dma, priv->tx_len[priv->tx_tail]-n); - release_dma_lock(flags); - /* Enable TX underrun interrupt */ - write_scc(priv, R15, TxUIE); - /* Configure DREQ */ - if (priv->type == TYPE_TWIN) - outb((priv->param.dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3, - priv->card_base + TWIN_DMA_CFG); - else - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | WT_RDY_ENAB); - /* Write first byte(s) */ - spin_lock_irqsave(priv->register_lock, flags); - for (i = 0; i < n; i++) - write_scc_data(priv, priv->tx_buf[priv->tx_tail][i], 1); - enable_dma(priv->param.dma); - spin_unlock_irqrestore(priv->register_lock, flags); - } else { - write_scc(priv, R15, TxUIE); - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN | TxINT_ENAB); - tx_isr(priv); - } - /* Reset EOM latch if we do not have the AUTOEOM feature */ - if (priv->chip == Z8530) write_scc(priv, R0, RES_EOM_L); -} - - -static inline void rx_on(struct scc_priv *priv) { - unsigned long flags; - - /* Clear RX FIFO */ - while (read_scc(priv, R0) & Rx_CH_AV) read_scc_data(priv); - priv->rx_over = 0; - if (priv->param.dma >= 0) { - /* Program DMA controller */ - flags = claim_dma_lock(); - set_dma_mode(priv->param.dma, DMA_MODE_READ); - set_dma_addr(priv->param.dma, (int) priv->rx_buf[priv->rx_head]); - set_dma_count(priv->param.dma, BUF_SIZE); - release_dma_lock(flags); - enable_dma(priv->param.dma); - /* Configure PackeTwin DMA */ - if (priv->type == TYPE_TWIN) { - outb((priv->param.dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3, - priv->card_base + TWIN_DMA_CFG); - } - /* Sp. cond. intr. only, ext int enable, RX DMA enable */ - write_scc(priv, R1, EXT_INT_ENAB | INT_ERR_Rx | - WT_RDY_RT | WT_FN_RDYFN | WT_RDY_ENAB); - } else { - /* Reset current frame */ - priv->rx_ptr = 0; - /* Intr. on all Rx characters and Sp. cond., ext int enable */ - write_scc(priv, R1, EXT_INT_ENAB | INT_ALL_Rx | WT_RDY_RT | - WT_FN_RDYFN); - } - write_scc(priv, R0, ERR_RES); - write_scc(priv, R3, RxENABLE | Rx8 | RxCRC_ENAB); -} - - -static inline void rx_off(struct scc_priv *priv) { - /* Disable receiver */ - write_scc(priv, R3, Rx8); - /* Disable DREQ / RX interrupt */ - if (priv->param.dma >= 0 && priv->type == TYPE_TWIN) - outb(0, priv->card_base + TWIN_DMA_CFG); - else - write_scc(priv, R1, EXT_INT_ENAB | WT_FN_RDYFN); - /* Disable DMA */ - if (priv->param.dma >= 0) disable_dma(priv->param.dma); -} - - -static void start_timer(struct scc_priv *priv, int t, int r15) { - unsigned long flags; - - outb(priv->tmr_mode, priv->tmr_ctrl); - if (t == 0) { - tm_isr(priv); - } else if (t > 0) { - save_flags(flags); - cli(); - outb(t & 0xFF, priv->tmr_cnt); - outb((t >> 8) & 0xFF, priv->tmr_cnt); - if (priv->type != TYPE_TWIN) { - write_scc(priv, R15, r15 | CTSIE); - priv->rr0 |= CTS; - } - restore_flags(flags); - } -} - - -static inline unsigned char random(void) { - /* See "Numerical Recipes in C", second edition, p. 284 */ - rand = rand * 1664525L + 1013904223L; - return (unsigned char) (rand >> 24); -} - From romieu@fr.zoreil.com Mon Aug 2 15:36:20 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:36:27 -0700 (PDT) Received: from fr.zoreil.com (electric-eye.fr.zoreil.com [213.41.134.224]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72MaCBJ018892 for ; Mon, 2 Aug 2004 15:36:19 -0700 Received: from electric-eye.fr.zoreil.com (localhost.localdomain [127.0.0.1]) by fr.zoreil.com (8.12.8/8.12.1) with ESMTP id i72MZah9031941; Tue, 3 Aug 2004 00:35:36 +0200 Received: (from romieu@localhost) by electric-eye.fr.zoreil.com (8.12.8/8.12.1) id i72MZF4G031940; Tue, 3 Aug 2004 00:35:15 +0200 Date: Tue, 3 Aug 2004 00:35:15 +0200 From: Francois Romieu To: Pasi Sjoholm Cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , akpm@osdl.org, netdev@oss.sgi.com, brad@brad-x.com, shemminger@osdl.org Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) Message-ID: <20040803003515.A29885@electric-eye.fr.zoreil.com> References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="bp/iNruPH9dso1Pn" Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from ptsjohol@cc.jyu.fi on Mon, Aug 02, 2004 at 01:03:15PM +0300 X-Organisation: Land of Sunshine Inc. X-archive-position: 7426 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: romieu@fr.zoreil.com Precedence: bulk X-list: netdev --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Pasi Sjoholm : > I forgot to mention that it was quite hard to crash the driver with that > /* Clear out errors and receive interrupts */-patch. Took about 15minutes > everytime, when normally it takes about 2mins. I have made a few changes. Please enable the DEBUG option and set msglvl to its maximal value via ethtool. You may test the patches separately if you find some time but the log once both r8139-10.patch and r8139-20.patch are applied would be enough. If the log fills too fast, you may comment out any message which does not belong to rtl8139_rx(). -- Ueimor --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="r8139-10.patch" - read the interruption status word that the driver will ack before the actual processing is done; - avoid a few heavy pci transactions when several packets are received at the same time. drivers/net/8139too.c | 17 ++++++++++------- 1 files changed, 10 insertions(+), 7 deletions(-) diff -puN drivers/net/8139too.c~r8139-10 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-10 2004-08-02 22:39:24.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-08-02 23:08:00.000000000 +0200 @@ -1934,12 +1934,15 @@ static int rtl8139_rx(struct net_device int received = 0; unsigned char *rx_ring = tp->rx_ring; unsigned int cur_rx = tp->cur_rx; + u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); + status = RTL_R16 (IntrStatus) & RxAckBits; + while (netif_running(dev) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) { u32 ring_offset = cur_rx % RX_BUF_LEN; @@ -1947,7 +1950,6 @@ static int rtl8139_rx(struct net_device unsigned int rx_size; unsigned int pkt_size; struct sk_buff *skb; - u16 status; rmb(); @@ -1977,7 +1979,7 @@ static int rtl8139_rx(struct net_device */ if (unlikely(rx_size == 0xfff0)) { tp->xstats.early_rx++; - goto done; + break; } /* If Rx err or invalid rx_size/rx_status received @@ -1989,7 +1991,8 @@ static int rtl8139_rx(struct net_device (rx_size < 8) || (!(rx_status & RxStatusOK)))) { rtl8139_rx_err (rx_status, dev, tp, ioaddr); - return -1; + received = -1; + goto out; } /* Malloc up new buffer, compatible with net-2e. */ @@ -2024,21 +2027,20 @@ static int rtl8139_rx(struct net_device cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; RTL_W16 (RxBufPtr, (u16) (cur_rx - 16)); + } + if (received > 0) { /* Clear out errors and receive interrupts */ - status = RTL_R16 (IntrStatus) & RxAckBits; if (likely(status != 0)) { if (unlikely(status & (RxFIFOOver | RxOverflow))) { tp->stats.rx_errors++; - if (status & RxFIFOOver) + if (status & RxFIFOOver) tp->stats.rx_fifo_errors++; } RTL_W16_F (IntrStatus, RxAckBits); } } - done: - #if RTL8139_DEBUG > 1 DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x," " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, @@ -2047,6 +2049,7 @@ static int rtl8139_rx(struct net_device #endif tp->cur_rx = cur_rx; +out: return received; } _ --bp/iNruPH9dso1Pn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="r8139-20.patch" Let's be sure that the driver will make some progress/reset when crap hits the packet size descriptor. drivers/net/8139too.c | 25 ++++++++++++++++++++++++- 1 files changed, 24 insertions(+), 1 deletion(-) diff -puN drivers/net/8139too.c~r8139-20 drivers/net/8139too.c --- linux-2.6.8-rc2/drivers/net/8139too.c~r8139-20 2004-08-02 23:21:36.000000000 +0200 +++ linux-2.6.8-rc2-romieu/drivers/net/8139too.c 2004-08-03 00:13:56.000000000 +0200 @@ -593,6 +593,7 @@ struct rtl8139_private { int time_to_die; struct mii_if_info mii; unsigned int regs_len; + unsigned long fifo_copy_timeout; }; MODULE_AUTHOR ("Jeff Garzik "); @@ -1937,7 +1938,7 @@ static int rtl8139_rx(struct net_device u16 status; DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x," - " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx, + " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx, RTL_R16 (RxBufAddr), RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd)); @@ -1978,10 +1979,24 @@ static int rtl8139_rx(struct net_device * since EarlyRx is disabled. */ if (unlikely(rx_size == 0xfff0)) { + if (!tp->fifo_copy_timeout) + tp->fifo_copy_timeout = jiffies + 2; + else if (time_after(jiffies, tp->fifo_copy_timeout)) { + DPRINTK ("%s: hung FIFO. Reset.", dev->name); + rx_size = 0; + goto no_early_rx; + } + if (netif_msg_intr(tp)) { + printk(KERN_DEBUG "%s: fifo copy in progress.", + dev->name); + } tp->xstats.early_rx++; break; } +no_early_rx: + tp->fifo_copy_timeout = 0; + /* If Rx err or invalid rx_size/rx_status received * (which happens if we get lost in the ring), * Rx process gets reset, so we abort any further @@ -2049,6 +2064,14 @@ static int rtl8139_rx(struct net_device #endif tp->cur_rx = cur_rx; + + /* + * The receive buffer should be mostly empty. + * Tell NAPI to reenable the Rx irq. + */ + if (tp->fifo_copy_timeout) + received = budget; + out: return received; } _ --bp/iNruPH9dso1Pn-- From shemminger@osdl.org Mon Aug 2 15:38:32 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 15:38:36 -0700 (PDT) Received: from mail.osdl.org (fw.osdl.org [65.172.181.6]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72McVwt019243 for ; Mon, 2 Aug 2004 15:38:31 -0700 Received: from dell_ss3.pdx.osdl.net (dell_ss3.pdx.osdl.net [172.20.1.60]) by mail.osdl.org (8.11.6/8.11.6) with SMTP id i72Mc5114309; Mon, 2 Aug 2004 15:38:05 -0700 Date: Mon, 2 Aug 2004 15:38:05 -0700 From: Stephen Hemminger To: Jamal Hadi Salim , "David S. Miller" Cc: netdev@oss.sgi.com Subject: iproute2 and kernel headers Message-Id: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> Organization: Open Source Development Lab X-Mailer: Sylpheed version 0.9.10claws (GTK+ 1.2.10; i386-redhat-linux-gnu) X-Face: &@E+xe?c%:&e4D{>f1O<&U>2qwRREG5!}7R4;D<"NO^UI2mJ[eEOA2*3>(`Th.yP,VDPo9$ /`~cw![cmj~~jWe?AHY7D1S+\}5brN0k*NE?pPh_'_d>6;XGG[\KDRViCfumZT3@[ Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7427 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: shemminger@osdl.org Precedence: bulk X-list: netdev I am willing to put some headers (not all) in with the user level code, provided they are copies since they I can easily update. I don't want to get into keeping an edited set of headers in sync. What headers really seem to change a lot? The obvious ones are: linux/pkt_sched.h linux/tcp_diag.h linux/xfrm.h From davem@redhat.com Mon Aug 2 16:06:16 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:06:21 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72N6FCJ019781 for ; Mon, 2 Aug 2004 16:06:16 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i72N69e1004105; Mon, 2 Aug 2004 19:06:09 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i72N68a13968; Mon, 2 Aug 2004 19:06:08 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i72N5PA1016870; Mon, 2 Aug 2004 19:05:25 -0400 Date: Mon, 2 Aug 2004 16:04:45 -0700 From: "David S. Miller" To: Stephen Hemminger Cc: hadi@znyx.com, netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-Id: <20040802160445.5ef3b251.davem@redhat.com> In-Reply-To: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7428 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 15:38:05 -0700 Stephen Hemminger wrote: > I am willing to put some headers (not all) in with the user level > code, provided they are copies since they I can easily update. I don't want > to get into keeping an edited set of headers in sync. > > What headers really seem to change a lot? The obvious ones are: > > linux/pkt_sched.h > linux/tcp_diag.h > linux/xfrm.h I would add linux/rtnetlink.h From garzik@havoc.gtf.org Mon Aug 2 16:11:23 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:11:28 -0700 (PDT) Received: from havoc.gtf.org (havoc.gtf.org [216.162.42.101]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72NBNSm020257 for ; Mon, 2 Aug 2004 16:11:23 -0700 Received: from havoc.gtf.org (havoc.gtf.org [127.0.0.1]) by havoc.gtf.org (Postfix) with ESMTP id BD2D575A5; Mon, 2 Aug 2004 19:11:12 -0400 (EDT) Received: (from garzik@localhost) by havoc.gtf.org (8.12.10/8.12.10/Submit) id i72NBC2T001012; Mon, 2 Aug 2004 19:11:12 -0400 Date: Mon, 2 Aug 2004 19:11:12 -0400 From: Jeff Garzik To: Andy Fleming Cc: Andy Fleming , Kumar Gala , "" , jamal , "" , Christoph Hellwig Subject: Re: [RFR] gianfar ethernet driver Message-ID: <20040802231112.GA890@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.1i X-archive-position: 7429 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jgarzik@pobox.com Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 05:19:13PM -0500, Andy Fleming wrote: > Here's an updated patch which fixes module support which does this: > > * More cleanup/minor bug fixes > * Added locking to PHY read/write wrappers > * Fixed module support > * Removed fastroute code > > As before, this patch replaces the previous ones I have submitted. the patch? :) Jeff From afleming@freescale.com Mon Aug 2 16:41:18 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 16:41:32 -0700 (PDT) Received: from motgate8.mot.com (motgate8.mot.com [129.188.136.8]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i72NfFkx024061 for ; Mon, 2 Aug 2004 16:41:17 -0700 Received: from il06exr03.mot.com (il06exr03.mot.com [129.188.137.133]) by motgate8.mot.com (Motorola/Motgate8) with ESMTP id i72NQoRC008533; Mon, 2 Aug 2004 16:26:50 -0700 (MST) Received: from [10.82.17.240] ([10.82.17.240]) by il06exr03.mot.com (Motorola/il06exr03) with ESMTP id i72NPrLl003257; Mon, 2 Aug 2004 18:25:53 -0500 In-Reply-To: <20040802231112.GA890@havoc.gtf.org> References: <89563A5C-CFAE-11D8-BA44-000393C30512@freescale.com> <1089170282.1038.80.camel@jzny.localdomain> <20040707032913.GA1822@havoc.gtf.org> <20040802231112.GA890@havoc.gtf.org> Mime-Version: 1.0 (Apple Message framework v618) Content-Type: multipart/mixed; boundary=Apple-Mail-1--634686679 Message-Id: <4819CC65-E4DB-11D8-999F-000393C30512@freescale.com> Cc: Andy Fleming , , Kumar Gala , jamal , Christoph Hellwig , From: Andy Fleming Subject: Re: [RFR] gianfar ethernet driver Date: Mon, 2 Aug 2004 18:25:46 -0500 To: Jeff Garzik X-Mailer: Apple Mail (2.618) X-archive-position: 7430 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: afleming@freescale.com Precedence: bulk X-list: netdev --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed D'oh! --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: application/octet-stream; x-unix-mode=0644; name="patch_2004_8_2" Content-Disposition: attachment; filename=patch_2004_8_2 diff -Nru a/drivers/net/Makefile b/drivers/net/Makefile --- a/drivers/net/Makefile Mon Aug 2 17:03:36 2004 +++ b/drivers/net/Makefile Mon Aug 2 17:03:36 2004 @@ -10,7 +10,9 @@ obj-$(CONFIG_IBM_EMAC) += ibm_emac/ obj-$(CONFIG_IXGB) += ixgb/ obj-$(CONFIG_BONDING) += bonding/ -obj-$(CONFIG_GIANFAR) += gianfar.o gianfar_ethtool.o gianfar_phy.o +obj-$(CONFIG_GIANFAR) += gianfar_driver.o + +gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o # # link order important here diff -Nru a/drivers/net/gianfar.c b/drivers/net/gianfar.c --- a/drivers/net/gianfar.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar.c Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -96,15 +96,6 @@ #include "gianfar.h" #include "gianfar_phy.h" -#ifdef CONFIG_NET_FASTROUTE -#include -#include -#endif - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,41) -#define irqreturn_t void -#define IRQ_HANDLED -#endif #define TX_TIMEOUT (1*HZ) #define SKB_ALLOC_TIMEOUT 1000000 @@ -117,9 +108,8 @@ #define RECEIVE(x) netif_rx(x) #endif -#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.0, " -char gfar_driver_name[] = "Gianfar Ethernet"; -char gfar_driver_version[] = "1.0"; +const char gfar_driver_name[] = "Gianfar Ethernet"; +const char gfar_driver_version[] = "1.1"; int startup_gfar(struct net_device *dev); static int gfar_enet_open(struct net_device *dev); @@ -148,24 +138,11 @@ #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct net_device *dev, int *budget); #endif -#ifdef CONFIG_NET_FASTROUTE -static int gfar_accept_fastpath(struct net_device *dev, struct dst_entry *dst); -#endif -static inline int try_fastroute(struct sk_buff *skb, struct net_device *dev, int length); -#ifdef CONFIG_GFAR_NAPI static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); -#else -static int gfar_clean_rx_ring(struct net_device *dev); -#endif static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); +static void gfar_phy_startup_timer(unsigned long data); extern struct ethtool_ops gfar_ethtool_ops; -extern void gfar_gstrings_normon(struct net_device *dev, u32 stringset, - u8 * buf); -extern void gfar_fill_stats_normon(struct net_device *dev, - struct ethtool_stats *dummy, u64 * buf); -extern int gfar_stats_count_normon(struct net_device *dev); - MODULE_AUTHOR("Freescale Semiconductor, Inc"); MODULE_DESCRIPTION("Gianfar Ethernet Driver"); @@ -183,7 +160,7 @@ struct ocp_gfar_data *einfo; int idx; int err = 0; - struct ethtool_ops *dev_ethtool_ops; + int dev_ethtool_ops = 0; einfo = (struct ocp_gfar_data *) ocpdev->def->additions; @@ -197,7 +174,8 @@ /* get a pointer to the register memory which can * configure the PHYs. If it's different from this set, * get the device which has those regs */ - if ((einfo->phyregidx >= 0) && (einfo->phyregidx != ocpdev->def->index)) { + if ((einfo->phyregidx >= 0) && + (einfo->phyregidx != ocpdev->def->index)) { mdiodev = ocp_find_device(OCP_ANY_ID, OCP_FUNC_GFAR, einfo->phyregidx); @@ -222,7 +200,7 @@ /* get a pointer to the register memory */ priv->regs = (struct gfar *) - ioremap(ocpdev->def->paddr, sizeof (struct gfar)); + ioremap(ocpdev->def->paddr, sizeof (struct gfar)); if (priv->regs == NULL) { err = -ENOMEM; @@ -238,6 +216,8 @@ goto phy_regs_fail; } + spin_lock_init(&priv->lock); + ocp_set_drvdata(ocpdev, dev); /* Stop the DMA engine now, in case it was running before */ @@ -269,15 +249,13 @@ gfar_write(&priv->regs->ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the dev structure, */ - /* and into the address registers MAC_STNADDR1,2. */ - /* Backwards, because little endian MACs are dumb. */ - /* Don't set the regs if the firmware already did */ memcpy(dev->dev_addr, einfo->mac_addr, MAC_ADDR_LEN); /* Set the dev->base_addr to the gfar reg region */ dev->base_addr = (unsigned long) (priv->regs); SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &ocpdev->dev); /* Fill in the dev structure */ dev->open = gfar_enet_open; @@ -293,37 +271,16 @@ dev->change_mtu = gfar_change_mtu; dev->mtu = 1500; dev->set_multicast_list = gfar_set_multi; - dev->flags |= IFF_MULTICAST; - dev_ethtool_ops = - (struct ethtool_ops *)kmalloc(sizeof(struct ethtool_ops), - GFP_KERNEL); + /* Index into the array of possible ethtool + * ops to catch all 4 possibilities */ + if((priv->einfo->flags & GFAR_HAS_RMON) == 0) + dev_ethtool_ops += 1; - if(dev_ethtool_ops == NULL) { - err = -ENOMEM; - goto ethtool_fail; - } + if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) + dev_ethtool_ops += 2; - memcpy(dev_ethtool_ops, &gfar_ethtool_ops, sizeof(gfar_ethtool_ops)); - - /* If there is no RMON support in this device, we don't - * want to expose non-existant statistics */ - if((priv->einfo->flags & GFAR_HAS_RMON) == 0) { - dev_ethtool_ops->get_strings = gfar_gstrings_normon; - dev_ethtool_ops->get_stats_count = gfar_stats_count_normon; - dev_ethtool_ops->get_ethtool_stats = gfar_fill_stats_normon; - } - - if((priv->einfo->flags & GFAR_HAS_COALESCE) == 0) { - dev_ethtool_ops->set_coalesce = NULL; - dev_ethtool_ops->get_coalesce = NULL; - } - - dev->ethtool_ops = dev_ethtool_ops; - -#ifdef CONFIG_NET_FASTROUTE - dev->accept_fastpath = gfar_accept_fastpath; -#endif + dev->ethtool_ops = gfar_op_array[dev_ethtool_ops]; priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE; #ifdef CONFIG_GFAR_BUFSTASH @@ -332,27 +289,26 @@ priv->tx_ring_size = DEFAULT_TX_RING_SIZE; priv->rx_ring_size = DEFAULT_RX_RING_SIZE; - /* Initially, coalescing is disabled */ - priv->txcoalescing = 0; - priv->txcount = 0; - priv->txtime = 0; - priv->rxcoalescing = 0; - priv->rxcount = 0; - priv->rxtime = 0; + priv->txcoalescing = DEFAULT_TX_COALESCE; + priv->txcount = DEFAULT_TXCOUNT; + priv->txtime = DEFAULT_TXTIME; + priv->rxcoalescing = DEFAULT_RX_COALESCE; + priv->rxcount = DEFAULT_RXCOUNT; + priv->rxtime = DEFAULT_RXTIME; err = register_netdev(dev); if (err) { printk(KERN_ERR "%s: Cannot register net device, aborting.\n", - dev->name); + dev->name); goto register_fail; } /* Print out the device info */ - printk(DEVICE_NAME, dev->name); + printk(KERN_INFO DEVICE_NAME, dev->name); for (idx = 0; idx < 6; idx++) - printk("%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); - printk("\n"); + printk(KERN_INFO "%2.2x%c", dev->dev_addr[idx], idx == 5 ? ' ' : ':'); + printk(KERN_INFO "\n"); /* Even more device info helps when determining which kernel */ /* provided which set of benchmarks. Since this is global for all */ @@ -367,10 +323,7 @@ return 0; - register_fail: - kfree(dev_ethtool_ops); -ethtool_fail: iounmap((void *) priv->phyregs); phy_regs_fail: iounmap((void *) priv->regs); @@ -386,7 +339,6 @@ ocp_set_drvdata(ocpdev, NULL); - kfree(dev->ethtool_ops); iounmap((void *) priv->regs); iounmap((void *) priv->phyregs); free_netdev(dev); @@ -399,26 +351,90 @@ { struct gfar_private *priv = netdev_priv(dev); struct phy_info *curphy; + unsigned int timeout = PHY_INIT_TIMEOUT; + struct gfar *phyregs = priv->phyregs; + struct gfar_mii_info *mii_info; + int err; - priv->link = 1; priv->oldlink = 0; priv->oldspeed = 0; - priv->olddplx = -1; + priv->oldduplex = -1; + + mii_info = kmalloc(sizeof(struct gfar_mii_info), + GFP_KERNEL); + + if(NULL == mii_info) { + printk(KERN_ERR "%s: Could not allocate mii_info\n", + dev->name); + return -ENOMEM; + } + + mii_info->speed = SPEED_1000; + mii_info->duplex = DUPLEX_FULL; + mii_info->pause = 0; + mii_info->link = 1; + + mii_info->advertising = (ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Full); + mii_info->autoneg = 1; + + mii_info->mii_id = priv->einfo->phyid; + + mii_info->dev = dev; + + mii_info->mdio_read = &read_phy_reg; + mii_info->mdio_write = &write_phy_reg; + + priv->mii_info = mii_info; + + /* Reset the management interface */ + gfar_write(&phyregs->miimcfg, MIIMCFG_RESET); + + /* Setup the MII Mgmt clock speed */ + gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE); + + /* Wait until the bus is free */ + while ((gfar_read(&phyregs->miimind) & MIIMIND_BUSY) && + timeout--) + cpu_relax(); + + if(timeout <= 0) { + printk(KERN_ERR "%s: The MII Bus is stuck!\n", + dev->name); + err = -1; + goto bus_fail; + } /* get info for this PHY */ - curphy = get_phy_info(dev); + curphy = get_phy_info(priv->mii_info); if (curphy == NULL) { printk(KERN_ERR "%s: No PHY found\n", dev->name); - return -1; + err = -1; + goto no_phy; } - priv->phyinfo = curphy; + mii_info->phyinfo = curphy; - /* Run the commands which configure the PHY */ - phy_run_commands(dev, curphy->config); + /* Run the commands which initialize the PHY */ + if(curphy->init) { + err = curphy->init(priv->mii_info); + + if (err) + goto phy_init_fail; + } return 0; + +phy_init_fail: +no_phy: +bus_fail: + kfree(mii_info); + + return err; } static void init_registers(struct net_device *dev) @@ -494,7 +510,7 @@ spin_lock_irqsave(&priv->lock, flags); /* Tell the kernel the link is down */ - priv->link = 0; + priv->mii_info->link = 0; adjust_link(dev); /* Mask all interrupts */ @@ -521,7 +537,12 @@ gfar_write(®s->maccfg1, tempval); if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - phy_run_commands(dev, priv->phyinfo->shutdown); + /* Clear any pending interrupts */ + mii_clear_phy_interrupt(priv->mii_info); + + /* Disable PHY Interrupts */ + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_DISABLED); } spin_unlock_irqrestore(&priv->lock, flags); @@ -543,15 +564,17 @@ free_skb_resources(priv); - dma_unmap_single(NULL, gfar_read(®s->tbase), - sizeof(struct txbd)*priv->tx_ring_size, - DMA_BIDIRECTIONAL); - dma_unmap_single(NULL, gfar_read(®s->rbase), - sizeof(struct rxbd)*priv->rx_ring_size, - DMA_BIDIRECTIONAL); + dma_free_coherent(NULL, + sizeof(struct txbd8)*priv->tx_ring_size + + sizeof(struct rxbd8)*priv->rx_ring_size, + priv->tx_bd_base, + gfar_read(®s->tbase)); /* Free the buffer descriptors */ - kfree(priv->tx_bd_base); + kfree(priv->mii_info); + + if (priv->mii_info->phyinfo->close) + priv->mii_info->phyinfo->close(priv->mii_info); } /* If there are any tx skbs or rx skbs still around, free them. @@ -610,7 +633,8 @@ { struct txbd8 *txbdp; struct rxbd8 *rxbdp; - unsigned long addr; + dma_addr_t addr; + unsigned long vaddr; int i; struct gfar_private *priv = netdev_priv(dev); struct gfar *regs = priv->regs; @@ -620,32 +644,27 @@ gfar_write(®s->imask, IMASK_INIT_CLEAR); /* Allocate memory for the buffer descriptors */ - addr = - (unsigned int) kmalloc(sizeof (struct txbd8) * priv->tx_ring_size + - sizeof (struct rxbd8) * priv->rx_ring_size, - GFP_KERNEL); + vaddr = (unsigned long) dma_alloc_coherent(NULL, + sizeof (struct txbd8) * priv->tx_ring_size + + sizeof (struct rxbd8) * priv->rx_ring_size, + &addr, GFP_KERNEL); - if (addr == 0) { + if (vaddr == 0) { printk(KERN_ERR "%s: Could not allocate buffer descriptors!\n", dev->name); return -ENOMEM; } - priv->tx_bd_base = (struct txbd8 *) addr; + priv->tx_bd_base = (struct txbd8 *) vaddr; /* enet DMA only understands physical addresses */ - gfar_write(®s->tbase, - dma_map_single(NULL, (void *)addr, - sizeof(struct txbd8) * priv->tx_ring_size, - DMA_BIDIRECTIONAL)); + gfar_write(®s->tbase, addr); /* Start the rx descriptor ring where the tx ring leaves off */ addr = addr + sizeof (struct txbd8) * priv->tx_ring_size; - priv->rx_bd_base = (struct rxbd8 *) addr; - gfar_write(®s->rbase, - dma_map_single(NULL, (void *)addr, - sizeof(struct rxbd8) * priv->rx_ring_size, - DMA_BIDIRECTIONAL)); + vaddr = vaddr + sizeof (struct txbd8) * priv->tx_ring_size; + priv->rx_bd_base = (struct rxbd8 *) vaddr; + gfar_write(®s->rbase, addr); /* Setup the skbuff rings */ priv->tx_skbuff = @@ -755,39 +774,13 @@ } } - /* Grab the PHY interrupt */ - if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { - if (request_irq(priv->einfo->interruptPHY, phy_interrupt, - SA_SHIRQ, "phy_interrupt", dev) < 0) { - printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n", - dev->name, priv->einfo->interruptPHY); - - err = -1; - - if (priv->einfo->flags & GFAR_HAS_MULTI_INTR) - goto phy_irq_fail; - else - goto tx_irq_fail; - } - } else { - init_timer(&priv->phy_info_timer); - priv->phy_info_timer.function = &gfar_phy_timer; - priv->phy_info_timer.data = (unsigned long) dev; - mod_timer(&priv->phy_info_timer, jiffies + 2 * HZ); - } - - /* Set up the bottom half queue */ - INIT_WORK(&priv->tq, (void (*)(void *))gfar_phy_change, dev); + /* Set up the PHY change work queue */ + INIT_WORK(&priv->tq, gfar_phy_change, dev); - /* Configure the PHY interrupt */ - phy_run_commands(dev, priv->phyinfo->startup); - - /* Tell the kernel the link is up, and determine the - * negotiated features (speed, duplex) */ - adjust_link(dev); - - if (priv->link == 0) - printk(KERN_INFO "%s: No link detected\n", dev->name); + init_timer(&priv->phy_info_timer); + priv->phy_info_timer.function = &gfar_phy_startup_timer; + priv->phy_info_timer.data = (unsigned long) priv->mii_info; + mod_timer(&priv->phy_info_timer, jiffies + HZ); /* Configure the coalescing support */ if (priv->txcoalescing) @@ -827,8 +820,6 @@ return 0; -phy_irq_fail: - free_irq(priv->einfo->interruptReceive, dev); rx_irq_fail: free_irq(priv->einfo->interruptTransmit, dev); tx_irq_fail: @@ -837,7 +828,16 @@ rx_skb_fail: free_skb_resources(priv); tx_skb_fail: - kfree(priv->tx_bd_base); + dma_free_coherent(NULL, + sizeof(struct txbd8)*priv->tx_ring_size + + sizeof(struct rxbd8)*priv->rx_ring_size, + priv->tx_bd_base, + gfar_read(®s->tbase)); + kfree(priv->mii_info); + + if (priv->mii_info->phyinfo->close) + priv->mii_info->phyinfo->close(priv->mii_info); + return err; } @@ -854,7 +854,7 @@ err = init_phy(dev); - if (err) + if(err) return err; err = startup_gfar(dev); @@ -971,121 +971,6 @@ return 0; } -/********************************************************************** - * gfar_accept_fastpath - * - * Used to authenticate to the kernel that a fast path entry can be - * added to device's routing table cache - * - * Input : pointer to ethernet interface network device structure and - * a pointer to the designated entry to be added to the cache. - * Output : zero upon success, negative upon failure - **********************************************************************/ -#ifdef CONFIG_NET_FASTROUTE -static int gfar_accept_fastpath(struct net_device *dev, struct dst_entry *dst) -{ - struct net_device *odev = dst->dev; - - if ((dst->ops->protocol != __constant_htons(ETH_P_IP)) - || (odev->type != ARPHRD_ETHER) - || (odev->accept_fastpath == NULL)) { - return -1; - } - - return 0; -} -#endif - -/* try_fastroute() -- Checks the fastroute cache to see if a given packet - * can be routed immediately to another device. If it can, we send it. - * If we used a fastroute, we return 1. Otherwise, we return 0. - * Returns 0 if CONFIG_NET_FASTROUTE is not on - */ -static inline int try_fastroute(struct sk_buff *skb, struct net_device *dev, int length) -{ -#ifdef CONFIG_NET_FASTROUTE - struct ethhdr *eth; - struct iphdr *iph; - unsigned int hash; - struct rtable *rt; - struct net_device *odev; - struct gfar_private *priv = netdev_priv(dev); - unsigned int CPU_ID = smp_processor_id(); - - eth = (struct ethhdr *) (skb->data); - - /* Only route ethernet IP packets */ - if (eth->h_proto == __constant_htons(ETH_P_IP)) { - iph = (struct iphdr *) (skb->data + ETH_HLEN); - - /* Generate the hash value */ - hash = ((*(u8 *) &iph->daddr) ^ (*(u8 *) & iph->saddr)) & NETDEV_FASTROUTE_HMASK; - - rt = (struct rtable *) (dev->fastpath[hash]); - if (rt != NULL - && ((*(u32 *) &iph->daddr) == (*(u32 *) &rt->key.dst)) - && ((*(u32 *) &iph->saddr) == (*(u32 *) &rt->key.src)) - && !(rt->u.dst.obsolete)) { - odev = rt->u.dst.dev; - netdev_rx_stat[CPU_ID].fastroute_hit++; - - /* Make sure the packet is: - * 1) IPv4 - * 2) without any options (header length of 5) - * 3) Not a multicast packet - * 4) going to a valid destination - * 5) Not out of time-to-live - */ - if (iph->version == 4 - && iph->ihl == 5 - && (!(eth->h_dest[0] & 0x01)) - && neigh_is_valid(rt->u.dst.neighbour) - && iph->ttl > 1) { - - /* Fast Route Path: Taken if the outgoing device is ready to transmit the packet now */ - if ((!netif_queue_stopped(odev)) - && (!spin_is_locked(odev->xmit_lock)) - && (skb->len <= (odev->mtu + ETH_HLEN + 2 + 4))) { - - skb->pkt_type = PACKET_FASTROUTE; - skb->protocol = __constant_htons(ETH_P_IP); - ip_decrease_ttl(iph); - memcpy(eth->h_source, odev->dev_addr, MAC_ADDR_LEN); - memcpy(eth->h_dest, rt->u.dst.neighbour->ha, MAC_ADDR_LEN); - skb->dev = odev; - - /* Prep the skb for the packet */ - skb_put(skb, length); - - if (odev->hard_start_xmit(skb, odev) != 0) { - panic("%s: FastRoute path corrupted", dev->name); - } - netdev_rx_stat[CPU_ID].fastroute_success++; - } - - /* Semi Fast Route Path: Mark the packet as needing fast routing, but let the - * stack handle getting it to the device */ - else { - skb->pkt_type = PACKET_FASTROUTE; - skb->nh.raw = skb->data + ETH_HLEN; - skb->protocol = __constant_htons(ETH_P_IP); - netdev_rx_stat[CPU_ID].fastroute_defer++; - - /* Prep the skb for the packet */ - skb_put(skb, length); - - if(RECEIVE(skb) == NET_RX_DROP) { - priv->extra_stats.kernel_dropped++; - } - } - - return 1; - } - } - } -#endif /* CONFIG_NET_FASTROUTE */ - return 0; -} static int gfar_change_mtu(struct net_device *dev, int new_mtu) { @@ -1148,8 +1033,7 @@ startup_gfar(dev); } - if (!netif_queue_stopped(dev)) - netif_schedule(dev); + netif_schedule(dev); } /* Interrupt Handler for Transmit complete */ @@ -1315,7 +1199,7 @@ #else spin_lock(&priv->lock); - gfar_clean_rx_ring(dev); + gfar_clean_rx_ring(dev, priv->rx_ring_size); /* If we are coalescing interrupts, update the timer */ /* Otherwise, clear it */ @@ -1336,7 +1220,7 @@ /* gfar_process_frame() -- handle one incoming packet if skb - * isn't NULL. Try the fastroute before using the stack */ + * isn't NULL. */ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length) { @@ -1350,17 +1234,15 @@ priv->stats.rx_dropped++; priv->extra_stats.rx_skbmissing++; } else { - if(try_fastroute(skb, dev, length) == 0) { - /* Prep the skb for the packet */ - skb_put(skb, length); - - /* Tell the skb what kind of packet this is */ - skb->protocol = eth_type_trans(skb, dev); - - /* Send the packet up the stack */ - if (RECEIVE(skb) == NET_RX_DROP) { - priv->extra_stats.kernel_dropped++; - } + /* Prep the skb for the packet */ + skb_put(skb, length); + + /* Tell the skb what kind of packet this is */ + skb->protocol = eth_type_trans(skb, dev); + + /* Send the packet up the stack */ + if (RECEIVE(skb) == NET_RX_DROP) { + priv->extra_stats.kernel_dropped++; } } @@ -1368,14 +1250,10 @@ } /* gfar_clean_rx_ring() -- Processes each frame in the rx ring - * until all are gone (or, in the case of NAPI, the budget/quota - * has been reached). Returns the number of frames handled + * until the budget/quota has been reached. Returns the number + * of frames handled */ -#ifdef CONFIG_GFAR_NAPI static int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) -#else -static int gfar_clean_rx_ring(struct net_device *dev) -#endif { struct rxbd8 *bdp; struct sk_buff *skb; @@ -1386,12 +1264,7 @@ /* Get the first full descriptor */ bdp = priv->cur_rx; -#ifdef CONFIG_GFAR_NAPI -#define GFAR_RXDONE() ((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0)) -#else -#define GFAR_RXDONE() (bdp->status & RXBD_EMPTY) -#endif - while (!GFAR_RXDONE()) { + while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) { skb = priv->rx_skbuff[priv->skb_currx]; if (!(bdp->status & @@ -1407,7 +1280,6 @@ gfar_process_frame(dev, skb, pkt_len); priv->stats.rx_bytes += pkt_len; - } else { count_errors(bdp->status, priv); @@ -1462,7 +1334,6 @@ if (rx_work_limit > dev->quota) rx_work_limit = dev->quota; - spin_lock(&priv->lock); howmany = gfar_clean_rx_ring(dev, rx_work_limit); dev->quota -= howmany; @@ -1489,8 +1360,6 @@ priv->rxclean = 1; } - spin_unlock(priv->lock); - return (rx_work_limit < 0) ? 1 : 0; } #endif @@ -1586,10 +1455,14 @@ struct net_device *dev = (struct net_device *) dev_id; struct gfar_private *priv = netdev_priv(dev); - /* Run the commands which acknowledge the interrupt */ - phy_run_commands(dev, priv->phyinfo->ack_int); + /* Clear the interrupt */ + mii_clear_phy_interrupt(priv->mii_info); + + /* Disable PHY interrupts */ + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_DISABLED); - /* Schedule the bottom half */ + /* Schedule the phy change */ schedule_work(&priv->tq); return IRQ_HANDLED; @@ -1600,18 +1473,24 @@ { struct net_device *dev = (struct net_device *) data; struct gfar_private *priv = netdev_priv(dev); - int timeout = HZ / 1000 + 1; + int result = 0; /* Delay to give the PHY a chance to change the * register state */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); + msleep(1); - /* Run the commands which check the link state */ - phy_run_commands(dev, priv->phyinfo->handle_int); + /* Update the link, speed, duplex */ + result = priv->mii_info->phyinfo->read_status(priv->mii_info); - /* React to the change in state */ - adjust_link(dev); + /* Adjust the known status as long as the link + * isn't still coming up */ + if((0 == result) || (priv->mii_info->link == 0)) + adjust_link(dev); + + /* Reenable interrupts, if needed */ + if (priv->einfo->flags & GFAR_HAS_PHY_INTR) + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_ENABLED); } /* Called every so often on systems that don't interrupt @@ -1623,7 +1502,72 @@ schedule_work(&priv->tq); - mod_timer(&priv->phy_info_timer, jiffies + 2 * HZ); + mod_timer(&priv->phy_info_timer, jiffies + + GFAR_PHY_CHANGE_TIME * HZ); +} + +/* Keep trying aneg for some time + * If, after GFAR_AN_TIMEOUT seconds, it has not + * finished, we switch to forced. + * Either way, once the process has completed, we either + * request the interrupt, or switch the timer over to + * using gfar_phy_timer to check status */ +static void gfar_phy_startup_timer(unsigned long data) +{ + int result; + static int secondary = GFAR_AN_TIMEOUT; + struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data; + struct gfar_private *priv = netdev_priv(mii_info->dev); + + /* Configure the Auto-negotiation */ + result = mii_info->phyinfo->config_aneg(mii_info); + + /* If autonegotiation failed to start, and + * we haven't timed out, reset the timer, and return */ + if (result && secondary--) { + mod_timer(&priv->phy_info_timer, jiffies + HZ); + return; + } else if (result) { + /* Couldn't start autonegotiation. + * Try switching to forced */ + mii_info->autoneg = 0; + result = mii_info->phyinfo->config_aneg(mii_info); + + /* Forcing failed! Give up */ + if(result) { + printk(KERN_ERR "%s: Forcing failed!\n", + mii_info->dev->name); + return; + } + } + + /* Kill the timer so it can be restarted */ + del_timer_sync(&priv->phy_info_timer); + + /* Grab the PHY interrupt, if necessary/possible */ + if (priv->einfo->flags & GFAR_HAS_PHY_INTR) { + if (request_irq(priv->einfo->interruptPHY, + phy_interrupt, + SA_SHIRQ, + "phy_interrupt", + mii_info->dev) < 0) { + printk(KERN_ERR "%s: Can't get IRQ %d (PHY)\n", + mii_info->dev->name, + priv->einfo->interruptPHY); + } else { + mii_configure_phy_interrupt(priv->mii_info, + MII_INTERRUPT_ENABLED); + return; + } + } + + /* Start the timer again, this time in order to + * handle a change in status */ + init_timer(&priv->phy_info_timer); + priv->phy_info_timer.function = &gfar_phy_timer; + priv->phy_info_timer.data = (unsigned long) mii_info->dev; + mod_timer(&priv->phy_info_timer, jiffies + + GFAR_PHY_CHANGE_TIME * HZ); } /* Called every time the controller might need to be made @@ -1637,12 +1581,13 @@ struct gfar_private *priv = netdev_priv(dev); struct gfar *regs = priv->regs; u32 tempval; + struct gfar_mii_info *mii_info = priv->mii_info; - if (priv->link) { + if (mii_info->link) { /* Now we make sure that we can be in full duplex mode. * If not, we operate in half-duplex mode. */ - if (priv->duplexity != priv->olddplx) { - if (!(priv->duplexity)) { + if (mii_info->duplex != priv->oldduplex) { + if (!(mii_info->duplex)) { tempval = gfar_read(®s->maccfg2); tempval &= ~(MACCFG2_FULL_DUPLEX); gfar_write(®s->maccfg2, tempval); @@ -1658,11 +1603,11 @@ dev->name); } - priv->olddplx = priv->duplexity; + priv->oldduplex = mii_info->duplex; } - if (priv->speed != priv->oldspeed) { - switch (priv->speed) { + if (mii_info->speed != priv->oldspeed) { + switch (mii_info->speed) { case 1000: tempval = gfar_read(®s->maccfg2); tempval = @@ -1679,14 +1624,14 @@ default: printk(KERN_WARNING "%s: Ack! Speed (%d) is not 10/100/1000!\n", - dev->name, priv->speed); + dev->name, mii_info->speed); break; } printk(KERN_INFO "%s: Speed %dBT\n", dev->name, - priv->speed); + mii_info->speed); - priv->oldspeed = priv->speed; + priv->oldspeed = mii_info->speed; } if (!priv->oldlink) { @@ -1700,7 +1645,7 @@ printk(KERN_INFO "%s: Link is down\n", dev->name); priv->oldlink = 0; priv->oldspeed = 0; - priv->olddplx = -1; + priv->oldduplex = -1; netif_carrier_off(dev); } } @@ -1900,11 +1845,7 @@ int rc; rc = ocp_register_driver(&gfar_driver); -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) if (rc != 0) { -#else - if (rc == 0) { -#endif ocp_unregister_driver(&gfar_driver); return -ENODEV; } diff -Nru a/drivers/net/gianfar.h b/drivers/net/gianfar.h --- a/drivers/net/gianfar.h Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar.h Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -42,15 +42,7 @@ #include #include #include - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41) #include -#else -#include -#define work_struct tq_struct -#define schedule_work schedule_task -#endif - #include #include #include @@ -70,8 +62,13 @@ #define MAC_ADDR_LEN 6 -extern char gfar_driver_name[]; -extern char gfar_driver_version[]; +#define PHY_INIT_TIMEOUT 100000 +#define GFAR_PHY_CHANGE_TIME 2 + +#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, " +#define DRV_NAME "gfar-enet" +extern const char gfar_driver_name[]; +extern const char gfar_driver_version[]; /* These need to be powers of 2 for this driver */ #ifdef CONFIG_GFAR_NAPI @@ -105,11 +102,13 @@ #define GFAR_100_TIME 2560 #define GFAR_10_TIME 25600 +#define DEFAULT_TX_COALESCE 1 #define DEFAULT_TXCOUNT 16 -#define DEFAULT_TXTIME 32768 +#define DEFAULT_TXTIME 400 +#define DEFAULT_RX_COALESCE 1 #define DEFAULT_RXCOUNT 16 -#define DEFAULT_RXTIME 32768 +#define DEFAULT_RXTIME 400 #define TBIPA_VALUE 0x1f #define MIIMCFG_INIT_VALUE 0x00000007 @@ -467,8 +466,7 @@ * empty and completely full conditions. The empty/ready indicator in * the buffer descriptor determines the actual condition. */ -struct gfar_private -{ +struct gfar_private { /* pointers to arrays of skbuffs for tx and rx */ struct sk_buff ** tx_skbuff; struct sk_buff ** rx_skbuff; @@ -496,7 +494,6 @@ struct txbd8 *cur_tx; /* Next free ring entry */ struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */ - struct phy_info *phyinfo; struct gfar *phyregs; struct work_struct tq; struct timer_list phy_info_timer; @@ -509,15 +506,14 @@ unsigned int rx_ring_size; wait_queue_head_t rxcleanupq; unsigned int rxclean; - int link; /* current link state */ - int oldlink; - int duplexity; /* Indicates negotiated duplex state */ - int olddplx; - int speed; /* Indicates negotiated speed */ - int oldspeed; - + /* Info structure initialized by board setup code */ struct ocp_gfar_data *einfo; + + struct gfar_mii_info *mii_info; + int oldspeed; + int oldduplex; + int oldlink; }; extern inline u32 gfar_read(volatile unsigned *addr) @@ -532,6 +528,6 @@ out_be32(addr, val); } - +extern struct ethtool_ops *gfar_op_array[]; #endif /* __GIANFAR_H */ diff -Nru a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c --- a/drivers/net/gianfar_ethtool.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_ethtool.c Mon Aug 2 17:03:36 2004 @@ -1,18 +1,18 @@ /* - * drivers/net/gianfar_ethtool.c + * drivers/net/gianfar_ethtool.c * - * Gianfar Ethernet Driver - * Ethtool support for Gianfar Enet - * Based on e1000 ethtool support + * Gianfar Ethernet Driver + * Ethtool support for Gianfar Enet + * Based on e1000 ethtool support * - * Author: Andy Fleming - * Maintainer: Kumar Gala (kumar.gala@freescale.com) + * Author: Andy Fleming + * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2003,2004 Freescale Semiconductor, Inc. * - * This software may be used and distributed according to - * the terms of the GNU Public License, Version 2, incorporated herein - * by reference. + * This software may be used and distributed according to + * the terms of the GNU Public License, Version 2, incorporated herein + * by reference. */ #include @@ -58,64 +58,64 @@ void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo); static char stat_gstrings[][ETH_GSTRING_LEN] = { - "RX Dropped by Kernel", - "RX Large Frame Errors", - "RX Short Frame Errors", - "RX Non-Octet Errors", - "RX CRC Errors", - "RX Overrun Errors", - "RX Busy Errors", - "RX Babbling Errors", - "RX Truncated Frames", - "Ethernet Bus Error", - "TX Babbling Errors", - "TX Underrun Errors", - "RX SKB Missing Errors", - "TX Timeout Errors", - "tx&rx 64B frames", - "tx&rx 65-127B frames", - "tx&rx 128-255B frames", - "tx&rx 256-511B frames", - "tx&rx 512-1023B frames", - "tx&rx 1024-1518B frames", - "tx&rx 1519-1522B Good VLAN", - "RX bytes", - "RX Packets", - "RX FCS Errors", - "Receive Multicast Packet", - "Receive Broadcast Packet", - "RX Control Frame Packets", - "RX Pause Frame Packets", - "RX Unknown OP Code", - "RX Alignment Error", - "RX Frame Length Error", - "RX Code Error", - "RX Carrier Sense Error", - "RX Undersize Packets", - "RX Oversize Packets", - "RX Fragmented Frames", - "RX Jabber Frames", - "RX Dropped Frames", - "TX Byte Counter", - "TX Packets", - "TX Multicast Packets", - "TX Broadcast Packets", - "TX Pause Control Frames", - "TX Deferral Packets", - "TX Excessive Deferral Packets", - "TX Single Collision Packets", - "TX Multiple Collision Packets", - "TX Late Collision Packets", - "TX Excessive Collision Packets", - "TX Total Collision", - "RESERVED", - "TX Dropped Frames", - "TX Jabber Frames", - "TX FCS Errors", - "TX Control Frames", - "TX Oversize Frames", - "TX Undersize Frames", - "TX Fragmented Frames", + "rx-dropped-by-kernel", + "rx-large-frame-errors", + "rx-short-frame-errors", + "rx-non-octet-errors", + "rx-crc-errors", + "rx-overrun-errors", + "rx-busy-errors", + "rx-babbling-errors", + "rx-truncated-frames", + "ethernet-bus-error", + "tx-babbling-errors", + "tx-underrun-errors", + "rx-skb-missing-errors", + "tx-timeout-errors", + "tx-rx-64-frames", + "tx-rx-65-127-frames", + "tx-rx-128-255-frames", + "tx-rx-256-511-frames", + "tx-rx-512-1023-frames", + "tx-rx-1024-1518-frames", + "tx-rx-1519-1522-good-vlan", + "rx-bytes", + "rx-packets", + "rx-fcs-errors", + "receive-multicast-packet", + "receive-broadcast-packet", + "rx-control-frame-packets", + "rx-pause-frame-packets", + "rx-unknown-op-code", + "rx-alignment-error", + "rx-frame-length-error", + "rx-code-error", + "rx-carrier-sense-error", + "rx-undersize-packets", + "rx-oversize-packets", + "rx-fragmented-frames", + "rx-jabber-frames", + "rx-dropped-frames", + "tx-byte-counter", + "tx-packets", + "tx-multicast-packets", + "tx-broadcast-packets", + "tx-pause-control-frames", + "tx-deferral-packets", + "tx-excessive-deferral-packets", + "tx-single-collision-packets", + "tx-multiple-collision-packets", + "tx-late-collision-packets", + "tx-excessive-collision-packets", + "tx-total-collision", + "reserved", + "tx-dropped-frames", + "tx-jabber-frames", + "tx-fcs-errors", + "tx-control-frames", + "tx-oversize-frames", + "tx-undersize-frames", + "tx-fragmented-frames", }; /* Fill in an array of 64-bit statistics from various sources. @@ -125,7 +125,7 @@ void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, u64 * buf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u32 *rmon = (u32 *) & priv->regs->rmon; u64 *extra = (u64 *) & priv->extra_stats; struct gfar_stats *stats = (struct gfar_stats *) buf; @@ -154,7 +154,7 @@ struct ethtool_stats *dummy, u64 * buf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u64 *extra = (u64 *) & priv->extra_stats; for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) { @@ -171,7 +171,7 @@ void gfar_gdrvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { - strncpy(drvinfo->driver, gfar_driver_name, GFAR_INFOSTR_LEN); + strncpy(drvinfo->driver, DRV_NAME, GFAR_INFOSTR_LEN); strncpy(drvinfo->version, gfar_driver_version, GFAR_INFOSTR_LEN); strncpy(drvinfo->fw_version, "N/A", GFAR_INFOSTR_LEN); strncpy(drvinfo->bus_info, "N/A", GFAR_INFOSTR_LEN); @@ -184,7 +184,7 @@ /* Return the current settings in the ethtool_cmd structure */ int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); uint gigabit_support = priv->einfo->flags & GFAR_HAS_GIGABIT ? SUPPORTED_1000baseT_Full : 0; uint gigabit_advert = @@ -201,10 +201,10 @@ | ADVERTISED_100baseT_Full | gigabit_advert | ADVERTISED_Autoneg); - cmd->speed = priv->speed; - cmd->duplex = priv->duplexity; + cmd->speed = priv->mii_info->speed; + cmd->duplex = priv->mii_info->duplex; cmd->port = PORT_MII; - cmd->phy_address = priv->einfo->phyid; + cmd->phy_address = priv->mii_info->mii_id; cmd->transceiver = XCVR_EXTERNAL; cmd->autoneg = AUTONEG_ENABLE; cmd->maxtxpkt = priv->txcount; @@ -223,7 +223,7 @@ void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf) { int i; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); u32 *theregs = (u32 *) priv->regs; u32 *buf = (u32 *) regbuf; @@ -231,13 +231,6 @@ buf[i] = theregs[i]; } -/* Return the link state 1 is up, 0 is down */ -u32 gfar_get_link(struct net_device *dev) -{ - struct gfar_private *priv = (struct gfar_private *) dev->priv; - return (u32) priv->link; -} - /* Fill in a buffer with the strings which correspond to the * stats */ void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf) @@ -252,7 +245,7 @@ unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->speed) { + switch (priv->mii_info->speed) { case 1000: count = GFAR_GBIT_TIME; break; @@ -276,7 +269,7 @@ unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->speed) { + switch (priv->mii_info->speed) { case 1000: count = GFAR_GBIT_TIME; break; @@ -298,7 +291,7 @@ * structure. */ int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); cvals->rx_max_coalesced_frames = priv->rxcount; @@ -344,7 +337,7 @@ */ int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); /* Set up rx coalescing */ if ((cvals->rx_coalesce_usecs == 0) || @@ -386,7 +379,7 @@ * jumbo are ignored by the driver */ void gfar_gringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); rvals->rx_max_pending = GFAR_RX_MAX_RING_SIZE; rvals->rx_mini_max_pending = GFAR_RX_MAX_RING_SIZE; @@ -409,7 +402,7 @@ int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rvals) { u32 tempval; - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); int err = 0; if (rvals->rx_pending > GFAR_RX_MAX_RING_SIZE) @@ -473,7 +466,7 @@ .get_drvinfo = gfar_gdrvinfo, .get_regs_len = gfar_reglen, .get_regs = gfar_get_regs, - .get_link = gfar_get_link, + .get_link = ethtool_op_get_link, .get_coalesce = gfar_gcoalesce, .set_coalesce = gfar_scoalesce, .get_ringparam = gfar_gringparam, @@ -481,4 +474,52 @@ .get_strings = gfar_gstrings, .get_stats_count = gfar_stats_count, .get_ethtool_stats = gfar_fill_stats, +}; + +struct ethtool_ops gfar_normon_nocoalesce_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings_normon, + .get_stats_count = gfar_stats_count_normon, + .get_ethtool_stats = gfar_fill_stats_normon, +}; + +struct ethtool_ops gfar_nocoalesce_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings, + .get_stats_count = gfar_stats_count, + .get_ethtool_stats = gfar_fill_stats, +}; + +struct ethtool_ops gfar_normon_ethtool_ops = { + .get_settings = gfar_gsettings, + .get_drvinfo = gfar_gdrvinfo, + .get_regs_len = gfar_reglen, + .get_regs = gfar_get_regs, + .get_link = ethtool_op_get_link, + .get_coalesce = gfar_gcoalesce, + .set_coalesce = gfar_scoalesce, + .get_ringparam = gfar_gringparam, + .set_ringparam = gfar_sringparam, + .get_strings = gfar_gstrings_normon, + .get_stats_count = gfar_stats_count_normon, + .get_ethtool_stats = gfar_fill_stats_normon, +}; + +struct ethtool_ops *gfar_op_array[] = { + &gfar_ethtool_ops, + &gfar_normon_ethtool_ops, + &gfar_nocoalesce_ethtool_ops, + &gfar_normon_nocoalesce_ethtool_ops }; diff -Nru a/drivers/net/gianfar_phy.c b/drivers/net/gianfar_phy.c --- a/drivers/net/gianfar_phy.c Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_phy.c Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -38,21 +38,31 @@ #include #include #include +#include #include "gianfar.h" #include "gianfar_phy.h" +static void config_genmii_advert(struct gfar_mii_info *mii_info); +static void genmii_setup_forced(struct gfar_mii_info *mii_info); +static void genmii_restart_aneg(struct gfar_mii_info *mii_info); +static int gbit_config_aneg(struct gfar_mii_info *mii_info); +static int genmii_config_aneg(struct gfar_mii_info *mii_info); +static int genmii_update_link(struct gfar_mii_info *mii_info); +static int genmii_read_status(struct gfar_mii_info *mii_info); +u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum); +void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val); + /* Write value to the PHY for this device to the register at regnum, */ /* waiting until the write is done before it returns. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -void write_phy_reg(struct net_device *dev, u16 regnum, u16 value) +void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); struct gfar *regbase = priv->phyregs; - struct ocp_gfar_data *einfo = priv->einfo; /* Set the PHY address and the register address we want to write */ - gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum); + gfar_write(®base->miimadd, (mii_id << 8) | regnum); /* Write out the value we want */ gfar_write(®base->miimcon, value); @@ -65,19 +75,18 @@ /* Reads from register regnum in the PHY for device dev, */ /* returning the value. Clears miimcom first. All PHY */ /* configuration has to be done through the TSEC1 MIIM regs */ -u16 read_phy_reg(struct net_device *dev, u16 regnum) +int read_phy_reg(struct net_device *dev, int mii_id, int regnum) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + struct gfar_private *priv = netdev_priv(dev); struct gfar *regbase = priv->phyregs; - struct ocp_gfar_data *einfo = priv->einfo; u16 value; /* Set the PHY address and the register address we want to read */ - gfar_write(®base->miimadd, ((einfo->phyid) << 8) | regnum); + gfar_write(®base->miimadd, (mii_id << 8) | regnum); /* Clear miimcom, and then initiate a read */ gfar_write(®base->miimcom, 0); - gfar_write(®base->miimcom, MIIM_READ_COMMAND); + gfar_write(®base->miimcom, MII_READ_COMMAND); /* Wait for the transaction to finish */ while (gfar_read(®base->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY)) @@ -89,362 +98,557 @@ return value; } -/* returns which value to write to the control register. */ -/* For 10/100 the value is slightly different. */ -u16 mii_cr_init(u16 mii_reg, struct net_device * dev) +void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - struct ocp_gfar_data *einfo = priv->einfo; + if(mii_info->phyinfo->ack_interrupt) + mii_info->phyinfo->ack_interrupt(mii_info); +} - if (einfo->flags & GFAR_HAS_GIGABIT) - return MIIM_CONTROL_INIT; - else - return MIIM_CR_INIT; + +void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts) +{ + mii_info->interrupts = interrupts; + if(mii_info->phyinfo->config_intr) + mii_info->phyinfo->config_intr(mii_info); +} + + +/* Writes MII_ADVERTISE with the appropriate values, after + * sanitizing advertise to make sure only supported features + * are advertised + */ +static void config_genmii_advert(struct gfar_mii_info *mii_info) +{ + u32 advertise; + u16 adv; + + /* Only allow advertising what this PHY supports */ + mii_info->advertising &= mii_info->phyinfo->features; + advertise = mii_info->advertising; + + /* Setup standard advertisement */ + adv = phy_read(mii_info, MII_ADVERTISE); + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); + if (advertise & ADVERTISED_10baseT_Half) + adv |= ADVERTISE_10HALF; + if (advertise & ADVERTISED_10baseT_Full) + adv |= ADVERTISE_10FULL; + if (advertise & ADVERTISED_100baseT_Half) + adv |= ADVERTISE_100HALF; + if (advertise & ADVERTISED_100baseT_Full) + adv |= ADVERTISE_100FULL; + phy_write(mii_info, MII_ADVERTISE, adv); +} + +static void genmii_setup_forced(struct gfar_mii_info *mii_info) +{ + u16 ctrl; + u32 features = mii_info->phyinfo->features; + + ctrl = phy_read(mii_info, MII_BMCR); + + ctrl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPEED1000|BMCR_ANENABLE); + ctrl |= BMCR_RESET; + + switch(mii_info->speed) { + case SPEED_1000: + if(features & (SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full)) { + ctrl |= BMCR_SPEED1000; + break; + } + mii_info->speed = SPEED_100; + case SPEED_100: + if (features & (SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full)) { + ctrl |= BMCR_SPEED100; + break; + } + mii_info->speed = SPEED_10; + case SPEED_10: + if (features & (SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full)) + break; + default: /* Unsupported speed! */ + printk(KERN_ERR "%s: Bad speed!\n", + mii_info->dev->name); + break; + } + + phy_write(mii_info, MII_BMCR, ctrl); +} + + +/* Enable and Restart Autonegotiation */ +static void genmii_restart_aneg(struct gfar_mii_info *mii_info) +{ + u16 ctl; + + ctl = phy_read(mii_info, MII_BMCR); + ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); + phy_write(mii_info, MII_BMCR, ctl); +} + + +static int gbit_config_aneg(struct gfar_mii_info *mii_info) +{ + u16 adv; + u32 advertise; + + if(mii_info->autoneg) { + /* Configure the ADVERTISE register */ + config_genmii_advert(mii_info); + advertise = mii_info->advertising; + + adv = phy_read(mii_info, MII_1000BASETCONTROL); + adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP | + MII_1000BASETCONTROL_HALFDUPLEXCAP); + if (advertise & SUPPORTED_1000baseT_Half) + adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP; + if (advertise & SUPPORTED_1000baseT_Full) + adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP; + phy_write(mii_info, MII_1000BASETCONTROL, adv); + + /* Start/Restart aneg */ + genmii_restart_aneg(mii_info); + } else + genmii_setup_forced(mii_info); + + return 0; +} + +static int marvell_config_aneg(struct gfar_mii_info *mii_info) +{ + /* The Marvell PHY has an errata which requires + * that certain registers get written in order + * to restart autonegotiation */ + phy_write(mii_info, MII_BMCR, BMCR_RESET); + + phy_write(mii_info, 0x1d, 0x1f); + phy_write(mii_info, 0x1e, 0x200c); + phy_write(mii_info, 0x1d, 0x5); + phy_write(mii_info, 0x1e, 0); + phy_write(mii_info, 0x1e, 0x100); + + gbit_config_aneg(mii_info); + + return 0; +} +static int genmii_config_aneg(struct gfar_mii_info *mii_info) +{ + if (mii_info->autoneg) { + config_genmii_advert(mii_info); + genmii_restart_aneg(mii_info); + } else + genmii_setup_forced(mii_info); + + return 0; } -#define BRIEF_GFAR_ERRORS -/* Wait for auto-negotiation to complete */ -u16 mii_parse_sr(u16 mii_reg, struct net_device * dev) + +static int genmii_update_link(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + u16 status; - unsigned int timeout = GFAR_AN_TIMEOUT; + /* Do a fake read */ + phy_read(mii_info, MII_BMSR); - if (mii_reg & MIIM_STATUS_LINK) - priv->link = 1; + /* Read link and autonegotiation status */ + status = phy_read(mii_info, MII_BMSR); + if ((status & BMSR_LSTATUS) == 0) + mii_info->link = 0; else - priv->link = 0; + mii_info->link = 1; - /* Only auto-negotiate if the link has just gone up */ - if (priv->link && !priv->oldlink) { - while ((!(mii_reg & MIIM_STATUS_AN_DONE)) && timeout--) - mii_reg = read_phy_reg(dev, MIIM_STATUS); - -#if defined(BRIEF_GFAR_ERRORS) - if (mii_reg & MIIM_STATUS_AN_DONE) - printk(KERN_INFO "%s: Auto-negotiation done\n", - dev->name); - else - printk(KERN_INFO "%s: Auto-negotiation timed out\n", - dev->name); -#endif - } + /* If we are autonegotiating, and not done, + * return an error */ + if (mii_info->autoneg && !(status & BMSR_ANEGCOMPLETE)) + return -EAGAIN; return 0; } -/* Determine the speed and duplex which was negotiated */ -u16 mii_parse_88E1011_psr(u16 mii_reg, struct net_device * dev) +static int genmii_read_status(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - unsigned int speed; + u16 status; + int err; - if (priv->link) { - if (mii_reg & MIIM_88E1011_PHYSTAT_DUPLEX) - priv->duplexity = 1; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + if (mii_info->autoneg) { + status = phy_read(mii_info, MII_LPA); + + if (status & (LPA_10FULL | LPA_100FULL)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + if (status & (LPA_100FULL | LPA_100HALF)) + mii_info->speed = SPEED_100; else - priv->duplexity = 0; + mii_info->speed = SPEED_10; + mii_info->pause = 0; + } + /* On non-aneg, we assume what we put in BMCR is the speed, + * though magic-aneg shouldn't prevent this case from occurring + */ - speed = (mii_reg & MIIM_88E1011_PHYSTAT_SPEED); + return 0; +} +static int marvell_read_status(struct gfar_mii_info *mii_info) +{ + u16 status; + int err; - switch (speed) { - case MIIM_88E1011_PHYSTAT_GBIT: - priv->speed = 1000; - break; - case MIIM_88E1011_PHYSTAT_100: - priv->speed = 100; - break; - default: - priv->speed = 10; - break; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int speed; + status = phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS); + +#if 0 + /* If speed and duplex aren't resolved, + * return an error. Isn't this handled + * by checking aneg? + */ + if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0) + return -EAGAIN; +#endif + + /* Get the duplexity */ + if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + + /* Get the speed */ + speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK; + switch(speed) { + case MII_M1011_PHY_SPEC_STATUS_1000: + mii_info->speed = SPEED_1000; + break; + case MII_M1011_PHY_SPEC_STATUS_100: + mii_info->speed = SPEED_100; + break; + default: + mii_info->speed = SPEED_10; + break; } - } else { - priv->speed = 0; - priv->duplexity = 0; + mii_info->pause = 0; } return 0; } -u16 mii_parse_cis8201(u16 mii_reg, struct net_device * dev) + +static int cis820x_read_status(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; - unsigned int speed; + u16 status; + int err; - if (priv->link) { - if (mii_reg & MIIM_CIS8201_AUXCONSTAT_DUPLEX) - priv->duplexity = 1; + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + int speed; + + status = phy_read(mii_info, MII_CIS8201_AUX_CONSTAT); + if (status & MII_CIS8201_AUXCONSTAT_DUPLEX) + mii_info->duplex = DUPLEX_FULL; else - priv->duplexity = 0; + mii_info->duplex = DUPLEX_HALF; - speed = mii_reg & MIIM_CIS8201_AUXCONSTAT_SPEED; + speed = status & MII_CIS8201_AUXCONSTAT_SPEED; switch (speed) { - case MIIM_CIS8201_AUXCONSTAT_GBIT: - priv->speed = 1000; + case MII_CIS8201_AUXCONSTAT_GBIT: + mii_info->speed = SPEED_1000; break; - case MIIM_CIS8201_AUXCONSTAT_100: - priv->speed = 100; + case MII_CIS8201_AUXCONSTAT_100: + mii_info->speed = SPEED_100; break; default: - priv->speed = 10; + mii_info->speed = SPEED_10; break; } - } else { - priv->speed = 0; - priv->duplexity = 0; } return 0; } -u16 mii_parse_dm9161_scsr(u16 mii_reg, struct net_device * dev) +static int marvell_ack_interrupt(struct gfar_mii_info *mii_info) { - struct gfar_private *priv = (struct gfar_private *) dev->priv; + /* Clear the interrupts by reading the reg */ + phy_read(mii_info, MII_M1011_IEVENT); - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_100H)) - priv->speed = 100; + return 0; +} + +static int marvell_config_intr(struct gfar_mii_info *mii_info) +{ + if(mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT); else - priv->speed = 10; + phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); + + return 0; +} + +static int cis820x_init(struct gfar_mii_info *mii_info) +{ + phy_write(mii_info, MII_CIS8201_AUX_CONSTAT, + MII_CIS8201_AUXCONSTAT_INIT); + phy_write(mii_info, MII_CIS8201_EXT_CON1, + MII_CIS8201_EXTCON1_INIT); + + return 0; +} + +static int cis820x_ack_interrupt(struct gfar_mii_info *mii_info) +{ + phy_read(mii_info, MII_CIS8201_ISTAT); - if (mii_reg & (MIIM_DM9161_SCSR_100F | MIIM_DM9161_SCSR_10F)) - priv->duplexity = 1; + return 0; +} + +static int cis820x_config_intr(struct gfar_mii_info *mii_info) +{ + if(mii_info->interrupts == MII_INTERRUPT_ENABLED) + phy_write(mii_info, MII_CIS8201_IMASK, MII_CIS8201_IMASK_MASK); else - priv->duplexity = 0; + phy_write(mii_info, MII_CIS8201_IMASK, 0); return 0; } -u16 dm9161_wait(u16 mii_reg, struct net_device *dev) +#define DM9161_DELAY 10 + +static int dm9161_read_status(struct gfar_mii_info *mii_info) { - int timeout = HZ; - int secondary = 10; - u16 temp; - - do { - - /* Davicom takes a bit to come up after a reset, - * so wait here for a bit */ - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(timeout); - - temp = read_phy_reg(dev, MIIM_STATUS); - - secondary--; - } while ((!(temp & MIIM_STATUS_AN_DONE)) && secondary); - - return 0; -} - -static struct phy_info phy_info_M88E1011S = { - 0x01410c6, - "Marvell 88E1011S", - 4, - (const struct phy_cmd[]) { /* config */ - /* Reset and configure the PHY */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr}, - /* Clear the IEVENT register */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - /* Set up the mask */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - /* Clear the interrupt */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Check the status */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - {MIIM_88E1011_PHY_STATUS, miim_read, mii_parse_88E1011_psr}, - /* Enable Interrupts */ - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {MIIM_88E1011_IEVENT, miim_read, NULL}, - {MIIM_88E1011_IMASK, MIIM_88E1011_IMASK_CLEAR, NULL}, - {miim_end,} - }, -}; + u16 status; + int err; + + /* Update the link, but return if there + * was an error */ + err = genmii_update_link(mii_info); + if (err) + return err; + + /* If the link is up, read the speed and duplex */ + /* If we aren't autonegotiating, assume speeds + * are as set */ + if (mii_info->autoneg && mii_info->link) { + status = phy_read(mii_info, MII_DM9161_SCSR); + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H)) + mii_info->speed = SPEED_100; + else + mii_info->speed = SPEED_10; + + if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F)) + mii_info->duplex = DUPLEX_FULL; + else + mii_info->duplex = DUPLEX_HALF; + } + + return 0; +} + + +static int dm9161_config_aneg(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv = mii_info->priv; + + if(0 == priv->resetdone) + return -EAGAIN; + + return 0; +} + +static void dm9161_timer(unsigned long data) +{ + struct gfar_mii_info *mii_info = (struct gfar_mii_info *)data; + struct dm9161_private *priv = mii_info->priv; + u16 status = phy_read(mii_info, MII_BMSR); + + if (status & BMSR_ANEGCOMPLETE) { + priv->resetdone = 1; + } else + mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); +} + +static int dm9161_init(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv; + + /* Allocate the private data structure */ + priv = kmalloc(sizeof(struct dm9161_private), GFP_KERNEL); + + if (NULL == priv) + return -ENOMEM; + + mii_info->priv = priv; + + /* Reset is not done yet */ + priv->resetdone = 0; + + /* Isolate the PHY */ + phy_write(mii_info, MII_BMCR, BMCR_ISOLATE); + + /* Do not bypass the scrambler/descrambler */ + phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT); + + /* Clear 10BTCSR to default */ + phy_write(mii_info, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); + + /* Reconnect the PHY, and enable Autonegotiation */ + phy_write(mii_info, MII_BMCR, BMCR_ANENABLE); + + /* Start a timer for DM9161_DELAY seconds to wait + * for the PHY to be ready */ + init_timer(&priv->timer); + priv->timer.function = &dm9161_timer; + priv->timer.data = (unsigned long) mii_info; + mod_timer(&priv->timer, jiffies + DM9161_DELAY * HZ); + + return 0; +} -/* Cicada 8204 */ -static struct phy_info phy_info_cis8204 = { - 0x3f11, +static void dm9161_close(struct gfar_mii_info *mii_info) +{ + struct dm9161_private *priv = mii_info->priv; + + del_timer_sync(&priv->timer); + kfree(priv); +} + +#if 0 +static int dm9161_ack_interrupt(struct gfar_mii_info *mii_info) +{ + phy_read(mii_info, MII_DM9161_INTR); + + return 0; +} +#endif + +/* Cicada 820x */ +static struct phy_info phy_info_cis820x = { + 0x000fc440, "Cicada Cis8204", - 6, - (const struct phy_cmd[]) { /* config */ - /* Override PHY config settings */ - {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, - /* Set up the interface mode */ - {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Enable interrupts */ - {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_CIS8204_IMASK, 0x0, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - /* Enable interrupts */ - {MIIM_CIS8204_IMASK, MIIM_CIS8204_IMASK_MASK, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - /* Clear the status register */ - {MIIM_CIS8204_ISTAT, miim_read, NULL}, - /* Disable interrupts */ - {MIIM_CIS8204_IMASK, 0x0, NULL}, - {miim_end,} - }, + 0x000fffc0, + .features = MII_GBIT_FEATURES, + .init = &cis820x_init, + .config_aneg = &gbit_config_aneg, + .read_status = &cis820x_read_status, + .ack_interrupt = &cis820x_ack_interrupt, + .config_intr = &cis820x_config_intr, }; -/* Cicada 8201 */ -static struct phy_info phy_info_cis8201 = { - 0xfc41, - "CIS8201", - 4, - (const struct phy_cmd[]) { /* config */ - /* Override PHY config settings */ - {MIIM_CIS8201_AUX_CONSTAT, MIIM_CIS8201_AUXCONSTAT_INIT, NULL}, - /* Set up the interface mode */ - {MIIM_CIS8201_EXT_CON1, MIIM_CIS8201_EXTCON1_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CONTROL_INIT, mii_cr_init}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Read the Status (2x to make sure link is right) */ - {MIIM_STATUS, miim_read, NULL}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_CIS8201_AUX_CONSTAT, miim_read, mii_parse_cis8201}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {miim_end,} - }, +static struct phy_info phy_info_dm9161 = { + .phy_id = 0x0181b880, + .name = "Davicom DM9161E", + .phy_id_mask = 0x0ffffff0, + .init = dm9161_init, + .config_aneg = dm9161_config_aneg, + .read_status = dm9161_read_status, + .close = dm9161_close, }; -static struct phy_info phy_info_dm9161 = { - 0x0181b88, - "Davicom DM9161E", - 4, - (const struct phy_cmd[]) { /* config */ - {MIIM_CONTROL, MIIM_DM9161_CR_STOP, NULL}, - /* Do not bypass the scrambler/descrambler */ - {MIIM_DM9161_SCR, MIIM_DM9161_SCR_INIT, NULL}, - /* Clear 10BTCSR to default */ - {MIIM_DM9161_10BTCSR, MIIM_DM9161_10BTCSR_INIT, NULL}, - /* Configure some basic stuff */ - {MIIM_CONTROL, MIIM_CR_INIT, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* startup */ - /* Restart Auto Negotiation */ - {MIIM_CONTROL, MIIM_DM9161_CR_RSTAN, NULL}, - /* Status is read once to clear old link state */ - {MIIM_STATUS, miim_read, dm9161_wait}, - /* Auto-negotiate */ - {MIIM_STATUS, miim_read, mii_parse_sr}, - /* Read the status */ - {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr}, - /* Clear any pending interrupts */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* ack_int */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* handle_int */ - {MIIM_STATUS, miim_read, NULL}, - {MIIM_STATUS, miim_read, mii_parse_sr}, - {MIIM_DM9161_SCSR, miim_read, mii_parse_dm9161_scsr}, - {miim_end,} - }, - (const struct phy_cmd[]) { /* shutdown */ - {MIIM_DM9161_INTR, miim_read, NULL}, - {miim_end,} - }, +static struct phy_info phy_info_marvell = { + .phy_id = 0x01410c00, + .phy_id_mask = 0xffffff00, + .name = "Marvell 88E1101", + .features = MII_GBIT_FEATURES, + .config_aneg = &marvell_config_aneg, + .read_status = &marvell_read_status, + .ack_interrupt = &marvell_ack_interrupt, + .config_intr = &marvell_config_intr, +}; + +static struct phy_info phy_info_genmii= { + .phy_id = 0x00000000, + .phy_id_mask = 0x00000000, + .name = "Generic MII", + .features = MII_BASIC_FEATURES, + .config_aneg = genmii_config_aneg, + .read_status = genmii_read_status, }; static struct phy_info *phy_info[] = { - &phy_info_cis8201, - &phy_info_cis8204, - &phy_info_M88E1011S, + &phy_info_cis820x, + &phy_info_marvell, &phy_info_dm9161, + &phy_info_genmii, NULL }; +u16 phy_read(struct gfar_mii_info *mii_info, u16 regnum) +{ + u16 retval; + unsigned long flags; + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + retval = mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); + + return retval; +} + +void phy_write(struct gfar_mii_info *mii_info, u16 regnum, u16 val) +{ + unsigned long flags; + + spin_lock_irqsave(&mii_info->mdio_lock, flags); + mii_info->mdio_write(mii_info->dev, + mii_info->mii_id, + regnum, val); + spin_unlock_irqrestore(&mii_info->mdio_lock, flags); +} + /* Use the PHY ID registers to determine what type of PHY is attached * to device dev. return a struct phy_info structure describing that PHY */ -struct phy_info * get_phy_info(struct net_device *dev) +struct phy_info * get_phy_info(struct gfar_mii_info *mii_info) { u16 phy_reg; u32 phy_ID; int i; struct phy_info *theInfo = NULL; + struct net_device *dev = mii_info->dev; /* Grab the bits from PHYIR1, and put them in the upper half */ - phy_reg = read_phy_reg(dev, MIIM_PHYIR1); + phy_reg = phy_read(mii_info, MII_PHYSID1); phy_ID = (phy_reg & 0xffff) << 16; /* Grab the bits from PHYIR2, and put them in the lower half */ - phy_reg = read_phy_reg(dev, MIIM_PHYIR2); + phy_reg = phy_read(mii_info, MII_PHYSID2); phy_ID |= (phy_reg & 0xffff); /* loop through all the known PHY types, and find one that */ /* matches the ID we read from the PHY. */ for (i = 0; phy_info[i]; i++) - if (phy_info[i]->id == (phy_ID >> phy_info[i]->shift)) + if (phy_info[i]->phy_id == + (phy_ID & phy_info[i]->phy_id_mask)) { theInfo = phy_info[i]; + break; + } + /* This shouldn't happen, as we have generic PHY support */ if (theInfo == NULL) { printk("%s: PHY id %x is not supported!\n", dev->name, phy_ID); return NULL; @@ -454,51 +658,4 @@ } return theInfo; -} - -/* Take a list of struct phy_cmd, and, depending on the values, either */ -/* read or write, using a helper function if provided */ -/* It is assumed that all lists of struct phy_cmd will be terminated by */ -/* mii_end. */ -void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd) -{ - int i; - u16 result; - struct gfar_private *priv = (struct gfar_private *) dev->priv; - struct gfar *phyregs = priv->phyregs; - - /* Reset the management interface */ - gfar_write(&phyregs->miimcfg, MIIMCFG_RESET); - - /* Setup the MII Mgmt clock speed */ - gfar_write(&phyregs->miimcfg, MIIMCFG_INIT_VALUE); - - /* Wait until the bus is free */ - while (gfar_read(&phyregs->miimind) & MIIMIND_BUSY) - cpu_relax(); - - for (i = 0; cmd->mii_reg != miim_end; i++) { - /* The command is a read if mii_data is miim_read */ - if (cmd->mii_data == miim_read) { - /* Read the value of the PHY reg */ - result = read_phy_reg(dev, cmd->mii_reg); - - /* If a function was supplied, we need to let it process */ - /* the result. */ - if (cmd->funct != NULL) - (*(cmd->funct)) (result, dev); - } else { /* Otherwise, it's a write */ - /* If a function was supplied, it will provide - * the value to write */ - /* Otherwise, the value was supplied in cmd->mii_data */ - if (cmd->funct != NULL) - result = (*(cmd->funct)) (0, dev); - else - result = cmd->mii_data; - - /* Write the appropriate value to the PHY reg */ - write_phy_reg(dev, cmd->mii_reg, result); - } - cmd++; - } } diff -Nru a/drivers/net/gianfar_phy.h b/drivers/net/gianfar_phy.h --- a/drivers/net/gianfar_phy.h Mon Aug 2 17:03:36 2004 +++ b/drivers/net/gianfar_phy.h Mon Aug 2 17:03:36 2004 @@ -8,7 +8,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala (kumar.gala@freescale.com) * - * Copyright 2004 Freescale Semiconductor, Inc + * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -19,135 +19,144 @@ #ifndef __GIANFAR_PHY_H #define __GIANFAR_PHY_H -#define miim_end ((u32)-2) -#define miim_read ((u32)-1) +#define MII_end ((u32)-2) +#define MII_read ((u32)-1) #define MIIMIND_BUSY 0x00000001 #define MIIMIND_NOTVALID 0x00000004 -#define MIIM_CONTROL 0x00 -#define MIIM_CONTROL_RESET 0x00008000 -#define MIIM_CONTROL_INIT 0x00001140 -#define MIIM_ANEN 0x00001000 - -#define MIIM_CR 0x00 -#define MIIM_CR_RST 0x00008000 -#define MIIM_CR_INIT 0x00001000 - -#define MIIM_STATUS 0x1 -#define MIIM_STATUS_AN_DONE 0x00000020 -#define MIIM_STATUS_LINK 0x0004 - -#define MIIM_PHYIR1 0x2 -#define MIIM_PHYIR2 0x3 - -#define GFAR_AN_TIMEOUT 0x000fffff - -#define MIIM_ANLPBPA 0x5 -#define MIIM_ANLPBPA_HALF 0x00000040 -#define MIIM_ANLPBPA_FULL 0x00000020 - -#define MIIM_ANEX 0x6 -#define MIIM_ANEX_NP 0x00000004 -#define MIIM_ANEX_PRX 0x00000002 +#define GFAR_AN_TIMEOUT 2000 +/* 1000BT control (Marvell & BCM54xx at least) */ +#define MII_1000BASETCONTROL 0x09 +#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200 +#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100 /* Cicada Extended Control Register 1 */ -#define MIIM_CIS8201_EXT_CON1 0x17 -#define MIIM_CIS8201_EXTCON1_INIT 0x0000 +#define MII_CIS8201_EXT_CON1 0x17 +#define MII_CIS8201_EXTCON1_INIT 0x0000 /* Cicada Interrupt Mask Register */ -#define MIIM_CIS8204_IMASK 0x19 -#define MIIM_CIS8204_IMASK_IEN 0x8000 -#define MIIM_CIS8204_IMASK_SPEED 0x4000 -#define MIIM_CIS8204_IMASK_LINK 0x2000 -#define MIIM_CIS8204_IMASK_DUPLEX 0x1000 -#define MIIM_CIS8204_IMASK_MASK 0xf000 +#define MII_CIS8201_IMASK 0x19 +#define MII_CIS8201_IMASK_IEN 0x8000 +#define MII_CIS8201_IMASK_SPEED 0x4000 +#define MII_CIS8201_IMASK_LINK 0x2000 +#define MII_CIS8201_IMASK_DUPLEX 0x1000 +#define MII_CIS8201_IMASK_MASK 0xf000 /* Cicada Interrupt Status Register */ -#define MIIM_CIS8204_ISTAT 0x1a -#define MIIM_CIS8204_ISTAT_STATUS 0x8000 -#define MIIM_CIS8204_ISTAT_SPEED 0x4000 -#define MIIM_CIS8204_ISTAT_LINK 0x2000 -#define MIIM_CIS8204_ISTAT_DUPLEX 0x1000 +#define MII_CIS8201_ISTAT 0x1a +#define MII_CIS8201_ISTAT_STATUS 0x8000 +#define MII_CIS8201_ISTAT_SPEED 0x4000 +#define MII_CIS8201_ISTAT_LINK 0x2000 +#define MII_CIS8201_ISTAT_DUPLEX 0x1000 /* Cicada Auxiliary Control/Status Register */ -#define MIIM_CIS8201_AUX_CONSTAT 0x1c -#define MIIM_CIS8201_AUXCONSTAT_INIT 0x0004 -#define MIIM_CIS8201_AUXCONSTAT_DUPLEX 0x0020 -#define MIIM_CIS8201_AUXCONSTAT_SPEED 0x0018 -#define MIIM_CIS8201_AUXCONSTAT_GBIT 0x0010 -#define MIIM_CIS8201_AUXCONSTAT_100 0x0008 +#define MII_CIS8201_AUX_CONSTAT 0x1c +#define MII_CIS8201_AUXCONSTAT_INIT 0x0004 +#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 +#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 +#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 +#define MII_CIS8201_AUXCONSTAT_100 0x0008 /* 88E1011 PHY Status Register */ -#define MIIM_88E1011_PHY_STATUS 0x11 -#define MIIM_88E1011_PHYSTAT_SPEED 0xc000 -#define MIIM_88E1011_PHYSTAT_GBIT 0x8000 -#define MIIM_88E1011_PHYSTAT_100 0x4000 -#define MIIM_88E1011_PHYSTAT_DUPLEX 0x2000 -#define MIIM_88E1011_PHYSTAT_LINK 0x0400 - -#define MIIM_88E1011_IEVENT 0x13 -#define MIIM_88E1011_IEVENT_CLEAR 0x0000 - -#define MIIM_88E1011_IMASK 0x12 -#define MIIM_88E1011_IMASK_INIT 0x6400 -#define MIIM_88E1011_IMASK_CLEAR 0x0000 - -/* DM9161 Control register values */ -#define MIIM_DM9161_CR_STOP 0x0400 -#define MIIM_DM9161_CR_RSTAN 0x1200 +#define MII_M1011_PHY_SPEC_STATUS 0x11 +#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000 +#define MII_M1011_PHY_SPEC_STATUS_100 0x4000 +#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000 +#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000 +#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800 +#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400 + +#define MII_M1011_IEVENT 0x13 +#define MII_M1011_IEVENT_CLEAR 0x0000 + +#define MII_M1011_IMASK 0x12 +#define MII_M1011_IMASK_INIT 0x6400 +#define MII_M1011_IMASK_CLEAR 0x0000 -#define MIIM_DM9161_SCR 0x10 -#define MIIM_DM9161_SCR_INIT 0x0610 +#define MII_DM9161_SCR 0x10 +#define MII_DM9161_SCR_INIT 0x0610 /* DM9161 Specified Configuration and Status Register */ -#define MIIM_DM9161_SCSR 0x11 -#define MIIM_DM9161_SCSR_100F 0x8000 -#define MIIM_DM9161_SCSR_100H 0x4000 -#define MIIM_DM9161_SCSR_10F 0x2000 -#define MIIM_DM9161_SCSR_10H 0x1000 +#define MII_DM9161_SCSR 0x11 +#define MII_DM9161_SCSR_100F 0x8000 +#define MII_DM9161_SCSR_100H 0x4000 +#define MII_DM9161_SCSR_10F 0x2000 +#define MII_DM9161_SCSR_10H 0x1000 /* DM9161 Interrupt Register */ -#define MIIM_DM9161_INTR 0x15 -#define MIIM_DM9161_INTR_PEND 0x8000 -#define MIIM_DM9161_INTR_DPLX_MASK 0x0800 -#define MIIM_DM9161_INTR_SPD_MASK 0x0400 -#define MIIM_DM9161_INTR_LINK_MASK 0x0200 -#define MIIM_DM9161_INTR_MASK 0x0100 -#define MIIM_DM9161_INTR_DPLX_CHANGE 0x0010 -#define MIIM_DM9161_INTR_SPD_CHANGE 0x0008 -#define MIIM_DM9161_INTR_LINK_CHANGE 0x0004 -#define MIIM_DM9161_INTR_INIT 0x0000 -#define MIIM_DM9161_INTR_STOP \ -(MIIM_DM9161_INTR_DPLX_MASK | MIIM_DM9161_INTR_SPD_MASK \ - | MIIM_DM9161_INTR_LINK_MASK | MIIM_DM9161_INTR_MASK) +#define MII_DM9161_INTR 0x15 +#define MII_DM9161_INTR_PEND 0x8000 +#define MII_DM9161_INTR_DPLX_MASK 0x0800 +#define MII_DM9161_INTR_SPD_MASK 0x0400 +#define MII_DM9161_INTR_LINK_MASK 0x0200 +#define MII_DM9161_INTR_MASK 0x0100 +#define MII_DM9161_INTR_DPLX_CHANGE 0x0010 +#define MII_DM9161_INTR_SPD_CHANGE 0x0008 +#define MII_DM9161_INTR_LINK_CHANGE 0x0004 +#define MII_DM9161_INTR_INIT 0x0000 +#define MII_DM9161_INTR_STOP \ +(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ + | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) /* DM9161 10BT Configuration/Status */ -#define MIIM_DM9161_10BTCSR 0x12 -#define MIIM_DM9161_10BTCSR_INIT 0x7800 +#define MII_DM9161_10BTCSR 0x12 +#define MII_DM9161_10BTCSR_INIT 0x7800 - -#define MIIM_READ_COMMAND 0x00000001 - -/* - * struct phy_cmd: A command for reading or writing a PHY register - * - * mii_reg: The register to read or write - * - * mii_data: For writes, the value to put in the register. - * A value of -1 indicates this is a read. - * - * funct: A function pointer which is invoked for each command. - * For reads, this function will be passed the value read - * from the PHY, and process it. - * For writes, the result of this function will be written - * to the PHY register - */ -struct phy_cmd { - u32 mii_reg; - u32 mii_data; - u16 (*funct) (u16 mii_reg, struct net_device * dev); +#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ + SUPPORTED_10baseT_Full | \ + SUPPORTED_100baseT_Half | \ + SUPPORTED_100baseT_Full | \ + SUPPORTED_Autoneg | \ + SUPPORTED_TP | \ + SUPPORTED_MII) + +#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ + SUPPORTED_1000baseT_Half | \ + SUPPORTED_1000baseT_Full) + +#define MII_READ_COMMAND 0x00000001 + +#define MII_INTERRUPT_DISABLED 0x0 +#define MII_INTERRUPT_ENABLED 0x1 +/* Taken from mii_if_info and sungem_phy.h */ +struct gfar_mii_info { + /* Information about the PHY type */ + /* And management functions */ + struct phy_info *phyinfo; + + /* forced speed & duplex (no autoneg) + * partner speed & duplex & pause (autoneg) + */ + int speed; + int duplex; + int pause; + + /* The most recently read link state */ + int link; + + /* Enabled Interrupts */ + u32 interrupts; + + u32 advertising; + int autoneg; + int mii_id; + + /* private data pointer */ + /* For use by PHYs to maintain extra state */ + void *priv; + + /* Provided by host chip */ + struct net_device *dev; + + /* A lock to ensure that only one thing can read/write + * the MDIO bus at a time */ + spinlock_t mdio_lock; + + /* Provided by ethernet driver */ + int (*mdio_read) (struct net_device *dev, int mii_id, int reg); + void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val); }; /* struct phy_info: a structure which defines attributes for a PHY @@ -155,38 +164,50 @@ * id will contain a number which represents the PHY. During * startup, the driver will poll the PHY to find out what its * UID--as defined by registers 2 and 3--is. The 32-bit result - * gotten from the PHY will be shifted right by "shift" bits to + * gotten from the PHY will be ANDed with phy_id_mask to * discard any bits which may change based on revision numbers * unimportant to functionality * - * The struct phy_cmd entries represent pointers to an arrays of - * commands which tell the driver what to do to the PHY. + * There are 6 commands which take a gfar_mii_info structure. + * Each PHY must declare config_aneg, and read_status. */ struct phy_info { - u32 id; - char *name; - unsigned int shift; - /* Called to configure the PHY, and modify the controller - * based on the results */ - const struct phy_cmd *config; - - /* Called when starting up the controller. Usually sets - * up the interrupt for state changes */ - const struct phy_cmd *startup; - - /* Called inside the interrupt handler to acknowledge - * the interrupt */ - const struct phy_cmd *ack_int; - - /* Called in the bottom half to handle the interrupt */ - const struct phy_cmd *handle_int; - - /* Called when bringing down the controller. Usually stops - * the interrupts from being generated */ - const struct phy_cmd *shutdown; + u32 phy_id; + char *name; + unsigned int phy_id_mask; + u32 features; + + /* Called to initialize the PHY */ + int (*init)(struct gfar_mii_info *mii_info); + + /* Called to suspend the PHY for power */ + int (*suspend)(struct gfar_mii_info *mii_info); + + /* Reconfigures autonegotiation (or disables it) */ + int (*config_aneg)(struct gfar_mii_info *mii_info); + + /* Determines the negotiated speed and duplex */ + int (*read_status)(struct gfar_mii_info *mii_info); + + /* Clears any pending interrupts */ + int (*ack_interrupt)(struct gfar_mii_info *mii_info); + + /* Enables or disables interrupts */ + int (*config_intr)(struct gfar_mii_info *mii_info); + + /* Clears up any memory if needed */ + void (*close)(struct gfar_mii_info *mii_info); }; -struct phy_info *get_phy_info(struct net_device *dev); -void phy_run_commands(struct net_device *dev, const struct phy_cmd *cmd); +struct phy_info *get_phy_info(struct gfar_mii_info *mii_info); +int read_phy_reg(struct net_device *dev, int mii_id, int regnum); +void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value); +void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info); +void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts); + +struct dm9161_private { + struct timer_list timer; + int resetdone; +}; #endif /* GIANFAR_PHY_H */ diff -Nru a/include/linux/mii.h b/include/linux/mii.h --- a/include/linux/mii.h Mon Aug 2 17:03:36 2004 +++ b/include/linux/mii.h Mon Aug 2 17:03:36 2004 @@ -33,7 +33,8 @@ #define MII_NCONFIG 0x1c /* Network interface config */ /* Basic mode control register. */ -#define BMCR_RESV 0x007f /* Unused... */ +#define BMCR_RESV 0x003f /* Unused... */ +#define BMCR_SPEED1000 0x0040 /* MSB of Speed (1000) */ #define BMCR_CTST 0x0080 /* Collision test */ #define BMCR_FULLDPLX 0x0100 /* Full duplex */ #define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */ --Apple-Mail-1--634686679 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII; format=flowed On Aug 2, 2004, at 18:11, Jeff Garzik wrote: > On Mon, Aug 02, 2004 at 05:19:13PM -0500, Andy Fleming wrote: >> Here's an updated patch which fixes module support which does this: >> >> * More cleanup/minor bug fixes >> * Added locking to PHY read/write wrappers >> * Fixed module support >> * Removed fastroute code >> >> As before, this patch replaces the previous ones I have submitted. > > the patch? :) > > Jeff > --Apple-Mail-1--634686679-- From matthias.andree@gmx.de Mon Aug 2 17:09:46 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:09:54 -0700 (PDT) Received: from mail.dt.e-technik.uni-dortmund.de (IDENT:7RfVXN0v6r7rTx3dughqjqVtOTfrqSoX@mail.dt.E-Technik.Uni-Dortmund.DE [129.217.163.1]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7309jrR025163 for ; Mon, 2 Aug 2004 17:09:46 -0700 Received: from m2a2.dyndns.org (pD9E1ED50.dip.t-dialin.net [217.225.237.80]) by mail.dt.e-technik.uni-dortmund.de (Postfix) with ESMTP id 49E492BDA5; Tue, 3 Aug 2004 02:09:40 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by merlin.emma.line.org (Postfix) with ESMTP id 87AF9C2C65; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Received: from merlin.emma.line.org ([127.0.0.1]) by localhost (m2a2.dyndns.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 05176-02; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Received: by merlin.emma.line.org (Postfix, from userid 500) id 28218C1104; Tue, 3 Aug 2004 02:03:54 +0200 (CEST) Date: Tue, 3 Aug 2004 02:03:54 +0200 From: Matthias Andree To: Andrew Morton Cc: Matthias Andree , netdev@oss.sgi.com Subject: Re: 2.6.8-rc2-mm1 breaks PPPoE for me (was: 2.6.8-rc2-mm1) Message-ID: <20040803000354.GA5327@merlin.emma.line.org> References: <20040728020444.4dca7e23.akpm@osdl.org> <20040731100947.GA7453@merlin.emma.line.org> <20040802142706.46100c6d.akpm@osdl.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040802142706.46100c6d.akpm@osdl.org> User-Agent: Mutt/1.5.6i X-Virus-Scanned: by amavisd-new at m2a2.dyndns.org X-archive-position: 7431 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: matthias.andree@gmx.de Precedence: bulk X-list: netdev On Mon, 02 Aug 2004, Andrew Morton wrote: > I'm a bit stumped by this - I'm not aware of any change which would have > caused the pppoe device to start returning -ENOTTY. > > Is this still happening? Are you sure the relevant modules are loaded? > Could you capture an strace of pppd while it's happening? It happens in 2.6.8-rc2-mm2, too. The strace is inconclusive. Setup description: I am running pppd 2.4.1 (SuSE 8.2 RPM) with the PPPOE plugin tied to eth1: PCI: Enabling device 0000:00:0b.0 (0004 -> 0005) ACPI: PCI interrupt 0000:00:0b.0[A] -> GSI 19 (level, low) -> IRQ 19 0000:00:0b.0: 3Com PCI 3c905 Boomerang 100baseTx at 0xd400. Vers LK1.1.19 eth1: Dropping NETIF_F_SG since no checksum feature. I am starting pppd via DJB's daemontools (http://cr.yp.to/daemontools.html), with this run file: #! /bin/sh exec strace -ff -F -o /tmp/dump-pppd /usr/sbin/pppd call pppoe Starting pppd from a bash (in an xterm, only thing I've tried) works, I get a connection. Writing such a pppd command into inittab yields ENOENT rather than ENOTTY and fails as well. The strace looks unhelpful to me, the only occurrence of ENOTTY is: readlink("/proc/self/fd/0", "/dev/null", 511) = 9 ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffff700) = -1 ENOTTY (Inappropriate ioctl for device) ltrace reveals this happens inside getlogin() - and pppd appears to fall back to getpwuid. I'd think this is unrelated for I have the same lines with a working kernel as well. Using rp-pppoe as pty (instead of the plugin) doesn't work either, the PPP link is negotiated properly but my log is full of "martian address" log entries as though it was receiving its own packets externally. How strange. I wonder if this is an strace artifact... No useful debugging information. I hope someone can reproduce this. :-( -- Matthias Andree Encrypted mail welcome: my GnuPG key ID is 0x052E7D95 (PGP/MIME preferred) From davem@redhat.com Mon Aug 2 17:09:55 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:10:01 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7309s6o025172 for ; Mon, 2 Aug 2004 17:09:55 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i7309fe1015846; Mon, 2 Aug 2004 20:09:41 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i7309fa28153; Mon, 2 Aug 2004 20:09:41 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i7308vtZ014741; Mon, 2 Aug 2004 20:08:58 -0400 Date: Mon, 2 Aug 2004 17:08:17 -0700 From: "David S. Miller" To: yoshfuji@linux-ipv6.org Cc: suckfish@ihug.co.nz, pekkas@netcore.fi, linux-kernel@vger.kernel.org, yoshfuji@linux-ipv6.org, netdev@oss.sgi.com Subject: Re: [PATCH] Trivial ipv6 fix. Message-Id: <20040802170817.3f9be894.davem@redhat.com> In-Reply-To: <20040802.065940.86004622.yoshfuji@linux-ipv6.org> References: <1091434328.16469.5.camel@localhost.localdomain> <20040802.065940.86004622.yoshfuji@linux-ipv6.org> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by oss.sgi.com id i7309s6o025172 X-archive-position: 7432 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 02 Aug 2004 06:59:40 -0700 (PDT) YOSHIFUJI Hideaki / $B5HF#1QL@(B wrote: > In article <1091434328.16469.5.camel@localhost.localdomain> (at Mon, 02 Aug 2004 20:12:08 +1200), Ralph Loader says: > > > ipv6_addr_hash doesn't do what it's comment says. The comment was > > probably what was intended, not that it'll make much difference in > > practice. > > Oops, David, please apply this. Done, thanks guys. From davem@redhat.com Mon Aug 2 17:11:07 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:11:15 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730B6eu025460 for ; Mon, 2 Aug 2004 17:11:07 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i730Ate1016125; Mon, 2 Aug 2004 20:10:55 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i730Ata28669; Mon, 2 Aug 2004 20:10:55 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i730ABRe015548; Mon, 2 Aug 2004 20:10:11 -0400 Date: Mon, 2 Aug 2004 17:09:30 -0700 From: "David S. Miller" To: Herbert Xu Cc: netdev@oss.sgi.com Subject: Re: [1/2] [IPSEC] Remove unnecessary inet_ecn.h inclusions Message-Id: <20040802170930.2073894f.davem@redhat.com> In-Reply-To: <20040802093153.GA19706@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7433 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 19:31:53 +1000 Herbert Xu wrote: > I should've removed the inet_ecn.h inclusions in that change as the > ECN code has been moved to xfrm[46]_output.c. This patch does exactly > that. Ok, applied. From achirica@telefonica.net Mon Aug 2 17:12:21 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:12:27 -0700 (PDT) Received: from pc22.admin.cnc (194-179-2-161.mad.ttd.net [194.179.2.161]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730CKSx026003 for ; Mon, 2 Aug 2004 17:12:21 -0700 Received: from tudela.mad.ttd.net (tudela.gestion.cnc [172.24.8.233]) by pc22.admin.cnc (8.11.2/8.11.2/SuSE Linux 8.11.1-0.5) with ESMTP id i730CAq05669; Tue, 3 Aug 2004 02:12:10 +0200 Received: from localhost (localhost [127.0.0.1]) by tudela.mad.ttd.net (8.11.6/8.11.6) with ESMTP id i730C9g13773; Tue, 3 Aug 2004 02:12:09 +0200 (MEST) Date: Tue, 3 Aug 2004 02:12:09 +0200 (MEST) From: Javier Achirica X-Sender: To: cc: Jeff Garzik , Subject: Re: [PATCH 2.6] airo.c set_bit bug In-Reply-To: <20040723002114.GA11815@bougret.hpl.hp.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-archive-position: 7434 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: achirica@telefonica.net Precedence: bulk X-list: netdev Thanks. Applied. I haven't found any other occurrence. Javier Achirica On Thu, 22 Jul 2004, Jean Tourrilhes wrote: > Hi Javier, > > Managed to find a bug in the usage of set_bit/clear_bit in the > airo driver. I'm not sure if I caught all occurence of this pattern, > and not sure about exact consequences of the bug, but we might as well > fix it... > Patch below... > > Have fun... > > Jean > > -------------------------------------------------------- > > --- linux/drivers/net/wireless/airo.j1.c Thu Jul 22 15:27:48 2004 > +++ linux/drivers/net/wireless/airo.c Thu Jul 22 15:29:11 2004 > @@ -1808,7 +1808,8 @@ static int writeConfigRid(struct airo_in > if (!test_bit (FLAG_COMMIT, &ai->flags)) > return SUCCESS; > > - clear_bit (FLAG_COMMIT | FLAG_RESET, &ai->flags); > + clear_bit (FLAG_COMMIT, &ai->flags); > + clear_bit (FLAG_RESET, &ai->flags); > checkThrottle(ai); > cfgr = ai->config; > > @@ -6158,7 +6159,8 @@ static int airo_set_txpow(struct net_dev > readCapabilityRid(local, &cap_rid); > > if (vwrq->disabled) { > - set_bit (FLAG_RADIO_OFF | FLAG_COMMIT, &local->flags); > + set_bit (FLAG_RADIO_OFF, &local->flags); > + set_bit (FLAG_COMMIT, &local->flags); > return -EINPROGRESS; /* Call commit handler */ > } > if (vwrq->flags != IW_TXPOW_MWATT) { > From davem@redhat.com Mon Aug 2 17:12:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:13:03 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i730Cw08026236 for ; Mon, 2 Aug 2004 17:12:58 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i730Coe1016484; Mon, 2 Aug 2004 20:12:50 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i730Coa29031; Mon, 2 Aug 2004 20:12:50 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i730C7SI016381; Mon, 2 Aug 2004 20:12:07 -0400 Date: Mon, 2 Aug 2004 17:11:26 -0700 From: "David S. Miller" To: Herbert Xu Cc: netdev@oss.sgi.com Subject: Re: [2/2] [IPSEC] Move xfrm[46]_tunnel_check_size into xfrm[46]_output.c Message-Id: <20040802171126.09dc4887.davem@redhat.com> In-Reply-To: <20040802093500.GA19747@gondor.apana.org.au> References: <20040802093153.GA19706@gondor.apana.org.au> <20040802093500.GA19747@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7435 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 19:35:00 +1000 Herbert Xu wrote: > This patch moves xfrm[46]_tunnel_check_size() into xfrm[46]_output.c > where it can be made static since it's only used there. > > While moving the icmp.h inclusions over I also discovered that the > tunnel files are missing an inclusion of net/protocol.h. So I've > added them as well. The net/xfrm.h hunk failed, but I fixed that up by hand. Applied, thanks. From zdzichu@irc.pl Mon Aug 2 17:15:03 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 17:15:09 -0700 (PDT) Received: from mother.ds.pg.gda.pl (serwer.tvgawex.pl [212.122.214.2]) by oss.sgi.com (8.13.0/8.13.0) with SMTP id i730F1Ct026770 for ; Mon, 2 Aug 2004 17:15:02 -0700 Received: (qmail 8739 invoked by uid 1000); 3 Aug 2004 00:14:59 -0000 Date: Tue, 3 Aug 2004 02:14:59 +0200 From: Tomasz Torcz To: netdev@oss.sgi.com Subject: Re: iproute2 and kernel headers Message-ID: <20040803001459.GA8637@irc.pl> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-2 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> User-Agent: Mutt/1.5.4i X-archive-position: 7436 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: zdzichu@irc.pl Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 03:38:05PM -0700, Stephen Hemminger wrote: > I am willing to put some headers (not all) in with the user level > code, provided they are copies since they I can easily update. I don't want > to get into keeping an edited set of headers in sync. Aren't linux-libc-headers (*) sufficient? * - http://ep09.pld-linux.org/~mmazur/linux-libc-headers/ -- Tomasz Torcz To co nierealne - tutaj jest normalne. zdzichu@irc.-nie.spam-.pl Ziomale na ¿ycie maj± tu patenty specjalne. From jesse.brandeburg@intel.com Mon Aug 2 19:07:50 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:07:57 -0700 (PDT) Received: from fmsfmr003.fm.intel.com (fmr10.intel.com [192.55.52.30]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i7327oIC032489 for ; Mon, 2 Aug 2004 19:07:50 -0700 Received: from petasus.fm.intel.com (petasus.fm.intel.com [10.1.192.37]) by fmsfmr003.fm.intel.com (8.12.9-20030918-01/8.12.9/d: major-outer.mc,v 1.15 2004/01/30 18:16:28 root Exp $) with ESMTP id i73285eH015744 for ; Tue, 3 Aug 2004 02:08:05 GMT Received: from fmsmsxvs043.fm.intel.com (fmsmsxvs043.fm.intel.com [132.233.42.129]) by petasus.fm.intel.com (8.12.9-20030918-01/8.12.9/d: major-inner.mc,v 1.11 2004/07/29 22:51:53 root Exp $) with SMTP id i7327eal012712 for ; Tue, 3 Aug 2004 02:07:40 GMT Received: from Westville2.jf.intel.com ([134.134.3.161]) by fmsmsxvs043.fm.intel.com (SAVSMTP 3.1.2.35) with SMTP id M2004080219074112919 ; Mon, 02 Aug 2004 19:07:41 -0700 Date: Mon, 2 Aug 2004 18:51:21 -0700 (PDT) From: Jesse Brandeburg To: netdev@oss.sgi.com Subject: [PATCH 2.6] ixgb - fix bug in transmit cleanup for ppc64 Message-ID: ReplyTo: "Jesse Brandeburg" MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Scanned-By: MIMEDefang 2.31 (www . roaringpenguin . com / mimedefang) X-archive-position: 7437 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: jesse.brandeburg@intel.com Precedence: bulk X-list: netdev This fixes an endianness error when on PPC64 arch. Signed off by: Jesse Brandeburg diff -Nurp --exclude=CVS linux-2.6.7/drivers/net/ixgb/ixgb_main.c linux-2.6.7_mod/drivers/net/ixgb/ixgb_main.c --- linux-2.6.7/drivers/net/ixgb/ixgb_main.c 2004-06-16 05:19:01.000000000 +0000 +++ linux-2.6.7_mod/drivers/net/ixgb/ixgb_main.c 2004-08-03 01:34:52.000000000 +0000 @@ -1677,7 +1677,7 @@ static boolean_t ixgb_clean_tx_irq(struc eop = tx_ring->buffer_info[i].next_to_watch; eop_desc = IXGB_TX_DESC(*tx_ring, eop); - while (eop_desc->status & cpu_to_le32(IXGB_TX_DESC_STATUS_DD)) { + while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) { for (cleaned = FALSE; !cleaned;) { tx_desc = IXGB_TX_DESC(*tx_ring, i); From davem@redhat.com Mon Aug 2 19:11:00 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:11:06 -0700 (PDT) Received: from mx1.redhat.com (mx1.redhat.com [66.187.233.31]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i732Ax7T000474 for ; Mon, 2 Aug 2004 19:11:00 -0700 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i732Aee1010321; Mon, 2 Aug 2004 22:10:40 -0400 Received: from devserv.devel.redhat.com (devserv.devel.redhat.com [172.16.58.1]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i732Aea22704; Mon, 2 Aug 2004 22:10:40 -0400 Received: from cheetah.davemloft.net (localhost.localdomain [127.0.0.1]) by devserv.devel.redhat.com (8.12.11/8.12.10) with SMTP id i7329uCl008359; Mon, 2 Aug 2004 22:09:56 -0400 Date: Mon, 2 Aug 2004 19:09:14 -0700 From: "David S. Miller" To: Herbert Xu Cc: kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-Id: <20040802190914.303ccfbe.davem@redhat.com> In-Reply-To: <20040802074147.GA16381@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> X-Mailer: Sylpheed version 0.9.12 (GTK+ 1.2.10; sparc-unknown-linux-gnu) X-Face: "_;p5u5aPsO,_Vsx"^v-pEq09'CU4&Dc1$fQExov$62l60cgCc%FnIwD=.UF^a>?5'9Kn[;433QFVV9M..2eN.@4ZWPGbdi<=?[:T>y?SD(R*-3It"Vj:)"dP Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-archive-position: 7438 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: davem@redhat.com Precedence: bulk X-list: netdev On Mon, 2 Aug 2004 17:41:47 +1000 Herbert Xu wrote: > This raises an interesting question. Is it really correct to look at > the first hop address when doing the route lookup? > > The problem is that if we use the first-hop address as the dst when > doing the route lookup then we may end up with incorrect MTU information. > This is because the MTU to the final destination may well be smaller than > the MTU to the first hop. > > It seems that Alexey thought about this six years ago according to > the rthdr comment in icmpv6_rcv(). When the ICMP6 packet comes back in such a case, the type zero routing header will be suitable edited. So at least we can determine which exact destination address the PMTU information applies to. But I understand what the problem is. We cannot update the destination cache entry for destination "D" if the ICMP message is for hop "B" specified in the routing header. Furthermore, we cannot even update a destination cache entry for hop "B" in the case where the routing header specifies --> A --> B --> C --> D because a direct packet destinated for "B" might use a different path than "A" does. An intesting solution would be to use stacked destinations, which do no actual encapsulation (or perhaps do the routing header work) and merely represent the hop-by-hop path. Then the PMTU propagation machinery can be used, and route lookups will go through a slower path to find these special stacked hop-by-hop routes. From scarfboy@gmail.com Mon Aug 2 19:47:54 2004 Received: with ECARTIS (v1.0.0; list netdev); Mon, 02 Aug 2004 19:47:58 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.192]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i732lotV001376 for ; Mon, 2 Aug 2004 19:47:53 -0700 Received: by mproxy.gmail.com with SMTP id 73so143907rnk for ; Mon, 02 Aug 2004 19:47:43 -0700 (PDT) Received: by 10.38.81.50 with SMTP id e50mr138197rnb; Mon, 02 Aug 2004 19:47:43 -0700 (PDT) Message-ID: Date: Tue, 3 Aug 2004 04:47:43 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_102_23147333.1091501263553" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> X-archive-position: 7439 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_102_23147333.1091501263553 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Okay, after I Did Stuff(tm) to my new computer, it's capable of generating approximately 50Kints/s, which transates to 66MB/s in a network benchmark (Actually, netio misreports the speeds, probably because of an overflow; I was amused) There's two howevers and one unfortunately, though. The howevers: - it's not in the direction I want -- meaning I should update, which I can live with. But: - the bench speed going from my old computer wend down from ~33mb to ~20MB/s which I can't make any sense of at all, and the practical speeds from the server didn't change for the better, possibly for the worse. I'm not sure, because of... The unfortunately: - After a few minutes, my old computer kernel paniced. I assume this is because it can't handle the incoming traffic, as its own pace of sending (and therefore probably handling interrupts) is more like 20kints/sec than 50. I couldn't tell anything vmstat-wise as during the data going in that direction (un udp; tcp hung around 17MB both ways - which is better thn before, but *still* short of impressive), the ssh shells just stopped responding, and I guess so did vmstat. It's probably being battered in hardware interrupts, I saw high figures. Quite possibly this has to do with renicing ksoftircq (negatively) as someone suggested. However, I am still of the opinion that a difference in processor speeds should not crash anything. The panic looks a lot like the last one; same kernel (napi still enabled for the 8169). Image attached. I'ld like to know what's wrong here, so that I can avoid it. I can deal and live with stupid speeds better than crashing serves. Makes me grumble less, y'know. --Bart Alewijnse ------=_Part_102_23147333.1091501263553 Content-Type: image/gif; name="panic2.gif" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="panic2.gif" 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 ------=_Part_102_23147333.1091501263553-- From romieu@fr.zoreil.com Tue Aug 3 00:51:48 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 00:51:54 -0700 (PDT) Received: from fr.zoreil.com (electric-eye.fr.zoreil.com [213.41.134.224]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i737pl2a014879 for ; Tue, 3 Aug 2004 00:51:48 -0700 Received: from electric-eye.fr.zoreil.com (localhost.localdomain [127.0.0.1]) by fr.zoreil.com (8.12.8/8.12.1) with ESMTP id i737mhh9005238; Tue, 3 Aug 2004 09:48:43 +0200 Received: (from romieu@localhost) by electric-eye.fr.zoreil.com (8.12.8/8.12.1) id i737mgmS005236; Tue, 3 Aug 2004 09:48:42 +0200 Date: Tue, 3 Aug 2004 09:48:42 +0200 From: Francois Romieu To: Bart Alewijnse Cc: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble Message-ID: <20040803094842.B4911@electric-eye.fr.zoreil.com> References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from scarfboy@gmail.com on Tue, Aug 03, 2004 at 04:47:43AM +0200 X-Organisation: Land of Sunshine Inc. X-archive-position: 7440 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: romieu@fr.zoreil.com Precedence: bulk X-list: netdev Bart Alewijnse : [...] > The panic looks a lot like the last one; same kernel (napi still > enabled for the 8169). Image attached. The irq rate are strangely high for a napi version of the r8169 driver. Can you describe your test commands so that I reproduce these here ? -- Ueimor From yoshfuji@linux-ipv6.org Tue Aug 3 00:55:26 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 00:55:32 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i737tPTO015212 for ; Tue, 3 Aug 2004 00:55:26 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id 2A36333CE5; Tue, 3 Aug 2004 16:55:48 +0900 (JST) Date: Tue, 03 Aug 2004 00:55:42 -0700 (PDT) Message-Id: <20040803.005542.104434029.yoshfuji@linux-ipv6.org> To: davem@redhat.com, shemminger@osdl.org Cc: hadi@znyx.com, netdev@oss.sgi.com, yoshfuji@linux-ipv6.org Subject: Re: iproute2 and kernel headers From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040802160445.5ef3b251.davem@redhat.com> References: <20040802153805.487f832f@dell_ss3.pdx.osdl.net> <20040802160445.5ef3b251.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7441 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040802160445.5ef3b251.davem@redhat.com> (at Mon, 2 Aug 2004 16:04:45 -0700), "David S. Miller" says: > > What headers really seem to change a lot? The obvious ones are: > > > > linux/pkt_sched.h > > linux/tcp_diag.h > > linux/xfrm.h > > I would add linux/rtnetlink.h Then, linux/snmp.h. --yoshfuji From yoshfuji@linux-ipv6.org Tue Aug 3 01:18:56 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 01:19:02 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i738Itpn016068 for ; Tue, 3 Aug 2004 01:18:55 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id DBE1233CE5; Tue, 3 Aug 2004 17:19:17 +0900 (JST) Date: Tue, 03 Aug 2004 01:19:12 -0700 (PDT) Message-Id: <20040803.011912.128392049.yoshfuji@linux-ipv6.org> To: davem@redhat.com Cc: herbert@gondor.apana.org.au, kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru, yoshfuji@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040802190914.303ccfbe.davem@redhat.com> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> <20040802190914.303ccfbe.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7442 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040802190914.303ccfbe.davem@redhat.com> (at Mon, 2 Aug 2004 19:09:14 -0700), "David S. Miller" says: > An intesting solution would be to use stacked destinations, which > do no actual encapsulation (or perhaps do the routing header work) > and merely represent the hop-by-hop path. Then the PMTU propagation > machinery can be used, and route lookups will go through a slower path > to find these special stacked hop-by-hop routes. Well, I think it would probably be another rt6_info{} member rt6i_srcrt (or something like that). --yoshfuji From yoshfuji@linux-ipv6.org Tue Aug 3 01:59:59 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 02:00:05 -0700 (PDT) Received: from yue.st-paulia.net ([203.178.140.15]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i738xw9h017014 for ; Tue, 3 Aug 2004 01:59:59 -0700 Received: from localhost (localhost [127.0.0.1]) by yue.st-paulia.net (Postfix) with ESMTP id 2319533CE5; Tue, 3 Aug 2004 18:00:21 +0900 (JST) Date: Tue, 03 Aug 2004 02:00:15 -0700 (PDT) Message-Id: <20040803.020015.44364045.yoshfuji@linux-ipv6.org> To: davem@redhat.com Cc: kazunori@miyazawa.org, herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, yoshfuji@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup From: YOSHIFUJI Hideaki / =?iso-2022-jp?B?GyRCNUhGIzFRTEAbKEI=?= In-Reply-To: <20040801195135.16734846.davem@redhat.com> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040801195135.16734846.davem@redhat.com> Organization: USAGI Project X-URL: http://www.yoshifuji.org/%7Ehideaki/ X-Fingerprint: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA X-PGP-Key-URL: http://www.yoshifuji.org/%7Ehideaki/hideaki@yoshifuji.org.asc X-Face: "5$Al-.M>NJ%a'@hhZdQm:."qn~PA^gq4o*>iCFToq*bAi#4FRtx}enhuQKz7fNqQz\BYU] $~O_5m-9'}MIs`XGwIEscw;e5b>n"B_?j/AkL~i/MEaZBLP X-Mailer: Mew version 2.2 on Emacs 20.7 / Mule 4.1 (AOI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-archive-position: 7443 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: yoshfuji@linux-ipv6.org Precedence: bulk X-list: netdev In article <20040801195135.16734846.davem@redhat.com> (at Sun, 1 Aug 2004 19:51:35 -0700), "David S. Miller" says: > On Fri, 30 Jul 2004 17:12:05 +0900 > Kazunori Miyazawa wrote: > > > I consider copying flowi(fl_rt) uses too much stack at the moment. > > I'll re-send the fixed patch again. > > I agree, and let's defer this patch until we > resolve that. Is the overhead for allocating memory okay? Or, do we allcoate some per-cpu memory while ipv6.o initalization phase? (check: lock? preemption?) Or, will we allocate fl (and fl_rt) per sock{} (ipv6_pinfo{})? (ditto.) We have similar stack usage in other codes, and I would fix them at the same time. Another question just for future reference: how many bytes (approx.) do we accept on stack? Note: sizeof(struct flowi) is 72 bytes (on i386) --yoshfuji From kazunori@miyazawa.org Tue Aug 3 02:22:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 02:22:20 -0700 (PDT) Received: from miyazawa.org (usen-221x116x13x66.ap-US01.usen.ad.jp [221.116.13.66]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i739M6gR023201 for ; Tue, 3 Aug 2004 02:22:06 -0700 Received: from [IPv6:2001:240:5bf:128:a59f:7c54:52e4:e0e8] ([2001:240:5bf:128:a59f:7c54:52e4:e0e8]) (AUTH: LOGIN kazunori, SSL: TLSv1/SSLv3,128bits,RC4-MD5) by miyazawa.org with esmtp; Tue, 03 Aug 2004 18:20:05 +0900 id 00000C4F.410F58C6.00007301 Message-ID: <410F5906.30402@miyazawa.org> Date: Tue, 03 Aug 2004 18:21:10 +0900 From: Kazunori Miyazawa User-Agent: Mozilla Thunderbird 0.7 (Windows/20040616) X-Accept-Language: en-us, en MIME-Version: 1.0 To: YOSHIFUJI Hideaki CC: davem@redhat.com, herbert@gondor.apana.org.au, netdev@oss.sgi.com, usagi-core@linux-ipv6.org Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040801195135.16734846.davem@redhat.com> <20040803.020015.44364045.yoshfuji@linux-ipv6.org> In-Reply-To: <20040803.020015.44364045.yoshfuji@linux-ipv6.org> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-archive-position: 7444 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: kazunori@miyazawa.org Precedence: bulk X-list: netdev YOSHIFUJI Hideaki wrote: > In article <20040801195135.16734846.davem@redhat.com> (at Sun, 1 Aug 2004 19:51:35 -0700), "David S. Miller" says: > > >>On Fri, 30 Jul 2004 17:12:05 +0900 >>Kazunori Miyazawa wrote: >> >> >>>I consider copying flowi(fl_rt) uses too much stack at the moment. >>>I'll re-send the fixed patch again. >> >>I agree, and let's defer this patch until we >>resolve that. > > > Is the overhead for allocating memory okay? > Or, do we allcoate some per-cpu memory while ipv6.o initalization phase? > (check: lock? preemption?) > Or, will we allocate fl (and fl_rt) per sock{} (ipv6_pinfo{})? > (ditto.) > My intention is not high art, just using struct in6_addr instead of struct flowi to store final destination. > We have similar stack usage in other codes, and > I would fix them at the same time. > These might be my changes. I will fix them. > > Another question just for future reference: > how many bytes (approx.) do we accept on stack? > > Note: sizeof(struct flowi) is 72 bytes (on i386) > > --yoshfuji --Kazunori Miyazawa From herbert@gondor.apana.org.au Tue Aug 3 03:55:44 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 03:55:52 -0700 (PDT) Received: from arnor.apana.org.au (mail@arnor.apana.org.au [203.14.152.115]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73Atgsj016097 for ; Tue, 3 Aug 2004 03:55:44 -0700 Received: from gondolin.me.apana.org.au ([192.168.0.6] ident=mail) by arnor.apana.org.au with esmtp (Exim 3.35 #1 (Debian)) id 1Brwx3-0005cn-00; Tue, 03 Aug 2004 20:55:25 +1000 Received: from herbert by gondolin.me.apana.org.au with local (Exim 3.36 #1 (Debian)) id 1Brwwy-0007ZY-00; Tue, 03 Aug 2004 20:55:20 +1000 Date: Tue, 3 Aug 2004 20:55:20 +1000 To: "David S. Miller" Cc: kazunori@miyazawa.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org, kuznet@ms2.inr.ac.ru Subject: Re: [PATCH][IPv6] separation xfrm_lookup from ip6_dst_lookup Message-ID: <20040803105520.GA29077@gondor.apana.org.au> References: <20040730171205.114f22ba.kazunori@miyazawa.org> <20040802074147.GA16381@gondor.apana.org.au> <20040802190914.303ccfbe.davem@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040802190914.303ccfbe.davem@redhat.com> User-Agent: Mutt/1.5.6+20040523i From: Herbert Xu X-archive-position: 7445 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: herbert@gondor.apana.org.au Precedence: bulk X-list: netdev On Mon, Aug 02, 2004 at 07:09:14PM -0700, David S. Miller wrote: > > An intesting solution would be to use stacked destinations, which > do no actual encapsulation (or perhaps do the routing header work) > and merely represent the hop-by-hop path. Then the PMTU propagation > machinery can be used, and route lookups will go through a slower path > to find these special stacked hop-by-hop routes. Yes that's brilliant. We can replace the current rt dst with an rthdr dst + an rt dst. The rt dst will be the same one pointing to the first hop. The rthdr will contain MTU information for that exact path. This will work since any ICMP messages we receive due to MTU issues must carry the entire IP header including the rthdr (or in the case of IPv4 the ?SR option). We can then attribute that MTU to the rthdr dst. The rthdr can even add the option/extension header as a transform. Thanks, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt From ptsjohol@cc.jyu.fi Tue Aug 3 05:33:06 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 05:33:14 -0700 (PDT) Received: from posti6.jyu.fi (posti6.jyu.fi [130.234.4.43]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73CWjVf027633 for ; Tue, 3 Aug 2004 05:33:06 -0700 Received: from silmu.st.jyu.fi (IDENT:i+l7SQ6073MYpVQbfBUEyZ6AO77O2o0J@silmu.st.jyu.fi [130.234.4.64]) by posti6.jyu.fi (8.12.8/8.12.8/antispam) with ESMTP id i73CWIob027197; Tue, 3 Aug 2004 15:32:18 +0300 Date: Tue, 3 Aug 2004 15:32:15 +0300 (EEST) From: Pasi Sjoholm X-X-Sender: ptsjohol@silmu.st.jyu.fi To: Francois Romieu cc: Robert Olsson , H?ctor Mart?n , Linux-Kernel , , , , Subject: Re: ksoftirqd uses 99% CPU triggered by network traffic (maybe RLT-8139 related) In-Reply-To: <20040803003515.A29885@electric-eye.fr.zoreil.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=iso-8859-1 Content-Transfer-Encoding: 8BIT X-Virus-Scanned: by amavisd-milter (http://www.amavis.org/) at posti6.jyu.fi; Tue, 03 Aug 2004 15:32:21 +0300 X-archive-position: 7447 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: ptsjohol@cc.jyu.fi Precedence: bulk X-list: netdev On Tue, 3 Aug 2004, Francois Romieu wrote: > I have made a few changes. Please enable the DEBUG option and set msglvl > to its maximal value via ethtool. You may test the patches separately if > you find some time but the log once both r8139-10.patch and r8139-20.patch > are applied would be enough. The full logfiles can be downloaded from: http://www.cc.jyu.fi/~ptsjohol/syslog1.gz http://www.cc.jyu.fi/~ptsjohol/syslog2.gz The first log file is with both patchs applied and the second one with one little change to rx8139_rx() to show if it even goes to through " while (netif_running(dev) && received < budget && (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {"-section. This was the change which I made.. so you can see in the second log file that there won't be any of these messages after the driver has crashed. /* if (netif_msg_rx_status(tp))*/ printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x," " cur %4.4x.\n", dev->name, rx_status, rx_size, cur_rx); For the first logfile the exact crash time is "13:02:22" and the for the second one it is "14:54:49". > If the log fills too fast, you may comment out any message which does > not belong to rtl8139_rx(). I took out those "exiting with interrupt"-messages. -- Pasi Sjöholm From scarfboy@gmail.com Tue Aug 3 05:32:37 2004 Received: with ECARTIS (v1.0.0; list netdev); Tue, 03 Aug 2004 05:32:44 -0700 (PDT) Received: from mproxy.gmail.com (rproxy.gmail.com [64.233.170.202]) by oss.sgi.com (8.13.0/8.13.0) with ESMTP id i73CWGTN027626 for ; Tue, 3 Aug 2004 05:32:37 -0700 Received: by mproxy.gmail.com with SMTP id 73so153437rnk for ; Tue, 03 Aug 2004 05:32:07 -0700 (PDT) Received: by 10.38.81.50 with SMTP id e50mr258492rnb; Tue, 03 Aug 2004 05:32:07 -0700 (PDT) Message-ID: Date: Tue, 3 Aug 2004 14:32:07 +0200 From: Bart Alewijnse To: netdev@oss.sgi.com, linux-kernel@vger.kernel.org Subject: Re: gigabit trouble In-Reply-To: <20040803094842.B4911@electric-eye.fr.zoreil.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_9_19135111.1091536327656" References: <20040729210401.A32456@electric-eye.fr.zoreil.com> <20040730205412.A15669@electric-eye.fr.zoreil.com> <20040730234120.A15536@electric-eye.fr.zoreil.com> <20040731231836.A31121@electric-eye.fr.zoreil.com> <20040803094842.B4911@electric-eye.fr.zoreil.com> X-archive-position: 7446 X-ecartis-version: Ecartis v1.0.0 Sender: netdev-bounce@oss.sgi.com Errors-to: netdev-bounce@oss.sgi.com X-original-sender: scarfboy@gmail.com Precedence: bulk X-list: netdev ------=_Part_9_19135111.1091536327656 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Quite simply a 'netio -s' on one computer, and a 'netio -u 192.168.1.whichever' on the other. I was monitoring with 'vmstat 1' for hardware stuff and bmon to see the actual speed and had a ssh open. The things I've been fiddling with recently to see if it'd make a difference: - Renicing of ksoftirqc to anything between -5 and -17, I don't remember exactly. - Disabling tcp window scaling. I read somewhere that that may help throughhput, but it may be a stupid move. - Some barely thought about (I did read the following: http://lists.samba.org/archive/samba/2003-December/077198.html) window memory buffer size changes, with a 'so that that at least won't be a bottleneck' angle: -------------------- echo 400000 > /proc/sys/net/core/wmem_default echo 512000 > /proc/sys/net/core/wmem_max echo 400000 > /proc/sys/net/core/rmem_default echo 512000 > /proc/sys/net/core/rmem_max echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_mem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_wmem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_rmem echo 98304 512000 640000 > /proc/sys/net/ipv4/tcp_mem ----------- It seems that windows (in which I have jumbo frames on) doesn' quite need as many interrupts, although I'm not sure that was for the same speed, as I had another kernel panic (attached, this one has a small visible trace). I was running the windows version of netio as a server, and doing a client test with udp. --Bart Alewijnse ------=_Part_9_19135111.1091536327656 Content-Type: image/gif; name="panic3.gif" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="panic3.gif" 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