Add initial implementation of PHY via bit-banged code. This is to test the mdio_bb code and will need updating for real board values. --- hw/net/Kconfig | 1 + hw/net/lowrisc.c | 42 +++++++++++++++++++++++++++++++----- include/hw/net/lowrisc_eth.h | 4 ++++ 3 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/hw/net/Kconfig b/hw/net/Kconfig index 3abee9130e..0bc11e567a 100644 --- a/hw/net/Kconfig +++ b/hw/net/Kconfig @@ -114,6 +114,7 @@ config MDIO_BB config LOWRISC_ETH bool + select MDIO_BB config SUNHME bool diff --git a/hw/net/lowrisc.c b/hw/net/lowrisc.c index 98177793e6..d5cae83eb0 100644 --- a/hw/net/lowrisc.c +++ b/hw/net/lowrisc.c @@ -194,6 +194,32 @@ static bool lowrisc_eth_can_receive(NetClientState *nc) return ok; } +static unsigned lowrisc_eth_phy_read(void *opaque, unsigned reg) +{ + unsigned phy = reg >> 5; + + reg &= 0x1f; + if (phy == 1) { + switch (reg) { + case 0x00: + return 0xcafe; + case 0x01: + return 0xf00d; + + default: + return 0xffff; + } + } else { + return reg; + } + + return 0xffff; +} + +static void lowrisc_eth_phy_write(void *opaque, unsigned reg, unsigned val) +{ +} + #define make_mac(__m, __b) (((uint32_t)(__m)) << (__b)) static void lowrisc_eth_init_registers(LowriscEthState *s) @@ -209,6 +235,13 @@ static void lowrisc_eth_init_registers(LowriscEthState *s) s->r_mdioctrl = FIELD_DP32(0x0, MDIOCTRL, M_DI, 1); memset(&s->r_rplr, 0, sizeof(s->r_rplr)); + /* setup the mdio bus */ + mdio_bb_init(&s->mdio_bb); + s->mdio_bb.name = "lowrisc_eth"; + s->mdio_bb.param = s; + s->mdio_bb.read = lowrisc_eth_phy_read; + s->mdio_bb.write = lowrisc_eth_phy_write; + /* init mac registers */ mac = &s->conf.macaddr.a[0]; @@ -259,12 +292,11 @@ static uint64_t lowrisc_eth_read(void *opaque, hwaddr offset, unsigned size) static void lowrisc_eth_update_mdioctrl(LowriscEthState *s, uint32_t val) { - /* since we're not implementing any sort of bit-banged MDIO, we just - * return the data input as high, which seems to be enough to allow - * the PHY link checks to work - */ + bool mdc = FIELD_EX32(val, MDIOCTRL, M_CLK); + bool mdo = FIELD_EX32(val, MDIOCTRL, M_DO); - s->r_mdioctrl = FIELD_DP32(s->r_mdioctrl, MDIOCTRL, M_DI, 1); + mdio_bb_update(&s->mdio_bb, mdc, mdo); + s->r_mdioctrl = FIELD_DP32(val, MDIOCTRL, M_DI, s->mdio_bb.mdi); } /* update tplr register, assume we're transmitting a packet */ diff --git a/include/hw/net/lowrisc_eth.h b/include/hw/net/lowrisc_eth.h index 1f27d92ca8..5c15549cc1 100644 --- a/include/hw/net/lowrisc_eth.h +++ b/include/hw/net/lowrisc_eth.h @@ -17,6 +17,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(LowriscEthState, LOWRISC_ETH) #include "net/net.h" #include "hw/sysbus.h" +#include "hw/net/mdio_bb.h" #define RX_SZ (2048) #define NR_RX_BUFFS (8) @@ -37,6 +38,9 @@ struct LowriscEthState { NICConf conf; qemu_irq irq; + /* the mdio bus */ + struct mdio_bb mdio_bb; + /* register states */ uint32_t r_maclo; uint32_t r_machi; -- 2.37.2.352.g3c44437643