Hi,
The diff below sets SMSC_MII_BUSY bit, which is necessary for PHY to
acknowledge a read/write request; from FreeBSD r333096.
While here, mask off the PHY address and register.
Tested on rpi3.
# dmesg |grep smsc
smsc0 at uhub1 port 1 configuration 1 interface 0 "Standard Microsystems
SMSC9512/14" rev 2.00/2.00 addr 3
smsc0: address b8:27:eb:b0:32:5d
ukphy0 at smsc0 phy 1: Generic IEEE 802.3u media interface, rev. 3: OUI
0x0001f0, model 0x000c
Index: sys/dev/usb/if_smsc.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_smsc.c,v
retrieving revision 1.31
diff -u -p -u -p -r1.31 if_smsc.c
--- sys/dev/usb/if_smsc.c 29 Jul 2017 17:24:04 -0000 1.31
+++ sys/dev/usb/if_smsc.c 27 Jun 2018 08:37:34 -0000
@@ -283,7 +283,6 @@ int
smsc_miibus_readreg(struct device *dev, int phy, int reg)
{
struct smsc_softc *sc = (struct smsc_softc *)dev;
- uint32_t addr;
uint32_t val = 0;
smsc_lock_mii(sc);
@@ -292,8 +291,8 @@ smsc_miibus_readreg(struct device *dev,
goto done;
}
- addr = (phy << 11) | (reg << 6) | SMSC_MII_READ;
- smsc_write_reg(sc, SMSC_MII_ADDR, addr);
+ smsc_write_reg(sc, SMSC_MII_ADDR, SMSC_MII_READ | SMSC_MII_BUSY |
+ SMSC_MII_PHY_ADDR(phy) | SMSC_MII_REG_ADDR(reg));
if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
smsc_warn_printf(sc, "MII read timeout\n");
@@ -309,7 +308,6 @@ void
smsc_miibus_writereg(struct device *dev, int phy, int reg, int val)
{
struct smsc_softc *sc = (struct smsc_softc *)dev;
- uint32_t addr;
if (sc->sc_phyno != phy)
return;
@@ -323,8 +321,9 @@ smsc_miibus_writereg(struct device *dev,
smsc_write_reg(sc, SMSC_MII_DATA, val);
- addr = (phy << 11) | (reg << 6) | SMSC_MII_WRITE;
- smsc_write_reg(sc, SMSC_MII_ADDR, addr);
+ smsc_write_reg(sc, SMSC_MII_ADDR, SMSC_MII_WRITE | SMSC_MII_BUSY |
+ SMSC_MII_PHY_ADDR(phy) | SMSC_MII_REG_ADDR(reg));
+
smsc_unlock_mii(sc);
if (smsc_wait_for_bits(sc, SMSC_MII_ADDR, SMSC_MII_BUSY) != 0)
Index: sys/dev/usb/if_smscreg.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/if_smscreg.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 if_smscreg.h
--- sys/dev/usb/if_smscreg.h 18 Jun 2015 09:28:54 -0000 1.5
+++ sys/dev/usb/if_smscreg.h 27 Jun 2018 08:37:35 -0000
@@ -215,9 +215,17 @@
#define SMSC_INTR_GPIOS 0x000007FFUL
/* Phy MII interface register */
+#define SMSC_MII_PHY_ADDR_MASK 0x0000F800
+#define SMSC_MII_PHY_ADDR_SHIFT 11
+#define SMSC_MII_REG_ADDR_MASK 0x000007C0
+#define SMSC_MII_REG_ADDR_SHIFT 6
#define SMSC_MII_WRITE (0x1UL << 1)
#define SMSC_MII_READ (0x0UL << 1)
#define SMSC_MII_BUSY (0x1UL << 0)
+#define SMSC_MII_REG_ADDR(x) \
+ (((x) << SMSC_MII_REG_ADDR_SHIFT ) & SMSC_MII_REG_ADDR_MASK)
+#define SMSC_MII_PHY_ADDR(x) \
+ (((x) << SMSC_MII_PHY_ADDR_SHIFT) & SMSC_MII_PHY_ADDR_MASK)
/* H/W checksum register */
#define SMSC_COE_CTRL_TX_EN (0x1UL << 16) /* Tx H/W csum enable */