RTL8139 not filling buffer in QEMU
Posted: Tue Apr 16, 2013 1:02 pm
Hi,
I have this weird problem and I'm looking for ideas on what could be wrong.
I'm trying to write a driver for the RTL8139 network card which is supported in QEMU. I receive interrupts from it when data packets come in but for some reason the RX buffer that it is suppose to fill with incoming packets does not fill.
This is how I initialize the card:
After initializing I set up a simple handler for when irq happens. It looks like this:
All this interrupt handler does is that it writes back the same bit it received. This is to just tell the nic that this type of interrupts has been handled. This actually works, I do receive this interrupt when I send data to it (from the host OS). The problem is that later using another entrance I try to read data from the self->rx buffer but it is just empty. The interrupt tells me there is data to be read but still the data isn't stored in the buffer. I can also see that the register that says how much data is currently in the buffer has increased.
My first idea was that perhaps the RBSTART address is just pointing to something else and fills in the data somewhere it shouldn't but I have tripple checked that and even hard-coded a physical memory address instead of using the self->rx address but that made no difference what so ever. All memory in this case is also identity mapped so the virtual addresses are the same as the physical ones.
This is the parameters I use for qemu in order to enable RTL8139 for QEMU:
ANY help would be so much appreciated.
I have this weird problem and I'm looking for ideas on what could be wrong.
I'm trying to write a driver for the RTL8139 network card which is supported in QEMU. I receive interrupts from it when data packets come in but for some reason the RX buffer that it is suppose to fill with incoming packets does not fill.
This is how I initialize the card:
Code: Select all
outb(self->io + RTL8139_CONFIG1, 0x00); // Power on
outb(self->io + RTL8139_CR, 0x10); // Send reset
while (inb(self->io + RTL8139_CR) & 0x10); // Wait for reset to complete
outw(self->io + RTL8139_IMR, RTL8139_ISR_ROK); // Unmask receive ok interrupt
outd(self->io + RTL8139_RBSTART, (unsigned int)self->rx); // Tell the nic to use the self->rx buffer (defined as a char[0x2600])
outd(self->io + RTL8139_RCR, 0xF); // Tell the nic to accept all valid packages
Code: Select all
unsigned int status = inw(driver->io + RTL8139_ISR); // Read isr status
if (status & RTL8139_ISR_ROK)
outw(driver->io + RTL8139_ISR, RTL8139_ISR_ROK);
My first idea was that perhaps the RBSTART address is just pointing to something else and fills in the data somewhere it shouldn't but I have tripple checked that and even hard-coded a physical memory address instead of using the self->rx address but that made no difference what so ever. All memory in this case is also identity mapped so the virtual addresses are the same as the physical ones.
This is the parameters I use for qemu in order to enable RTL8139 for QEMU:
Code: Select all
-net nic,model=rtl8139 -net tap,script=no,downscript=no,ifname=tap0