Commit 3ba2a466 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/home/axboe/linus-merge-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 2adf779d 16c7c780
......@@ -96,7 +96,10 @@ AT-2500TX 10/100 PCI Fast Ethernet Network Adapter Card
KTI KF-230TX
KTI KF-230TX/2
Lantech FastNet TX
Ovislink Fast Ethernet
Planet ENW-9504 (V.4) 10/100
SMC EZNET 10/100
UNEX NexNIC ND012C
(please add your adapter model to this list)
......@@ -181,11 +184,18 @@ suggestions welcome) (WIP)
Change History
--------------
Version 0.9.23 - In progress
* New, compile-time conditional for testing better RX reset
* Only account specific RX errors if rx_status is !OK
Version 0.9.22 - November 8, 2001
* Additional retries before aborting Tx
* Do not write other TxConfig bits when writing clear-abort bit.
* Ack TxErr intr status after each Tx abort, too.
* Fix oops in interface restart
Version 0.9.21 - November 1, 2001
......
D-Link DL2000-based Gigabit Ethernet Adapter Installation
for Linux
Nov 12, 2001
Jan 02, 2002
Contents
========
......@@ -182,7 +182,7 @@ driver.
mtu=packet_size - Specifies the maximum packet size. default
is 1500.
media=xxxxxxxxx - Specifies the media type the NIC operates at.
media=media_type - Specifies the media type the NIC operates at.
autosense Autosensing active media.
10mbps_hd 10Mbps half duplex.
10mbps_fd 10Mbps full duplex.
......@@ -195,28 +195,41 @@ media=xxxxxxxxx - Specifies the media type the NIC operates at.
2 10Mbps full duplex.
3 100Mbps half duplex.
4 100Mbps full duplex.
5 1000Mbps full duplex.
6 1000Mbps half duplex.
5 1000Mbps half duplex.
6 1000Mbps full duplex.
By default, the NIC operates at autosense.
Note that only 1000mbps_fd and 1000mbps_hd
types are available for fiber adapter.
vlan=x - Specifies the VLAN ID. If vlan=0, the
vlan=[0|1] - Specifies the VLAN ID. If vlan=0, the
Virtual Local Area Network (VLAN) function is
disable.
jumbo=x - Specifies the jumbo frame support. If jumbo=1,
jumbo=[0|1] - Specifies the jumbo frame support. If jumbo=1,
the NIC accept jumbo frames. By default, this
function is disabled.
Jumbo frame usually improve the performance
int gigabit.
int_count - Rx frame count each interrupt.
int_timeout - Rx DMA wait time for an interrupt. Proper
values of int_count and int_timeout bring
a conspicuous performance in the fast machine.
Ex. int_count=5 and int_timeout=750
rx_coalesce=n - Rx frame count each interrupt.
rx_timeout=n - Rx DMA wait time for an interrupt. Proper
values of rx_coalesce and rx_timeout bring
a conspicuous performance in the fast machine.
Ex. rx_coalesce=5 and rx_timeout=750
tx_coalesce=n - Tx transmit count each TxComp interrupt.
Setting value larger than 1 will improve
performance, but this is possible to lower
stability in slow UP machines. By default,
tx_coalesce=1. (dl2k)
tx_flow=[1|0] - Specifies the Tx flow control. If tx_flow=1,
the Tx flow control enable.
rx_flow=[1|0] - Specifies the Rx flow control. If rx_flow=1,
the Rx flow control enable.
Configuration Script Sample
===========================
......
......@@ -436,8 +436,8 @@ static void srm_console_write(struct console *co, const char *s,
static kdev_t srm_console_device(struct console *c)
{
/* Huh? */
return MKDEV(TTY_MAJOR, 64 + c->index);
/* Huh? */
return mk_kdev(TTY_MAJOR, 64 + c->index);
}
static int __init srm_console_setup(struct console *co, char *options)
......
......@@ -196,8 +196,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
*/
out_of_memory:
if (current->pid == 1) {
current->policy |= SCHED_YIELD;
schedule();
yield();
down_read(&mm->mmap_sem);
goto survive;
}
......
......@@ -291,7 +291,7 @@ static int hci_vhci_chr_close(struct inode *inode, struct file *file)
static struct file_operations hci_vhci_fops = {
owner: THIS_MODULE,
llseek: no_lseek,
llseek: no_llseek,
read: hci_vhci_chr_read,
write: hci_vhci_chr_write,
poll: hci_vhci_chr_poll,
......
......@@ -87,8 +87,12 @@
*
*/
#define DRV_NAME "3c501"
#define DRV_VERSION "2001/11/17"
static const char version[] =
"3c501.c: 2000/02/08 Alan Cox (alan@redhat.com).\n";
DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@redhat.com).\n";
/*
* Braindamage remaining:
......@@ -108,7 +112,9 @@ static const char version[] =
#include <linux/errno.h>
#include <linux/config.h> /* for CONFIG_IP_MULTICAST */
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -139,12 +145,14 @@ static void el_reset(struct net_device *dev);
static int el1_close(struct net_device *dev);
static struct net_device_stats *el1_get_stats(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);
#define EL1_IO_EXTENT 16
#ifndef EL_DEBUG
#define EL_DEBUG 0 /* use 0 for production, 1 for devel., >2 for debug */
#endif /* Anything above 5 is wordy death! */
#define debug el_debug
static int el_debug = EL_DEBUG;
/*
......@@ -377,6 +385,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
dev->stop = &el1_close;
dev->get_stats = &el1_get_stats;
dev->set_multicast_list = &set_multicast_list;
dev->do_ioctl = netdev_ioctl;
/*
* Setup the generic properties
......@@ -915,6 +924,86 @@ static void set_multicast_list(struct net_device *dev)
}
}
/**
* 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;
}
#ifdef MODULE
static struct net_device dev_3c501 = {
......
......@@ -29,11 +29,17 @@
Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards.
Paul Gortmaker : multiple card support for module users.
rjohnson@analogic.com : Fix up PIO interface for efficient operation.
Jeff Garzik : ethtool support
*/
#define DRV_NAME "3c503"
#define DRV_VERSION "1.10a"
#define DRV_RELDATE "11/17/2001"
static const char version[] =
"3c503.c:v1.10 9/23/93 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
#include <linux/module.h>
......@@ -45,7 +51,9 @@ static const char version[] =
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/byteorder.h>
......@@ -74,6 +82,7 @@ static void el2_block_input(struct net_device *dev, int count, struct sk_buff *s
int ring_offset);
static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
/* This routine probes for a memory-mapped 3c503 board by looking for
......@@ -301,6 +310,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
dev->open = &el2_open;
dev->stop = &el2_close;
dev->do_ioctl = &netdev_ioctl;
if (dev->mem_start)
printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
......@@ -607,6 +617,71 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
return;
}
/**
* 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;
}
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;
}
#ifdef MODULE
#define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */
......
......@@ -35,8 +35,13 @@
* Philip Blundell <Philip.Blundell@pobox.com>
* Multicard/soft configurable dma channel/rev 2 hardware support
* by Christopher Collins <ccollins@pcug.org.au>
* Ethtool support (jgarzik), 11/17/2001
*/
#define DRV_NAME "3c505"
#define DRV_VERSION "1.10a"
/* Theory of operation:
*
* The 3c505 is quite an intelligent board. All communication with it is done
......@@ -103,6 +108,9 @@
#include <linux/slab.h>
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
......@@ -148,10 +156,11 @@ static char couldnot_msg[] __initdata = "%s: 3c505 not found\n";
*********************************************************/
#ifdef ELP_DEBUG
static const int elp_debug = ELP_DEBUG;
static int elp_debug = ELP_DEBUG;
#else
static const int elp_debug;
static int elp_debug;
#endif
#define debug elp_debug
/*
* 0 = no messages (well, some)
......@@ -1260,6 +1269,87 @@ static void elp_set_mc_list(struct net_device *dev)
}
}
/**
* 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;
}
/******************************************************
*
* initialise Etherlink Plus board
......@@ -1280,6 +1370,7 @@ static inline void elp_init(struct net_device *dev)
dev->tx_timeout = elp_timeout; /* local */
dev->watchdog_timeo = 10*HZ;
dev->set_multicast_list = elp_set_mc_list; /* local */
dev->do_ioctl = netdev_ioctl; /* local */
/* Setup the generic properties */
ether_setup(dev);
......
......@@ -25,8 +25,12 @@
The statistics need to be updated correctly.
*/
#define DRV_NAME "3c507"
#define DRV_VERSION "1.10a"
#define DRV_RELDATE "11/17/2001"
static const char version[] =
"3c507.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n";
#include <linux/module.h>
......@@ -52,6 +56,9 @@ static const char version[] =
#include <linux/in.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -70,6 +77,8 @@ static const char version[] =
#define NET_DEBUG 1
#endif
static unsigned int net_debug = NET_DEBUG;
#define debug net_debug
/* A zero-terminated list of common I/O addresses to be probed. */
static unsigned int netcard_portlist[] __initdata =
......@@ -296,6 +305,7 @@ static void el16_tx_timeout (struct net_device *dev);
static void hardware_send_packet(struct net_device *dev, void *buf, short length);
static void init_82586_mem(struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
/* Check for a network adaptor of this type, and return '0' iff one exists.
......@@ -427,6 +437,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
dev->get_stats = el16_get_stats;
dev->tx_timeout = el16_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl;
ether_setup(dev); /* Generic ethernet behaviour */
......@@ -864,6 +875,88 @@ static void el16_rx(struct net_device *dev)
lp->rx_head = rx_head;
lp->rx_tail = rx_tail;
}
/**
* 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;
}
#ifdef MODULE
static struct net_device dev_3c507;
static int io = 0x300;
......
......@@ -43,8 +43,14 @@
v1.18 12Mar2001 Andrew Morton <andrewm@uow.edu.au>
- Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
- Reviewed against 1.18 from scyld.com
v1.18 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com>
- ethtool support
*/
#define DRV_NAME "3c509"
#define DRV_VERSION "1.18a"
#define DRV_RELDATE "17Nov2001"
/* A few values that may be tweaked. */
/* Time in jiffies before concluding the transmitter is hung. */
......@@ -70,12 +76,14 @@ static int max_interrupt_work = 10;
#include <linux/skbuff.h>
#include <linux/delay.h> /* for udelay() */
#include <linux/spinlock.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/irq.h>
static char versionA[] __initdata = "3c509.c:1.18 12Mar2001 becker@scyld.com\n";
static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n";
static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
#ifdef EL3_DEBUG
......@@ -84,6 +92,7 @@ static int el3_debug = EL3_DEBUG;
static int el3_debug = 2;
#endif
/* To minimize the size of the driver source I only define operating
constants if they are used several times. You'll need the manual
anyway if you want to understand driver details. */
......@@ -158,6 +167,7 @@ static int el3_rx(struct net_device *dev);
static int el3_close(struct net_device *dev);
static void set_multicast_list(struct net_device *dev);
static void el3_tx_timeout (struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
#ifdef CONFIG_MCA
struct el3_mca_adapters_struct {
......@@ -513,6 +523,7 @@ int __init el3_probe(struct net_device *dev)
dev->set_multicast_list = &set_multicast_list;
dev->tx_timeout = el3_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
dev->do_ioctl = netdev_ioctl;
/* Fill in the generic fields of the device structure. */
ether_setup(dev);
......@@ -1003,6 +1014,85 @@ el3_close(struct net_device *dev)
return 0;
}
/**
* 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);
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 = el3_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;
el3_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;
}
#ifdef MODULE
/* Parameters that may be passed into the module. */
static int debug = -1;
......
......@@ -16,9 +16,17 @@
2/2/00- Added support for kernel-level ISAPnP
by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo
Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox.
11/17/2001 - Added ethtool support (jgarzik)
*/
static char *version = "3c515.c:v0.99-sn 2000/02/12 becker@cesdis.gsfc.nasa.gov and others\n";
#define DRV_NAME "3c515"
#define DRV_VERSION "0.99t"
#define DRV_RELDATE "17-Nov-2001"
static char *version =
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n";
#define CORKSCREW 1
......@@ -63,6 +71,9 @@ static int max_interrupt_work = 20;
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
......@@ -393,6 +404,7 @@ static int corkscrew_close(struct net_device *dev);
static void update_stats(int addr, struct net_device *dev);
static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
static void set_rx_mode(struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
/*
......@@ -721,6 +733,7 @@ static int corkscrew_probe1(struct net_device *dev)
dev->stop = &corkscrew_close;
dev->get_stats = &corkscrew_get_stats;
dev->set_multicast_list = &set_rx_mode;
dev->do_ioctl = netdev_ioctl;
return 0;
}
......@@ -1591,6 +1604,87 @@ static void set_rx_mode(struct net_device *dev)
outw(new_mode, ioaddr + EL3_CMD);
}
/**
* 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 = corkscrew_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;
corkscrew_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;
}
#ifdef MODULE
void cleanup_module(void)
......
......@@ -81,10 +81,15 @@
added option to disable multicast as is causes problems
Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
Stuart Adamson <stuart.adamson@compsoc.net>
Nov 2001
added support for ethtool (jgarzik)
$Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
*/
#define DRV_NAME "3c523"
#define DRV_VERSION "17-Nov-2001"
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
......@@ -95,6 +100,9 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mca.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -182,6 +190,7 @@ static void elmc_timeout(struct net_device *dev);
#ifdef ELMC_MULTICAST
static void set_multicast_list(struct net_device *dev);
#endif
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
/* helper-functions */
static int init586(struct net_device *dev);
......@@ -563,7 +572,8 @@ int __init elmc_probe(struct net_device *dev)
#else
dev->set_multicast_list = NULL;
#endif
dev->do_ioctl = netdev_ioctl;
ether_setup(dev);
/* note that we haven't actually requested the IRQ from the kernel.
......@@ -1214,6 +1224,69 @@ static void set_multicast_list(struct net_device *dev)
}
#endif
/**
* 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, "MCA 0x%lx", dev->base_addr);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
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;
}
/*************************************************************************/
#ifdef MODULE
......
......@@ -16,8 +16,12 @@
*
*/
#define DRV_NAME "3c527"
#define DRV_VERSION "0.6a"
#define DRV_RELDATE "2001/11/17"
static const char *version =
"3c527.c:v0.6 2001/03/03 Richard Proctor (rnp@netlink.co.nz)\n";
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Proctor (rnp@netlink.co.nz)\n";
/**
* DOC: Traps for the unwary
......@@ -90,6 +94,9 @@ static const char *version =
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
......@@ -108,7 +115,7 @@ static const char *version =
* The name of the card. Is used for messages and in the requests for
* io regions, irqs and dma channels
*/
static const char* cardname = "3c527";
static const char* cardname = DRV_NAME;
/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
......@@ -213,6 +220,7 @@ static int mc32_close(struct net_device *dev);
static struct net_device_stats *mc32_get_stats(struct net_device *dev);
static void mc32_set_multicast_list(struct net_device *dev);
static void mc32_reset_multicast_list(struct net_device *dev);
static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
/**
* mc32_probe - Search for supported boards
......@@ -502,7 +510,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
dev->set_multicast_list = mc32_set_multicast_list;
dev->tx_timeout = mc32_timeout;
dev->watchdog_timeo = HZ*5; /* Board does all the work */
dev->do_ioctl = netdev_ioctl;
lp->xceiver_state = HALTED;
......@@ -1644,6 +1652,86 @@ static void mc32_reset_multicast_list(struct net_device *dev)
do_mc32_set_multicast_list(dev,1);
}
/**
* 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, "MCA 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 = mc32_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;
mc32_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;
}
#ifdef MODULE
static struct net_device this_device;
......
......@@ -20,7 +20,6 @@
TODO, in rough priority order:
* dev->tx_timeout
* LinkChg interrupt
* ETHTOOL_[GS]SET
* Support forcing media type with a module parameter,
like dl2k.c/sundance.c
* Implement PCI suspend/resume
......@@ -33,18 +32,19 @@
* Rx checksumming
* Tx checksumming
* ETHTOOL_GREGS, ETHTOOL_[GS]WOL,
ETHTOOL_[GS]MSGLVL, ETHTOOL_NWAY_RST
* Jumbo frames / dev->change_mtu
* Investigate using skb->priority with h/w VLAN priority
* Investigate using High Priority Tx Queue with skb->priority
* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
* Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
* Implement Tx software interrupt mitigation via
Tx descriptor bit
*/
#define DRV_NAME "8139cp"
#define DRV_VERSION "0.0.5"
#define DRV_RELDATE "Oct 19, 2001"
#define DRV_VERSION "0.0.6cvs"
#define DRV_RELDATE "Nov 19, 2001"
#include <linux/module.h>
......@@ -56,6 +56,7 @@
#include <linux/delay.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <asm/io.h>
#include <asm/uaccess.h>
......@@ -94,10 +95,10 @@ MODULE_PARM_DESC (multicast_filter_limit, "8139cp maximum number of filtered mul
(((CP)->tx_tail <= (CP)->tx_head) ? \
(CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head : \
(CP)->tx_tail - (CP)->tx_head - 1)
#define CP_CHIP_VERSION 0x76
#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
#define RX_OFFSET 2
#define CP_INTERNAL_PHY 32
/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */
#define RX_FIFO_THRESH 5 /* Rx buffer level before first PCI xfer. */
......@@ -126,6 +127,11 @@ enum {
Config3 = 0x59, /* Config3 */
Config4 = 0x5A, /* Config4 */
MultiIntr = 0x5C, /* Multiple interrupt select */
BasicModeCtrl = 0x62, /* MII BMCR */
BasicModeStatus = 0x64, /* MII BMSR */
NWayAdvert = 0x66, /* MII ADVERTISE */
NWayLPAR = 0x68, /* MII LPA */
NWayExpansion = 0x6A, /* MII Expansion */
Config5 = 0xD8, /* Config5 */
TxPoll = 0xD9, /* Tell chip to check Tx descriptors for work */
CpCmd = 0xE0, /* C+ Command register (C+ mode only) */
......@@ -279,6 +285,8 @@ struct cp_private {
struct sk_buff *frag_skb;
unsigned dropping_frag : 1;
struct mii_if_info mii_if;
};
#define cpr8(reg) readb(cp->regs + (reg))
......@@ -985,6 +993,39 @@ static int cp_close (struct net_device *dev)
return 0;
}
static char mii_2_8139_map[8] = {
BasicModeCtrl,
BasicModeStatus,
0,
0,
NWayAdvert,
NWayLPAR,
NWayExpansion,
0
};
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
struct cp_private *cp = dev->priv;
return location < 8 && mii_2_8139_map[location] ?
readw(cp->regs + mii_2_8139_map[location]) : 0;
}
static void mdio_write(struct net_device *dev, int phy_id, int location,
int value)
{
struct cp_private *cp = dev->priv;
if (location == 0) {
cpw8(Cfg9346, Cfg9346_Unlock);
cpw16(BasicModeCtrl, value);
cpw8(Cfg9346, Cfg9346_Lock);
} else if (location < 8 && mii_2_8139_map[location])
cpw16(mii_2_8139_map[location], value);
}
static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
{
u32 ethcmd;
......@@ -992,21 +1033,71 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
/* dev_ioctl() in ../../net/core/dev.c has already checked
capable(CAP_NET_ADMIN), so don't bother with that here. */
if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
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);
strcpy (info.bus_info, cp->pdev->slot_name);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, DRV_NAME);
strcpy (info.version, DRV_VERSION);
strcpy (info.bus_info, cp->pdev->slot_name);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
/* get settings */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
spin_lock_irq(&cp->lock);
mii_ethtool_gset(&cp->mii_if, &ecmd);
spin_unlock_irq(&cp->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
int r;
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&cp->lock);
r = mii_ethtool_sset(&cp->mii_if, &ecmd);
spin_unlock_irq(&cp->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return mii_nway_restart(&cp->mii_if);
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
edata.data = mii_link_ok(&cp->mii_if);
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 = cp->msg_enable;
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;
cp->msg_enable = edata.data;
return 0;
}
default:
break;
......@@ -1136,6 +1227,10 @@ static int __devinit cp_init_one (struct pci_dev *pdev,
cp->dev = dev;
cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
spin_lock_init (&cp->lock);
cp->mii_if.dev = dev;
cp->mii_if.mdio_read = mdio_read;
cp->mii_if.mdio_write = mdio_write;
cp->mii_if.phy_id = CP_INTERNAL_PHY;
rc = pci_enable_device(pdev);
if (rc)
......
This diff is collapsed.
......@@ -179,6 +179,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
dep_mbool ' Use PIO instead of MMIO' CONFIG_8139TOO_PIO $CONFIG_8139TOO
dep_mbool ' Support for automatic channel equalization (EXPERIMENTAL)' CONFIG_8139TOO_TUNE_TWISTER $CONFIG_8139TOO $CONFIG_EXPERIMENTAL
dep_mbool ' Support for older RTL-8129/8130 boards' CONFIG_8139TOO_8129 $CONFIG_8139TOO
dep_mbool ' Experiment for better RX reset (EXPERIMENTAL)' CONFIG_8139_NEW_RX_RESET $CONFIG_8139TOO $CONFIG_EXPERIMENTAL
dep_tristate ' SiS 900/7016 PCI Fast Ethernet Adapter support' CONFIG_SIS900 $CONFIG_PCI
dep_tristate ' SMC EtherPower II' CONFIG_EPIC100 $CONFIG_PCI
dep_tristate ' Sundance Alta support' CONFIG_SUNDANCE $CONFIG_PCI
......
......@@ -68,7 +68,7 @@ obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
obj-$(CONFIG_PCNET32) += pcnet32.o
obj-$(CONFIG_EEPRO100) += eepro100.o
obj-$(CONFIG_TLAN) += tlan.o
obj-$(CONFIG_EPIC100) += epic100.o
obj-$(CONFIG_EPIC100) += epic100.o mii.o
obj-$(CONFIG_SIS900) += sis900.o
obj-$(CONFIG_DM9102) += dmfe.o
obj-$(CONFIG_YELLOWFIN) += yellowfin.o
......@@ -77,7 +77,7 @@ obj-$(CONFIG_VETH) += veth.o
obj-$(CONFIG_NATSEMI) += natsemi.o
obj-$(CONFIG_NS83820) += ns83820.o
obj-$(CONFIG_STNIC) += stnic.o 8390.o
obj-$(CONFIG_FEALNX) += fealnx.o
obj-$(CONFIG_FEALNX) += fealnx.o mii.o
ifeq ($(CONFIG_SK98LIN),y)
obj-y += sk98lin/sk98lin.o
......@@ -87,7 +87,7 @@ ifeq ($(CONFIG_SKFP),y)
obj-y += skfp/skfp.o
endif
obj-$(CONFIG_VIA_RHINE) += via-rhine.o
obj-$(CONFIG_VIA_RHINE) += via-rhine.o mii.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
#
......@@ -100,7 +100,7 @@ obj-$(CONFIG_AIRONET4500_NONCS) += aironet4500_card.o
obj-$(CONFIG_AIRONET4500_PROC) += aironet4500_proc.o
obj-$(CONFIG_AIRONET4500_CS) += aironet4500_proc.o
obj-$(CONFIG_WINBOND_840) += winbond-840.o
obj-$(CONFIG_WINBOND_840) += winbond-840.o mii.o
obj-$(CONFIG_SUNDANCE) += sundance.o
obj-$(CONFIG_HAMACHI) += hamachi.o
obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
......@@ -164,8 +164,8 @@ obj-$(CONFIG_EL3) += 3c509.o
obj-$(CONFIG_3C515) += 3c515.o
obj-$(CONFIG_EEXPRESS) += eexpress.o
obj-$(CONFIG_EEXPRESS_PRO) += eepro.o
obj-$(CONFIG_8139CP) += 8139cp.o
obj-$(CONFIG_8139TOO) += 8139too.o
obj-$(CONFIG_8139CP) += 8139cp.o mii.o
obj-$(CONFIG_8139TOO) += 8139too.o mii.o
obj-$(CONFIG_ARLAN) += arlan.o arlan-proc.o
obj-$(CONFIG_ZNET) += znet.o
obj-$(CONFIG_LAN_SAA9730) += saa9730.o
......
......@@ -1135,12 +1135,14 @@ static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* fixme */
switch(cmd) {
case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
case SIOCGMIIPHY: /* Get the address of the PHY in use. */
data[0] = PHY_ADDRESS;
case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
case SIOCGMIIREG: /* Read the specified MII register. */
//data[3] = mdio_read(ioaddr, data[0], data[1]);
return 0;
case SIOCDEVPRIVATE+2: /* Write the specified MII register */
case SIOCSMIIREG: /* Write the specified MII register */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
//mdio_write(ioaddr, data[0], data[1], data[2]);
......
......@@ -3645,7 +3645,7 @@ de4x5_alloc_rx_buff(struct net_device *dev, int index, int len)
tmp = virt_to_bus(p->data);
i = ((tmp + ALIGN) & ~ALIGN) - tmp;
skb_reserve(p, i);
lp->rx_ring[index].buf = tmp + i;
lp->rx_ring[index].buf = cpu_to_le32(tmp + i);
ret = lp->rx_skb[index];
lp->rx_skb[index] = p;
......@@ -5616,7 +5616,7 @@ de4x5_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
if (!capable(CAP_NET_ADMIN)) return -EPERM;
omr = inl(DE4X5_OMR);
omr &= ~OMR_PR;
outb(omr, DE4X5_OMR);
outl(omr, DE4X5_OMR);
dev->flags &= ~IFF_PROMISC;
break;
......
This diff is collapsed.
......@@ -34,7 +34,7 @@
#include <linux/spinlock.h>
#include <linux/time.h>
#define TX_RING_SIZE 128
#define TX_QUEUE_LEN 96 /* Limit ring entries actually used. */
#define TX_QUEUE_LEN 120 /* Limit ring entries actually used. */
#define RX_RING_SIZE 128
#define TX_TOTAL_SIZE TX_RING_SIZE*sizeof(struct netdev_desc)
#define RX_TOTAL_SIZE RX_RING_SIZE*sizeof(struct netdev_desc)
......@@ -183,12 +183,12 @@ enum IntStatus_bits {
/* Bits in the ReceiveMode register. */
enum ReceiveMode_bits {
ReceiveIPMulticast = 0x0020,
ReceiveMulticastHash = 0x0010,
ReceiveAllFrames = 0x0008,
ReceiveBroadcast = 0x0004,
ReceiveMulticast = 0x0002,
ReceiveUnicast = 0x0001,
ReceiveMulticast = 0x0002,
ReceiveBroadcast = 0x0004,
ReceiveAllFrames = 0x0008,
ReceiveMulticastHash = 0x0010,
ReceiveIPMulticast = 0x0020,
ReceiveVLANMatch = 0x0100,
ReceiveVLANHash = 0x0200,
};
......@@ -650,20 +650,20 @@ struct netdev_private {
struct pci_dev *pdev;
spinlock_t lock;
struct net_device_stats stats;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int speed; /* Operating speed */
unsigned int vlan; /* VLAN Id */
unsigned int chip_id; /* PCI table chip id */
unsigned int int_count; /* Maximum frames each RxDMAComplete intr */
unsigned int int_timeout; /* Wait time between RxDMAComplete intr */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int speed; /* Operating speed */
unsigned int vlan; /* VLAN Id */
unsigned int chip_id; /* PCI table chip id */
unsigned int rx_coalesce; /* Maximum frames each RxDMAComplete intr */
unsigned int rx_timeout; /* Wait time between RxDMAComplete intr */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int an_enable:2; /* Auto-Negotiated Enable */
unsigned int jumbo:1; /* Jumbo frame enable */
unsigned int coalesce:1; /* Rx coalescing enable */
unsigned int tx_flow:1; /* Tx flow control enable */
unsigned int rx_flow:1; /* Rx flow control enable */
unsigned int phy_media:1; /* 1: fiber, 0: copper */
unsigned int phy_media:1; /* 1: fiber, 0: copper */
struct netdev_desc *last_tx; /* Last Tx descriptor used. */
unsigned long cur_rx, old_rx; /* Producer/consumer ring indices */
unsigned long cur_tx, old_tx;
......@@ -698,7 +698,12 @@ static struct pci_device_id rio_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
#define TX_TIMEOUT (4*HZ)
#define PACKET_SIZE 1536
#define MAX_JUMBO 8000
#define RIO_IO_SIZE 340
#define DEFAULT_RXC 5
#define DEFAULT_RXT 750
#define DEFAULT_TXC 1
#define MAX_TXC 8
#ifdef RIO_DEBUG
#define DEBUG_TFD_DUMP(x) debug_tfd_dump(x)
#define DEBUG_RFD_DUMP(x,flag) debug_rfd_dump(x,flag)
......
This diff is collapsed.
......@@ -15,8 +15,19 @@
Support information and updates available at
http://www.scyld.com/network/pci-skeleton.html
Linux kernel updates:
Version 2.51, Nov 17, 2001 (jgarzik):
- Add ethtool support
- Replace some MII-related magic numbers with constants
*/
#define DRV_NAME "fealnx"
#define DRV_VERSION "2.51"
#define DRV_RELDATE "Nov-17-2001"
static int debug; /* 1-> print debug message */
static int max_interrupt_work = 20;
......@@ -72,14 +83,16 @@ static int full_duplex[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1 };
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/crc32.h>
#include <asm/processor.h> /* Processor type for cache alignment. */
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/uaccess.h>
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
KERN_INFO "fealnx.c:v2.50 1/17/2001\n";
KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "\n";
/* This driver was written to use PCI memory space, however some x86 systems
......@@ -380,6 +393,8 @@ struct netdev_private {
dma_addr_t rx_ring_dma;
dma_addr_t tx_ring_dma;
spinlock_t lock;
struct net_device_stats stats;
/* Media monitoring timer. */
......@@ -404,19 +419,17 @@ struct netdev_private {
unsigned int linkok;
unsigned int line_speed;
unsigned int duplexmode;
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int duplex_lock:1;
unsigned int medialock:1; /* Do not sense media. */
unsigned int default_port:4; /* Last dev->if_port value. */
unsigned int PHYType;
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
unsigned char phys[2]; /* MII device addresses. */
struct mii_if_info mii;
};
static unsigned int mdio_read(struct net_device *dev, int phy_id, int location);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int netdev_open(struct net_device *dev);
static void getlinktype(struct net_device *dev);
......@@ -539,9 +552,13 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
/* Make certain the descriptor lists are aligned. */
np = dev->priv;
spin_lock_init(&np->lock);
np->pci_dev = pdev;
np->flags = skel_netdrv_tbl[chip_id].flags;
pci_set_drvdata(pdev, dev);
np->mii.dev = dev;
np->mii.mdio_read = mdio_read;
np->mii.mdio_write = mdio_write;
ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);
if (!ring_space) {
......@@ -606,6 +623,7 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
else
np->PHYType = OtherPHY;
}
np->mii.phy_id = np->phys[0];
if (dev->mem_start)
option = dev->mem_start;
......@@ -613,17 +631,14 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x200)
np->full_duplex = 1;
np->mii.full_duplex = 1;
np->default_port = option & 15;
if (np->default_port)
np->medialock = 1;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
np->full_duplex = full_duplex[card_idx];
np->mii.full_duplex = full_duplex[card_idx];
if (np->full_duplex) {
if (np->mii.full_duplex) {
printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
/* 89/6/13 add, (begin) */
// if (np->PHYType==MarvellPHY)
......@@ -636,10 +651,10 @@ static int __devinit fealnx_init_one(struct pci_dev *pdev,
}
/* 89/6/13 add, (end) */
if (np->flags == HAS_MII_XCVR)
mdio_write(dev, np->phys[0], 4, 0x141);
mdio_write(dev, np->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
else
writel(0x141, dev->base_addr + ANARANLPAR);
np->duplex_lock = 1;
writel(ADVERTISE_FULL, dev->base_addr + ANARANLPAR);
np->mii.duplex_lock = 1;
}
/* The chip-specific entries in the device structure. */
......@@ -787,7 +802,7 @@ static ulong m80x_send_cmd_to_phy(long miiport, int opcode, int phyad, int regad
}
static unsigned int mdio_read(struct net_device *dev, int phyad, int regad)
static int mdio_read(struct net_device *dev, int phyad, int regad)
{
long miiport = dev->base_addr + MANAGEMENT;
ulong miir;
......@@ -821,7 +836,7 @@ static unsigned int mdio_read(struct net_device *dev, int phyad, int regad)
miir &= ~MASK_MIIR_MII_MDC;
writel(miir, miiport);
return data;
return data & 0xffff;
}
......@@ -941,7 +956,7 @@ static int netdev_open(struct net_device *dev)
// 89/9/1 modify,
// np->crvalue = 0x00e40001; /* tx store and forward, tx/rx enable */
np->crvalue |= 0x00e40001; /* tx store and forward, tx/rx enable */
np->full_duplex = np->duplex_lock;
np->mii.full_duplex = np->mii.duplex_lock;
getlinkstatus(dev);
if (np->linkok)
getlinktype(dev);
......@@ -990,7 +1005,7 @@ static void getlinkstatus(struct net_device *dev)
}
} else {
for (i = 0; i < DelayTime; ++i) {
if (mdio_read(dev, np->phys[0], 1) & 0x4) {
if (mdio_read(dev, np->phys[0], MII_BMSR) & BMSR_LSTATUS) {
np->linkok = 1;
return;
}
......@@ -1475,7 +1490,7 @@ static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
np->stats.tx_window_errors++;
if (tx_status & UDF)
np->stats.tx_fifo_errors++;
if ((tx_status & HF) && np->full_duplex == 0)
if ((tx_status & HF) && np->mii.full_duplex == 0)
np->stats.tx_heartbeat_errors++;
#ifdef ETHER_STATS
......@@ -1751,24 +1766,100 @@ static void set_rx_mode(struct net_device *dev)
writel(np->crvalue, ioaddr + TCRRCR);
}
static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
{
struct netdev_private *np = 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, DRV_NAME);
strcpy (info.version, DRV_VERSION);
strcpy (info.bus_info, np->pci_dev->slot_name);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
/* get settings */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii, &ecmd);
spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
int r;
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii, &ecmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return mii_nway_restart(&np->mii);
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
edata.data = mii_link_ok(&np->mii);
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:
break;
}
return -EOPNOTSUPP;
}
static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = ((struct netdev_private *) dev->priv)->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
......
......@@ -1941,17 +1941,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
/* TODO: Check the sequencing of this. Might need to stop and
* restart Rx and Tx engines. -KDU
*/
......
......@@ -168,6 +168,10 @@ int mii_nway_restart (struct mii_if_info *mii)
return r;
}
MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
MODULE_DESCRIPTION ("MII hardware support library");
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(mii_link_ok);
EXPORT_SYMBOL(mii_nway_restart);
EXPORT_SYMBOL(mii_ethtool_gset);
......
#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
* ===============
......@@ -86,9 +87,11 @@
#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);
......
......@@ -834,7 +834,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
printk (KERN_INFO
"%s: Media type forced to Full Duplex.\n",
dev->name);
mdio_write (dev, tp->phys[0], 4, 0x141);
mdio_write (dev, tp->phys[0], MII_ADVERTISE, ADVERTISE_FULL);
tp->duplex_lock = 1;
}
......@@ -1235,20 +1235,20 @@ static void netdrv_timer (unsigned long data)
struct netdrv_private *tp = dev->priv;
void *ioaddr = tp->mmio_addr;
int next_tick = 60 * HZ;
int mii_reg5;
int mii_lpa;
mii_reg5 = mdio_read (dev, tp->phys[0], 5);
mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
if (!tp->duplex_lock && mii_reg5 != 0xffff) {
int duplex = (mii_reg5 & 0x0100)
|| (mii_reg5 & 0x01C0) == 0x0040;
if (!tp->duplex_lock && mii_lpa != 0xffff) {
int duplex = (mii_lpa & LPA_100FULL)
|| (mii_lpa & 0x01C0) == 0x0040;
if (tp->full_duplex != duplex) {
tp->full_duplex = duplex;
printk (KERN_INFO
"%s: Setting %s-duplex based on MII #%d link"
" partner ability of %4.4x.\n", dev->name,
tp->full_duplex ? "full" : "half",
tp->phys[0], mii_reg5);
tp->phys[0], mii_lpa);
NETDRV_W8 (Cfg9346, Cfg9346_Unlock);
NETDRV_W8 (Config1, tp->full_duplex ? 0x60 : 0x20);
NETDRV_W8 (Cfg9346, Cfg9346_Lock);
......@@ -1793,19 +1793,16 @@ static int netdrv_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
switch (cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = tp->phys[0] & 0x3f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
spin_lock_irqsave (&tp->lock, flags);
data->val_out = mdio_read (dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
spin_unlock_irqrestore (&tp->lock, flags);
break;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable (CAP_NET_ADMIN)) {
rc = -EPERM;
break;
......
......@@ -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)) {
......
......@@ -10,8 +10,11 @@
*
*/
#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);
......
......@@ -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;
}
......
......@@ -1472,21 +1472,18 @@ static int xircom_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* Legacy mii-diag interface */
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
if (tp->mii_cnt)
data[0] = phy;
else
return -ENODEV;
return 0;
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
save_flags(flags);
cli();
data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
restore_flags(flags);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
save_flags(flags);
......
......@@ -483,7 +483,7 @@ static void sl_tx_timeout(struct net_device *dev)
* 14 Oct 1994 Dmitry Gorodchanin.
*/
#ifdef SL_CHECK_TRANSMIT
if (jiffies - dev->trans_start < 20 * HZ) {
if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
/* 20 sec timeout not reached */
goto out;
}
......@@ -1387,7 +1387,7 @@ cleanup_module(void)
int i;
if (slip_ctrls != NULL) {
unsigned long start = jiffies;
unsigned long timeout = jiffies + HZ;
int busy = 0;
/* First of all: check for active disciplines and hangup them.
......@@ -1410,7 +1410,7 @@ cleanup_module(void)
spin_unlock(&slc->ctrl.lock);
}
local_bh_enable();
} while (busy && jiffies - start < 1*HZ);
} while (busy && time_before(jiffies, timeout));
busy = 0;
for (i = 0; i < slip_maxdev; i++) {
......
......@@ -93,13 +93,16 @@
- 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;
}
......@@ -1784,17 +1828,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
/* Legacy mii-diag interface */
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = np->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (data->phy_id == np->phys[0]) {
......
......@@ -21,11 +21,15 @@
Version 1.01a (jgarzik):
- Replace some MII-related magic numbers with constants
Version 1.02 (D-Link):
- Add new board to PCI ID list
- Fix multicast bug
*/
#define DRV_NAME "sundance"
#define DRV_VERSION "1.01a"
#define DRV_RELDATE "11-Nov-2001"
#define DRV_VERSION "1.02"
#define DRV_RELDATE "17-Jan-2002"
/* The user-configurable values.
......@@ -223,8 +227,9 @@ static struct pci_device_id sundance_pci_tbl[] __devinitdata = {
{0x1186, 0x1002, 0x1186, 0x1002, 0, 0, 0},
{0x1186, 0x1002, 0x1186, 0x1003, 0, 0, 1},
{0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2},
{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
{0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3},
{0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4},
{0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5},
{0,}
};
MODULE_DEVICE_TABLE(pci, sundance_pci_tbl);
......@@ -247,6 +252,8 @@ static struct pci_id_info pci_id_tbl[] = {
PCI_IOTYPE, 128, CanHaveMII},
{"D-Link DFE-580TX 4 port Server Adapter", {0x10121186, 0xffffffff,},
PCI_IOTYPE, 128, CanHaveMII},
{"D-Link DFE-530TXS FAST Ethernet Adapter", {0x10021186, 0xffffffff,},
PCI_IOTYPE, 128, CanHaveMII},
{"D-Link DL10050-based FAST Ethernet Adapter",
{0x10021186, 0xffffffff,},
PCI_IOTYPE, 128, CanHaveMII},
......@@ -1287,11 +1294,16 @@ static void set_rx_mode(struct net_device *dev)
rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
} else if (dev->mc_count) {
struct dev_mc_list *mclist;
memset(mc_filter, 0, sizeof(mc_filter));
int bit;
int index;
int crc;
memset (mc_filter, 0, sizeof (mc_filter));
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next) {
set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
mc_filter);
i++, mclist = mclist->next) {
crc = ether_crc_le (ETH_ALEN, mclist->dmi_addr);
for (index=0, bit=0; bit < 6; bit++, crc <<= 1)
if (crc & 0x80000000) index |= 1 << bit;
mc_filter[index/16] |= (1 << (index % 16));
}
rx_mode = AcceptBroadcast | AcceptMultiHash | AcceptMyPhys;
} else {
......@@ -1335,17 +1347,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
mdio_write(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
......
......@@ -923,18 +923,15 @@ static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
switch(cmd) {
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = phy;
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
......
This diff is collapsed.
......@@ -175,7 +175,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
case LMCIOCSINFO: /*fold01*/
sp = &((struct ppp_device *) dev)->sppp;
if (!suser ()) {
if (!capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
......@@ -210,7 +210,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
u_int16_t old_type = sc->if_type;
u_int16_t new_type;
if (!suser ()) {
if (!capable(CAP_NET_ADMIN)) {
ret = -EPERM;
break;
}
......@@ -290,7 +290,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
case LMCIOCCLEARLMCSTATS: /*fold01*/
if (!suser ()){
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
......@@ -304,7 +304,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
case LMCIOCSETCIRCUIT: /*fold01*/
if (!suser ()){
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
......@@ -322,7 +322,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
break;
case LMCIOCRESET: /*fold01*/
if (!suser ()){
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
......@@ -355,7 +355,7 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
{
struct lmc_xilinx_control xc; /*fold02*/
if (!suser ()){
if (!capable(CAP_NET_ADMIN)){
ret = -EPERM;
break;
}
......
......@@ -36,6 +36,8 @@
power management.
support for big endian descriptors
Copyright (C) 2001 Manfred Spraul
* ethtool support (jgarzik)
* Replace some MII-related magic numbers with constants (jgarzik)
TODO:
* enable pci_power_off
......@@ -43,8 +45,8 @@
*/
#define DRV_NAME "winbond-840"
#define DRV_VERSION "1.01-c"
#define DRV_RELDATE "6/30/2000"
#define DRV_VERSION "1.01-d"
#define DRV_RELDATE "Nov-17-2001"
/* Automatically extracted configuration info:
......@@ -364,14 +366,11 @@ struct netdev_private {
unsigned int cur_tx, dirty_tx;
unsigned int tx_q_bytes;
unsigned int tx_full; /* The Tx queue is full. */
/* These values are keep track of the transceiver/media in use. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int duplex_lock:1;
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
unsigned char phys[MII_CNT]; /* MII device addresses, but only the first is used */
u32 mii;
struct mii_if_info mii_if;
};
static int eeprom_read(long ioaddr, int location);
......@@ -453,6 +452,9 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
np->chip_id = chip_idx;
np->drv_flags = pci_id_tbl[chip_idx].drv_flags;
spin_lock_init(&np->lock);
np->mii_if.dev = dev;
np->mii_if.mdio_read = mdio_read;
np->mii_if.mdio_write = mdio_write;
pci_set_drvdata(pdev, dev);
......@@ -462,16 +464,16 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
/* The lower four bits are the media type. */
if (option > 0) {
if (option & 0x200)
np->full_duplex = 1;
np->mii_if.full_duplex = 1;
if (option & 15)
printk(KERN_INFO "%s: ignoring user supplied media type %d",
dev->name, option & 15);
}
if (find_cnt < MAX_UNITS && full_duplex[find_cnt] > 0)
np->full_duplex = 1;
np->mii_if.full_duplex = 1;
if (np->full_duplex)
np->duplex_lock = 1;
if (np->mii_if.full_duplex)
np->mii_if.duplex_lock = 1;
/* The chip-specific entries in the device structure. */
dev->open = &netdev_open;
......@@ -496,18 +498,19 @@ static int __devinit w840_probe1 (struct pci_dev *pdev,
if (np->drv_flags & CanHaveMII) {
int phy, phy_idx = 0;
for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
int mii_status = mdio_read(dev, phy, 1);
int mii_status = mdio_read(dev, phy, MII_BMSR);
if (mii_status != 0xffff && mii_status != 0x0000) {
np->phys[phy_idx++] = phy;
np->advertising = mdio_read(dev, phy, 4);
np->mii = (mdio_read(dev, phy, 2) << 16)+
mdio_read(dev, phy, 3);
np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
np->mii = (mdio_read(dev, phy, MII_PHYSID1) << 16)+
mdio_read(dev, phy, MII_PHYSID2);
printk(KERN_INFO "%s: MII PHY %8.8xh found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
dev->name, np->mii, phy, mii_status, np->advertising);
dev->name, np->mii, phy, mii_status, np->mii_if.advertising);
}
}
np->mii_cnt = phy_idx;
np->mii_if.phy_id = np->phys[0];
if (phy_idx == 0) {
printk(KERN_WARNING "%s: MII PHY not found -- this device may "
"not operate correctly.\n", dev->name);
......@@ -654,7 +657,7 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
int i;
if (location == 4 && phy_id == np->phys[0])
np->advertising = value;
np->mii_if.advertising = value;
if (mii_preamble_required)
mdio_sync(mdio_addr);
......@@ -728,12 +731,12 @@ static int update_link(struct net_device *dev)
int duplex, fasteth, result, mii_reg;
/* BSMR */
mii_reg = mdio_read(dev, np->phys[0], 1);
mii_reg = mdio_read(dev, np->phys[0], MII_BMSR);
if (mii_reg == 0xffff)
return np->csr6;
/* reread: the link status bit is sticky */
mii_reg = mdio_read(dev, np->phys[0], 1);
mii_reg = mdio_read(dev, np->phys[0], MII_BMSR);
if (!(mii_reg & 0x4)) {
if (netif_carrier_ok(dev)) {
if (debug)
......@@ -759,18 +762,18 @@ static int update_link(struct net_device *dev)
* Instead bit 9 and 13 of the BMCR are updated to the result
* of the negotiation..
*/
mii_reg = mdio_read(dev, np->phys[0], 0);
duplex = mii_reg & 0x100;
fasteth = mii_reg & 0x2000;
mii_reg = mdio_read(dev, np->phys[0], MII_BMCR);
duplex = mii_reg & BMCR_FULLDPLX;
fasteth = mii_reg & BMCR_SPEED100;
} else {
int negotiated;
mii_reg = mdio_read(dev, np->phys[0], 5);
negotiated = mii_reg & np->advertising;
mii_reg = mdio_read(dev, np->phys[0], MII_LPA);
negotiated = mii_reg & np->mii_if.advertising;
duplex = (negotiated & 0x0100) || ((negotiated & 0x02C0) == 0x0040);
duplex = (negotiated & LPA_100FULL) || ((negotiated & 0x02C0) == LPA_10FULL);
fasteth = negotiated & 0x380;
}
duplex |= np->duplex_lock;
duplex |= np->mii_if.duplex_lock;
/* remove fastether and fullduplex */
result = np->csr6 & ~0x20000200;
if (duplex)
......@@ -822,7 +825,7 @@ static inline void update_csr6(struct net_device *dev, int new)
/* and restart them with the new configuration */
writel(np->csr6, ioaddr + NetworkConfig);
if (new & 0x200)
np->full_duplex = 1;
np->mii_if.full_duplex = 1;
}
static void netdev_timer(unsigned long data)
......@@ -1131,7 +1134,7 @@ static void netdev_tx_done(struct net_device *dev)
if (tx_status & 0x0C80) np->stats.tx_carrier_errors++;
if (tx_status & 0x0200) np->stats.tx_window_errors++;
if (tx_status & 0x0002) np->stats.tx_fifo_errors++;
if ((tx_status & 0x0080) && np->full_duplex == 0)
if ((tx_status & 0x0080) && np->mii_if.full_duplex == 0)
np->stats.tx_heartbeat_errors++;
#ifdef ETHER_STATS
if (tx_status & 0x0100) np->stats.collisions16++;
......@@ -1469,6 +1472,56 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
return 0;
}
/* get settings */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii_if, &ecmd);
spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
int r;
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii_if, &ecmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
return mii_nway_restart(&np->mii_if);
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
edata.data = mii_link_ok(&np->mii_if);
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;
}
}
return -EOPNOTSUPP;
......@@ -1483,19 +1536,16 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
spin_lock_irq(&np->lock);
data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
spin_unlock_irq(&np->lock);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
spin_lock_irq(&np->lock);
......
......@@ -1420,17 +1420,14 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
data->phy_id = np->phys[0] & 0x1f;
/* Fall Through */
case SIOCGMIIREG: /* Read MII PHY register. */
case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
case SIOCSMIIREG: /* Write MII PHY register. */
case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (data->phy_id == np->phys[0]) {
......
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