Commit ceaade5e authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jeff Garzik

Add ETHTOOL_GDRVINFO ioctl support to several pcmcia net drivers,

and one USB net driver:  3c574_cs, ibmtr_cs, pcnet_cs, ray_cs,
xirc2ps_cs, xircom_cb, and usb/net/kaweth
parent 8fee88bd
...@@ -86,6 +86,8 @@ earlier 3Com products. ...@@ -86,6 +86,8 @@ earlier 3Com products.
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <pcmcia/version.h> #include <pcmcia/version.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
...@@ -1189,6 +1191,26 @@ static int el3_rx(struct net_device *dev, int worklimit) ...@@ -1189,6 +1191,26 @@ static int el3_rx(struct net_device *dev, int worklimit)
return worklimit; return worklimit;
} }
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "3c574_cs", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
/* Provide ioctl() calls to examine the MII xcvr state. */ /* Provide ioctl() calls to examine the MII xcvr state. */
static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
...@@ -1202,6 +1224,8 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1202,6 +1224,8 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
data[0], data[1], data[2], data[3]); data[0], data[1], data[2], data[3]);
switch(cmd) { switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *)rq->ifr_data);
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = phy; data[0] = phy;
case SIOCDEVPRIVATE+1: /* Read the specified MII register. */ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
......
...@@ -53,6 +53,8 @@ ...@@ -53,6 +53,8 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -164,6 +166,37 @@ static void cs_error(client_handle_t handle, int func, int ret) ...@@ -164,6 +166,37 @@ static void cs_error(client_handle_t handle, int func, int ret)
CardServices(ReportError, handle, &err); CardServices(ReportError, handle, &err);
} }
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "ibmtr_cs", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
static int private_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;
}
}
/*====================================================================== /*======================================================================
ibmtr_attach() creates an "instance" of the driver, allocating ibmtr_attach() creates an "instance" of the driver, allocating
...@@ -216,6 +249,7 @@ static dev_link_t *ibmtr_attach(void) ...@@ -216,6 +249,7 @@ static dev_link_t *ibmtr_attach(void)
link->irq.Instance = info->dev = dev; link->irq.Instance = info->dev = dev;
dev->init = &ibmtr_probe; dev->init = &ibmtr_probe;
dev->do_ioctl = &private_ioctl;
/* Register with Card Services */ /* Register with Card Services */
link->next = dev_list; link->next = dev_list;
......
...@@ -37,9 +37,11 @@ ...@@ -37,9 +37,11 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <../drivers/net/8390.h> #include <../drivers/net/8390.h>
...@@ -115,6 +117,7 @@ static int pcnet_event(event_t event, int priority, ...@@ -115,6 +117,7 @@ static int pcnet_event(event_t event, int priority,
static int pcnet_open(struct net_device *dev); static int pcnet_open(struct net_device *dev);
static int pcnet_close(struct net_device *dev); static int pcnet_close(struct net_device *dev);
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd);
static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs); static void ei_irq_wrapper(int irq, void *dev_id, struct pt_regs *regs);
static void ei_watchdog(u_long arg); static void ei_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev); static void pcnet_reset_8390(struct net_device *dev);
...@@ -772,8 +775,10 @@ static void pcnet_config(dev_link_t *link) ...@@ -772,8 +775,10 @@ static void pcnet_config(dev_link_t *link)
dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id); dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
if (info->pna_phy) if (info->pna_phy)
printk("PNA, "); printk("PNA, ");
} else } else {
printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name); printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
dev->do_ioctl = &do_ioctl_light;
}
printk("io %#3lx, irq %d,", dev->base_addr, dev->irq); printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
if (info->flags & USE_SHMEM) if (info->flags & USE_SHMEM)
printk (" mem %#5lx,", dev->mem_start); printk (" mem %#5lx,", dev->mem_start);
...@@ -1206,12 +1211,37 @@ static void ei_watchdog(u_long arg) ...@@ -1206,12 +1211,37 @@ static void ei_watchdog(u_long arg)
/*====================================================================*/ /*====================================================================*/
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "pcnet_cs", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
/*====================================================================*/
static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
pcnet_dev_t *info = (pcnet_dev_t *)dev; pcnet_dev_t *info = (pcnet_dev_t *)dev;
u16 *data = (u16 *)&rq->ifr_data; u16 *data = (u16 *)&rq->ifr_data;
ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO; ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
switch (cmd) { switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCDEVPRIVATE: case SIOCDEVPRIVATE:
data[0] = info->phy_id; data[0] = info->phy_id;
case SIOCDEVPRIVATE+1: case SIOCDEVPRIVATE+1:
...@@ -1228,6 +1258,17 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1228,6 +1258,17 @@ static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/*====================================================================*/ /*====================================================================*/
static int do_ioctl_light(struct net_device *dev, struct ifreq *rq, int cmd)
{
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
}
return -EOPNOTSUPP;
}
/*====================================================================*/
static void dma_get_8390_hdr(struct net_device *dev, static void dma_get_8390_hdr(struct net_device *dev,
struct e8390_pkt_hdr *hdr, struct e8390_pkt_hdr *hdr,
int ring_page) int ring_page)
......
...@@ -48,6 +48,8 @@ ...@@ -48,6 +48,8 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <pcmcia/version.h> #include <pcmcia/version.h>
#include <pcmcia/cs_types.h> #include <pcmcia/cs_types.h>
...@@ -1224,7 +1226,32 @@ AP to AP 1 1 dest AP src AP dest source ...@@ -1224,7 +1226,32 @@ AP to AP 1 1 dest AP src AP dest source
} }
} }
} /* end encapsulate_frame */ } /* end encapsulate_frame */
/*===========================================================================*/ /*===========================================================================*/
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "ray_cs", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
/*====================================================================*/
static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{ {
ray_dev_t *local = (ray_dev_t *)dev->priv; ray_dev_t *local = (ray_dev_t *)dev->priv;
...@@ -1242,6 +1269,10 @@ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ...@@ -1242,6 +1269,10 @@ static int ray_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
/* Validate the command */ /* Validate the command */
switch (cmd) switch (cmd)
{ {
case SIOCETHTOOL:
err = netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data);
break;
#if WIRELESS_EXT > 7 #if WIRELESS_EXT > 7
/* --------------- WIRELESS EXTENSIONS --------------- */ /* --------------- WIRELESS EXTENSIONS --------------- */
/* Get name */ /* Get name */
......
...@@ -74,9 +74,11 @@ ...@@ -74,9 +74,11 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/in.h> #include <linux/in.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/ethtool.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/uaccess.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
...@@ -1715,6 +1717,26 @@ do_open(struct net_device *dev) ...@@ -1715,6 +1717,26 @@ do_open(struct net_device *dev)
return 0; return 0;
} }
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "xirc2ps_cs", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
static int static int
do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{ {
...@@ -1730,6 +1752,8 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ...@@ -1730,6 +1752,8 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return -EOPNOTSUPP; return -EOPNOTSUPP;
switch(cmd) { switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = 0; /* we have only this address */ data[0] = 0; /* we have only this address */
/* fall trough */ /* fall trough */
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -176,6 +178,37 @@ static void print_binary(unsigned int number) ...@@ -176,6 +178,37 @@ static void print_binary(unsigned int number)
} }
#endif #endif
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "xircom_cb", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
static int private_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;
}
}
/* xircom_probe is the code that gets called on device insertion. /* xircom_probe is the code that gets called on device insertion.
it sets up the hardware and registers the device to the networklayer. it sets up the hardware and registers the device to the networklayer.
...@@ -265,6 +298,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ ...@@ -265,6 +298,7 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_
dev->stop = &xircom_close; dev->stop = &xircom_close;
dev->get_stats = &xircom_get_stats; dev->get_stats = &xircom_get_stats;
dev->priv = private; dev->priv = private;
dev->do_ioctl = &private_ioctl;
pdev->driver_data = dev; pdev->driver_data = dev;
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
...@@ -638,11 +640,35 @@ static int kaweth_close(struct net_device *net) ...@@ -638,11 +640,35 @@ static int kaweth_close(struct net_device *net)
return 0; return 0;
} }
static int netdev_ethtool_ioctl(struct net_device *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};
strncpy(info.driver, "kaweth", sizeof(info.driver)-1);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
}
/**************************************************************** /****************************************************************
* kaweth_ioctl * kaweth_ioctl
****************************************************************/ ****************************************************************/
static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd) static int kaweth_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
{ {
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);
}
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
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