Skip to contentSkip to conversation

ne2000 and Netware 3.11

PATCH In review Mark Jonckheere 2 participants 3 messages Mar 23, 2005 – Apr 8, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ne2000 and Netware 3.11

I installed an old Netware 3.11 distribution in a qemu virtual machine and MSdos 5.0 and a Netware client in an other one.

The network connection was tested with VDE using following commands:

as user root:

vde_switch -tap tap0 -hub -daemon
chmod 766 /tmp/vde.ctl
ethereal &

as non-privileged user:

vdeqemu novell.img -localtime -isa &
vdeqemu msdos5.img -localtime -isa -macaddr 52:54:00:22:44:66 &

Ethereal showed me that the IPX packets from Netware where malformed, and after a lot of tracing and debugging I found out that the netware ne2000 driver initializes the TPSR register with value 0xc0. This makes the transmitter point to memory offset 48K where there is only memory defined between offset 16K and 48K.

Since the TPSR register can address 64K memory and the NIC has only 32K "physical" memory available, the most logical solution is to consider the most significant bit as a non-connected addressline and make the memory adresses wrap around.

the following patch makes the ne2000 NIC work correctly under Netware 3.11

++++++++++++++++++++++++

hw/ne2000.c Tue Mar 22 20:13:07 2005 renamed from hw/ne2000.c Sun Oct 3 15:56:00 2004 +3 -1
diff -wurb qemu/hw/ne2000.c qemu-patched/hw/ne2000.c
@@ -268,6 +268,7 @@
                 /* signal end of transfert */
                 s->tsr = ENTSR_PTX;
                 s->isr |= ENISR_TX;
+                s->cmd &= ~E8390_TRANS;
                 ne2000_update_irq(s);
             }
         }
@@ -289,7 +290,8 @@
             ne2000_update_irq(s);
             break;
         case EN0_TPSR:
-            s->tpsr = val;
+            /* XXX: only 32K memory available, ignore bit 8 */
+            s->tpsr = val & 0x7f;
             break;
         case EN0_TCNTLO:
             s->tcnt = (s->tcnt & 0xff00) | val;

++++++++++++++++++++++++

Note:this patch also includes the patch I proposed on 24-12-2004 with title: "[PATCH] ne2000: Reset TXP bit after sending packet." since it is also needed to make Netware recognise the ne2000 card.

see also:
http://lists.gnu.org/archive/html/qemu-devel/2004-12/msg00292.html

groeten,
Mark.

Signature · 1 line
:wq
#1 lore raw
Quoted 5 lines · Mark Jonckheere

++++++++++++++++++++++++
diff -wurb qemu/hw/ne2000.c qemu-patched/hw/ne2000.c

hw/ne2000.c Tue Mar 22 20:13:07 2005 line 297

Quoted 9 lines
hw/ne2000.c Tue Mar 22 20:13:07 2005 renamed from hw/ne2000.c Sun Oct 3 15:56:00 2004 +2 -1
@@ -289,7 +290,8 @@
             ne2000_update_irq(s);
             break;
         case EN0_TPSR:
-            s->tpsr = val;
+            /* XXX: only 32K memory available, ignore bit 8 */
+            s->tpsr = val & 0x7f;
             break;
         case EN0_TCNTLO:
             s->tcnt = (s->tcnt & 0xff00) | val;

This patch is not correct: it limits the memory to 16K, not 32K because the memory starts at a 16K offset. A possible solution could be to wrap to 16K only if (tpsr << 8) >= 48K. Moreover, it should be done in the packet transmit code.

Quoted 3 lines

Note:this patch also includes the patch I proposed on 24-12-2004 with title: "[PATCH] ne2000: Reset TXP bit after sending packet." since it is also needed to make Netware recognise the ne2000 card.

OK for this one.

Fabrice.

#2 lore raw

[Qemu-devel] Re: [PATCH] ne2000 and Netware 3.11 (Revised patch)

Quoted 3 lines · Fabrice Bellard

This patch is not correct: it limits the memory to 16K, not 32K because the memory starts at a 16K offset. A possible solution could be to wrap to 16K only if (tpsr << 8) >= 48K. Moreover, it should be done in the packet transmit code.

The patch worked because standard drivers know that an original ne2000 card only has 16K RAM. I wonder if Netware works with a 32K ne2000-clone.

I include two possible revised patches:

The first one is just a more consistent rewrite of the previous patch:

++8<++cut+here++>8++

ne2000-p1.c renamed from ne2000.c +4 -2
@@ -103,7 +103,7 @@
 #define ENTSR_CDH 0x40	/* The collision detect "heartbeat" signal was lost. */
 #define ENTSR_OWC 0x80  /* There was an out-of-window collision. */
 
-#define NE2000_PMEM_SIZE    (32*1024)
+#define NE2000_PMEM_SIZE    (16*1024)
 #define NE2000_PMEM_START   (16*1024)
 #define NE2000_PMEM_END     (NE2000_PMEM_SIZE+NE2000_PMEM_START)
 #define NE2000_MEM_SIZE     NE2000_PMEM_END
@@ -268,6 +268,7 @@
                 /* signal end of transfert */
                 s->tsr = ENTSR_PTX;
                 s->isr |= ENISR_TX;
+                s->cmd &= ~E8390_TRANS;
                 ne2000_update_irq(s);
             }
         }
@@ -289,7 +290,8 @@
             ne2000_update_irq(s);
             break;
         case EN0_TPSR:
-            s->tpsr = val;
+            /* XXX: only 16K memory available, ignore bit 8 */
+            s->tpsr = val & 0x7f;
             break;
         case EN0_TCNTLO:
             s->tcnt = (s->tcnt & 0xff00) | val;

++8<++cut+here++>8++

in the second one the correction is in the packet transmit code as you asked

++8<++cut+here++>8++

ne2000-p2.c renamed from ne2000.c +7 -1
@@ -247,6 +247,7 @@
 {
     NE2000State *s = opaque;
     int offset, page;
+    int index;
 
     addr &= 0xf;
 #ifdef DEBUG_NE2000
@@ -264,10 +265,15 @@
                 ne2000_update_irq(s);
             }
             if (val & E8390_TRANS) {
-                qemu_send_packet(s->nd, s->mem + (s->tpsr << 8), s->tcnt);
+                /* XXX: next 3 lines are a hack to make netware 3.11 work */
+                index = s->tpsr << 8;
+                if (index >= NE2000_PMEM_END)
+                    index -= NE2000_PMEM_SIZE;
+                qemu_send_packet(s->nd, s->mem + index, s->tcnt);
                 /* signal end of transfert */
                 s->tsr = ENTSR_PTX;
                 s->isr |= ENISR_TX;
+                s->cmd &= ~E8390_TRANS;
                 ne2000_update_irq(s);
             }
         }

++8<++cut+here++>8++

greetings
Mark.

Signature · 1 line
:wq