]> git.hungrycats.org Git - linux/commitdiff
Add basic ethtool ioctl support to pcmcia net drivers
authorJeff Garzik <jgarzik@rum.normnet.org>
Wed, 6 Feb 2002 23:28:06 +0000 (18:28 -0500)
committerJeff Garzik <jgarzik@rum.normnet.org>
Wed, 6 Feb 2002 23:28:06 +0000 (18:28 -0500)
3c589_cs, aironet4500_cs, and fmvj18x_cs.

drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/aironet4500_cs.c
drivers/net/pcmcia/fmvj18x_cs.c

index 2098eab9c5a5cd3a3d5d5bc63b475b1ed2337988..a782e5d0d37960331cb7f0a175f59764e8d7ad4e 100644 (file)
@@ -17,6 +17,9 @@
 
 ======================================================================*/
 
+#define DRV_NAME       "3c589_cs"
+#define DRV_VERSION    "1.162"
+
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -28,6 +31,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
+
+#include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -134,7 +140,7 @@ MODULE_PARM(irq_list, "1-4i");
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
 static char *version =
-"3c589_cs.c 1.162 2001/10/13 00:08:50 (David Hinds)";
+DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -159,6 +165,7 @@ static int el3_rx(struct net_device *dev);
 static int el3_close(struct net_device *dev);
 static void el3_tx_timeout(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
+static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
 
 static dev_info_t dev_info = "3c589_cs";
 
@@ -249,7 +256,8 @@ static dev_link_t *tc589_attach(void)
     dev->tx_timeout = el3_tx_timeout;
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
-    
+    dev->do_ioctl = netdev_ioctl;
+
     /* Register with Card Services */
     link->next = dev_list;
     dev_list = link;
@@ -640,6 +648,71 @@ static void tc589_reset(struct net_device *dev)
         | AdapterFailure, ioaddr + EL3_CMD);
 }
 
+static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+       u32 ethcmd;
+
+       /* dev_ioctl() in ../../net/core/dev.c has already checked
+          capable(CAP_NET_ADMIN), so don't bother with that here.  */
+
+       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);
+               sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr);
+               if (copy_to_user (useraddr, &info, sizeof (info)))
+                       return -EFAULT;
+               return 0;
+       }
+
+#ifdef PCMCIA_DEBUG
+       /* get message-level */
+       case ETHTOOL_GMSGLVL: {
+               struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+               edata.data = pc_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;
+               pc_debug = edata.data;
+               return 0;
+       }
+#endif
+
+       default:
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       int rc;
+
+       switch (cmd) {
+       case SIOCETHTOOL:
+               rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+               break;
+
+       default:
+               rc = -EOPNOTSUPP;
+               break;
+       }
+
+       return rc;
+}
+
 static int el3_config(struct net_device *dev, struct ifmap *map)
 {
     if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) {
index 4c26b7f48f37d919e67e1779859970f33f6f80fb..3b0195a9010bc5c25a458154574513ba06f12c0a 100644 (file)
  *
  */
 
+#define DRV_NAME       "aironet4500_cs"
+#define DRV_VERSION    "0.1"
+
 static const char *awc_version =
-"aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
+DRV_NAME ".c v" DRV_VERSION " 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
 
 
 #include <linux/module.h>
@@ -24,6 +27,9 @@ static const char *awc_version =
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/in.h>
+#include <linux/ethtool.h>
+
+#include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -159,6 +165,66 @@ static int awc_pcmcia_close(struct net_device *dev)
        return ret;
 }
 
+static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+       u32 ethcmd;
+
+       /* dev_ioctl() in ../../net/core/dev.c has already checked
+          capable(CAP_NET_ADMIN), so don't bother with that here.  */
+
+       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);
+               sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr);
+               if (copy_to_user (useraddr, &info, sizeof (info)))
+                       return -EFAULT;
+               return 0;
+       }
+
+#ifdef PCMCIA_DEBUG
+       /* get message-level */
+       case ETHTOOL_GMSGLVL: {
+               struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+               edata.data = pc_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;
+               pc_debug = edata.data;
+               return 0;
+       }
+#endif
+
+       default:
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static int awc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       switch (cmd) {
+       case SIOCETHTOOL:
+               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+       default:
+               return -EOPNOTSUPP;
+       }
+       return 0;
+}
+
 /*
        awc_attach() creates an "instance" of the driver, allocating
        local data structures for one device.  The device is registered
@@ -230,7 +296,8 @@ static dev_link_t *awc_attach(void)
 //     dev->set_config =               &awc_config_misiganes,aga mitte awc_config;
        dev->get_stats =                &awc_get_stats;
 //     dev->set_multicast_list =       &awc_set_multicast_list;
-
+       dev->do_ioctl =                 &awc_ioctl;
+       
        strcpy(dev->name, ((struct awc_private *)dev->priv)->node.dev_name);
 
        ether_setup(dev);
index 6c47c37a0a0b22b50b8f311163abad19292f5cd1..95bc343696bfa8ce0f72b8fecc4ef4bf1d4718a2 100644 (file)
@@ -28,6 +28,9 @@
    
 ======================================================================*/
 
+#define DRV_NAME       "fmvj18x_cs"
+#define DRV_VERSION    "2.6"
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -39,6 +42,9 @@
 #include <linux/interrupt.h>
 #include <linux/in.h>
 #include <linux/delay.h>
+#include <linux/ethtool.h>
+
+#include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/system.h>
 
@@ -74,7 +80,7 @@ INT_MODULE_PARM(sram_config, 0);
 #ifdef PCMCIA_DEBUG
 INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-static char *version = "fmvj18x_cs.c 2.6 2001/09/17";
+static char *version = DRV_NAME ".c " DRV_VERSION " 2001/09/17";
 #else
 #define DEBUG(n, args...)
 #endif
@@ -104,6 +110,7 @@ static void fjn_reset(struct net_device *dev);
 static struct net_device_stats *fjn_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 static void fjn_tx_timeout(struct net_device *dev);
+static int fjn_ioctl(struct net_device *, struct ifreq *, int);
 
 static dev_info_t dev_info = "fmvj18x_cs";
 static dev_link_t *dev_list;
@@ -316,6 +323,7 @@ static dev_link_t *fmvj18x_attach(void)
     dev->tx_timeout = fjn_tx_timeout;
     dev->watchdog_timeo = TX_TIMEOUT;
 #endif
+    dev->do_ioctl = fjn_ioctl;
     
     /* Register with Card Services */
     link->next = dev_list;
@@ -1103,6 +1111,65 @@ static void fjn_rx(struct net_device *dev)
 
 /*====================================================================*/
 
+static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
+{
+       u32 ethcmd;
+
+       /* dev_ioctl() in ../../net/core/dev.c has already checked
+          capable(CAP_NET_ADMIN), so don't bother with that here.  */
+
+       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);
+               sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr);
+               if (copy_to_user (useraddr, &info, sizeof (info)))
+                       return -EFAULT;
+               return 0;
+       }
+
+#ifdef PCMCIA_DEBUG
+       /* get message-level */
+       case ETHTOOL_GMSGLVL: {
+               struct ethtool_value edata = {ETHTOOL_GMSGLVL};
+               edata.data = pc_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;
+               pc_debug = edata.data;
+               return 0;
+       }
+#endif
+
+       default:
+               break;
+       }
+
+       return -EOPNOTSUPP;
+}
+
+static int fjn_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       switch (cmd) {
+       case SIOCETHTOOL:
+               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static int fjn_config(struct net_device *dev, struct ifmap *map){
     return 0;
 }