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));
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;
}
/* get message-level */ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct epic_private *np = dev->priv;
edata.data = debug; int rc;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT; spin_lock_irq(&np->lock);
return 0; rc = mii_ethtool_gset(&np->mii, cmd);
} spin_unlock_irq(&np->lock);
/* 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; 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) 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) spin_lock_irq(&np->lock);
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
spin_unlock_irq(&np->lock);
/* 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);
}
/* 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));
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;
}
/* get message-level */ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct netdev_private *np = dev->priv;
edata.data = debug; int rc;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT; spin_lock_irq(&np->lock);
return 0; rc = mii_ethtool_gset(&np->mii, cmd);
} spin_unlock_irq(&np->lock);
/* set message-level */
case ETHTOOL_SMSGLVL: { return rc;
struct ethtool_value edata; }
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT; static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
debug = edata.data; {
return 0; struct netdev_private *np = dev->priv;
} int rc;
default:
break;
}
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) 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) spin_lock_irq(&np->lock);
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
spin_unlock_irq(&np->lock);
else {
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, data, cmd, NULL);
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));
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;
}
/* get message-level */ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct netdev_private *np = dev->priv;
edata.data = debug; int rc;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT; spin_lock_irq(&np->lock);
return 0; rc = mii_ethtool_gset(&np->mii_if, cmd);
} spin_unlock_irq(&np->lock);
/* set message-level */
case ETHTOOL_SMSGLVL: { return rc;
struct ethtool_value edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
debug = edata.data;
return 0;
}
}
return -EOPNOTSUPP;
} }
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) 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));
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;
}
/* get message-level */ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
case ETHTOOL_GMSGLVL: { {
struct ethtool_value edata = {ETHTOOL_GMSGLVL}; struct netdev_private *np = dev->priv;
edata.data = debug; int rc;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT; if (!(np->drv_flags & CanHaveMII))
return 0; return -EINVAL;
}
/* set message-level */ spin_lock_irq(&np->lock);
case ETHTOOL_SMSGLVL: { rc = mii_ethtool_gset(&np->mii_if, cmd);
struct ethtool_value edata; spin_unlock_irq(&np->lock);
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT; return rc;
debug = edata.data; }
return 0;
} static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
default: {
break; 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) 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) spin_lock_irq(&np->lock);
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data); rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
spin_unlock_irq(&np->lock);
else {
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
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