hw/net/xilinx_ethlite: Introduce rxbuf_ptr() helper

rxbuf_ptr() points to the beginning of a (RAM) RX buffer
within the device state.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
Message-Id: <20241112181044.92193-11-philmd@linaro.org>
This commit is contained in:
Philippe Mathieu-Daudé 2024-11-11 18:51:57 +01:00
parent 8d956610f5
commit 785fd1a9af

View file

@ -60,6 +60,12 @@
#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 +83,7 @@ struct XlnxXpsEthLite
unsigned int port_index; /* dual port RAM index */
UnimplementedDeviceState mdio;
XlnxXpsEthLitePort port[2];
uint32_t regs[R_MAX];
};
@ -100,10 +107,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 +130,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 +185,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 +217,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 +239,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);
}