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 <hua...@xilinx.com> Signed-off-by: Peter Crosthwaite <peter.crosthwa...@xilinx.com> --- 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); -- 1.7.12.1.396.g16eed7c