@ -618,6 +618,31 @@ static void ar7240sw_setup(struct ar7240sw *as)
ar7240sw_reg_rmw ( mii , AR7240_REG_SERVICE_TAG , AR7240_SERVICE_TAG_M , 0 ) ;
ar7240sw_reg_rmw ( mii , AR7240_REG_SERVICE_TAG , AR7240_SERVICE_TAG_M , 0 ) ;
}
}
/* inspired by phy_poll_reset in drivers/net/phy/phy_device.c */
static int
ar7240sw_phy_poll_reset ( struct mii_bus * bus )
{
const unsigned int sleep_msecs = 20 ;
int ret , elapsed , i ;
for ( elapsed = sleep_msecs ; elapsed < = 600 ;
elapsed + = sleep_msecs ) {
msleep ( sleep_msecs ) ;
for ( i = 0 ; i < AR7240_NUM_PHYS ; i + + ) {
ret = ar7240sw_phy_read ( bus , i , MII_BMCR ) ;
if ( ret < 0 )
return ret ;
if ( ret & BMCR_RESET )
break ;
if ( i = = AR7240_NUM_PHYS - 1 ) {
usleep_range ( 1000 , 2000 ) ;
return 0 ;
}
}
}
return - ETIMEDOUT ;
}
static int ar7240sw_reset ( struct ar7240sw * as )
static int ar7240sw_reset ( struct ar7240sw * as )
{
{
struct mii_bus * mii = as - > mii_bus ;
struct mii_bus * mii = as - > mii_bus ;
@ -646,7 +671,9 @@ static int ar7240sw_reset(struct ar7240sw *as)
ar7240sw_phy_write ( mii , i , MII_BMCR ,
ar7240sw_phy_write ( mii , i , MII_BMCR ,
BMCR_RESET | BMCR_ANENABLE ) ;
BMCR_RESET | BMCR_ANENABLE ) ;
}
}
msleep ( 1000 ) ;
ret = ar7240sw_phy_poll_reset ( mii ) ;
if ( ret )
return ret ;
ar7240sw_setup ( as ) ;
ar7240sw_setup ( as ) ;
return ret ;
return ret ;