diff --git a/hw/axi-stream.c b/hw/axi-stream.c
new file mode 100644
index 0000000..d0d9bb8
--- /dev/null
+++ b/hw/axi-stream.c
@@ -0,0 +1,15 @@
+#include "axi-stream.h"
+
+static TypeInfo axi_stream_slave_info = {
+    .name          = TYPE_AXI_STREAM_SLAVE,
+    .parent        = TYPE_INTERFACE,
+    .instance_size = sizeof(struct AXIStreamSlaveIface),
+};
+
+
+static void axi_stream_slave_register_types(void)
+{
+    type_register_static(&axi_stream_slave_info);
+}
+
+type_init(axi_stream_slave_register_types)
diff --git a/hw/axi-stream.h b/hw/axi-stream.h
new file mode 100644
index 0000000..f1a60ca
--- /dev/null
+++ b/hw/axi-stream.h
@@ -0,0 +1,35 @@
+#ifndef AXI_STREAM_H
+#define AXI_STREAM_H 1
+
+#include "qemu-common.h"
+#include "qemu/object.h"
+
+/* AXI stream slave. Used until qdev provides a generic way.  */
+#define TYPE_AXI_STREAM_SLAVE "axi-stream-slave"
+
+#define AXI_STREAM_SLAVE_IFACE(klass) \
+     OBJECT_CLASS_CHECK(AXIStreamSlaveIface, klass, TYPE_AXI_STREAM_SLAVE)
+
+/* This is usually done implicitly by object_set_link_property.  */
+#define AXI_STREAM_SLAVE(obj) \
+     OBJECT_CHECK(AXIStreamSlave, obj, TYPE_AXI_STREAM_SLAVE)
+
+typedef Interface AXIStreamSlave;
+typedef struct AXIStreamSlaveIface AXIStreamSlaveIface;
+
+struct AXIStreamSlaveIface {
+    InterfaceClass parent;
+
+    void (*push)(Object *obj, unsigned char *buf, size_t len, uint32_t *app);
+};
+
+static inline
+void axi_stream_push(AXIStreamSlave *peer, uint8_t *buf, size_t len, uint32_t *app)
+{
+    AXIStreamSlaveIface *iface = container_of(INTERFACE_GET_CLASS(peer),
+                                                AXIStreamSlaveIface,
+                                                parent);
+    iface->push(INTERFACE_OBJECT(peer), buf, len, app);
+}
+
+#endif
diff --git a/hw/microblaze/Makefile.objs b/hw/microblaze/Makefile.objs
index 020f7b6..cc7c222 100644
--- a/hw/microblaze/Makefile.objs
+++ b/hw/microblaze/Makefile.objs
@@ -9,6 +9,7 @@ obj-y += xilinx_uartlite.o
 obj-y += xilinx_ethlite.o
 obj-y += xilinx_axidma.o
 obj-y += xilinx_axienet.o
+obj-y += axi-stream.o
 obj-$(CONFIG_FDT) += ../device_tree.o
 
 obj-y := $(addprefix ../,$(obj-y))
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 3739db7..40d91cf 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -39,7 +39,8 @@
 
 #include "microblaze_boot.h"
 #include "microblaze_pic_cpu.h"
-#include "xilinx_axidma.h"
+
+#include "axi-stream.h"
 
 #define LMB_BRAM_SIZE  (128 * 1024)
 #define FLASH_SIZE     (32 * 1024 * 1024)
diff --git a/hw/xilinx.h b/hw/xilinx.h
index 0a940b8..f1d07fc 100644
--- a/hw/xilinx.h
+++ b/hw/xilinx.h
@@ -1,4 +1,4 @@
-#include "xilinx_axidma.h"
+#include "axi-stream.h"
 #include "qemu-common.h"
 #include "net.h"
 
