Message ID | 20200430162439.2659-7-edgar.iglesias@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hw/core: stream: Add end-of-packet flag | expand |
On [2020 Apr 30] Thu 18:24:36, Edgar E. Iglesias wrote: > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com> > > Add support for fragmented packets from the DMA. > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com> > --- > hw/net/xilinx_axienet.c | 31 ++++++++++++++++++++++++------- > 1 file changed, 24 insertions(+), 7 deletions(-) > > diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c > index bd48305577..e3826cf3fc 100644 > --- a/hw/net/xilinx_axienet.c > +++ b/hw/net/xilinx_axienet.c > @@ -402,6 +402,9 @@ struct XilinxAXIEnet { > > uint32_t hdr[CONTROL_PAYLOAD_WORDS]; > > + uint8_t *txmem; > + uint32_t txpos; > + > uint8_t *rxmem; > uint32_t rxsize; > uint32_t rxpos; > @@ -421,6 +424,7 @@ static void axienet_rx_reset(XilinxAXIEnet *s) > static void axienet_tx_reset(XilinxAXIEnet *s) > { > s->tc = TC_JUM | TC_TX | TC_VLAN; > + s->txpos = 0; > } > > static inline int axienet_rx_resetting(XilinxAXIEnet *s) > @@ -902,17 +906,28 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj); > XilinxAXIEnet *s = ds->enet; > > - /* We don't support fragmented packets yet. */ > - assert(eop); > - > /* TX enable ? */ > if (!(s->tc & TC_TX)) { > return size; > } > > + if (s->txpos == 0 && eop) { > + /* Fast path single fragment. */ > + s->txpos = size; > + } else { > + memcpy(s->txmem + s->txpos, buf, size); > + buf = s->txmem; > + s->txpos += size; > + > + if (!eop) { > + return size; > + } > + } > + > /* Jumbo or vlan sizes ? */ > if (!(s->tc & TC_JUM)) { > - if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) { > + if (s->txpos > 1518 && s->txpos <= 1522 && !(s->tc & TC_VLAN)) { > + s->txpos = 0; > return size; > } > } > @@ -923,7 +938,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > uint32_t tmp_csum; > uint16_t csum; > > - tmp_csum = net_checksum_add(size - start_off, > + tmp_csum = net_checksum_add(s->txpos - start_off, > buf + start_off); > /* Accumulate the seed. */ > tmp_csum += s->hdr[2] & 0xffff; > @@ -936,12 +951,13 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > buf[write_off + 1] = csum & 0xff; > } > > - qemu_send_packet(qemu_get_queue(s->nic), buf, size); > + qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos); > > - s->stats.tx_bytes += size; > + s->stats.tx_bytes += s->txpos; > s->regs[R_IS] |= IS_TX_COMPLETE; > enet_update_irq(s); > > + s->txpos = 0; > return size; > } > > @@ -989,6 +1005,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) > s->TEMAC.parent = s; > > s->rxmem = g_malloc(s->c_rxmem); > + s->txmem = g_malloc(s->c_txmem); > return; > > xilinx_enet_realize_fail: > -- > 2.20.1 >
On Thu, Apr 30, 2020 at 06:24:36PM +0200, Edgar E. Iglesias wrote: > From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com> > > Add support for fragmented packets from the DMA. In v2 I'll add a check in the tx-path for packets larger than c_txmem... Cheers, Edgar > > Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> > --- > hw/net/xilinx_axienet.c | 31 ++++++++++++++++++++++++------- > 1 file changed, 24 insertions(+), 7 deletions(-) > > diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c > index bd48305577..e3826cf3fc 100644 > --- a/hw/net/xilinx_axienet.c > +++ b/hw/net/xilinx_axienet.c > @@ -402,6 +402,9 @@ struct XilinxAXIEnet { > > uint32_t hdr[CONTROL_PAYLOAD_WORDS]; > > + uint8_t *txmem; > + uint32_t txpos; > + > uint8_t *rxmem; > uint32_t rxsize; > uint32_t rxpos; > @@ -421,6 +424,7 @@ static void axienet_rx_reset(XilinxAXIEnet *s) > static void axienet_tx_reset(XilinxAXIEnet *s) > { > s->tc = TC_JUM | TC_TX | TC_VLAN; > + s->txpos = 0; > } > > static inline int axienet_rx_resetting(XilinxAXIEnet *s) > @@ -902,17 +906,28 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj); > XilinxAXIEnet *s = ds->enet; > > - /* We don't support fragmented packets yet. */ > - assert(eop); > - > /* TX enable ? */ > if (!(s->tc & TC_TX)) { > return size; > } > > + if (s->txpos == 0 && eop) { > + /* Fast path single fragment. */ > + s->txpos = size; > + } else { > + memcpy(s->txmem + s->txpos, buf, size); > + buf = s->txmem; > + s->txpos += size; > + > + if (!eop) { > + return size; > + } > + } > + > /* Jumbo or vlan sizes ? */ > if (!(s->tc & TC_JUM)) { > - if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) { > + if (s->txpos > 1518 && s->txpos <= 1522 && !(s->tc & TC_VLAN)) { > + s->txpos = 0; > return size; > } > } > @@ -923,7 +938,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > uint32_t tmp_csum; > uint16_t csum; > > - tmp_csum = net_checksum_add(size - start_off, > + tmp_csum = net_checksum_add(s->txpos - start_off, > buf + start_off); > /* Accumulate the seed. */ > tmp_csum += s->hdr[2] & 0xffff; > @@ -936,12 +951,13 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, > buf[write_off + 1] = csum & 0xff; > } > > - qemu_send_packet(qemu_get_queue(s->nic), buf, size); > + qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos); > > - s->stats.tx_bytes += size; > + s->stats.tx_bytes += s->txpos; > s->regs[R_IS] |= IS_TX_COMPLETE; > enet_update_irq(s); > > + s->txpos = 0; > return size; > } > > @@ -989,6 +1005,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) > s->TEMAC.parent = s; > > s->rxmem = g_malloc(s->c_rxmem); > + s->txmem = g_malloc(s->c_txmem); > return; > > xilinx_enet_realize_fail: > -- > 2.20.1 >
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index bd48305577..e3826cf3fc 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -402,6 +402,9 @@ struct XilinxAXIEnet { uint32_t hdr[CONTROL_PAYLOAD_WORDS]; + uint8_t *txmem; + uint32_t txpos; + uint8_t *rxmem; uint32_t rxsize; uint32_t rxpos; @@ -421,6 +424,7 @@ static void axienet_rx_reset(XilinxAXIEnet *s) static void axienet_tx_reset(XilinxAXIEnet *s) { s->tc = TC_JUM | TC_TX | TC_VLAN; + s->txpos = 0; } static inline int axienet_rx_resetting(XilinxAXIEnet *s) @@ -902,17 +906,28 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(obj); XilinxAXIEnet *s = ds->enet; - /* We don't support fragmented packets yet. */ - assert(eop); - /* TX enable ? */ if (!(s->tc & TC_TX)) { return size; } + if (s->txpos == 0 && eop) { + /* Fast path single fragment. */ + s->txpos = size; + } else { + memcpy(s->txmem + s->txpos, buf, size); + buf = s->txmem; + s->txpos += size; + + if (!eop) { + return size; + } + } + /* Jumbo or vlan sizes ? */ if (!(s->tc & TC_JUM)) { - if (size > 1518 && size <= 1522 && !(s->tc & TC_VLAN)) { + if (s->txpos > 1518 && s->txpos <= 1522 && !(s->tc & TC_VLAN)) { + s->txpos = 0; return size; } } @@ -923,7 +938,7 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, uint32_t tmp_csum; uint16_t csum; - tmp_csum = net_checksum_add(size - start_off, + tmp_csum = net_checksum_add(s->txpos - start_off, buf + start_off); /* Accumulate the seed. */ tmp_csum += s->hdr[2] & 0xffff; @@ -936,12 +951,13 @@ xilinx_axienet_data_stream_push(StreamSlave *obj, uint8_t *buf, size_t size, buf[write_off + 1] = csum & 0xff; } - qemu_send_packet(qemu_get_queue(s->nic), buf, size); + qemu_send_packet(qemu_get_queue(s->nic), buf, s->txpos); - s->stats.tx_bytes += size; + s->stats.tx_bytes += s->txpos; s->regs[R_IS] |= IS_TX_COMPLETE; enet_update_irq(s); + s->txpos = 0; return size; } @@ -989,6 +1005,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp) s->TEMAC.parent = s; s->rxmem = g_malloc(s->c_rxmem); + s->txmem = g_malloc(s->c_txmem); return; xilinx_enet_realize_fail: