git: dc4c75c9a3c3 - main - smsc: Support external PHY
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 23 Oct 2026 22:01:28 UTC
The branch main has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=dc4c75c9a3c3611af451da13990e49e267551475
commit dc4c75c9a3c3611af451da13990e49e267551475
Author: Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2026-10-14 01:04:24 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2026-10-23 22:00:48 +0000
smsc: Support external PHY
SMSC_HW_CFG_PSEL indicates that an external PHY is present. Skip the
internal PHY initialization when set and store the ID of the detected
PHY.
Reviewed by: br
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60744
---
sys/dev/usb/net/if_smsc.c | 39 +++++++++++++++++++++++++++++++--------
sys/dev/usb/net/if_smscreg.h | 1 +
2 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/sys/dev/usb/net/if_smsc.c b/sys/dev/usb/net/if_smsc.c
index 5803a5bd1bcf..3144eb7e8917 100644
--- a/sys/dev/usb/net/if_smsc.c
+++ b/sys/dev/usb/net/if_smsc.c
@@ -1449,11 +1449,12 @@ smsc_chip_init(struct smsc_softc *sc)
/* Vlan */
smsc_write_reg(sc, SMSC_VLAN1, (uint32_t)ETHERTYPE_VLAN);
- /*
- * Initialise the PHY
- */
- if ((err = smsc_phy_init(sc)) != 0)
- goto init_failed;
+ if ((sc->sc_flags & SMSC_FLAG_EXT_PHY) == 0) {
+ /* Initialise the PHY */
+ err = smsc_phy_init(sc);
+ if (err != 0)
+ goto init_failed;
+ }
/*
* Start TX
@@ -1621,14 +1622,12 @@ smsc_attach_post(struct usb_ether *ue)
{
struct smsc_softc *sc = uether_getsc(ue);
struct ether_addr eaddr;
- uint32_t mac_h, mac_l;
+ uint32_t hwcfg, mac_h, mac_l;
int err;
int i;
smsc_dbg_printf(sc, "smsc_attach_post\n");
- /* Setup some of the basics */
- sc->sc_phyno = 1;
/* Attempt to get the mac address, if an EEPROM is not attached this
* will just return FF:FF:FF:FF:FF:FF, so in such cases we invent a MAC
@@ -1636,6 +1635,15 @@ smsc_attach_post(struct usb_ether *ue)
*/
memset(sc->sc_ue.ue_eaddr, 0xff, ETHER_ADDR_LEN);
+ smsc_read_reg(sc, SMSC_HW_CFG, &hwcfg);
+ if (hwcfg & SMSC_HW_CFG_PSEL) {
+ smsc_dbg_printf(sc, "HW_CFG indicates external PHY\n");
+ sc->sc_flags |= SMSC_FLAG_EXT_PHY;
+ sc->sc_phyno = MII_PHY_ANY;
+ } else {
+ sc->sc_phyno = 1;
+ }
+
/* Check if there is already a MAC address in the register */
if ((smsc_read_reg(sc, SMSC_MAC_ADDRL, &mac_l) == 0) &&
(smsc_read_reg(sc, SMSC_MAC_ADDRH, &mac_h) == 0)) {
@@ -1688,6 +1696,8 @@ static int
smsc_attach_post_sub(struct usb_ether *ue)
{
struct smsc_softc *sc;
+ struct mii_softc *miisc;
+ struct mii_data *mii;
if_t ifp;
int error;
@@ -1718,6 +1728,19 @@ smsc_attach_post_sub(struct usb_ether *ue)
error = mii_attach(ue->ue_dev, &ue->ue_miibus, ifp,
uether_ifmedia_upd, ue->ue_methods->ue_mii_sts,
BMSR_DEFCAPMASK, sc->sc_phyno, MII_OFFSET_ANY, 0);
+
+ if (error != 0)
+ goto fail;
+
+ if (sc->sc_phyno == MII_PHY_ANY) {
+ /* Store the actual PHY address we found. */
+ mii = device_get_softc(ue->ue_miibus);
+ miisc = LIST_FIRST(&mii->mii_phys);
+ if (miisc != NULL)
+ sc->sc_phyno = miisc->mii_phy;
+ }
+
+fail:
bus_topo_unlock();
return (error);
diff --git a/sys/dev/usb/net/if_smscreg.h b/sys/dev/usb/net/if_smscreg.h
index 1d27b661b16e..be18caf7627a 100644
--- a/sys/dev/usb/net/if_smscreg.h
+++ b/sys/dev/usb/net/if_smscreg.h
@@ -268,6 +268,7 @@ struct smsc_softc {
uint32_t sc_flags;
#define SMSC_FLAG_LINK 0x0001
#define SMSC_FLAG_LAN9514 0x1000 /* LAN9514 */
+#define SMSC_FLAG_EXT_PHY 0x2000 /* External PHY (HW_CFG.PSEL) */
};
#define SMSC_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)