qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements)
@ 2011-04-30 20:40 Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 01/10] eepro100: Avoid duplicate debug messages Stefan Weil
                   ` (11 more replies)
  0 siblings, 12 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

Hi,

this is the second version of a series of patches for eepro100 which mainly
fix endianness issues and enhance register access. There was a bug report
on qemu-devel recently which is fixed by these enhancements, see
http://lists.nongnu.org/archive/html/qemu-devel/2011-03/msg02109.html.

Changes in v2:

* The 2nd patch is new.

* Patches are sorted in a different order. The first 4 patches and the
  rest are independent, so it's possible to apply parts of the series.

* The endianness patch was updated to address the feedback which I received.
  I still use local functions to access physical memory - mainly because
  I want to use cpu_physical_memory_read / cpu_physical_memory_write as long
  as I am not sure whether the alignment requirements for the suggested
  open coded variant are met.
  The prefix is e100 - shorter and more up-to-date than eepro100.
  When I started this device emulation, linux still used a module called
  eepro100. Today, the only linux module is called e100. So my final goal
  is renaming all eepro100 to e100.

I did not change the patch which adds padding to short received frames,
because I'd like to keep the preprocessor statement (CONFIG_PAD_RECEIVED_FRAMES)
as some kind of documentation (even if QEMU's network code won't be modified
in the near future to fully support a real ethernet emulation).

Kind regards,

Stefan W.



The following changes since commit 08ab2ccb08372a52ee1c597acf640cadb9089a3a:

  Merge branch 'patches' of git://qemu.weilnetz.de/git/qemu (2011-04-29 20:01:51 +0000)

are available in the git repository at:

  git://qemu.weilnetz.de/git/qemu.git patches

Stefan Weil (10):
      eepro100: Avoid duplicate debug messages
      eepro100: Remove type casts which are no longer needed
      eepro100: Remove unused structure element
      eepro100: Pad received short frames
      eepro100: Fix endianness issues
      eepro100: Support byte/word writes to port address
      eepro100: Support byte/word writes to pointer register
      eepro100: Support byte/word read/write access to MDI control register
      eepro100: Support byte read access to general control register
      eepro100: Support 32 bit read/write access to flash register

 hw/eepro100.c |  298 +++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 217 insertions(+), 81 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 01/10] eepro100: Avoid duplicate debug messages
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 02/10] eepro100: Remove type casts which are no longer needed Stefan Weil
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

When DEBUG_EEPRO100 was enabled, unsupported writes were logged twice.
Now logging in eepro100_write1 and eepro100_write2 is similar to the
logging in eepro100_write4 (which already was correct).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 369ad7f..cbbaf14 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1,7 +1,7 @@
 /*
  * QEMU i8255x (PRO100) emulation
  *
- * Copyright (C) 2006-2010 Stefan Weil
+ * Copyright (C) 2006-2011 Stefan Weil
  *
  * Portions of the code are copies from grub / etherboot eepro100.c
  * and linux e100.c.
@@ -1393,18 +1393,20 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
         memcpy(&s->mem[addr], &val, sizeof(val));
     }
 
-    TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
-
     switch (addr) {
     case SCBStatus:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         break;
     case SCBAck:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         eepro100_acknowledge(s);
         break;
     case SCBCmd:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         eepro100_write_command(s, val);
         break;
     case SCBIntmask:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         if (val & BIT(1)) {
             eepro100_swi_interrupt(s);
         }
@@ -1418,6 +1420,7 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
         TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         break;
     case SCBeeprom:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         eepro100_write_eeprom(s->eeprom, val);
         break;
     default:
@@ -1433,18 +1436,19 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
         memcpy(&s->mem[addr], &val, sizeof(val));
     }
 
-    TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
-
     switch (addr) {
     case SCBStatus:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         s->mem[SCBAck] = (val >> 8);
         eepro100_acknowledge(s);
         break;
     case SCBCmd:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         eepro100_write_command(s, val);
         eepro100_write1(s, SCBIntmask, val >> 8);
         break;
     case SCBeeprom:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         eepro100_write_eeprom(s->eeprom, val);
         break;
     default:
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 02/10] eepro100: Remove type casts which are no longer needed
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 01/10] eepro100: Avoid duplicate debug messages Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 03/10] eepro100: Remove unused structure element Stefan Weil
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index cbbaf14..0e22d91 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -311,7 +311,7 @@ static const uint16_t eepro100_mdi_mask[] = {
 static void stl_le_phys(target_phys_addr_t addr, uint32_t val)
 {
     val = cpu_to_le32(val);
-    cpu_physical_memory_write(addr, (const uint8_t *)&val, sizeof(val));
+    cpu_physical_memory_write(addr, &val, sizeof(val));
 }
 
 #define POLYNOMIAL 0x04c11db6
@@ -694,8 +694,7 @@ static void dump_statistics(EEPRO100State * s)
      * values which really matter.
      * Number of data should check configuration!!!
      */
-    cpu_physical_memory_write(s->statsaddr,
-                              (uint8_t *) & s->statistics, s->stats_size);
+    cpu_physical_memory_write(s->statsaddr, &s->statistics, s->stats_size);
     stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
     stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
     stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
@@ -709,7 +708,7 @@ static void dump_statistics(EEPRO100State * s)
 
 static void read_cb(EEPRO100State *s)
 {
-    cpu_physical_memory_read(s->cb_address, (uint8_t *) &s->tx, sizeof(s->tx));
+    cpu_physical_memory_read(s->cb_address, &s->tx, sizeof(s->tx));
     s->tx.status = le16_to_cpu(s->tx.status);
     s->tx.command = le16_to_cpu(s->tx.command);
     s->tx.link = le32_to_cpu(s->tx.link);
@@ -1268,10 +1267,10 @@ static void eepro100_write_port(EEPRO100State * s, uint32_t val)
     case PORT_SELFTEST:
         TRACE(OTHER, logout("selftest address=0x%08x\n", address));
         eepro100_selftest_t data;
-        cpu_physical_memory_read(address, (uint8_t *) & data, sizeof(data));
+        cpu_physical_memory_read(address, &data, sizeof(data));
         data.st_sign = 0xffffffff;
         data.st_result = 0;
-        cpu_physical_memory_write(address, (uint8_t *) & data, sizeof(data));
+        cpu_physical_memory_write(address, &data, sizeof(data));
         break;
     case PORT_SELECTIVE_RESET:
         TRACE(OTHER, logout("selective reset, selftest address=0x%08x\n", address));
@@ -1738,7 +1737,7 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
     }
     /* !!! */
     eepro100_rx_t rx;
-    cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
+    cpu_physical_memory_read(s->ru_base + s->ru_offset, &rx,
                              offsetof(eepro100_rx_t, packet));
     uint16_t rfd_command = le16_to_cpu(rx.command);
     uint16_t rfd_size = le16_to_cpu(rx.size);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 03/10] eepro100: Remove unused structure element
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 01/10] eepro100: Avoid duplicate debug messages Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 02/10] eepro100: Remove type casts which are no longer needed Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames Stefan Weil
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

cppcheck reports that 'packet' is unused.

It was only used to calculate the size of the preceding data.
Removing it saves a lot of stack space (local variable rx).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 0e22d91..82c6369 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -173,7 +173,7 @@ typedef struct {
     uint32_t rx_buf_addr;       /* void * */
     uint16_t count;
     uint16_t size;
-    char packet[MAX_ETH_FRAME_SIZE + 4];
+    /* Ethernet frame data follows. */
 } eepro100_rx_t;
 
 typedef enum {
@@ -1738,7 +1738,7 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
     /* !!! */
     eepro100_rx_t rx;
     cpu_physical_memory_read(s->ru_base + s->ru_offset, &rx,
-                             offsetof(eepro100_rx_t, packet));
+                             sizeof(eepro100_rx_t));
     uint16_t rfd_command = le16_to_cpu(rx.command);
     uint16_t rfd_size = le16_to_cpu(rx.size);
 
@@ -1769,7 +1769,7 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
     assert(!(s->configuration[17] & BIT(0)));
 #endif
     cpu_physical_memory_write(s->ru_base + s->ru_offset +
-                              offsetof(eepro100_rx_t, packet), buf, size);
+                              sizeof(eepro100_rx_t), buf, size);
     s->statistics.rx_good_frames++;
     eepro100_fr_interrupt(s);
     s->ru_offset = le32_to_cpu(rx.link);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (2 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 03/10] eepro100: Remove unused structure element Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-05-05 13:00   ` Michael S. Tsirkin
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 05/10] eepro100: Fix endianness issues Stefan Weil
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

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 <weil@mail.berlios.de>
---
 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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 05/10] eepro100: Fix endianness issues
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (3 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 06/10] eepro100: Support byte/word writes to port address Stefan Weil
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

