Commit 386e9189 authored by Jeff Garzik's avatar Jeff Garzik

Merge basic ethtool ioctl support from 2.4.x for 3c505 and sis900

net drivers.  Merge two sis900 bug fixes from 2.4.x.

Via Dave Jones.
parent 063b805f
...@@ -1160,6 +1160,87 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev) ...@@ -1160,6 +1160,87 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
return &adapter->stats; return &adapter->stats;
} }
/**
* netdev_ethtool_ioctl: Handle network interface SIOCETHTOOL ioctls
* @dev: network interface on which out-of-band action is to be performed
* @useraddr: userspace address to which data is to be read and returned
*
* Process the various commands of the SIOCETHTOOL interface.
*/
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, "ISA 0x%lx", dev->base_addr);
if (copy_to_user (useraddr, &info, sizeof (info)))
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;
}
return -EOPNOTSUPP;
}
/**
* netdev_ioctl: Handle network interface ioctls
* @dev: network interface on which out-of-band action is to be performed
* @rq: user request data
* @cmd: command issued by user
*
* Process the various out-of-band ioctls passed to this driver.
*/
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{
int rc = 0;
switch (cmd) {
case SIOCETHTOOL:
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
break;
default:
rc = -EOPNOTSUPP;
break;
}
return rc;
}
/****************************************************** /******************************************************
* *
* close the board * close the board
......
...@@ -18,7 +18,8 @@ ...@@ -18,7 +18,8 @@
preliminary Rev. 1.0 Jan. 18, 1998 preliminary Rev. 1.0 Jan. 18, 1998
http://www.sis.com.tw/support/databook.htm http://www.sis.com.tw/support/databook.htm
Rev 1.08.02 Jan. 4 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function Rev 1.08.02 Nov. 30 2001 Hui-Fen Hsu workaround for EDB & bug fix for dhcp problem
Jan. 4 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix Rev 1.08.00 Jun. 11 2001 Hui-Fen Hsu workaround for RTL8201 PHY and some bug fix
Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3 Rev 1.07.11 Apr. 2 2001 Hui-Fen Hsu updates PCI drivers to use the new pci_set_dma_mask for kernel 2.4.3
...@@ -56,19 +57,24 @@ ...@@ -56,19 +57,24 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
#include <asm/processor.h> /* Processor type for cache alignment. */ #include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/delay.h> #include <asm/uaccess.h> /* User space memory access functions */
#include <linux/crc32.h>
#include "sis900.h" #include "sis900.h"
#define SIS900_MODULE_NAME "sis900"
#define SIS900_DRV_VERSION "v1.08.02 1/4/2002"
static char version[] __devinitdata = static char version[] __devinitdata =
KERN_INFO "sis900.c: v1.08.02 1/4/2002\n"; KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
static int max_interrupt_work = 40; static int max_interrupt_work = 40;
static int multicast_filter_limit = 128; static int multicast_filter_limit = 128;
...@@ -872,6 +878,9 @@ sis900_open(struct net_device *net_dev) ...@@ -872,6 +878,9 @@ sis900_open(struct net_device *net_dev)
netif_start_queue(net_dev); netif_start_queue(net_dev);
/* Workaround for EDB */
sis900_set_mode(ioaddr, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
/* Enable all known interrupts by setting the interrupt mask. */ /* Enable all known interrupts by setting the interrupt mask. */
outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr); outl((RxSOVR|RxORN|RxERR|RxOK|TxURN|TxERR|TxIDLE), ioaddr + imr);
outl(RxENA | inl(ioaddr + cr), ioaddr + cr); outl(RxENA | inl(ioaddr + cr), ioaddr + cr);
...@@ -1128,6 +1137,7 @@ static void sis900_timer(unsigned long data) ...@@ -1128,6 +1137,7 @@ static void sis900_timer(unsigned long data)
sis900_set_mode(net_dev->base_addr, speed, duplex); sis900_set_mode(net_dev->base_addr, speed, duplex);
pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision); pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
sis630_set_eq(net_dev, revision); sis630_set_eq(net_dev, revision);
netif_start_queue(net_dev);
} }
sis_priv->timer.expires = jiffies + HZ; sis_priv->timer.expires = jiffies + HZ;
...@@ -1411,6 +1421,12 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev) ...@@ -1411,6 +1421,12 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
unsigned int entry; unsigned int entry;
unsigned long flags; unsigned long flags;
/* Don't transmit data before the complete of auto-negotiation */
if(!sis_priv->autong_complete){
netif_stop_queue(net_dev);
return 1;
}
spin_lock_irqsave(&sis_priv->lock, flags); spin_lock_irqsave(&sis_priv->lock, flags);
/* Calculate the next Tx descriptor entry. */ /* Calculate the next Tx descriptor entry. */
...@@ -1768,6 +1784,40 @@ sis900_close(struct net_device *net_dev) ...@@ -1768,6 +1784,40 @@ sis900_close(struct net_device *net_dev)
return 0; return 0;
} }
/**
* netdev_ethtool_ioctl: - For the basic support of ethtool
* @net_dev: the net device to command for
* @useraddr: start address of interface request
*
* Process ethtool command such as "ehtool -i" to show information
*/
static int netdev_ethtool_ioctl (struct net_device *net_dev, void *useraddr)
{
struct sis900_private *sis_priv = net_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, SIS900_MODULE_NAME);
strcpy (info.version, SIS900_DRV_VERSION);
strcpy (info.bus_info, sis_priv->pci_dev->slot_name);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
default:
break;
}
return -EOPNOTSUPP;
}
/** /**
* mii_ioctl: - process MII i/o control command * mii_ioctl: - process MII i/o control command
* @net_dev: the net device to command for * @net_dev: the net device to command for
...@@ -1783,6 +1833,9 @@ static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd) ...@@ -1783,6 +1833,9 @@ static int mii_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data; struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
switch(cmd) { switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(net_dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */ case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = sis_priv->mii->phy_addr; data->phy_id = sis_priv->mii->phy_addr;
/* Fall Through */ /* Fall Through */
...@@ -2072,8 +2125,6 @@ static void __devexit sis900_remove(struct pci_dev *pci_dev) ...@@ -2072,8 +2125,6 @@ static void __devexit sis900_remove(struct pci_dev *pci_dev)
pci_set_drvdata(pci_dev, NULL); pci_set_drvdata(pci_dev, NULL);
} }
#define SIS900_MODULE_NAME "sis900"
static struct pci_driver sis900_pci_driver = { static struct pci_driver sis900_pci_driver = {
name: SIS900_MODULE_NAME, name: SIS900_MODULE_NAME,
id_table: sis900_pci_tbl, id_table: sis900_pci_tbl,
......
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