From patchwork Sat Jan 26 20:18:31 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [QEMU,RFC,2/2] xilinx_axienet: Model timing. Date: Sat, 26 Jan 2013 10:18:31 -0000 From: Peter Crosthwaite X-Patchwork-Id: 215931 Message-Id: To: Cc: edgar.iglesias@gmail.com, aliguori@us.ibm.com, Peter Crosthwaite , stefanha@gmail.com 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 Signed-off-by: Peter Crosthwaite --- hw/xilinx_axienet.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) 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);