@ -259,67 +259,27 @@ static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = {
static int hns_nic_config_phy_loopback ( struct phy_device * phy_dev , u8 en )
{
# define COPPER_CONTROL_REG 0
# define PHY_POWER_DOWN BIT(11)
# define PHY_LOOP_BACK BIT(14)
u16 val = 0 ;
if ( phy_dev - > is_c45 ) /* c45 branch adding for XGE PHY */
return - ENOTSUPP ;
int err ;
if ( en ) {
/* speed : 1000M */
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 2 ) ;
phy_write ( phy_dev , 21 , 0x1046 ) ;
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 0 ) ;
/* Force Master */
phy_write ( phy_dev , 9 , 0x1F00 ) ;
/* Soft-reset */
phy_write ( phy_dev , 0 , 0x9140 ) ;
/* If autoneg disabled,two soft-reset operations */
phy_write ( phy_dev , 0 , 0x9140 ) ;
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 0xFA ) ;
/* Default is 0x0400 */
phy_write ( phy_dev , 1 , 0x418 ) ;
/* Force 1000M Link, Default is 0x0200 */
phy_write ( phy_dev , 7 , 0x20C ) ;
/* Powerup Fiber */
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 1 ) ;
val = phy_read ( phy_dev , COPPER_CONTROL_REG ) ;
val & = ~ PHY_POWER_DOWN ;
phy_write ( phy_dev , COPPER_CONTROL_REG , val ) ;
/* Enable Phy Loopback */
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 0 ) ;
val = phy_read ( phy_dev , COPPER_CONTROL_REG ) ;
val | = PHY_LOOP_BACK ;
val & = ~ PHY_POWER_DOWN ;
phy_write ( phy_dev , COPPER_CONTROL_REG , val ) ;
/* Doing phy loopback in offline state, phy resuming is
* needed to power up the device .
*/
err = phy_resume ( phy_dev ) ;
if ( err )
goto out ;
err = phy_loopback ( phy_dev , true ) ;
} else {
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 0xFA ) ;
phy_write ( phy_dev , 1 , 0x400 ) ;
phy_write ( phy_dev , 7 , 0x200 ) ;
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 1 ) ;
val = phy_read ( phy_dev , COPPER_CONTROL_REG ) ;
val | = PHY_POWER_DOWN ;
phy_write ( phy_dev , COPPER_CONTROL_REG , val ) ;
phy_write ( phy_dev , HNS_PHY_PAGE_REG , 0 ) ;
phy_write ( phy_dev , 9 , 0xF00 ) ;
val = phy_read ( phy_dev , COPPER_CONTROL_REG ) ;
val & = ~ PHY_LOOP_BACK ;
val | = PHY_POWER_DOWN ;
phy_write ( phy_dev , COPPER_CONTROL_REG , val ) ;
err = phy_loopback ( phy_dev , false ) ;
if ( err )
goto out ;
err = phy_suspend ( phy_dev ) ;
}
return 0 ;
out :
return err ;
}
static int __lb_setup ( struct net_device * ndev ,
@ -332,10 +292,9 @@ static int __lb_setup(struct net_device *ndev,
switch ( loop ) {
case MAC_INTERNALLOOP_PHY :
if ( ( phy_dev ) & & ( ! phy_dev - > is_c45 ) ) {
ret = hns_nic_config_phy_loopback ( phy_dev , 0x1 ) ;
ret | = h - > dev - > ops - > set_loopback ( h , loop , 0x1 ) ;
}
ret = hns_nic_config_phy_loopback ( phy_dev , 0x1 ) ;
if ( ! ret )
ret = h - > dev - > ops - > set_loopback ( h , loop , 0x1 ) ;
break ;
case MAC_INTERNALLOOP_MAC :
if ( ( h - > dev - > ops - > set_loopback ) & &
@ -346,17 +305,17 @@ static int __lb_setup(struct net_device *ndev,
if ( h - > dev - > ops - > set_loopback )
ret = h - > dev - > ops - > set_loopback ( h , loop , 0x1 ) ;
break ;
case MAC_LOOP_PHY_NONE :
ret = hns_nic_config_phy_loopback ( phy_dev , 0x0 ) ;
case MAC_LOOP_NONE :
if ( ( phy_dev ) & & ( ! phy_dev - > is_c45 ) )
ret | = hns_nic_config_phy_loopback ( phy_dev , 0x0 ) ;
if ( h - > dev - > ops - > set_loopback ) {
if ( ! ret & & h - > dev - > ops - > set_loopback ) {
if ( priv - > ae_handle - > phy_if ! = PHY_INTERFACE_MODE_XGMII )
ret | = h - > dev - > ops - > set_loopback ( h ,
ret = h - > dev - > ops - > set_loopback ( h ,
MAC_INTERNALLOOP_MAC , 0x0 ) ;
ret | = h - > dev - > ops - > set_loopback ( h ,
MAC_INTERNALLOOP_SERDES , 0x0 ) ;
if ( ! ret )
ret = h - > dev - > ops - > set_loopback ( h ,
MAC_INTERNALLOOP_SERDES , 0x0 ) ;
}
break ;
default :
@ -582,13 +541,16 @@ static int __lb_run_test(struct net_device *ndev,
return ret_val ;
}
static int __lb_down ( struct net_device * ndev )
static int __lb_down ( struct net_device * ndev , enum hnae_loop loop )
{
struct hns_nic_priv * priv = netdev_priv ( ndev ) ;
struct hnae_handle * h = priv - > ae_handle ;
int ret ;
ret = __lb_setup ( ndev , MAC_LOOP_NONE ) ;
if ( loop = = MAC_INTERNALLOOP_PHY )
ret = __lb_setup ( ndev , MAC_LOOP_PHY_NONE ) ;
else
ret = __lb_setup ( ndev , MAC_LOOP_NONE ) ;
if ( ret )
netdev_err ( ndev , " %s: __lb_setup return error(%d)! \n " ,
__func__ ,
@ -644,7 +606,8 @@ static void hns_nic_self_test(struct net_device *ndev,
if ( ! data [ test_index ] ) {
data [ test_index ] = __lb_run_test (
ndev , ( enum hnae_loop ) st_param [ i ] [ 0 ] ) ;
( void ) __lb_down ( ndev ) ;
( void ) __lb_down ( ndev ,
( enum hnae_loop ) st_param [ i ] [ 0 ] ) ;
}
if ( data [ test_index ] )