[PATCH] smsc95xx: Add quirk for TJA1100 BroadRReach PHY

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxx>
Cc: David S. Miller <davem@xxxxxxxxxxxxx>
Cc: Nisar Sayed <Nisar.Sayed@xxxxxxxxxxxxx>
Cc: Woojung Huh <Woojung.Huh@xxxxxxxxxxxxx>
---
 drivers/net/usb/smsc95xx.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux