@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value)
}
/**
* ks8695_get_settings - Get device - specific settings .
* ks8695_wan_ get_settings - Get device - specific settings .
* @ ndev : The network device to read settings from
* @ cmd : The ethtool structure to read into
*/
static int
ks8695_get_settings ( struct net_device * ndev , struct ethtool_cmd * cmd )
ks8695_wan_ get_settings ( struct net_device * ndev , struct ethtool_cmd * cmd )
{
struct ks8695_priv * ksp = netdev_priv ( ndev ) ;
u32 ctrl ;
@ -870,69 +870,50 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
SUPPORTED_TP | SUPPORTED_MII ) ;
cmd - > transceiver = XCVR_INTERNAL ;
/* Port specific extras */
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
cmd - > phy_address = 0 ;
/* not supported for HPNA */
cmd - > autoneg = AUTONEG_DISABLE ;
cmd - > advertising = ADVERTISED_TP | ADVERTISED_MII ;
cmd - > port = PORT_MII ;
cmd - > supported | = ( SUPPORTED_Autoneg | SUPPORTED_Pause ) ;
cmd - > phy_address = 0 ;
/* BUG: Erm, dtype hpna implies no phy regs */
/*
ctrl = readl ( KS8695_MISC_VA + KS8695_HMC ) ;
cmd - > speed = ( ctrl & HMC_HSS ) ? SPEED_100 : SPEED_10 ;
cmd - > duplex = ( ctrl & HMC_HDS ) ? DUPLEX_FULL : DUPLEX_HALF ;
*/
return - EOPNOTSUPP ;
case KS8695_DTYPE_WAN :
cmd - > advertising = ADVERTISED_TP | ADVERTISED_MII ;
cmd - > port = PORT_MII ;
cmd - > supported | = ( SUPPORTED_Autoneg | SUPPORTED_Pause ) ;
cmd - > phy_address = 0 ;
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
if ( ( ctrl & WMC_WAND ) = = 0 ) {
/* auto-negotiation is enabled */
cmd - > advertising | = ADVERTISED_Autoneg ;
if ( ctrl & WMC_WANA100F )
cmd - > advertising | = ADVERTISED_100baseT_Full ;
if ( ctrl & WMC_WANA100H )
cmd - > advertising | = ADVERTISED_100baseT_Half ;
if ( ctrl & WMC_WANA10F )
cmd - > advertising | = ADVERTISED_10baseT_Full ;
if ( ctrl & WMC_WANA10H )
cmd - > advertising | = ADVERTISED_10baseT_Half ;
if ( ctrl & WMC_WANAP )
cmd - > advertising | = ADVERTISED_Pause ;
cmd - > autoneg = AUTONEG_ENABLE ;
cmd - > speed = ( ctrl & WMC_WSS ) ? SPEED_100 : SPEED_10 ;
cmd - > duplex = ( ctrl & WMC_WDS ) ?
DUPLEX_FULL : DUPLEX_HALF ;
} else {
/* auto-negotiation is disabled */
cmd - > autoneg = AUTONEG_DISABLE ;
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
if ( ( ctrl & WMC_WAND ) = = 0 ) {
/* auto-negotiation is enabled */
cmd - > advertising | = ADVERTISED_Autoneg ;
if ( ctrl & WMC_WANA100F )
cmd - > advertising | = ADVERTISED_100baseT_Full ;
if ( ctrl & WMC_WANA100H )
cmd - > advertising | = ADVERTISED_100baseT_Half ;
if ( ctrl & WMC_WANA10F )
cmd - > advertising | = ADVERTISED_10baseT_Full ;
if ( ctrl & WMC_WANA10H )
cmd - > advertising | = ADVERTISED_10baseT_Half ;
if ( ctrl & WMC_WANAP )
cmd - > advertising | = ADVERTISED_Pause ;
cmd - > autoneg = AUTONEG_ENABLE ;
cmd - > speed = ( ctrl & WMC_WSS ) ? SPEED_100 : SPEED_10 ;
cmd - > duplex = ( ctrl & WMC_WDS ) ?
DUPLEX_FULL : DUPLEX_HALF ;
} else {
/* auto-negotiation is disabled */
cmd - > autoneg = AUTONEG_DISABLE ;
cmd - > speed = ( ctrl & WMC_WANF100 ) ?
SPEED_100 : SPEED_10 ;
cmd - > duplex = ( ctrl & WMC_WANFF ) ?
DUPLEX_FULL : DUPLEX_HALF ;
}
break ;
case KS8695_DTYPE_LAN :
return - EOPNOTSUPP ;
cmd - > speed = ( ctrl & WMC_WANF100 ) ?
SPEED_100 : SPEED_10 ;
cmd - > duplex = ( ctrl & WMC_WANFF ) ?
DUPLEX_FULL : DUPLEX_HALF ;
}
return 0 ;
}
/**
* ks8695_set_settings - Set device - specific settings .
* ks8695_wan_set_settings - Set device - specific settings .
* @ ndev : The network device to configure
* @ cmd : The settings to configure
*/
static int
ks8695_set_settings ( struct net_device * ndev , struct ethtool_cmd * cmd )
ks8695_wan_set_settings ( struct net_device * ndev , struct ethtool_cmd * cmd )
{
struct ks8695_priv * ksp = netdev_priv ( ndev ) ;
u32 ctrl ;
@ -956,171 +937,99 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ADVERTISED_100baseT_Full ) ) = = 0 )
return - EINVAL ;
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
/* HPNA does not support auto-negotiation. */
return - EINVAL ;
case KS8695_DTYPE_WAN :
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
ctrl & = ~ ( WMC_WAND | WMC_WANA100F | WMC_WANA100H |
WMC_WANA10F | WMC_WANA10H ) ;
if ( cmd - > advertising & ADVERTISED_100baseT_Full )
ctrl | = WMC_WANA100F ;
if ( cmd - > advertising & ADVERTISED_100baseT_Half )
ctrl | = WMC_WANA100H ;
if ( cmd - > advertising & ADVERTISED_10baseT_Full )
ctrl | = WMC_WANA10F ;
if ( cmd - > advertising & ADVERTISED_10baseT_Half )
ctrl | = WMC_WANA10H ;
/* force a re-negotiation */
ctrl | = WMC_WANR ;
writel ( ctrl , ksp - > phyiface_regs + KS8695_WMC ) ;
break ;
case KS8695_DTYPE_LAN :
return - EOPNOTSUPP ;
}
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
ctrl & = ~ ( WMC_WAND | WMC_WANA100F | WMC_WANA100H |
WMC_WANA10F | WMC_WANA10H ) ;
if ( cmd - > advertising & ADVERTISED_100baseT_Full )
ctrl | = WMC_WANA100F ;
if ( cmd - > advertising & ADVERTISED_100baseT_Half )
ctrl | = WMC_WANA100H ;
if ( cmd - > advertising & ADVERTISED_10baseT_Full )
ctrl | = WMC_WANA10F ;
if ( cmd - > advertising & ADVERTISED_10baseT_Half )
ctrl | = WMC_WANA10H ;
/* force a re-negotiation */
ctrl | = WMC_WANR ;
writel ( ctrl , ksp - > phyiface_regs + KS8695_WMC ) ;
} else {
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
/* BUG: dtype_hpna implies no phy registers */
/*
ctrl = __raw_readl ( KS8695_MISC_VA + KS8695_HMC ) ;
ctrl & = ~ ( HMC_HSS | HMC_HDS ) ;
if ( cmd - > speed = = SPEED_100 )
ctrl | = HMC_HSS ;
if ( cmd - > duplex = = DUPLEX_FULL )
ctrl | = HMC_HDS ;
__raw_writel ( ctrl , KS8695_MISC_VA + KS8695_HMC ) ;
*/
return - EOPNOTSUPP ;
case KS8695_DTYPE_WAN :
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
/* disable auto-negotiation */
ctrl | = WMC_WAND ;
ctrl & = ~ ( WMC_WANF100 | WMC_WANFF ) ;
if ( cmd - > speed = = SPEED_100 )
ctrl | = WMC_WANF100 ;
if ( cmd - > duplex = = DUPLEX_FULL )
ctrl | = WMC_WANFF ;
writel ( ctrl , ksp - > phyiface_regs + KS8695_WMC ) ;
break ;
case KS8695_DTYPE_LAN :
return - EOPNOTSUPP ;
}
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
/* disable auto-negotiation */
ctrl | = WMC_WAND ;
ctrl & = ~ ( WMC_WANF100 | WMC_WANFF ) ;
if ( cmd - > speed = = SPEED_100 )
ctrl | = WMC_WANF100 ;
if ( cmd - > duplex = = DUPLEX_FULL )
ctrl | = WMC_WANFF ;
writel ( ctrl , ksp - > phyiface_regs + KS8695_WMC ) ;
}
return 0 ;
}
/**
* ks8695_nwayreset - Restart the autonegotiation on the port .
* ks8695_wan_nwayreset - Restart the autonegotiation on the port .
* @ ndev : The network device to restart autoneotiation on
*/
static int
ks8695_nwayreset ( struct net_device * ndev )
ks8695_wan_nwayreset ( struct net_device * ndev )
{
struct ks8695_priv * ksp = netdev_priv ( ndev ) ;
u32 ctrl ;
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
/* No phy means no autonegotiation on hpna */
return - EINVAL ;
case KS8695_DTYPE_WAN :
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
if ( ( ctrl & WMC_WAND ) = = 0 )
writel ( ctrl | WMC_WANR ,
ksp - > phyiface_regs + KS8695_WMC ) ;
else
/* auto-negotiation not enabled */
return - EINVAL ;
break ;
case KS8695_DTYPE_LAN :
return - EOPNOTSUPP ;
}
if ( ( ctrl & WMC_WAND ) = = 0 )
writel ( ctrl | WMC_WANR ,
ksp - > phyiface_regs + KS8695_WMC ) ;
else
/* auto-negotiation not enabled */
return - EINVAL ;
return 0 ;
}
/**
* ks8695_get_link - Retrieve link status of network interface
* ks8695_wan_ get_link - Retrieve link status of network interface
* @ ndev : The network interface to retrive the link status of .
*/
static u32
ks8695_get_link ( struct net_device * ndev )
ks8695_wan_ get_link ( struct net_device * ndev )
{
struct ks8695_priv * ksp = netdev_priv ( ndev ) ;
u32 ctrl ;
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
/* HPNA always has link */
return 1 ;
case KS8695_DTYPE_WAN :
/* WAN we can read the PHY for */
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
return ctrl & WMC_WLS ;
case KS8695_DTYPE_LAN :
return - EOPNOTSUPP ;
}
return 0 ;
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
return ctrl & WMC_WLS ;
}
/**
* ks8695_get_pause - Retrieve network pause / flow - control advertising
* ks8695_wan_get_pause - Retrieve network pause / flow - control advertising
* @ ndev : The device to retrieve settings from
* @ param : The structure to fill out with the information
*/
static void
ks8695_get_pause ( struct net_device * ndev , struct ethtool_pauseparam * param )
ks8695_wan_get_pause ( struct net_device * ndev , struct ethtool_pauseparam * param )
{
struct ks8695_priv * ksp = netdev_priv ( ndev ) ;
u32 ctrl ;
switch ( ksp - > dtype ) {
case KS8695_DTYPE_HPNA :
/* No phy link on hpna to configure */
return ;
case KS8695_DTYPE_WAN :
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
/* advertise Pause */
param - > autoneg = ( ctrl & WMC_WANAP ) ;
ctrl = readl ( ksp - > phyiface_regs + KS8695_WMC ) ;
/* current Rx Flow-control */
ctrl = ks8695_readreg ( ksp , KS8695_DRXC ) ;
param - > rx_pause = ( ctrl & DRXC_RFCE ) ;
/* advertise Pause */
param - > autoneg = ( ctrl & WMC_WANAP ) ;
/* current Tx Flow-control */
ctrl = ks8695_readreg ( ksp , KS8695_DTXC ) ;
param - > tx_pause = ( ctrl & DTXC_TFCE ) ;
break ;
case KS8695_DTYPE_LAN :
/* The LAN's "phy" is a direct-attached switch */
return ;
}
}
/* current Rx Flow-control */
ctrl = ks8695_readreg ( ksp , KS8695_DRXC ) ;
param - > rx_pause = ( ctrl & DRXC_RFCE ) ;
/**
* ks8695_set_pause - Configure pause / flow - control
* @ ndev : The device to configure
* @ param : The pause parameters to set
*
* TODO : Implement this
*/
static int
ks8695_set_pause ( struct net_device * ndev , struct ethtool_pauseparam * param )
{
return - EOPNOTSUPP ;
/* current Tx Flow-control */
ctrl = ks8695_readreg ( ksp , KS8695_DTXC ) ;
param - > tx_pause = ( ctrl & DTXC_TFCE ) ;
}
/**
@ -1140,12 +1049,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
static const struct ethtool_ops ks8695_ethtool_ops = {
. get_msglevel = ks8695_get_msglevel ,
. set_msglevel = ks8695_set_msglevel ,
. get_settings = ks8695_get_settings ,
. set_settings = ks8695_set_settings ,
. nway_reset = ks8695_nwayreset ,
. get_link = ks8695_get_link ,
. get_pauseparam = ks8695_get_pause ,
. set_pauseparam = ks8695_set_pause ,
. get_drvinfo = ks8695_get_drvinfo ,
} ;
static const struct ethtool_ops ks8695_wan_ethtool_ops = {
. get_msglevel = ks8695_get_msglevel ,
. set_msglevel = ks8695_set_msglevel ,
. get_settings = ks8695_wan_get_settings ,
. set_settings = ks8695_wan_set_settings ,
. nway_reset = ks8695_wan_nwayreset ,
. get_link = ks8695_wan_get_link ,
. get_pauseparam = ks8695_wan_get_pause ,
. get_drvinfo = ks8695_get_drvinfo ,
} ;
@ -1541,7 +1455,6 @@ ks8695_probe(struct platform_device *pdev)
/* driver system setup */
ndev - > netdev_ops = & ks8695_netdev_ops ;
SET_ETHTOOL_OPS ( ndev , & ks8695_ethtool_ops ) ;
ndev - > watchdog_timeo = msecs_to_jiffies ( watchdog ) ;
netif_napi_add ( ndev , & ksp - > napi , ks8695_poll , NAPI_WEIGHT ) ;
@ -1608,12 +1521,15 @@ ks8695_probe(struct platform_device *pdev)
if ( ksp - > phyiface_regs & & ksp - > link_irq = = - 1 ) {
ks8695_init_switch ( ksp ) ;
ksp - > dtype = KS8695_DTYPE_LAN ;
SET_ETHTOOL_OPS ( ndev , & ks8695_ethtool_ops ) ;
} else if ( ksp - > phyiface_regs & & ksp - > link_irq ! = - 1 ) {
ks8695_init_wan_phy ( ksp ) ;
ksp - > dtype = KS8695_DTYPE_WAN ;
SET_ETHTOOL_OPS ( ndev , & ks8695_wan_ethtool_ops ) ;
} else {
/* No initialisation since HPNA does not have a PHY */
ksp - > dtype = KS8695_DTYPE_HPNA ;
SET_ETHTOOL_OPS ( ndev , & ks8695_ethtool_ops ) ;
}
/* And bring up the net_device with the net core */