Fix lan9118 buffer length handling
authorRoy Franz <roy.franz@linaro.org>
Wed, 8 Jan 2014 04:19:52 +0000 (20:19 -0800)
committerStefan Hajnoczi <stefanha@redhat.com>
Mon, 27 Jan 2014 14:44:06 +0000 (15:44 +0100)
The 9118 ethernet controller supports transmission of multi-buffer packets
with arbitrary byte alignment of the start and end bytes.  All writes to
the packet fifo are 32 bits, so the controller discards bytes at the beginning
and end of each buffer based on the 'Data start offset' and 'Buffer size'
of the TX command 'A' format.

This patch uses the provided buffer length to limit the bytes transmitted.
Previously all the bytes of the last 32-bit word written to the TX fifo
were added to the internal transmit buffer structure resulting in more bytes
being transmitted than were submitted to the hardware in the command.  This
resulted in extra bytes being inserted into the middle of multi-buffer
packets when the non-final buffers had non-32bit aligned ending addresses.

Signed-off-by: Roy Franz <roy.franz@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
hw/net/lan9118.c

index bb0c503a1becf685f669e68ab2277ecb031cda3d..e528290b41ded1b5f8f7df2a4203ffee63672220 100644 (file)
@@ -763,7 +763,7 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
         if (s->txp->buffer_size <= 0 && s->txp->pad != 0) {
             s->txp->pad--;
         } else {
-            n = 4;
+            n = MIN(4, s->txp->buffer_size + s->txp->offset);
             while (s->txp->offset) {
                 val >>= 8;
                 n--;