*
* This code is licensed under the GPL.
*/
+#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include <zlib.h>
if ((s->rctl & SE_RCTL_RXEN) == 0)
return -1;
if (s->np >= 31) {
- DPRINTF("Packet dropped\n");
- return -1;
+ return 0;
}
DPRINTF("Received packet len=%zu\n", size);
n = s->next_packet + s->np;
if (n >= 31)
n -= 31;
- s->np++;
+ if (size >= sizeof(s->rx[n].data) - 6) {
+ /* If the packet won't fit into the
+ * emulated 2K RAM, this is reported
+ * as a FIFO overrun error.
+ */
+ s->ris |= SE_INT_FOV;
+ stellaris_enet_update(s);
+ return -1;
+ }
+
+ s->np++;
s->rx[n].len = size + 6;
p = s->rx[n].data;
*(p++) = (size + 6);
return size;
}
-static int stellaris_enet_can_receive(NetClientState *nc)
+static int stellaris_enet_can_receive(stellaris_enet_state *s)
{
- stellaris_enet_state *s = qemu_get_nic_opaque(nc);
-
- if ((s->rctl & SE_RCTL_RXEN) == 0)
- return 1;
-
return (s->np < 31);
}
s->next_packet = 0;
s->np--;
DPRINTF("RX done np=%d\n", s->np);
+ if (!s->np && stellaris_enet_can_receive(s)) {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
}
return val;
}
s->thr = value;
break;
case 0x20: /* MCTL */
- s->mctl = value;
+ /* TODO: MII registers aren't modelled.
+ * Clear START, indicating that the operation completes immediately.
+ */
+ s->mctl = value & ~1;
break;
case 0x24: /* MDV */
s->mdv = value;
s->tx_fifo_len = 0;
}
-static void stellaris_enet_cleanup(NetClientState *nc)
-{
- stellaris_enet_state *s = qemu_get_nic_opaque(nc);
-
- s->nic = NULL;
-}
-
static NetClientInfo net_stellaris_enet_info = {
- .type = NET_CLIENT_OPTIONS_KIND_NIC,
+ .type = NET_CLIENT_DRIVER_NIC,
.size = sizeof(NICState),
- .can_receive = stellaris_enet_can_receive,
.receive = stellaris_enet_receive,
- .cleanup = stellaris_enet_cleanup,
};
static int stellaris_enet_init(SysBusDevice *sbd)
return 0;
}
-static void stellaris_enet_unrealize(DeviceState *dev, Error **errp)
-{
- stellaris_enet_state *s = STELLARIS_ENET(dev);
-
- memory_region_destroy(&s->mmio);
-}
-
static Property stellaris_enet_properties[] = {
DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf),
DEFINE_PROP_END_OF_LIST(),
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = stellaris_enet_init;
- dc->unrealize = stellaris_enet_unrealize;
dc->props = stellaris_enet_properties;
dc->vmsd = &vmstate_stellaris_enet;
}