return (crc >> 26);
}
-/* return the max buffer size if the NE2000 can receive more data */
-static int ne2000_can_receive(void *opaque)
+static int ne2000_buffer_full(NE2000State *s)
{
- NE2000State *s = opaque;
int avail, index, boundary;
-
- if (s->cmd & E8390_STOP)
- return 0;
+
index = s->curpag << 8;
boundary = s->boundary << 8;
- if (index < boundary)
+ if (index <= boundary)
avail = boundary - index;
else
avail = (s->stop - s->start) - (index - boundary);
if (avail < (MAX_ETH_FRAME_SIZE + 4))
- return 0;
- return MAX_ETH_FRAME_SIZE;
+ return 1;
+ return 0;
+}
+
+static int ne2000_can_receive(void *opaque)
+{
+ NE2000State *s = opaque;
+
+ if (s->cmd & E8390_STOP)
+ return 1;
+ return !ne2000_buffer_full(s);
}
#define MIN_BUF_SIZE 60
printf("NE2000: received len=%d\n", size);
#endif
- if (!ne2000_can_receive(s))
+ if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
return;
/* XXX: check this */
}
s->curpag = next >> 8;
- /* now we can signal we have receive something */
+ /* now we can signal we have received something */
s->isr |= ENISR_RX;
ne2000_update_irq(s);
}
{
NE2000State* s=(NE2000State*)opaque;
+ if (s->pci_dev)
+ pci_device_save(s->pci_dev, f);
+
qemu_put_8s(f, &s->rxcr);
qemu_put_8s(f, &s->cmd);
static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
{
NE2000State* s=(NE2000State*)opaque;
+ int ret;
- if (version_id == 2) {
+ if (version_id > 3)
+ return -EINVAL;
+
+ if (s->pci_dev && version_id >= 3) {
+ ret = pci_device_load(s->pci_dev, f);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (version_id >= 2) {
qemu_get_8s(f, &s->rxcr);
- } else if (version_id == 1) {
- s->rxcr = 0x0c;
} else {
- return -EINVAL;
+ s->rxcr = 0x0c;
}
qemu_get_8s(f, &s->cmd);
ne2000_reset(s);
- s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
+ s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
+ ne2000_can_receive, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
register_ioport_read(addr + 0x1f, 1, 1, ne2000_reset_ioport_read, s);
}
-void pci_ne2000_init(PCIBus *bus, NICInfo *nd)
+void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
{
PCINE2000State *d;
NE2000State *s;
d = (PCINE2000State *)pci_register_device(bus,
"NE2000", sizeof(PCINE2000State),
- -1,
+ devfn,
NULL, NULL);
pci_conf = d->dev.config;
pci_conf[0x00] = 0xec; // Realtek 8029
s->pci_dev = (PCIDevice *)d;
memcpy(s->macaddr, nd->macaddr, 6);
ne2000_reset(s);
- s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s);
+ s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive,
+ ne2000_can_receive, s);
snprintf(s->vc->info_str, sizeof(s->vc->info_str),
"ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x",
s->macaddr[5]);
/* XXX: instance number ? */
- register_savevm("ne2000", 0, 2, ne2000_save, ne2000_load, s);
- register_savevm("ne2000_pci", 0, 1, generic_pci_save, generic_pci_load,
- &d->dev);
+ register_savevm("ne2000", 0, 3, ne2000_save, ne2000_load, s);
}