aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2015-04-21 16:43:30 +0100
committerMichael Brown <mcb30@ipxe.org>2015-04-21 16:52:33 +0100
commit8958f62a1c85ff6b449a685a729b61b9ea69f50a (patch)
tree93c2af638cb0dbe5d2f33a1d7b4f0e14be9b6785
parent63dcab002e11123328bdbb73a475e5bc43b26b17 (diff)
downloadipxe-8958f62a1c85ff6b449a685a729b61b9ea69f50a.zip
ipxe-8958f62a1c85ff6b449a685a729b61b9ea69f50a.tar.gz
ipxe-8958f62a1c85ff6b449a685a729b61b9ea69f50a.tar.bz2
[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>
-rw-r--r--src/drivers/net/intel.c10
-rw-r--r--src/drivers/net/intel.h4
2 files changed, 13 insertions, 1 deletions
diff --git a/src/drivers/net/intel.c b/src/drivers/net/intel.c
index 954025d..671aad7 100644
--- a/src/drivers/net/intel.c
+++ b/src/drivers/net/intel.c
@@ -572,6 +572,13 @@ static int intel_open ( struct net_device *netdev ) {
/* Update link state */
intel_check_link ( netdev );
+ /* Apply required errata */
+ if ( intel->flags & INTEL_VMWARE ) {
+ DBGC ( intel, "INTEL %p applying VMware errata workaround\n",
+ intel );
+ intel->force_icr = INTEL_IRQ_RXT0;
+ }
+
return 0;
intel_destroy_ring ( intel, &intel->rx );
@@ -740,6 +747,7 @@ static void intel_poll ( struct net_device *netdev ) {
icr = readl ( intel->regs + INTEL_ICR );
profile_stop ( &intel_vm_poll_profiler );
profile_exclude ( &intel_vm_poll_profiler );
+ icr |= intel->force_icr;
if ( ! icr )
return;
@@ -907,7 +915,7 @@ static struct pci_device_id intel_nics[] = {
PCI_ROM ( 0x8086, 0x100c, "82544gc", "82544GC (Copper)", 0 ),
PCI_ROM ( 0x8086, 0x100d, "82544gc-l", "82544GC (LOM)", 0 ),
PCI_ROM ( 0x8086, 0x100e, "82540em", "82540EM", 0 ),
- PCI_ROM ( 0x8086, 0x100f, "82545em", "82545EM (Copper)", 0 ),
+ PCI_ROM ( 0x8086, 0x100f, "82545em", "82545EM (Copper)", INTEL_VMWARE ),
PCI_ROM ( 0x8086, 0x1010, "82546eb", "82546EB (Copper)", 0 ),
PCI_ROM ( 0x8086, 0x1011, "82545em-f", "82545EM (Fiber)", 0 ),
PCI_ROM ( 0x8086, 0x1012, "82546eb-f", "82546EB (Fiber)", 0 ),
diff --git a/src/drivers/net/intel.h b/src/drivers/net/intel.h
index 5482fb1..c868167 100644
--- a/src/drivers/net/intel.h
+++ b/src/drivers/net/intel.h
@@ -233,6 +233,8 @@ struct intel_nic {
unsigned int port;
/** Flags */
unsigned int flags;
+ /** Forced interrupts */
+ unsigned int force_icr;
/** EEPROM */
struct nvs_device eeprom;
@@ -253,6 +255,8 @@ struct intel_nic {
enum intel_flags {
/** PBS/PBA errata workaround required */
INTEL_PBS_ERRATA = 0x0001,
+ /** VMware missing interrupt workaround required */
+ INTEL_VMWARE = 0x0002,
};
extern int intel_create_ring ( struct intel_nic *intel,