My NE2000 send doesn't work
Posted: Sat Oct 03, 2015 11:15 am
I have attempted to write a driver for the NE2000 NIC:
When I attempt to send an ICMP Echo Request to 255.255.255.255 (which the OS automatically maps to MAC ff:ff:ff:ff:ff:ff) just as a test, I get the following in the debug console (from the kprintf_debug()s):
But in the ne2k-pktlog file from Bochs I get:
What this code is trying to do is write the frame to NIC memory (using the "DMA Write") and then I transmit from that buffer, but clearly it's sending all zeroes for some reason.
Does anyone know why this is happening?
Code: Select all
static void ne2k_setremaddr(NeInterface *nif, uint32_t val)
{
outb(nif->iobase + 0x08, (uint8_t) (val & 0xFF));
outb(nif->iobase + 0x09, (uint8_t) ((val >> 8) & 0xFF));
};
static void ne2k_setremcount(NeInterface *nif, size_t val)
{
outb(nif->iobase + 0x0A, (uint8_t) (val & 0xFF));
outb(nif->iobase + 0x0B, (uint8_t) ((val >> 8) & 0xFF));
};
static void ne2k_write(NeInterface *nif, uint32_t addr, const void *buffer, size_t size)
{
ne2k_setremaddr(nif, addr);
ne2k_setremcount(nif, size);
outb(nif->iobase + 0x0E, 0x48); // set byte-wide access
const uint8_t *scan = (const uint8_t*) buffer;
outb(nif->iobase, 0x12); // write DMA + start
while (size--)
{
outb(nif->iobase + 0x10, *scan++);
};
while ((inb(nif->iobase + 0x07) & 0x40) == 0);
};
static void ne2k_settxcount(NeInterface *nif, size_t count)
{
outb(nif->iobase + 0x05, (uint8_t) (count & 0xFF));
outb(nif->iobase + 0x06, (uint8_t) ((count >> 8) & 0xFF));
};
static void ne2k_send(NetIf *netif, const void *frame, size_t framelen)
{
(void)netif;
(void)frame;
(void)framelen;
kprintf_debug("ne2k_send called (size=%d):\n", (int) framelen);
EthernetHeader *head = (EthernetHeader*) frame;
kprintf_debug("\tDST: %x:%x:%x:%x:%x:%x\n", head->dest.addr[0], head->dest.addr[1], head->dest.addr[2],
head->dest.addr[3], head->dest.addr[4], head->dest.addr[5]);
kprintf_debug("\tSRC: %x:%x:%x:%x:%x:%x\n", head->src.addr[0], head->src.addr[1], head->src.addr[2],
head->src.addr[3], head->src.addr[4], head->src.addr[5]);
kprintf_debug("\tTYP: 0x%x\n", __builtin_bswap16(head->type));
kprintf_debug("\tCHK: 0x%x\n", ether_checksum(frame, framelen));
NeInterface *nif = (NeInterface*) netif->drvdata;
spinlockAcquire(&nif->lock);
// write the frame to the transmit buffer
ne2k_write(nif, (16*1024)/256, frame, framelen);
// specify the location of transmission buffer in NIC memory
outb(nif->iobase + 0x04, (16*1024)/256);
// specify the size of the frame
ne2k_settxcount(nif, framelen);
// transmit
outb(nif->iobase, 0x26);
// wait for transmit to complete
while ((inb(nif->iobase) & 0x04) == 0);
spinlockRelease(&nif->lock);
kprintf_debug("PACKET SENT\n");
};
Code: Select all
PING 255.255.255.255 (255.255.255.255)
ne2k_send called (size=64):
DST: ff:ff:ff:ff:ff:ff
SRC: b0:c4:20:0:0:0
TYP: 0x800
CHK: 0x2144df1c
PACKET SENT
Code: Select all
vnet packetmover readable log file
TFTP root = xl0
host MAC address = b0:c4:20:00:00:03
guest MAC address = b0:c4:20:00:00:00
--
a packet from guest to host, length 64
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
--
Does anyone know why this is happening?