This patch is to fix a big-endian problem in the RTL-8139 driver. The additional
debugging is mine, and the actual code fixes are by Garrison (Igor Kovalenko -
[EMAIL PROTECTED]). Code has been tested on 32-bit Solaris x86 and 32-bit
Solaris Sparc hosts, with and without debugging.
There were two problems.
1) the setup of the MAC address was not big-endian friendly
2) due to some feature of le32_to_cpu, the pointer to the buffer
for the packet was off in never-never land. Just setting the
val in rtl8139_TxAddr_write was enough to fix the problem,
and networking both in and out are working properly on a sparc host.
Ben
--- qemu/hw/rtl8139.c.ORIG 2007-03-12 17:41:46.739541000 -0400
+++ qemu/hw/rtl8139.c 2007-03-12 17:55:14.749309000 -0400
@@ -73,7 +73,9 @@
( ( input ) & ( size - 1 ) )
#if defined (DEBUG_RTL8139)
-# define DEBUG_PRINT(x) do { printf x ; } while (0)
+#include <stdarg.h>
+# define DEBUG_PRINT_VA(fmt, ...) do { printf ( "rtl8139.c:%d:%s: " fmt, __LINE__, __FUNCTION__, ## __VA_ARGS__ ); } while (0)
+# define DEBUG_PRINT(x) do { DEBUG_PRINT_VA x ; } while (0)
#else
# define DEBUG_PRINT(x)
#endif
@@ -637,8 +639,13 @@
int prom9346_get_wire(RTL8139State *s)
{
EEprom9346 *eeprom = &s->eeprom;
- if (!eeprom->eecs)
+ DEBUG_PRINT(("eeprom->eecs = 0x%08x, eeprom->eedo = 0x%08x\n", eeprom->eecs, eeprom->eedo));
+ if (!eeprom->eecs) {
+ DEBUG_PRINT(("eeprom->eedo = 0, returning 0\n"));
return 0;
+ }
+
+ DEBUG_PRINT(("return eeprom->eedo = 0x%08x\n", eeprom->eedo));
return eeprom->eedo;
}
@@ -778,6 +785,7 @@
/* non-wrapping path or overwrapping enabled */
cpu_physical_memory_write( s->RxBuf + s->RxBufAddr, buf, size );
+ DEBUG_PRINT((">>> RTL8139: called cpu_physical_memory_write\n" ));
s->RxBufAddr += size;
}
@@ -797,6 +805,7 @@
RTL8139State *s = opaque;
int avail;
+ DEBUG_PRINT(("s->clock_enabled = 0x%04x\n", s->clock_enabled ));
/* Recieve (drop) packets if card is disabled. */
if (!s->clock_enabled)
return 1;
@@ -1162,6 +1171,7 @@
static void rtl8139_receive(void *opaque, const uint8_t *buf, int size)
{
+ DEBUG_PRINT(("entering rtl8139_receive\n"));
rtl8139_do_receive(opaque, buf, size, 1);
}
@@ -1192,7 +1202,9 @@
s->eeprom.contents[1] = 0x10ec;
s->eeprom.contents[2] = 0x8139;
#endif
- memcpy(&s->eeprom.contents[7], s->macaddr, 6);
+ s->eeprom.contents[7] = s->macaddr[0] | s->macaddr[1] << 8;
+ s->eeprom.contents[8] = s->macaddr[2] | s->macaddr[3] << 8;
+ s->eeprom.contents[9] = s->macaddr[4] | s->macaddr[5] << 8;
/* mark all status registers as owned by host */
for (i = 0; i < 4; ++i)
@@ -1756,6 +1768,7 @@
}
else
{
+ DEBUG_PRINT(("RTL8139: +++ qemu_send_packet(s->vc, buf, size)\n"));
qemu_send_packet(s->vc, buf, size);
}
}
@@ -1786,10 +1799,20 @@
cpu_physical_memory_read(s->TxAddr[descriptor], txbuffer, txsize);
+ DEBUG_PRINT(("RTL8139: +++ finished calling cpu_physical_memory_read, txbuffer = 0x%08x\n", txbuffer ));
+#if DEBUG_RTL8139
+ int bx;
+ for(bx=0;bx<txsize;bx+=8) {
+ DEBUG_PRINT(("txbuffer[%d]: 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x 0x%2x\n",
+ bx,txbuffer[bx],txbuffer[bx+1],txbuffer[bx+2],txbuffer[bx+3],txbuffer[bx+4],txbuffer[bx+5],txbuffer[bx+6],txbuffer[bx+7]));
+ }
+#endif
+
/* Mark descriptor as transferred */
s->TxStatus[descriptor] |= TxHostOwns;
s->TxStatus[descriptor] |= TxStatOK;
-
+ DEBUG_PRINT(("RTL8139: +++ calling rtl8139_transfer_frame(s, txbuffer = 0x%08x, txsize = 0x%04x, 0)\n",
+ txbuffer, txsize));
rtl8139_transfer_frame(s, txbuffer, txsize, 0);
DEBUG_PRINT(("RTL8139: +++ transmitted %d bytes from descriptor %d\n", txsize, descriptor));
@@ -2455,14 +2478,15 @@
{
DEBUG_PRINT(("RTL8139: TxAddr write offset=0x%x val=0x%08x\n", txAddrOffset, val));
- s->TxAddr[txAddrOffset/4] = le32_to_cpu(val);
+ s->TxAddr[txAddrOffset/4] = val;
+ DEBUG_PRINT(("RTL8139: s->TxAddr[%d] = 0x%08x\n", txAddrOffset/4, val));
}
static uint32_t rtl8139_TxAddr_read(RTL8139State *s, uint32_t txAddrOffset)
{
uint32_t ret = cpu_to_le32(s->TxAddr[txAddrOffset/4]);
- DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset, ret));
+ DEBUG_PRINT(("RTL8139: TxAddr read offset=0x%x val=0x%08x\n", txAddrOffset/4, ret));
return ret;
}
@@ -2608,36 +2632,46 @@
switch (addr)
{
case MAC0 ... MAC0+5:
+ DEBUG_PRINT(("RTL8139: s->phys[%d] set 0x%x\n", addr - MAC0, val));
s->phys[addr - MAC0] = val;
break;
case MAC0+6 ... MAC0+7:
/* reserved */
break;
case MAR0 ... MAR0+7:
+ DEBUG_PRINT(("RTL8139: s->mult[%d] set 0x%x\n", addr - MAR0, val));
s->mult[addr - MAR0] = val;
break;
case ChipCmd:
+ DEBUG_PRINT(("RTL8139: ChipCmd write set 0x%x\n", val));
rtl8139_ChipCmd_write(s, val);
break;
case Cfg9346:
+ DEBUG_PRINT(("RTL8139: Cfg9346 write set 0x%x\n", val));
rtl8139_Cfg9346_write(s, val);
break;
case TxConfig: /* windows driver sometimes writes using byte-lenth call */
+ DEBUG_PRINT(("RTL8139: TxConfig write set 0x%x\n", val));
rtl8139_TxConfig_writeb(s, val);
break;
case Config0:
+ DEBUG_PRINT(("RTL8139: Config0 write set 0x%x\n", val));
rtl8139_Config0_write(s, val);
break;
case Config1:
+ DEBUG_PRINT(("RTL8139: Config1 write set 0x%x\n", val));
rtl8139_Config1_write(s, val);
break;
case Config3:
+ DEBUG_PRINT(("RTL8139: Config3 write set 0x%x\n", val));
rtl8139_Config3_write(s, val);
break;
case Config4:
+ DEBUG_PRINT(("RTL8139: Config4 write set 0x%x\n", val));
rtl8139_Config4_write(s, val);
break;
case Config5:
+ DEBUG_PRINT(("RTL8139: Config5 write set 0x%x\n", val));
rtl8139_Config5_write(s, val);
break;
case MediaStatus:
@@ -2692,25 +2726,31 @@
switch (addr)
{
case IntrMask:
+ DEBUG_PRINT(("RTL8139: IntrMask write(w) val=0x%04x\n", val));
rtl8139_IntrMask_write(s, val);
break;
case IntrStatus:
+ DEBUG_PRINT(("RTL8139: IntrStatus write(w) val=0x%04x\n", val));
rtl8139_IntrStatus_write(s, val);
break;
case MultiIntr:
+ DEBUG_PRINT(("RTL8139: MultiIntr write(w) val=0x%04x\n", val));
rtl8139_MultiIntr_write(s, val);
break;
case RxBufPtr:
+ DEBUG_PRINT(("RTL8139: RxBufPtr write(w) val=0x%04x\n", val));
rtl8139_RxBufPtr_write(s, val);
break;
case BasicModeCtrl:
+ DEBUG_PRINT(("RTL8139: BasicModeCtrl write(w) val=0x%04x\n", val));
rtl8139_BasicModeCtrl_write(s, val);
break;
case BasicModeStatus:
+ DEBUG_PRINT(("RTL8139: BasicModeStatus write(w) val=0x%04x\n", val));
rtl8139_BasicModeStatus_write(s, val);
break;
case NWayAdvert:
@@ -2726,10 +2766,12 @@
break;
case CpCmd:
+ DEBUG_PRINT(("RTL8139: CpCmd write(w) val=0x%04x\n", val));
rtl8139_CpCmd_write(s, val);
break;
case IntrMitigate:
+ DEBUG_PRINT(("RTL8139: IntrMitigate write(w) val=0x%04x\n", val));
rtl8139_IntrMitigate_write(s, val);
break;
@@ -2761,22 +2803,27 @@
break;
case TxConfig:
+ DEBUG_PRINT(("RTL8139: TxConfig_write val=0x%08x\n", val));
rtl8139_TxConfig_write(s, val);
break;
case RxConfig:
+ DEBUG_PRINT(("RTL8139: RxConfig_write val=0x%08x\n", val));
rtl8139_RxConfig_write(s, val);
break;
case TxStatus0 ... TxStatus0+4*4-1:
+ DEBUG_PRINT(("RTL8139: TxStatus_write addr-TxStatus0 = 0x%08x, val=0x%08x\n", addr-TxStatus0, val));
rtl8139_TxStatus_write(s, addr-TxStatus0, val);
break;
case TxAddr0 ... TxAddr0+4*4-1:
+ DEBUG_PRINT(("RTL8139: TxAddr_write addr-TxAddr0 = 0x%08x, val=0x%08x\n", addr-TxAddr0, val));
rtl8139_TxAddr_write(s, addr-TxAddr0, val);
break;
case RxBuf:
+ DEBUG_PRINT(("RTL8139: RxBuf_write val=0x%08x\n", val));
rtl8139_RxBuf_write(s, val);
break;
@@ -2829,33 +2876,42 @@
{
case MAC0 ... MAC0+5:
ret = s->phys[addr - MAC0];
+ DEBUG_PRINT(("RTL8139: s->phys[%d] read 0x%x\n", addr - MAC0, ret));
break;
case MAC0+6 ... MAC0+7:
ret = 0;
break;
case MAR0 ... MAR0+7:
ret = s->mult[addr - MAR0];
+ DEBUG_PRINT(("RTL8139: s->mult[%d] read 0x%x\n", addr -MAR0, ret));
break;
case ChipCmd:
ret = rtl8139_ChipCmd_read(s);
+ DEBUG_PRINT(("RTL8139: ChipCmd read 0x%x\n", ret));
break;
case Cfg9346:
ret = rtl8139_Cfg9346_read(s);
+ DEBUG_PRINT(("RTL8139: Cfg9346 read 0x%x\n", ret));
break;
case Config0:
ret = rtl8139_Config0_read(s);
+ DEBUG_PRINT(("RTL8139: Config0 read 0x%x\n", ret));
break;
case Config1:
ret = rtl8139_Config1_read(s);
+ DEBUG_PRINT(("RTL8139: Config2 read 0x%x\n", ret));
break;
case Config3:
ret = rtl8139_Config3_read(s);
+ DEBUG_PRINT(("RTL8139: Config3 read 0x%x\n", ret));
break;
case Config4:
ret = rtl8139_Config4_read(s);
+ DEBUG_PRINT(("RTL8139: Config4 read 0x%x\n", ret));
break;
case Config5:
ret = rtl8139_Config5_read(s);
+ DEBUG_PRINT(("RTL8139: Config5 read 0x%x\n", ret));
break;
case MediaStatus:
@@ -2903,29 +2959,36 @@
{
case IntrMask:
ret = rtl8139_IntrMask_read(s);
+ DEBUG_PRINT(("RTL8139: IntrMask read(w) val=0x%04x\n", ret));
break;
case IntrStatus:
ret = rtl8139_IntrStatus_read(s);
+ DEBUG_PRINT(("RTL8139: IntrStatus read(w) val=0x%04x\n", ret));
break;
case MultiIntr:
ret = rtl8139_MultiIntr_read(s);
+ DEBUG_PRINT(("RTL8139: MultiIntr read(w) val=0x%04x\n", ret));
break;
case RxBufPtr:
ret = rtl8139_RxBufPtr_read(s);
+ DEBUG_PRINT(("RTL8139: RxBufPtr read(w) val=0x%04x\n", ret));
break;
case RxBufAddr:
ret = rtl8139_RxBufAddr_read(s);
+ DEBUG_PRINT(("RTL8139: RxBufAddr read(w) val=0x%04x\n", ret));
break;
case BasicModeCtrl:
ret = rtl8139_BasicModeCtrl_read(s);
+ DEBUG_PRINT(("RTL8139: BasicModeCtrl read(w) val=0x%04x\n", ret));
break;
case BasicModeStatus:
ret = rtl8139_BasicModeStatus_read(s);
+ DEBUG_PRINT(("RTL8139: BasicModeStatus read(w) val=0x%04x\n", ret));
break;
case NWayAdvert:
ret = s->NWayAdvert;
@@ -2942,18 +3005,22 @@
case CpCmd:
ret = rtl8139_CpCmd_read(s);
+ DEBUG_PRINT(("RTL8139: CpCmd read(w) val=0x%04x\n", ret));
break;
case IntrMitigate:
ret = rtl8139_IntrMitigate_read(s);
+ DEBUG_PRINT(("RTL8139: IntrMitigate read(w) val=0x%04x\n", ret));
break;
case TxSummary:
ret = rtl8139_TSAD_read(s);
+ DEBUG_PRINT(("RTL8139: TSAD read(w) val=0x%04x\n", ret));
break;
case CSCR:
ret = rtl8139_CSCR_read(s);
+ DEBUG_PRINT(("RTL8139: CSCR read(w) val=0x%04x\n", ret));
break;
default:
@@ -2985,28 +3052,32 @@
{
case RxMissed:
ret = s->RxMissed;
-
DEBUG_PRINT(("RTL8139: RxMissed read val=0x%08x\n", ret));
break;
case TxConfig:
ret = rtl8139_TxConfig_read(s);
+ DEBUG_PRINT(("RTL8139: TxConfig read val=0x%08x\n", ret));
break;
case RxConfig:
ret = rtl8139_RxConfig_read(s);
+ DEBUG_PRINT(("RTL8139: RxConfig read val=0x%08x\n", ret));
break;
case TxStatus0 ... TxStatus0+4*4-1:
ret = rtl8139_TxStatus_read(s, addr-TxStatus0);
+ DEBUG_PRINT(("RTL8139: TxStatus%d read val=0x%08x\n", addr-TxStatus0, ret));
break;
case TxAddr0 ... TxAddr0+4*4-1:
ret = rtl8139_TxAddr_read(s, addr-TxAddr0);
+ DEBUG_PRINT(("RTL8139: TxAddr%d read val=0x%08x\n", addr-TxAddr0, ret));
break;
case RxBuf:
ret = rtl8139_RxBuf_read(s);
+ DEBUG_PRINT(("RTL8139: RxBuf read val=0x%08x\n", ret));
break;
case RxRingAddrLO:
_______________________________________________
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel