qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames


From: Michael S. Tsirkin
Subject: Re: [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames
Date: Thu, 5 May 2011 16:00:51 +0300
User-agent: Mutt/1.5.21 (2010-09-15)

On Sat, Apr 30, 2011 at 10:40:07PM +0200, Stefan Weil wrote:
> QEMU sends frames smaller than 60 bytes to ethernet nics.
> This should be fixed in the networking code because normally
> such frames are rejected by real NICs and their emulations.
> To avoid this behaviour, other NIC emulations pad received
> frames. This patch enables this workaround for eepro100, too.
> 
> All related code is marked with CONFIG_PAD_RECEIVED_FRAMES,
> so emulation of the correct handling for short frames can
> be restored as soon as QEMU's networking code is fixed.
> 
> Signed-off-by: Stefan Weil <address@hidden>

Applied, I tweaked the comment a bit as we don't intend
to change it in qemu. But go ahead and keep the ifdef around
if you like.

> ---
>  hw/eepro100.c |   25 ++++++++++++++++++++++++-
>  1 files changed, 24 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/eepro100.c b/hw/eepro100.c
> index 82c6369..2104bc0 100644
> --- a/hw/eepro100.c
> +++ b/hw/eepro100.c
> @@ -48,6 +48,14 @@
>  #include "eeprom93xx.h"
>  #include "sysemu.h"
>  
> +/* QEMU sends frames smaller than 60 bytes to ethernet nics.
> + * This should be fixed in the networking code because normally
> + * such frames are rejected by real nics and their emulations.
> + * To avoid this behaviour, other nic emulations pad received
> + * frames. The following definition enables this workaround for
> + * eepro100, too. */
> +#define CONFIG_PAD_RECEIVED_FRAMES
> +
>  #define KiB 1024
>  
>  /* Debug EEPRO100 card. */
> @@ -1656,19 +1664,32 @@ static ssize_t nic_receive(VLANClientState *nc, const 
> uint8_t * buf, size_t size
>       */
>      EEPRO100State *s = DO_UPCAST(NICState, nc, nc)->opaque;
>      uint16_t rfd_status = 0xa000;
> +#if defined(CONFIG_PAD_RECEIVED_FRAMES)
> +    uint8_t min_buf[60];
> +#endif
>      static const uint8_t broadcast_macaddr[6] =
>          { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
>  
> +#if defined(CONFIG_PAD_RECEIVED_FRAMES)
> +    /* Pad to minimum Ethernet frame length */
> +    if (size < sizeof(min_buf)) {
> +        memcpy(min_buf, buf, size);
> +        memset(&min_buf[size], 0, sizeof(min_buf) - size);
> +        buf = min_buf;
> +        size = sizeof(min_buf);
> +    }
> +#endif
> +
>      if (s->configuration[8] & 0x80) {
>          /* CSMA is disabled. */
>          logout("%p received while CSMA is disabled\n", s);
>          return -1;
> +#if !defined(CONFIG_PAD_RECEIVED_FRAMES)
>      } else if (size < 64 && (s->configuration[7] & BIT(0))) {
>          /* Short frame and configuration byte 7/0 (discard short receive) 
> set:
>           * Short frame is discarded */
>          logout("%p received short frame (%zu byte)\n", s, size);
>          s->statistics.rx_short_frame_errors++;
> -#if 0
>          return -1;
>  #endif
>      } else if ((size > MAX_ETH_FRAME_SIZE + 4) && !(s->configuration[18] & 
> BIT(3))) {
> @@ -1747,9 +1768,11 @@ static ssize_t nic_receive(VLANClientState *nc, const 
> uint8_t * buf, size_t size
>              "(%zu bytes); data truncated\n", rfd_size, size);
>          size = rfd_size;
>      }
> +#if !defined(CONFIG_PAD_RECEIVED_FRAMES)
>      if (size < 64) {
>          rfd_status |= 0x0080;
>      }
> +#endif
>      TRACE(OTHER, logout("command 0x%04x, link 0x%08x, addr 0x%08x, size 
> %u\n",
>            rfd_command, rx.link, rx.rx_buf_addr, rfd_size));
>      stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
> -- 
> 1.7.2.5



reply via email to

[Prev in Thread] Current Thread [Next in Thread]