Patchwork [V2,4/6] hw/mdio: Add VMState support

login
register
mail settings
Submitter Grant Likely
Date Jan. 23, 2013, 4:15 p.m.
Message ID <1358957730-17897-5-git-send-email-grant.likely@secretlab.ca>
Download mbox | patch
Permalink /patch/215056/
State New
Headers show

Comments

Grant Likely - Jan. 23, 2013, 4:15 p.m.
The MDIO model needs to have VMState support before it can be used by
devices that support VMState. This patch adds VMState macros for both
qemu_mdio and qemu_phy.

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Paul Brook <paul@codesourcery.com>
Cc: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Cc: Anthony Liguori <aliguori@us.ibm.com>
Cc: Andreas Färber <afaerber@suse.de>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
 hw/mdio.c |   49 ++++++++++++++++++++++++++++++++++++++++---------
 hw/mdio.h |   50 ++++++++++++++++++++++++++++++++++----------------
 2 files changed, 74 insertions(+), 25 deletions(-)

Patch

diff --git a/hw/mdio.c b/hw/mdio.c
index b138efa..ca55e21 100644
--- a/hw/mdio.c
+++ b/hw/mdio.c
@@ -44,7 +44,7 @@ 
  * linux driver (PHYID and Diagnostics reg).
  * TODO: Add friendly names for the register nums.
  */
-static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
+static uint16_t tdk_read(struct qemu_phy *phy, unsigned int req)
 {
     int regnum;
     unsigned r = 0;
@@ -108,7 +108,7 @@  static unsigned int tdk_read(struct qemu_phy *phy, unsigned int req)
     return r;
 }
 
-static void tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data)
+static void tdk_write(struct qemu_phy *phy, unsigned int req, uint16_t data)
 {
     int regnum;
 
@@ -133,7 +133,7 @@  void tdk_init(struct qemu_phy *phy)
     phy->regs[3] = 0xe400;
     /* Autonegotiation advertisement reg. */
     phy->regs[4] = 0x01e1;
-    phy->link = 1;
+    phy->link = true;
 
     phy->read = tdk_read;
     phy->write = tdk_write;
@@ -178,7 +178,7 @@  void mdio_cycle(struct qemu_mdio *bus)
     bus->cnt++;
 
     D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n",
-             bus->mdc, bus->mdio, bus->state, bus->cnt, bus->drive));
+             bus->mdc, bus->mdio, bus->state, bus->cnt, bus->output_enable));
     switch (bus->state) {
     case PREAMBLE:
         if (bus->mdc) {
@@ -240,7 +240,7 @@  void mdio_cycle(struct qemu_mdio *bus)
             bus->cnt = 0;
 
             if (bus->opc == 2) {
-                bus->drive = 1;
+                bus->output_enable = true;
                 bus->data = mdio_read_req(bus, bus->addr, bus->req);
                 bus->mdio = bus->data & 1;
             }
@@ -249,22 +249,22 @@  void mdio_cycle(struct qemu_mdio *bus)
         break;
     case DATA:
         if (!bus->mdc) {
-            if (bus->drive) {
+            if (bus->output_enable) {
                 bus->mdio = !!(bus->data & (1 << 15));
                 bus->data <<= 1;
             }
         } else {
-            if (!bus->drive) {
+            if (!bus->output_enable) {
                 bus->data <<= 1;
                 bus->data |= bus->mdio;
             }
             if (bus->cnt == 16 * 2) {
                 bus->cnt = 0;
                 bus->state = PREAMBLE;
-                if (!bus->drive) {
+                if (!bus->output_enable) {
                     mdio_write_req(bus, bus->addr, bus->req, bus->data);
                 }
-                bus->drive = 0;
+                bus->output_enable = false;
             }
         }
         break;
@@ -272,3 +272,34 @@  void mdio_cycle(struct qemu_mdio *bus)
         break;
     }
 }
+
+const VMStateDescription vmstate_mdio = {
+    .name = "mdio",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_BOOL(mdc, struct qemu_mdio),
+        VMSTATE_BOOL(mdio, struct qemu_mdio),
+        VMSTATE_BOOL(output_enable, struct qemu_mdio),
+        VMSTATE_UINT32(state, struct qemu_mdio),
+        VMSTATE_UINT8(cnt, struct qemu_mdio),
+        VMSTATE_UINT8(addr, struct qemu_mdio),
+        VMSTATE_UINT8(opc, struct qemu_mdio),
+        VMSTATE_UINT8(req, struct qemu_mdio),
+        VMSTATE_UINT32(data, struct qemu_mdio),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+const VMStateDescription vmstate_mdio_phy = {
+    .name = "mdio",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT16_ARRAY(regs, struct qemu_phy, 32),
+        VMSTATE_BOOL(link, struct qemu_phy),
+        VMSTATE_END_OF_LIST()
+    }
+};
diff --git a/hw/mdio.h b/hw/mdio.h
index c0c2533..1cbb422 100644
--- a/hw/mdio.h
+++ b/hw/mdio.h
@@ -26,22 +26,31 @@ 
  */
 
 #include <stdint.h>
+#include "migration/vmstate.h"
 
 struct qemu_phy {
-    uint32_t regs[32];
+    uint16_t regs[32];
+    bool link;
 
-    int link;
-
-    unsigned int (*read)(struct qemu_phy *phy, unsigned int req);
-    void (*write)(struct qemu_phy *phy, unsigned int req, unsigned int data);
+    uint16_t (*read)(struct qemu_phy *phy, unsigned int req);
+    void (*write)(struct qemu_phy *phy, unsigned int req, uint16_t data);
 };
 
-struct qemu_mdio {
-    /* bus. */
-    int mdc;
-    int mdio;
+extern const VMStateDescription vmstate_mdio_phy;
+
+#define VMSTATE_MDIO_PHY(_field, _state) {                           \
+    .name   = (stringify(_field)),                                   \
+    .size   = sizeof(struct qemu_phy),                               \
+    .vmsd   = &vmstate_mdio_phy,                                     \
+    .flags  = VMS_STRUCT,                                            \
+    .offset = vmstate_offset_value(_state, _field, struct qemu_phy), \
+}
 
-    /* decoder.  */
+struct qemu_mdio {
+    /* bitbanging state machine */
+    bool mdc;
+    bool mdio;
+    bool output_enable;
     enum {
         PREAMBLE,
         SOF,
@@ -51,17 +60,26 @@  struct qemu_mdio {
         TURNAROUND,
         DATA
     } state;
-    unsigned int drive;
 
-    unsigned int cnt;
-    unsigned int addr;
-    unsigned int opc;
-    unsigned int req;
-    unsigned int data;
+    uint8_t cnt; /* Bit count for current state */
+    uint8_t addr; /* PHY Address; retrieved during ADDR state */
+    uint8_t opc; /* Operation; 2:read */
+    uint8_t req; /* Register address */
+    uint32_t data; /* Data to write, or data read from PHY */
 
     struct qemu_phy *devs[32];
 };
 
+extern const VMStateDescription vmstate_mdio;
+
+#define VMSTATE_MDIO(_field, _state) {                                 \
+    .name   = (stringify(_field)),                                     \
+    .size   = sizeof(struct qemu_mdio),                                \
+    .vmsd   = &vmstate_mdio,                                           \
+    .flags  = VMS_STRUCT,                                              \
+    .offset = vmstate_offset_value(_state, _field, struct qemu_mdio),  \
+}
+
 void tdk_init(struct qemu_phy *phy);
 void mdio_attach(struct qemu_mdio *bus, struct qemu_phy *phy,
                  unsigned int addr);