diff mbox series

[v4,05/14] dp8393x: Update LLFA and CRDA registers from rx descriptor

Message ID dae9a2e3f6cdd403e6afab901b234a8b7f3289b8.1580290069.git.fthain@telegraphics.com.au (mailing list archive)
State New, archived
Headers show
Series Fixes for DP8393X SONIC device emulation | expand

Commit Message

Finn Thain Jan. 29, 2020, 9:27 a.m. UTC
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(-)

Comments

Philippe Mathieu-Daudé Jan. 29, 2020, 4:38 p.m. UTC | #1
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);
>
diff mbox series

Patch

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];
     }
 
     /* 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);