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

Reply via email to