@@ -61,7 +61,7 @@ xilinx_axiethernet_create(NICInfo *nd, Object *peer,
     qdev_set_nic_properties(dev, nd);
     qdev_prop_set_uint32(dev, "c_rxmem", rxmem);
     qdev_prop_set_uint32(dev, "c_txmem", txmem);
-    object_property_set_link(OBJECT(dev), OBJECT(peer), "peer", NULL);
+    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
     qdev_init_nofail(dev);
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
     sysbus_connect_irq(sysbus_from_qdev(dev), 0, irq);
@@ -75,7 +75,7 @@ xilinx_axiethernetdma_init(DeviceState *dev, Object *peer,
                            qemu_irq irq2, int freqhz)
 {
     qdev_prop_set_uint32(dev, "freqhz", freqhz);
-    object_property_set_link(OBJECT(dev), OBJECT(peer), "peer", NULL);
+    object_property_set_link(OBJECT(dev), OBJECT(peer), "tx_dev", NULL);
     qdev_init_nofail(dev);
 
     sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
diff --git a/hw/xilinx_axidma.c b/hw/xilinx_axidma.c
index 267b19b..9d4efe3 100644
--- a/hw/xilinx_axidma.c
+++ b/hw/xilinx_axidma.c
@@ -29,7 +29,7 @@
 #include "qemu-log.h"
 #include "qdev-addr.h"
 
-#include "xilinx_axidma.h"
+#include "axi-stream.h"
 
 #define D(x)
 
@@ -77,6 +77,10 @@ enum {
     SDESC_STATUS_COMPLETE = (1 << 31)
 };
 
+/* FIXME: this is a misnomer, it refers to the control subregion of the DMA to
+ * control a stream, not a AXIStream connection
+ */
+
 struct AXIStream {
     QEMUBH *bh;
     ptimer_state *ptimer;
@@ -94,7 +98,7 @@ struct XilinxAXIDMA {
     SysBusDevice busdev;
     MemoryRegion iomem;
     uint32_t freqhz;
-    XilinxAXIDMAPeer *peer;
+    AXIStreamSlave *tx_dev;
 
     struct AXIStream streams[2];
 };
@@ -241,7 +245,7 @@ static void stream_complete(struct AXIStream *s)
 }
 
 static void stream_process_mem2s(struct AXIStream *s,
-                                 XilinxAXIDMAPeer *peer)
+                                 AXIStreamSlave *tx_dev)
 {
     uint32_t prev_d;
     unsigned char txbuf[16 * 1024];
@@ -276,7 +280,7 @@ static void stream_process_mem2s(struct AXIStream *s,
         s->pos += txlen;
 
         if (stream_desc_eof(&s->desc)) {
-            xlx_dma_push(peer, txbuf, s->pos, app);
+            axi_stream_push(tx_dev, txbuf, s->pos, app);
             s->pos = 0;
             stream_complete(s);
         }
@@ -440,7 +444,7 @@ static void axidma_write(void *opaque, target_phys_addr_t addr,
             s->regs[addr] = value;
             s->regs[R_DMASR] &= ~DMASR_IDLE; /* Not idle.  */
             if (!sid) {
-                stream_process_mem2s(s, d->peer);
+                stream_process_mem2s(s, d->tx_dev);
             }
             break;
         default:
@@ -484,13 +488,13 @@ static void xilinx_axidma_initfn(Object *obj)
 {
     struct XilinxAXIDMA *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
 
-    object_property_add_link(obj, "peer", TYPE_XILINX_AXIDMA_PEER, 
-                             (Object **) &s->peer, NULL);
+    object_property_add_link(obj, "tx_dev", TYPE_AXI_STREAM_SLAVE,
+                             (Object **) &s->tx_dev, NULL);
 }
 
-static void xilinx_axidma_peer_initfn(ObjectClass *klass, void *data)
+static void xilinx_axidma_rx_stream_initfn(ObjectClass *klass, void *data)
 {
-    XilinxAXIDMAPeerIface *k = XILINX_AXIDMA_PEER_IFACE(klass);
+    AXIStreamSlaveIface *k = AXI_STREAM_SLAVE_IFACE(klass);
 
     k->push = axidma_push;
 }
@@ -516,21 +520,14 @@ static TypeInfo axidma_info = {
     .class_init    = axidma_class_init,
     .instance_init = xilinx_axidma_initfn,
     .interfaces = (InterfaceInfo[]) {
-	    { TYPE_XILINX_AXIDMA_PEER, xilinx_axidma_peer_initfn },
+	    { TYPE_AXI_STREAM_SLAVE, xilinx_axidma_rx_stream_initfn },
 	    { }
     }
 };
 
-static TypeInfo axidma_peer_info = {
-    .name          = TYPE_XILINX_AXIDMA_PEER,
-    .parent        = TYPE_INTERFACE,
-    .instance_size = sizeof(struct XilinxAXIDMAPeerIface),
-};
-
 static void xilinx_axidma_register_types(void)
 {
     type_register_static(&axidma_info);
-    type_register_static(&axidma_peer_info);
 }
 
 type_init(xilinx_axidma_register_types)
diff --git a/hw/xilinx_axidma.h b/hw/xilinx_axidma.h
deleted file mode 100644
index 99c8371..0000000
--- a/hw/xilinx_axidma.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef XILINX_AXIDMA_H
-#define XILINX_AXIDMA_H 1
-
-/* AXI DMA connection. Used until qdev provides a generic way.  */
-#define TYPE_XILINX_AXIDMA_PEER "xilinx-axidma-peer"
-
-#define XILINX_AXIDMA_PEER_IFACE(klass) \
-     OBJECT_CLASS_CHECK(XilinxAXIDMAPeerIface, klass, TYPE_XILINX_AXIDMA_PEER)
-
-/* This is usually done implicitly by object_set_link_property.  */
-#define XILINX_AXIDMA_PEER(obj) \
-     OBJECT_CHECK(XilinxAXIDMAPeer, obj, TYPE_XILINX_AXIDMA_PEER)
-
-typedef Interface XilinxAXIDMAPeer;
-typedef struct XilinxAXIDMAPeerIface XilinxAXIDMAPeerIface;
-
-struct XilinxAXIDMAPeerIface {
-    InterfaceClass parent;
-
-    void (*push)(Object *obj, unsigned char *buf, size_t len, uint32_t *app);
-};
-
-static inline
-void xlx_dma_push(XilinxAXIDMAPeer *peer,
-                  uint8_t *buf, size_t len, uint32_t *app)
-{
-    XilinxAXIDMAPeerIface *iface = container_of(INTERFACE_GET_CLASS(peer),
-                                                XilinxAXIDMAPeerIface,
-                                                parent);
-    iface->push(INTERFACE_OBJECT(peer), buf, len, app);
-}
-
-#endif
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index a340cf2..62b36e7 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -28,7 +28,7 @@
 #include "net.h"
 #include "net/checksum.h"
 
-#include "xilinx_axidma.h"
+#include "axi-stream.h"
 
 #define DPHY(x)
 
@@ -310,7 +310,7 @@ struct XilinxAXIEnet {
     SysBusDevice busdev;
     MemoryRegion iomem;
     qemu_irq irq;
-    XilinxAXIDMAPeer *peer;
+    AXIStreamSlave *tx_dev;
     NICState *nic;
     NICConf conf;
 
@@ -773,7 +773,7 @@ static ssize_t eth_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     /* Good frame.  */
     app[2] |= 1 << 6;
 
-    xlx_dma_push(s->peer, (void *)s->rxmem, size, app);
+    axi_stream_push(s->tx_dev, (void *)s->rxmem, size, app);
 
     s->regs[R_IS] |= IS_RX_COMPLETE;
     enet_update_irq(s);
@@ -868,13 +868,13 @@ static void xilinx_enet_initfn(Object *obj)
 {
     struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), SYS_BUS_DEVICE(obj));
 
-    object_property_add_link(obj, "peer", TYPE_XILINX_AXIDMA_PEER,
-                             (Object **) &s->peer, NULL);
+    object_property_add_link(obj, "tx_dev", TYPE_AXI_STREAM_SLAVE,
+                             (Object **) &s->tx_dev, NULL);
 }
 
-static void xilinx_enet_peer_initfn(ObjectClass *klass, void *data)
+static void xilinx_enet_rx_stream_initfn(ObjectClass *klass, void *data)
 {
-    XilinxAXIDMAPeerIface *k = XILINX_AXIDMA_PEER_IFACE(klass);
+    AXIStreamSlaveIface *k = AXI_STREAM_SLAVE_IFACE(klass);
 
     k->push = axienet_stream_push;
 }
@@ -903,7 +903,7 @@ static TypeInfo xilinx_enet_info = {
     .class_init    = xilinx_enet_class_init,
     .instance_init = xilinx_enet_initfn,
     .interfaces = (InterfaceInfo[]) {
-            { TYPE_XILINX_AXIDMA_PEER, xilinx_enet_peer_initfn },
+            { TYPE_AXI_STREAM_SLAVE, xilinx_enet_rx_stream_initfn },
             { }
     }
 };
