Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+99 −183
Original line number Diff line number Diff line
@@ -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,21 +870,6 @@ 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;

		/* 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);
@@ -918,21 +903,17 @@ ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
		cmd->duplex = (ctrl & WMC_WANFF) ?
			DUPLEX_FULL : DUPLEX_HALF;
	}
		break;
	case KS8695_DTYPE_LAN:
		return -EOPNOTSUPP;
	}

	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,11 +937,6 @@ 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 |
@@ -977,28 +953,7 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
		/* force a re-negotiation */
		ctrl |= WMC_WANR;
		writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
			break;
		case KS8695_DTYPE_LAN:
			return -EOPNOTSUPP;
		}

	} 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 */
@@ -1011,30 +966,21 @@ ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
			ctrl |= WMC_WANFF;

		writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
			break;
		case KS8695_DTYPE_LAN:
			return -EOPNOTSUPP;
		}
	}

	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);

	if ((ctrl & WMC_WAND) == 0)
@@ -1043,54 +989,35 @@ ks8695_nwayreset(struct net_device *ndev)
	else
		/* auto-negotiation not enabled */
		return -EINVAL;
		break;
	case KS8695_DTYPE_LAN:
		return -EOPNOTSUPP;
	}

	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;
}

/**
 *	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 */
@@ -1103,24 +1030,6 @@ ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
	/* 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;
	}
}

/**
 *	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)
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 */