* Re: [PATCH] sungem rework & wake on lan
From: Benjamin Herrenschmidt @ 2004-11-26 22:03 UTC (permalink / raw)
To: Colin Leroy; +Cc: David S. Miller, linuxppc-dev list, Jeff Garzik
In-Reply-To: <20041126200754.1123e8f8@jack.colino.net>
On Fri, 2004-11-26 at 20:07 +0100, Colin Leroy wrote:
> On 26 Nov 2004 at 14h11, Benjamin Herrenschmidt wrote:
>
> Hi Ben,
>
> if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend)
> - gp->phy_mii.def->ops->suspend(&gp->phy_mii, 0 /* wake on lan options */);
> + gp->phy_mii.def->ops->suspend(&gp->phy_mii);
>
> Shouldn't this if() have an "&& !wol" clause ?
> At least it doesn't work without it, and works with it, here on 5221 PHY.
>
> Thanks for your work. Will post a patch applying to 2.6.9+sleep_patch soon
> for the possibly interested people.
You are right. It happens to work in both case with the 5201 I have
here, but that may be because the superisolate code doesn't quite work
on it ...
Anyway, I do _not_ intend to keep the driver in this state. I dislike
the fact that I have to udelay() between 10 and 100usec (depending on
the machine) at IRQ time with a spinlock held every second when polling
for the link.
I will move the link poll to task level so it can schedule instead. But
the problem is complex. There is a problem with kenrel autoconfig
(ipconfig) which doesn't schedule and should probably be fixed. Also to
do what I want to do (which is to also switch the clock off when the
iface is up, but the link down), I'll have locking issues with set_mtu()
and set_multicast() calls which happen to be called with a spinlock
held.
Ben.
^ permalink raw reply
* Re: [PATCH] sungem rework & wake on lan
From: Colin Leroy @ 2004-11-26 19:07 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: David S. Miller, linuxppc-dev list, Jeff Garzik
In-Reply-To: <1101439228.4633.74.camel@gaston>
On 26 Nov 2004 at 14h11, Benjamin Herrenschmidt wrote:
Hi Ben,
if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend)
- gp->phy_mii.def->ops->suspend(&gp->phy_mii, 0 /* wake on lan options */);
+ gp->phy_mii.def->ops->suspend(&gp->phy_mii);
Shouldn't this if() have an "&& !wol" clause ?
At least it doesn't work without it, and works with it, here on 5221 PHY.
Thanks for your work. Will post a patch applying to 2.6.9+sleep_patch soon
for the possibly interested people.
--
Colin
http://www.colino.net/
^ permalink raw reply
* Re: MPC5200 toolchain test
From: Wolfgang Denk @ 2004-11-26 14:36 UTC (permalink / raw)
To: ivica; +Cc: linuxppc-embedded
In-Reply-To: <41A709E1.4050608@asist-traffic.com>
Dear Ivica,
in message <41A709E1.4050608@asist-traffic.com> you wrote:
>
> Educational reasons were my primary motives besides the independence
> factor. :-)
OK, understood and accepted (that was the starting point for the
ELDK, too :-)
> I will have a certain budget to spend.What tools should I use? BDI2000?
> Any alternatives,
> or is this simply superior tool for debugging purposes?
It is. IMHO the BDI2000 is the de-facto standard tool for low-level
Linux debugging.
> >There is some pretty extensive documentation in our DULG about how to
...
> Yes I know of it. It doesn't describe though the process of compiling
> and linking standalone
> applications to run without OS.
Ummm.. there is. See http://www.denx.de/twiki/bin/view/DULG/UBootStandalone
[I hope you don't call "U-Boot" an OS ;-) ]
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Commitment, n.: Commitment can be illustrated by a breakfast
of ham and eggs. The chicken was involved, the pig was committed.
^ permalink raw reply
* Re: G3 iBook LCD brightness in X under kernel 2.4.25 and 2.6.8
From: murphyf+xfree86 @ 2004-11-26 15:38 UTC (permalink / raw)
To: Christof Petig; +Cc: linuxppc-dev, debian-x
In-Reply-To: <41A70567.8050000@petig-baender.de>
On Fri, 26 Nov 2004 11:28:55 +0100, "Christof Petig" said:
> Frank Murphy schrieb:
> > I'm trying to migrate from a 2.4 to a 2.6 kernel, but I have one last problem
> > keeping me with 2.4.25. There's a problem with adjusting screen brightness
> > under X (4.3.0.dfsg.1-8).
> >
> > I'm running pbbuttonsd 0.6.6-2 with gtkpbbuttons 0.6.4-3 (which are tools that
> > enable the LCD to be dimmed and brightened with keyboard pressed). When I'm
> > running the Debian kernel-image 2.4.25-8 and I press the brightness up or
> > down keys, I get the on-screen indication from gtkpbbuttons and the LCD dims
> > or brightens as expected in both X and on the console. However, when I boot
> > into kernel-image 2.6.8-6 or 2.6.9-1 and press the brightness keys, I get the
> > on-screen indication in X, but the LCD doesn't change brightness. However, if
> > I switch to a VT with a console, the brightness changes to what I tried to
> > change it to. Also, pressing the brightness buttons works fine when I press
> > them while in the console.
> >
> > My video card is a Mach64, and I'm using the 'ati' driver for X. One guess I
> > have is that in 2.6, lots more things are built as kernel modules. I'd like
> > to try build any needed video stuff in, but I don't know what it could be.
> > Does anyone here have an idea what controls screen brightness in X?
>
> Your mouse pointer might get some noisy spots on brightness change, ever
> noticed? I would blame the kernel first (since 2.4 works well).
I have noticed it, acutally. I don't know what it means exactly, but it
seems that some small set of pixels near the cursor is affected. These
corrupted pixels then move around with the cursor as well.
> > The reason this is important for me is that the LCD is not dimmed when I close
> > the lid for sleep, which kind of ruins the point of sleep.
> >
> > Does anyone have an idea of what else I need to do to get screen dimming to
> > work under X with Linux 2.6?
>
> Try to ask on the ppc-kernel list (CCed). I suspect that nobody has
> reimplemented power management for mach64 in 2.6. The fact that lid
> closing does not put the display to sleep keeps me locked in 2.4, too
> (though I experienced that 2.6 is way faster).
>
> I played with the thought of fixing it myself (like I plan to fix DRI
> DMA some time) but was unable to allocate ressources (and enough
> motivation)
>
> So take this as a "I have the problem, too" posting
Well, that's something. What is your hardware? I have an original iBook
(actually, it's the 1.5 generation that came with a slightly faster CPU
and a bigger HD).
Frank
^ permalink raw reply
* Re: MPC5200 toolchain test
From: ivica @ 2004-11-26 10:48 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20041125225810.A5B02C1430@atlas.denx.de>
Wolfgang Denk wrote:
>Dear Ivica,
>
>in message <41A5F930.3080104@asist-traffic.com> you wrote:
>
>
>>I have a MPC5200 based custom board with preloaded u-boot.
>>
>>
>
>May I ask why you want to start from scratch? Is it for educational
>purposes? Otherwise you could just use existing and well-tested
>toolchains like our ELDK which isavailable for free (see
>http://www.denx.de/ELDK.html); of course you can also use the ELDK's
>build environment to rebuild everything from scratch if you really
>want to be sure that you can recompile everything without need to
>rely on any external resources.
>
>
Educational reasons were my primary motives besides the independence
factor. :-)
I used ELDK extensively on my other projects and I was very pleased with
the kit.
I used this kit on TQM boards on my former job. Board that I use now is
totally
custom made and I expect to have difficulties with it anyway. My motto
was "If I
can't build/create the tools I'm going to work with I really shouldn't
mess around
in the first place".
That said, I will always keep a backup solution ready (read ELDK) and
try to thoroughly
understand everything I do. I wanted to build my system from the ground
up but
I don't have the tools to do it (BDI2000, ...). My board was preloaded
with u-boot.
Since this board is not yet truly industrial ready I will need to
somehow stress it and test it.
I will have a certain budget to spend.What tools should I use? BDI2000?
Any alternatives,
or is this simply superior tool for debugging purposes?
>>So far I managed to create GNU toolchain for it with crostool from
>>Dan Kegel. Everything was built without any problems. Of course,
>>I wanted to test this toolchain so I wanted to compile a simple
>>hello_world program load it into the memory of my MPC5200 board
>>and run it. So far I've failed. I admit. I don't know how to compile
>>a program to run without the OS. But I have some clues. I think it
>>
>>
>
>There is some pretty extensive documentation in our DULG about how to
>use U-Boot and Linux in Embedded systems; have a look at
>http://www.denx.de/twiki/bin/view/DULG/Manual
>
>
>
Yes I know of it. It doesn't describe though the process of compiling
and linking standalone
applications to run without OS.
Regards,
Ivica
^ permalink raw reply
* Re: G3 iBook LCD brightness in X under kernel 2.4.25 and 2.6.8
From: Christof Petig @ 2004-11-26 10:28 UTC (permalink / raw)
To: Frank Murphy; +Cc: linuxppc-dev, debian-x
In-Reply-To: <200411232008.16854.murphyf+xfree86@f-m.fm>
Frank Murphy schrieb:
> I'm trying to migrate from a 2.4 to a 2.6 kernel, but I have one last problem
> keeping me with 2.4.25. There's a problem with adjusting screen brightness
> under X (4.3.0.dfsg.1-8).
>
> I'm running pbbuttonsd 0.6.6-2 with gtkpbbuttons 0.6.4-3 (which are tools that
> enable the LCD to be dimmed and brightened with keyboard pressed). When I'm
> running the Debian kernel-image 2.4.25-8 and I press the brightness up or
> down keys, I get the on-screen indication from gtkpbbuttons and the LCD dims
> or brightens as expected in both X and on the console. However, when I boot
> into kernel-image 2.6.8-6 or 2.6.9-1 and press the brightness keys, I get the
> on-screen indication in X, but the LCD doesn't change brightness. However, if
> I switch to a VT with a console, the brightness changes to what I tried to
> change it to. Also, pressing the brightness buttons works fine when I press
> them while in the console.
>
> My video card is a Mach64, and I'm using the 'ati' driver for X. One guess I
> have is that in 2.6, lots more things are built as kernel modules. I'd like
> to try build any needed video stuff in, but I don't know what it could be.
> Does anyone here have an idea what controls screen brightness in X?
Your mouse pointer might get some noisy spots on brightness change, ever
noticed? I would blame the kernel first (since 2.4 works well).
> The reason this is important for me is that the LCD is not dimmed when I close
> the lid for sleep, which kind of ruins the point of sleep.
>
> Does anyone have an idea of what else I need to do to get screen dimming to
> work under X with Linux 2.6?
Try to ask on the ppc-kernel list (CCed). I suspect that nobody has
reimplemented power management for mach64 in 2.6. The fact that lid
closing does not put the display to sleep keeps me locked in 2.4, too
(though I experienced that 2.6 is way faster).
I played with the thought of fixing it myself (like I plan to fix DRI
DMA some time) but was unable to allocate ressources (and enough motivation)
So take this as a "I have the problem, too" posting
Christof
^ permalink raw reply
* Re: pb booting 2.6.9 kernel on Tibook
From: wrobell @ 2004-11-26 10:29 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <41A62853.8060107@emse.fr>
On Thu, Nov 25, 2004 at 07:45:39PM +0100, Philippe Jaillon wrote:
> Hi,
>
> I have problem configuring a booting 2.6 kernel. it hang at
> "adb: starting probe task"
I've had similar problem, but after applying Ben's ibook sleep patch it has
gone.
[...]
wrobell <wrobell@pld-linux.org>
^ permalink raw reply
* Re: 440GP "Ebony" boot problems
From: Andriy Korud @ 2004-11-26 10:28 UTC (permalink / raw)
To: Eugene Surovegin; +Cc: linuxppc-embedded
In-Reply-To: <20041126083013.GA4609@gate.ebshome.net>
Thanks,
the problem was buggy OpenBIOS v 1.18 (problems with EMAC).
After upgrading to 1.19 everything works fine.
thanks,
--
Andriy Korud
On Fri, 2004-11-26 at 00:30 -0800, Eugene Surovegin wrote:
> On Fri, Nov 26, 2004 at 10:13:31AM +0100, Andriy Korud wrote:
> > - make bzImage within stock 2.6.9 gives me zImage.elf
>
> You should use arch/ppc/boot/images/zImage.ebony, not zImage.elf
>
> Correct OpenBIOS image has "\0RPO" at the beginning.
>
> --
> Eugene
>
^ permalink raw reply
* Re: 440GP "Ebony" boot problems
From: Eugene Surovegin @ 2004-11-26 8:30 UTC (permalink / raw)
To: Andriy Korud; +Cc: linuxppc-embedded
In-Reply-To: <1101460411.6134.2.camel@localhost>
On Fri, Nov 26, 2004 at 10:13:31AM +0100, Andriy Korud wrote:
> - make bzImage within stock 2.6.9 gives me zImage.elf
You should use arch/ppc/boot/images/zImage.ebony, not zImage.elf
Correct OpenBIOS image has "\0RPO" at the beginning.
--
Eugene
^ permalink raw reply
* Re: 440GP "Ebony" boot problems
From: Andriy Korud @ 2004-11-26 9:13 UTC (permalink / raw)
To: Eugene Surovegin; +Cc: linuxppc-embedded
In-Reply-To: <20041125185233.GA13325@gate.ebshome.net>
I also thought similar, but:
- make bzImage within stock 2.6.9 gives me zImage.elf
- when trying to boot Ebony with it I have:
Booting from [EMAC0] Ethernet 0 ...
Sending bootp request ...
Loading file "zImage.elf" ...
Sending tftp boot request ...
Not a valid boot image file
And I'm completely lost with this :-)
regards,
--
Andriy Korud
On Thu, 2004-11-25 at 10:52 -0800, Eugene Surovegin wrote:
> On Thu, Nov 25, 2004 at 05:18:49PM +0100, Andriy Korud wrote:
> > I'm trying to boot original 440GP "Ebony" board wiath original IBM ROM
> > Monitor:
> > ...
> > 440GP 1.18 ROM Monitor (02/11/02)
> > ...
> >
> > However I've discovered that it requires special image in KDI (Kernel
> > Downloadable Image) format. And it seems that the only way to make such
> > image is to use 'mkimage' utility from LynuxWorks which is not widely
> > available :-)
> > Can anybody help me with this?
>
> Huh? I'm away from my Ebony right now, so I cannot check which
> OpenBIOS version it has but I never heard about KDI.
>
> Image generated by the `make bzImage` in 2.4 or 2.6 official
> kernel should be bootable on Ebony with original IBM firmware.
>
> Why do you think IBM firmware requires LynuxWorks special image? This
> sounds like a nonsense, frankly.
>
> --
> Eugene
^ permalink raw reply
* [patch] Race condition #2 in arch/ppc/cpm2_io/fcc_enet.c
From: Stefan Nickl @ 2004-11-26 7:27 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1012 bytes --]
The initialisation sequence of the fcc ethernet driver contains race
condition that will crash the machine when a packet is received in the
wrong moment during system boot.
The oops usually shows ip_route_input() as the responsible function, but
that is not where things go wrong.
The problem is that when fec_enet_init() calls init_fcc_startup() during
device setup, fcc_restart() enables the receiver and the device will
start to receive packets while the rest of networking is not yet
prepared for this -> crash.
This situation can easily be created when the system is loaded with a
flood ping during boot, it will almost certainly crash (ping the
broadcast address on a isolated network to be sure the booting device
really gets it's share).
The patch moves the calls to fcc_restart() to fcc_enet_open(), so
packets will only start to come in when the kernel is ready for it.
I'm not 100% about all the implications this could have, but it seems to
work fine.
--
Stefan Nickl
Kontron Modular Computers
[-- Attachment #2: fcc_enet-startup_race.patch --]
[-- Type: text/x-patch, Size: 969 bytes --]
--- linuxppc-2.4/arch/ppc/cpm2_io/fcc_enet.c 2004-08-09 08:32:28.000000000 +0200
+++ fcc_enet.c 2004-11-25 18:41:22.000000000 +0100
@@ -2008,16 +2008,6 @@ init_fcc_startup(fcc_info_t *fip, struct
*(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_FETHIEN;
*(volatile uint *)(BCSR_ADDR + 4) |= BCSR1_FETH_RST;
#endif
-
-#if defined(CONFIG_USE_MDIO) || defined(CONFIG_TQM8260)
- /* start in full duplex mode, and negotiate speed
- */
- fcc_restart (dev, 1);
-#else
- /* start in half duplex mode
- */
- fcc_restart (dev, 0);
-#endif
}
#ifdef CONFIG_USE_MDIO
@@ -2155,6 +2145,16 @@ fcc_enet_open(struct net_device *dev)
{
struct fcc_enet_private *fep = dev->priv;
+#if defined(CONFIG_USE_MDIO) || defined(CONFIG_TQM8260)
+ /* start in full duplex mode, and negotiate speed
+ */
+ fcc_restart (dev, 1);
+#else
+ /* start in half duplex mode
+ */
+ fcc_restart (dev, 0);
+#endif
+
#ifdef CONFIG_USE_MDIO
fep->sequence_done = 0;
fep->link = 0;
^ permalink raw reply
* [patch] Race condition #1 in arch/ppc/cpm2_io/fcc_enet.c
From: Stefan Nickl @ 2004-11-26 7:27 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 636 bytes --]
According to my PHY's (lxt972) datasheet, during the second half of a
read frame on the MDIO, the PHY drives MDIO to the value of the
respective data bit at the rising edge of MDC.
The current code samples MDIO immediately after it generates the rising
edge, so a fast enough processor (like the PowerQUICC III) will not read
the corresponding response of the PHY, but the value MDIO had in the
cycle before, which amounts to all response words appearing shifted by
one bit.
The patch simply moves the udelay(1) between rising MDC and reading
MDIO, leaving the PHY enough time to respond.
--
Stefan Nickl
Kontron Modular Computers
[-- Attachment #2: fcc_enet-mdio_race.patch --]
[-- Type: text/x-patch, Size: 412 bytes --]
--- linuxppc-2.4/arch/ppc/cpm2_io/fcc_enet.c 2004-08-09 08:32:28.000000000 +0200
+++ fcc_enet.c 2004-11-25 18:28:56.000000000 +0100
@@ -2095,10 +2095,10 @@ mii_send_receive(fcc_info_t *fip, uint c
for (i = 0, off = 15; i < 16; i++, off--)
{
FCC_PDATC_MDC(1);
+ udelay(1);
retval <<= 1;
if (io->iop_pdatc & fip->fc_mdio)
retval++;
- udelay(1);
FCC_PDATC_MDC(0);
udelay(1);
}
^ permalink raw reply
* issues with cardbus on mpc5200
From: Andrew Dennison @ 2004-11-26 5:21 UTC (permalink / raw)
To: linuxppc-embedded
I'm going through the process of bringing up Linux on our mpc5200 based
hardware.
I have tweaked u-boot to support our board. DDR is working, CFI can
program the flash, irq fixups done for PCI devices and I can boot into =
an
NFS root filesystem with a DENX kernel, either 2.4.23 (with RTAI =
patches)
or top of tree 2.4.25.
My problem is cardbus.
If I enable PCMCIA support in u-boot CF cards are correctly detected in
the PCMCIA sockets (haven't tried to boot from them though).
I tweaked Linux drivers/pcmcia/yenta.c to extend the IO port range, same
as seems to have been done to yenta.c in 2.6.x, so IO resources could be
allocated.
Card services detects CF cards and loads ide-cs.o, however it fails the
ide detection.
Cardbus cards cause a TEA.
I've been progressively turning on more debugging as I wade through the
code, and I have a BDI to work with, but that doesn't help much when I
don't completely understand the problem yet:)
>From my googling I know cardbus is supported on PPC, and there appear to
be several embedded PPC systems that have a PCMCIA socket so there
shouldn't be too much I need to do to make it work, however I haven't
managed to find any relevant references... Maybe there's something in =
the
linuxppc-embedded archives:(
I thought the 5200 support in Linux was doing something unusual, as
_IO_BASE was defined as 0 instead of isa_io_base, however this seems to =
be
the thing to do for embedded ppc.
Anyone with more experience in this stuff got some ideas of where I =
should
look? My PCI setup in u-boot and Linux is unchanged from the icecube
reference, so this may be a common problem?
The PCI errata doesn't seem to be relevant to what I'm experiencing as =
the
controllers are actually being detected, unlike my cardbus PCI card in =
the
lite5200.
My previous embedded Linux design used a SC520 and all this stuff just
worked. Having to learn about more than device drivers this time:)
Thanks for any help,
Andrew
^ permalink raw reply
* [PATCH] sungem rework & wake on lan
From: Benjamin Herrenschmidt @ 2004-11-26 3:20 UTC (permalink / raw)
To: David S. Miller, Jeff Garzik; +Cc: linuxppc-dev list
Hi David, Jeff !
This patch is a rework of sungem toward simplification of the open/close
and power management mecanisms, along with getting rid of some races that
were lurking around at the same time). It also adds support for Wake-On-Lan
(Magic packets only for now, David, if you have infos about what the WOL CSR
bits actually mean, it seem it may be possible to support
unicast/multicast/broadcats WOL as well).
I also wrote a blurb at the beginning of the driver explaining some concerns
I have with locking. The driver is currently "over-locking" imho and that
could probably be improved (well, I improved the close() path already but
the open() and reset path could use some work too) though I have some concerns
about the feasibility of nicer locking with NAPI (see my comments).
Please, comment on it, but don't merge it right now, at least certainly not in
2.6.10-rc (obviously) as it definitely need to be re-tested on a lot of
the supported hardware, I only did quick tests on a pmac laptop so far.
The patch contain a small blurb in arch/ppc which is necessary to prevent the
arch PM code from switching off the clock to the GEM cell (thus breaking
wake-on-lan).
The PM changes remove the whole timer thing. The PHY is now always up (the PHYs
used by Apple all have some sort of automatic low power when no link anyway) so
packages like laptop-net will work. The chip cell clock is switched off when the
interface is down (and back up temporarily when the link timer kicks in or when
needed for other reasons, this can be done very quickly)
Patch is against 2.6.9 for now.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Index: linux-2.6.9-sleep/drivers/net/sungem_phy.c
===================================================================
--- linux-2.6.9-sleep.orig/drivers/net/sungem_phy.c 2004-10-19 13:37:28.000000000 +1000
+++ linux-2.6.9-sleep/drivers/net/sungem_phy.c 2004-11-26 13:56:30.159911152 +1100
@@ -98,25 +98,15 @@
data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
phy_write(phy, MII_BCM5201_MULTIPHY, data);
+ phy_write(phy, MII_BCM5201_INTERRUPT, 0);
+
return 0;
}
-static int bcm5201_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5201_suspend(struct mii_phy* phy)
{
- if (!wol_options)
- phy_write(phy, MII_BCM5201_INTERRUPT, 0);
-
- /* Here's a strange hack used by both MacOS 9 and X */
- phy_write(phy, MII_LPA, phy_read(phy, MII_LPA));
-
- if (!wol_options) {
-#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
- u16 val = phy_read(phy, MII_BCM5201_AUXMODE2)
- phy_write(phy, MII_BCM5201_AUXMODE2,
- val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
-#endif
- phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
- }
+ phy_write(phy, MII_BCM5201_INTERRUPT, 0);
+ phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
return 0;
}
@@ -144,6 +134,21 @@
return 0;
}
+static int bcm5221_suspend(struct mii_phy* phy)
+{
+ u16 data;
+
+ data = phy_read(phy, MII_BCM5221_TEST);
+ phy_write(phy, MII_BCM5221_TEST,
+ data | MII_BCM5221_TEST_ENABLE_SHADOWS);
+
+ data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
+ phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
+ data | MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE);
+
+ return 0;
+}
+
static int bcm5400_init(struct mii_phy* phy)
{
u16 data;
@@ -173,7 +178,7 @@
return 0;
}
-static int bcm5400_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5400_suspend(struct mii_phy* phy)
{
#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
phy_write(phy, MII_BMCR, BMCR_PDOWN);
@@ -229,7 +234,7 @@
return 0;
}
-static int bcm5401_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5401_suspend(struct mii_phy* phy)
{
#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
phy_write(phy, MII_BMCR, BMCR_PDOWN);
@@ -266,7 +271,7 @@
return 0;
}
-static int bcm5411_suspend(struct mii_phy* phy, int wol_options)
+static int bcm5411_suspend(struct mii_phy* phy)
{
phy_write(phy, MII_BMCR, BMCR_PDOWN);
@@ -662,7 +667,7 @@
/* Broadcom BCM 5221 */
static struct mii_phy_ops bcm5221_phy_ops = {
- .suspend = bcm5201_suspend,
+ .suspend = bcm5221_suspend,
.init = bcm5221_init,
.setup_aneg = genmii_setup_aneg,
.setup_forced = genmii_setup_forced,
Index: linux-2.6.9-sleep/drivers/net/sungem_phy.h
===================================================================
--- linux-2.6.9-sleep.orig/drivers/net/sungem_phy.h 2004-10-19 13:37:56.000000000 +1000
+++ linux-2.6.9-sleep/drivers/net/sungem_phy.h 2004-11-26 13:56:30.160911000 +1100
@@ -7,7 +7,7 @@
struct mii_phy_ops
{
int (*init)(struct mii_phy *phy);
- int (*suspend)(struct mii_phy *phy, int wol_options);
+ int (*suspend)(struct mii_phy *phy);
int (*setup_aneg)(struct mii_phy *phy, u32 advertise);
int (*setup_forced)(struct mii_phy *phy, int speed, int fd);
int (*poll_link)(struct mii_phy *phy);
@@ -80,6 +80,7 @@
#define MII_BCM5221_SHDOW_AUX_STAT2 0x1b
#define MII_BCM5221_SHDOW_AUX_STAT2_APD 0x0020
#define MII_BCM5221_SHDOW_AUX_MODE4 0x1a
+#define MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE 0x0001
#define MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR 0x0004
/* MII BCM5400 1000-BASET Control register */
Index: linux-2.6.9-sleep/drivers/net/sungem.c
===================================================================
--- linux-2.6.9-sleep.orig/drivers/net/sungem.c 2004-10-19 13:38:05.000000000 +1000
+++ linux-2.6.9-sleep/drivers/net/sungem.c 2004-11-26 14:17:08.013728768 +1100
@@ -10,9 +10,24 @@
* (C) 2004 by Eric Lemoine (eric.lemoine@gmail.com)
*
* TODO:
- * - Get rid of all those nasty mdelay's and replace them
- * with schedule_timeout.
- * - Implement WOL
+ * - Now that the driver was significantly simplified, I need to rework
+ * the locking. I'm sure we don't need _2_ spinlocks, and we probably
+ * can avoid taking most of them for so long period of time (and schedule
+ * instead). The main issues at this point are caused by the netdev layer
+ * though:
+ *
+ * gem_change_mtu() and gem_set_multicast() are called with a read_lock()
+ * help by net/core/dev.c, thus they can't schedule. That means they can't
+ * call netif_poll_disable() neither, thus force gem_poll() to keep a spinlock
+ * where it could have been dropped. change_mtu especially would love also to
+ * be able to msleep instead of horrid locked delays when resetting the HW,
+ * but that read_lock() makes it impossible, unless I defer it's action to
+ * the reset task, which means it'll be asynchronous (won't take effect until
+ * the system schedules a bit).
+ *
+ * Also, it would probably be possible to also remove most of the long-life
+ * locking in open/resume code path (gem_reinit_chip) by beeing more careful
+ * about when we can start taking interrupts or get xmit() called...
*/
#include <linux/module.h>
@@ -196,6 +211,29 @@
writel(GREG_STAT_NAPI | GREG_STAT_TXDONE, gp->regs + GREG_IMASK);
}
+static void gem_get_cell(struct gem *gp)
+{
+ gp->cell_enabled++;
+#ifdef CONFIG_PPC_PMAC
+ if (gp->cell_enabled == 1) {
+ mb();
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 1);
+ udelay(10);
+ }
+#endif /* CONFIG_PPC_PMAC */
+}
+
+/* Turn off the chip's clock */
+static void gem_put_cell(struct gem *gp)
+{
+ gp->cell_enabled--;
+ BUG_ON(gp->cell_enabled < 0);
+#ifdef CONFIG_PPC_PMAC
+ if (gp->cell_enabled == 0)
+ pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
+#endif /* CONFIG_PPC_PMAC */
+}
+
static void gem_handle_mif_event(struct gem *gp, u32 reg_val, u32 changed_bits)
{
if (netif_msg_intr(gp))
@@ -597,7 +635,7 @@
return 0;
do_reset:
- gp->reset_task_pending = 2;
+ gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
return 1;
@@ -823,6 +861,9 @@
struct gem *gp = dev->priv;
unsigned long flags;
+ /*
+ * NAPI locking nightmare: See comment at head of driver
+ */
spin_lock_irqsave(&gp->lock, flags);
do {
@@ -874,8 +915,11 @@
struct gem *gp = dev->priv;
unsigned long flags;
- /* Swallow interrupts when shutting the chip down */
- if (!gp->hw_running)
+ /* Swallow interrupts when shutting the chip down, though
+ * that shouldn't happen, we should have done free_irq() at
+ * this point...
+ */
+ if (!gp->running)
return IRQ_HANDLED;
spin_lock_irqsave(&gp->lock, flags);
@@ -916,7 +960,7 @@
struct gem *gp = dev->priv;
printk(KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
- if (!gp->hw_running) {
+ if (!gp->running) {
printk("%s: hrm.. hw not running !\n", dev->name);
return;
}
@@ -934,7 +978,7 @@
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
- gp->reset_task_pending = 2;
+ gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
spin_unlock(&gp->tx_lock);
@@ -975,6 +1019,11 @@
local_irq_restore(flags);
return NETDEV_TX_LOCKED;
}
+ /* We raced with gem_do_stop() */
+ if (!gp->running) {
+ spin_unlock_irqrestore(&gp->tx_lock, flags);
+ return NETDEV_TX_BUSY;
+ }
/* This is a hard error, log it. */
if (TX_BUFFS_AVAIL(gp) <= (skb_shinfo(skb)->nr_frags + 1)) {
@@ -1073,46 +1122,10 @@
return NETDEV_TX_OK;
}
-/* Jumbo-grams don't seem to work :-( */
-#define GEM_MIN_MTU 68
-#if 1
-#define GEM_MAX_MTU 1500
-#else
-#define GEM_MAX_MTU 9000
-#endif
-
-static int gem_change_mtu(struct net_device *dev, int new_mtu)
-{
- struct gem *gp = dev->priv;
-
- if (new_mtu < GEM_MIN_MTU || new_mtu > GEM_MAX_MTU)
- return -EINVAL;
-
- if (!netif_running(dev) || !netif_device_present(dev)) {
- /* We'll just catch it later when the
- * device is up'd or resumed.
- */
- dev->mtu = new_mtu;
- return 0;
- }
-
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
- dev->mtu = new_mtu;
- gp->reset_task_pending = 1;
- schedule_work(&gp->reset_task);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
-
- flush_scheduled_work();
-
- return 0;
-}
-
#define STOP_TRIES 32
/* Must be invoked under gp->lock and gp->tx_lock. */
-static void gem_stop(struct gem *gp)
+static void gem_reset(struct gem *gp)
{
int limit;
u32 val;
@@ -1140,7 +1153,7 @@
/* Must be invoked under gp->lock and gp->tx_lock. */
static void gem_start_dma(struct gem *gp)
{
- unsigned long val;
+ u32 val;
/* We are ready to rock, turn everything on. */
val = readl(gp->regs + TXDMA_CFG);
@@ -1155,10 +1168,31 @@
(void) readl(gp->regs + MAC_RXCFG);
udelay(100);
- writel(GREG_STAT_TXDONE, gp->regs + GREG_IMASK);
+ gem_enable_ints(gp);
writel(RX_RING_SIZE - 4, gp->regs + RXDMA_KICK);
+}
+
+/* Must be invoked under gp->lock and gp->tx_lock. DMA won't be
+ * actually stopped before about 4ms tho ...
+ */
+static void gem_stop_dma(struct gem *gp)
+{
+ u32 val;
+
+ /* We are done rocking, turn everything off. */
+ val = readl(gp->regs + TXDMA_CFG);
+ writel(val & ~TXDMA_CFG_ENABLE, gp->regs + TXDMA_CFG);
+ val = readl(gp->regs + RXDMA_CFG);
+ writel(val & ~RXDMA_CFG_ENABLE, gp->regs + RXDMA_CFG);
+ val = readl(gp->regs + MAC_TXCFG);
+ writel(val & ~MAC_TXCFG_ENAB, gp->regs + MAC_TXCFG);
+ val = readl(gp->regs + MAC_RXCFG);
+ writel(val & ~MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
+
+ (void) readl(gp->regs + MAC_RXCFG);
+ /* Need to wait a bit ... done by the caller */
}
@@ -1219,10 +1253,10 @@
if (speed == 0)
speed = SPEED_10;
- /* If HW is down, we don't try to actually setup the PHY, we
+ /* If we are asleep, we don't try to actually setup the PHY, we
* just store the settings
*/
- if (!gp->hw_running) {
+ if (gp->asleep) {
gp->phy_mii.autoneg = gp->want_autoneg = autoneg;
gp->phy_mii.speed = speed;
gp->phy_mii.duplex = duplex;
@@ -1279,6 +1313,9 @@
printk(KERN_INFO "%s: Link is up at %d Mbps, %s-duplex.\n",
gp->dev->name, speed, (full_duplex ? "full" : "half"));
+ if (!gp->running)
+ return 0;
+
val = (MAC_TXCFG_EIPG0 | MAC_TXCFG_NGU);
if (full_duplex) {
val |= (MAC_TXCFG_ICS | MAC_TXCFG_ICOLL);
@@ -1405,48 +1442,19 @@
}
}
-static void gem_init_rings(struct gem *);
-static void gem_init_hw(struct gem *, int);
-
-static void gem_reset_task(void *data)
-{
- struct gem *gp = (struct gem *) data;
-
- netif_poll_disable(gp->dev);
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
-
- if (gp->hw_running && gp->opened) {
- netif_stop_queue(gp->dev);
-
- /* Reset the chip & rings */
- gem_stop(gp);
- gem_init_rings(gp);
-
- gem_init_hw(gp,
- (gp->reset_task_pending == 2));
-
- netif_wake_queue(gp->dev);
- }
- gp->reset_task_pending = 0;
-
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
- netif_poll_enable(gp->dev);
-}
-
static void gem_link_timer(unsigned long data)
{
struct gem *gp = (struct gem *) data;
int restart_aneg = 0;
- if (!gp->hw_running)
+ if (gp->asleep)
return;
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
+ gem_get_cell(gp);
- /* If the link of task is still pending, we just
+ /* If the reset task is still pending, we just
* reschedule the link timer
*/
if (gp->reset_task_pending)
@@ -1462,8 +1470,7 @@
if ((val & PCS_MIISTAT_LS) != 0) {
gp->lstate = link_up;
netif_carrier_on(gp->dev);
- if (gp->opened)
- (void)gem_set_link_modes(gp);
+ (void)gem_set_link_modes(gp);
}
goto restart;
}
@@ -1484,7 +1491,7 @@
} else if (gp->lstate != link_up) {
gp->lstate = link_up;
netif_carrier_on(gp->dev);
- if (gp->opened && gem_set_link_modes(gp))
+ if (gem_set_link_modes(gp))
restart_aneg = 1;
}
} else {
@@ -1497,7 +1504,7 @@
printk(KERN_INFO "%s: Link down\n",
gp->dev->name);
netif_carrier_off(gp->dev);
- gp->reset_task_pending = 2;
+ gp->reset_task_pending = 1;
schedule_work(&gp->reset_task);
restart_aneg = 1;
} else if (++gp->timer_ticks > 10) {
@@ -1514,6 +1521,7 @@
restart:
mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
out_unlock:
+ gem_put_cell(gp);
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
}
@@ -1619,59 +1627,40 @@
wmb();
}
-/* Must be invoked under gp->lock and gp->tx_lock. */
+/* Init PHY interface and start link poll state machine */
static void gem_init_phy(struct gem *gp)
{
u32 mifcfg;
-
+
/* Revert MIF CFG setting done on stop_phy */
mifcfg = readl(gp->regs + MIF_CFG);
mifcfg &= ~MIF_CFG_BBMODE;
writel(mifcfg, gp->regs + MIF_CFG);
-#ifdef CONFIG_PPC_PMAC
if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
- int i, j;
+ int i;
/* Those delay sucks, the HW seem to love them though, I'll
* serisouly consider breaking some locks here to be able
* to schedule instead
*/
- pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
- for (j = 0; j < 3; j++) {
+ for (i = 0; i < 3; i++) {
+#ifdef CONFIG_PPC_PMAC
+ pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
+ msleep(20);
+#endif
/* Some PHYs used by apple have problem getting back to us,
- * we _know_ it's actually at addr 0 or 1, that's a hack, but
- * it helps to do that reset now. I suspect some motherboards
- * don't wire the PHY reset line properly, thus the PHY doesn't
- * come back with the above pmac_call_feature.
+ * we do an additional reset here
*/
- gp->mii_phy_addr = 0;
- phy_write(gp, MII_BMCR, BMCR_RESET);
- gp->mii_phy_addr = 1;
phy_write(gp, MII_BMCR, BMCR_RESET);
- /* We should probably break some locks here and schedule... */
- mdelay(10);
-
- /* On K2, we only probe the internal PHY at address 1, other
- * addresses tend to return garbage.
- */
- if (gp->pdev->device == PCI_DEVICE_ID_APPLE_K2_GMAC)
+ msleep(20);
+ if (phy_read(gp, MII_BMCR) != 0xffff)
break;
-
- for (i = 0; i < 32; i++) {
- gp->mii_phy_addr = i;
- if (phy_read(gp, MII_BMCR) != 0xffff)
- break;
- }
- if (i == 32) {
+ if (i == 2)
printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
gp->dev->name);
- gp->mii_phy_addr = 0;
- } else
- break;
}
}
-#endif /* CONFIG_PPC_PMAC */
if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
gp->pdev->device == PCI_DEVICE_ID_SUN_GEM) {
@@ -1755,6 +1744,16 @@
val |= PCS_SCTRL_LOOP;
writel(val, gp->regs + PCS_SCTRL);
}
+
+ /* Default aneg parameters */
+ gp->timer_ticks = 0;
+ gp->lstate = link_down;
+ netif_carrier_off(gp->dev);
+
+ /* Can I advertise gigabit here ? I'd need BCM PHY docs... */
+ spin_lock_irq(&gp->lock);
+ gem_begin_auto_negotiation(gp, NULL);
+ spin_unlock_irq(&gp->lock);
}
/* Must be invoked under gp->lock and gp->tx_lock. */
@@ -1796,8 +1795,7 @@
}
/* Must be invoked under gp->lock and gp->tx_lock. */
-static u32
-gem_setup_multicast(struct gem *gp)
+static u32 gem_setup_multicast(struct gem *gp)
{
u32 rxcfg = 0;
int i;
@@ -1914,6 +1912,10 @@
* make no use of those events other than to record them.
*/
writel(0xffffffff, gp->regs + MAC_MCMASK);
+
+ /* Don't enable GEM's WOL in normal operations
+ */
+ writel(0, gp->regs + WOL_WAKECSR);
}
/* Must be invoked under gp->lock and gp->tx_lock. */
@@ -1975,6 +1977,23 @@
gp->tx_fifo_sz = readl(gp->regs + TXDMA_FSZ) * 64;
gp->rx_fifo_sz = readl(gp->regs + RXDMA_FSZ) * 64;
gp->swrst_base = 0;
+
+ mif_cfg = readl(gp->regs + MIF_CFG);
+ mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1);
+ mif_cfg |= MIF_CFG_MDI0;
+ writel(mif_cfg, gp->regs + MIF_CFG);
+ writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
+ writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
+
+ /* We hard-code the PHY address so we can properly bring it out of
+ * reset later on, we can't really probe it at this point, though
+ * that isn't an issue.
+ */
+ if (gp->pdev->device == PCI_DEVICE_ID_APPLE_K2_GMAC)
+ gp->mii_phy_addr = 1;
+ else
+ gp->mii_phy_addr = 0;
+
return 0;
}
@@ -2053,68 +2072,28 @@
}
/* Must be invoked under gp->lock and gp->tx_lock. */
-static void gem_init_hw(struct gem *gp, int restart_link)
+static void gem_reinit_chip(struct gem *gp)
{
- /* On Apple's gmac, I initialize the PHY only after
- * setting up the chip. It appears the gigabit PHYs
- * don't quite like beeing talked to on the GII when
- * the chip is not running, I suspect it might not
- * be clocked at that point. --BenH
- */
- if (restart_link)
- gem_init_phy(gp);
- gem_init_pause_thresholds(gp);
- gem_init_dma(gp);
- gem_init_mac(gp);
-
- if (restart_link) {
- /* Default aneg parameters */
- gp->timer_ticks = 0;
- gp->lstate = link_down;
- netif_carrier_off(gp->dev);
-
- /* Can I advertise gigabit here ? I'd need BCM PHY docs... */
- gem_begin_auto_negotiation(gp, NULL);
- } else {
- if (gp->lstate == link_up) {
- netif_carrier_on(gp->dev);
- gem_set_link_modes(gp);
- }
- }
-}
+ /* Reset the chip */
+ gem_reset(gp);
-#ifdef CONFIG_PPC_PMAC
-/* Enable the chip's clock and make sure it's config space is
- * setup properly. There appear to be no need to restore the
- * base addresses.
- */
-static void gem_apple_powerup(struct gem *gp)
-{
- u32 mif_cfg;
+ /* Make sure ints are disabled */
+ gem_disable_ints(gp);
- mb();
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 1);
+ /* Allocate & setup ring buffers */
+ gem_init_rings(gp);
- udelay(3);
-
- mif_cfg = readl(gp->regs + MIF_CFG);
- mif_cfg &= ~(MIF_CFG_PSELECT|MIF_CFG_POLL|MIF_CFG_BBMODE|MIF_CFG_MDI1);
- mif_cfg |= MIF_CFG_MDI0;
- writel(mif_cfg, gp->regs + MIF_CFG);
- writel(PCS_DMODE_MGM, gp->regs + PCS_DMODE);
- writel(MAC_XIFCFG_OE, gp->regs + MAC_XIFCFG);
-}
+ /* Configure pause thresholds */
+ gem_init_pause_thresholds(gp);
-/* Turn off the chip's clock */
-static void gem_apple_powerdown(struct gem *gp)
-{
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, gp->of_node, 0, 0);
+ /* Init DMA & MAC engines */
+ gem_init_dma(gp);
+ gem_init_mac(gp);
}
-#endif /* CONFIG_PPC_PMAC */
/* Must be invoked with no lock held. */
-static void gem_stop_phy(struct gem *gp)
+static void gem_stop_phy(struct gem *gp, int wol)
{
u32 mifcfg;
unsigned long flags;
@@ -2131,8 +2110,22 @@
mifcfg &= ~MIF_CFG_POLL;
writel(mifcfg, gp->regs + MIF_CFG);
- if (gp->wake_on_lan) {
- /* Setup wake-on-lan */
+ if (wol) {
+ unsigned char *e = &gp->dev->dev_addr[0];
+ u32 csr;
+
+ /* Setup wake-on-lan for MAGIC packet */
+ writel(MAC_RXCFG_HFE | MAC_RXCFG_SFCS | MAC_RXCFG_ENAB,
+ gp->regs + MAC_RXCFG);
+ writel((e[4] << 8) | e[5], gp->regs + WOL_MATCH0);
+ writel((e[2] << 8) | e[3], gp->regs + WOL_MATCH1);
+ writel((e[0] << 8) | e[1], gp->regs + WOL_MATCH2);
+
+ writel(WOL_MCOUNT_N | WOL_MCOUNT_M, gp->regs + WOL_MCOUNT);
+ csr = WOL_WAKECSR_ENABLE;
+ if ((readl(gp->regs + MAC_XIFCFG) & MAC_XIFCFG_GMII) == 0)
+ csr |= WOL_WAKECSR_MII;
+ writel(csr, gp->regs + WOL_WAKECSR);
} else {
writel(0, gp->regs + MAC_RXCFG);
(void)readl(gp->regs + MAC_RXCFG);
@@ -2148,10 +2141,11 @@
writel(0, gp->regs + TXDMA_CFG);
writel(0, gp->regs + RXDMA_CFG);
- if (!gp->wake_on_lan) {
+ /* No need to take the lock here */
+ if (!wol) {
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
- gem_stop(gp);
+ gem_reset(gp);
writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST);
writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST);
spin_unlock(&gp->tx_lock);
@@ -2159,9 +2153,9 @@
}
if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend)
- gp->phy_mii.def->ops->suspend(&gp->phy_mii, 0 /* wake on lan options */);
+ gp->phy_mii.def->ops->suspend(&gp->phy_mii);
- if (!gp->wake_on_lan) {
+ if (!wol) {
/* According to Apple, we must set the MDIO pins to this begnign
* state or we may 1) eat more current, 2) damage some PHYs
*/
@@ -2174,181 +2168,160 @@
}
}
-/* Shut down the chip, must be called with pm_sem held. */
-static void gem_shutdown(struct gem *gp)
+
+static int gem_do_start(struct net_device *dev)
{
- /* Make us not-running to avoid timers respawning
- * and swallow irqs
- */
- gp->hw_running = 0;
- wmb();
+ struct gem *gp = dev->priv;
+ unsigned long flags;
- /* Stop the link timer */
- del_timer_sync(&gp->link_timer);
+ spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
- /* Stop the reset task */
- while (gp->reset_task_pending)
- yield();
-
- /* Actually stop the chip */
- if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
- gem_stop_phy(gp);
+ /* Enable the cell */
+ gem_get_cell(gp);
-#ifdef CONFIG_PPC_PMAC
- /* Power down the chip */
- gem_apple_powerdown(gp);
-#endif /* CONFIG_PPC_PMAC */
- } else{
- unsigned long flags;
+ /* Init & setup chip hardware */
+ gem_reinit_chip(gp);
+
+ gp->running = 1;
+
+ if (gp->lstate == link_up) {
+ netif_carrier_on(gp->dev);
+ gem_set_link_modes(gp);
+ }
+
+ netif_wake_queue(gp->dev);
+
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irqrestore(&gp->lock, flags);
+
+ if (request_irq(gp->pdev->irq, gem_interrupt,
+ SA_SHIRQ, dev->name, (void *)dev)) {
+ printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
spin_lock_irqsave(&gp->lock, flags);
spin_lock(&gp->tx_lock);
- gem_stop(gp);
+
+ gp->running = 0;
+ gem_reset(gp);
+ gem_clean_rings(gp);
+ gem_put_cell(gp);
+
spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags);
+
+ return -EAGAIN;
}
+
+ return 0;
}
-static void gem_pm_task(void *data)
+static void gem_do_stop(struct net_device *dev, int wol)
{
- struct gem *gp = (struct gem *) data;
+ struct gem *gp = dev->priv;
+ unsigned long flags;
- /* We assume if we can't lock the pm_sem, then open() was
- * called again (or suspend()), and we can safely ignore
- * the PM request
- */
- if (down_trylock(&gp->pm_sem))
- return;
+ spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
- /* Driver was re-opened or already shut down */
- if (gp->opened || !gp->hw_running) {
- up(&gp->pm_sem);
- return;
- }
+ gp->running = 0;
- gem_shutdown(gp);
+ /* Stop netif queue */
+ netif_stop_queue(dev);
- up(&gp->pm_sem);
-}
+ /* Make sure ints are disabled */
+ gem_disable_ints(gp);
-static void gem_pm_timer(unsigned long data)
-{
- struct gem *gp = (struct gem *) data;
+ /* We can drop the lock now */
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irqrestore(&gp->lock, flags);
+
+ /* If we are going to sleep with WOL */
+ if (wol)
+ gem_stop_dma(gp);
+ else
+ gem_reset(gp);
+ msleep(10);
+
+ /* Get rid of rings */
+ gem_clean_rings(gp);
+
+ /* No irq needed anymore */
+ free_irq(gp->pdev->irq, (void *) dev);
- schedule_work(&gp->pm_task);
+ /* Cell not needed neither if no WOL */
+ if (!wol) {
+ spin_lock_irqsave(&gp->lock, flags);
+ gem_put_cell(gp);
+ spin_unlock_irqrestore(&gp->lock, flags);
+ }
}
-static int gem_open(struct net_device *dev)
+static void gem_reset_task(void *data)
{
- struct gem *gp = dev->priv;
- int hw_was_up;
+ struct gem *gp = (struct gem *) data;
down(&gp->pm_sem);
- hw_was_up = gp->hw_running;
+ netif_poll_disable(gp->dev);
- /* Stop the PM timer/task */
- del_timer(&gp->pm_timer);
- flush_scheduled_work();
+ spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
- /* The power-management semaphore protects the hw_running
- * etc. state so it is safe to do this bit without gp->lock
- */
- if (!gp->hw_running) {
-#ifdef CONFIG_PPC_PMAC
- /* First, we need to bring up the chip */
- if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
- gem_apple_powerup(gp);
- gem_check_invariants(gp);
- }
-#endif /* CONFIG_PPC_PMAC */
+ if (gp->running == 0)
+ goto not_running;
- /* Reset the chip */
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
- gem_stop(gp);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
+ if (gp->running) {
+ netif_stop_queue(gp->dev);
- gp->hw_running = 1;
+ /* Reset the chip & rings */
+ gem_reinit_chip(gp);
+ if (gp->lstate == link_up)
+ gem_set_link_modes(gp);
+ netif_wake_queue(gp->dev);
}
+ not_running:
+ gp->reset_task_pending = 0;
- /* We can now request the interrupt as we know it's masked
- * on the controller
- */
- if (request_irq(gp->pdev->irq, gem_interrupt,
- SA_SHIRQ, dev->name, (void *)dev)) {
- printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irq(&gp->lock);
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
-#ifdef CONFIG_PPC_PMAC
- if (!hw_was_up && gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
- gem_apple_powerdown(gp);
-#endif /* CONFIG_PPC_PMAC */
- /* Fire the PM timer that will shut us down in about 10 seconds */
- gp->pm_timer.expires = jiffies + 10*HZ;
- add_timer(&gp->pm_timer);
- up(&gp->pm_sem);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
-
- return -EAGAIN;
- }
+ netif_poll_enable(gp->dev);
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ up(&gp->pm_sem);
+}
- /* Allocate & setup ring buffers */
- gem_init_rings(gp);
- /* Init & setup chip hardware */
- gem_init_hw(gp, !hw_was_up);
+static int gem_open(struct net_device *dev)
+{
+ struct gem *gp = dev->priv;
+ int rc = 0;
- gp->opened = 1;
+ down(&gp->pm_sem);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
+ /* We need the cell enabled */
+ if (!gp->asleep)
+ rc = gem_do_start(dev);
+ gp->opened = (rc == 0);
up(&gp->pm_sem);
- return 0;
+ return rc;
}
static int gem_close(struct net_device *dev)
{
struct gem *gp = dev->priv;
- /* Make sure we don't get distracted by suspend/resume */
- down(&gp->pm_sem);
-
/* Note: we don't need to call netif_poll_disable() here because
* our caller (dev_close) already did it for us
*/
- /* Stop traffic, mark us closed */
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ down(&gp->pm_sem);
gp->opened = 0;
-
- netif_stop_queue(dev);
-
- /* Stop chip */
- gem_stop(gp);
-
- /* Get rid of rings */
- gem_clean_rings(gp);
-
- /* Bye, the pm timer will finish the job */
- free_irq(gp->pdev->irq, (void *) dev);
-
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
-
- /* Fire the PM timer that will shut us down in about 10 seconds */
- gp->pm_timer.expires = jiffies + 10*HZ;
- add_timer(&gp->pm_timer);
+ if (!gp->asleep)
+ gem_do_stop(dev, 0);
up(&gp->pm_sem);
@@ -2360,45 +2333,63 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct gem *gp = dev->priv;
+ unsigned long flags;
- netif_poll_disable(dev);
-
- /* We hold the PM semaphore during entire driver
- * sleep time
- */
down(&gp->pm_sem);
+ netif_poll_disable(dev);
+
printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
- dev->name, gp->wake_on_lan ? "enabled" : "disabled");
+ dev->name,
+ (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
- /* If the driver is opened, we stop the DMA */
- if (gp->opened) {
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ /* Keep the cell enabled during the entire operation */
+ spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
+ gem_get_cell(gp);
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irqrestore(&gp->lock, flags);
+ /* If the driver is opened, we stop the MAC */
+ if (gp->opened) {
/* Stop traffic, mark us closed */
netif_device_detach(dev);
- /* Stop chip */
- gem_stop(gp);
+ /* Switch off MAC, remember WOL setting */
+ gp->asleep_wol = gp->wake_on_lan;
+ gem_do_stop(dev, gp->asleep_wol);
+ msleep(10);
+ } else
+ gp->asleep_wol = 0;
- /* Get rid of ring buffers */
- gem_clean_rings(gp);
+ /* Mark us asleep */
+ gp->asleep = 1;
+ wmb();
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
+ /* Stop the link timer */
+ del_timer_sync(&gp->link_timer);
- if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
- disable_irq(gp->pdev->irq);
- }
+ /* Now we release the semaphore to not block the reset task who
+ * can take it too. We are marked asleep, so there will be no
+ * conflict here
+ */
+ up(&gp->pm_sem);
- if (gp->hw_running) {
- /* Kill PM timer if any */
- del_timer_sync(&gp->pm_timer);
- flush_scheduled_work();
+ /* Wait for a pending reset task to complete */
+ while (gp->reset_task_pending)
+ yield();
+ flush_scheduled_work();
- gem_shutdown(gp);
- }
+ /* Shut the PHY down eventually and setup WOL */
+ gem_stop_phy(gp, gp->asleep_wol);
+
+ /* Make sure bus master is disabled */
+ pci_disable_device(gp->pdev);
+
+ /* Release the cell, no need to take a lock at this point since
+ * nothing else can happen now
+ */
+ gem_put_cell(gp);
return 0;
}
@@ -2407,36 +2398,74 @@
{
struct net_device *dev = pci_get_drvdata(pdev);
struct gem *gp = dev->priv;
+ unsigned long flags;
printk(KERN_INFO "%s: resuming\n", dev->name);
- if (gp->opened) {
-#ifdef CONFIG_PPC_PMAC
- /* First, we need to bring up the chip */
- if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
- gem_apple_powerup(gp);
- gem_check_invariants(gp);
- }
-#endif /* CONFIG_PPC_PMAC */
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ down(&gp->pm_sem);
- gem_stop(gp);
- gp->hw_running = 1;
- gem_init_rings(gp);
- gem_init_hw(gp, 1);
+ /* Keep the cell enabled during the entire operation, no need to
+ * take a lock here tho since nothing else can happen while we are
+ * marked asleep
+ */
+ gem_get_cell(gp);
+
+ /* Make sure PCI access and bus master are enabled */
+ if (pci_enable_device(gp->pdev)) {
+ printk(KERN_ERR "%s: Can't re-enable chip !\n",
+ dev->name);
+ /* Put cell and forget it for now, it will be considered as
+ * still asleep, a new sleep cycle may bring it back
+ */
+ gem_put_cell(gp);
+ up(&gp->pm_sem);
+ return 0;
+ }
+ pci_set_master(gp->pdev);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
+ /* Reset everything */
+ gem_reset(gp);
+
+ /* Mark us woken up */
+ gp->asleep = 0;
+ wmb();
+
+ /* Bring the PHY back. Again, lock is useless at this point as
+ * nothing can be happening until we restart the whole thing
+ */
+ gem_init_phy(gp);
+
+ /* If we were opened, bring everything back */
+ if (gp->opened) {
+ /* Restart MAC */
+ gem_do_start(dev);
+ /* Re-attach net device */
netif_device_attach(dev);
- if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE)
- enable_irq(gp->pdev->irq);
+
}
- up(&gp->pm_sem);
+
+ spin_lock_irqsave(&gp->lock, flags);
+ spin_lock(&gp->tx_lock);
+
+ /* If we had WOL enabled, the cell clock was never turned off during
+ * sleep, so we end up beeing unbalanced. Fix that here
+ */
+ if (gp->asleep_wol)
+ gem_put_cell(gp);
+
+ /* This function doesn't need to hold the cell, it will be held if the
+ * driver is open by gem_do_start().
+ */
+ gem_put_cell(gp);
+
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irqrestore(&gp->lock, flags);
netif_poll_enable(dev);
+ up(&gp->pm_sem);
+
return 0;
}
#endif /* CONFIG_PM */
@@ -2449,7 +2478,10 @@
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
- if (gp->hw_running) {
+ /* I have seen this being called while the PM was in progress,
+ * so we shield against this
+ */
+ if (gp->running) {
stats->rx_crc_errors += readl(gp->regs + MAC_FCSERR);
writel(0, gp->regs + MAC_FCSERR);
@@ -2479,12 +2511,12 @@
u32 rxcfg, rxcfg_new;
int limit = 10000;
- if (!gp->hw_running)
- return;
-
spin_lock_irq(&gp->lock);
spin_lock(&gp->tx_lock);
+ if (!gp->running)
+ goto bail;
+
netif_stop_queue(dev);
rxcfg = readl(gp->regs + MAC_RXCFG);
@@ -2507,9 +2539,46 @@
writel(rxcfg, gp->regs + MAC_RXCFG);
netif_wake_queue(dev);
+ bail:
+ spin_unlock(&gp->tx_lock);
+ spin_unlock_irq(&gp->lock);
+}
+
+/* Jumbo-grams don't seem to work :-( */
+#define GEM_MIN_MTU 68
+#if 1
+#define GEM_MAX_MTU 1500
+#else
+#define GEM_MAX_MTU 9000
+#endif
+
+static int gem_change_mtu(struct net_device *dev, int new_mtu)
+{
+ struct gem *gp = dev->priv;
+
+ if (new_mtu < GEM_MIN_MTU || new_mtu > GEM_MAX_MTU)
+ return -EINVAL;
+
+ if (!netif_running(dev) || !netif_device_present(dev)) {
+ /* We'll just catch it later when the
+ * device is up'd or resumed.
+ */
+ dev->mtu = new_mtu;
+ return 0;
+ }
+ spin_lock_irq(&gp->lock);
+ spin_lock(&gp->tx_lock);
+ dev->mtu = new_mtu;
+ if (gp->running) {
+ gem_reinit_chip(gp);
+ if (gp->lstate == link_up)
+ gem_set_link_modes(gp);
+ }
spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
+
+ return 0;
}
static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -2540,7 +2609,6 @@
/* Return current PHY settings */
spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
cmd->autoneg = gp->want_autoneg;
cmd->speed = gp->phy_mii.speed;
cmd->duplex = gp->phy_mii.duplex;
@@ -2552,7 +2620,6 @@
*/
if (cmd->advertising == 0)
cmd->advertising = cmd->supported;
- spin_unlock(&gp->tx_lock);
spin_unlock_irq(&gp->lock);
} else { // XXX PCS ?
cmd->supported =
@@ -2592,9 +2659,9 @@
/* Apply settings and restart link process. */
spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ gem_get_cell(gp);
gem_begin_auto_negotiation(gp, cmd);
- spin_unlock(&gp->tx_lock);
+ gem_put_cell(gp);
spin_unlock_irq(&gp->lock);
return 0;
@@ -2609,9 +2676,9 @@
/* Restart link process. */
spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
+ gem_get_cell(gp);
gem_begin_auto_negotiation(gp, NULL);
- spin_unlock(&gp->tx_lock);
+ gem_put_cell(gp);
spin_unlock_irq(&gp->lock);
return 0;
@@ -2628,7 +2695,31 @@
struct gem *gp = dev->priv;
gp->msg_enable = value;
}
-
+
+
+/* Add more when I understand how to program the chip */
+/* like WAKE_UCAST | WAKE_MCAST | WAKE_BCAST */
+
+#define WOL_SUPPORTED_MASK (WAKE_MAGIC)
+
+static void gem_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct gem *gp = dev->priv;
+
+ /* Add more when I understand how to program the chip */
+ wol->supported = WOL_SUPPORTED_MASK;
+ wol->wolopts = gp->wake_on_lan;
+}
+
+static int gem_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct gem *gp = dev->priv;
+
+ gp->wake_on_lan = wol->wolopts & WOL_SUPPORTED_MASK;
+
+ return 0;
+}
+
static struct ethtool_ops gem_ethtool_ops = {
.get_drvinfo = gem_get_drvinfo,
.get_link = ethtool_op_get_link,
@@ -2637,6 +2728,8 @@
.nway_reset = gem_nway_reset,
.get_msglevel = gem_get_msglevel,
.set_msglevel = gem_set_msglevel,
+ .get_wol = gem_get_wol,
+ .set_wol = gem_set_wol,
};
static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -2644,22 +2737,28 @@
struct gem *gp = dev->priv;
struct mii_ioctl_data *data = if_mii(ifr);
int rc = -EOPNOTSUPP;
-
+ unsigned long flags;
+
/* Hold the PM semaphore while doing ioctl's or we may collide
- * with open/close and power management and oops.
+ * with power management.
*/
down(&gp->pm_sem);
-
+
+ spin_lock_irqsave(&gp->lock, flags);
+ gem_get_cell(gp);
+ spin_unlock_irqrestore(&gp->lock, flags);
+
switch (cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = gp->mii_phy_addr;
/* Fallthrough... */
case SIOCGMIIREG: /* Read MII PHY register. */
- if (!gp->hw_running)
- rc = -EIO;
+ if (!gp->running)
+ rc = -EAGAIN;
else {
- data->val_out = __phy_read(gp, data->phy_id & 0x1f, data->reg_num & 0x1f);
+ data->val_out = __phy_read(gp, data->phy_id & 0x1f,
+ data->reg_num & 0x1f);
rc = 0;
}
break;
@@ -2667,14 +2766,19 @@
case SIOCSMIIREG: /* Write MII PHY register. */
if (!capable(CAP_NET_ADMIN))
rc = -EPERM;
- else if (!gp->hw_running)
- rc = -EIO;
+ else if (!gp->running)
+ rc = -EAGAIN;
else {
- __phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
+ __phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f,
+ data->val_in);
rc = 0;
}
break;
};
+
+ spin_lock_irqsave(&gp->lock, flags);
+ gem_put_cell(gp);
+ spin_unlock_irqrestore(&gp->lock, flags);
up(&gp->pm_sem);
@@ -2779,6 +2883,47 @@
return 0;
}
+static void __devexit gem_remove_one(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+
+ if (dev) {
+ struct gem *gp = dev->priv;
+
+ unregister_netdev(dev);
+
+ /* Stop the link timer */
+ del_timer_sync(&gp->link_timer);
+
+ /* We shouldn't need any locking here */
+ gem_get_cell(gp);
+
+ /* Wait for a pending reset task to complete */
+ while (gp->reset_task_pending)
+ yield();
+ flush_scheduled_work();
+
+ /* Shut the PHY down */
+ gem_stop_phy(gp, 0);
+
+ gem_put_cell(gp);
+
+ /* Make sure bus master is disabled */
+ pci_disable_device(gp->pdev);
+
+ /* Free resources */
+ pci_free_consistent(pdev,
+ sizeof(struct gem_init_block),
+ gp->init_block,
+ gp->gblock_dvma);
+ iounmap(gp->regs);
+ pci_release_regions(pdev);
+ free_netdev(dev);
+
+ pci_set_drvdata(pdev, NULL);
+ }
+}
+
static int __devinit gem_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -2870,11 +3015,6 @@
gp->link_timer.function = gem_link_timer;
gp->link_timer.data = (unsigned long) gp;
- init_timer(&gp->pm_timer);
- gp->pm_timer.function = gem_pm_timer;
- gp->pm_timer.data = (unsigned long) gp;
-
- INIT_WORK(&gp->pm_task, gem_pm_task, gp);
INIT_WORK(&gp->reset_task, gem_reset_task, gp);
gp->lstate = link_down;
@@ -2890,19 +3030,18 @@
}
/* On Apple, we power the chip up now in order for check
- * invariants to work, but also because the firmware might
- * not have properly shut down the PHY.
+ * invariants to work. We also set some registers that are
+ * normally
*/
#ifdef CONFIG_PPC_PMAC
gp->of_node = pci_device_to_OF_node(pdev);
- if (pdev->vendor == PCI_VENDOR_ID_APPLE)
- gem_apple_powerup(gp);
#endif
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
- gem_stop(gp);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
+
+ /* Make sure cell is enabled */
+ gem_get_cell(gp);
+
+ /* Make sure everything is stopped and in init state */
+ gem_reset(gp);
/* Fill up the mii_phy structure (even if we won't use it) */
gp->phy_mii.dev = dev;
@@ -2911,7 +3050,8 @@
/* By default, we start with autoneg */
gp->want_autoneg = 1;
-
+
+ /* Check fifo sizes, PHY type, etc... */
if (gem_check_invariants(gp)) {
err = -ENODEV;
goto err_out_iounmap;
@@ -2951,6 +3091,19 @@
dev->poll_controller = gem_poll_controller;
#endif
+ /* Set that now, in case PM kicks in now */
+ pci_set_drvdata(pdev, dev);
+
+ /* Detect & init PHY, start autoneg, we release the cell now
+ * too, it will be managed by whoever needs it
+ */
+ gem_init_phy(gp);
+
+ spin_lock_irq(&gp->lock);
+ gem_put_cell(gp);
+ spin_unlock_irq(&gp->lock);
+
+ /* Register with kernel */
if (register_netdev(dev)) {
printk(KERN_ERR PFX "Cannot register net device, "
"aborting.\n");
@@ -2965,48 +3118,22 @@
i == 5 ? ' ' : ':');
printk("\n");
- /* Detect & init PHY, start autoneg */
- spin_lock_irq(&gp->lock);
- spin_lock(&gp->tx_lock);
- gp->hw_running = 1;
- gem_init_phy(gp);
- gem_begin_auto_negotiation(gp, NULL);
- spin_unlock(&gp->tx_lock);
- spin_unlock_irq(&gp->lock);
-
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1)
printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
gp->phy_mii.def ? gp->phy_mii.def->name : "no");
- pci_set_drvdata(pdev, dev);
-
/* GEM can do it all... */
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX;
if (pci_using_dac)
dev->features |= NETIF_F_HIGHDMA;
- /* Fire the PM timer that will shut us down in about 10 seconds */
- gp->pm_timer.expires = jiffies + 10*HZ;
- add_timer(&gp->pm_timer);
-
return 0;
err_out_free_consistent:
- pci_free_consistent(pdev,
- sizeof(struct gem_init_block),
- gp->init_block,
- gp->gblock_dvma);
-
+ gem_remove_one(pdev);
err_out_iounmap:
- down(&gp->pm_sem);
- /* Stop the PM timer & task */
- del_timer_sync(&gp->pm_timer);
- flush_scheduled_work();
- if (gp->hw_running)
- gem_shutdown(gp);
- up(&gp->pm_sem);
-
+ gem_put_cell(gp);
iounmap(gp->regs);
err_out_free_res:
@@ -3020,34 +3147,6 @@
}
-static void __devexit gem_remove_one(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (dev) {
- struct gem *gp = dev->priv;
-
- unregister_netdev(dev);
-
- down(&gp->pm_sem);
- /* Stop the PM timer & task */
- del_timer_sync(&gp->pm_timer);
- flush_scheduled_work();
- if (gp->hw_running)
- gem_shutdown(gp);
- up(&gp->pm_sem);
-
- pci_free_consistent(pdev,
- sizeof(struct gem_init_block),
- gp->init_block,
- gp->gblock_dvma);
- iounmap(gp->regs);
- pci_release_regions(pdev);
- free_netdev(dev);
-
- pci_set_drvdata(pdev, NULL);
- }
-}
static struct pci_driver gem_driver = {
.name = GEM_MODULE_NAME,
Index: linux-2.6.9-sleep/drivers/net/sungem.h
===================================================================
--- linux-2.6.9-sleep.orig/drivers/net/sungem.h 2004-10-19 13:37:44.000000000 +1000
+++ linux-2.6.9-sleep/drivers/net/sungem.h 2004-11-26 13:56:30.177908416 +1100
@@ -170,6 +170,27 @@
* them later. -DaveM
*/
+/* WakeOnLan Registers */
+#define WOL_MATCH0 0x3000UL
+#define WOL_MATCH1 0x3004UL
+#define WOL_MATCH2 0x3008UL
+#define WOL_MCOUNT 0x300CUL
+#define WOL_WAKECSR 0x3010UL
+
+/* WOL Match count register
+ */
+#define WOL_MCOUNT_N 0x00000010
+#define WOL_MCOUNT_M 0x00000000 /* 0 << 8 */
+
+#define WOL_WAKECSR_ENABLE 0x00000001
+#define WOL_WAKECSR_MII 0x00000002
+#define WOL_WAKECSR_SEEN 0x00000004
+#define WOL_WAKECSR_FILT_UCAST 0x00000008
+#define WOL_WAKECSR_FILT_MCAST 0x00000010
+#define WOL_WAKECSR_FILT_BCAST 0x00000020
+#define WOL_WAKECSR_FILT_SEEN 0x00000040
+
+
/* Receive DMA Registers */
#define RXDMA_CFG 0x4000UL /* RX Configuration Register */
#define RXDMA_DBLOW 0x4004UL /* RX Descriptor Base Low */
@@ -961,11 +982,12 @@
/* Set when chip is actually in operational state
* (ie. not power managed)
*/
- int hw_running;
- int opened;
+ int asleep; /* chip asleep, protected by pm_sem */
+ int asleep_wol; /* was asleep with WOL enabled */
+ int cell_enabled; /* cell enable count, protected by lock */
+ int opened; /* driver opened, protected by pm_sem */
+ int running; /* chip running, protected by lock */
struct semaphore pm_sem;
- struct work_struct pm_task;
- struct timer_list pm_timer;
struct gem_init_block *init_block;
Index: linux-2.6.9-sleep/arch/ppc/platforms/pmac_feature.c
===================================================================
--- linux-2.6.9-sleep.orig/arch/ppc/platforms/pmac_feature.c 2004-11-24 17:56:19.000000000 +1100
+++ linux-2.6.9-sleep/arch/ppc/platforms/pmac_feature.c 2004-11-26 13:56:30.182907656 +1100
@@ -1688,8 +1688,11 @@
*/
save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
+ /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
+ * enabled !
+ */
UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
- ~(UNI_N_CLOCK_CNTL_GMAC|UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
+ ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
udelay(100);
UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
^ permalink raw reply
* Re: MPC5200 toolchain test
From: Wolfgang Denk @ 2004-11-25 22:58 UTC (permalink / raw)
To: ivica; +Cc: linuxppc-embedded
In-Reply-To: <41A5F930.3080104@asist-traffic.com>
Dear Ivica,
in message <41A5F930.3080104@asist-traffic.com> you wrote:
>
> I have a MPC5200 based custom board with preloaded u-boot.
> My job is to create some sort of development environment, build
> linux kernel and userland environment and in the end test the hardware
> before larger series are built.
May I ask why you want to start from scratch? Is it for educational
purposes? Otherwise you could just use existing and well-tested
toolchains like our ELDK which isavailable for free (see
http://www.denx.de/ELDK.html); of course you can also use the ELDK's
build environment to rebuild everything from scratch if you really
want to be sure that you can recompile everything without need to
rely on any external resources.
> So far I managed to create GNU toolchain for it with crostool from
> Dan Kegel. Everything was built without any problems. Of course,
> I wanted to test this toolchain so I wanted to compile a simple
> hello_world program load it into the memory of my MPC5200 board
> and run it. So far I've failed. I admit. I don't know how to compile
> a program to run without the OS. But I have some clues. I think it
There is some pretty extensive documentation in our DULG about how to
use U-Boot and Linux in Embedded systems; have a look at
http://www.denx.de/twiki/bin/view/DULG/Manual
> Anyhow I want to do this before I compile kernel. Since I'm talking
> about the kernel let me ask you what kernel you suggest for MPC5200?
> The latest 2.6.10-rc or the one Sylvain Munaut is maintaining?
Alternatively, you could use the stable 2.4.25 kernel from the
linuxppc_2_4_devel tree on our CVS server; for details see the DULG.
> Next ... I would like to create a development environment that is totally
> "closed" from my system and I want all the crosstools in it. This way
> I could ensure none of my native tools are conflicting with cross
> development.
The ELDK installs all files and tools in a single directory. This
should be an excellent base for crating a sandboxed environment
(although I have to admit that I don't understand which benefits this
might give you).
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
There is a biblical analogy I'd like to draw here. Casts are to C++
Programmers what the apple was to Eve. - Scott Douglas Meyers
^ permalink raw reply
* Questions about PCI resources in Linux 2.4.25 for MPC8260
From: Laurent Lagrange @ 2004-11-25 9:59 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
I ported a MPC8260 custom LSP from Linux 2.4.18 to Linux 2.4.25 and
I discovered something strange in the last kernel.
In the file arch/ppc/kernel/setup.c, the function "setup_arch" runs this new
code :
code_resource.start = virt_to_bus((void *)PAGE_OFFSET);
code_resource.end = virt_to_bus(&_etext)-1;
data_resource.start = virt_to_bus(&_etext);
data_resource.end = virt_to_bus(&_edata)-1;
request_resource(&iomem_resource, &code_resource);
request_resource(&iomem_resource, &data_resource);
This code seems to reserve PCI resources for the kernel code and data.
Has anybody an idea why these resources are added and needed ?
To detect future PCI conflicts ? To preserve from external PCI accesses ?
If the board sdram is not mapped on PCI at 0x00000000, these resources
generate problems when scanning pci bus and discovering sdram space
in own pci bridge header space.
Is there a new rule to set sdram board to 0x00000000 instead of 0x80000000
while enumerating PCI.
Thanks for your ideas.
Laurent
^ permalink raw reply
* MPC5200 toolchain test
From: ivica @ 2004-11-25 15:24 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1724 bytes --]
Greeting!
I have a MPC5200 based custom board with preloaded u-boot.
My job is to create some sort of development environment, build
linux kernel and userland environment and in the end test the hardware
before larger series are built.
So far I managed to create GNU toolchain for it with crostool from
Dan Kegel. Everything was built without any problems. Of course,
I wanted to test this toolchain so I wanted to compile a simple
hello_world program load it into the memory of my MPC5200 board
and run it. So far I've failed. I admit. I don't know how to compile
a program to run without the OS. But I have some clues. I think it
needs to be linked properly so all the things OS does for you are inserted
into the binary image that is supposed to get executed. I need some detail
understanding on this.
Anyhow I want to do this before I compile kernel. Since I'm talking
about the kernel let me ask you what kernel you suggest for MPC5200?
The latest 2.6.10-rc or the one Sylvain Munaut is maintaining?
Next ... I would like to create a development environment that is totally
"closed" from my system and I want all the crosstools in it. This way
I could ensure none of my native tools are conflicting with cross
development.
I keep hearing about jails and sanboxes but I don't know what they mean.
Ok maybe I really need to google it out here but I'm beat. I'm googling
three days already. :D
Any tips on creating these kind of environments would be greatly
appreciated.
I will attach scripts which I used to create toolchain. I hope I did it
correctly.
My sources of documentation are google, IRC and these two books:
Building Embedded Linux, Karim Yaghmour
Programming Embeded Systems, Michael Barr
TIA,
Ivica
[-- Attachment #2: demo-ppc603e.sh --]
[-- Type: text/plain, Size: 632 bytes --]
#!/bin/sh
set -ex
TARBALLS_DIR=$HOME/tmp/downloads
RESULT_TOP=/opt/MPC5200-crosstools
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++"
export GCC_LANGUAGES
# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
mkdir -p $RESULT_TOP
# Build the toolchain. Takes a couple hours and a couple gigabytes.
#eval `cat powerpc-604.dat gcc-3.4.0-glibc-2.3.2.dat` sh all.sh --builduserland --notest
eval `cat powerpc-603e.dat gcc-3.4.1-glibc-2.3.3.dat` sh all.sh --notest
#eval `cat powerpc-604.dat gcc-3.4.1-glibc-20040827.dat` sh all.sh --notest
echo Done.
[-- Attachment #3: powerpc-603e.dat --]
[-- Type: text/plain, Size: 125 bytes --]
TARGET=powerpc-603e-linux-gnu
TARGET_CFLAGS="-O -mcpu=603e"
GCC_EXTRA_CONFIG="--with-cpu=603e --enable-cxx-flags=-mcpu=603e"
^ permalink raw reply
* Re: 440GP "Ebony" boot problems
From: Eugene Surovegin @ 2004-11-25 18:52 UTC (permalink / raw)
To: Andriy Korud; +Cc: linuxppc-embedded
In-Reply-To: <1101402827.10369.8.camel@localhost>
On Thu, Nov 25, 2004 at 05:18:49PM +0100, Andriy Korud wrote:
> I'm trying to boot original 440GP "Ebony" board wiath original IBM ROM
> Monitor:
> ...
> 440GP 1.18 ROM Monitor (02/11/02)
> ...
>
> However I've discovered that it requires special image in KDI (Kernel
> Downloadable Image) format. And it seems that the only way to make such
> image is to use 'mkimage' utility from LynuxWorks which is not widely
> available :-)
> Can anybody help me with this?
Huh? I'm away from my Ebony right now, so I cannot check which
OpenBIOS version it has but I never heard about KDI.
Image generated by the `make bzImage` in 2.4 or 2.6 official
kernel should be bootable on Ebony with original IBM firmware.
Why do you think IBM firmware requires LynuxWorks special image? This
sounds like a nonsense, frankly.
--
Eugene
^ permalink raw reply
* pb booting 2.6.9 kernel on Tibook
From: Philippe Jaillon @ 2004-11-25 18:45 UTC (permalink / raw)
To: Linuxppc-dev
Hi,
I have problem configuring a booting 2.6 kernel. it hang at
"adb: starting probe task"
My last experiment are for a 2.6.9 kernel were sources come from
source.mvista.com bitkeper linuxppc-2.5 tree. I clone the sources
tagged v2.6.9_linuxppc. I use the pmac default config. Build works
fine, i have a kernel, some modules... I install all the stuff,
update my yaboot.conf, run ybin and reboot.
Some body known where i am wrong ?
My latop is
processor : 0
cpu : 7450, altivec supported
clock : 667MHz
revision : 2.1 (pvr 8000 0201)
bogomips : 665.19
machine : PowerBook3,3
motherboard : PowerBook3,3 MacRISC2 MacRISC Power Macintosh
board revision : 00000001
detected as : 72 (PowerBook Titanium II)
pmac flags : 0000000b
L2 cache : 256K unified
memory : 512MB
pmac-generation : NewWorld
Regards and thank you for your help
--
Philippe JAILLON Ecole des Mines de St-Etienne
158, Cours Fauriel Tel. (+33) 04 77 42 66 04
42023 Saint-Etienne, FRANCE Fax (+33) 04 77 42 66 66
^ permalink raw reply
* 440GP "Ebony" boot problems
From: Andriy Korud @ 2004-11-25 16:18 UTC (permalink / raw)
To: linuxppc-embedded
Hi,
I'm trying to boot original 440GP "Ebony" board wiath original IBM ROM
Monitor:
...
440GP 1.18 ROM Monitor (02/11/02)
...
However I've discovered that it requires special image in KDI (Kernel
Downloadable Image) format. And it seems that the only way to make such
image is to use 'mkimage' utility from LynuxWorks which is not widely
available :-)
Can anybody help me with this?
thanks in advance,
--
Andriy Korud
P.S. For some reason I cannot replace ROM Monitor with U-Boot on this
board.
^ permalink raw reply
* Re: problem on netdevice
From: Marc Leeman @ 2004-11-25 11:19 UTC (permalink / raw)
To: zhonglei, linuxppc-dev
In-Reply-To: <200411251657.AA31129806@RCS-9000.COM>
[-- Attachment #1: Type: text/plain, Size: 711 bytes --]
Make certain that your DHCP server is set up correctly (see the attached file).
For the kernel config; make certain you have the following enabled:
[mleeman@gemini linux-2.4.28]$ cat config.nfs |grep NFS
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
[mleeman@gemini linux-2.4.28]$ cat config.nfs |grep ROOT
CONFIG_ROOT_NFS=y
[mleeman@gemini linux-2.4.28]$ cat config.nfs |grep AUTO
CONFIG_AUTOFS4_FS=y
[mleeman@gemini linux-2.4.28]$ cat config.nfs |grep BOOTP
CONFIG_IP_PNP_BOOTP=y
Yours is not going to be bootp, but something similar with DHCP (same
goes with the att. file).
P.S. reply to the list too
--
ash nazg durbatulûk, ash nazg gimbatul,
ash nazg thrakatulûk agh burzum-ishi krimpatul
[-- Attachment #2: NFSSystem.txt --]
[-- Type: text/plain, Size: 5563 bytes --]
Barco home TWiki > Firmware > FirmwareDocumentation > NFSSystem TWiki webs:
Firmware | Software | Servers
Firmware . { Changes | Index | Search | Go ________________ }
Loading a cramfs is time consuming and during a testing/debugging/development cycle, if this is done quite often. Therefore
a NFS filesystem, where changes can be done on the fly, is more useful. The boards are configured to use BOOTP for booting.
In the following, the basic modifications are described to configure a GNU/Linux server to serve as a bootp server.
First of all, a number of services need to be installed on the serving machine (gemini in this example):
* a NFS server
* a DHCP server
On a GNU/Debian system, the following packages need to be installed:
[mleeman@gemini mleeman]$ dpkg -l |grep nfs
ii nfs-common 1.0-2woody1 NFS support files common to client and serve
ii nfs-kernel-ser 1.0-2woody1 Kernel NFS server support
[mleeman@gemini mleeman]$ dpkg -l |grep dhcp
ii dhcp 2.0pl5-19 DHCP server for automatic IP address assignment
Other distributions should have similarly named packages.
The main configuration for this is done in a number of files:
* /etc/exports contains the files of your files on the server which are exported over NetworkFileSystem (NFS). In this
case, this will be the root filesystem for our embedded board.
* /etc/dhcpd.conf contains the configuration of the DHCP server. You have to make certain that you are the only DHCP
server in your netrange. If you do not, a lot of unpleasantness can occuur since your server will reply with DHCPNACK on
requests for the official DHCP server.
Extract a root filesystem tarball (or something similar) to your homedir (or a predetermined location). A free and general
purpose PPC root filesystem can be found in ELDK (http://www.denx.de/ELDK/).
[mleeman@gemini mleeman]$ mkdir targets
[mleeman@gemini mleeman]$ tar xvfz target.scn.tar.gz -C targets/
With the current BARCO builds, you can also use the CompressedFileSystem backup to create your NFS root FS:
# mkdir fs; cd fs
# bzcat ../target-2.0.0.10.cpio.bz2 | cpio -vi
Do not forget to copy your stream.cfg file, which basically re-confirms your IP address to ppcserver into the
/root/ppcstream directory.
Secondly, add the following entry in the exports file, indicating that you want to export without any condition:
/home/mleeman/targets/target.scn.01 *(rw,no_root_squash,no_all_squash)
Finally, restart the NFS server:
[mleeman@gemini mleeman]$ sudo /etc/init.d/nfs-kernel-server restart
We're halfway through. We now need to link this NFS filesystem to the MAC address of our board. This is done by adding the
following in the /etc/dhcpd.conf file:
# global configuration options
# allow bootp packages
allow bootp;
# the first subnet we listen to
subnet 150.158.231.0 netmask 255.255.255.0 {
# options for the subnet in question
option routers 150.158.231.1;
default-lease-time 1209600;
max-lease-time 31557600;
# for each board, add the following configuration block.
# It is best that you use different root FS directories
# for each board.
group {
host scnhost01 {
# MAC address
hardware ethernet 00:d0:b7:85:f9:28;
# The fixed address we will assign to the board
fixed-address 150.158.231.20;
# hm. not relevant here, is the kernel, which we load in FLASH
filename "image";
# our root FS that will be passed to the board
option root-path "/home/mleeman/targets/target.scn.01";
}
}
}
We now need to restart the dhcp server:
[mleeman@gemini mleeman]$ sudo /etc/init.d/dhcpd restart
If you do not know the MAC address, and it is not indicated on the board in some way, just let the target boot (loaded with
an NFS kernel of course) and watch the messages of the dhcp server, it will display the the MAC address (but will not pass a
root FS).
[mleeman@gemini mleeman]$ sudo tail -f /var/log/messages
and search for something like the following passing:
Apr 9 07:53:22 gemini dhcpd: BOOTREQUEST from 00:04:a5:00:05:19 via eth0
Apr 9 07:53:22 gemini dhcpd: No applicable record for BOOTP host 00:04:a5:00:05:19 via eth0
More detailed information will be see in
sudo tail -f /var/log/syslog
Jul 13 15:57:08 gemini dhcpd: BOOTREQUEST from 00:04:a5:04:05:0c via eth0
Jul 13 15:57:08 gemini dhcpd: BOOTREPLY for 150.158.231.121 to hydra_stream_dmar (00:04:a5:04:05:0c) via eth0
Jul 13 15:57:13 gemini rpc.mountd: authenticated mount request from 150.158.231.121:800 for /home/dmartens/targets/target.01 (/home/d
martens/targets/target.01)
In this case 00:04:a5:00:05:19 is our MAC address.
More details about the kernel parameters are found in the attached file.
-- MarcLeeman - 17 Jun 2004
Attachment: Action: Size: Date: Who: Comment:
nfsroot.txt action 8020 21 Jun 2004 - 10:00 MarcLeeman Kernel Documentation (2.6.7) about an nfsroot
Topic NFSSystem . { Edit | Attach | Ref-By | Printable | Diffs | r1.9 | > | r1.8 | > | r1.7 | More }
Revision r1.9 - 13 Jul 2004 - 14:00 GMT - MarcLeeman
Parents: WebHome > FirmwareDocumentation Copyright © 1999-2003 by the contributing authors. All material on this
collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback.
^ permalink raw reply
* Re: problem on netdevice
From: Marc Leeman @ 2004-11-25 7:37 UTC (permalink / raw)
To: linuxppc-dev, zhonglei
In-Reply-To: <200411251511.AA20840738@RCS-9000.COM>
> [root@198 linuxppc_2_4_devel]# tail -f /var/log/syslog
> tail: /var/log/syslog: No such file or directory
> tail: no files remaining
Depends on your system, the messages might also be directed to
/var/log/messages.
> And I found that my u-boot has detected 2 net adapters.
> But I didn't assign the 2nd one an ip address.Is it the key of the proble=
m?
No.
Either you have stored your kernel in flash in which case whatever IP
configuration the bootloader makes is useless or you have obtained
your kernel over the network; in that case your bootloader
configuration is also not relevant.
--=20
ash nazg durbatul=FBk, ash nazg gimbatul,
ash nazg thrakatul=FBk agh burzum-ishi krimpatul
^ permalink raw reply
* Re: problem on netdevice
From: Marc Leeman @ 2004-11-25 6:23 UTC (permalink / raw)
To: zhonglei; +Cc: linuxppc-dev
In-Reply-To: <1f729c4804112422211cd6ba60@mail.gmail.com>
> 2. As Wolfgang told you in the U-boot mailing list, check if the DHCP
> packets actually arrive on the server
2b. and verify if your DHCP server handles them: sends out an IP and
has that IP linked to a particular NFS share.
You should have something like:
Nov 24 08:35:17 gemini dhcpd: BOOTREQUEST from 00:04:a5:04:05:53 via eth0
Nov 24 08:35:17 gemini dhcpd: BOOTREPLY for 150.158.231.130 to
hydra_stream_malm.01 (00:04:a5:04:05:53) via eth0
Nov 24 08:35:21 gemini rpc.mountd: authenticated mount request from
150.158.231.130:800 for /home/firmware/mleeman/targets/target.3.0.0.0
(/home/firmware/mleeman/targets/target.3.0.0.0)
--=20
ash nazg durbatul=FBk, ash nazg gimbatul,
ash nazg thrakatul=FBk agh burzum-ishi krimpatul
^ permalink raw reply
* Re: problem on netdevice
From: Marc Leeman @ 2004-11-25 6:21 UTC (permalink / raw)
To: zhonglei; +Cc: linuxppc-dev
In-Reply-To: <200411251042.AA26804430@RCS-9000.COM>
> Sorry for bothering you! But would you please give me a hand.When I in=
sert a Intel Pro/100s server Adapter into the PCI slot on Lite5200(motorola=
MPC5200 development kit) and start the embedded kernel,the kernel run into=
a dead lock. (Before that I used 'make xconfig' to enable the e100 driver =
in kernel)
1. The kernel is not in a deadlock; it's just not able to mount a root
filesystem.
2. As Wolfgang told you in the U-boot mailing list, check if the DHCP
packets actually arrive on the server
# tail -f /var/log/syslog
If you do not check this first; doing anything else is useless.
--=20
ash nazg durbatul=FBk, ash nazg gimbatul,
ash nazg thrakatul=FBk agh burzum-ishi krimpatul
^ permalink raw reply
* problem on netdevice
From: zhonglei @ 2004-11-25 2:42 UTC (permalink / raw)
To: linuxppc-dev
hi
Sorry for bothering you! But would you please give me a hand.When I insert a Intel Pro/100s server Adapter into the PCI slot on Lite5200(motorola MPC5200 development kit) and start the embedded kernel,the kernel run into a dead lock. (Before that I used 'make xconfig' to enable the e100 driver in kernel)
The reports are as follows:
.
.
.
IP-Config: Retrying forever (NFS root)...
eth1: config: auto-negotiation on, 100FDX, 100HDX, 10FDX, 10HDX.
eth1: Waiting for the link to be up...
eth1: status: link up, 100 Mbps Full Duplex, auto-negotiation complete.
e100: eth0 NIC Link is Up 100 Mbps Full duplex
Sending DHCP requests ...... timed out!
Please tell me how can I handle it! Thanks in advance!
Best Regards
zhonglei
^ 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