nvnet: Clean up mii read and write handling

This commit is contained in:
Matt Borgerson 2025-06-18 00:59:51 -07:00 committed by mborgerson
parent bc4dbcf4bb
commit 12127b469d
3 changed files with 47 additions and 46 deletions

View File

@ -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:

View File

@ -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... */

View File

@ -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