Like other Intel devices, e100 (eepro100) uses little endian byte order.

This patch was tested with these combinations:

i386 host, i386 + mipsel guests (le-le)
mipsel host, i386 guest (le-le)
i386 host, mips + ppc guests (le-be)
mips host, i386 guest (be-le)

mips and mipsel hosts were emulated machines.

v2:
Use prefix for new functions. Add the same prefix to stl_le_phys.
Fix alignment of mem (needed for word/dword reads/writes).

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |  141 +++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 97 insertions(+), 44 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 2104bc0..134e146 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -20,11 +20,10 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  * Tested features (i82559):
- *      PXE boot (i386) ok
+ *      PXE boot (i386 guest, i386 / mips / mipsel / ppc host) ok
  *      Linux networking (i386) ok
  *
  * Untested:
- *      non-i386 platforms
  *      Windows networking
  *
  * References:
@@ -138,7 +137,7 @@ typedef struct {
 
 /* Offsets to the various registers.
    All accesses need not be longword aligned. */
-enum speedo_offsets {
+typedef enum {
     SCBStatus = 0,              /* Status Word. */
     SCBAck = 1,
     SCBCmd = 2,                 /* Rx/Command Unit command and status. */
@@ -153,7 +152,7 @@ enum speedo_offsets {
     SCBpmdr = 27,               /* Power Management Driver. */
     SCBgctrl = 28,              /* General Control. */
     SCBgstat = 29,              /* General Status. */
-};
+} E100RegisterOffset;
 
 /* A speedo3 transmit buffer descriptor with two buffers... */
 typedef struct {
@@ -257,11 +256,13 @@ typedef struct {
     /* Statistical counters. Also used for wake-up packet (i82559). */
     eepro100_stats_t statistics;
 
+    /* Data in mem is always in the byte order of the controller (le).
+     * It must be dword aligned to allow direct access to 32 bit values. */
+    uint8_t mem[PCI_MEM_SIZE] __attribute__((aligned(8)));;
+
     /* Configuration bytes. */
     uint8_t configuration[22];
 
-    /* Data in mem is always in the byte order of the controller (le). */
-    uint8_t mem[PCI_MEM_SIZE];
     /* vmstate for each particular nic */
     VMStateDescription *vmstate;
 
@@ -315,8 +316,33 @@ static const uint16_t eepro100_mdi_mask[] = {
     0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
 };
 
-/* XXX: optimize */
-static void stl_le_phys(target_phys_addr_t addr, uint32_t val)
+/* Read a 16 bit little endian value from physical memory. */
+static uint16_t e100_ldw_le_phys(target_phys_addr_t addr)
+{
+    /* Load 16 bit (little endian) word from emulated hardware. */
+    uint16_t val;
+    cpu_physical_memory_read(addr, &val, sizeof(val));
+    return le16_to_cpu(val);
+}
+
+/* Read a 32 bit little endian value from physical memory. */
+static uint32_t e100_ldl_le_phys(target_phys_addr_t addr)
+{
+    /* Load 32 bit (little endian) word from emulated hardware. */
+    uint32_t val;
+    cpu_physical_memory_read(addr, &val, sizeof(val));
+    return le32_to_cpu(val);
+}
+
+/* Write a 16 bit little endian value to physical memory. */
+static void e100_stw_le_phys(target_phys_addr_t addr, uint16_t val)
+{
+    val = cpu_to_le16(val);
+    cpu_physical_memory_write(addr, &val, sizeof(val));
+}
+
+/* Write a 32 bit little endian value to physical memory. */
+static void e100_stl_le_phys(target_phys_addr_t addr, uint32_t val)
 {
     val = cpu_to_le32(val);
     cpu_physical_memory_write(addr, &val, sizeof(val));
@@ -347,6 +373,36 @@ static unsigned compute_mcast_idx(const uint8_t * ep)
     return (crc & BITS(7, 2)) >> 2;
 }
 
+/* Read a 16 bit control/status (CSR) register. */
+static uint16_t e100_read_reg2(EEPRO100State *s, E100RegisterOffset addr)
+{
+    assert(!((uintptr_t)&s->mem[addr] & 1));
+    return le16_to_cpup((uint16_t *)&s->mem[addr]);
+}
+
+/* Read a 32 bit control/status (CSR) register. */
+static uint32_t e100_read_reg4(EEPRO100State *s, E100RegisterOffset addr)
+{
+    assert(!((uintptr_t)&s->mem[addr] & 3));
+    return le32_to_cpup((uint32_t *)&s->mem[addr]);
+}
+
+/* Write a 16 bit control/status (CSR) register. */
+static void e100_write_reg2(EEPRO100State *s, E100RegisterOffset addr,
+                            uint16_t val)
+{
+    assert(!((uintptr_t)&s->mem[addr] & 1));
+    cpu_to_le16w((uint16_t *)&s->mem[addr], val);
+}
+
+/* Read a 32 bit control/status (CSR) register. */
+static void e100_write_reg4(EEPRO100State *s, E100RegisterOffset addr,
+                            uint32_t val)
+{
+    assert(!((uintptr_t)&s->mem[addr] & 3));
+    cpu_to_le32w((uint32_t *)&s->mem[addr], val);
+}
+
 #if defined(DEBUG_EEPRO100)
 static const char *nic_dump(const uint8_t * buf, unsigned size)
 {
@@ -598,8 +654,7 @@ static void nic_selective_reset(EEPRO100State * s)
     TRACE(EEPROM, logout("checksum=0x%04x\n", eeprom_contents[EEPROM_SIZE - 1]));
 
     memset(s->mem, 0, sizeof(s->mem));
-    uint32_t val = BIT(21);
-    memcpy(&s->mem[SCBCtrlMDI], &val, sizeof(val));
+    e100_write_reg4(s, SCBCtrlMDI, BIT(21));
 
     assert(sizeof(s->mdimem) == sizeof(eepro100_mdi_default));
     memcpy(&s->mdimem[0], &eepro100_mdi_default[0], sizeof(s->mdimem));
@@ -703,13 +758,13 @@ static void dump_statistics(EEPRO100State * s)
      * Number of data should check configuration!!!
      */
     cpu_physical_memory_write(s->statsaddr, &s->statistics, s->stats_size);
-    stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
-    stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
-    stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
-    stl_le_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
+    e100_stl_le_phys(s->statsaddr + 0, s->statistics.tx_good_frames);
+    e100_stl_le_phys(s->statsaddr + 36, s->statistics.rx_good_frames);
+    e100_stl_le_phys(s->statsaddr + 48, s->statistics.rx_resource_errors);
+    e100_stl_le_phys(s->statsaddr + 60, s->statistics.rx_short_frame_errors);
 #if 0
-    stw_le_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
-    stw_le_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
+    e100_stw_le_phys(s->statsaddr + 76, s->statistics.xmt_tco_frames);
+    e100_stw_le_phys(s->statsaddr + 78, s->statistics.rcv_tco_frames);
     missing("CU dump statistical counters");
 #endif
 }
@@ -746,10 +801,10 @@ static void tx_command(EEPRO100State *s)
     }
     assert(tcb_bytes <= sizeof(buf));
     while (size < tcb_bytes) {
-        uint32_t tx_buffer_address = ldl_phys(tbd_address);
-        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
+        uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
+        uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
 #if 0
-        uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
+        uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
 #endif
         tbd_address += 8;
         TRACE(RXTX, logout
@@ -768,9 +823,9 @@ static void tx_command(EEPRO100State *s)
         if (s->has_extended_tcb_support && !(s->configuration[6] & BIT(4))) {
             /* Extended Flexible TCB. */
             for (; tbd_count < 2; tbd_count++) {
-                uint32_t tx_buffer_address = ldl_phys(tbd_address);
-                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
-                uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
+                uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
+                uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
+                uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
                 tbd_address += 8;
                 TRACE(RXTX, logout
                     ("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
@@ -786,9 +841,9 @@ static void tx_command(EEPRO100State *s)
         }
         tbd_address = tbd_array;
         for (; tbd_count < s->tx.tbd_count; tbd_count++) {
-            uint32_t tx_buffer_address = ldl_phys(tbd_address);
-            uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
-            uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
+            uint32_t tx_buffer_address = e100_ldl_le_phys(tbd_address);
+            uint16_t tx_buffer_size = e100_ldw_le_phys(tbd_address + 4);
+            uint16_t tx_buffer_el = e100_ldw_le_phys(tbd_address + 6);
             tbd_address += 8;
             TRACE(RXTX, logout
                 ("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
@@ -896,7 +951,7 @@ static void action_command(EEPRO100State *s)
             break;
         }
         /* Write new status. */
-        stw_phys(s->cb_address, s->tx.status | ok_status | STATUS_C);
+        e100_stw_le_phys(s->cb_address, s->tx.status | ok_status | STATUS_C);
         if (bit_i) {
             /* CU completed action. */
             eepro100_cx_interrupt(s);
@@ -963,7 +1018,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
         /* Dump statistical counters. */
         TRACE(OTHER, logout("val=0x%02x (dump stats)\n", val));
         dump_statistics(s);
-        stl_le_phys(s->statsaddr + s->stats_size, 0xa005);
+        e100_stl_le_phys(s->statsaddr + s->stats_size, 0xa005);
         break;
     case CU_CMD_BASE:
         /* Load CU base. */
@@ -974,7 +1029,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
         /* Dump and reset statistical counters. */
         TRACE(OTHER, logout("val=0x%02x (dump stats and reset)\n", val));
         dump_statistics(s);
-        stl_le_phys(s->statsaddr + s->stats_size, 0xa007);
+        e100_stl_le_phys(s->statsaddr + s->stats_size, 0xa007);
         memset(&s->statistics, 0, sizeof(s->statistics));
         break;
     case CU_SRESUME:
@@ -1057,8 +1112,7 @@ static void eepro100_write_command(EEPRO100State * s, uint8_t val)
 
 static uint16_t eepro100_read_eeprom(EEPRO100State * s)
 {
-    uint16_t val;
-    memcpy(&val, &s->mem[SCBeeprom], sizeof(val));
+    uint16_t val = e100_read_reg2(s, SCBeeprom);
     if (eeprom93xx_read(s->eeprom)) {
         val |= EEPROM_DO;
     } else {
@@ -1128,8 +1182,7 @@ static const char *reg2name(uint8_t reg)
 
 static uint32_t eepro100_read_mdi(EEPRO100State * s)
 {
-    uint32_t val;
-    memcpy(&val, &s->mem[0x10], sizeof(val));
+    uint32_t val = e100_read_reg4(s, SCBCtrlMDI);
 
 #ifdef DEBUG_EEPRO100
     uint8_t raiseint = (val & BIT(29)) >> 29;
@@ -1238,7 +1291,7 @@ static void eepro100_write_mdi(EEPRO100State * s, uint32_t val)
         }
     }
     val = (val & 0xffff0000) + data;
-    memcpy(&s->mem[0x10], &val, sizeof(val));
+    e100_write_reg4(s, SCBCtrlMDI, val);
 }
 
 /*****************************************************************************
@@ -1265,7 +1318,6 @@ static uint32_t eepro100_read_port(EEPRO100State * s)
 
 static void eepro100_write_port(EEPRO100State * s, uint32_t val)
 {
-    val = le32_to_cpu(val);
     uint32_t address = (val & ~PORT_SELECTION_MASK);
     uint8_t selection = (val & PORT_SELECTION_MASK);
     switch (selection) {
@@ -1300,7 +1352,7 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
 {
     uint8_t val = 0;
     if (addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&val, &s->mem[addr], sizeof(val));
+        val = s->mem[addr];
     }
 
     switch (addr) {
@@ -1343,7 +1395,7 @@ static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr)
 {
     uint16_t val = 0;
     if (addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&val, &s->mem[addr], sizeof(val));
+        val = e100_read_reg2(s, addr);
     }
 
     switch (addr) {
@@ -1366,7 +1418,7 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
 {
     uint32_t val = 0;
     if (addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&val, &s->mem[addr], sizeof(val));
+        val = e100_read_reg4(s, addr);
     }
 
     switch (addr) {
@@ -1397,7 +1449,7 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
 {
     /* SCBStatus is readonly. */
     if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&s->mem[addr], &val, sizeof(val));
+        s->mem[addr] = val;
     }
 
     switch (addr) {
@@ -1440,7 +1492,7 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
 {
     /* SCBStatus is readonly. */
     if (addr > SCBStatus && addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&s->mem[addr], &val, sizeof(val));
+        e100_write_reg2(s, addr, val);
     }
 
     switch (addr) {
@@ -1467,7 +1519,7 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
 static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
 {
     if (addr <= sizeof(s->mem) - sizeof(val)) {
-        memcpy(&s->mem[addr], &val, sizeof(val));
+        e100_write_reg4(s, addr, val);
     }
 
     switch (addr) {
@@ -1775,9 +1827,10 @@ static ssize_t nic_receive(VLANClientState *nc, const uint8_t * buf, size_t size
 #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),
-             rfd_status);
-    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
+    e100_stw_le_phys(s->ru_base + s->ru_offset +
+                     offsetof(eepro100_rx_t, status), rfd_status);
+    e100_stw_le_phys(s->ru_base + s->ru_offset +
+                     offsetof(eepro100_rx_t, count), size);
     /* Early receive interrupt not supported. */
 #if 0
     eepro100_er_interrupt(s);
@@ -1906,7 +1959,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
     /* Handler for memory-mapped I/O */
     s->mmio_index =
         cpu_register_io_memory(pci_mmio_read, pci_mmio_write, s,
-                               DEVICE_NATIVE_ENDIAN);
+                               DEVICE_LITTLE_ENDIAN);
 
     pci_register_bar(&s->dev, 0, PCI_MEM_SIZE,
                            PCI_BASE_ADDRESS_SPACE_MEMORY |
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 06/10] eepro100: Support byte/word writes to port address
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (4 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 05/10] eepro100: Fix endianness issues Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 07/10] eepro100: Support byte/word writes to pointer register Stefan Weil
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

port is a 32 bit register, but may be written using 8 or 16 bit writes.
Add support for byte/word writes.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 134e146..37172a5 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1316,8 +1316,9 @@ static uint32_t eepro100_read_port(EEPRO100State * s)
     return 0;
 }
 
-static void eepro100_write_port(EEPRO100State * s, uint32_t val)
+static void eepro100_write_port(EEPRO100State *s)
 {
+    uint32_t val = e100_read_reg4(s, SCBPort);
     uint32_t address = (val & ~PORT_SELECTION_MASK);
     uint8_t selection = (val & PORT_SELECTION_MASK);
     switch (selection) {
@@ -1471,7 +1472,15 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
         }
         eepro100_interrupt(s, 0);
         break;
+    case SCBPort:
+    case SCBPort + 1:
+    case SCBPort + 2:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        break;
     case SCBPort + 3:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        eepro100_write_port(s);
+        break;
     case SCBFlow:       /* does not exist on 82557 */
     case SCBFlow + 1:
     case SCBFlow + 2:
@@ -1506,6 +1515,13 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
         eepro100_write_command(s, val);
         eepro100_write1(s, SCBIntmask, val >> 8);
         break;
+    case SCBPort:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        break;
+    case SCBPort + 2:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        eepro100_write_port(s);
+        break;
     case SCBeeprom:
         TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         eepro100_write_eeprom(s->eeprom, val);
@@ -1528,7 +1544,7 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
         break;
     case SCBPort:
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
-        eepro100_write_port(s, val);
+        eepro100_write_port(s);
         break;
     case SCBCtrlMDI:
         eepro100_write_mdi(s, val);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 07/10] eepro100: Support byte/word writes to pointer register
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (5 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 06/10] eepro100: Support byte/word writes to port address Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 08/10] eepro100: Support byte/word read/write access to MDI control register Stefan Weil
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

pointer is a 32 bit register, but may be written using 8 or 16 bit writes.
Add support for byte/word writes.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |   33 ++++++++++++++++-----------------
 1 files changed, 16 insertions(+), 17 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 37172a5..1949ee0 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -239,7 +239,6 @@ typedef struct {
     uint16_t mdimem[32];
     eeprom_t *eeprom;
     uint32_t device;            /* device variant */
-    uint32_t pointer;
     /* (cu_base + cu_offset) address the next command block in the command block list. */
     uint32_t cu_base;           /* CU base address */
     uint32_t cu_offset;         /* CU address offset */
@@ -990,7 +989,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
             logout("unexpected CU state is %u\n", cu_state);
         }
         set_cu_state(s, cu_active);
-        s->cu_offset = s->pointer;
+        s->cu_offset = e100_read_reg4(s, SCBPointer);
         action_command(s);
         break;
     case CU_RESUME:
@@ -1011,7 +1010,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
         break;
     case CU_STATSADDR:
         /* Load dump counters address. */
-        s->statsaddr = s->pointer;
+        s->statsaddr = e100_read_reg4(s, SCBPointer);
         TRACE(OTHER, logout("val=0x%02x (status address)\n", val));
         break;
     case CU_SHOWSTATS:
@@ -1023,7 +1022,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
     case CU_CMD_BASE:
         /* Load CU base. */
         TRACE(OTHER, logout("val=0x%02x (CU base address)\n", val));
-        s->cu_base = s->pointer;
+        s->cu_base = e100_read_reg4(s, SCBPointer);
         break;
     case CU_DUMPSTATS:
         /* Dump and reset statistical counters. */
@@ -1056,7 +1055,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
 #endif
         }
         set_ru_state(s, ru_ready);
-        s->ru_offset = s->pointer;
+        s->ru_offset = e100_read_reg4(s, SCBPointer);
         TRACE(OTHER, logout("val=0x%02x (rx start)\n", val));
         break;
     case RX_RESUME:
@@ -1080,7 +1079,7 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
     case RX_ADDR_LOAD:
         /* Load RU base. */
         TRACE(OTHER, logout("val=0x%02x (RU base address)\n", val));
-        s->ru_base = s->pointer;
+        s->ru_base = e100_read_reg4(s, SCBPointer);
         break;
     default:
         logout("val=0x%02x (undefined RU command)\n", val);
@@ -1137,12 +1136,6 @@ static void eepro100_write_eeprom(eeprom_t * eeprom, uint8_t val)
     eeprom93xx_write(eeprom, eecs, eesk, eedi);
 }
 
-static void eepro100_write_pointer(EEPRO100State * s, uint32_t val)
-{
-    s->pointer = le32_to_cpu(val);
-    TRACE(OTHER, logout("val=0x%08x\n", val));
-}
-
 /*****************************************************************************
  *
  * MDI emulation.
@@ -1427,9 +1420,6 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         break;
     case SCBPointer:
-#if 0
-        val = eepro100_read_pointer(s);
-#endif
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         break;
     case SCBPort:
@@ -1472,6 +1462,12 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
         }
         eepro100_interrupt(s, 0);
         break;
+    case SCBPointer:
+    case SCBPointer + 1:
+    case SCBPointer + 2:
+    case SCBPointer + 3:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        break;
     case SCBPort:
     case SCBPort + 1:
     case SCBPort + 2:
@@ -1515,6 +1511,10 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
         eepro100_write_command(s, val);
         eepro100_write1(s, SCBIntmask, val >> 8);
         break;
+    case SCBPointer:
+    case SCBPointer + 2:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        break;
     case SCBPort:
         TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         break;
@@ -1540,7 +1540,7 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
 
     switch (addr) {
     case SCBPointer:
-        eepro100_write_pointer(s, val);
+        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         break;
     case SCBPort:
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
@@ -1896,7 +1896,6 @@ static const VMStateDescription vmstate_eepro100 = {
         /* The eeprom should be saved and restored by its own routines. */
         VMSTATE_UINT32(device, EEPRO100State),
         /* TODO check device. */
-        VMSTATE_UINT32(pointer, EEPRO100State),
         VMSTATE_UINT32(cu_base, EEPRO100State),
         VMSTATE_UINT32(cu_offset, EEPRO100State),
         VMSTATE_UINT32(ru_base, EEPRO100State),
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 08/10] eepro100: Support byte/word read/write access to MDI control register
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (6 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 07/10] eepro100: Support byte/word writes to pointer register Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 09/10] eepro100: Support byte read access to general " Stefan Weil
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

MDI control is a 32 bit register, but may be read or written using
8 or 16 bit access. Data is latched when the MSB is written.

Add support for byte/word read/write access.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 1949ee0..ff8c9ba 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1192,8 +1192,9 @@ static uint32_t eepro100_read_mdi(EEPRO100State * s)
     return val;
 }
 
-static void eepro100_write_mdi(EEPRO100State * s, uint32_t val)
+static void eepro100_write_mdi(EEPRO100State *s)
 {
+    uint32_t val = e100_read_reg4(s, SCBCtrlMDI);
     uint8_t raiseint = (val & BIT(29)) >> 29;
     uint8_t opcode = (val & BITS(27, 26)) >> 26;
     uint8_t phy = (val & BITS(25, 21)) >> 21;
@@ -1369,6 +1370,13 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
     case SCBeeprom:
         val = eepro100_read_eeprom(s);
         break;
+    case SCBCtrlMDI:
+    case SCBCtrlMDI + 1:
+    case SCBCtrlMDI + 2:
+    case SCBCtrlMDI + 3:
+        val = (uint8_t)(eepro100_read_mdi(s) >> (8 * (addr & 3)));
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        break;
     case SCBpmdr:       /* Power Management Driver Register */
         val = 0;
         TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
@@ -1401,6 +1409,11 @@ static uint16_t eepro100_read2(EEPRO100State * s, uint32_t addr)
         val = eepro100_read_eeprom(s);
         TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         break;
+    case SCBCtrlMDI:
+    case SCBCtrlMDI + 2:
+        val = (uint16_t)(eepro100_read_mdi(s) >> (8 * (addr & 3)));
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        break;
     default:
         logout("addr=%s val=0x%04x\n", regname(addr), val);
         missing("unknown word read");
@@ -1487,6 +1500,15 @@ static void eepro100_write1(EEPRO100State * s, uint32_t addr, uint8_t val)
         TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         eepro100_write_eeprom(s->eeprom, val);
         break;
+    case SCBCtrlMDI:
+    case SCBCtrlMDI + 1:
+    case SCBCtrlMDI + 2:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        break;
+    case SCBCtrlMDI + 3:
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        eepro100_write_mdi(s);
+        break;
     default:
         logout("addr=%s val=0x%02x\n", regname(addr), val);
         missing("unknown byte write");
@@ -1526,6 +1548,13 @@ static void eepro100_write2(EEPRO100State * s, uint32_t addr, uint16_t val)
         TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
         eepro100_write_eeprom(s->eeprom, val);
         break;
+    case SCBCtrlMDI:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        break;
+    case SCBCtrlMDI + 2:
+        TRACE(OTHER, logout("addr=%s val=0x%04x\n", regname(addr), val));
+        eepro100_write_mdi(s);
+        break;
     default:
         logout("addr=%s val=0x%04x\n", regname(addr), val);
         missing("unknown word write");
@@ -1547,7 +1576,8 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
         eepro100_write_port(s);
         break;
     case SCBCtrlMDI:
-        eepro100_write_mdi(s, val);
+        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
+        eepro100_write_mdi(s);
         break;
     default:
         logout("addr=%s val=0x%08x\n", regname(addr), val);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 09/10] eepro100: Support byte read access to general control register
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (7 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 08/10] eepro100: Support byte/word read/write access to MDI control register Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 10/10] eepro100: Support 32 bit read/write access to flash register Stefan Weil
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

The general control register is a byte register.
Add support for byte reads.

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index ff8c9ba..3aee707 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1381,6 +1381,9 @@ static uint8_t eepro100_read1(EEPRO100State * s, uint32_t addr)
         val = 0;
         TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
         break;
+    case SCBgctrl:      /* General Control Register */
+        TRACE(OTHER, logout("addr=%s val=0x%02x\n", regname(addr), val));
+        break;
     case SCBgstat:      /* General Status Register */
         /* 100 Mbps full duplex, valid link */
         val = 0x07;
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [Qemu-devel] [PATCH v2 10/10] eepro100: Support 32 bit read/write access to flash register
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (8 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 09/10] eepro100: Support byte read access to general " Stefan Weil
@ 2011-04-30 20:40 ` Stefan Weil
  2011-05-05 13:01 ` [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Michael S. Tsirkin
  2011-05-15 12:48 ` Michael S. Tsirkin
  11 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-04-30 20:40 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 hw/eepro100.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 3aee707..9eb43db 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1442,6 +1442,10 @@ static uint32_t eepro100_read4(EEPRO100State * s, uint32_t addr)
         val = eepro100_read_port(s);
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         break;
+    case SCBflash:
+        val = eepro100_read_eeprom(s);
+        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
+        break;
     case SCBCtrlMDI:
         val = eepro100_read_mdi(s);
         break;
@@ -1578,6 +1582,11 @@ static void eepro100_write4(EEPRO100State * s, uint32_t addr, uint32_t val)
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         eepro100_write_port(s);
         break;
+    case SCBflash:
+        TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
+        val = val >> 16;
+        eepro100_write_eeprom(s->eeprom, val);
+        break;
     case SCBCtrlMDI:
         TRACE(OTHER, logout("addr=%s val=0x%08x\n", regname(addr), val));
         eepro100_write_mdi(s);
-- 
1.7.2.5

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames Stefan Weil
@ 2011-05-05 13:00   ` Michael S. Tsirkin
  2011-05-05 16:19     ` Stefan Weil
  0 siblings, 1 reply; 15+ messages in thread
From: Michael S. Tsirkin @ 2011-05-05 13:00 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

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 <weil@mail.berlios.de>

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

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements)
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (9 preceding siblings ...)
  2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 10/10] eepro100: Support 32 bit read/write access to flash register Stefan Weil
@ 2011-05-05 13:01 ` Michael S. Tsirkin
  2011-05-15 12:48 ` Michael S. Tsirkin
  11 siblings, 0 replies; 15+ messages in thread
From: Michael S. Tsirkin @ 2011-05-05 13:01 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

On Sat, Apr 30, 2011 at 10:40:03PM +0200, Stefan Weil wrote:
> Hi,
> 
> this is the second version of a series of patches for eepro100 which mainly
> fix endianness issues and enhance register access. There was a bug report
> on qemu-devel recently which is fixed by these enhancements, see
> http://lists.nongnu.org/archive/html/qemu-devel/2011-03/msg02109.html.
> 
> Changes in v2:
> 
> * The 2nd patch is new.
> 
> * Patches are sorted in a different order. The first 4 patches and the
>   rest are independent, so it's possible to apply parts of the series.
> 
> * The endianness patch was updated to address the feedback which I received.
>   I still use local functions to access physical memory - mainly because
>   I want to use cpu_physical_memory_read / cpu_physical_memory_write as long
>   as I am not sure whether the alignment requirements for the suggested
>   open coded variant are met.
>   The prefix is e100 - shorter and more up-to-date than eepro100.
>   When I started this device emulation, linux still used a module called
>   eepro100. Today, the only linux module is called e100. So my final goal
>   is renaming all eepro100 to e100.
> 
> I did not change the patch which adds padding to short received frames,
> because I'd like to keep the preprocessor statement (CONFIG_PAD_RECEIVED_FRAMES)
> as some kind of documentation (even if QEMU's network code won't be modified
> in the near future to fully support a real ethernet emulation).
> 
> Kind regards,
> 
> Stefan W.
> 

Applied with a small tweak, thanks!

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames
  2011-05-05 13:00   ` Michael S. Tsirkin
@ 2011-05-05 16:19     ` Stefan Weil
  0 siblings, 0 replies; 15+ messages in thread
From: Stefan Weil @ 2011-05-05 16:19 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: QEMU Developers

Am 05.05.2011 15:00, schrieb Michael S. Tsirkin:
> 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<weil@mail.berlios.de>
> 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.

The new comment is ok, thanks.

Cheers,
Stefan W.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements)
  2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
                   ` (10 preceding siblings ...)
  2011-05-05 13:01 ` [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Michael S. Tsirkin
@ 2011-05-15 12:48 ` Michael S. Tsirkin
  11 siblings, 0 replies; 15+ messages in thread
From: Michael S. Tsirkin @ 2011-05-15 12:48 UTC (permalink / raw)
  To: Stefan Weil; +Cc: QEMU Developers

On Sat, Apr 30, 2011 at 10:40:03PM +0200, Stefan Weil wrote:
> Hi,
> 
> this is the second version of a series of patches for eepro100 which mainly
> fix endianness issues and enhance register access. There was a bug report
> on qemu-devel recently which is fixed by these enhancements, see
> http://lists.nongnu.org/archive/html/qemu-devel/2011-03/msg02109.html.
> 
> Changes in v2:
> 
> * The 2nd patch is new.
> 
> * Patches are sorted in a different order. The first 4 patches and the
>   rest are independent, so it's possible to apply parts of the series.
> 
> * The endianness patch was updated to address the feedback which I received.
>   I still use local functions to access physical memory - mainly because
>   I want to use cpu_physical_memory_read / cpu_physical_memory_write as long
>   as I am not sure whether the alignment requirements for the suggested
>   open coded variant are met.
>   The prefix is e100 - shorter and more up-to-date than eepro100.
>   When I started this device emulation, linux still used a module called
>   eepro100. Today, the only linux module is called e100. So my final goal
>   is renaming all eepro100 to e100.

We still have e1000 and it might be a bit confusing for the device
name/file name. So I'm not sure 100%. Pls do keep an alias at least.
But short function names are surely good.

> I did not change the patch which adds padding to short received frames,
> because I'd like to keep the preprocessor statement (CONFIG_PAD_RECEIVED_FRAMES)
> as some kind of documentation (even if QEMU's network code won't be modified
> in the near future to fully support a real ethernet emulation).
> 
> Kind regards,
> 
> Stefan W.
> 
> 
> 
> The following changes since commit 08ab2ccb08372a52ee1c597acf640cadb9089a3a:
> 
>   Merge branch 'patches' of git://qemu.weilnetz.de/git/qemu (2011-04-29 20:01:51 +0000)
> 
> are available in the git repository at:
> 
>   git://qemu.weilnetz.de/git/qemu.git patches
> 
> Stefan Weil (10):
>       eepro100: Avoid duplicate debug messages
>       eepro100: Remove type casts which are no longer needed
>       eepro100: Remove unused structure element
>       eepro100: Pad received short frames
>       eepro100: Fix endianness issues
>       eepro100: Support byte/word writes to port address
>       eepro100: Support byte/word writes to pointer register
>       eepro100: Support byte/word read/write access to MDI control register
>       eepro100: Support byte read access to general control register
>       eepro100: Support 32 bit read/write access to flash register
> 
>  hw/eepro100.c |  298 +++++++++++++++++++++++++++++++++++++++++----------------
>  1 files changed, 217 insertions(+), 81 deletions(-)

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2011-05-15 12:48 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-30 20:40 [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 01/10] eepro100: Avoid duplicate debug messages Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 02/10] eepro100: Remove type casts which are no longer needed Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 03/10] eepro100: Remove unused structure element Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 04/10] eepro100: Pad received short frames Stefan Weil
2011-05-05 13:00   ` Michael S. Tsirkin
2011-05-05 16:19     ` Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 05/10] eepro100: Fix endianness issues Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 06/10] eepro100: Support byte/word writes to port address Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 07/10] eepro100: Support byte/word writes to pointer register Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 08/10] eepro100: Support byte/word read/write access to MDI control register Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 09/10] eepro100: Support byte read access to general " Stefan Weil
2011-04-30 20:40 ` [Qemu-devel] [PATCH v2 10/10] eepro100: Support 32 bit read/write access to flash register Stefan Weil
2011-05-05 13:01 ` [Qemu-devel] [PULL v2] eepro100: Update of patch series (fixes and enhancements) Michael S. Tsirkin
2011-05-15 12:48 ` Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).