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.
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
......@@ -1189,6 +1191,26 @@ static int el3_rx(struct net_device *dev, int 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. */
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]);
switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *)rq->ifr_data);
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = phy;
case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
......
......@@ -53,6 +53,8 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/module.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
......@@ -164,6 +166,37 @@ static void cs_error(client_handle_t handle, int func, int ret)
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
......@@ -216,6 +249,7 @@ static dev_link_t *ibmtr_attach(void)
link->irq.Instance = info->dev = dev;
dev->init = &ibmtr_probe;
dev->do_ioctl = &private_ioctl;
/* Register with Card Services */
link->next = dev_list;
......
......@@ -37,9 +37,11 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <linux/netdevice.h>
#include <../drivers/net/8390.h>
......@@ -115,6 +117,7 @@ static int pcnet_event(event_t event, int priority,
static int pcnet_open(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 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_watchdog(u_long arg);
static void pcnet_reset_8390(struct net_device *dev);
......@@ -772,8 +775,10 @@ static void pcnet_config(dev_link_t *link)
dev->name, ((info->flags & IS_DL10022) ? 22 : 19), id);
if (info->pna_phy)
printk("PNA, ");
} else
} else {
printk(KERN_INFO "%s: NE2000 Compatible: ", dev->name);
dev->do_ioctl = &do_ioctl_light;
}
printk("io %#3lx, irq %d,", dev->base_addr, dev->irq);
if (info->flags & USE_SHMEM)
printk (" mem %#5lx,", dev->mem_start);
......@@ -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)
{
pcnet_dev_t *info = (pcnet_dev_t *)dev;
u16 *data = (u16 *)&rq->ifr_data;
ioaddr_t mii_addr = dev->base_addr + DLINK_GPIO;
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCDEVPRIVATE:
data[0] = info->phy_id;
case SIOCDEVPRIVATE+1:
......@@ -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,
struct e8390_pkt_hdr *hdr,
int ring_page)
......
......@@ -48,6 +48,8 @@
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <linux/skbuff.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
......@@ -1224,7 +1226,32 @@ AP to AP 1 1 dest AP src AP dest source
}
}
} /* 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)
{
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)
/* Validate the command */
switch (cmd)
{
case SIOCETHTOOL:
err = netdev_ethtool_ioctl(dev, (void *) ifr->ifr_data);
break;
#if WIRELESS_EXT > 7
/* --------------- WIRELESS EXTENSIONS --------------- */
/* Get name */
......
......@@ -74,9 +74,11 @@
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
......@@ -1715,6 +1717,26 @@ do_open(struct net_device *dev)
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
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;
switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
data[0] = 0; /* we have only this address */
/* fall trough */
......
......@@ -29,6 +29,8 @@
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -176,6 +178,37 @@ static void print_binary(unsigned int number)
}
#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.
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_
dev->stop = &xircom_close;
dev->get_stats = &xircom_get_stats;
dev->priv = private;
dev->do_ioctl = &private_ioctl;
pdev->driver_data = dev;
......
......@@ -55,6 +55,8 @@
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/types.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/byteorder.h>
......@@ -638,11 +640,35 @@ static int kaweth_close(struct net_device *net)
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
****************************************************************/
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;
}
......
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