Commit 2ad657e3 authored by Roy Franz's avatar Roy Franz Committed by Stefan Hajnoczi
Browse files

Fix lan9118 TX "CMD A" handling



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 changes the buffer size and offset internal state variables to be
updated on every "TX command A" write.  Previously they were only updated for
the first segment, which resulted incorrect behavior for packets with more
than one segment. Each segment of the packet has its own CMD A command, with
its own buffer size and start offset.

Also update extraction of fields from the CMD A word to use extract32().

Signed-off-by: default avatarRoy Franz <roy.franz@linaro.org>
Reviewed-by: default avatarPeter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 4bf2c138
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -727,14 +727,14 @@ static void tx_fifo_push(lan9118_state *s, uint32_t val)
        s->txp->cmd_a = val & 0x831f37ff;
        s->txp->fifo_used++;
        s->txp->state = TX_B;
        s->txp->buffer_size = extract32(s->txp->cmd_a, 0, 11);
        s->txp->offset = extract32(s->txp->cmd_a, 16, 5);
        break;
    case TX_B:
        if (s->txp->cmd_a & 0x2000) {
            /* First segment */
            s->txp->cmd_b = val;
            s->txp->fifo_used++;
            s->txp->buffer_size = s->txp->cmd_a & 0x7ff;
            s->txp->offset = (s->txp->cmd_a >> 16) & 0x1f;
            /* End alignment does not include command words.  */
            n = (s->txp->buffer_size + s->txp->offset + 3) >> 2;
            switch ((n >> 24) & 3) {