Commit 296ceaae authored by Jeff Garzik's avatar Jeff Garzik

[netdrvr] ethtool_ops for epic100, fealnx, winbond-840, via-rhine

parent 9a2f7a76
...@@ -362,6 +362,7 @@ static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); ...@@ -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 int epic_rx(struct net_device *dev);
static irqreturn_t epic_interrupt(int irq, void *dev_instance, struct pt_regs *regs); 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 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 int epic_close(struct net_device *dev);
static struct net_device_stats *epic_get_stats(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); static void set_rx_mode(struct net_device *dev);
...@@ -539,6 +540,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, ...@@ -539,6 +540,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev,
dev->get_stats = &epic_get_stats; dev->get_stats = &epic_get_stats;
dev->set_multicast_list = &set_rx_mode; dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &netdev_ioctl; dev->do_ioctl = &netdev_ioctl;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
dev->tx_timeout = &epic_tx_timeout; dev->tx_timeout = &epic_tx_timeout;
...@@ -1361,82 +1363,73 @@ static void set_rx_mode(struct net_device *dev) ...@@ -1361,82 +1363,73 @@ static void set_rx_mode(struct net_device *dev)
return; 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; struct epic_private *np = dev->priv;
u32 ethcmd;
if (copy_from_user (&ethcmd, 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 */ strcpy (info->driver, DRV_NAME);
case ETHTOOL_GSET: { strcpy (info->version, DRV_VERSION);
struct ethtool_cmd ecmd = { ETHTOOL_GSET }; strcpy (info->bus_info, pci_name(np->pci_dev));
}
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); spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii, &ecmd); rc = mii_ethtool_gset(&np->mii, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT; return rc;
return 0; }
}
/* set settings */ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_SSET: { {
int r; struct epic_private *np = dev->priv;
struct ethtool_cmd ecmd; int rc;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii, &ecmd); rc = mii_ethtool_sset(&np->mii, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
return r;
} return rc;
/* restart autonegotiation */ }
case ETHTOOL_NWAY_RST: {
static int netdev_nway_reset(struct net_device *dev)
{
struct epic_private *np = dev->priv;
return mii_nway_restart(&np->mii); 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;
}
/* get message-level */ static u32 netdev_get_link(struct net_device *dev)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct epic_private *np = dev->priv;
edata.data = debug; return mii_link_ok(&np->mii);
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;
}
return -EOPNOTSUPP; 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) static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
struct epic_private *np = dev->priv; struct epic_private *np = dev->priv;
...@@ -1450,16 +1443,10 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -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); outl((inl(ioaddr + NVCTL) & ~0x003C) | 0x4800, ioaddr + NVCTL);
} }
/* ethtool commands */ /* all non-ethtool ioctls (the SIOC[GS]MIIxxx ioctls) */
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); spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
}
/* power-down, if interface is down */ /* power-down, if interface is down */
if (! netif_running(dev)) { if (! netif_running(dev)) {
......
...@@ -443,6 +443,7 @@ static int netdev_rx(struct net_device *dev); ...@@ -443,6 +443,7 @@ static int netdev_rx(struct net_device *dev);
static void 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 struct net_device_stats *get_stats(struct net_device *dev);
static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 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 int netdev_close(struct net_device *dev);
static void reset_rx_descriptors(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, ...@@ -667,6 +668,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
dev->get_stats = &get_stats; dev->get_stats = &get_stats;
dev->set_multicast_list = &set_rx_mode; dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &mii_ioctl; dev->do_ioctl = &mii_ioctl;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->tx_timeout = tx_timeout; dev->tx_timeout = tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
...@@ -1760,82 +1762,72 @@ static void set_rx_mode(struct net_device *dev) ...@@ -1760,82 +1762,72 @@ static void set_rx_mode(struct net_device *dev)
writel(np->crvalue, ioaddr + TCRRCR); 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; struct netdev_private *np = dev->priv;
u32 ethcmd;
if (copy_from_user (&ethcmd, 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 */ strcpy (info->driver, DRV_NAME);
case ETHTOOL_GSET: { strcpy (info->version, DRV_VERSION);
struct ethtool_cmd ecmd = { ETHTOOL_GSET }; strcpy (info->bus_info, pci_name(np->pci_dev));
}
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); spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii, &ecmd); rc = mii_ethtool_gset(&np->mii, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT; return rc;
return 0; }
}
/* set settings */ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_SSET: { {
int r; struct netdev_private *np = dev->priv;
struct ethtool_cmd ecmd; int rc;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii, &ecmd); rc = mii_ethtool_sset(&np->mii, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
return r;
} return rc;
/* restart autonegotiation */ }
case ETHTOOL_NWAY_RST: {
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
return mii_nway_restart(&np->mii); 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;
}
/* get message-level */ static u32 netdev_get_link(struct net_device *dev)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct netdev_private *np = dev->priv;
edata.data = debug; return mii_link_ok(&np->mii);
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;
}
return -EOPNOTSUPP; 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) 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) ...@@ -1846,14 +1838,9 @@ static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!netif_running(dev)) if (!netif_running(dev))
return -EINVAL; return -EINVAL;
if (cmd == SIOCETHTOOL)
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
else {
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, data, cmd, NULL); rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
}
return rc; return rc;
} }
......
...@@ -392,6 +392,7 @@ static u32 __set_rx_mode(struct net_device *dev); ...@@ -392,6 +392,7 @@ static u32 __set_rx_mode(struct net_device *dev);
static void 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 struct net_device_stats *get_stats(struct net_device *dev);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 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); static int netdev_close(struct net_device *dev);
...@@ -482,6 +483,7 @@ static int __devinit w840_probe1 (struct pci_dev *pdev, ...@@ -482,6 +483,7 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
dev->get_stats = &get_stats; dev->get_stats = &get_stats;
dev->set_multicast_list = &set_rx_mode; dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = &netdev_ioctl; dev->do_ioctl = &netdev_ioctl;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->tx_timeout = &tx_timeout; dev->tx_timeout = &tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
...@@ -1452,88 +1454,79 @@ static void set_rx_mode(struct net_device *dev) ...@@ -1452,88 +1454,79 @@ static void set_rx_mode(struct net_device *dev)
spin_unlock_irq(&np->lock); 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; struct netdev_private *np = dev->priv;
u32 ethcmd;
if (copy_from_user(&ethcmd, 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 */ strcpy (info->driver, DRV_NAME);
case ETHTOOL_GSET: { strcpy (info->version, DRV_VERSION);
struct ethtool_cmd ecmd = { ETHTOOL_GSET }; strcpy (info->bus_info, pci_name(np->pci_dev));
}
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); spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii_if, &ecmd); rc = mii_ethtool_gset(&np->mii_if, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT; return rc;
return 0; }
}
/* set settings */ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_SSET: { {
int r; struct netdev_private *np = dev->priv;
struct ethtool_cmd ecmd; int rc;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii_if, &ecmd); rc = mii_ethtool_sset(&np->mii_if, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
return r;
} return rc;
/* restart autonegotiation */ }
case ETHTOOL_NWAY_RST: {
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
return mii_nway_restart(&np->mii_if); 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;
}
/* get message-level */ static u32 netdev_get_link(struct net_device *dev)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct netdev_private *np = dev->priv;
edata.data = debug; return mii_link_ok(&np->mii_if);
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 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) 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 mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
struct netdev_private *np = dev->priv; struct netdev_private *np = dev->priv;
switch(cmd) { switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f; data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */ /* Fall Through */
......
...@@ -547,6 +547,7 @@ static void via_rhine_error(struct net_device *dev, int intr_status); ...@@ -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 void via_rhine_set_rx_mode(struct net_device *dev);
static struct net_device_stats *via_rhine_get_stats(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 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 int via_rhine_close(struct net_device *dev);
static inline u32 get_intr_status(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, ...@@ -780,6 +781,7 @@ static int __devinit via_rhine_init_one (struct pci_dev *pdev,
dev->get_stats = via_rhine_get_stats; dev->get_stats = via_rhine_get_stats;
dev->set_multicast_list = via_rhine_set_rx_mode; dev->set_multicast_list = via_rhine_set_rx_mode;
dev->do_ioctl = netdev_ioctl; dev->do_ioctl = netdev_ioctl;
dev->ethtool_ops = &netdev_ethtool_ops;
dev->tx_timeout = via_rhine_tx_timeout; dev->tx_timeout = via_rhine_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT; dev->watchdog_timeo = TX_TIMEOUT;
if (np->drv_flags & ReqTxAlign) if (np->drv_flags & ReqTxAlign)
...@@ -1741,90 +1743,87 @@ static void via_rhine_set_rx_mode(struct net_device *dev) ...@@ -1741,90 +1743,87 @@ static void via_rhine_set_rx_mode(struct net_device *dev)
writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig); 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; 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 */ strcpy (info->driver, DRV_NAME);
case ETHTOOL_GSET: { strcpy (info->version, DRV_VERSION);
struct ethtool_cmd ecmd = { ETHTOOL_GSET }; strcpy (info->bus_info, pci_name(np->pdev));
}
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)) if (!(np->drv_flags & CanHaveMII))
break; return -EINVAL;
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii_if, &ecmd); rc = mii_ethtool_gset(&np->mii_if, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT; return rc;
return 0; }
}
/* set settings */ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_SSET: { {
int r; struct netdev_private *np = dev->priv;
struct ethtool_cmd ecmd; int rc;
if (!(np->drv_flags & CanHaveMII)) if (!(np->drv_flags & CanHaveMII))
break; return -EINVAL;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii_if, &ecmd); rc = mii_ethtool_sset(&np->mii_if, cmd);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
return r;
} return rc;
/* restart autonegotiation */ }
case ETHTOOL_NWAY_RST: {
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
if (!(np->drv_flags & CanHaveMII)) if (!(np->drv_flags & CanHaveMII))
break; return -EINVAL;
return mii_nway_restart(&np->mii_if); return mii_nway_restart(&np->mii_if);
} }
/* get link status */
case ETHTOOL_GLINK: { static u32 netdev_get_link(struct net_device *dev)
struct ethtool_value edata = {ETHTOOL_GLINK}; {
struct netdev_private *np = dev->priv;
if (!(np->drv_flags & CanHaveMII)) if (!(np->drv_flags & CanHaveMII))
break; return 0; /* -EINVAL */
edata.data = mii_link_ok(&np->mii_if);
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
/* get message-level */ return mii_link_ok(&np->mii_if);
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;
}
return -EOPNOTSUPP; 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) static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
struct netdev_private *np = dev->priv; struct netdev_private *np = dev->priv;
...@@ -1834,14 +1833,9 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1834,14 +1833,9 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!netif_running(dev)) if (!netif_running(dev))
return -EINVAL; return -EINVAL;
if (cmd == SIOCETHTOOL)
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
else {
spin_lock_irq(&np->lock); spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL); rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
spin_unlock_irq(&np->lock); spin_unlock_irq(&np->lock);
}
return rc; return rc;
} }
......
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