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

Commit 61a44b9c authored by Matthew Wilcox's avatar Matthew Wilcox Committed by David S. Miller
Browse files

[NET]: ethtool ops are the only way



During the transition to the ethtool_ops way of doing things, we supported
calling the device's ->do_ioctl method to allow unconverted drivers to
continue working.  Those days are long behind us, all in-tree drivers
use the ethtool_ops way, and so we no longer need to support this.

The bonding driver is the biggest beneficiary of this; it no longer
needs to call ioctl() as a fallback if ethtool_ops aren't supported.

Also put a proper copyright statement on ethtool.c.

Signed-off-by: default avatarMatthew Wilcox <matthew@wil.cx>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f1543f8b
Loading
Loading
Loading
Loading
+10 −42
Original line number Diff line number Diff line
@@ -613,38 +613,20 @@ down:
static int bond_update_speed_duplex(struct slave *slave)
{
	struct net_device *slave_dev = slave->dev;
	static int (* ioctl)(struct net_device *, struct ifreq *, int);
	struct ifreq ifr;
	struct ethtool_cmd etool;
	int res;

	/* Fake speed and duplex */
	slave->speed = SPEED_100;
	slave->duplex = DUPLEX_FULL;

	if (slave_dev->ethtool_ops) {
		int res;

		if (!slave_dev->ethtool_ops->get_settings) {
	if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings)
		return -1;
		}

	res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
		if (res < 0) {
			return -1;
		}

		goto verify;
	}

	ioctl = slave_dev->do_ioctl;
	strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
	etool.cmd = ETHTOOL_GSET;
	ifr.ifr_data = (char*)&etool;
	if (!ioctl || (IOCTL(slave_dev, &ifr, SIOCETHTOOL) < 0)) {
	if (res < 0)
		return -1;
	}

verify:
	switch (etool.speed) {
	case SPEED_10:
	case SPEED_100:
@@ -690,7 +672,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
	static int (* ioctl)(struct net_device *, struct ifreq *, int);
	struct ifreq ifr;
	struct mii_ioctl_data *mii;
	struct ethtool_value etool;

	if (bond->params.use_carrier) {
		return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
@@ -721,9 +702,10 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
		}
	}

	/* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */
	/* for a period of time so we attempt to get link status   */
	/* from it last if the above MII ioctls fail...            */
	/*
	 * Some drivers cache ETHTOOL_GLINK for a period of time so we only
	 * attempt to get link status from it if the above MII ioctls fail.
	 */
	if (slave_dev->ethtool_ops) {
		if (slave_dev->ethtool_ops->get_link) {
			u32 link;
@@ -734,23 +716,9 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
		}
	}

	if (ioctl) {
		strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
		etool.cmd = ETHTOOL_GLINK;
		ifr.ifr_data = (char*)&etool;
		if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
			if (etool.data == 1) {
				return BMSR_LSTATUS;
			} else {
				dprintk("SIOCETHTOOL shows link down\n");
				return 0;
			}
		}
	}

	/*
	 * If reporting, report that either there's no dev->do_ioctl,
	 * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we
	 * or both SIOCGMIIREG and get_link failed (meaning that we
	 * cannot report link status).  If not reporting, pretend
	 * we're ok.
	 */
+0 −3
Original line number Diff line number Diff line
@@ -668,9 +668,6 @@ int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
		if (real_dev->do_ioctl && netif_device_present(real_dev))
			err = real_dev->do_ioctl(real_dev, &ifrr, cmd);
		break;

	case SIOCETHTOOL:
		err = dev_ethtool(&ifrr);
	}

	if (!err)
+15 −26
Original line number Diff line number Diff line
@@ -29,25 +29,13 @@
 * Determine initial path cost based on speed.
 * using recommendations from 802.1d standard
 *
 * Need to simulate user ioctl because not all device's that support
 * ethtool, use ethtool_ops.  Also, since driver might sleep need to
 * not be holding any locks.
 * Since driver might sleep need to not be holding any locks.
 */
static int port_cost(struct net_device *dev)
{
	if (dev->ethtool_ops->get_settings) {
		struct ethtool_cmd ecmd = { ETHTOOL_GSET };
	struct ifreq ifr;
	mm_segment_t old_fs;
	int err;

	strncpy(ifr.ifr_name, dev->name, IFNAMSIZ);
	ifr.ifr_data = (void __user *) &ecmd;

	old_fs = get_fs();
	set_fs(KERNEL_DS);
	err = dev_ethtool(&ifr);
	set_fs(old_fs);

		int err = dev->ethtool_ops->get_settings(dev, &ecmd);
		if (!err) {
			switch(ecmd.speed) {
			case SPEED_100:
@@ -60,6 +48,7 @@ static int port_cost(struct net_device *dev)
				return 100;
			}
		}
	}

	/* Old silly heuristics based on name */
	if (!strncmp(dev->name, "lec", 3))
+7 −14
Original line number Diff line number Diff line
@@ -3,10 +3,12 @@
 * Copyright (c) 2003 Matthew Wilcox <matthew@wil.cx>
 *
 * This file is where we call all the ethtool_ops commands to get
 * the information ethtool needs.  We fall back to calling do_ioctl()
 * for drivers which haven't been converted to ethtool_ops yet.
 * the information ethtool needs.
 *
 * It's GPL, stupid.
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <linux/module.h>
@@ -821,7 +823,7 @@ int dev_ethtool(struct ifreq *ifr)
		return -ENODEV;

	if (!dev->ethtool_ops)
		goto ioctl;
		return -EOPNOTSUPP;

	if (copy_from_user(&ethcmd, useraddr, sizeof (ethcmd)))
		return -EFAULT;
@@ -970,15 +972,6 @@ int dev_ethtool(struct ifreq *ifr)
		netdev_features_change(dev);

	return rc;

 ioctl:
	/* Keep existing behaviour for the moment.	 */
	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (dev->do_ioctl)
		return dev->do_ioctl(dev, ifr, SIOCETHTOOL);
	return -EOPNOTSUPP;
}

EXPORT_SYMBOL(dev_ethtool);