diff mbox series

smsc95xx: Add quirk for TJA1100 BroadRReach PHY

Message ID 20180911101237.4281-1-marex@denx.de (mailing list archive)
State New, archived
Headers show
Series smsc95xx: Add quirk for TJA1100 BroadRReach PHY | expand

Commit Message

Marek Vasut Sept. 11, 2018, 10:12 a.m. UTC
The company atmes.de manufactures a SMSC95xx device with default USB
ID 0424:9e00 , but with external NXP TJA1100 PHY at address 0x4. This
PHY is not 802.3 c22 compliant, but rather c96 compliant. The register
set is slightly different and does not provide link state information
in c22-compliant manner and any duplex information.

This patch adds a quirk for such a setup. The PHY is detected by its
PHY ID register values and if present, link detection is not performed
and duplex is always forced to full.

Signed-off-by: Marek Vasut <marex@denx.de>
Cc: David S. Miller <davem@davemloft.net>
Cc: Nisar Sayed <Nisar.Sayed@microchip.com>
Cc: Woojung Huh <Woojung.Huh@microchip.com>
---
 drivers/net/usb/smsc95xx.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 014bb71ce8a8..454a3994133d 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -74,6 +74,7 @@  struct smsc95xx_priv {
 	u8 suspend_flags;
 	u8 mdix_ctrl;
 	bool link_ok;
+	bool has_tja1100_phy;
 	struct delayed_work carrier_check;
 	struct usbnet *dev;
 };
@@ -578,7 +579,8 @@  static int smsc95xx_link_reset(struct usbnet *dev)
 	if (ret < 0)
 		return ret;
 
-	mii_check_media(mii, 1, 1);
+	if (!pdata->has_tja1100_phy)
+		mii_check_media(mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 	lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
 	rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
@@ -588,7 +590,7 @@  static int smsc95xx_link_reset(struct usbnet *dev)
 		  ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
 
 	spin_lock_irqsave(&pdata->mac_cr_lock, flags);
-	if (ecmd.duplex != DUPLEX_FULL) {
+	if (!pdata->has_tja1100_phy && ecmd.duplex != DUPLEX_FULL) {
 		pdata->mac_cr &= ~MAC_CR_FDPX_;
 		pdata->mac_cr |= MAC_CR_RCVOWN_;
 	} else {
@@ -985,6 +987,7 @@  static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm)
 
 static int smsc95xx_phy_address(struct usbnet *dev)
 {
+	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
 	u32 read_buf;
 	int ret, id1, id2, phyad;
 
@@ -1006,9 +1009,19 @@  static int smsc95xx_phy_address(struct usbnet *dev)
 	for (phyad = 0x1f; phyad >= 0; phyad--) {
 		id1 = smsc95xx_mdio_read(dev->net, phyad, MII_PHYSID1);
 		id2 = smsc95xx_mdio_read(dev->net, phyad, MII_PHYSID2);
+
 		/* Check for valid response from the PHY */
-		if (id1 > 0 && id2 > 0 && id1 != 0x7fff && id2 != 0xffff)
+		if (id1 > 0 && id2 > 0 && id1 != 0x7fff && id2 != 0xffff) {
+			/*
+			 * Check for special mutation of the SMSC95xx USB
+			 * device with NXP TJA1100 BroadRReach PHY. If this
+			 * is present, enable quirk.
+			 */
+			if (id1 == 0x0180 && id2 == 0xdc48)
+				pdata->has_tja1100_phy = true;
+
 			return phyad;
+		}
 	}
 
 	/* No PHY found. */