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
 	/* Update link state */
572
 	/* Update link state */
573
 	intel_check_link ( netdev );
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
 	return 0;
582
 	return 0;
576
 
583
 
577
 	intel_destroy_ring ( intel, &intel->rx );
584
 	intel_destroy_ring ( intel, &intel->rx );
740
 	icr = readl ( intel->regs + INTEL_ICR );
747
 	icr = readl ( intel->regs + INTEL_ICR );
741
 	profile_stop ( &intel_vm_poll_profiler );
748
 	profile_stop ( &intel_vm_poll_profiler );
742
 	profile_exclude ( &intel_vm_poll_profiler );
749
 	profile_exclude ( &intel_vm_poll_profiler );
750
+	icr |= intel->force_icr;
743
 	if ( ! icr )
751
 	if ( ! icr )
744
 		return;
752
 		return;
745
 
753
 
907
 	PCI_ROM ( 0x8086, 0x100c, "82544gc", "82544GC (Copper)", 0 ),
915
 	PCI_ROM ( 0x8086, 0x100c, "82544gc", "82544GC (Copper)", 0 ),
908
 	PCI_ROM ( 0x8086, 0x100d, "82544gc-l", "82544GC (LOM)", 0 ),
916
 	PCI_ROM ( 0x8086, 0x100d, "82544gc-l", "82544GC (LOM)", 0 ),
909
 	PCI_ROM ( 0x8086, 0x100e, "82540em", "82540EM", 0 ),
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
 	PCI_ROM ( 0x8086, 0x1010, "82546eb", "82546EB (Copper)", 0 ),
919
 	PCI_ROM ( 0x8086, 0x1010, "82546eb", "82546EB (Copper)", 0 ),
912
 	PCI_ROM ( 0x8086, 0x1011, "82545em-f", "82545EM (Fiber)", 0 ),
920
 	PCI_ROM ( 0x8086, 0x1011, "82545em-f", "82545EM (Fiber)", 0 ),
913
 	PCI_ROM ( 0x8086, 0x1012, "82546eb-f", "82546EB (Fiber)", 0 ),
921
 	PCI_ROM ( 0x8086, 0x1012, "82546eb-f", "82546EB (Fiber)", 0 ),

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

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

Loading…
Cancel
Save