+#include "qemu/osdep.h"
#include "hw/hw.h"
#include "net/net.h"
#include "trace.h"
#define MAX_ETH_FRAME_SIZE 1514
+#define TYPE_MIPS_NET "mipsnet"
+#define MIPS_NET(obj) OBJECT_CHECK(MIPSnetState, (obj), TYPE_MIPS_NET)
+
typedef struct MIPSnetState {
- SysBusDevice busdev;
+ SysBusDevice parent_obj;
uint32_t busy;
uint32_t rx_count;
trace_mipsnet_receive(size);
if (!mipsnet_can_receive(nc))
- return -1;
+ return 0;
+ if (size >= sizeof(s->rx_buffer)) {
+ return 0;
+ }
s->busy = 1;
/* Just accept everything. */
if (s->rx_count) {
s->rx_count--;
ret = s->rx_buffer[s->rx_read++];
+ if (mipsnet_can_receive(s->nic->ncs)) {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
}
break;
/* Reads as zero. */
}
s->busy = !!s->intctl;
mipsnet_update_irq(s);
+ if (mipsnet_can_receive(s->nic->ncs)) {
+ qemu_flush_queued_packets(qemu_get_queue(s->nic));
+ }
break;
case MIPSNET_TX_DATA_BUFFER:
s->tx_buffer[s->tx_written++] = val;
- if (s->tx_written == s->tx_count) {
+ if ((s->tx_written >= MAX_ETH_FRAME_SIZE)
+ || (s->tx_written == s->tx_count)) {
/* Send buffer. */
- trace_mipsnet_send(s->tx_count);
- qemu_send_packet(qemu_get_queue(s->nic), s->tx_buffer, s->tx_count);
+ trace_mipsnet_send(s->tx_written);
+ qemu_send_packet(qemu_get_queue(s->nic),
+ s->tx_buffer, s->tx_written);
s->tx_count = s->tx_written = 0;
s->intctl |= MIPSNET_INTCTL_TXDONE;
s->busy = 1;
.name = "mipsnet",
.version_id = 0,
.minimum_version_id = 0,
- .minimum_version_id_old = 0,
- .fields = (VMStateField[]) {
+ .fields = (VMStateField[]) {
VMSTATE_UINT32(busy, MIPSnetState),
VMSTATE_UINT32(rx_count, MIPSnetState),
VMSTATE_UINT32(rx_read, MIPSnetState),
}
};
-static void mipsnet_cleanup(NetClientState *nc)
-{
- MIPSnetState *s = qemu_get_nic_opaque(nc);
-
- s->nic = NULL;
-}
-
static NetClientInfo net_mipsnet_info = {
- .type = NET_CLIENT_OPTIONS_KIND_NIC,
+ .type = NET_CLIENT_DRIVER_NIC,
.size = sizeof(NICState),
- .can_receive = mipsnet_can_receive,
.receive = mipsnet_receive,
- .cleanup = mipsnet_cleanup,
};
static const MemoryRegionOps mipsnet_ioport_ops = {
.impl.max_access_size = 4,
};
-static int mipsnet_sysbus_init(SysBusDevice *dev)
+static int mipsnet_sysbus_init(SysBusDevice *sbd)
{
- MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev, dev);
+ DeviceState *dev = DEVICE(sbd);
+ MIPSnetState *s = MIPS_NET(dev);
memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s,
"mipsnet-io", 36);
- sysbus_init_mmio(dev, &s->io);
- sysbus_init_irq(dev, &s->irq);
+ sysbus_init_mmio(sbd, &s->io);
+ sysbus_init_irq(sbd, &s->irq);
s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
- object_get_typename(OBJECT(dev)), dev->qdev.id, s);
+ object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
return 0;
static void mipsnet_sysbus_reset(DeviceState *dev)
{
- MIPSnetState *s = DO_UPCAST(MIPSnetState, busdev.qdev, dev);
+ MIPSnetState *s = MIPS_NET(dev);
mipsnet_reset(s);
}
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = mipsnet_sysbus_init;
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "MIPS Simulator network device";
dc->reset = mipsnet_sysbus_reset;
dc->vmsd = &vmstate_mipsnet;
}
static const TypeInfo mipsnet_info = {
- .name = "mipsnet",
+ .name = TYPE_MIPS_NET,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MIPSnetState),
.class_init = mipsnet_class_init,