diff options
author | Edgar E. Iglesias <edgar.iglesias@xilinx.com> | 2013-12-03 21:55:05 -0800 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2013-12-10 13:28:49 +0000 |
commit | 3b2c97f9916e15ef630e3f8449b1b10902bf9407 (patch) | |
tree | 51a0b4dd8d1b9ddd10994748433d5cb337ac2149 /hw/net/cadence_gem.c | |
parent | 24e822ea4669145c94552cef67751fbd9a42b4c8 (diff) | |
download | qemu-3b2c97f9916e15ef630e3f8449b1b10902bf9407.zip |
net/cadence_gem: Update DMA rx descriptors as we process them
We were updating the ownership bit of all descriptors if packets
get split and written through several descriptors.
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: d61b7847b51487118783c93765a485bc5c66d272.1386136219.git.peter.crosthwaite@xilinx.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/net/cadence_gem.c')
-rw-r--r-- | hw/net/cadence_gem.c | 33 |
1 files changed, 16 insertions, 17 deletions
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index a31801d659..b84ee60942 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -592,6 +592,7 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) unsigned rxbuf_offset; uint8_t rxbuf[2048]; uint8_t *rxbuf_ptr; + bool first_desc = true; s = qemu_get_nic_opaque(nc); @@ -701,6 +702,21 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) rxbuf_ptr, MIN(bytes_to_copy, rxbufsize)); bytes_to_copy -= MIN(bytes_to_copy, rxbufsize); rxbuf_ptr += MIN(bytes_to_copy, rxbufsize); + + /* Update the descriptor. */ + if (first_desc) { + rx_desc_set_sof(desc); + first_desc = false; + } + if (bytes_to_copy == 0) { + rx_desc_set_eof(desc); + rx_desc_set_length(desc, size); + } + rx_desc_set_ownership(desc); + /* Descriptor write-back. */ + cpu_physical_memory_write(packet_desc_addr, + (uint8_t *)&desc[0], sizeof(desc)); + if (bytes_to_copy == 0) { break; } @@ -716,12 +732,6 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) DB_PRINT("set length: %ld, EOF on descriptor 0x%x\n", size, (unsigned)packet_desc_addr); - /* Update last descriptor with EOF and total length */ - rx_desc_set_eof(desc); - rx_desc_set_length(desc, size); - cpu_physical_memory_write(packet_desc_addr, - (uint8_t *)&desc[0], sizeof(desc)); - /* Advance RX packet descriptor Q */ last_desc_addr = packet_desc_addr; packet_desc_addr = s->rx_desc_addr; @@ -734,20 +744,9 @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size) s->rx_desc_addr += 8; } - DB_PRINT("set SOF, OWN on descriptor 0x%08x\n", (unsigned)packet_desc_addr); - /* Count it */ gem_receive_updatestats(s, buf, size); - /* Update first descriptor (which could also be the last) */ - /* read descriptor */ - cpu_physical_memory_read(packet_desc_addr, - (uint8_t *)&desc[0], sizeof(desc)); - rx_desc_set_sof(desc); - rx_desc_set_ownership(desc); - cpu_physical_memory_write(packet_desc_addr, - (uint8_t *)&desc[0], sizeof(desc)); - s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD; s->regs[GEM_ISR] |= GEM_INT_RXCMPL & ~(s->regs[GEM_IMR]); |