No need for drivers to open code the check for clock state change. This patch moves it into the common code.
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/etraxfs_eth.c | 7 ++----- hw/mdio.c | 20 ++++++++++++-------- hw/mdio.h | 2 +- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c index f26e338..1bcdd12 100644 --- a/hw/etraxfs_eth.c +++ b/hw/etraxfs_eth.c @@ -173,11 +173,8 @@ eth_write(void *opaque, hwaddr addr, if (value & 2) { eth->mdio_bus.mdio = value & 1; } - if (eth->mdio_bus.mdc != (value & 4)) { - mdio_cycle(ð->mdio_bus); - eth_validate_duplex(eth); - } - eth->mdio_bus.mdc = !!(value & 4); + mdio_cycle(ð->mdio_bus, value & 4); + eth_validate_duplex(eth); eth->regs[addr] = value; break; diff --git a/hw/mdio.c b/hw/mdio.c index ca55e21..5272656 100644 --- a/hw/mdio.c +++ b/hw/mdio.c @@ -173,15 +173,19 @@ void mdio_write_req(struct qemu_mdio *bus, uint8_t addr, uint8_t req, } } -void mdio_cycle(struct qemu_mdio *bus) +void mdio_cycle(struct qemu_mdio *bus, bool mdc) { + if (mdc == bus->mdc) { + return; /* Clock state hasn't changed; do nothing */ + } + bus->mdc = mdc; bus->cnt++; D(printf("mdc=%d mdio=%d state=%d cnt=%d drv=%d\n", bus->mdc, bus->mdio, bus->state, bus->cnt, bus->output_enable)); switch (bus->state) { case PREAMBLE: - if (bus->mdc) { + if (!mdc) { if (bus->cnt >= (32 * 2) && !bus->mdio) { bus->cnt = 0; bus->state = SOF; @@ -190,7 +194,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case SOF: - if (bus->mdc) { + if (!mdc) { if (bus->mdio != 1) { printf("WARNING: no SOF\n"); } @@ -202,7 +206,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case OPC: - if (bus->mdc) { + if (!mdc) { bus->opc <<= 1; bus->opc |= bus->mdio & 1; if (bus->cnt == 2*2) { @@ -213,7 +217,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case ADDR: - if (bus->mdc) { + if (!mdc) { bus->addr <<= 1; bus->addr |= bus->mdio & 1; @@ -225,7 +229,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case REQ: - if (bus->mdc) { + if (!mdc) { bus->req <<= 1; bus->req |= bus->mdio & 1; if (bus->cnt == 5*2) { @@ -235,7 +239,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case TURNAROUND: - if (bus->mdc && bus->cnt == 2*2) { + if (!mdc && bus->cnt == 2*2) { bus->mdio = 0; bus->cnt = 0; @@ -248,7 +252,7 @@ void mdio_cycle(struct qemu_mdio *bus) } break; case DATA: - if (!bus->mdc) { + if (mdc) { if (bus->output_enable) { bus->mdio = !!(bus->data & (1 << 15)); bus->data <<= 1; diff --git a/hw/mdio.h b/hw/mdio.h index 1cbb422..bd1d0a0 100644 --- a/hw/mdio.h +++ b/hw/mdio.h @@ -85,6 +85,6 @@ void mdio_attach(struct qemu_mdio *bus, struct qemu_phy *phy, unsigned int addr); uint16_t mdio_read_req(struct qemu_mdio *bus, uint8_t addr, uint8_t req); void mdio_write_req(struct qemu_mdio *bus, uint8_t addr, uint8_t req, uint16_t data); -void mdio_cycle(struct qemu_mdio *bus); +void mdio_cycle(struct qemu_mdio *bus, bool mdc); #endif -- 1.7.10.4