diff options
author | Michael Brown <mcb30@ipxe.org> | 2012-08-23 13:35:19 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2012-08-23 15:15:43 +0100 |
commit | 0dacd54174a78d32f7bfff958dd120f04f130f4b (patch) | |
tree | a1e9e608d209b6957a4bfe9bf0a2efccbb8cd70d | |
parent | 0e61beb26f789da01a566ff4bfdf571faacb9ce3 (diff) | |
download | ipxe-0dacd54174a78d32f7bfff958dd120f04f130f4b.zip ipxe-0dacd54174a78d32f7bfff958dd120f04f130f4b.tar.gz ipxe-0dacd54174a78d32f7bfff958dd120f04f130f4b.tar.bz2 |
[realtek] Enable DAC only when built as a 64-bit binary
Some RTL8169 cards (observed with an RTL8169SC) crash and burn if DAC
is enabled, even if only 32-bit addresses are used. Observed
behaviour includes system lockups and repeated transmission of garbage
data onto the wire.
This seems to be a known problem. The Linux r8169 driver disables DAC
by default and provides a "use_dac" module parameter.
There appears to be no known test for determining whether or not DAC
will work. As a workaround, enable DAC only if we are built as as
64-bit binary. This at least eliminates the problem in the common
case of a 32-bit build, which will never use 64-bit addresses anyway.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/drivers/net/realtek.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/drivers/net/realtek.c b/src/drivers/net/realtek.c index f63f25f..98fc02f 100644 --- a/src/drivers/net/realtek.c +++ b/src/drivers/net/realtek.c @@ -878,10 +878,15 @@ static void realtek_detect ( struct realtek_nic *rtl ) { /* The C+ Command register is present only on 8169 and 8139C+. * Try to enable C+ mode and PCI Dual Address Cycle (for * 64-bit systems), if supported. + * + * Note that enabling DAC seems to cause bizarre behaviour + * (lockups, garbage data on the wire) on some systems, even + * if only 32-bit addresses are used. */ cpcr = readw ( rtl->regs + RTL_CPCR ); - cpcr |= ( RTL_CPCR_DAC | RTL_CPCR_MULRW | RTL_CPCR_CPRX | - RTL_CPCR_CPTX ); + cpcr |= ( RTL_CPCR_MULRW | RTL_CPCR_CPRX | RTL_CPCR_CPTX ); + if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) + cpcr |= RTL_CPCR_DAC; writew ( cpcr, rtl->regs + RTL_CPCR ); check_cpcr = readw ( rtl->regs + RTL_CPCR ); |