Commit c3d2a730 authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

ks8695net: Disable non-working ethtool operations

Some ethtool operations can only be implemented for the WAN port, and
not all such operations are allowed to return an error code such as
-EOPNOTSUPP.  Therefore, define two separate ethtool_ops structures
for WAN and non-WAN ports; simplify and rename the WAN-only functions.

This is completely untested as I don't have an ARM build environment.
Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9e56790a
...@@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value) ...@@ -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 * @ndev: The network device to read settings from
* @cmd: The ethtool structure to read into * @cmd: The ethtool structure to read into
*/ */
static int 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); struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl; u32 ctrl;
...@@ -870,21 +870,6 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ...@@ -870,21 +870,6 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
SUPPORTED_TP | SUPPORTED_MII); SUPPORTED_TP | SUPPORTED_MII);
cmd->transceiver = XCVR_INTERNAL; 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;
/* 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->advertising = ADVERTISED_TP | ADVERTISED_MII;
cmd->port = PORT_MII; cmd->port = PORT_MII;
cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause); cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
...@@ -918,21 +903,17 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ...@@ -918,21 +903,17 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
cmd->duplex = (ctrl & WMC_WANFF) ? cmd->duplex = (ctrl & WMC_WANFF) ?
DUPLEX_FULL : DUPLEX_HALF; DUPLEX_FULL : DUPLEX_HALF;
} }
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
return 0; return 0;
} }
/** /**
* ks8695_set_settings - Set device-specific settings. * ks8695_wan_set_settings - Set device-specific settings.
* @ndev: The network device to configure * @ndev: The network device to configure
* @cmd: The settings to configure * @cmd: The settings to configure
*/ */
static int 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); struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl; u32 ctrl;
...@@ -956,11 +937,6 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ...@@ -956,11 +937,6 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ADVERTISED_100baseT_Full)) == 0) ADVERTISED_100baseT_Full)) == 0)
return -EINVAL; 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 = readl(ksp->phyiface_regs + KS8695_WMC);
ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H | ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
...@@ -977,28 +953,7 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ...@@ -977,28 +953,7 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
/* force a re-negotiation */ /* force a re-negotiation */
ctrl |= WMC_WANR; ctrl |= WMC_WANR;
writel(ctrl, ksp->phyiface_regs + KS8695_WMC); writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
} else { } 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); ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
/* disable auto-negotiation */ /* disable auto-negotiation */
...@@ -1011,30 +966,21 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ...@@ -1011,30 +966,21 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ctrl |= WMC_WANFF; ctrl |= WMC_WANFF;
writel(ctrl, ksp->phyiface_regs + KS8695_WMC); writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
} }
return 0; 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 * @ndev: The network device to restart autoneotiation on
*/ */
static int static int
ks8695_nwayreset(struct net_device *ndev) ks8695_wan_nwayreset(struct net_device *ndev)
{ {
struct ks8695_priv *ksp = netdev_priv(ndev); struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl; 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) if ((ctrl & WMC_WAND) == 0)
...@@ -1043,54 +989,35 @@ ks8695_nwayreset(struct net_device *ndev) ...@@ -1043,54 +989,35 @@ ks8695_nwayreset(struct net_device *ndev)
else else
/* auto-negotiation not enabled */ /* auto-negotiation not enabled */
return -EINVAL; return -EINVAL;
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
return 0; 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. * @ndev: The network interface to retrive the link status of.
*/ */
static u32 static u32
ks8695_get_link(struct net_device *ndev) ks8695_wan_get_link(struct net_device *ndev)
{ {
struct ks8695_priv *ksp = netdev_priv(ndev); struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl; 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); ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
return ctrl & WMC_WLS; return ctrl & WMC_WLS;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
return 0;
} }
/** /**
* 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 * @ndev: The device to retrieve settings from
* @param: The structure to fill out with the information * @param: The structure to fill out with the information
*/ */
static void 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); struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl; 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); ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
/* advertise Pause */ /* advertise Pause */
...@@ -1103,24 +1030,6 @@ ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param) ...@@ -1103,24 +1030,6 @@ ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
/* current Tx Flow-control */ /* current Tx Flow-control */
ctrl = ks8695_readreg(ksp, KS8695_DTXC); ctrl = ks8695_readreg(ksp, KS8695_DTXC);
param->tx_pause = (ctrl & DTXC_TFCE); param->tx_pause = (ctrl & DTXC_TFCE);
break;
case KS8695_DTYPE_LAN:
/* The LAN's "phy" is a direct-attached switch */
return;
}
}
/**
* 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;
} }
/** /**
...@@ -1140,12 +1049,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) ...@@ -1140,12 +1049,17 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
static const struct ethtool_ops ks8695_ethtool_ops = { static const struct ethtool_ops ks8695_ethtool_ops = {
.get_msglevel = ks8695_get_msglevel, .get_msglevel = ks8695_get_msglevel,
.set_msglevel = ks8695_set_msglevel, .set_msglevel = ks8695_set_msglevel,
.get_settings = ks8695_get_settings, .get_drvinfo = ks8695_get_drvinfo,
.set_settings = ks8695_set_settings, };
.nway_reset = ks8695_nwayreset,
.get_link = ks8695_get_link, static const struct ethtool_ops ks8695_wan_ethtool_ops = {
.get_pauseparam = ks8695_get_pause, .get_msglevel = ks8695_get_msglevel,
.set_pauseparam = ks8695_set_pause, .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, .get_drvinfo = ks8695_get_drvinfo,
}; };
...@@ -1541,7 +1455,6 @@ ks8695_probe(struct platform_device *pdev) ...@@ -1541,7 +1455,6 @@ ks8695_probe(struct platform_device *pdev)
/* driver system setup */ /* driver system setup */
ndev->netdev_ops = &ks8695_netdev_ops; ndev->netdev_ops = &ks8695_netdev_ops;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT); netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
...@@ -1608,12 +1521,15 @@ ks8695_probe(struct platform_device *pdev) ...@@ -1608,12 +1521,15 @@ ks8695_probe(struct platform_device *pdev)
if (ksp->phyiface_regs && ksp->link_irq == -1) { if (ksp->phyiface_regs && ksp->link_irq == -1) {
ks8695_init_switch(ksp); ks8695_init_switch(ksp);
ksp->dtype = KS8695_DTYPE_LAN; ksp->dtype = KS8695_DTYPE_LAN;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
} else if (ksp->phyiface_regs && ksp->link_irq != -1) { } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
ks8695_init_wan_phy(ksp); ks8695_init_wan_phy(ksp);
ksp->dtype = KS8695_DTYPE_WAN; ksp->dtype = KS8695_DTYPE_WAN;
SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
} else { } else {
/* No initialisation since HPNA does not have a PHY */ /* No initialisation since HPNA does not have a PHY */
ksp->dtype = KS8695_DTYPE_HPNA; ksp->dtype = KS8695_DTYPE_HPNA;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
} }
/* And bring up the net_device with the net core */ /* And bring up the net_device with the net core */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment