diff options
Diffstat (limited to 'hw/net')
-rw-r--r-- | hw/net/xilinx_axienet.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index aa358ccae2..f4638b2fdf 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -33,10 +33,15 @@ #define DPHY(x) #define TYPE_XILINX_AXI_ENET "xlnx.axi-ethernet" +#define TYPE_XILINX_AXI_ENET_DATA_STREAM "xilinx-axienet-data-stream" #define XILINX_AXI_ENET(obj) \ OBJECT_CHECK(XilinxAXIEnet, (obj), TYPE_XILINX_AXI_ENET) +#define XILINX_AXI_ENET_DATA_STREAM(obj) \ + OBJECT_CHECK(XilinxAXIEnetStreamSlave, (obj),\ + TYPE_XILINX_AXI_ENET_DATA_STREAM) + /* Advertisement control register. */ #define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */ #define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */ @@ -311,13 +316,21 @@ struct TEMAC { void *parent; }; +typedef struct XilinxAXIEnetStreamSlave XilinxAXIEnetStreamSlave; typedef struct XilinxAXIEnet XilinxAXIEnet; +struct XilinxAXIEnetStreamSlave { + Object parent; + + struct XilinxAXIEnet *enet; +} ; + struct XilinxAXIEnet { SysBusDevice busdev; MemoryRegion iomem; qemu_irq irq; StreamSlave *tx_dev; + XilinxAXIEnetStreamSlave rx_data_dev; NICState *nic; NICConf conf; @@ -803,9 +816,11 @@ static void eth_cleanup(NetClientState *nc) } static void -axienet_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, uint32_t *hdr) +xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, + uint32_t *hdr) { - XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj)); + XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj); + XilinxAXIEnet *s = ds->enet; /* TX enable ? */ if (!(s->tc & TC_TX)) { @@ -856,6 +871,18 @@ static NetClientInfo net_xilinx_enet_info = { static void xilinx_enet_realize(DeviceState *dev, Error **errp) { XilinxAXIEnet *s = XILINX_AXI_ENET(dev); + XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev); + Error *local_errp = NULL; + + object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet", + (Object **) &ds->enet, &local_errp); + if (local_errp) { + goto xilinx_enet_realize_fail; + } + object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_errp); + if (local_errp) { + goto xilinx_enet_realize_fail; + } qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_xilinx_enet_info, &s->conf, @@ -868,6 +895,12 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) s->TEMAC.parent = s; s->rxmem = g_malloc(s->c_rxmem); + return; + +xilinx_enet_realize_fail: + if (!*errp) { + *errp = local_errp; + } } static void xilinx_enet_init(Object *obj) @@ -880,6 +913,11 @@ static void xilinx_enet_init(Object *obj) (Object **) &s->tx_dev, &errp); assert_no_error(errp); + object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_ENET_DATA_STREAM); + object_property_add_child(OBJECT(s), "axistream-connected-target", + (Object *)&s->rx_data_dev, &errp); + assert_no_error(errp); + sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->iomem, &enet_ops, s, "enet", 0x40000); @@ -897,12 +935,17 @@ static Property xilinx_enet_properties[] = { static void xilinx_enet_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); dc->realize = xilinx_enet_realize; dc->props = xilinx_enet_properties; dc->reset = xilinx_axienet_reset; - ssc->push = axienet_stream_push; +} + +static void xilinx_enet_stream_class_init(ObjectClass *klass, void *data) +{ + StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass); + + ssc->push = data; } static const TypeInfo xilinx_enet_info = { @@ -911,6 +954,14 @@ static const TypeInfo xilinx_enet_info = { .instance_size = sizeof(XilinxAXIEnet), .class_init = xilinx_enet_class_init, .instance_init = xilinx_enet_init, +}; + +static const TypeInfo xilinx_enet_data_stream_info = { + .name = TYPE_XILINX_AXI_ENET_DATA_STREAM, + .parent = TYPE_OBJECT, + .instance_size = sizeof(struct XilinxAXIEnetStreamSlave), + .class_init = xilinx_enet_stream_class_init, + .class_data = xilinx_axienet_data_stream_push, .interfaces = (InterfaceInfo[]) { { TYPE_STREAM_SLAVE }, { } @@ -920,6 +971,7 @@ static const TypeInfo xilinx_enet_info = { static void xilinx_enet_register_types(void) { type_register_static(&xilinx_enet_info); + type_register_static(&xilinx_enet_data_stream_info); } type_init(xilinx_enet_register_types) |