[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V2 4/6] hw/mdio: Add VMState support
From: |
Grant Likely |
Subject: |
[Qemu-devel] [PATCH V2 4/6] hw/mdio: Add VMState support |
Date: |
Wed, 23 Jan 2013 16:15:28 +0000 |
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 <address@hidden>
Cc: Paul Brook <address@hidden>
Cc: Edgar E. Iglesias <address@hidden>
Cc: Anthony Liguori <address@hidden>
Cc: Andreas Färber <address@hidden>
Signed-off-by: Grant Likely <address@hidden>
---
hw/mdio.c | 49 ++++++++++++++++++++++++++++++++++++++++---------
hw/mdio.h | 50 ++++++++++++++++++++++++++++++++++----------------
2 files changed, 74 insertions(+), 25 deletions(-)
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);
--
1.7.10.4