Browse Source

[intel] Force RX polling on VMware emulated 82545em

The emulated Intel 82545em in some versions of VMware (observed with
ESXi v5.1) seems to sometimes fail to set the RXT0 bit in the
interrupt cause register (ICR), causing iPXE to stop receiving
packets.  Work around this problem (for the 82545em only) by always
polling the receive queue regardless of the state of the ICR.

Reported-by: Slava Bendersky <volga629@networklab.ca>
Tested-by: Slava Bendersky <volga629@networklab.ca>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
8958f62a1c
2 changed files with 13 additions and 1 deletions
  1. 9
    1
      src/drivers/net/intel.c
  2. 4
    0
      src/drivers/net/intel.h

+ 9
- 1
src/drivers/net/intel.c View File

@@ -572,6 +572,13 @@ static int intel_open ( struct net_device *netdev ) {
572 572
 	/* Update link state */
573 573
 	intel_check_link ( netdev );
574 574
 
575
+	/* Apply required errata */
576
+	if ( intel->flags & INTEL_VMWARE ) {
577
+		DBGC ( intel, "INTEL %p applying VMware errata workaround\n",
578
+		       intel );
579
+		intel->force_icr = INTEL_IRQ_RXT0;
580
+	}
581
+
575 582
 	return 0;
576 583
 
577 584
 	intel_destroy_ring ( intel, &intel->rx );
@@ -740,6 +747,7 @@ static void intel_poll ( struct net_device *netdev ) {
740 747
 	icr = readl ( intel->regs + INTEL_ICR );
741 748
 	profile_stop ( &intel_vm_poll_profiler );
742 749
 	profile_exclude ( &intel_vm_poll_profiler );
750
+	icr |= intel->force_icr;
743 751
 	if ( ! icr )
744 752
 		return;
745 753
 
@@ -907,7 +915,7 @@ static struct pci_device_id intel_nics[] = {
907 915
 	PCI_ROM ( 0x8086, 0x100c, "82544gc", "82544GC (Copper)", 0 ),
908 916
 	PCI_ROM ( 0x8086, 0x100d, "82544gc-l", "82544GC (LOM)", 0 ),
909 917
 	PCI_ROM ( 0x8086, 0x100e, "82540em", "82540EM", 0 ),
910
-	PCI_ROM ( 0x8086, 0x100f, "82545em", "82545EM (Copper)", 0 ),
918
+	PCI_ROM ( 0x8086, 0x100f, "82545em", "82545EM (Copper)", INTEL_VMWARE ),
911 919
 	PCI_ROM ( 0x8086, 0x1010, "82546eb", "82546EB (Copper)", 0 ),
912 920
 	PCI_ROM ( 0x8086, 0x1011, "82545em-f", "82545EM (Fiber)", 0 ),
913 921
 	PCI_ROM ( 0x8086, 0x1012, "82546eb-f", "82546EB (Fiber)", 0 ),

+ 4
- 0
src/drivers/net/intel.h View File

@@ -233,6 +233,8 @@ struct intel_nic {
233 233
 	unsigned int port;
234 234
 	/** Flags */
235 235
 	unsigned int flags;
236
+	/** Forced interrupts */
237
+	unsigned int force_icr;
236 238
 
237 239
 	/** EEPROM */
238 240
 	struct nvs_device eeprom;
@@ -253,6 +255,8 @@ struct intel_nic {
253 255
 enum intel_flags {
254 256
 	/** PBS/PBA errata workaround required */
255 257
 	INTEL_PBS_ERRATA = 0x0001,
258
+	/** VMware missing interrupt workaround required */
259
+	INTEL_VMWARE = 0x0002,
256 260
 };
257 261
 
258 262
 extern int intel_create_ring ( struct intel_nic *intel,

Loading…
Cancel
Save