From 296ceaae9574d7bac52686106892b0476d3b6764 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 1 Sep 2003 09:05:15 -0400 Subject: [PATCH] [netdrvr] ethtool_ops for epic100, fealnx, winbond-840, via-rhine --- drivers/net/epic100.c | 145 +++++++++++++--------------- drivers/net/fealnx.c | 141 +++++++++++++-------------- drivers/net/tulip/winbond-840.c | 133 ++++++++++++-------------- drivers/net/via-rhine.c | 164 +++++++++++++++----------------- 4 files changed, 272 insertions(+), 311 deletions(-) diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index da86ea07fc7c5..93fdb1469a0cd 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -362,6 +362,7 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); static int epic_rx(struct net_device *dev); static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int epic_close(struct net_device *dev); static struct net_device_stats *epic_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); @@ -539,6 +540,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, dev->get_stats = &epic_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->watchdog_timeo = TX_TIMEOUT; dev->tx_timeout = &epic_tx_timeout; @@ -1361,82 +1363,73 @@ static void set_rx_mode(struct net_device *dev) return; } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct epic_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); - return -EOPNOTSUPP; + return rc; } +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct epic_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct epic_private *np = dev->priv; + return mii_link_ok(&np->mii); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct epic_private *np = dev->priv; @@ -1450,16 +1443,10 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL); } - /* ethtool commands */ - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - /* all other ioctls (the SIOC[GS]MIIxxx ioctls) */ - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + /* all non-ethtool ioctls (the SIOC[GS]MIIxxx ioctls) */ + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); /* power-down, if interface is down */ if (! netif_running(dev)) { diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 3b2d473feedd4..d2c1283cc5965 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -443,6 +443,7 @@ static int netdev_rx(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); static void reset_rx_descriptors(struct net_device *dev); @@ -667,6 +668,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev, dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &mii_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1760,82 +1762,72 @@ static void set_rx_mode(struct net_device *dev) writel(np->crvalue, ioaddr + TCRRCR); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user (ðcmd, useraddr, sizeof (ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; - return -EOPNOTSUPP; + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii); } +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -1846,14 +1838,9 @@ static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index 42dee7a5d4233..76056f5ae6710 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -392,6 +392,7 @@ static u32 __set_rx_mode(struct net_device *dev); static void set_rx_mode(struct net_device *dev); static struct net_device_stats *get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int netdev_close(struct net_device *dev); @@ -482,6 +483,7 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, dev->get_stats = &get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = &tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; @@ -1452,88 +1454,79 @@ static void set_rx_mode(struct net_device *dev) spin_unlock_irq(&np->lock); } -static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pci_dev)); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - } - - return -EOPNOTSUPP; +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; } +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_nway_restart(&np->mii_if); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; +} + +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; struct netdev_private *np = dev->priv; switch(cmd) { - case SIOCETHTOOL: - return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); case SIOCGMIIPHY: /* Get address of MII PHY in use. */ data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; /* Fall Through */ diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index b4fa9c684a452..c247af6bf6ad0 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -547,6 +547,7 @@ static void via_rhine_error(struct net_device *dev, int intr_status); static void via_rhine_set_rx_mode(struct net_device *dev); static struct net_device_stats *via_rhine_get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); +static struct ethtool_ops netdev_ethtool_ops; static int via_rhine_close(struct net_device *dev); static inline u32 get_intr_status(struct net_device *dev) @@ -780,6 +781,7 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev, dev->get_stats = via_rhine_get_stats; dev->set_multicast_list = via_rhine_set_rx_mode; dev->do_ioctl = netdev_ioctl; + dev->ethtool_ops = &netdev_ethtool_ops; dev->tx_timeout = via_rhine_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; if (np->drv_flags & ReqTxAlign) @@ -1741,90 +1743,87 @@ static void via_rhine_set_rx_mode(struct net_device *dev) writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); } -static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr) +static void netdev_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info) { struct netdev_private *np = dev->priv; - u32 ethcmd; - - if (get_user(ethcmd, (u32 *)useraddr)) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO }; - strcpy (info.driver, DRV_NAME); - strcpy (info.version, DRV_VERSION); - strcpy (info.bus_info, pci_name(np->pdev)); - if (copy_to_user (useraddr, &info, sizeof (info))) - return -EFAULT; - return 0; - } - /* get settings */ - case ETHTOOL_GSET: { - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; - if (!(np->drv_flags & CanHaveMII)) - break; - spin_lock_irq(&np->lock); - mii_ethtool_gset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) - return -EFAULT; - return 0; - } - /* set settings */ - case ETHTOOL_SSET: { - int r; - struct ethtool_cmd ecmd; - if (!(np->drv_flags & CanHaveMII)) - break; - if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) - return -EFAULT; - spin_lock_irq(&np->lock); - r = mii_ethtool_sset(&np->mii_if, &ecmd); - spin_unlock_irq(&np->lock); - return r; - } - /* restart autonegotiation */ - case ETHTOOL_NWAY_RST: { - if (!(np->drv_flags & CanHaveMII)) - break; - return mii_nway_restart(&np->mii_if); - } - /* get link status */ - case ETHTOOL_GLINK: { - struct ethtool_value edata = {ETHTOOL_GLINK}; - if (!(np->drv_flags & CanHaveMII)) - break; - edata.data = mii_link_ok(&np->mii_if); - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } + strcpy (info->driver, DRV_NAME); + strcpy (info->version, DRV_VERSION); + strcpy (info->bus_info, pci_name(np->pdev)); +} - /* get message-level */ - case ETHTOOL_GMSGLVL: { - struct ethtool_value edata = {ETHTOOL_GMSGLVL}; - edata.data = debug; - if (copy_to_user(useraddr, &edata, sizeof(edata))) - return -EFAULT; - return 0; - } - /* set message-level */ - case ETHTOOL_SMSGLVL: { - struct ethtool_value edata; - if (copy_from_user(&edata, useraddr, sizeof(edata))) - return -EFAULT; - debug = edata.data; - return 0; - } - default: - break; - } +static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + spin_lock_irq(&np->lock); + rc = mii_ethtool_gset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct netdev_private *np = dev->priv; + int rc; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; - return -EOPNOTSUPP; + spin_lock_irq(&np->lock); + rc = mii_ethtool_sset(&np->mii_if, cmd); + spin_unlock_irq(&np->lock); + + return rc; +} + +static int netdev_nway_reset(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (!(np->drv_flags & CanHaveMII)) + return -EINVAL; + + return mii_nway_restart(&np->mii_if); +} + +static u32 netdev_get_link(struct net_device *dev) +{ + struct netdev_private *np = dev->priv; + + if (!(np->drv_flags & CanHaveMII)) + return 0; /* -EINVAL */ + + return mii_link_ok(&np->mii_if); +} + +static u32 netdev_get_msglevel(struct net_device *dev) +{ + return debug; +} + +static void netdev_set_msglevel(struct net_device *dev, u32 value) +{ + debug = value; } +static struct ethtool_ops netdev_ethtool_ops = { + .get_drvinfo = netdev_get_drvinfo, + .get_settings = netdev_get_settings, + .set_settings = netdev_set_settings, + .nway_reset = netdev_nway_reset, + .get_link = netdev_get_link, + .get_msglevel = netdev_get_msglevel, + .set_msglevel = netdev_set_msglevel, + .get_sg = ethtool_op_get_sg, + .get_tx_csum = ethtool_op_get_tx_csum, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct netdev_private *np = dev->priv; @@ -1834,14 +1833,9 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); - - else { - spin_lock_irq(&np->lock); - rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); - spin_unlock_irq(&np->lock); - } + spin_lock_irq(&np->lock); + rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); + spin_unlock_irq(&np->lock); return rc; } -- 2.53.0