From: Daniele Venzano <webvenza@libero.it>

Fix PHY transceiver detection code to fall back to known PHY and not to the
last detected.

The code checks every transceiver detected for link status and type, but fails
when ghost transceivers are detected, deciding to use the last one detected.

With this patch the driver should choose the correct transceiver even when
some ghosts are detected by checking for the type of the tranceiver it is
going to use.


---

 25-akpm/drivers/net/sis900.c |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff -puN drivers/net/sis900.c~sis900-fix-phy-transceiver-detection drivers/net/sis900.c
--- 25/drivers/net/sis900.c~sis900-fix-phy-transceiver-detection	2004-05-19 12:40:44.319929224 -0700
+++ 25-akpm/drivers/net/sis900.c	2004-05-19 12:40:44.325928312 -0700
@@ -116,6 +116,7 @@ static struct mii_chip_info {
 #define	HOME 	0x0001
 #define LAN	0x0002
 #define MIX	0x0003
+#define UNKNOWN	0x0
 } mii_chip_table[] = {
 	{ "SiS 900 Internal MII PHY", 		0x001d, 0x8000, LAN },
 	{ "SiS 7014 Physical Layer Solution", 	0x0016, 0xf830, LAN },
@@ -577,9 +578,11 @@ static int __init sis900_mii_probe (stru
 				break;
 			}
 			
-		if( !mii_chip_table[i].phy_id1 )
+		if( !mii_chip_table[i].phy_id1 ) {
 			printk(KERN_INFO "%s: Unknown PHY transceiver found at address %d.\n",
-			       net_dev->name, phy_addr);			
+			       net_dev->name, phy_addr);
+			mii_phy->phy_types = UNKNOWN;
+		}
 	}
 	
 	if (sis_priv->mii == NULL) {
@@ -644,15 +647,15 @@ static int __init sis900_mii_probe (stru
 static u16 sis900_default_phy(struct net_device * net_dev)
 {
 	struct sis900_private * sis_priv = net_dev->priv;
- 	struct mii_phy *phy = NULL, *phy_home = NULL, *default_phy = NULL;
+ 	struct mii_phy *phy = NULL, *phy_home = NULL, *default_phy = NULL, *phy_lan = NULL;
 	u16 status;
 
         for( phy=sis_priv->first_mii; phy; phy=phy->next ){
 		status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
 		status = mdio_read(net_dev, phy->phy_addr, MII_STATUS);
 
-		/* Link ON & Not select deafalut PHY */
-		 if ( (status & MII_STAT_LINK) && !(default_phy) )
+		/* Link ON & Not select default PHY & not ghost PHY */
+		 if ( (status & MII_STAT_LINK) && !default_phy && (phy->phy_types != UNKNOWN) )
 		 	default_phy = phy;
 		 else{
 			status = mdio_read(net_dev, phy->phy_addr, MII_CONTROL);
@@ -660,12 +663,16 @@ static u16 sis900_default_phy(struct net
 				status | MII_CNTL_AUTO | MII_CNTL_ISOLATE);
 			if( phy->phy_types == HOME )
 				phy_home = phy;
+			else if (phy->phy_types == LAN)
+				phy_lan = phy;
 		 }
 	}
 
-	if( (!default_phy) && phy_home )
+	if( !default_phy && phy_home )
 		default_phy = phy_home;
-	else if(!default_phy)
+	else if( !default_phy && phy_lan )
+		default_phy = phy_lan;
+	else if ( !default_phy )
 		default_phy = sis_priv->first_mii;
 
 	if( sis_priv->mii != default_phy ){

_