diff mbox

[QEMU,RFC,2/2] xilinx_axienet: Model timing.

Message ID a311ceee-9b01-41d2-98e9-4017f1875ddc@TX2EHSMHS008.ehs.local
State New
Headers show

Commit Message

Peter Crosthwaite Jan. 26, 2013, 8:18 p.m. UTC
Add an artificial delay after receiving a packet to throttle rx traffic.

This patch is a non-functional RFC please see the cover letter for discussion.

Reported-by: Jason Wu <huanyu@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
 hw/xilinx_axienet.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 51c2896..fa8c3de 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -360,7 +360,8 @@  struct XilinxAXIEnet {
     /* 32K x 1 lookup filter.  */
     uint32_t ext_mtable[1024];
 
-
+    QEMUTimer *transfer_timer;
+    bool rxing;
     uint8_t *rxmem;
 };
 
@@ -620,7 +621,7 @@  static int eth_can_rx(NetClientState *nc)
     struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
 
     /* RX enabled?  */
-    return !axienet_rx_resetting(s) && axienet_rx_enabled(s);
+    return !axienet_rx_resetting(s) && axienet_rx_enabled(s) && !s->rxing;
 }
 
 static int enet_match_addr(const uint8_t *buf, uint32_t f0, uint32_t f1)
@@ -650,6 +651,9 @@  static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size)
     uint32_t csum32;
     uint16_t csum16;
     int i;
+    s->rxing = true;
+    qemu_mod_timer(s->transfer_timer,
+                   qemu_get_clock_ns(vm_clock) + 500 * size);
 
     DENET(qemu_log("%s: %zd bytes\n", __func__, size));
 
@@ -841,6 +845,13 @@  static NetClientInfo net_xilinx_enet_info = {
     .cleanup = eth_cleanup,
 };
 
+static void transfer_timer(void *opaque)
+{
+    struct XilinxAXIEnet *s = (struct XilinxAXIEnet *)opaque;
+
+    s->rxing = false;
+}
+
 static int xilinx_enet_init(SysBusDevice *dev)
 {
     struct XilinxAXIEnet *s = FROM_SYSBUS(typeof(*s), dev);
@@ -859,6 +870,7 @@  static int xilinx_enet_init(SysBusDevice *dev)
     mdio_attach(&s->TEMAC.mdio_bus, &s->TEMAC.phy, s->c_phyaddr);
 
     s->TEMAC.parent = s;
+    s->transfer_timer = qemu_new_timer_ns(vm_clock, transfer_timer, s);
 
     s->rxmem = g_malloc(s->c_rxmem);
     axienet_reset(s);