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.mayd...@linaro.org> Cc: Paul Brook <p...@codesourcery.com> Cc: Edgar E. Iglesias <edgar.igles...@gmail.com> Cc: Anthony Liguori <aligu...@us.ibm.com> Cc: Andreas Färber <afaer...@suse.de> Signed-off-by: Grant Likely <grant.lik...@secretlab.ca> --- 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