[PATCH 14/16] net: dm9000: Receive one packet per recv call

Ramon Fried rfried.dev at gmail.com
Tue Apr 12 21:51:26 CEST 2022


On Mon, Apr 11, 2022 at 8:56 PM Marek Vasut <marex at denx.de> wrote:
>
> Instead of reading out the entire FIFO and possibly overwriting U-Boot
> memory, read out one packet per recv call, pass it to U-Boot network
> stack, and repeat.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Joe Hershberger <joe.hershberger at ni.com>
> Cc: Ramon Fried <rfried.dev at gmail.com>
> ---
>  drivers/net/dm9000x.c | 102 +++++++++++++++++++++---------------------
>  1 file changed, 50 insertions(+), 52 deletions(-)
>
> diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
> index 97084d16ffa..84b012ec65d 100644
> --- a/drivers/net/dm9000x.c
> +++ b/drivers/net/dm9000x.c
> @@ -480,10 +480,9 @@ static void dm9000_halt_common(struct dm9000_priv *db)
>  /*
>   * Received a packet and pass to upper layer
>   */
> -static int dm9000_recv_common(struct dm9000_priv *db)
> +static int dm9000_recv_common(struct dm9000_priv *db, uchar *rdptr)
>  {
>         u8 rxbyte;
> -       u8 *rdptr = (u8 *)net_rx_packets[0];
>         u16 rxstatus, rxlen = 0;
>
>         /*
> @@ -496,58 +495,52 @@ static int dm9000_recv_common(struct dm9000_priv *db)
>         dm9000_iow(db, DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */
>
>         /* There is _at least_ 1 package in the fifo, read them all */
> -       for (;;) {
> -               dm9000_ior(db, DM9000_MRCMDX);  /* Dummy read */
> -
> -               /*
> -                * Get most updated data,
> -                * only look at bits 0:1, See application notes DM9000
> -                */
> -               rxbyte = dm9000_inb(db->base_data) & 0x03;
> -
> -               /* Status check: this byte must be 0 or 1 */
> -               if (rxbyte > DM9000_PKT_RDY) {
> -                       dm9000_iow(db, DM9000_RCR, 0x00);       /* Stop Device */
> -                       dm9000_iow(db, DM9000_ISR, 0x80);       /* Stop INT request */
> -                       printf("DM9000 error: status check fail: 0x%x\n",
> -                              rxbyte);
> -                       return 0;
> -               }
> +       dm9000_ior(db, DM9000_MRCMDX);  /* Dummy read */
> +
> +       /*
> +        * Get most updated data,
> +        * only look at bits 0:1, See application notes DM9000
> +        */
> +       rxbyte = dm9000_inb(db->base_data) & 0x03;
> +
> +       /* Status check: this byte must be 0 or 1 */
> +       if (rxbyte > DM9000_PKT_RDY) {
> +               dm9000_iow(db, DM9000_RCR, 0x00);       /* Stop Device */
> +               dm9000_iow(db, DM9000_ISR, 0x80);       /* Stop INT request */
> +               printf("DM9000 error: status check fail: 0x%x\n",
> +                      rxbyte);
> +               return -EINVAL;
> +       }
> +
> +       if (rxbyte != DM9000_PKT_RDY)
> +               return 0; /* No packet received, ignore */
>
> -               if (rxbyte != DM9000_PKT_RDY)
> -                       return 0; /* No packet received, ignore */
> -
> -               debug("receiving packet\n");
> -
> -               /* A packet ready now  & Get status/length */
> -               db->rx_status(db, &rxstatus, &rxlen);
> -
> -               debug("rx status: 0x%04x rx len: %d\n", rxstatus, rxlen);
> -
> -               /* Move data from DM9000 */
> -               /* Read received packet from RX SRAM */
> -               db->inblk(db, rdptr, rxlen);
> -
> -               if (rxstatus & 0xbf00 || rxlen < 0x40 ||
> -                   rxlen > DM9000_PKT_MAX) {
> -                       if (rxstatus & 0x100)
> -                               printf("rx fifo error\n");
> -                       if (rxstatus & 0x200)
> -                               printf("rx crc error\n");
> -                       if (rxstatus & 0x8000)
> -                               printf("rx length error\n");
> -                       if (rxlen > DM9000_PKT_MAX) {
> -                               printf("rx length too big\n");
> -                               dm9000_reset(db);
> -                       }
> -               } else {
> -                       dm9000_dump_packet(__func__, rdptr, rxlen);
> -
> -                       debug("passing packet to upper layer\n");
> -                       net_process_received_packet(net_rx_packets[0], rxlen);
> +       debug("receiving packet\n");
> +
> +       /* A packet ready now  & Get status/length */
> +       db->rx_status(db, &rxstatus, &rxlen);
> +
> +       debug("rx status: 0x%04x rx len: %d\n", rxstatus, rxlen);
> +
> +       /* Move data from DM9000 */
> +       /* Read received packet from RX SRAM */
> +       db->inblk(db, rdptr, rxlen);
> +
> +       if (rxstatus & 0xbf00 || rxlen < 0x40 || rxlen > DM9000_PKT_MAX) {
> +               if (rxstatus & 0x100)
> +                       printf("rx fifo error\n");
> +               if (rxstatus & 0x200)
> +                       printf("rx crc error\n");
> +               if (rxstatus & 0x8000)
> +                       printf("rx length error\n");
> +               if (rxlen > DM9000_PKT_MAX) {
> +                       printf("rx length too big\n");
> +                       dm9000_reset(db);
>                 }
> +               return -EINVAL;
>         }
> -       return 0;
> +
> +       return rxlen;
>  }
>
>  /*
> @@ -599,8 +592,13 @@ static int dm9000_send(struct eth_device *dev, void *packet, int length)
>  static int dm9000_recv(struct eth_device *dev)
>  {
>         struct dm9000_priv *db = container_of(dev, struct dm9000_priv, dev);
> +       int ret;
> +
> +       ret = dm9000_recv_common(db, net_rx_packets[0]);
> +       if (ret > 0)
> +               net_process_received_packet(net_rx_packets[0], ret);
>
> -       return dm9000_recv_common(db);
> +       return ret;
>  }
>
>  int dm9000_initialize(struct bd_info *bis)
> --
> 2.35.1
>
Reviewed-by: Ramon Fried <rfried.dev at gmail.com>


More information about the U-Boot mailing list