aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Crosthwaite <peter.crosthwaite@xilinx.com>2013-04-16 10:25:18 +1000
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>2013-04-16 10:04:22 +0200
commit55b3e0c2f8fb7ef6d7929de23f3ae2a3d805ebff (patch)
treedd78aaa0375d41451b2a6b01a882016d4ce7a0f3
parentb19ceaad0dee6bca619ba2de19003b50e1a8cb01 (diff)
xilinx_axienet: Create Proxy object for stream
Create a separate child object to proxy the stream slave connection. This is setup for future work where a second stream slave connection is needed. The new child object is created at qdev init time and is linked back to the parent (the ethernet device itself) automatically. Stream slave masters differentiate which slave connection they are connected to by linking to the proxy object rather than the parent. Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c5
-rw-r--r--hw/net/xilinx_axienet.c60
2 files changed, 60 insertions, 5 deletions
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index a5e9b358a5..0bad3621c3 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -79,6 +79,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
const char *cpu_model = args->cpu_model;
MemoryRegion *address_space_mem = get_system_memory();
DeviceState *dev, *dma, *eth0;
+ Object *peer;
MicroBlazeCPU *cpu;
SysBusDevice *busdev;
CPUMBState *env;
@@ -142,7 +143,9 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
xilinx_axiethernet_init(eth0, &nd_table[0], STREAM_SLAVE(dma),
0x82780000, irq[3], 0x1000, 0x1000);
- xilinx_axidma_init(dma, STREAM_SLAVE(eth0), 0x84600000, irq[1], irq[0],
+ peer = object_property_get_link(OBJECT(eth0),
+ "axistream-connected-target", NULL);
+ xilinx_axidma_init(dma, STREAM_SLAVE(peer), 0x84600000, irq[1], irq[0],
100 * 1000000);
{
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)