mirror of https://github.com/xemu-project/xemu.git
nvnet: Clean up mii read and write handling
This commit is contained in:
parent
bc4dbcf4bb
commit
12127b469d
|
@ -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:
|
||||
|
|
|
@ -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... */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue