Network iPXE Intel 82579LM HP IRQ Polling mode fix

From richud.com
Jump to: navigation, search



This is a patch I made to allow iPXE booting of certain Intel 82579LM NIC based HP laptops (6570b, 2170b, xx70x et al.) that have firmwares that tell fibs. (In a nutshell - They claim that IRQs are supported, but then never generate interrupts.)

Some examples (afraid my notes were rather poor here as I write it up, I didn't denote which code was which laptop)

(Windows)

VEN_8086&DEV_1502
VEN_8086&DEV_1503

(Linux)

8086:1502 103c:1618
8086:1502 103c:17a7
8086:1502 103c:1815
8086:1503 ??? 

I think it has been a problem for quite a while (and with other cards) that previously had no fix. I hope this may help people who come across the problem be able to see how it manifests itself.

You will get the message up like this with a load of dots until it just stops. Simplistically - its working initially from a PXE F12 style boot, gets a DHCP response, boots iPXE, but then iPXE is waiting for an interrupt that never comes so cant contact the DHCP server again and times out.

DHCP (net0 10:60:4b:48:7c:08)..........

This is the patch that just does the overriding based on the vendor and device PCID codes matching

--- a/src/arch/i386/drivers/net/undinet.c	2013-01-09 14:25:49.824273512 +0000
+++ b/src/arch/i386/drivers/net/undinet.cc	2013-01-09 14:31:35.484271369 +0000
@@ -639,6 +639,16 @@
 	     ( undinic->irq != 0 ) ) {
 		undinic->irq_supported = 1;
 	}
+        /* Override to polling mode on broken HP laptops that incorrectly report interrupt mode 
+               ven:8086 dev:1503 (6570b) & ven:8086 dev:1502 (6570b,2170b,xx70x) - Richard Moore
+               NB device ids in decimal
+        */
+        if ( ( undi->pci_vendor == 32902 ) &&
+             ( ( undi->pci_device == 5378 || undi->pci_device == 5378 ) ) ) {
+               undinic->irq_supported = 0;
+               DBGC ( undinic, "UNDINIC Forcing polling mode for match VEN:%d ", undi->pci_vendor );
+               DBGC ( undinic, "DEV:%d\n", undi->pci_device );
+        }
 	DBGC ( undinic, "UNDINIC %p using %s mode\n", undinic,
 	       ( undinic->irq_supported ? "interrupt" : "polling" ) );
 	if ( strncmp ( ( ( char * ) undi_iface.IfaceType ), "Etherboot",