On Thu, Apr 30, 2020 at 9:31 AM Edgar E. Iglesias <edgar.igles...@gmail.com> wrote: > > From: "Edgar E. Iglesias" <edgar.igles...@xilinx.com> > > Stream descriptor by descriptor from memory instead of > buffering entire packets before pushing. This enables > non-packet streaming clients to work and also lifts the > limitation that our internal DMA buffer needs to be able > to hold entire packets. > > Signed-off-by: Edgar E. Iglesias <edgar.igles...@xilinx.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > hw/dma/xilinx_axidma.c | 31 +++++++++++++++++-------------- > 1 file changed, 17 insertions(+), 14 deletions(-) > > diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c > index a770e12c96..101d32a965 100644 > --- a/hw/dma/xilinx_axidma.c > +++ b/hw/dma/xilinx_axidma.c > @@ -111,7 +111,6 @@ struct Stream { > int nr; > > struct SDesc desc; > - int pos; > unsigned int complete_cnt; > uint32_t regs[R_MAX]; > uint8_t app[20]; > @@ -267,7 +266,9 @@ static void stream_process_mem2s(struct Stream *s, > StreamSlave *tx_data_dev, > StreamSlave *tx_control_dev) > { > uint32_t prev_d; > - unsigned int txlen; > + uint32_t txlen; > + uint64_t addr; > + bool eop; > > if (!stream_running(s) || stream_idle(s)) { > return; > @@ -282,24 +283,26 @@ static void stream_process_mem2s(struct Stream *s, > StreamSlave *tx_data_dev, > } > > if (stream_desc_sof(&s->desc)) { > - s->pos = 0; > stream_push(tx_control_dev, s->desc.app, sizeof(s->desc.app), > true); > } > > txlen = s->desc.control & SDESC_CTRL_LEN_MASK; > - if ((txlen + s->pos) > sizeof s->txbuf) { > - hw_error("%s: too small internal txbuf! %d\n", __func__, > - txlen + s->pos); > - } > > - address_space_read(&s->dma->as, s->desc.buffer_address, > - MEMTXATTRS_UNSPECIFIED, > - s->txbuf + s->pos, txlen); > - s->pos += txlen; > + eop = stream_desc_eof(&s->desc); > + addr = s->desc.buffer_address; > + while (txlen) { > + unsigned int len; > + > + len = txlen > sizeof s->txbuf ? sizeof s->txbuf : txlen; > + address_space_read(&s->dma->as, addr, > + MEMTXATTRS_UNSPECIFIED, > + s->txbuf, len); > + stream_push(tx_data_dev, s->txbuf, len, eop && len == txlen); > + txlen -= len; > + addr += len; > + } > > - if (stream_desc_eof(&s->desc)) { > - stream_push(tx_data_dev, s->txbuf, s->pos, true); > - s->pos = 0; > + if (eop) { > stream_complete(s); > } > > -- > 2.20.1 > >