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);
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 (&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 */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
strcpy (info->driver, DRV_NAME);
strcpy (info->version, DRV_VERSION);
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);
mii_ethtool_gset(&np->mii, &ecmd);
rc = mii_ethtool_gset(&np->mii, cmd);
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;
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);
r = mii_ethtool_sset(&np->mii, &ecmd);
rc = mii_ethtool_sset(&np->mii, cmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return rc;
}
static int netdev_nway_reset(struct net_device *dev)
{
struct epic_private *np = dev->priv;
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 */
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 u32 netdev_get_link(struct net_device *dev)
{
struct epic_private *np = dev->priv;
return mii_link_ok(&np->mii);
}
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)
{
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 {
/* 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)) {
......
......@@ -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 (&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 */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
strcpy (info->driver, DRV_NAME);
strcpy (info->version, DRV_VERSION);
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);
mii_ethtool_gset(&np->mii, &ecmd);
rc = mii_ethtool_gset(&np->mii, cmd);
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;
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);
r = mii_ethtool_sset(&np->mii, &ecmd);
rc = mii_ethtool_sset(&np->mii, cmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return rc;
}
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
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 */
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 u32 netdev_get_link(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
return mii_link_ok(&np->mii);
}
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)
{
......@@ -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);
}
return rc;
}
......
......@@ -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(&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 */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
strcpy (info->driver, DRV_NAME);
strcpy (info->version, DRV_VERSION);
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);
mii_ethtool_gset(&np->mii_if, &ecmd);
rc = mii_ethtool_gset(&np->mii_if, cmd);
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;
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);
r = mii_ethtool_sset(&np->mii_if, &ecmd);
rc = mii_ethtool_sset(&np->mii_if, cmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return rc;
}
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
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 */
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;
}
}
static u32 netdev_get_link(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
return mii_link_ok(&np->mii_if);
}
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)
{
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 */
......
......@@ -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 };
strcpy (info->driver, DRV_NAME);
strcpy (info->version, DRV_VERSION);
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))
break;
return -EINVAL;
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);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
int r;
struct ethtool_cmd ecmd;
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))
break;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
return -EINVAL;
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);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return rc;
}
static int netdev_nway_reset(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
if (!(np->drv_flags & CanHaveMII))
break;
return -EINVAL;
return mii_nway_restart(&np->mii_if);
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
}
static u32 netdev_get_link(struct net_device *dev)
{
struct netdev_private *np = dev->priv;
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;
}
return 0; /* -EINVAL */
/* 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;
}
return mii_link_ok(&np->mii_if);
}
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)
{
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);
}
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