From 12127b469d7da4c1f44c94b27663d1aa79cabc67 Mon Sep 17 00:00:00 2001 From: Matt Borgerson Date: Wed, 18 Jun 2025 00:59:51 -0700 Subject: [PATCH] nvnet: Clean up mii read and write handling --- hw/xbox/mcpx/nvnet/nvnet.c | 80 +++++++++++++++++---------------- hw/xbox/mcpx/nvnet/nvnet_regs.h | 9 ++-- hw/xbox/mcpx/nvnet/trace-events | 4 +- 3 files changed, 47 insertions(+), 46 deletions(-) diff --git a/hw/xbox/mcpx/nvnet/nvnet.c b/hw/xbox/mcpx/nvnet/nvnet.c index 82777fe910..93ae9a6978 100644 --- a/hw/xbox/mcpx/nvnet/nvnet.c +++ b/hw/xbox/mcpx/nvnet/nvnet.c @@ -34,6 +34,8 @@ #define IOPORT_SIZE 0x8 #define MMIO_SIZE 0x400 +#define GET_MASK(v, mask) (((v) & (mask)) >> ctz32(mask)) + static const uint8_t bcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; // #define DEBUG @@ -115,8 +117,6 @@ static uint64_t nvnet_io_read(void *opaque, hwaddr addr, unsigned int size); static void nvnet_io_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size); -static int nvnet_mii_rw(NvNetState *s, - uint64_t val); /* Link State */ static void nvnet_link_down(NvNetState *s); @@ -233,51 +233,57 @@ static void nvnet_set_reg(NvNetState *s, /* * Read from PHY. */ -static int nvnet_mii_rw(NvNetState *s, uint64_t val) +static void nvnet_mii_read(NvNetState *s) { - uint32_t mii_ctl; - int write, retval, phy_addr, reg; - - retval = 0; - mii_ctl = nvnet_get_reg(s, NvRegMIIControl, 4); - phy_addr = (mii_ctl >> NVREG_MIICTL_ADDRSHIFT) & 0x1f; - reg = mii_ctl & ((1 << NVREG_MIICTL_ADDRSHIFT) - 1); - write = mii_ctl & NVREG_MIICTL_WRITE; + uint32_t mii_ctl = nvnet_get_reg(s, NvRegMIIControl, 4); + uint32_t mii_data = -1; + uint32_t phy_addr = GET_MASK(mii_ctl, NVREG_MIICTL_PHYADDR); + uint32_t phy_reg = GET_MASK(mii_ctl, NVREG_MIICTL_PHYREG); if (phy_addr != 1) { - retval = -1; goto out; } - if (write) { - goto out; - } - - switch (reg) { + switch (phy_reg) { case MII_BMSR: - retval = MII_BMSR_AN_COMP | MII_BMSR_LINK_ST; + mii_data = MII_BMSR_AN_COMP | MII_BMSR_LINK_ST; break; case MII_ANAR: /* Fall through... */ case MII_ANLPAR: - retval = MII_ANLPAR_10 | MII_ANLPAR_10FD | MII_ANLPAR_TX | - MII_ANLPAR_TXFD | MII_ANLPAR_T4; + mii_data = MII_ANLPAR_10 | MII_ANLPAR_10FD | MII_ANLPAR_TX | + MII_ANLPAR_TXFD | MII_ANLPAR_T4; break; default: + mii_data = 0; break; } out: - if (write) { - trace_nvnet_mii_write(phy_addr, reg, nvnet_get_mii_reg_name(reg), val); - } else { - trace_nvnet_mii_read(phy_addr, reg, nvnet_get_mii_reg_name(reg), - retval); - } - return retval; + mii_ctl &= ~NVREG_MIICTL_INUSE; + nvnet_set_reg(s, NvRegMIIControl, mii_ctl, 4); + nvnet_set_reg(s, NvRegMIIData, mii_data, 4); + trace_nvnet_mii_read(phy_addr, phy_reg, nvnet_get_mii_reg_name(phy_reg), + mii_data); +} + +/* + * Write to PHY. + */ +static void nvnet_mii_write(NvNetState *s) +{ + uint32_t mii_ctl = nvnet_get_reg(s, NvRegMIIControl, 4); + uint32_t mii_data = nvnet_get_reg(s, NvRegMIIData, 4); + uint32_t phy_addr = GET_MASK(mii_ctl, NVREG_MIICTL_PHYADDR); + uint32_t phy_reg = GET_MASK(mii_ctl, NVREG_MIICTL_PHYREG); + + mii_ctl &= ~NVREG_MIICTL_INUSE; + nvnet_set_reg(s, NvRegMIIControl, mii_ctl, 4); + trace_nvnet_mii_write(phy_addr, phy_reg, nvnet_get_mii_reg_name(phy_reg), + mii_data); } /******************************************************************************* @@ -293,16 +299,6 @@ static uint64_t nvnet_mmio_read(void *opaque, hwaddr addr, unsigned int size) uint64_t retval; switch (addr) { - case NvRegMIIData: - assert(size == 4); - retval = nvnet_mii_rw(s, MII_READ); - break; - - case NvRegMIIControl: - retval = nvnet_get_reg(s, addr, size); - retval &= ~NVREG_MIICTL_INUSE; - break; - case NvRegMIIStatus: retval = 0; break; @@ -334,8 +330,14 @@ static void nvnet_mmio_write(void *opaque, hwaddr addr, s->tx_ring_size = ((val >> NVREG_RINGSZ_TXSHIFT) & 0xffff) + 1; break; - case NvRegMIIData: - nvnet_mii_rw(s, val); + case NvRegMIIControl: + assert(size == 4); + nvnet_set_reg(s, addr, val, size); + if (val & NVREG_MIICTL_WRITE) { + nvnet_mii_write(s); + } else { + nvnet_mii_read(s); + } break; case NvRegTxRxControl: diff --git a/hw/xbox/mcpx/nvnet/nvnet_regs.h b/hw/xbox/mcpx/nvnet/nvnet_regs.h index 6a82bbc3da..b311b87278 100644 --- a/hw/xbox/mcpx/nvnet/nvnet_regs.h +++ b/hw/xbox/mcpx/nvnet/nvnet_regs.h @@ -176,9 +176,10 @@ enum { # define NVREG_MIISPEED_BIT8 (1 << 8) # define NVREG_MIIDELAY 5 NvRegMIIControl = 0x190, -# define NVREG_MIICTL_INUSE 0x8000 -# define NVREG_MIICTL_WRITE 0x0400 -# define NVREG_MIICTL_ADDRSHIFT 5 +# define NVREG_MIICTL_INUSE 0x8000 +# define NVREG_MIICTL_WRITE 0x0400 +# define NVREG_MIICTL_PHYADDR 0x03e0 +# define NVREG_MIICTL_PHYREG 0x001f NvRegMIIData = 0x194, NvRegWakeUpFlags = 0x200, # define NVREG_WAKEUPFLAGS_VAL 0x7770 @@ -270,8 +271,6 @@ enum { #define OOM_REFILL (1 + HZ / 20) #define POLL_WAIT (1 + HZ / 100) -#define MII_READ (-1) - /* Link partner ability register. */ #define LPA_SLCT 0x001f /* Same as advertise selector */ #define LPA_RESV 0x1c00 /* Unused... */ diff --git a/hw/xbox/mcpx/nvnet/trace-events b/hw/xbox/mcpx/nvnet/trace-events index fbda278fe7..4115e4e7eb 100644 --- a/hw/xbox/mcpx/nvnet/trace-events +++ b/hw/xbox/mcpx/nvnet/trace-events @@ -1,8 +1,8 @@ # See docs/devel/tracing.rst for syntax documentation. # nvnet.c -nvnet_mii_read(unsigned int phy_addr, uint32_t addr, const char *name, uint64_t val) "phy %d addr 0x%"PRIx32" %s val 0x%"PRIx64 -nvnet_mii_write(unsigned int phy_addr, uint32_t addr, const char *name, uint64_t val) "phy %d addr 0x%"PRIx32" %s val 0x%"PRIx64 +nvnet_mii_read(unsigned int phy_addr, uint32_t addr, const char *name, uint32_t val) "phy %d addr 0x%"PRIx32" %s val 0x%"PRIx32 +nvnet_mii_write(unsigned int phy_addr, uint32_t addr, const char *name, uint32_t val) "phy %d addr 0x%"PRIx32" %s val 0x%"PRIx32 nvnet_reg_read(uint32_t addr, const char *name, unsigned int size, uint64_t val) "addr 0x%"PRIx32" %s size %d val 0x%"PRIx64 nvnet_reg_write(uint32_t addr, const char *name, unsigned int size, uint64_t val) "addr 0x%"PRIx32" %s size %d val 0x%"PRIx64 nvnet_io_read(uint32_t addr, unsigned int size, uint64_t val) "addr 0x%"PRIx32" size %d val 0x%"PRIx64