rxbuf_ptr() points to the beginning of a (RAM) RX buffer within the device state.
Signed-off-by: Philippe Mathieu-Daudé <phi...@linaro.org> Reviewed-by: Edgar E. Iglesias <edgar.igles...@amd.com> --- hw/net/xilinx_ethlite.c | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 21ce2a112c..a993cb8bb9 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -60,6 +60,13 @@ #define CTRL_P 0x2 #define CTRL_S 0x1 +typedef struct XlnxXpsEthLitePort +{ + struct { + uint32_t rx_ctrl; + } reg; +} XlnxXpsEthLitePort; + #define TYPE_XILINX_ETHLITE "xlnx.xps-ethernetlite" OBJECT_DECLARE_SIMPLE_TYPE(XlnxXpsEthLite, XILINX_ETHLITE) @@ -77,6 +84,7 @@ struct XlnxXpsEthLite unsigned int port_index; /* dual port RAM index */ UnimplementedDeviceState mdio; + XlnxXpsEthLitePort port[2]; uint32_t regs[R_MAX]; }; @@ -100,10 +108,18 @@ static void *txbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) return &s->regs[rxbase + R_TX_BUF0]; } +static void *rxbuf_ptr(XlnxXpsEthLite *s, unsigned port_index) +{ + unsigned int rxbase = port_index * (0x800 / 4); + + return &s->regs[rxbase + R_RX_BUF0]; +} + static uint64_t eth_read(void *opaque, hwaddr addr, unsigned int size) { XlnxXpsEthLite *s = opaque; + unsigned port_index = addr_to_port_index(addr); uint32_t r = 0; addr >>= 2; @@ -115,9 +131,12 @@ eth_read(void *opaque, hwaddr addr, unsigned int size) case R_TX_LEN1: case R_TX_CTRL1: case R_TX_CTRL0: + r = s->regs[addr]; + break; + case R_RX_CTRL1: case R_RX_CTRL0: - r = s->regs[addr]; + r = s->port[port_index].reg.rx_ctrl; break; default: @@ -167,7 +186,9 @@ eth_write(void *opaque, hwaddr addr, if (!(value & CTRL_S)) { qemu_flush_queued_packets(qemu_get_queue(s->nic)); } - /* fall through */ + s->port[port_index].reg.rx_ctrl = value; + break; + case R_TX_LEN0: case R_TX_LEN1: case R_TX_GIE0: @@ -197,22 +218,21 @@ static const MemoryRegionOps eth_ops = { static bool eth_can_rx(NetClientState *nc) { XlnxXpsEthLite *s = qemu_get_nic_opaque(nc); - unsigned int rxbase = s->port_index * (0x800 / 4); - return !(s->regs[rxbase + R_RX_CTRL0] & CTRL_S); + return !(s->port[s->port_index].reg.rx_ctrl & CTRL_S); } static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size) { XlnxXpsEthLite *s = qemu_get_nic_opaque(nc); - unsigned int rxbase = s->port_index * (0x800 / 4); + unsigned int port_index = s->port_index; /* DA filter. */ if (!(buf[0] & 0x80) && memcmp(&s->conf.macaddr.a[0], buf, 6)) return size; - if (s->regs[rxbase + R_RX_CTRL0] & CTRL_S) { - trace_ethlite_pkt_lost(s->regs[R_RX_CTRL0]); + if (s->port[port_index].reg.rx_ctrl & CTRL_S) { + trace_ethlite_pkt_lost(s->port[port_index].reg.rx_ctrl); return -1; } @@ -220,10 +240,10 @@ static ssize_t eth_rx(NetClientState *nc, const uint8_t *buf, size_t size) trace_ethlite_pkt_size_too_big(size); return -1; } - memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size); + memcpy(rxbuf_ptr(s, port_index), buf, size); - s->regs[rxbase + R_RX_CTRL0] |= CTRL_S; - if (s->regs[R_RX_CTRL0] & CTRL_I) { + s->port[port_index].reg.rx_ctrl |= CTRL_S; + if (s->port[port_index].reg.rx_ctrl & CTRL_I) { eth_pulse_irq(s); } -- 2.45.2