* Audio Dirver for the 403/405?
From: bert_maxel @ 2007-05-30 21:44 UTC (permalink / raw)
To: linuxppc-embedded
Hi all,
Has anybody got some working audio driver (linux) for the ML403/405 ?
I know it's an ac97 codec, but I can't find anything related to the xilinx
boards?
If nobody has worked on this yet, I'm in trouble. I don't know where to
start, or from what ac97 driver should I base my initial development?
Any suggestion is much appreciated.
Thanks
--
View this message in context: http://www.nabble.com/Audio-Dirver-for-the-403-405--tf3843165.html#a10883262
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* sys_futex
From: Charles Krinke @ 2007-05-30 21:53 UTC (permalink / raw)
To: Linux PPC; +Cc: Kevin Smith
In-Reply-To: <fa686aa40705291125m2096b198yba60c38f048c1cbb@mail.gmail.com>
This is a user space application to kernel interface question. We are
using linux-2.6.17.11 in our design and have two boards. One 8241 and
one 8541.
In user space, we need to use the system call "sys_futex", but when the
user space application is compiled we have an unresolved linkage error.
Can someone offer a suggestion on the care and feeding of "sys_futex" in
a ppc 8241/8541 environment.
Thanks.
^ permalink raw reply
* Re: [PATCH 2/5] Add uli1575 pci-bridge sector to MPC8641HPCN dts file.
From: Wade Farnsworth @ 2007-05-30 22:26 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <17B6534B-3C1C-433D-8875-1C2255E79D98@kernel.crashing.org>
This adds device nodes for the PCI bridges as well as the ISA devices on
the newer revision MPC8641HPCN. It also adds the PCI ranges to the soc
node so that address translation for the ISA devices works properly.
Signed-off-by: Wade Farnsworth <wfarnsworth@mvista.com>
---
Here's the merged patch.
I've updated the ISA nodes somewhat according to the comments the
original patch received.
I also took the liberty of fixing the addresses of the pci bridges and
removing the unused "uli1575:" label.
arch/powerpc/boot/dts/mpc8641_hpcn.dts | 89 +++++++++++++++++++----
1 file changed, 77 insertions(+), 12 deletions(-)
Index: linux-2.6-powerpc-8641/arch/powerpc/boot/dts/mpc8641_hpcn.dts
===================================================================
--- linux-2.6-powerpc-8641.orig/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ linux-2.6-powerpc-8641/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -56,7 +56,11 @@
#size-cells = <1>;
#interrupt-cells = <2>;
device_type = "soc";
- ranges = <0 f8000000 00100000>;
+ ranges = <00000000 f8000000 00100000
+ 80000000 80000000 20000000
+ e2000000 e2000000 00100000
+ a0000000 a0000000 20000000
+ e3000000 e3000000 00100000>;
reg = <f8000000 00100000>; // CCSRBAR 1M
bus-frequency = <0>;
@@ -285,17 +289,78 @@
f800 0 0 3 &i8259 0 0
f800 0 0 4 &i8259 0 0
>;
- i8259: i8259@4d0 {
- clock-frequency = <0>;
- interrupt-controller;
- device_type = "interrupt-controller";
- #address-cells = <0>;
- #interrupt-cells = <2>;
- built-in;
- compatible = "chrp,iic";
- big-endian;
- interrupts = <49 2>;
- interrupt-parent = <&mpic>;
+ uli1575@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <02000000 0 80000000
+ 02000000 0 80000000
+ 0 20000000
+ 01000000 0 00000000
+ 01000000 0 00000000
+ 0 00100000>;
+
+ pci_bridge@0 {
+ reg = <0 0 0 0 0>;
+ #size-cells = <2>;
+ #address-cells = <3>;
+ ranges = <02000000 0 80000000
+ 02000000 0 80000000
+ 0 20000000
+ 01000000 0 00000000
+ 01000000 0 00000000
+ 0 00100000>;
+
+ isa@1e {
+ device_type = "isa";
+ #interrupt-cells = <2>;
+ #size-cells = <1>;
+ #address-cells = <2>;
+ reg = <f000 0 0 0 0>;
+ ranges = <1 0 01000000 0 0
+ 00001000>;
+ interrupt-parent = <&i8259>;
+
+ i8042@60 {
+ reg = <1 60 1 1 64 1>;
+ interrupts = <1 3 c 3>;
+ interrupt-parent =
+ <&i8259>;
+
+ keyboard@0 {
+ compatible = "pnpPNP,303";
+ };
+
+ mouse@1 {
+ compatible = "pnpPNP,f03";
+ };
+ };
+
+ rtc@70 {
+ compatible =
+ "pnpPNP,b00";
+ reg = <1 70 2>;
+ };
+
+ gpio@400 {
+ reg = <1 400 80>;
+ };
+
+ i8259: i8259@4d0 {
+ clock-frequency = <0>;
+ interrupt-controller;
+ device_type = "interrupt-controller";
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ built-in;
+ compatible = "chrp,iic";
+ big-endian;
+ interrupts = <49 2>;
+ interrupt-parent =
+ <&mpic>;
+ };
+ };
+ };
};
};
^ permalink raw reply
* Re: Audio Dirver for the 403/405?
From: Grant Likely @ 2007-05-30 23:10 UTC (permalink / raw)
To: bert_maxel; +Cc: linuxppc-embedded
In-Reply-To: <10883262.post@talk.nabble.com>
On 5/30/07, bert_maxel <bonlutin@hotmail.com> wrote:
>
> Hi all,
>
> Has anybody got some working audio driver (linux) for the ML403/405 ?
> I know it's an ac97 codec, but I can't find anything related to the xilinx
> boards?
> If nobody has worked on this yet, I'm in trouble. I don't know where to
> start, or from what ac97 driver should I base my initial development?
IIRC, the old mvista 2.4 tree has an audio driver.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195
^ permalink raw reply
* Re: Consolidate cuboot initialization code
From: David Gibson @ 2007-05-31 1:33 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <465D9672.9060100@freescale.com>
On Wed, May 30, 2007 at 10:21:22AM -0500, Scott Wood wrote:
> David Gibson wrote:
> > On Wed, May 30, 2007 at 10:09:11AM -0500, Scott Wood wrote:
> >>Is there any particular reason to not just do a direct call to
> >>cuboot_init, and move the memcpy and end-of-ram calculation there? I'd
> >>rather avoid macros if possible.
> >
> > Uh.. yeah.. because cuboot_init() doesn't know the size to memcpy(),
> > because it doesn't have the right bd_t definition.
>
> Ah, yes. Don't mind me, it's still morning here... :-P
>
> We could probably do away with the copy altogether, though, as u-boot
> puts the bd_t near the stack, which is exempted from the bootwrapper's
> heap with the 1MiB exclusion.
Possibly, though the copy is safer. I'm hoping to be able to merge
libfdt in a few weeks, which with luck will let me get rid of malloc()
entirely. I'll think about revisiting this then.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* Re: Fix problems with Holly's DT representation of ethernet PHYs
From: David Gibson @ 2007-05-30 11:32 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: linuxppc-dev list, Paul Mackerras, Alexandre Bounine
In-Reply-To: <1180523835.19517.245.camel@localhost.localdomain>
On Wed, May 30, 2007 at 09:17:15PM +1000, Benjamin Herrenschmidt wrote:
> On Tue, 2007-05-29 at 14:29 -0500, Josh Boyer wrote:
> >
> > *shrug* Either way works for me.
> >
> > We're adding these compatible properties to DTS files and the drivers
> > at
> > the same time. Unless (until?) there are firmwares for these boards
> > that start specifying something else in a real device tree, it really
> > doesn't matter much. Not that there's anything wrong with your
> > reasoning. Just seems like we're trying really hard to define
> > something
> > "correctly" when we control what's on both sides :).
> >
>
> I do think Segher is right there... compatible 109 and then 108
That's what I've done in the new patch.
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
^ permalink raw reply
* RE: [PATCH 5/5] Set IDE in ULI1575 to not native mode.
From: Zhang Wei-r63237 @ 2007-05-31 2:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, paulus
In-Reply-To: <1180525258.19517.261.camel@localhost.localdomain>
Hi, Ben,
I agree with your comments -- 'Native mode should generally work
better'.
In 100% native mode, the driver will get irq itself. So we need this
patch.
Thanks!
Wei.
>=20
> Sorry, I didn't understand... care to explain in more details ?
>=20
> Ben.
>=20
>=20
>=20
^ permalink raw reply
* Re: [PATCH v2]: Fix e500 v2 core reboot bug
From: Zang Roy-r61911 @ 2007-05-31 2:38 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <19325B38-202C-4837-9BE8-0ACA482F2605@kernel.crashing.org>
On Wed, 2007-05-30 at 20:25, Kumar Gala wrote:
> On May 30, 2007, at 12:46 AM, Zang Roy-r61911 wrote:
>
> > On Wed, 2007-05-30 at 10:40, Kumar Gala wrote:
> >> On May 29, 2007, at 9:34 PM, Zang Roy-r61911 wrote:
> >>
> >>> On Wed, 2007-05-30 at 03:29, Kumar Gala wrote:
> >>>> On May 28, 2007, at 9:36 PM, Zang Roy-r61911 wrote:
> >>>>
> >>>>> Fix the e500 v2 core reset bug.
> >>>>> For e500 v2 core, a new reset control register is added to
> >>>>> reset the core.
> >>>>> On 85xx CDS board with e500 v2 core, normal reboot code will
> >>>>> induce DDR block in u-boot. This patch fixes this bug. It is
> >>>>> also tested on legacy e500 v1 core.
> >>>>
> >>>> what happens on an e500 based 85xx system?
> >>>
> >>> Without this patch on MPC8548CDS board, after key in "reboot"
> >> command,
> >>> the u-boot will hang at DDR init. See the following log without
> this
> >>> patch:
> >>
> >> Sorry I meant what happens on a e500 v1 based 85xx system w/this
> >> patch.
> >
> > E500 V1 core can boot up normally with/without this patch. Such as
> > 8555CDS system.
>
> Sure, but what happens when you reboot on e500v1 based part?
Sorry, Maybe I do not understand clearly.
The u-boot boot up correctly, when I reboot on a e500v1 based part.
This patch do not affect the e500v1 core boot up. Current code is enough
for e500v1 core. While for E500 v2 core, the u-boot will block without
this patch as I posted before.
Is it clear?
>
> [snip]
>
> >>>> I'm not terrible happy with blindly writing to rstcr.
> >>>>
> >>> I can understand you.
> >>> But I jut want to make things simple and workable.
> >>> Any idea?
> >>
> >> one idea would be for us to add a property on the soc node.
> >> Something like has-rstcr or something similar in a guts node?
> > I have seen your suggestion before to add a property in device tree.
> > But I still think the current implementation is simple.
>
> While it simple you are depending on the fact that a given
> implementation may or may not have something at the particular
> offset. Who knows if 8599 or some future part could put the 'cause
> my part to smoke and self-destruct' at the same offset in the future
> :)
I do not know the future, but I think the 85xx processor should have a
compatible register define. I do not think the future 85xx processor
will use this offset for other usage. It will cause big confusion.
If you study the road map of 85xx processor register define, you can see
that next generation processors only use reserved offset for expanded
usage.
>
> > Anyway, I can try your suggestion.
>
> I'm thinking have a guts block and putting a property in it makes the
> most sense.
>
> - k
>
^ permalink raw reply
* Re: [PATCH v2]: Fix e500 v2 core reboot bug
From: Zang Roy-r61911 @ 2007-05-31 3:40 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <976AFF56-7590-46B9-ADCA-4FA6673D4C9B@kernel.crashing.org>
On Wed, 2007-05-30 at 21:49, Kumar Gala wrote:
> >>>>> I'm not terrible happy with blindly writing to rstcr.
> >>>>>
> >>>> I can understand you.
> >>>> But I jut want to make things simple and workable.
> >>>> Any idea?
> >>>
> >>> one idea would be for us to add a property on the soc node.
> >>> Something like has-rstcr or something similar in a guts node?
> >> I have seen your suggestion before to add a property in device
> tree.
> >> But I still think the current implementation is simple.
> >
> > While it simple you are depending on the fact that a given
> > implementation may or may not have something at the particular
> > offset. Who knows if 8599 or some future part could put the 'cause
> > my part to smoke and self-destruct' at the same offset in the
> > future :)
> >
> >> Anyway, I can try your suggestion.
> >
> > I'm thinking have a guts block and putting a property in it makes
> the
> > most sense.
>
> After some discussion on IRC I think the following is the suggested
> node we should add in.
>
> guts@e00000 {
> compatible = "fsl,mpc8548-guts";
> reg = <e00000 1000>;
> fsl,has-rstcr;
> };
Great!
Roy
^ permalink raw reply
* Re: [PATCH v2]: Fix e500 v2 core reboot bug
From: Zang Roy-r61911 @ 2007-05-31 5:32 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <e868acb03f9976b619eac6b988a10144@kernel.crashing.org>
On Wed, 2007-05-30 at 23:21, Segher Boessenkool wrote:
> >> I'm thinking have a guts block and putting a property in it makes
> the
> >> most sense.
> >
> > After some discussion on IRC I think the following is the suggested
> > node we should add in.
> >
> > guts@e00000 {
> > compatible = "fsl,mpc8548-guts";
> > reg = <e00000 1000>;
> > fsl,has-rstcr;
> > };
>
> Except you shouldn't call it "guts".
guts has a confused meaning :-)
How about
gub: global utility block
or
guf: global utility feature
?
Any other idea?
Roy
^ permalink raw reply
* Re: Saving to 32 bits of GPRs in signal context
From: Benjamin Herrenschmidt @ 2007-05-31 5:39 UTC (permalink / raw)
To: Felix Domke; +Cc: linuxppc-dev list
In-Reply-To: <465D68E5.7000005@elitedvb.net>
On Wed, 2007-05-30 at 14:07 +0200, Felix Domke wrote:
>
> If you don't provide a real, portable, useful way *now* for detecting
> compatibility with 64bit insn, people (=ffmpeg, mplayer first) *will*
> invent their own way of detecting it, possibly using SIGILL, faster
> than
> you could imagine.
I'm pretty sure I had the feature bits before mplayer did altivec, but
then, nobody cares about the feature bits because they exist only on
linux.
There is no portable way to do these things and there won't be because
apple doesn't care what linux does and glibc people don't care about
what apple do etc...
> Please avoid that this time. And please declare the use of SIGILL for
> detecting extensions as plainly wrong, not as a "bad workaround, but
> still better than what's available". If you can't be sure that an
> extension will work as expected (for example because there is just no
> interface to query the OS for it), then simply don't use it. If this
> is
> going to be a performance problem, bug the kernel people to fix it.
>
> (Sorry, this is the point of view of myself a pure *user*. I don't
> want
> to debug crashing programs with incorrect memcpy results because some
> program decided on its own that it's safe to use this extension when
> it
> wasn't.)
Unfortunately, we can't just "declare" things and have people follow
us :-)
Ben.
^ permalink raw reply
* Re: [PATCH v2]: Fix e500 v2 core reboot bug
From: Benjamin Herrenschmidt @ 2007-05-31 5:52 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: linuxppc-dev list, Paul Mackerras
In-Reply-To: <e868acb03f9976b619eac6b988a10144@kernel.crashing.org>
On Wed, 2007-05-30 at 17:21 +0200, Segher Boessenkool wrote:
> >> I'm thinking have a guts block and putting a property in it makes the
> >> most sense.
> >
> > After some discussion on IRC I think the following is the suggested
> > node we should add in.
> >
> > guts@e00000 {
> > compatible = "fsl,mpc8548-guts";
> > reg = <e00000 1000>;
> > fsl,has-rstcr;
> > };
>
> Except you shouldn't call it "guts".
You prefer "bowels" ? :-)
Ben.
^ permalink raw reply
* RE: Fix problems with Holly's DT representation of ethernet PHYs
From: Zang Roy-r61911 @ 2007-05-31 5:54 UTC (permalink / raw)
To: Josh Boyer, Segher Boessenkool
Cc: linuxppc-dev list, Alexandre Bounine, Paul Mackerras,
David Gibson
In-Reply-To: <1180466979.3360.69.camel@zod.rchland.ibm.com>
>=20
> On Tue, 2007-05-29 at 16:49 +0200, Segher Boessenkool wrote:
> > >>> + compatible =3D "tsi-mdio";
> > >>
> > >> Hrm, did I miss this before? A more exact "compatible"
> > >> property would be better ("tsi109-mdio" "tsi108-mdio" or
> > >> something like that).
> > >
> > > If we must, then tsi108-mdio is what I would recommend. =20
> They are the
> > > same between 108, 109, and 110 as far as I know, so it's=20
> the lowest
> > > common denominator.
> >=20
> > [Assuming what is really on the board is a tsi109...]
>=20
> For Holly, yes. For Taiga, it's 108. For Hackberry, it's 110.
For Taiga, it's 108 or 109.
The new manufactured taiga board with 109 chip!
Roy
^ permalink raw reply
* RE: [PATCH 3/3] Modified quirk_mpc8641_transparent() to initializebridge resources.
From: Zang Roy-r61911 @ 2007-05-31 6:48 UTC (permalink / raw)
To: Kumar Gala, Loeliger Jon-LOELIGER; +Cc: linuxppc-dev
In-Reply-To: <F962B8B4-32C0-46A6-B808-C18211353FCC@kernel.crashing.org>
>=20
> On May 29, 2007, at 1:23 PM, Jon Loeliger wrote:
>=20
> > From: Jon Loeliger <jdl@freescale.com>
> >
> > The 8641 RC poses as a transparent bridge, but does not=20
> implement the
> > IO_BASE or IO_LIMIT registers in the config space. This means that
> > the code which initializes the bridge resources ends up setting the
> > IO resources erroneously.
> >
> > This change initializes the RC bridge resources from the=20
> device tree.
> >
> > Signed-off-by: Andy Fleming <afleming@freescale.com>
> > Signed-off-by: Jon Loeliger <jdl@freescale.com>
>=20
> Can this be merged with Zhang's "Set RC of mpc8641 to transparent =20
> bridge for transfer legacy I/O access." patch since it pretty much =20
> supersedes it.
I should be!=20
But why apply them sperately?=20
They refect differnet content and stage. For end user, they will only
see the unified code :-).
Roy
^ permalink raw reply
* Re: [PATCH 1/3] Let subordinate transparent bridges be transparent.
From: Zang Roy-r61911 @ 2007-05-31 6:53 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev list
In-Reply-To: <1180462974.13106.61.camel@ld0161-tx32>
On Wed, 2007-05-30 at 02:22, Jon Loeliger wrote:
> From: York Sun <yorksun@freescale.com>
>
> In pcibios_fixup_bus(), bridges that are subordinate
> to transparent bridges were still relocating their
> IORESOURCE_IO start and end values.
>
> Fix this by preventing the transparent bridge from
> relocating the start and end values, thus allowing the
> subordinate non-transparent bridge full molestation rights.
>
> Signed-off-by: York Sun <yorksun@freescale.com>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>
> ---
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
^ permalink raw reply
* Re: [PATCH 2/3] Export of_bus_pci_get_flags().
From: Zang Roy-r61911 @ 2007-05-31 6:54 UTC (permalink / raw)
To: Jon Loeliger; +Cc: linuxppc-dev list
In-Reply-To: <1180462985.13106.63.camel@ld0161-tx32>
On Wed, 2007-05-30 at 02:23, Jon Loeliger wrote:
> From: Jon Loeliger <jdl@freescale.com>
>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
> Signed-off-by: Jon Loeliger <jdl@freescale.com>
> ---
> arch/powerpc/kernel/prom_parse.c | 2 +-
> include/asm-powerpc/prom.h | 1 +
> 2 files changed, 2 insertions(+), 1 deletions(-)
Acked-by: Roy Zang <tie-fei.zang@freescale.com>
^ permalink raw reply
* Re: Audio Dirver for the 403/405?
From: Andrei Konovalov @ 2007-05-31 7:45 UTC (permalink / raw)
To: Grant Likely; +Cc: bert_maxel, linuxppc-embedded
In-Reply-To: <fa686aa40705301610q6ba8f2abq482f43a89f44d1bc@mail.gmail.com>
Grant Likely wrote:
> On 5/30/07, bert_maxel <bonlutin@hotmail.com> wrote:
>> Hi all,
>>
>> Has anybody got some working audio driver (linux) for the ML403/405 ?
>> I know it's an ac97 codec, but I can't find anything related to the xilinx
>> boards?
>> If nobody has worked on this yet, I'm in trouble. I don't know where to
>> start, or from what ac97 driver should I base my initial development?
>
> IIRC, the old mvista 2.4 tree has an audio driver.
>
> g.
>
I am afraid it doesn't...
Thanks,
Andrei
^ permalink raw reply
* [PATCH] of_serial: ignore unknown serial port
From: Ishizaki Kou @ 2007-05-31 9:30 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev, arnd
Current of_serial driver assumes unknown serial port to be 8250. But
this behavior may cause fatal problems when the serial port is not
8250. This patch corrects probe routine to ignore unknown serial port.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Cc: Arnd Bergmann <arnd@arndb.de>
---
Index: linux-powerpc-git/drivers/serial/of_serial.c
===================================================================
--- linux-powerpc-git.orig/drivers/serial/of_serial.c
+++ linux-powerpc-git/drivers/serial/of_serial.c
@@ -75,15 +75,13 @@ static int __devinit of_platform_serial_
goto out;
switch (port_type) {
- case PORT_UNKNOWN:
- dev_info(&ofdev->dev, "Unknown serial port found, "
- "attempting to use 8250 driver\n");
- /* fallthrough */
case PORT_8250 ... PORT_MAX_8250:
ret = serial8250_register_port(&port);
break;
default:
/* need to add code for these */
+ case PORT_UNKNOWN:
+ dev_info(&ofdev->dev, "Unknown serial port found, ignored\n");
ret = -ENODEV;
break;
}
^ permalink raw reply
* [PATCH] of_serial: add port type checking
From: Ishizaki Kou @ 2007-05-31 9:33 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev, arnd
Currently, of_serial driver supports only 8250 compatible ports, but
prepares that others can easily be added. Yet unregister routine
assumes port is 8250. This patch corrects unregister routine to check
port type.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Cc: Arnd Bergmann <arnd@arndb.de>
---
Index: linux-powerpc-git/drivers/serial/of_serial.c
===================================================================
--- linux-powerpc-git.orig/drivers/serial/of_serial.c
+++ linux-powerpc-git/drivers/serial/of_serial.c
@@ -17,6 +17,11 @@
#include <asm/of_platform.h>
#include <asm/prom.h>
+struct of_serial_info {
+ int type;
+ int line;
+};
+
/*
* Fill a struct uart_port for a given device node
*/
@@ -62,6 +67,7 @@ static int __devinit of_platform_serial_
static int __devinit of_platform_serial_probe(struct of_device *ofdev,
const struct of_device_id *id)
{
+ struct of_serial_info *info;
struct uart_port port;
int port_type;
int ret;
@@ -69,6 +75,10 @@ static int __devinit of_platform_serial_
if (of_find_property(ofdev->node, "used-by-rtas", NULL))
return -EBUSY;
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (info == NULL)
+ return -ENOMEM;
+
port_type = (unsigned long)id->data;
ret = of_platform_serial_setup(ofdev, port_type, &port);
if (ret)
@@ -88,9 +98,12 @@ static int __devinit of_platform_serial_
if (ret < 0)
goto out;
- ofdev->dev.driver_data = (void *)(unsigned long)ret;
+ info->type = port_type;
+ info->line = ret;
+ ofdev->dev.driver_data = info;
return 0;
out:
+ kfree(info);
irq_dispose_mapping(port.irq);
return ret;
}
@@ -100,8 +113,16 @@ out:
*/
static int of_platform_serial_remove(struct of_device *ofdev)
{
- int line = (unsigned long)ofdev->dev.driver_data;
- serial8250_unregister_port(line);
+ struct of_serial_info *info = ofdev->dev.driver_data;
+ switch (info->type) {
+ case PORT_8250 ... PORT_MAX_8250:
+ serial8250_unregister_port(info->line);
+ break;
+ default:
+ /* need to add code for these */
+ break;
+ }
+ kfree(info);
return 0;
}
^ permalink raw reply
* Xilinx ethernet EMAC and bad checksum?
From: Guillaume Berthelom @ 2007-05-31 10:06 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
I am trying to use the Xilinx ethernet EMAC drivers on my board with a
2.6.20 linux kernel.
I have used the adapter.c file from the EDK 8.2 and changed some functions
to adapte it for the 2.6 kernel, on the same way like Grant Likely did in
his TEMAC patch.
The ping and DHCP client work fine as same as the TCP handshake, so the
connexion is established fine. But when the frame (TCP or UDP) send by my
board need a checksum, this checksum failed and the server don't respond me.
I'm using the plb_ethernet IP in FIFO mode.
So if you could give me some way where might be the issue, I'll really
appreciate...
Thanks,
Guillaume Berthelom
--
View this message in context: http://www.nabble.com/Xilinx-ethernet-EMAC-and-bad-checksum--tf3845670.html#a10890962
Sent from the linuxppc-embedded mailing list archive at Nabble.com.
^ permalink raw reply
* [PATCH] [ppc] fix mot_info section
From: Meelis Roos @ 2007-05-31 10:09 UTC (permalink / raw)
To: linuxppc-dev
(resend to linuxppc-dev)
The following patch makes mot_info __initdata since it is used only in
__init functions. prep_pci.c change has been tested in real life on
Motorola Powerstack II (compiles without modpost warnings and boots
fine), pplus.c has not been tested but seems similar.
Signed-off-by: Meelis Roos <mroos@linux.ee>
diff --git a/arch/ppc/platforms/pplus.c b/arch/ppc/platforms/pplus.c
index 8a1788c..c569962 100644
--- a/arch/ppc/platforms/pplus.c
+++ b/arch/ppc/platforms/pplus.c
@@ -256,7 +256,7 @@ struct brd_info {
const char *name;
int (*map_irq) (struct pci_dev *, unsigned char, unsigned char);
};
-struct brd_info mot_info[] = {
+struct brd_info mot_info[] __initdata = {
{0x300, 0x00, 0x00, "MVME 2400", Genesis2_map_irq},
{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)", mesquite_map_irq},
{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)", sitka_map_irq},
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index 1df3150..d8c4e28 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -803,7 +803,7 @@ struct mot_info {
void (*map_non0_bus)(struct pci_dev *); /* For boards with more than bus 0 devices. */
struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
unsigned char secondary_bridge_devfn; /* devfn of secondary bus transparent bridge */
-} mot_info[] = {
+} mot_info[] __initdata = {
{0x300, 0x00, 0x00, "MVME 2400", Genesis2_pci_IRQ_map, Raven_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xFF},
{0x010, 0x00, 0x00, "Genesis", Genesis_pci_IRQ_map, Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
{0x020, 0x00, 0x00, "Powerstack (Series E)", Comet_pci_IRQ_map, Comet_pci_IRQ_routes, NULL, NULL, 0x00},
--
Meelis Roos (mroos@linux.ee)
^ permalink raw reply related
* Re: [PATCH] of_serial: add port type checking
From: Arnd Bergmann @ 2007-05-31 10:46 UTC (permalink / raw)
To: Ishizaki Kou; +Cc: linuxppc-dev, paulus
In-Reply-To: <200705310933.l4V9X4Pl009909@toshiba.co.jp>
On Thursday 31 May 2007, Ishizaki Kou wrote:
>
> Currently, of_serial driver supports only 8250 compatible ports, but
> prepares that others can easily be added. Yet unregister routine
> assumes port is 8250. This patch corrects unregister routine to check
> port type.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
> Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* Re: [PATCH] of_serial: ignore unknown serial port
From: Arnd Bergmann @ 2007-05-31 10:46 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20070531.183033.-1300520557.kouish@swc.toshiba.co.jp>
On Thursday 31 May 2007, Ishizaki Kou wrote:
> Current of_serial driver assumes unknown serial port to be 8250. But
> this behavior may cause fatal problems when the serial port is not
> 8250. This patch corrects probe routine to ignore unknown serial port.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
> Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Arnd Bergmann <arnd@arndb.de>
^ permalink raw reply
* [PATCH 1/2] ehea: Whitespace cleanup
From: Thomas Klein @ 2007-05-31 11:54 UTC (permalink / raw)
To: Jeff Garzik
Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
Christoph Raisch, Stefan Roscher, linux-ppc, Marcus Eder
This patch fixes several whitespace issues.
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
---
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea.h patched_kernel/drivers/net/ehea/ehea.h
--- linux-2.6.22-rc3/drivers/net/ehea/ehea.h 2007-05-30 12:13:36.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea.h 2007-05-30 12:27:13.000000000 +0200
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0061"
+#define DRV_VERSION "EHEA_0062"
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -136,10 +136,10 @@ void ehea_dump(void *adr, int len, char
(0xffffffffffffffffULL >> ((64 - (mask)) & 0xffff))
#define EHEA_BMASK_SET(mask, value) \
- ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask))
+ ((EHEA_BMASK_MASK(mask) & ((u64)(value))) << EHEA_BMASK_SHIFTPOS(mask))
#define EHEA_BMASK_GET(mask, value) \
- (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask)))
+ (EHEA_BMASK_MASK(mask) & (((u64)(value)) >> EHEA_BMASK_SHIFTPOS(mask)))
/*
* Generic ehea page
@@ -190,7 +190,7 @@ struct ehea_av;
* Queue attributes passed to ehea_create_qp()
*/
struct ehea_qp_init_attr {
- /* input parameter */
+ /* input parameter */
u32 qp_token; /* queue token */
u8 low_lat_rq1;
u8 signalingtype; /* cqe generation flag */
@@ -212,7 +212,7 @@ struct ehea_qp_init_attr {
u64 recv_cq_handle;
u64 aff_eq_handle;
- /* output parameter */
+ /* output parameter */
u32 qp_nr;
u16 act_nr_send_wqes;
u16 act_nr_rwqes_rq1;
@@ -279,12 +279,12 @@ struct ehea_qp {
* Completion Queue attributes
*/
struct ehea_cq_attr {
- /* input parameter */
+ /* input parameter */
u32 max_nr_of_cqes;
u32 cq_token;
u64 eq_handle;
- /* output parameter */
+ /* output parameter */
u32 act_nr_of_cqes;
u32 nr_pages;
};
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea_hw.h patched_kernel/drivers/net/ehea/ehea_hw.h
--- linux-2.6.22-rc3/drivers/net/ehea/ehea_hw.h 2007-05-26 04:55:14.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea_hw.h 2007-05-30 12:27:13.000000000 +0200
@@ -211,34 +211,34 @@ static inline void epa_store_acc(struct
}
#define epa_store_eq(epa, offset, value)\
- epa_store(epa, EQTEMM_OFFSET(offset), value)
+ epa_store(epa, EQTEMM_OFFSET(offset), value)
#define epa_load_eq(epa, offset)\
- epa_load(epa, EQTEMM_OFFSET(offset))
+ epa_load(epa, EQTEMM_OFFSET(offset))
#define epa_store_cq(epa, offset, value)\
- epa_store(epa, CQTEMM_OFFSET(offset), value)
+ epa_store(epa, CQTEMM_OFFSET(offset), value)
#define epa_load_cq(epa, offset)\
- epa_load(epa, CQTEMM_OFFSET(offset))
+ epa_load(epa, CQTEMM_OFFSET(offset))
#define epa_store_qp(epa, offset, value)\
- epa_store(epa, QPTEMM_OFFSET(offset), value)
+ epa_store(epa, QPTEMM_OFFSET(offset), value)
#define epa_load_qp(epa, offset)\
- epa_load(epa, QPTEMM_OFFSET(offset))
+ epa_load(epa, QPTEMM_OFFSET(offset))
#define epa_store_qped(epa, offset, value)\
- epa_store(epa, QPEDMM_OFFSET(offset), value)
+ epa_store(epa, QPEDMM_OFFSET(offset), value)
#define epa_load_qped(epa, offset)\
- epa_load(epa, QPEDMM_OFFSET(offset))
+ epa_load(epa, QPEDMM_OFFSET(offset))
#define epa_store_mrmw(epa, offset, value)\
- epa_store(epa, MRMWMM_OFFSET(offset), value)
+ epa_store(epa, MRMWMM_OFFSET(offset), value)
#define epa_load_mrmw(epa, offset)\
- epa_load(epa, MRMWMM_OFFSET(offset))
+ epa_load(epa, MRMWMM_OFFSET(offset))
#define epa_store_base(epa, offset, value)\
- epa_store(epa, HCAGR_OFFSET(offset), value)
+ epa_store(epa, HCAGR_OFFSET(offset), value)
#define epa_load_base(epa, offset)\
- epa_load(epa, HCAGR_OFFSET(offset))
+ epa_load(epa, HCAGR_OFFSET(offset))
static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes)
{
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea_main.c patched_kernel/drivers/net/ehea/ehea_main.c
--- linux-2.6.22-rc3/drivers/net/ehea/ehea_main.c 2007-05-30 12:13:36.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea_main.c 2007-05-30 12:27:13.000000000 +0200
@@ -81,7 +81,7 @@ MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Mu
static int port_name_cnt = 0;
static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
- const struct of_device_id *id);
+ const struct of_device_id *id);
static int __devexit ehea_remove(struct ibmebus_dev *dev);
@@ -236,7 +236,7 @@ static int ehea_refill_rq_def(struct ehe
rwqe = ehea_get_next_rwqe(qp, rq_nr);
rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
- | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
+ | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
rwqe->sg_list[0].l_key = pr->recv_mr.lkey;
rwqe->sg_list[0].vaddr = (u64)skb->data;
rwqe->sg_list[0].len = packet_size;
@@ -427,7 +427,7 @@ static struct ehea_cqe *ehea_proc_rwqes(
break;
}
skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
- cqe->num_bytes_transfered - 4);
+ cqe->num_bytes_transfered - 4);
ehea_fill_skb(port->netdev, skb, cqe);
} else if (rq == 2) { /* RQ2 */
skb = get_skb_by_index(skb_arr_rq2,
@@ -617,7 +617,7 @@ static struct ehea_port *ehea_get_port(s
for (i = 0; i < EHEA_MAX_PORTS; i++)
if (adapter->port[i])
- if (adapter->port[i]->logical_port_id == logical_port)
+ if (adapter->port[i]->logical_port_id == logical_port)
return adapter->port[i];
return NULL;
}
@@ -1694,6 +1694,7 @@ static void ehea_xmit2(struct sk_buff *s
{
if (skb->protocol == htons(ETH_P_IP)) {
const struct iphdr *iph = ip_hdr(skb);
+
/* IPv4 */
swqe->tx_control |= EHEA_SWQE_CRC
| EHEA_SWQE_IP_CHECKSUM
@@ -1704,13 +1705,12 @@ static void ehea_xmit2(struct sk_buff *s
write_ip_start_end(swqe, skb);
if (iph->protocol == IPPROTO_UDP) {
- if ((iph->frag_off & IP_MF) ||
- (iph->frag_off & IP_OFFSET))
+ if ((iph->frag_off & IP_MF)
+ || (iph->frag_off & IP_OFFSET))
/* IP fragment, so don't change cs */
swqe->tx_control &= ~EHEA_SWQE_TCP_CHECKSUM;
else
write_udp_offset_end(swqe, skb);
-
} else if (iph->protocol == IPPROTO_TCP) {
write_tcp_offset_end(swqe, skb);
}
@@ -1738,6 +1738,7 @@ static void ehea_xmit3(struct sk_buff *s
if (skb->protocol == htons(ETH_P_IP)) {
const struct iphdr *iph = ip_hdr(skb);
+
/* IPv4 */
write_ip_start_end(swqe, skb);
@@ -1750,8 +1751,8 @@ static void ehea_xmit3(struct sk_buff *s
write_tcp_offset_end(swqe, skb);
} else if (iph->protocol == IPPROTO_UDP) {
- if ((iph->frag_off & IP_MF) ||
- (iph->frag_off & IP_OFFSET))
+ if ((iph->frag_off & IP_MF)
+ || (iph->frag_off & IP_OFFSET))
/* IP fragment, so don't change cs */
swqe->tx_control |= EHEA_SWQE_CRC
| EHEA_SWQE_IMM_DATA_PRESENT;
@@ -2409,7 +2410,7 @@ static void __devinit logical_port_relea
}
static int ehea_driver_sysfs_add(struct device *dev,
- struct device_driver *driver)
+ struct device_driver *driver)
{
int ret;
@@ -2426,7 +2427,7 @@ static int ehea_driver_sysfs_add(struct
}
static void ehea_driver_sysfs_remove(struct device *dev,
- struct device_driver *driver)
+ struct device_driver *driver)
{
struct device_driver *drv = driver;
@@ -2455,7 +2456,7 @@ static struct device *ehea_register_port
}
ret = device_create_file(&port->ofdev.dev, &dev_attr_log_port_id);
- if (ret) {
+ if (ret) {
ehea_error("failed to register attributes, ret=%d", ret);
goto out_unreg_of_dev;
}
@@ -2603,6 +2604,7 @@ static int ehea_setup_ports(struct ehea_
{
struct device_node *lhea_dn;
struct device_node *eth_dn = NULL;
+
const u32 *dn_log_port_id;
int i = 0;
@@ -2610,7 +2612,7 @@ static int ehea_setup_ports(struct ehea_
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
- NULL);
+ NULL);
if (!dn_log_port_id) {
ehea_error("bad device node: eth_dn name=%s",
eth_dn->full_name);
@@ -2650,7 +2652,7 @@ static struct device_node *ehea_get_eth_
while ((eth_dn = of_get_next_child(lhea_dn, eth_dn))) {
dn_log_port_id = of_get_property(eth_dn, "ibm,hea-port-no",
- NULL);
+ NULL);
if (dn_log_port_id)
if (*dn_log_port_id == logical_port_id)
return eth_dn;
@@ -2791,7 +2793,7 @@ static int __devinit ehea_probe_adapter(
adapter->ebus_dev = dev;
adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
- NULL);
+ NULL);
if (adapter_handle)
adapter->handle = *adapter_handle;
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea_qmr.c patched_kernel/drivers/net/ehea/ehea_qmr.c
--- linux-2.6.22-rc3/drivers/net/ehea/ehea_qmr.c 2007-05-26 04:55:14.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea_qmr.c 2007-05-30 12:27:13.000000000 +0200
@@ -211,7 +211,7 @@ u64 ehea_destroy_cq_res(struct ehea_cq *
u64 hret;
u64 adapter_handle = cq->adapter->handle;
- /* deregister all previous registered pages */
+ /* deregister all previous registered pages */
hret = ehea_h_free_resource(adapter_handle, cq->fw_handle, force);
if (hret != H_SUCCESS)
return hret;
@@ -362,7 +362,7 @@ int ehea_destroy_eq(struct ehea_eq *eq)
if (hret != H_SUCCESS) {
ehea_error("destroy EQ failed");
return -EIO;
- }
+ }
return 0;
}
@@ -507,44 +507,44 @@ out_freemem:
u64 ehea_destroy_qp_res(struct ehea_qp *qp, u64 force)
{
- u64 hret;
- struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
+ u64 hret;
+ struct ehea_qp_init_attr *qp_attr = &qp->init_attr;
- ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
- hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
- if (hret != H_SUCCESS)
- return hret;
+ ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
+ hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle, force);
+ if (hret != H_SUCCESS)
+ return hret;
- hw_queue_dtor(&qp->hw_squeue);
- hw_queue_dtor(&qp->hw_rqueue1);
+ hw_queue_dtor(&qp->hw_squeue);
+ hw_queue_dtor(&qp->hw_rqueue1);
- if (qp_attr->rq_count > 1)
- hw_queue_dtor(&qp->hw_rqueue2);
- if (qp_attr->rq_count > 2)
- hw_queue_dtor(&qp->hw_rqueue3);
- kfree(qp);
+ if (qp_attr->rq_count > 1)
+ hw_queue_dtor(&qp->hw_rqueue2);
+ if (qp_attr->rq_count > 2)
+ hw_queue_dtor(&qp->hw_rqueue3);
+ kfree(qp);
- return hret;
+ return hret;
}
int ehea_destroy_qp(struct ehea_qp *qp)
{
- u64 hret;
- if (!qp)
- return 0;
-
- if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
- ehea_error_data(qp->adapter, qp->fw_handle);
- hret = ehea_destroy_qp_res(qp, FORCE_FREE);
- }
-
- if (hret != H_SUCCESS) {
- ehea_error("destroy QP failed");
- return -EIO;
- }
+ u64 hret;
+ if (!qp)
+ return 0;
+
+ if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) {
+ ehea_error_data(qp->adapter, qp->fw_handle);
+ hret = ehea_destroy_qp_res(qp, FORCE_FREE);
+ }
+
+ if (hret != H_SUCCESS) {
+ ehea_error("destroy QP failed");
+ return -EIO;
+ }
- return 0;
+ return 0;
}
int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
^ permalink raw reply
* [PATCH 2/2] ehea: Receive SKB Aggregation
From: Thomas Klein @ 2007-05-31 11:54 UTC (permalink / raw)
To: Jeff Garzik
Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
Christoph Raisch, Stefan Roscher, linux-ppc, Marcus Eder
After there were no technical concerns about this patch I'm resending it with
all whitespace issues fixed which were mentioned by Stephen Rothwell.
This patch enables the receive side processing to aggregate TCP packets within
the HEA device driver. It analyses the packets already received after an
interrupt arrived and forwards these as chains of SKBs for the same TCP
connection with modified header field. We have seen a lower CPU load and
improved throughput for small numbers of parallel TCP connections.
We added a disabled module parameter to prevent disruption of normal driver
operation.
We currently consider this as "experimental" until further review and tests
have been passed.
Signed-off-by: Thomas Klein <tklein@de.ibm.com>
---
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea.h patched_kernel/drivers/net/ehea/ehea.h
--- linux-2.6.22-rc3/drivers/net/ehea/ehea.h 2007-05-30 13:25:43.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea.h 2007-05-30 13:28:16.000000000 +0200
@@ -39,7 +39,7 @@
#include <asm/io.h>
#define DRV_NAME "ehea"
-#define DRV_VERSION "EHEA_0062"
+#define DRV_VERSION "EHEA_0063"
#define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -49,6 +49,7 @@
#define EHEA_MAX_ENTRIES_RQ3 16383
#define EHEA_MAX_ENTRIES_SQ 32767
#define EHEA_MIN_ENTRIES_QP 127
+#define EHEA_LRO_MAX_PKTS 60
#define EHEA_SMALL_QUEUES
#define EHEA_NUM_TX_QP 1
@@ -78,6 +79,9 @@
#define EHEA_RQ2_PKT_SIZE 1522
#define EHEA_L_PKT_SIZE 256 /* low latency */
+#define MAX_LRO_DESCRIPTORS 8
+#define LRO_DESC_MASK 0xFFFFFFFF
+
/* Send completion signaling */
/* Protection Domain Identifier */
@@ -334,6 +338,29 @@ struct ehea_q_skb_arr {
};
/*
+ * Large Receive Offload (LRO) descriptor for a tcp seesion
+ */
+struct ehea_lro {
+ struct sk_buff *parent;
+ struct sk_buff *last_skb;
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+
+ u32 tcp_rcv_tsecr;
+ u32 tcp_rcv_tsval;
+ u32 tcp_ack;
+ u32 tcp_next_seq;
+ u32 skb_tot_frags_len;
+ u16 ip_tot_len;
+ u16 tcp_saw_tstamp; /* timestamps enabled */
+ u16 tcp_window;
+ u16 vlan_tag;
+ int skb_sg_cnt; /* counts aggregated skbs */
+ int vlan_packet;
+ int active;
+};
+
+/*
* Port resources
*/
struct ehea_port_res {
@@ -362,6 +389,9 @@ struct ehea_port_res {
u64 tx_packets;
u64 rx_packets;
u32 poll_counter;
+ struct ehea_lro lro[MAX_LRO_DESCRIPTORS];
+ u64 lro_desc;
+ struct port_stats p_state;
};
@@ -411,6 +441,7 @@ struct ehea_port {
u32 msg_enable;
u32 sig_comp_iv;
u32 state;
+ u32 lro_max_aggr;
u8 full_duplex;
u8 autoneg;
u8 num_def_qps;
diff -Nurp -X dontdiff linux-2.6.22-rc3/drivers/net/ehea/ehea_main.c patched_kernel/drivers/net/ehea/ehea_main.c
--- linux-2.6.22-rc3/drivers/net/ehea/ehea_main.c 2007-05-30 13:25:43.000000000 +0200
+++ patched_kernel/drivers/net/ehea/ehea_main.c 2007-05-30 13:28:16.000000000 +0200
@@ -34,6 +34,7 @@
#include <linux/list.h>
#include <linux/if_ether.h>
#include <net/ip.h>
+#include <net/tcp.h>
#include "ehea.h"
#include "ehea_qmr.h"
@@ -52,6 +53,8 @@ static int rq2_entries = EHEA_DEF_ENTRIE
static int rq3_entries = EHEA_DEF_ENTRIES_RQ3;
static int sq_entries = EHEA_DEF_ENTRIES_SQ;
static int use_mcs = 0;
+static int use_lro = 0;
+static int lro_max_pkts = EHEA_LRO_MAX_PKTS;
static int num_tx_qps = EHEA_NUM_TX_QP;
module_param(msg_level, int, 0);
@@ -60,6 +63,8 @@ module_param(rq2_entries, int, 0);
module_param(rq3_entries, int, 0);
module_param(sq_entries, int, 0);
module_param(use_mcs, int, 0);
+module_param(use_lro, int, 0);
+module_param(lro_max_pkts, int, 0);
module_param(num_tx_qps, int, 0);
MODULE_PARM_DESC(num_tx_qps, "Number of TX-QPS");
@@ -77,6 +82,9 @@ MODULE_PARM_DESC(sq_entries, " Number of
"[2^x - 1], x = [6..14]. Default = "
__MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")");
MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
+MODULE_PARM_DESC(lro_max_pkts, "LRO: Max packets to be aggregated. Default = "
+ __MODULE_STRING(EHEA_LRO_MAX_PKTS));
+MODULE_PARM_DESC(use_lro, "1: enable, 0: disable Large Reveive Offload ");
static int port_name_cnt = 0;
@@ -380,6 +388,282 @@ static int ehea_treat_poll_error(struct
return 0;
}
+static int try_get_ip_tcp_hdr(struct ehea_cqe *cqe, struct sk_buff *skb,
+ struct iphdr **iph, struct tcphdr **tcph)
+{
+ int ip_len;
+
+ /* non tcp/udp packets */
+ if (!cqe->header_length)
+ return -1;
+
+ /* non tcp packet */
+ *iph = (struct iphdr *)(skb->data);
+ if ((*iph)->protocol != IPPROTO_TCP)
+ return -1;
+
+ ip_len = (u8)((*iph)->ihl);
+ ip_len <<= 2;
+ *tcph = (struct tcphdr *)(((u64)*iph) + ip_len);
+
+ return 0;
+}
+
+#define TCP_PAYLOAD_LENGTH(iph, tcph) \
+(ntohs(iph->tot_len) - (iph->ihl << 2) - (tcph->doff << 2))
+
+#define IPH_LEN_WO_OPTIONS 5
+#define TCPH_LEN_WO_OPTIONS 5
+#define TCPH_LEN_W_TIMESTAMP 8
+
+static int lro_tcp_check(struct iphdr *iph, struct tcphdr *tcph,
+ int tcp_data_len, struct ehea_lro *lro)
+{
+ if (tcp_data_len == 0)
+ return -1;
+
+ if (iph->ihl != IPH_LEN_WO_OPTIONS)
+ return -1;
+
+ if (tcph->cwr || tcph->ece || tcph->urg || !tcph->ack || tcph->psh
+ || tcph->rst || tcph->syn || tcph->fin)
+ return -1;
+
+ if (INET_ECN_is_ce(ipv4_get_dsfield(iph)))
+ return -1;
+
+ if (tcph->doff != TCPH_LEN_WO_OPTIONS
+ && tcph->doff != TCPH_LEN_W_TIMESTAMP)
+ return -1;
+
+ /* check tcp options (only timestamp allowed) */
+ if (tcph->doff == TCPH_LEN_W_TIMESTAMP) {
+ u32 *topt = (u32 *)(tcph + 1);
+
+ if (*topt != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
+ return -1;
+
+ /* timestamp should be in right order */
+ topt++;
+ if (lro && (ntohl(lro->tcp_rcv_tsval) > ntohl(*topt)))
+ return -1;
+
+ /* timestamp reply should not be zero */
+ topt++;
+ if (*topt == 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+static void update_tcp_ip_header(struct ehea_lro *lro)
+{
+ struct iphdr *iph = lro->iph;
+ struct tcphdr *tcph = lro->tcph;
+ u32 *p;
+
+ tcph->ack_seq = lro->tcp_ack;
+ tcph->window = lro->tcp_window;
+
+ if (lro->tcp_saw_tstamp) {
+ p = (u32 *)(tcph + 1);
+ *(p+2) = lro->tcp_rcv_tsecr;
+ }
+
+ iph->tot_len = htons(lro->ip_tot_len);
+ iph->check = 0;
+ iph->check = ip_fast_csum((u8 *)lro->iph, iph->ihl);
+}
+
+static void init_lro_desc(struct ehea_lro *lro, struct ehea_cqe *cqe,
+ struct sk_buff *skb, struct iphdr *iph,
+ struct tcphdr *tcph, u32 tcp_data_len)
+{
+ u32 *ptr;
+
+ lro->parent = skb;
+ lro->iph = iph;
+ lro->tcph = tcph;
+ lro->tcp_next_seq = ntohl(tcph->seq) + tcp_data_len;
+ lro->tcp_ack = ntohl(tcph->ack_seq);
+
+ lro->skb_sg_cnt = 1;
+ lro->ip_tot_len = ntohs(iph->tot_len);
+
+ if (tcph->doff == 8) {
+ ptr = (u32 *)(tcph+1);
+ lro->tcp_saw_tstamp = 1;
+ lro->tcp_rcv_tsval = *(ptr+1);
+ lro->tcp_rcv_tsecr = *(ptr+2);
+ }
+
+ if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) {
+ lro->vlan_packet = 1;
+ lro->vlan_tag = cqe->vlan_tag;
+ }
+
+ lro->active = 1;
+}
+
+static inline void clear_lro_desc(struct ehea_lro *lro)
+{
+ memset(lro, 0, sizeof(struct ehea_lro));
+}
+
+static void lro_add_packet(struct ehea_lro *lro, struct sk_buff *skb,
+ struct tcphdr *tcph, u32 tcp_len)
+{
+ struct sk_buff *parent = lro->parent;
+ u32 *topt;
+
+ lro->skb_sg_cnt++;
+
+ lro->ip_tot_len += tcp_len;
+ lro->tcp_next_seq += tcp_len;
+ lro->tcp_window = lro->tcph->window;
+ lro->tcp_ack = lro->tcph->ack_seq;
+
+ if (lro->tcp_saw_tstamp) {
+ topt = (u32 *) (tcph + 1);
+ lro->tcp_rcv_tsval = *(topt + 1);
+ lro->tcp_rcv_tsecr = *(topt + 2);
+ }
+
+ parent->len += tcp_len;
+ parent->data_len += tcp_len;
+
+ skb_pull(skb, (skb->len - tcp_len));
+ parent->truesize += skb->truesize;
+
+ if (lro->last_skb)
+ lro->last_skb->next = skb;
+ else
+ skb_shinfo(parent)->frag_list = skb;
+
+ lro->last_skb = skb;
+
+ return;
+}
+
+static int check_tcp_conn(struct ehea_lro *lro, struct iphdr *iph,
+ struct tcphdr *tcph)
+{
+ // fixme: compare source and destination at the same time? u64 compare?
+ if ((lro->iph->saddr != iph->saddr) || (lro->iph->daddr != iph->daddr) ||
+ (lro->tcph->source != tcph->source) || (lro->tcph->dest != tcph->dest))
+ return -1;
+ return 0;
+}
+
+static void flush_lro(struct ehea_port_res *pr, struct ehea_lro *lro)
+{
+ update_tcp_ip_header(lro);
+
+ if (lro->vlan_packet)
+ vlan_hwaccel_receive_skb(lro->parent, pr->port->vgrp,
+ lro->vlan_tag);
+ else
+ netif_receive_skb(lro->parent);
+
+ clear_lro_desc(lro);
+}
+
+static void flush_all_lro(struct ehea_port_res *pr)
+{
+ int i;
+ struct ehea_lro *lro;
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ lro = &pr->lro[i];
+ if (lro->active)
+ flush_lro(pr, lro);
+ }
+}
+
+static struct ehea_lro *ehea_get_lro(struct ehea_port_res *pr,
+ struct iphdr *iph, struct tcphdr *tcph)
+{
+ struct ehea_lro *lro = NULL;
+ struct ehea_lro *tmp;
+ int i;
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ tmp = &pr->lro[i];
+ if (tmp->active)
+ if (!check_tcp_conn(tmp, iph, tcph)) {
+ lro = tmp;
+ goto out;
+ }
+ }
+
+ for (i = 0; i < MAX_LRO_DESCRIPTORS; i++) {
+ if(!pr->lro[i].active) {
+ lro = &pr->lro[i];
+ goto out;
+ }
+ }
+
+out:
+ return lro;
+}
+
+static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe,
+ struct sk_buff *skb)
+{
+ struct iphdr *iph;
+ struct tcphdr *tcph;
+ struct ehea_lro *lro;
+ int tcp_data_len;
+ int skip_orig_skb = 0;
+
+ if (use_lro) {
+ if (try_get_ip_tcp_hdr(cqe, skb, &iph, &tcph))
+ goto out;
+
+ lro = ehea_get_lro(pr, iph, tcph);
+ if (!lro)
+ goto out;
+
+ tcp_data_len = TCP_PAYLOAD_LENGTH(iph, tcph);
+
+ if (!lro->active) {
+ if (lro_tcp_check(iph, tcph, tcp_data_len, NULL))
+ goto out;
+
+ init_lro_desc(lro, cqe, skb, iph, tcph, tcp_data_len);
+ return;
+ }
+
+ if (lro->tcp_next_seq != ntohl(tcph->seq)) {
+ flush_lro(pr, lro);
+ goto out;
+ }
+
+ if (lro_tcp_check(iph, tcph, tcp_data_len, lro)) {
+ flush_lro(pr, lro);
+ goto out;
+ }
+
+ lro_add_packet(lro, skb, tcph, tcp_data_len);
+
+ if (lro->skb_sg_cnt > pr->port->lro_max_aggr)
+ flush_lro(pr, lro);
+
+ skip_orig_skb = 1;
+ }
+
+out:
+ if (skip_orig_skb)
+ return;
+
+ if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
+ vlan_hwaccel_receive_skb(skb, pr->port->vgrp, cqe->vlan_tag);
+ else
+ netif_receive_skb(skb);
+}
+
static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
struct ehea_port_res *pr,
int *budget)
@@ -426,6 +710,7 @@ static struct ehea_cqe *ehea_proc_rwqes(
if (!skb)
break;
}
+ skb_reserve(skb, NET_IP_ALIGN);
skb_copy_to_linear_data(skb, ((char*)cqe) + 64,
cqe->num_bytes_transfered - 4);
ehea_fill_skb(port->netdev, skb, cqe);
@@ -451,11 +736,7 @@ static struct ehea_cqe *ehea_proc_rwqes(
processed_rq3++;
}
- if (cqe->status & EHEA_CQE_VLAN_TAG_XTRACT)
- vlan_hwaccel_receive_skb(skb, port->vgrp,
- cqe->vlan_tag);
- else
- netif_receive_skb(skb);
+ ehea_proc_skb(pr, cqe, skb);
} else {
pr->p_stats.poll_receive_errors++;
port_reset = ehea_treat_poll_error(pr, rq, cqe,
@@ -467,6 +748,8 @@ static struct ehea_cqe *ehea_proc_rwqes(
cqe = ehea_poll_rq1(qp, &wqe_index);
}
+ flush_all_lro(pr);
+
pr->rx_packets += processed;
*budget -= processed;
@@ -1683,9 +1966,15 @@ out:
static int ehea_change_mtu(struct net_device *dev, int new_mtu)
{
+ struct ehea_port *port = netdev_priv(dev);
+
if ((new_mtu < 68) || (new_mtu > EHEA_MAX_PACKET_SIZE))
return -EINVAL;
dev->mtu = new_mtu;
+
+ if (use_lro)
+ port->lro_max_aggr = (0xFFFF / new_mtu);
+
return 0;
}
@@ -2493,6 +2782,7 @@ struct ehea_port *ehea_setup_single_port
struct ehea_port *port;
struct device *port_dev;
int jumbo;
+ int lro_pkts;
/* allocate memory for the port structures */
dev = alloc_etherdev(sizeof(struct ehea_port));
@@ -2567,6 +2857,12 @@ struct ehea_port *ehea_setup_single_port
goto out_unreg_port;
}
+ lro_pkts = (0xFFFF / dev->mtu);
+ if (lro_pkts < lro_max_pkts)
+ port->lro_max_aggr = lro_pkts;
+ else
+ port->lro_max_aggr = lro_max_pkts;
+
ret = ehea_get_jumboframe_status(port, &jumbo);
if (ret)
ehea_error("failed determining jumbo frame status for %s",
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox