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


Reply via email to