On 1/29/20 10:27 AM, Finn Thain wrote:
> Follow the algorithm given in the National Semiconductor DP83932C
> datasheet in section 3.4.7:
>
> At the next reception, the SONIC re-reads the last RXpkt.link field,
> and updates its CRDA register to point to the next descriptor.
>
> The chip is designed to allow the host to provide a new list of
> descriptors in this way.
>
> Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
> Tested-by: Laurent Vivier <laurent@vivier.eu>
> ---
> Changed since v1:
> - Update CRDA register from LLFA register after EOL is cleared.
> ---
> hw/net/dp8393x.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
> index ece72cbf42..249be403af 100644
> --- a/hw/net/dp8393x.c
> +++ b/hw/net/dp8393x.c
> @@ -784,12 +784,13 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
> address = dp8393x_crda(s) + sizeof(uint16_t) * 5 * width;
> address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED,
> (uint8_t *)s->data, size, 0);
> - if (dp8393x_get(s, width, 0) & SONIC_DESC_EOL) {
> + s->regs[SONIC_LLFA] = dp8393x_get(s, width, 0);
> + if (s->regs[SONIC_LLFA] & SONIC_DESC_EOL) {
> /* Still EOL ; stop reception */
> return -1;
> - } else {
> - s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
> }
> + /* Link has been updated by host */
> + s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> }
>
> /* Save current position */
> @@ -837,7 +838,7 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
> address_space_rw(&s->as, dp8393x_crda(s),
> MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 1);
>
> - /* Move to next descriptor */
> + /* Check link field */
> size = sizeof(uint16_t) * width;
> address_space_rw(&s->as, dp8393x_crda(s) + sizeof(uint16_t) * 5 * width,
> MEMTXATTRS_UNSPECIFIED, (uint8_t *)s->data, size, 0);
> @@ -852,6 +853,8 @@ static ssize_t dp8393x_receive(NetClientState *nc, const uint8_t * buf,
> dp8393x_put(s, width, 0, 0);
> address_space_rw(&s->as, address, MEMTXATTRS_UNSPECIFIED,
> (uint8_t *)s->data, size, 1);
> +
> + /* Move to next descriptor */
> s->regs[SONIC_CRDA] = s->regs[SONIC_LLFA];
> s->regs[SONIC_ISR] |= SONIC_ISR_PKTRX;
> s->regs[SONIC_RSC] = (s->regs[SONIC_RSC] & 0xff00) | (((s->regs[SONIC_RSC] & 0x00ff) + 1) & 0x00ff);
>