]> git.hungrycats.org Git - linux/commitdiff
Additional media-related ethtool ioctls for net drivers
authorJeff Garzik <jgarzik@rum.normnet.org>
Wed, 6 Feb 2002 23:45:09 +0000 (18:45 -0500)
committerJeff Garzik <jgarzik@rum.normnet.org>
Wed, 6 Feb 2002 23:45:09 +0000 (18:45 -0500)
ns82830, starfire.

drivers/net/ns83820.c
drivers/net/starfire.c

index 8a1187855208ddaf5312c22e9e3df3c1b637087d..1016a21105212065f05b36d0997be5c6b01abf04 100644 (file)
@@ -1,4 +1,4 @@
-#define VERSION "0.13"
+#define VERSION "0.14"
 /* ns83820.c by Benjamin LaHaise <bcrl@redhat.com>
  *
  * $Revision: 1.34.2.8 $
@@ -45,6 +45,7 @@
  *                     0.12 - add statistics counters
  *                          - add allmulti/promisc support
  *     20011009        0.13 - hotplug support, other smaller pci api cleanups
+ *     20011117        0.14 - ethtool GDRVINFO, GLINK support
  *
  * Driver Overview
  * ===============
 #include <linux/in.h>  /* for IPPROTO_... */
 #include <linux/eeprom.h>
 #include <linux/compiler.h>
+#include <linux/ethtool.h>
 //#include <linux/skbrefill.h>
 
 #include <asm/io.h>
+#include <asm/uaccess.h>
 
 /* Dprintk is used for more interesting debug events */
 #undef Dprintk
@@ -1007,6 +1010,59 @@ static struct net_device_stats *ns83820_get_stats(struct net_device *_dev)
        return &dev->stats;
 }
 
+static int ns83820_ethtool_ioctl (struct ns83820 *dev, void *useraddr)
+{
+       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, "ns83820");
+                       strcpy (info.version, VERSION);
+                       strcpy (info.bus_info, dev->pci_dev->slot_name);
+                       if (copy_to_user (useraddr, &info, sizeof (info)))
+                               return -EFAULT;
+                       return 0;
+               }
+
+       /* get link status */
+       case ETHTOOL_GLINK: {
+               struct ethtool_value edata = {ETHTOOL_GLINK};
+               u32 cfg = readl(dev->base + CFG) ^ SPDSTS_POLARITY;
+
+               if (cfg & CFG_LNKSTS)
+                       edata.data = 1;
+               else
+                       edata.data = 0;
+               if (copy_to_user(useraddr, &edata, sizeof(edata)))
+                       return -EFAULT;
+               return 0;
+       }
+
+       default:
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static int ns83820_ioctl(struct net_device *_dev, struct ifreq *rq, int cmd)
+{
+       struct ns83820 *dev = _dev->priv;
+
+       switch(cmd) {
+       case SIOCETHTOOL:
+               return ns83820_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static void ns83820_irq(int foo, void *data, struct pt_regs *regs)
 {
        struct ns83820 *dev = data;
@@ -1294,6 +1350,7 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_
        dev->net_dev.get_stats = ns83820_get_stats;
        dev->net_dev.change_mtu = ns83820_change_mtu;
        dev->net_dev.set_multicast_list = ns83820_set_multicast;
+       dev->net_dev.do_ioctl = ns83820_ioctl;
        //FIXME: dev->net_dev.tx_timeout = ns83820_tx_timeout;
 
        pci_set_drvdata(pci_dev, dev);
index 3d17fd6c2ff619b6b1b49a276aae8cdcb94dabf1..1d1c2794d4a578941cbbd81c505094ef5e505f2e 100644 (file)
        - Fixed initialization timing problems
        - Fixed interrupt mask definitions
 
+       LK1.3.5 (jgarzik)
+       - ethtool NWAY_RST, GLINK, [GS]MSGLVL support
+
 TODO:
        - implement tx_timeout() properly
 */
 
 #define DRV_NAME       "starfire"
-#define DRV_VERSION    "1.03+LK1.3.4"
-#define DRV_RELDATE    "August 14, 2001"
+#define DRV_VERSION    "1.03+LK1.3.5"
+#define DRV_RELDATE    "November 17, 2001"
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -1767,6 +1770,47 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
                return 0;
        }
 
+       /* restart autonegotiation */
+       case ETHTOOL_NWAY_RST: {
+               int tmp;
+               int r = -EINVAL;
+               /* if autoneg is off, it's an error */
+               tmp = mdio_read(dev, np->phys[0], MII_BMCR);
+               if (tmp & BMCR_ANENABLE) {
+                       tmp |= (BMCR_ANRESTART);
+                       mdio_write(dev, np->phys[0], MII_BMCR, tmp);
+                       r = 0;
+               }
+               return r;
+       }
+       /* get link status */
+       case ETHTOOL_GLINK: {
+               struct ethtool_value edata = {ETHTOOL_GLINK};
+               if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS)
+                       edata.data = 1;
+               else
+                       edata.data = 0;
+               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:
                return -EOPNOTSUPP;
        }