summary refs log tree commit diff stats
path: root/hw/net/imx_fec.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2024-12-12 18:40:08 -0500
committerStefan Hajnoczi <stefanha@redhat.com>2024-12-12 18:40:08 -0500
commit2a1823456c3ab500a90c3fe0cfcc5fc6f560282b (patch)
treecc58ee284de8459593ffa044af87f6592abc9480 /hw/net/imx_fec.c
parented2db97e60fdc32441f22526a26bd66a6557674d (diff)
parent1abe28d519239eea5cf9620bb13149423e5665f8 (diff)
downloadfocaccia-qemu-2a1823456c3ab500a90c3fe0cfcc5fc6f560282b.tar.gz
focaccia-qemu-2a1823456c3ab500a90c3fe0cfcc5fc6f560282b.zip
Merge tag 'pull-target-arm-20241211' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue:
 * hw/net/lan9118: Extract PHY model, reuse with imx_fec, fix bugs
 * fpu: Make muladd NaN handling runtime-selected, not compile-time
 * fpu: Make default NaN pattern runtime-selected, not compile-time
 * fpu: Minor NaN-related cleanups
 * MAINTAINERS: email address updates

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmdZu14ZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3mgiD/98Q+m7/t54FdCd2bx1cr2k
# dw+7DYhp+60Vo3OjlGtKWwPD67oN8e0jhOoArmJNW0Fmkcsvfvd4wv6kCf8zftLm
# 0/lPO687mvFNCAprTch+z2pGB7aS0HdIr126ytsyg5PlHtldd+OBA+yUUYafR3zo
# BECRSWZmMFxfl9uckJzntdntghTX5pnJDSGBYE9NEyRfo0Ntj1HvhaHSQJkqpf5B
# QwE8R965CXc4i34PqlOCju47AXwJc3x36ftdiNmpPvMS4odG9yb/OmhHSgVZlThb
# 1x0HEX69KF5FQbtVNDMmFyYehDzqYFpqOSa1IKtaNLmDSZJ5P8fWw4eBdMdr/QyD
# QKssgHAO6Z13MLppK4B1PFtSVlsLYUURYddYUFz4RUNOxrS/pzAIT0KhClYFytQo
# x9xid4fng1PY9doYEM3v4vEQCU6S+2aj2gU4EOwdB8GmMhtjSl8YlcEs7cysqkoQ
# gbGX97i6Eh616q9VsRzUwcY6u4XP/lssn6I98k4AEqgRpyFCMTLyFodV89d6J4EJ
# IJKsJf10gctpe1JdMgtDxuleKOZc+O5nOMJLKYwc9siakCBZsH7zmgS6m8QVoUSD
# 7R+4OtbaQwM0+GPbc0AhAlDtq3Q1QAtCYa94iICUixC4NjzfdC9B9yCz1XnA7sfS
# jPHU8INw6rz3psEnlFQdhA==
# =+ELh
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 11 Dec 2024 11:18:38 EST
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20241211' of https://git.linaro.org/people/pmaydell/qemu-arm: (72 commits)
  MAINTAINERS: Add correct email address for Vikram Garhwal
  MAINTAINERS: update email address for Leif Lindholm
  softfloat: Replace WHICH with RET in parts_pick_nan
  softfloat: Sink frac_cmp in parts_pick_nan until needed
  softfloat: Share code between parts_pick_nan cases
  softfloat: Inline pickNaN
  softfloat: Use parts_pick_nan in propagateFloatx80NaN
  softfloat: Move propagateFloatx80NaN to softfloat.c
  softfloat: Pad array size in pick_nan_muladd
  softfloat: Remove which from parts_pick_nan_muladd
  softfloat: Use goto for default nan case in pick_nan_muladd
  softfloat: Inline pickNaNMulAdd
  fpu: Remove default handling for dnan_pattern
  target/tricore: Set default NaN pattern explicitly
  target/riscv: Set default NaN pattern explicitly
  target/hexagon: Set default NaN pattern explicitly
  target/xtensa: Set default NaN pattern explicitly
  target/sparc: Set default NaN pattern explicitly
  target/s390x: Set default NaN pattern explicitly
  target/rx: Set default NaN pattern explicitly
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/net/imx_fec.c')
-rw-r--r--hw/net/imx_fec.c146
1 files changed, 15 insertions, 131 deletions
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 6294d29202..4ee6f74206 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -203,17 +203,12 @@ static const VMStateDescription vmstate_imx_eth_txdescs = {
 
 static const VMStateDescription vmstate_imx_eth = {
     .name = TYPE_IMX_FEC,
-    .version_id = 2,
-    .minimum_version_id = 2,
+    .version_id = 3,
+    .minimum_version_id = 3,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
         VMSTATE_UINT32(rx_descriptor, IMXFECState),
         VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
-        VMSTATE_UINT32(phy_status, IMXFECState),
-        VMSTATE_UINT32(phy_control, IMXFECState),
-        VMSTATE_UINT32(phy_advertise, IMXFECState),
-        VMSTATE_UINT32(phy_int, IMXFECState),
-        VMSTATE_UINT32(phy_int_mask, IMXFECState),
         VMSTATE_END_OF_LIST()
     },
     .subsections = (const VMStateDescription * const []) {
@@ -222,14 +217,6 @@ static const VMStateDescription vmstate_imx_eth = {
     },
 };
 
-#define PHY_INT_ENERGYON            (1 << 7)
-#define PHY_INT_AUTONEG_COMPLETE    (1 << 6)
-#define PHY_INT_FAULT               (1 << 5)
-#define PHY_INT_DOWN                (1 << 4)
-#define PHY_INT_AUTONEG_LP          (1 << 3)
-#define PHY_INT_PARFAULT            (1 << 2)
-#define PHY_INT_AUTONEG_PAGE        (1 << 1)
-
 static void imx_eth_update(IMXFECState *s);
 
 /*
@@ -238,47 +225,19 @@ static void imx_eth_update(IMXFECState *s);
  * For now we don't handle any GPIO/interrupt line, so the OS will
  * have to poll for the PHY status.
  */
-static void imx_phy_update_irq(IMXFECState *s)
-{
-    imx_eth_update(s);
-}
-
-static void imx_phy_update_link(IMXFECState *s)
+static void imx_phy_update_irq(void *opaque, int n, int level)
 {
-    /* Autonegotiation status mirrors link status.  */
-    if (qemu_get_queue(s->nic)->link_down) {
-        trace_imx_phy_update_link("down");
-        s->phy_status &= ~0x0024;
-        s->phy_int |= PHY_INT_DOWN;
-    } else {
-        trace_imx_phy_update_link("up");
-        s->phy_status |= 0x0024;
-        s->phy_int |= PHY_INT_ENERGYON;
-        s->phy_int |= PHY_INT_AUTONEG_COMPLETE;
-    }
-    imx_phy_update_irq(s);
+    imx_eth_update(opaque);
 }
 
 static void imx_eth_set_link(NetClientState *nc)
 {
-    imx_phy_update_link(IMX_FEC(qemu_get_nic_opaque(nc)));
-}
-
-static void imx_phy_reset(IMXFECState *s)
-{
-    trace_imx_phy_reset();
-
-    s->phy_status = 0x7809;
-    s->phy_control = 0x3000;
-    s->phy_advertise = 0x01e1;
-    s->phy_int_mask = 0;
-    s->phy_int = 0;
-    imx_phy_update_link(s);
+    lan9118_phy_update_link(&IMX_FEC(qemu_get_nic_opaque(nc))->mii,
+                            nc->link_down);
 }
 
 static uint32_t imx_phy_read(IMXFECState *s, int reg)
 {
-    uint32_t val;
     uint32_t phy = reg / 32;
 
     if (!s->phy_connected) {
@@ -296,54 +255,7 @@ static uint32_t imx_phy_read(IMXFECState *s, int reg)
 
     reg %= 32;
 
-    switch (reg) {
-    case 0:     /* Basic Control */
-        val = s->phy_control;
-        break;
-    case 1:     /* Basic Status */
-        val = s->phy_status;
-        break;
-    case 2:     /* ID1 */
-        val = 0x0007;
-        break;
-    case 3:     /* ID2 */
-        val = 0xc0d1;
-        break;
-    case 4:     /* Auto-neg advertisement */
-        val = s->phy_advertise;
-        break;
-    case 5:     /* Auto-neg Link Partner Ability */
-        val = 0x0f71;
-        break;
-    case 6:     /* Auto-neg Expansion */
-        val = 1;
-        break;
-    case 29:    /* Interrupt source.  */
-        val = s->phy_int;
-        s->phy_int = 0;
-        imx_phy_update_irq(s);
-        break;
-    case 30:    /* Interrupt mask */
-        val = s->phy_int_mask;
-        break;
-    case 17:
-    case 18:
-    case 27:
-    case 31:
-        qemu_log_mask(LOG_UNIMP, "[%s.phy]%s: reg %d not implemented\n",
-                      TYPE_IMX_FEC, __func__, reg);
-        val = 0;
-        break;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
-                      TYPE_IMX_FEC, __func__, reg);
-        val = 0;
-        break;
-    }
-
-    trace_imx_phy_read(val, phy, reg);
-
-    return val;
+    return lan9118_phy_read(&s->mii, reg);
 }
 
 static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
@@ -365,39 +277,7 @@ static void imx_phy_write(IMXFECState *s, int reg, uint32_t val)
 
     reg %= 32;
 
-    trace_imx_phy_write(val, phy, reg);
-
-    switch (reg) {
-    case 0:     /* Basic Control */
-        if (val & 0x8000) {
-            imx_phy_reset(s);
-        } else {
-            s->phy_control = val & 0x7980;
-            /* Complete autonegotiation immediately.  */
-            if (val & 0x1000) {
-                s->phy_status |= 0x0020;
-            }
-        }
-        break;
-    case 4:     /* Auto-neg advertisement */
-        s->phy_advertise = (val & 0x2d7f) | 0x80;
-        break;
-    case 30:    /* Interrupt mask */
-        s->phy_int_mask = val & 0xff;
-        imx_phy_update_irq(s);
-        break;
-    case 17:
-    case 18:
-    case 27:
-    case 31:
-        qemu_log_mask(LOG_UNIMP, "[%s.phy)%s: reg %d not implemented\n",
-                      TYPE_IMX_FEC, __func__, reg);
-        break;
-    default:
-        qemu_log_mask(LOG_GUEST_ERROR, "[%s.phy]%s: Bad address at offset %d\n",
-                      TYPE_IMX_FEC, __func__, reg);
-        break;
-    }
+    lan9118_phy_write(&s->mii, reg, val);
 }
 
 static void imx_fec_read_bd(IMXFECBufDesc *bd, dma_addr_t addr)
@@ -682,9 +562,6 @@ static void imx_eth_reset(DeviceState *d)
 
     s->rx_descriptor = 0;
     memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
-
-    /* We also reset the PHY */
-    imx_phy_reset(s);
 }
 
 static uint32_t imx_default_read(IMXFECState *s, uint32_t index)
@@ -1329,6 +1206,13 @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
     sysbus_init_irq(sbd, &s->irq[0]);
     sysbus_init_irq(sbd, &s->irq[1]);
 
+    qemu_init_irq(&s->mii_irq, imx_phy_update_irq, s, 0);
+    object_initialize_child(OBJECT(s), "mii", &s->mii, TYPE_LAN9118_PHY);
+    if (!sysbus_realize_and_unref(SYS_BUS_DEVICE(&s->mii), errp)) {
+        return;
+    }
+    qdev_connect_gpio_out(DEVICE(&s->mii), 0, &s->mii_irq);
+
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
     s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,