Subject: [PATCH] e1000e: Fix usage under kexec

From: Sven Anders <[email-masked]>
Date: Mon, 09 Nov 2009 21:25:21 +0100

Hello!

We're experiencing the following problem:

We start a minimal linux system, prepare the system and start the
final system via kexec.
On two different systems (one with a 82573 and one with a 82574),
the driver cannot initialize the network hardware, because the PHY
is not recognized.

We get the following error:
  e1000e: probe of 0000:02:00.0 failed with error -2

We cannot unload the driver of the first kernel, because it's
compiled in statically.

It's caused by the PHY, because it's already initialized by the
first driver and therefore does not respond correctly. The driver
assumes the PHY to be in 'reset' state, which is done by the BIOS.

We fixed it by adding a

+       /* Reset PHY before initializing it. Allows re-init after kexec. */
+       if (!e1000_check_reset_block(hw))
+         e1000_phy_hw_reset(hw);

to the initialization routine. I'm not sure, if we need the additional
"block" check.
A patch is attached.

Please send a note, if the patch is correct or wrong...

Regards
 Sven Anders

-- 
 Sven Anders <[email-masked]>                 () Ascii Ribbon Campaign
                                                 /\ Support plain text e-mail
 ANDURAS service solutions AG
 Innstrasse 71 - 94036 Passau - Germany
 Web: www.anduras.de - Tel: +49 (0)851-4 90 50-0 - Fax: +49 (0)851-4 90 50-55

Those who would give up essential Liberty, to purchase a little
temporary Safety, deserve neither Liberty nor Safety.
  - Benjamin Franklin
--- linux-2.6.29.6/drivers/net/e1000e/82571.c.orig	2009-11-04 00:44:27.000000000 +0100
+++ linux-2.6.29.6/drivers/net/e1000e/82571.c	2009-11-04 00:44:19.000000000 +0100
@@ -107,6 +107,10 @@ static s32 e1000_init_phy_params_82571(s
 		break;
 	}
 
+	/* Reset PHY before initializing it. Allows re-init after kexec. */
+	if (!e1000_check_reset_block(hw))
+	  e1000_phy_hw_reset(hw);
+
 	/* This can only be done after all function pointers are setup. */
 	ret_val = e1000_get_phy_id_82571(hw);